From 122af84d2d62cdbb21ad8f02c08b0dbb87c2548b Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Mon, 23 Sep 2024 10:00:50 +0000 Subject: [PATCH 001/425] Update lean-toolchain for testing https://github.com/leanprover/lean4/pull/5323 --- lake-manifest.json | 4 ++-- lakefile.lean | 2 +- lean-toolchain | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index 359958e90841e6..1dac685b2c0075 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,10 +5,10 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "e25ca36a17c75077f7812d85a8435a77096e16c5", + "rev": "f51886e35b46d714c48f3f7fe0251d42c6d037b3", "name": "batteries", "manifestFile": "lake-manifest.json", - "inputRev": "nightly-testing", + "inputRev": "nightly-testing-2024-09-21", "inherited": false, "configFile": "lakefile.lean"}, {"url": "https://github.com/leanprover-community/quote4", diff --git a/lakefile.lean b/lakefile.lean index 7ff1d428937c21..b5908fbaf2a694 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -7,7 +7,7 @@ open Lake DSL ## Mathlib dependencies on upstream projects -/ -require "leanprover-community" / "batteries" @ git "nightly-testing" +require "leanprover-community" / "batteries" @ git "nightly-testing-2024-09-21" require "leanprover-community" / "Qq" @ git "master" require "leanprover-community" / "aesop" @ git "master" require "leanprover-community" / "proofwidgets" @ git "v0.0.42" diff --git a/lean-toolchain b/lean-toolchain index f2c3a8904f6386..ba3ea96d389c76 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-09-21 +leanprover/lean4-pr-releases:pr-release-5323 From e704c154f75659965b0f19a8fb168335cb564ba8 Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Mon, 23 Sep 2024 10:32:46 +0000 Subject: [PATCH 002/425] Trigger CI for https://github.com/leanprover/lean4/pull/5323 From 4d68081db496a2081180bfbd4f618f9a429493fd Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Mon, 23 Sep 2024 11:54:45 +0000 Subject: [PATCH 003/425] Trigger CI for https://github.com/leanprover/lean4/pull/5323 From 976206fe106f3a5d558e57b49330e47e023bad6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20B=C3=B6ving?= Date: Mon, 23 Sep 2024 14:17:12 +0200 Subject: [PATCH 004/425] use fixed dependencies --- lake-manifest.json | 8 ++++---- lakefile.lean | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index 1dac685b2c0075..8a0d9f5c248b79 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,20 +5,20 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "f51886e35b46d714c48f3f7fe0251d42c6d037b3", + "rev": "0a29bb6321a27a14533a64393ae674e741e04dff", "name": "batteries", "manifestFile": "lake-manifest.json", - "inputRev": "nightly-testing-2024-09-21", + "inputRev": "lean-pr-testing-5323", "inherited": false, "configFile": "lakefile.lean"}, {"url": "https://github.com/leanprover-community/quote4", "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "2c8ae451ce9ffc83554322b14437159c1a9703f9", + "rev": "6e87b74d74c99137adcfc6f7d47d77b65b1eb927", "name": "Qq", "manifestFile": "lake-manifest.json", - "inputRev": "master", + "inputRev": "lean-pr-testing-5323", "inherited": false, "configFile": "lakefile.lean"}, {"url": "https://github.com/leanprover-community/aesop", diff --git a/lakefile.lean b/lakefile.lean index b5908fbaf2a694..002a86ba00e612 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -7,8 +7,8 @@ open Lake DSL ## Mathlib dependencies on upstream projects -/ -require "leanprover-community" / "batteries" @ git "nightly-testing-2024-09-21" -require "leanprover-community" / "Qq" @ git "master" +require "leanprover-community" / "batteries" @ git "lean-pr-testing-5323" +require "leanprover-community" / "Qq" @ git "lean-pr-testing-5323" require "leanprover-community" / "aesop" @ git "master" require "leanprover-community" / "proofwidgets" @ git "v0.0.42" require "leanprover-community" / "importGraph" @ git "main" From 45118cebb95f68c1132b0d302b6eaf9da4efe5d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20B=C3=B6ving?= Date: Mon, 23 Sep 2024 14:17:18 +0200 Subject: [PATCH 005/425] chore: fix antisymm proof --- Mathlib/Data/Char.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Data/Char.lean b/Mathlib/Data/Char.lean index 5383c65c38b2d7..69187fc4b9eb62 100644 --- a/Mathlib/Data/Char.lean +++ b/Mathlib/Data/Char.lean @@ -20,8 +20,8 @@ Provides a `LinearOrder` instance on `Char`. `Char` is the type of Unicode scala instance : LinearOrder Char where le_refl := fun _ => @le_refl ℕ _ _ le_trans := fun _ _ _ => @le_trans ℕ _ _ _ _ - le_antisymm := fun _ _ h₁ h₂ => Char.eq_of_val_eq <| UInt32.eq_of_val_eq <| Fin.ext <| - @le_antisymm ℕ _ _ _ h₁ h₂ + le_antisymm := fun _ _ h₁ h₂ => Char.eq_of_val_eq <| UInt32.eq_of_toBitVec_eq <| + BitVec.le_antisymm h₁ h₂ lt_iff_le_not_le := fun _ _ => @lt_iff_le_not_le ℕ _ _ _ le_total := fun _ _ => @le_total ℕ _ _ _ min := fun a b => if a ≤ b then a else b From bbd5d5800b0535ef93f33e0aa01d5d7a9f52ca38 Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Mon, 23 Sep 2024 13:20:24 +0000 Subject: [PATCH 006/425] Trigger CI for https://github.com/leanprover/lean4/pull/5323 From 0aa61183b0ba32a07b90fc6fb5fea72f876fde17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20B=C3=B6ving?= Date: Mon, 23 Sep 2024 16:07:13 +0200 Subject: [PATCH 007/425] steps towards fixing Data.UInt --- Mathlib/Data/UInt.lean | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Mathlib/Data/UInt.lean b/Mathlib/Data/UInt.lean index b4b7007f59abb9..1b1e670c16732a 100644 --- a/Mathlib/Data/UInt.lean +++ b/Mathlib/Data/UInt.lean @@ -22,6 +22,7 @@ cautious here. example : (0 : UInt8) = ⟨0⟩ := rfl + set_option hygiene false in run_cmd for typeName' in [`UInt8, `UInt16, `UInt32, `UInt64, `USize] do @@ -31,24 +32,24 @@ run_cmd instance neZero : NeZero size := ⟨by decide⟩ instance : Neg $typeName where - neg a := mk (-a.val) + neg a := mk ⟨-a.val⟩ instance : Pow $typeName ℕ where - pow a n := mk (a.val ^ n) + pow a n := mk ⟨a.val ^ n⟩ instance : SMul ℕ $typeName where - smul n a := mk (n • a.val) + smul n a := mk ⟨n • a.val⟩ instance : SMul ℤ $typeName where - smul z a := mk (z • a.val) + smul z a := mk ⟨z • a.val⟩ - lemma neg_def (a : $typeName) : -a = ⟨-a.val⟩ := rfl + lemma neg_def (a : $typeName) : -a = ⟨⟨-a.val⟩⟩ := rfl - lemma pow_def (a : $typeName) (n : ℕ) : a ^ n = ⟨a.val ^ n⟩ := rfl + lemma pow_def (a : $typeName) (n : ℕ) : a ^ n = ⟨⟨a.val ^ n⟩⟩ := rfl - lemma nsmul_def (n : ℕ) (a : $typeName) : n • a = ⟨n • a.val⟩ := rfl + lemma nsmul_def (n : ℕ) (a : $typeName) : n • a = ⟨⟨n • a.val⟩⟩ := rfl - lemma zsmul_def (z : ℤ) (a : $typeName) : z • a = ⟨z • a.val⟩ := rfl + lemma zsmul_def (z : ℤ) (a : $typeName) : z • a = ⟨⟨z • a.val⟩⟩ := rfl open $typeName (eq_of_val_eq) in lemma val_injective : Function.Injective val := @eq_of_val_eq @@ -75,7 +76,7 @@ run_cmd local instance instCommRing : CommRing $typeName := Function.Injective.commRing val val_injective rfl rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ => rfl) + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ => sorry) namespace CommRing attribute [scoped instance] instCommRing instNatCast instIntCast @@ -120,6 +121,6 @@ def isASCIIAlphanum (c : UInt8) : Bool := @[deprecated (since := "2024-06-06")] alias isAlphanum := isASCIIAlphanum /-- The numbers from 0 to 256 are all valid UTF-8 characters, so we can embed one in the other. -/ -def toChar (n : UInt8) : Char := ⟨n.toUInt32, .inl (n.1.2.trans (by decide))⟩ +def toChar (n : UInt8) : Char := ⟨n.toUInt32, .inl (Nat.lt_trans n.toBitVec.isLt (by decide))⟩ end UInt8 From 1b002ff7022013cbd37dd143b5d717d4560da7b6 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Tue, 24 Sep 2024 10:21:54 +1000 Subject: [PATCH 008/425] fixes for leanprover/lean4#5323 --- Mathlib/Data/UInt.lean | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mathlib/Data/UInt.lean b/Mathlib/Data/UInt.lean index 1b1e670c16732a..ddb06ac8604b83 100644 --- a/Mathlib/Data/UInt.lean +++ b/Mathlib/Data/UInt.lean @@ -22,14 +22,12 @@ cautious here. example : (0 : UInt8) = ⟨0⟩ := rfl - set_option hygiene false in run_cmd for typeName' in [`UInt8, `UInt16, `UInt32, `UInt64, `USize] do let typeName := Lean.mkIdent typeName' Lean.Elab.Command.elabCommand (← `( namespace $typeName - instance neZero : NeZero size := ⟨by decide⟩ instance : Neg $typeName where neg a := mk ⟨-a.val⟩ From 2627f102afe009df12785f9298dd67b821881643 Mon Sep 17 00:00:00 2001 From: Johan Commelin Date: Tue, 8 Oct 2024 11:47:51 +0200 Subject: [PATCH 009/425] wip --- lake-manifest.json | 4 ++-- lakefile.lean | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index 5bb5a40d2040a5..cb03203b6f6211 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,10 +5,10 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "9080a05cbfaea73ee81d426c18a9f69fa0d040d1", + "rev": "daf1ed91789811cf6bbb7bf2f4dad6b3bad8fbf4", "name": "batteries", "manifestFile": "lake-manifest.json", - "inputRev": "nightly-testing", + "inputRev": "main", "inherited": false, "configFile": "lakefile.lean"}, {"url": "https://github.com/leanprover-community/quote4", diff --git a/lakefile.lean b/lakefile.lean index 924c24ede3f60a..a4a09667f6c2b7 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -7,7 +7,7 @@ open Lake DSL ## Mathlib dependencies on upstream projects -/ -require "leanprover-community" / "batteries" @ git "nightly-testing" +require "leanprover-community" / "batteries" @ git "main" require "leanprover-community" / "Qq" @ git "master" require "leanprover-community" / "aesop" @ git "master" require "leanprover-community" / "proofwidgets" @ git "v0.0.43-pre" From 061a5b195fa7b98c1b5a5c01849a77642ea7edc3 Mon Sep 17 00:00:00 2001 From: Emily Riehl Date: Thu, 10 Oct 2024 21:35:59 +0000 Subject: [PATCH 010/425] chore(AlgebraicTopology): moved some files into SimplicialSet (#17620) The files `KanComplex.lean`, `Nerve.lean`, and `Quasicategory.lean` are moved from AlgebraicTopology into the SimplicialSet subfolder. The file `AlgebraicTopology/SimplicialSet.lean` is moved as well and renamed to`AlgebraicTopology/SimplicialSet/Basic.lean`. --- Mathlib.lean | 8 ++++---- Mathlib/AlgebraicTopology/ExtraDegeneracy.lean | 2 +- .../{SimplicialSet.lean => SimplicialSet/Basic.lean} | 0 .../AlgebraicTopology/{ => SimplicialSet}/KanComplex.lean | 2 +- Mathlib/AlgebraicTopology/SimplicialSet/Monoidal.lean | 2 +- Mathlib/AlgebraicTopology/{ => SimplicialSet}/Nerve.lean | 2 +- .../{ => SimplicialSet}/Quasicategory.lean | 2 +- Mathlib/AlgebraicTopology/SingularSet.lean | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) rename Mathlib/AlgebraicTopology/{SimplicialSet.lean => SimplicialSet/Basic.lean} (100%) rename Mathlib/AlgebraicTopology/{ => SimplicialSet}/KanComplex.lean (95%) rename Mathlib/AlgebraicTopology/{ => SimplicialSet}/Nerve.lean (96%) rename Mathlib/AlgebraicTopology/{ => SimplicialSet}/Quasicategory.lean (97%) diff --git a/Mathlib.lean b/Mathlib.lean index fc3079f804c1a2..122df323e5c60f 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -913,16 +913,16 @@ import Mathlib.AlgebraicTopology.FundamentalGroupoid.InducedMaps import Mathlib.AlgebraicTopology.FundamentalGroupoid.PUnit import Mathlib.AlgebraicTopology.FundamentalGroupoid.Product import Mathlib.AlgebraicTopology.FundamentalGroupoid.SimplyConnected -import Mathlib.AlgebraicTopology.KanComplex import Mathlib.AlgebraicTopology.MooreComplex -import Mathlib.AlgebraicTopology.Nerve -import Mathlib.AlgebraicTopology.Quasicategory import Mathlib.AlgebraicTopology.SimplexCategory import Mathlib.AlgebraicTopology.SimplicialCategory.Basic import Mathlib.AlgebraicTopology.SimplicialCategory.SimplicialObject import Mathlib.AlgebraicTopology.SimplicialObject -import Mathlib.AlgebraicTopology.SimplicialSet +import Mathlib.AlgebraicTopology.SimplicialSet.Basic +import Mathlib.AlgebraicTopology.SimplicialSet.KanComplex import Mathlib.AlgebraicTopology.SimplicialSet.Monoidal +import Mathlib.AlgebraicTopology.SimplicialSet.Nerve +import Mathlib.AlgebraicTopology.SimplicialSet.Quasicategory import Mathlib.AlgebraicTopology.SingularSet import Mathlib.AlgebraicTopology.SplitSimplicialObject import Mathlib.AlgebraicTopology.TopologicalSimplex diff --git a/Mathlib/AlgebraicTopology/ExtraDegeneracy.lean b/Mathlib/AlgebraicTopology/ExtraDegeneracy.lean index 4610e95420a71b..478287d6c7e9c8 100644 --- a/Mathlib/AlgebraicTopology/ExtraDegeneracy.lean +++ b/Mathlib/AlgebraicTopology/ExtraDegeneracy.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Joël Riou -/ import Mathlib.AlgebraicTopology.AlternatingFaceMapComplex -import Mathlib.AlgebraicTopology.SimplicialSet +import Mathlib.AlgebraicTopology.SimplicialSet.Basic import Mathlib.AlgebraicTopology.CechNerve import Mathlib.Algebra.Homology.Homotopy import Mathlib.Tactic.FinCases diff --git a/Mathlib/AlgebraicTopology/SimplicialSet.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Basic.lean similarity index 100% rename from Mathlib/AlgebraicTopology/SimplicialSet.lean rename to Mathlib/AlgebraicTopology/SimplicialSet/Basic.lean diff --git a/Mathlib/AlgebraicTopology/KanComplex.lean b/Mathlib/AlgebraicTopology/SimplicialSet/KanComplex.lean similarity index 95% rename from Mathlib/AlgebraicTopology/KanComplex.lean rename to Mathlib/AlgebraicTopology/SimplicialSet/KanComplex.lean index 73a6d4e026c32d..531bc99ebc39c9 100644 --- a/Mathlib/AlgebraicTopology/KanComplex.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/KanComplex.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Johan Commelin -/ -import Mathlib.AlgebraicTopology.SimplicialSet +import Mathlib.AlgebraicTopology.SimplicialSet.Basic /-! # Kan complexes diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Monoidal.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Monoidal.lean index 0c12ff6bec5e4c..fbee414ae5bd43 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Monoidal.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Monoidal.lean @@ -3,7 +3,7 @@ Copyright (c) 2024 Joël Riou. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Joël Riou, Jack McKoen -/ -import Mathlib.AlgebraicTopology.SimplicialSet +import Mathlib.AlgebraicTopology.SimplicialSet.Basic import Mathlib.CategoryTheory.ChosenFiniteProducts.FunctorCategory import Mathlib.CategoryTheory.Monoidal.Types.Basic diff --git a/Mathlib/AlgebraicTopology/Nerve.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Nerve.lean similarity index 96% rename from Mathlib/AlgebraicTopology/Nerve.lean rename to Mathlib/AlgebraicTopology/SimplicialSet/Nerve.lean index 611b1fea9cd222..9e299bd44fc83b 100644 --- a/Mathlib/AlgebraicTopology/Nerve.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Nerve.lean @@ -3,7 +3,7 @@ Copyright (c) 2022 Joël Riou. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Joël Riou -/ -import Mathlib.AlgebraicTopology.SimplicialSet +import Mathlib.AlgebraicTopology.SimplicialSet.Basic import Mathlib.CategoryTheory.ComposableArrows /-! diff --git a/Mathlib/AlgebraicTopology/Quasicategory.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Quasicategory.lean similarity index 97% rename from Mathlib/AlgebraicTopology/Quasicategory.lean rename to Mathlib/AlgebraicTopology/SimplicialSet/Quasicategory.lean index a2590b4c956f64..381e65660f6321 100644 --- a/Mathlib/AlgebraicTopology/Quasicategory.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Quasicategory.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Johan Commelin -/ -import Mathlib.AlgebraicTopology.KanComplex +import Mathlib.AlgebraicTopology.SimplicialSet.KanComplex /-! # Quasicategories diff --git a/Mathlib/AlgebraicTopology/SingularSet.lean b/Mathlib/AlgebraicTopology/SingularSet.lean index bc3d246833408f..d97397b1c6019c 100644 --- a/Mathlib/AlgebraicTopology/SingularSet.lean +++ b/Mathlib/AlgebraicTopology/SingularSet.lean @@ -3,7 +3,7 @@ Copyright (c) 2023 Johan Commelin. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Johan Commelin, Kim Morrison, Adam Topaz -/ -import Mathlib.AlgebraicTopology.SimplicialSet +import Mathlib.AlgebraicTopology.SimplicialSet.Basic import Mathlib.AlgebraicTopology.TopologicalSimplex import Mathlib.CategoryTheory.Limits.Presheaf import Mathlib.Topology.Category.TopCat.Limits.Basic From c413975517effe091de53c0935408a234f699dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Thu, 10 Oct 2024 23:04:25 +0000 Subject: [PATCH 011/425] =?UTF-8?q?feat(SetTheory/Ordinal/Exponential):=20?= =?UTF-8?q?`log=20b=20x=20=3D=20y=20=E2=86=94=20x=20=E2=88=88=20Set.Ico=20?= =?UTF-8?q?(b=20^=20y)=20(b=20^=20(succ=20y))`=20(#15930)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We give a nice characterization for `log b x = y`. We then use it to prove a more general version of `log_opow_mul_add`, alongside other lemmas. --- Mathlib/SetTheory/Ordinal/Exponential.lean | 72 ++++++++++++++-------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/Mathlib/SetTheory/Ordinal/Exponential.lean b/Mathlib/SetTheory/Ordinal/Exponential.lean index ca373660f3136a..25fc214a5ce321 100644 --- a/Mathlib/SetTheory/Ordinal/Exponential.lean +++ b/Mathlib/SetTheory/Ordinal/Exponential.lean @@ -226,6 +226,21 @@ theorem opow_mul (a b c : Ordinal) : a ^ (b * c) = (a ^ b) ^ c := by simp (config := { contextual := true }) only [IH] exact (opow_le_of_limit (opow_ne_zero _ a0) l).symm +theorem opow_mul_add_pos {b v : Ordinal} (hb : b ≠ 0) (u : Ordinal) (hv : v ≠ 0) (w : Ordinal) : + 0 < b ^ u * v + w := + (opow_pos u <| Ordinal.pos_iff_ne_zero.2 hb).trans_le <| + (le_mul_left _ <| Ordinal.pos_iff_ne_zero.2 hv).trans <| le_add_right _ _ + +theorem opow_mul_add_lt_opow_mul_succ {b u w : Ordinal} (v : Ordinal) (hw : w < b ^ u) : + b ^ u * v + w < b ^ u * succ v := by + rwa [mul_succ, add_lt_add_iff_left] + +theorem opow_mul_add_lt_opow_succ {b u v w : Ordinal} (hvb : v < b) (hw : w < b ^ u) : + b ^ u * v + w < b ^ succ u := by + convert (opow_mul_add_lt_opow_mul_succ v hw).trans_le + (mul_le_mul_left' (succ_le_of_lt hvb) _) using 1 + exact opow_succ b u + /-! ### Ordinal logarithm -/ @@ -402,35 +417,38 @@ theorem log_mod_opow_log_lt_log_self {b o : Ordinal} (hb : 1 < b) (ho : o ≠ 0) rw [← Ordinal.pos_iff_ne_zero] exact opow_pos _ (zero_lt_one.trans hb) -theorem opow_mul_add_pos {b v : Ordinal} (hb : b ≠ 0) (u : Ordinal) (hv : v ≠ 0) (w : Ordinal) : - 0 < b ^ u * v + w := - (opow_pos u <| Ordinal.pos_iff_ne_zero.2 hb).trans_le <| - (le_mul_left _ <| Ordinal.pos_iff_ne_zero.2 hv).trans <| le_add_right _ _ - -theorem opow_mul_add_lt_opow_mul_succ {b u w : Ordinal} (v : Ordinal) (hw : w < b ^ u) : - b ^ u * v + w < b ^ u * succ v := by rwa [mul_succ, add_lt_add_iff_left] - -theorem opow_mul_add_lt_opow_succ {b u v w : Ordinal} (hvb : v < b) (hw : w < b ^ u) : - b ^ u * v + w < b ^ succ u := by - convert (opow_mul_add_lt_opow_mul_succ v hw).trans_le (mul_le_mul_left' (succ_le_of_lt hvb) _) - using 1 - exact opow_succ b u - -theorem log_opow_mul_add {b u v w : Ordinal} (hb : 1 < b) (hv : v ≠ 0) (hvb : v < b) - (hw : w < b ^ u) : log b (b ^ u * v + w) = u := by - have hne' := (opow_mul_add_pos (zero_lt_one.trans hb).ne' u hv w).ne' - by_contra! hne - cases' lt_or_gt_of_ne hne with h h - · rw [← lt_opow_iff_log_lt hb hne'] at h - exact h.not_le ((le_mul_left _ (Ordinal.pos_iff_ne_zero.2 hv)).trans (le_add_right _ _)) - · conv at h => change u < log b (b ^ u * v + w) - rw [← succ_le_iff, ← opow_le_iff_le_log hb hne'] at h - exact (not_lt_of_le h) (opow_mul_add_lt_opow_succ hvb hw) +theorem log_eq_iff {b x : Ordinal} (hb : 1 < b) (hx : x ≠ 0) (y : Ordinal) : + log b x = y ↔ b ^ y ≤ x ∧ x < b ^ succ y := by + constructor + · rintro rfl + use opow_log_le_self b hx, lt_opow_succ_log_self hb x + · rintro ⟨hx₁, hx₂⟩ + apply le_antisymm + · rwa [← lt_succ_iff, ← lt_opow_iff_log_lt hb hx] + · rwa [← opow_le_iff_le_log hb hx] + +theorem log_opow_mul_add {b u v w : Ordinal} (hb : 1 < b) (hv : v ≠ 0) (hw : w < b ^ u) : + log b (b ^ u * v + w) = u + log b v := by + rw [log_eq_iff hb] + · constructor + · rw [opow_add] + exact (mul_le_mul_left' (opow_log_le_self b hv) _).trans (le_add_right _ w) + · apply (add_lt_add_left hw _).trans_le + rw [← mul_succ, ← add_succ, opow_add] + apply mul_le_mul_left' + rw [succ_le_iff] + exact lt_opow_succ_log_self hb _ + · exact fun h ↦ mul_ne_zero (opow_ne_zero u (bot_lt_of_lt hb).ne') hv <| + left_eq_zero_of_add_eq_zero h + +theorem log_opow_mul {b v : Ordinal} (hb : 1 < b) (u : Ordinal) (hv : v ≠ 0) : + log b (b ^ u * v) = u + log b v := by + simpa using log_opow_mul_add hb hv (opow_pos u (bot_lt_of_lt hb)) theorem log_opow {b : Ordinal} (hb : 1 < b) (x : Ordinal) : log b (b ^ x) = x := by - convert log_opow_mul_add hb zero_ne_one.symm hb (opow_pos x (zero_lt_one.trans hb)) - using 1 - rw [add_zero, mul_one] + convert log_opow_mul hb x zero_ne_one.symm using 1 + · rw [mul_one] + · rw [log_one_right, add_zero] theorem div_opow_log_pos (b : Ordinal) {o : Ordinal} (ho : o ≠ 0) : 0 < o / (b ^ log b o) := by rcases eq_zero_or_pos b with (rfl | hb) From 1cc075db4232c2842fc938697d677f91aaba6a96 Mon Sep 17 00:00:00 2001 From: sgouezel Date: Fri, 11 Oct 2024 06:22:37 +0000 Subject: [PATCH 012/425] feat: remove the `SmoothManifoldWithCorners` assumption in the definition of tangent spaces (#17616) Currently, the definition of the tangent space to a manifold includes (as a nolinted unused parameter) the assumption that the manifold is smooth. However, many statements make sense without this assumption (notably differentiability statements), and including it forces to include a lot of machinery on smooth bundles in the definition of `MDifferentiableWithinAt`, say. We remove the assumption from the definition. This makes it possible to remove the assumption `SmoothManifoldWithCorners` from a bunch of statements (including some where it is clearly irrelevant), and disentangle our import structure, without any bad consequence as far as I can tell. There is nothing added or removed in this PR, just moving things around and removing `[SmoothManifoldWithCorners I M]` assumptions. --- Mathlib.lean | 1 + .../Complex/UpperHalfPlane/Manifold.lean | 1 + .../Geometry/Manifold/ContMDiffMFDeriv.lean | 2 +- Mathlib/Geometry/Manifold/Diffeomorph.lean | 2 - Mathlib/Geometry/Manifold/IntegralCurve.lean | 8 ++- Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean | 34 --------- Mathlib/Geometry/Manifold/MFDeriv/Basic.lean | 18 ++--- Mathlib/Geometry/Manifold/MFDeriv/Defs.lean | 3 +- .../Manifold/MFDeriv/SpecificFunctions.lean | 6 +- .../Geometry/Manifold/MFDeriv/Tangent.lean | 64 +++++++++++++++++ .../Manifold/MFDeriv/UniqueDifferential.lean | 14 ++-- .../Manifold/SmoothManifoldWithCorners.lean | 65 ++++++++++++++++- .../Manifold/VectorBundle/SmoothSection.lean | 3 +- .../Manifold/VectorBundle/Tangent.lean | 71 ++++--------------- 14 files changed, 170 insertions(+), 122 deletions(-) create mode 100644 Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean diff --git a/Mathlib.lean b/Mathlib.lean index 122df323e5c60f..0a722b92eb92ef 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2773,6 +2773,7 @@ import Mathlib.Geometry.Manifold.MFDeriv.Basic import Mathlib.Geometry.Manifold.MFDeriv.Defs import Mathlib.Geometry.Manifold.MFDeriv.FDeriv import Mathlib.Geometry.Manifold.MFDeriv.SpecificFunctions +import Mathlib.Geometry.Manifold.MFDeriv.Tangent import Mathlib.Geometry.Manifold.MFDeriv.UniqueDifferential import Mathlib.Geometry.Manifold.Metrizable import Mathlib.Geometry.Manifold.PartitionOfUnity diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Manifold.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Manifold.lean index f3d8eacb2243d3..2bc3767cffe152 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Manifold.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Manifold.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Chris Birkbeck -/ import Mathlib.Analysis.Complex.UpperHalfPlane.Topology +import Mathlib.Geometry.Manifold.ContMDiff.Atlas import Mathlib.Geometry.Manifold.MFDeriv.Basic /-! diff --git a/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean b/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean index 0b4140f98c392c..98fc2cc47a1e1c 100644 --- a/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean +++ b/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean @@ -3,7 +3,7 @@ Copyright (c) 2020 Sébastien Gouëzel. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Sébastien Gouëzel, Floris van Doorn -/ -import Mathlib.Geometry.Manifold.MFDeriv.UniqueDifferential +import Mathlib.Geometry.Manifold.MFDeriv.Tangent import Mathlib.Geometry.Manifold.ContMDiffMap /-! diff --git a/Mathlib/Geometry/Manifold/Diffeomorph.lean b/Mathlib/Geometry/Manifold/Diffeomorph.lean index 07f8ab47bb49f9..425037472ff7a1 100644 --- a/Mathlib/Geometry/Manifold/Diffeomorph.lean +++ b/Mathlib/Geometry/Manifold/Diffeomorph.lean @@ -383,8 +383,6 @@ end end Constructions -variable [SmoothManifoldWithCorners I M] [SmoothManifoldWithCorners J N] - theorem uniqueMDiffOn_image_aux (h : M ≃ₘ^n⟮I, J⟯ N) (hn : 1 ≤ n) {s : Set M} (hs : UniqueMDiffOn I s) : UniqueMDiffOn J (h '' s) := by convert hs.uniqueMDiffOn_preimage (h.toPartialHomeomorph_mdifferentiable hn) diff --git a/Mathlib/Geometry/Manifold/IntegralCurve.lean b/Mathlib/Geometry/Manifold/IntegralCurve.lean index 76b954315da827..b16bd2c24cde97 100644 --- a/Mathlib/Geometry/Manifold/IntegralCurve.lean +++ b/Mathlib/Geometry/Manifold/IntegralCurve.lean @@ -6,7 +6,7 @@ Authors: Winston Yin import Mathlib.Analysis.ODE.Gronwall import Mathlib.Analysis.ODE.PicardLindelof import Mathlib.Geometry.Manifold.InteriorBoundary -import Mathlib.Geometry.Manifold.MFDeriv.Atlas +import Mathlib.Geometry.Manifold.MFDeriv.Tangent /-! # Integral curves of vector fields on a manifold @@ -65,7 +65,7 @@ open Function Set variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℝ E H} - {M : Type*} [TopologicalSpace M] [ChartedSpace H M] [SmoothManifoldWithCorners I M] + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] /-- If `γ : ℝ → M` is $C^1$ on `s : Set ℝ` and `v` is a vector field on `M`, `IsIntegralCurveOn γ v s` means `γ t` is tangent to `v (γ t)` for all `t ∈ s`. The value of `γ` @@ -150,6 +150,7 @@ lemma IsIntegralCurveAt.continuousAt (hγ : IsIntegralCurveAt γ v t₀) : lemma IsIntegralCurve.continuous (hγ : IsIntegralCurve γ v) : Continuous γ := continuous_iff_continuousAt.mpr fun _ ↦ (hγ.isIntegralCurveOn univ).continuousAt (mem_univ _) +variable [SmoothManifoldWithCorners I M] in /-- If `γ` is an integral curve of a vector field `v`, then `γ t` is tangent to `v (γ t)` when expressed in the local chart around the initial point `γ t₀`. -/ lemma IsIntegralCurveOn.hasDerivAt (hγ : IsIntegralCurveOn γ v s) {t : ℝ} (ht : t ∈ s) @@ -168,6 +169,7 @@ lemma IsIntegralCurveOn.hasDerivAt (hγ : IsIntegralCurveOn γ v s) {t : ℝ} (h mfderiv_chartAt_eq_tangentCoordChange I hsrc] rfl +variable [SmoothManifoldWithCorners I M] in lemma IsIntegralCurveAt.eventually_hasDerivAt (hγ : IsIntegralCurveAt γ v t₀) : ∀ᶠ t in 𝓝 t₀, HasDerivAt ((extChartAt I (γ t₀)) ∘ γ) (tangentCoordChange I (γ t) (γ t₀) (γ t) (v (γ t))) t := by @@ -304,7 +306,7 @@ end Scaling section ExistUnique -variable (t₀) {x₀ : M} +variable [SmoothManifoldWithCorners I M] (t₀) {x₀ : M} /-- Existence of local integral curves for a $C^1$ vector field at interior points of a smooth manifold. -/ diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean b/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean index 908659feaf54ac..cbdbcb8afc3911 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean @@ -127,37 +127,6 @@ theorem mdifferentiable_of_mem_atlas (h : e ∈ atlas H M) : e.MDifferentiable I theorem mdifferentiable_chart (x : M) : (chartAt H x).MDifferentiable I I := mdifferentiable_of_mem_atlas _ (chart_mem_atlas _ _) -/-- 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 = - (TotalSpace.toProd _ _).symm - ((chartAt (ModelProd H E) p : TangentBundle I M → ModelProd H E) q) := by - dsimp [tangentMap] - rw [MDifferentiableAt.mfderiv] - · rfl - · exact mdifferentiableAt_atlas _ (chart_mem_atlas _ _) h - -/-- The derivative of the inverse of the chart at a base point is the inverse of 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_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 = - (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)] - simp only [ContinuousLinearMap.coe_coe, TangentBundle.chartAt, h, tangentBundleCore, - mfld_simps, (· ∘ ·)] - -- `simp` fails to apply `PartialEquiv.prod_symm` with `ModelProd` - congr - exact ((chartAt H (TotalSpace.proj p)).right_inv h).symm - -lemma mfderiv_chartAt_eq_tangentCoordChange {x y : M} (hsrc : x ∈ (chartAt H y).source) : - mfderiv I I (chartAt H y) x = tangentCoordChange I x y x := by - have := mdifferentiableAt_atlas I (ChartedSpace.chart_mem_atlas _) hsrc - simp [mfderiv, if_pos this, Function.comp_assoc] - end Charts @@ -176,9 +145,6 @@ protected theorem mdifferentiableAt {x : M} (hx : x ∈ e.source) : MDifferentia theorem mdifferentiableAt_symm {x : M'} (hx : x ∈ e.target) : MDifferentiableAt I' I e.symm x := (he.2 x hx).mdifferentiableAt (e.open_target.mem_nhds hx) -variable [SmoothManifoldWithCorners I M] [SmoothManifoldWithCorners I' M'] - [SmoothManifoldWithCorners I'' M''] - theorem symm_comp_deriv {x : M} (hx : x ∈ e.source) : (mfderiv I' I e.symm (e x)).comp (mfderiv I I' e x) = ContinuousLinearMap.id 𝕜 (TangentSpace I x) := by diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean b/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean index 724f241edb6784..077f6308962443 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Sébastien Gouëzel, Floris van Doorn -/ import Mathlib.Geometry.Manifold.MFDeriv.Defs +import Mathlib.Geometry.Manifold.ContMDiff.Defs /-! # Basic properties of the manifold Fréchet derivative @@ -21,6 +22,8 @@ mimicking the API for Fréchet derivatives. noncomputable section +assert_not_exists tangentBundleCore + open scoped Topology Manifold open Set Bundle @@ -256,22 +259,17 @@ theorem writtenInExtChartAt_comp (h : ContinuousWithinAt f s x) : (h.preimage_mem_nhdsWithin (extChartAt_source_mem_nhds _ _))) mfld_set_tac -/- We name the typeclass variables related to `SmoothManifoldWithCorners` structure as they are -necessary in lemmas mentioning the derivative, but not in lemmas about differentiability, so we -want to include them or omit them when necessary. -/ -variable [Is : SmoothManifoldWithCorners I M] [I's : SmoothManifoldWithCorners I' M'] - [I''s : SmoothManifoldWithCorners I'' M''] - {f' f₀' f₁' : TangentSpace I x →L[𝕜] TangentSpace I' (f x)} +variable {f' f₀' f₁' : TangentSpace I x →L[𝕜] TangentSpace I' (f x)} {g' : TangentSpace I' (f x) →L[𝕜] TangentSpace I'' (g (f x))} /-- `UniqueMDiffWithinAt` achieves its goal: it implies the uniqueness of the derivative. -/ -nonrec theorem UniqueMDiffWithinAt.eq (U : UniqueMDiffWithinAt I s x) +protected nonrec theorem UniqueMDiffWithinAt.eq (U : UniqueMDiffWithinAt I s x) (h : HasMFDerivWithinAt I I' f s x f') (h₁ : HasMFDerivWithinAt I I' f s x f₁') : f' = f₁' := by -- Porting note: didn't need `convert` because of finding instances by unification convert U.eq h.2 h₁.2 -theorem UniqueMDiffOn.eq (U : UniqueMDiffOn I s) (hx : x ∈ s) (h : HasMFDerivWithinAt I I' f s x f') - (h₁ : HasMFDerivWithinAt I I' f s x f₁') : f' = f₁' := +protected theorem UniqueMDiffOn.eq (U : UniqueMDiffOn I 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₁ /-! @@ -280,6 +278,7 @@ theorem UniqueMDiffOn.eq (U : UniqueMDiffOn I s) (hx : x ∈ s) (h : HasMFDerivW We mimic the API for functions between vector spaces -/ +variable [SmoothManifoldWithCorners I M] [SmoothManifoldWithCorners I' M'] in /-- One can reformulate differentiability within a set at a point as continuity within this set at this point, and differentiability in any chart containing that point. -/ theorem mdifferentiableWithinAt_iff_of_mem_source {x' : M} {y : M'} @@ -418,6 +417,7 @@ theorem mfderivWithin_eq_mfderiv (hs : UniqueMDiffWithinAt I s x) (h : MDifferen rw [← mfderivWithin_univ] exact mfderivWithin_subset (subset_univ _) hs h.mdifferentiableWithinAt +variable [SmoothManifoldWithCorners I M] [SmoothManifoldWithCorners I' M'] in theorem mdifferentiableAt_iff_of_mem_source {x' : M} {y : M'} (hx : x' ∈ (chartAt H x).source) (hy : f x' ∈ (chartAt H' y).source) : MDifferentiableAt I I' f x' ↔ diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Defs.lean b/Mathlib/Geometry/Manifold/MFDeriv/Defs.lean index 5ffa095f95ed99..88e42b72004c08 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Defs.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Defs.lean @@ -3,7 +3,8 @@ Copyright (c) 2020 Sébastien Gouëzel. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Sébastien Gouëzel, Floris van Doorn -/ -import Mathlib.Geometry.Manifold.VectorBundle.Tangent +import Mathlib.Geometry.Manifold.SmoothManifoldWithCorners +import Mathlib.Geometry.Manifold.LocalInvariantProperties /-! # The derivative of functions between smooth manifolds diff --git a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean index 5e0909b901206c..e80b20105886e0 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean @@ -28,12 +28,12 @@ section SpecificFunctions variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) {M : Type*} - [TopologicalSpace M] [ChartedSpace H M] [SmoothManifoldWithCorners I M] {E' : Type*} + [TopologicalSpace M] [ChartedSpace H M] {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] {H' : Type*} [TopologicalSpace H'] (I' : ModelWithCorners 𝕜 E' H') {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] - [SmoothManifoldWithCorners I' M'] {E'' : Type*} [NormedAddCommGroup E''] [NormedSpace 𝕜 E''] + {E'' : Type*} [NormedAddCommGroup E''] [NormedSpace 𝕜 E''] {H'' : Type*} [TopologicalSpace H''] (I'' : ModelWithCorners 𝕜 E'' H'') {M'' : Type*} - [TopologicalSpace M''] [ChartedSpace H'' M''] [SmoothManifoldWithCorners I'' M''] + [TopologicalSpace M''] [ChartedSpace H'' M''] namespace ContinuousLinearMap diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean b/Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean new file mode 100644 index 00000000000000..b1da80bc215d6d --- /dev/null +++ b/Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean @@ -0,0 +1,64 @@ +/- +Copyright (c) 2024 Sébastien Gouëzel. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Sébastien Gouëzel, Floris van Doorn +-/ +import Mathlib.Geometry.Manifold.MFDeriv.Atlas +import Mathlib.Geometry.Manifold.MFDeriv.UniqueDifferential +import Mathlib.Geometry.Manifold.VectorBundle.Tangent + +/-! +# Derivatives of maps in the tangent bundle + +This file contains properties of derivatives which need the manifold structure of the tangent +bundle. Notably, it includes formulas for the tangent maps to charts, and unique differentiability +statements for subsets of the tangent bundle. +-/ + +open Bundle + +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'] + (I' : ModelWithCorners 𝕜 E' H') {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] + {E'' : Type*} [NormedAddCommGroup E''] [NormedSpace 𝕜 E''] {H'' : Type*} [TopologicalSpace H''] + (I'' : ModelWithCorners 𝕜 E'' H'') {M'' : Type*} [TopologicalSpace M''] [ChartedSpace H'' M''] + [SmoothManifoldWithCorners I M] + +/-- 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 = + (TotalSpace.toProd _ _).symm + ((chartAt (ModelProd H E) p : TangentBundle I M → ModelProd H E) q) := by + dsimp [tangentMap] + rw [MDifferentiableAt.mfderiv] + · rfl + · exact mdifferentiableAt_atlas _ (chart_mem_atlas _ _) h + +/-- The derivative of the inverse of the chart at a base point is the inverse of 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_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 = + (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)] + simp only [ContinuousLinearMap.coe_coe, TangentBundle.chartAt, h, tangentBundleCore, + mfld_simps, (· ∘ ·)] + -- `simp` fails to apply `PartialEquiv.prod_symm` with `ModelProd` + congr + exact ((chartAt H (TotalSpace.proj p)).right_inv h).symm + +lemma mfderiv_chartAt_eq_tangentCoordChange {x y : M} (hsrc : x ∈ (chartAt H y).source) : + mfderiv I I (chartAt H y) x = tangentCoordChange I x y x := by + have := mdifferentiableAt_atlas I (ChartedSpace.chart_mem_atlas _) hsrc + simp [mfderiv, if_pos 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. -/ +theorem UniqueMDiffOn.tangentBundle_proj_preimage {s : Set M} (hs : UniqueMDiffOn I s) : + UniqueMDiffOn I.tangent (π E (TangentSpace I) ⁻¹' s) := + hs.smooth_bundle_preimage _ diff --git a/Mathlib/Geometry/Manifold/MFDeriv/UniqueDifferential.lean b/Mathlib/Geometry/Manifold/MFDeriv/UniqueDifferential.lean index d73131e3999fb6..076089056c1236 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/UniqueDifferential.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/UniqueDifferential.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Sébastien Gouëzel, Floris van Doorn -/ import Mathlib.Geometry.Manifold.MFDeriv.Atlas +import Mathlib.Geometry.Manifold.VectorBundle.Basic /-! # Unique derivative sets in manifolds @@ -32,11 +33,10 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCom [TopologicalSpace M] [ChartedSpace H M] {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] {H' : Type*} [TopologicalSpace H'] {I' : ModelWithCorners 𝕜 E' H'} {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] - [SmoothManifoldWithCorners I' M'] {M'' : Type*} [TopologicalSpace M''] [ChartedSpace H' M''] + {M'' : Type*} [TopologicalSpace M''] [ChartedSpace H' M''] {s : Set M} {x : M} section -variable [SmoothManifoldWithCorners I M] /-- 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`. -/ @@ -82,6 +82,7 @@ theorem UniqueMDiffOn.uniqueMDiffOn_preimage (hs : UniqueMDiffOn I s) {e : Parti (he : e.MDifferentiable I I') : UniqueMDiffOn I' (e.target ∩ e.symm ⁻¹' s) := fun _x hx ↦ e.right_inv hx.1 ▸ (hs _ hx.2).preimage_partialHomeomorph he (e.map_target hx.1) +variable [SmoothManifoldWithCorners I 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) : @@ -94,6 +95,7 @@ theorem UniqueMDiffOn.uniqueDiffOn_target_inter (hs : UniqueMDiffOn I s) (x : M) (fun y hy ↦ hasMFDerivWithinAt_extChartAt I hy.2) fun y hy ↦ ((mdifferentiable_chart _ _).mfderiv_surjective hy.2).denseRange +variable [SmoothManifoldWithCorners I 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. -/ @@ -120,8 +122,6 @@ theorem Trivialization.mdifferentiable (e : Trivialization F (π F Z)) [MemTrivi e.toPartialHomeomorph.MDifferentiable (I.prod 𝓘(𝕜, F)) (I.prod 𝓘(𝕜, F)) := ⟨(e.smoothOn I).mdifferentiableOn, (e.smoothOn_symm I).mdifferentiableOn⟩ -variable [SmoothManifoldWithCorners I M] - theorem UniqueMDiffWithinAt.smooth_bundle_preimage {p : TotalSpace F Z} (hs : UniqueMDiffWithinAt I s p.proj) : UniqueMDiffWithinAt (I.prod 𝓘(𝕜, F)) (π F Z ⁻¹' s) p := by @@ -147,10 +147,4 @@ theorem UniqueMDiffOn.smooth_bundle_preimage (hs : UniqueMDiffOn I s) : UniqueMDiffOn (I.prod 𝓘(𝕜, F)) (π F Z ⁻¹' s) := fun _p hp ↦ (hs _ hp).smooth_bundle_preimage -/-- The preimage under the projection from the tangent bundle of a set with unique differential in -the basis also has unique differential. -/ -theorem UniqueMDiffOn.tangentBundle_proj_preimage (hs : UniqueMDiffOn I s) : - UniqueMDiffOn I.tangent (π E (TangentSpace I) ⁻¹' s) := - hs.smooth_bundle_preimage _ - end UniqueMDiff diff --git a/Mathlib/Geometry/Manifold/SmoothManifoldWithCorners.lean b/Mathlib/Geometry/Manifold/SmoothManifoldWithCorners.lean index 1b1e09a2916125..55142a16d8ebd1 100644 --- a/Mathlib/Geometry/Manifold/SmoothManifoldWithCorners.lean +++ b/Mathlib/Geometry/Manifold/SmoothManifoldWithCorners.lean @@ -3,9 +3,11 @@ 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 -/ -import Mathlib.Geometry.Manifold.ChartedSpace +import Mathlib.Analysis.Convex.Normed import Mathlib.Analysis.Normed.Module.FiniteDimension import Mathlib.Analysis.Calculus.ContDiff.Basic +import Mathlib.Data.Bundle +import Mathlib.Geometry.Manifold.ChartedSpace /-! # Smooth manifolds (possibly with boundary or corners) @@ -80,6 +82,14 @@ but again in product manifolds the natural model with corners will not be this o one (and they are not defeq as `(fun p : E × F ↦ (p.1, p.2))` is not defeq to the identity). So, it is important to use the above incantation to maximize the applicability of theorems. +We also define `TangentSpace I (x : M)` as a type synonym of `E`, and `TangentBundle I M` as a +type synonym for `Π (x : M), TangentSpace I x` (in the form of an +abbrev of `Bundle.TotalSpace E (TangentSpace I : M → Type _)`). Apart from basic typeclasses on +`TangentSpace I x`, nothing is proved about them in this file, but it is useful to have them +available as definitions early on to get a clean import structure below. The smooth bundle structure +is defined in `VectorBundle.Tangent`, while the definition is used to talk about manifold +derivatives in `MFDeriv.Basic`, and neither file needs import the other. + ## Implementation notes We want to talk about manifolds modelled on a vector space, but also on manifolds with @@ -1363,3 +1373,56 @@ lemma Manifold.locallyCompact_of_finiteDimensional exact ChartedSpace.locallyCompactSpace H M end Topology + +section TangentSpace + +/- We define the tangent space to `M` modelled on `I : ModelWithCorners 𝕜 E H` as a type synonym +for `E`. This is enough to define linear maps between tangent spaces, for instance derivatives, +but the interesting part is to define a manifold structure on the whole tangent bundle, which +requires that `M` is a smooth manifold with corners. The definition is put here to avoid importing +all the smooth bundle structure when defining manifold derivatives. -/ + +set_option linter.unusedVariables false in +/-- The tangent space at a point of the manifold `M`. It is just `E`. We could use instead +`(tangentBundleCore I M).to_topological_vector_bundle_core.fiber x`, but we use `E` to help the +kernel. +-/ +@[nolint unusedArguments] +def TangentSpace {𝕜 : Type*} [NontriviallyNormedField 𝕜] + {E : Type u} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] (_x : M) : Type u := E +-- Porting note: was deriving TopologicalSpace, AddCommGroup, TopologicalAddGroup + +/- In general, the definition of `TangentSpace` is not reducible, so that type class inference +does not pick wrong instances. We record the right instances for them. -/ + +variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] + {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] + {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} + +instance : TopologicalSpace (TangentSpace I x) := inferInstanceAs (TopologicalSpace E) +instance : AddCommGroup (TangentSpace I x) := inferInstanceAs (AddCommGroup E) +instance : TopologicalAddGroup (TangentSpace I x) := inferInstanceAs (TopologicalAddGroup E) +instance : Module 𝕜 (TangentSpace I x) := inferInstanceAs (Module 𝕜 E) +instance : Inhabited (TangentSpace I x) := ⟨0⟩ + +variable (M) in +-- is empty if the base manifold is empty +/-- The tangent bundle to a smooth manifold, as a Sigma type. Defined in terms of +`Bundle.TotalSpace` to be able to put a suitable topology on it. -/ +-- Porting note(#5171): was nolint has_nonempty_instance +abbrev TangentBundle := + Bundle.TotalSpace E (TangentSpace I : M → Type _) + +end TangentSpace + +section Real + +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] + {I : ModelWithCorners ℝ E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {x : M} + +instance : PathConnectedSpace (TangentSpace I x) := inferInstanceAs (PathConnectedSpace E) + +end Real diff --git a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean index b8beaedc2623ed..10e4fe0a92fe3f 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean @@ -3,9 +3,10 @@ Copyright (c) 2023 Heather Macbeth. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Heather Macbeth, Floris van Doorn -/ +import Mathlib.Geometry.Manifold.Algebra.LieGroup import Mathlib.Geometry.Manifold.MFDeriv.Basic import Mathlib.Topology.ContinuousMap.Basic -import Mathlib.Geometry.Manifold.Algebra.LieGroup +import Mathlib.Geometry.Manifold.VectorBundle.Basic /-! # Smooth sections diff --git a/Mathlib/Geometry/Manifold/VectorBundle/Tangent.lean b/Mathlib/Geometry/Manifold/VectorBundle/Tangent.lean index df7663e67c7acc..7c85fe03db9fda 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/Tangent.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/Tangent.lean @@ -4,16 +4,19 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Floris van Doorn, Heather Macbeth -/ import Mathlib.Geometry.Manifold.VectorBundle.Basic -import Mathlib.Analysis.Convex.Normed /-! # Tangent bundles This file defines the tangent bundle as a smooth vector bundle. -Let `M` be a smooth manifold with corners with model `I` on `(E, H)`. We define the tangent bundle -of `M` using the `VectorBundleCore` construction indexed by the charts of `M` with fibers `E`. -Given two charts `i, j : PartialHomeomorph M H`, the coordinate change between `i` and `j` -at a point `x : M` is the derivative of the composite +Let `M` be a manifold with model `I` on `(E, H)`. The tangent space `TangentSpace I (x : M)` has +already been defined as a type synonym for `E`, and the tangent bundle `TangentBundle I M` as an +abbrev of `Bundle.TotalSpace E (TangentSpace I : M → Type _)`. + +In this file, when `M` is smooth, we construct a smooth vector bundle structure +on `TangentBundle I M` using the `VectorBundleCore` construction indexed by the charts of `M` +with fibers `E`. Given two charts `i, j : PartialHomeomorph M H`, the coordinate change +between `i` and `j` at a point `x : M` is the derivative of the composite ``` I.symm i.symm j I E -----> H -----> M --> H --> E @@ -21,12 +24,13 @@ E -----> H -----> M --> H --> E within the set `range I ⊆ E` at `I (i x) : E`. This defines a smooth vector bundle `TangentBundle` with fibers `TangentSpace`. -## Main definitions +## Main definitions and results -* `TangentSpace I M x` is the fiber of the tangent bundle at `x : M`, which is defined to be `E`. +* `tangentBundleCore I M` is the vector bundle core for the tangent bundle over `M`. -* `TangentBundle I M` is the total space of `TangentSpace I M`, proven to be a smooth vector - bundle. +* When `M` is a smooth manifold with corners, `TangentBundle I M` has a smooth vector bundle +structure over `M`. In particular, it is a topological space, a vector bundle, a fiber bundle, +and a smooth manifold. -/ @@ -65,7 +69,7 @@ variable (M) open SmoothManifoldWithCorners /-- Let `M` be a smooth manifold with corners with model `I` on `(E, H)`. -Then `VectorBundleCore I M` is the vector bundle core for the tangent bundle over `M`. +Then `tangentBundleCore I M` is the vector bundle core for the tangent bundle over `M`. It is indexed by the atlas of `M`, with fiber `E` and its change of coordinates from the chart `i` to the chart `j` at point `x : M` is the derivative of the composite ``` @@ -164,49 +168,12 @@ lemma continuousOn_tangentCoordChange (x y : M) : ContinuousOn (tangentCoordChan end tangentCoordChange -/-- The tangent space at a point of the manifold `M`. It is just `E`. We could use instead -`(tangentBundleCore I M).to_topological_vector_bundle_core.fiber x`, but we use `E` to help the -kernel. --/ -@[nolint unusedArguments] -def TangentSpace {𝕜} [NontriviallyNormedField 𝕜] {E} [NormedAddCommGroup E] [NormedSpace 𝕜 E] - {H} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) {M} [TopologicalSpace M] - [ChartedSpace H M] [SmoothManifoldWithCorners I M] (_x : M) : Type* := E --- Porting note: was deriving TopologicalSpace, AddCommGroup, TopologicalAddGroup - -instance {x : M} : TopologicalSpace (TangentSpace I x) := inferInstanceAs (TopologicalSpace E) -instance {x : M} : AddCommGroup (TangentSpace I x) := inferInstanceAs (AddCommGroup E) -instance {x : M} : TopologicalAddGroup (TangentSpace I x) := inferInstanceAs (TopologicalAddGroup E) - variable (M) --- is empty if the base manifold is empty -/-- The tangent bundle to a smooth manifold, as a Sigma type. Defined in terms of -`Bundle.TotalSpace` to be able to put a suitable topology on it. -/ --- Porting note(#5171): was nolint has_nonempty_instance -abbrev TangentBundle := - Bundle.TotalSpace E (TangentSpace I : M → Type _) - local notation "TM" => TangentBundle I M section TangentBundleInstances -/- In general, the definition of `TangentSpace` is not reducible, so that type class inference -does not pick wrong instances. In this section, we record the right instances for -them, noting in particular that the tangent bundle is a smooth manifold. -/ -section - -variable {M} -variable (x : M) - -instance : Module 𝕜 (TangentSpace I x) := inferInstanceAs (Module 𝕜 E) - -instance : Inhabited (TangentSpace I x) := ⟨0⟩ - --- Porting note: removed unneeded ContinuousAdd (TangentSpace I x) - -end - instance : TopologicalSpace TM := (tangentBundleCore I M).toTopologicalSpace @@ -448,13 +415,3 @@ theorem inTangentCoordinates_eq (f : N → M) (g : N → M') (ϕ : N → E →L[ end inTangentCoordinates end General - -section Real - -variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H] - {I : ModelWithCorners ℝ E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] - [SmoothManifoldWithCorners I M] - -instance {x : M} : PathConnectedSpace (TangentSpace I x) := by unfold TangentSpace; infer_instance - -end Real From 3390e4047ee730f33011a787e6523bbbaf3cf8ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 11 Oct 2024 07:20:54 +0000 Subject: [PATCH 013/425] chore: rename `condCount` to `uniformOn` (#17571) --- Archive/Wiedijk100Theorems/BallotProblem.lean | 52 ++-- .../Wiedijk100Theorems/BirthdayProblem.lean | 8 +- Mathlib.lean | 2 +- Mathlib/Probability/CondCount.lean | 186 ------------- Mathlib/Probability/UniformOn.lean | 244 ++++++++++++++++++ scripts/no_lints_prime_decls.txt | 2 +- 6 files changed, 276 insertions(+), 218 deletions(-) delete mode 100644 Mathlib/Probability/CondCount.lean create mode 100644 Mathlib/Probability/UniformOn.lean diff --git a/Archive/Wiedijk100Theorems/BallotProblem.lean b/Archive/Wiedijk100Theorems/BallotProblem.lean index 8fbd5b2ecf7d05..3fd05ee140379c 100644 --- a/Archive/Wiedijk100Theorems/BallotProblem.lean +++ b/Archive/Wiedijk100Theorems/BallotProblem.lean @@ -3,7 +3,7 @@ Copyright (c) 2022 Bhavik Mehta, Kexing Ying. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Bhavik Mehta, Kexing Ying -/ -import Mathlib.Probability.CondCount +import Mathlib.Probability.UniformOn /-! # Ballot problem @@ -188,21 +188,21 @@ theorem count_countedSequence : ∀ p q : ℕ, count (countedSequence p q) = (p theorem first_vote_pos : ∀ p q, - 0 < p + q → condCount (countedSequence p q : Set (List ℤ)) {l | l.headI = 1} = p / (p + q) + 0 < p + q → uniformOn (countedSequence p q : Set (List ℤ)) {l | l.headI = 1} = p / (p + q) | p + 1, 0, _ => by - rw [counted_right_zero, condCount_singleton] + rw [counted_right_zero, uniformOn_singleton] simp [ENNReal.div_self _ _, List.replicate_succ] | 0, q + 1, _ => by - rw [counted_left_zero, condCount_singleton] + rw [counted_left_zero, uniformOn_singleton] simp only [List.replicate, Nat.add_eq, add_zero, mem_setOf_eq, List.headI_cons, Nat.cast_zero, ENNReal.zero_div, ite_eq_right_iff] decide | p + 1, q + 1, _ => by simp_rw [counted_succ_succ] - rw [← condCount_disjoint_union ((countedSequence_finite _ _).image _) + rw [← uniformOn_disjoint_union ((countedSequence_finite _ _).image _) ((countedSequence_finite _ _).image _) (disjoint_bits _ _), ← counted_succ_succ, - condCount_eq_one_of ((countedSequence_finite p (q + 1)).image _) + uniformOn_eq_one_of ((countedSequence_finite p (q + 1)).image _) ((countedSequence_nonempty _ _).image _)] · have : List.cons (-1) '' countedSequence (p + 1) q ∩ {l : List ℤ | l.headI = 1} = ∅ := by ext @@ -215,7 +215,7 @@ theorem first_vote_pos : List.cons 1 '' countedSequence p (q + 1) := by rw [inter_eq_right, counted_succ_succ] exact subset_union_left - rw [(condCount_eq_zero_iff <| (countedSequence_finite _ _).image _).2 this, condCount, + rw [(uniformOn_eq_zero_iff <| (countedSequence_finite _ _).image _).2 this, uniformOn, cond_apply _ list_int_measurableSet, hint, count_injective_image List.cons_injective, count_countedSequence, count_countedSequence, one_mul, zero_mul, add_zero, Nat.cast_add, Nat.cast_one, mul_comm, ← div_eq_mul_inv, ENNReal.div_eq_div_iff] @@ -230,17 +230,17 @@ theorem headI_mem_of_nonempty {α : Type*} [Inhabited α] : ∀ {l : List α} (_ | x::l, _ => List.mem_cons_self x l theorem first_vote_neg (p q : ℕ) (h : 0 < p + q) : - condCount (countedSequence p q) {l | l.headI = 1}ᶜ = q / (p + q) := by + uniformOn (countedSequence p q) {l | l.headI = 1}ᶜ = q / (p + q) := by have h' : (p + q : ℝ≥0∞) ≠ 0 := mod_cast h.ne' - have := condCount_compl + have := uniformOn_compl {l : List ℤ | l.headI = 1}ᶜ (countedSequence_finite p q) (countedSequence_nonempty p q) rw [compl_compl, first_vote_pos _ _ h] at this rw [ENNReal.eq_sub_of_add_eq _ this, ENNReal.eq_div_iff, ENNReal.mul_sub, mul_one, ENNReal.mul_div_cancel', ENNReal.add_sub_cancel_left] all_goals simp_all [ENNReal.div_eq_top] -theorem ballot_same (p : ℕ) : condCount (countedSequence (p + 1) (p + 1)) staysPositive = 0 := by - rw [condCount_eq_zero_iff (countedSequence_finite _ _), eq_empty_iff_forall_not_mem] +theorem ballot_same (p : ℕ) : uniformOn (countedSequence (p + 1) (p + 1)) staysPositive = 0 := by + rw [uniformOn_eq_zero_iff (countedSequence_finite _ _), eq_empty_iff_forall_not_mem] rintro x ⟨hx, t⟩ apply ne_of_gt (t x _ x.suffix_refl) · simpa using sum_of_mem_countedSequence hx @@ -248,9 +248,9 @@ theorem ballot_same (p : ℕ) : condCount (countedSequence (p + 1) (p + 1)) stay rw [length_of_mem_countedSequence hx] exact Nat.add_pos_left (Nat.succ_pos _) _ -theorem ballot_edge (p : ℕ) : condCount (countedSequence (p + 1) 0) staysPositive = 1 := by +theorem ballot_edge (p : ℕ) : uniformOn (countedSequence (p + 1) 0) staysPositive = 1 := by rw [counted_right_zero] - refine condCount_eq_one_of (finite_singleton _) (singleton_nonempty _) ?_ + refine uniformOn_eq_one_of (finite_singleton _) (singleton_nonempty _) ?_ refine singleton_subset_iff.2 fun l hl₁ hl₂ => List.sum_pos _ (fun x hx => ?_) hl₁ rw [List.eq_of_mem_replicate (hl₂.mem hx)] norm_num @@ -267,9 +267,9 @@ theorem countedSequence_int_pos_counted_succ_succ (p q : ℕ) : norm_num theorem ballot_pos (p q : ℕ) : - condCount (countedSequence (p + 1) (q + 1) ∩ {l | l.headI = 1}) staysPositive = - condCount (countedSequence p (q + 1)) staysPositive := by - rw [countedSequence_int_pos_counted_succ_succ, condCount, condCount, + uniformOn (countedSequence (p + 1) (q + 1) ∩ {l | l.headI = 1}) staysPositive = + uniformOn (countedSequence p (q + 1)) staysPositive := by + rw [countedSequence_int_pos_counted_succ_succ, uniformOn, uniformOn, cond_apply _ list_int_measurableSet, cond_apply _ list_int_measurableSet, count_injective_image List.cons_injective] congr 1 @@ -294,9 +294,9 @@ theorem countedSequence_int_neg_counted_succ_succ (p q : ℕ) : norm_num theorem ballot_neg (p q : ℕ) (qp : q < p) : - condCount (countedSequence (p + 1) (q + 1) ∩ {l | l.headI = 1}ᶜ) staysPositive = - condCount (countedSequence (p + 1) q) staysPositive := by - rw [countedSequence_int_neg_counted_succ_succ, condCount, condCount, + uniformOn (countedSequence (p + 1) (q + 1) ∩ {l | l.headI = 1}ᶜ) staysPositive = + uniformOn (countedSequence (p + 1) q) staysPositive := by + rw [countedSequence_int_neg_counted_succ_succ, uniformOn, uniformOn, cond_apply _ list_int_measurableSet, cond_apply _ list_int_measurableSet, count_injective_image List.cons_injective] congr 1 @@ -310,7 +310,7 @@ theorem ballot_neg (p q : ℕ) (qp : q < p) : exact List.cons_injective theorem ballot_problem' : - ∀ q p, q < p → (condCount (countedSequence p q) staysPositive).toReal = (p - q) / (p + q) := by + ∀ q p, q < p → (uniformOn (countedSequence p q) staysPositive).toReal = (p - q) / (p + q) := by classical apply Nat.diag_induction · intro p @@ -322,12 +322,12 @@ theorem ballot_problem' : rw [div_self] exact Nat.cast_add_one_ne_zero p · intro q p qp h₁ h₂ - haveI := condCount_isProbabilityMeasure + haveI := uniformOn_isProbabilityMeasure (countedSequence_finite p (q + 1)) (countedSequence_nonempty _ _) - haveI := condCount_isProbabilityMeasure + haveI := uniformOn_isProbabilityMeasure (countedSequence_finite (p + 1) q) (countedSequence_nonempty _ _) have h₃ : p + 1 + (q + 1) > 0 := Nat.add_pos_left (Nat.succ_pos _) _ - rw [← condCount_add_compl_eq {l : List ℤ | l.headI = 1} _ (countedSequence_finite _ _), + rw [← uniformOn_add_compl_eq {l : List ℤ | l.headI = 1} _ (countedSequence_finite _ _), first_vote_pos _ _ h₃, first_vote_neg _ _ h₃, ballot_pos, ballot_neg _ _ qp] rw [ENNReal.toReal_add, ENNReal.toReal_mul, ENNReal.toReal_mul, ← Nat.cast_add, ENNReal.toReal_div, ENNReal.toReal_div, ENNReal.toReal_nat, ENNReal.toReal_nat, @@ -349,12 +349,12 @@ theorem ballot_problem' : /-- The ballot problem. -/ theorem ballot_problem : - ∀ q p, q < p → condCount (countedSequence p q) staysPositive = (p - q) / (p + q) := by + ∀ q p, q < p → uniformOn (countedSequence p q) staysPositive = (p - q) / (p + q) := by intro q p qp haveI := - condCount_isProbabilityMeasure (countedSequence_finite p q) (countedSequence_nonempty _ _) + uniformOn_isProbabilityMeasure (countedSequence_finite p q) (countedSequence_nonempty _ _) have : - (condCount (countedSequence p q) staysPositive).toReal = + (uniformOn (countedSequence p q) staysPositive).toReal = ((p - q) / (p + q) : ℝ≥0∞).toReal := by rw [ballot_problem' q p qp] rw [ENNReal.toReal_div, ← Nat.cast_add, ← Nat.cast_add, ENNReal.toReal_nat, diff --git a/Archive/Wiedijk100Theorems/BirthdayProblem.lean b/Archive/Wiedijk100Theorems/BirthdayProblem.lean index 67d6fec9989c30..02a04dd66801e8 100644 --- a/Archive/Wiedijk100Theorems/BirthdayProblem.lean +++ b/Archive/Wiedijk100Theorems/BirthdayProblem.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Eric Rodriguez -/ import Mathlib.Data.Fintype.CardEmbedding -import Mathlib.Probability.CondCount +import Mathlib.Probability.UniformOn import Mathlib.Probability.Notation /-! @@ -52,15 +52,15 @@ instance : MeasurableSingletonClass (Fin m) := /- We then endow the space with a canonical measure, which is called ℙ. We define this to be the conditional counting measure. -/ noncomputable instance : MeasureSpace (Fin n → Fin m) := - ⟨condCount Set.univ⟩ + ⟨uniformOn Set.univ⟩ -- The canonical measure on `Fin n → Fin m` is a probability measure (except on an empty space). instance : IsProbabilityMeasure (ℙ : Measure (Fin n → Fin (m + 1))) := - condCount_isProbabilityMeasure Set.finite_univ Set.univ_nonempty + uniformOn_isProbabilityMeasure Set.finite_univ Set.univ_nonempty theorem FinFin.measure_apply {s : Set <| Fin n → Fin m} : ℙ s = |s.toFinite.toFinset| / ‖Fin n → Fin m‖ := by - erw [condCount_univ, Measure.count_apply_finite] + erw [uniformOn_univ, Measure.count_apply_finite] /-- **Birthday Problem**: first probabilistic interpretation. -/ theorem birthday_measure : diff --git a/Mathlib.lean b/Mathlib.lean index 0a722b92eb92ef..4e58a18529e1dc 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3761,7 +3761,6 @@ import Mathlib.Order.Zorn import Mathlib.Order.ZornAtoms import Mathlib.Probability.BorelCantelli import Mathlib.Probability.CDF -import Mathlib.Probability.CondCount import Mathlib.Probability.ConditionalExpectation import Mathlib.Probability.ConditionalProbability import Mathlib.Probability.Density @@ -3819,6 +3818,7 @@ import Mathlib.Probability.Process.HittingTime import Mathlib.Probability.Process.PartitionFiltration import Mathlib.Probability.Process.Stopping import Mathlib.Probability.StrongLaw +import Mathlib.Probability.UniformOn import Mathlib.Probability.Variance import Mathlib.RepresentationTheory.Action.Basic import Mathlib.RepresentationTheory.Action.Concrete diff --git a/Mathlib/Probability/CondCount.lean b/Mathlib/Probability/CondCount.lean deleted file mode 100644 index 1ea9812d6c2f66..00000000000000 --- a/Mathlib/Probability/CondCount.lean +++ /dev/null @@ -1,186 +0,0 @@ -/- -Copyright (c) 2022 Kexing Ying. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Kexing Ying, Bhavik Mehta --/ -import Mathlib.Probability.ConditionalProbability -import Mathlib.MeasureTheory.Measure.Count - -/-! -# Classical probability - -The classical formulation of probability states that the probability of an event occurring in a -finite probability space is the ratio of that event to all possible events. -This notion can be expressed with measure theory using -the counting measure. In particular, given the sets `s` and `t`, we define the probability of `t` -occurring in `s` to be `|s|⁻¹ * |s ∩ t|`. With this definition, we recover the probability over -the entire sample space when `s = Set.univ`. - -Classical probability is often used in combinatorics and we prove some useful lemmas in this file -for that purpose. - -## Main definition - -* `ProbabilityTheory.condCount`: given a set `s`, `condCount s` is the counting measure - conditioned on `s`. This is a probability measure when `s` is finite and nonempty. - -## Notes - -The original aim of this file is to provide a measure theoretic method of describing the -probability an element of a set `s` satisfies some predicate `P`. Our current formulation still -allow us to describe this by abusing the definitional equality of sets and predicates by simply -writing `condCount s P`. We should avoid this however as none of the lemmas are written for -predicates. --/ - - -noncomputable section - -open ProbabilityTheory - -open MeasureTheory MeasurableSpace - -namespace ProbabilityTheory - -variable {Ω : Type*} [MeasurableSpace Ω] - -/-- Given a set `s`, `condCount s` is the counting measure conditioned on `s`. In particular, -`condCount s t` is the proportion of `s` that is contained in `t`. - -This is a probability measure when `s` is finite and nonempty and is given by -`ProbabilityTheory.condCount_isProbabilityMeasure`. -/ -def condCount (s : Set Ω) : Measure Ω := - Measure.count[|s] - -instance {s : Set Ω} : IsZeroOrProbabilityMeasure (condCount s) := by - unfold condCount; infer_instance - -@[simp] -theorem condCount_empty_meas : (condCount ∅ : Measure Ω) = 0 := by simp [condCount] - -theorem condCount_empty {s : Set Ω} : condCount s ∅ = 0 := by simp - -theorem finite_of_condCount_ne_zero {s t : Set Ω} (h : condCount s t ≠ 0) : s.Finite := by - by_contra hs' - simp [condCount, cond, Measure.count_apply_infinite hs'] at h - -theorem condCount_univ [Fintype Ω] {s : Set Ω} : - condCount Set.univ s = Measure.count s / Fintype.card Ω := by - rw [condCount, cond_apply _ MeasurableSet.univ, ← ENNReal.div_eq_inv_mul, Set.univ_inter] - congr - rw [← Finset.coe_univ, Measure.count_apply, Finset.univ.tsum_subtype' fun _ => (1 : ENNReal)] - · simp [Finset.card_univ] - · exact (@Finset.coe_univ Ω _).symm ▸ MeasurableSet.univ - -variable [MeasurableSingletonClass Ω] - -theorem condCount_isProbabilityMeasure {s : Set Ω} (hs : s.Finite) (hs' : s.Nonempty) : - IsProbabilityMeasure (condCount s) := by - apply cond_isProbabilityMeasure_of_finite - · exact fun h => hs'.ne_empty <| Measure.empty_of_count_eq_zero h - · exact (Measure.count_apply_lt_top.2 hs).ne - -theorem condCount_singleton (ω : Ω) (t : Set Ω) [Decidable (ω ∈ t)] : - condCount {ω} t = if ω ∈ t then 1 else 0 := by - rw [condCount, cond_apply _ (measurableSet_singleton ω), Measure.count_singleton, inv_one, - one_mul] - split_ifs - · rw [(by simpa : ({ω} : Set Ω) ∩ t = {ω}), Measure.count_singleton] - · rw [(by simpa : ({ω} : Set Ω) ∩ t = ∅), Measure.count_empty] - -variable {s t u : Set Ω} - -theorem condCount_inter_self (hs : s.Finite) : condCount s (s ∩ t) = condCount s t := by - rw [condCount, cond_inter_self _ hs.measurableSet] - -theorem condCount_self (hs : s.Finite) (hs' : s.Nonempty) : condCount s s = 1 := by - rw [condCount, cond_apply _ hs.measurableSet, Set.inter_self, ENNReal.inv_mul_cancel] - · exact fun h => hs'.ne_empty <| Measure.empty_of_count_eq_zero h - · exact (Measure.count_apply_lt_top.2 hs).ne - -theorem condCount_eq_one_of (hs : s.Finite) (hs' : s.Nonempty) (ht : s ⊆ t) : - condCount s t = 1 := by - haveI := condCount_isProbabilityMeasure hs hs' - refine eq_of_le_of_not_lt prob_le_one ?_ - rw [not_lt, ← condCount_self hs hs'] - exact measure_mono ht - -theorem pred_true_of_condCount_eq_one (h : condCount s t = 1) : s ⊆ t := by - have hsf := finite_of_condCount_ne_zero (by rw [h]; exact one_ne_zero) - rw [condCount, cond_apply _ hsf.measurableSet, mul_comm] at h - replace h := ENNReal.eq_inv_of_mul_eq_one_left h - rw [inv_inv, Measure.count_apply_finite _ hsf, Measure.count_apply_finite _ (hsf.inter_of_left _), - Nat.cast_inj] at h - suffices s ∩ t = s by exact this ▸ fun x hx => hx.2 - rw [← @Set.Finite.toFinset_inj _ _ _ (hsf.inter_of_left _) hsf] - exact Finset.eq_of_subset_of_card_le (Set.Finite.toFinset_mono s.inter_subset_left) h.ge - -theorem condCount_eq_zero_iff (hs : s.Finite) : condCount s t = 0 ↔ s ∩ t = ∅ := by - simp [condCount, cond_apply _ hs.measurableSet, Measure.count_apply_eq_top, Set.not_infinite.2 hs, - Measure.count_apply_finite _ (hs.inter_of_left _)] - -theorem condCount_of_univ (hs : s.Finite) (hs' : s.Nonempty) : condCount s Set.univ = 1 := - condCount_eq_one_of hs hs' s.subset_univ - -theorem condCount_inter (hs : s.Finite) : - condCount s (t ∩ u) = condCount (s ∩ t) u * condCount s t := by - by_cases hst : s ∩ t = ∅ - · rw [hst, condCount_empty_meas, Measure.coe_zero, Pi.zero_apply, zero_mul, - condCount_eq_zero_iff hs, ← Set.inter_assoc, hst, Set.empty_inter] - rw [condCount, condCount, cond_apply _ hs.measurableSet, cond_apply _ hs.measurableSet, - cond_apply _ (hs.inter_of_left _).measurableSet, mul_comm _ (Measure.count (s ∩ t)), - ← mul_assoc, mul_comm _ (Measure.count (s ∩ t)), ← mul_assoc, ENNReal.mul_inv_cancel, one_mul, - mul_comm, Set.inter_assoc] - · rwa [← Measure.count_eq_zero_iff] at hst - · exact (Measure.count_apply_lt_top.2 <| hs.inter_of_left _).ne - -theorem condCount_inter' (hs : s.Finite) : - condCount s (t ∩ u) = condCount (s ∩ u) t * condCount s u := by - rw [← Set.inter_comm] - exact condCount_inter hs - -theorem condCount_union (hs : s.Finite) (htu : Disjoint t u) : - condCount s (t ∪ u) = condCount s t + condCount s u := by - rw [condCount, cond_apply _ hs.measurableSet, cond_apply _ hs.measurableSet, - cond_apply _ hs.measurableSet, Set.inter_union_distrib_left, measure_union, mul_add] - exacts [htu.mono inf_le_right inf_le_right, (hs.inter_of_left _).measurableSet] - -theorem condCount_compl (t : Set Ω) (hs : s.Finite) (hs' : s.Nonempty) : - condCount s t + condCount s tᶜ = 1 := by - rw [← condCount_union hs disjoint_compl_right, Set.union_compl_self, - (condCount_isProbabilityMeasure hs hs').measure_univ] - -theorem condCount_disjoint_union (hs : s.Finite) (ht : t.Finite) (hst : Disjoint s t) : - condCount s u * condCount (s ∪ t) s + condCount t u * condCount (s ∪ t) t = - condCount (s ∪ t) u := by - rcases s.eq_empty_or_nonempty with (rfl | hs') <;> rcases t.eq_empty_or_nonempty with (rfl | ht') - · simp - · simp [condCount_self ht ht'] - · simp [condCount_self hs hs'] - rw [condCount, condCount, condCount, cond_apply _ hs.measurableSet, - cond_apply _ ht.measurableSet, cond_apply _ (hs.union ht).measurableSet, - cond_apply _ (hs.union ht).measurableSet, cond_apply _ (hs.union ht).measurableSet] - conv_lhs => - rw [Set.union_inter_cancel_left, Set.union_inter_cancel_right, - mul_comm (Measure.count (s ∪ t))⁻¹, mul_comm (Measure.count (s ∪ t))⁻¹, ← mul_assoc, - ← mul_assoc, mul_comm _ (Measure.count s), mul_comm _ (Measure.count t), ← mul_assoc, - ← mul_assoc] - rw [ENNReal.mul_inv_cancel, ENNReal.mul_inv_cancel, one_mul, one_mul, ← add_mul, ← measure_union, - Set.union_inter_distrib_right, mul_comm] - exacts [hst.mono inf_le_left inf_le_left, (ht.inter_of_left _).measurableSet, - Measure.count_ne_zero ht', (Measure.count_apply_lt_top.2 ht).ne, Measure.count_ne_zero hs', - (Measure.count_apply_lt_top.2 hs).ne] - -/-- A version of the law of total probability for counting probabilities. -/ -theorem condCount_add_compl_eq (u t : Set Ω) (hs : s.Finite) : - condCount (s ∩ u) t * condCount s u + condCount (s ∩ uᶜ) t * condCount s uᶜ = - condCount s t := by - -- Porting note: The original proof used `conv_rhs`. However, that tactic timed out. - have : condCount s t = (condCount (s ∩ u) t * condCount (s ∩ u ∪ s ∩ uᶜ) (s ∩ u) + - condCount (s ∩ uᶜ) t * condCount (s ∩ u ∪ s ∩ uᶜ) (s ∩ uᶜ)) := by - rw [condCount_disjoint_union (hs.inter_of_left _) (hs.inter_of_left _) - (disjoint_compl_right.mono inf_le_right inf_le_right), Set.inter_union_compl] - rw [this] - simp [condCount_inter_self hs] - -end ProbabilityTheory diff --git a/Mathlib/Probability/UniformOn.lean b/Mathlib/Probability/UniformOn.lean new file mode 100644 index 00000000000000..8b1de52a5055df --- /dev/null +++ b/Mathlib/Probability/UniformOn.lean @@ -0,0 +1,244 @@ +/- +Copyright (c) 2022 Kexing Ying. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Kexing Ying, Bhavik Mehta +-/ +import Mathlib.Probability.ConditionalProbability +import Mathlib.MeasureTheory.Measure.Count + +/-! +# Classical probability + +The classical formulation of probability states that the probability of an event occurring in a +finite probability space is the ratio of that event to all possible events. +This notion can be expressed with measure theory using +the counting measure. In particular, given the sets `s` and `t`, we define the probability of `t` +occurring in `s` to be `|s|⁻¹ * |s ∩ t|`. With this definition, we recover the probability over +the entire sample space when `s = Set.univ`. + +Classical probability is often used in combinatorics and we prove some useful lemmas in this file +for that purpose. + +## Main definition + +* `ProbabilityTheory.uniformOn`: given a set `s`, `uniformOn s` is the counting measure + conditioned on `s`. This is a probability measure when `s` is finite and nonempty. + +## Notes + +The original aim of this file is to provide a measure theoretic method of describing the +probability an element of a set `s` satisfies some predicate `P`. Our current formulation still +allow us to describe this by abusing the definitional equality of sets and predicates by simply +writing `uniformOn s P`. We should avoid this however as none of the lemmas are written for +predicates. +-/ + + +noncomputable section + +open ProbabilityTheory + +open MeasureTheory MeasurableSpace + +namespace ProbabilityTheory + +variable {Ω : Type*} [MeasurableSpace Ω] + +/-- Given a set `s`, `uniformOn s` is the uniform measure on `s`, defined as the counting measure +conditioned by `s`. One should think of `uniformOn s t` as the proportion of `s` that is contained +in `t`. + +This is a probability measure when `s` is finite and nonempty and is given by +`ProbabilityTheory.uniformOn_isProbabilityMeasure`. -/ +def uniformOn (s : Set Ω) : Measure Ω := + Measure.count[|s] + +@[deprecated (since := "2024-10-09")] +noncomputable alias condCount := uniformOn + +instance {s : Set Ω} : IsZeroOrProbabilityMeasure (uniformOn s) := by + unfold uniformOn; infer_instance + +@[simp] +theorem uniformOn_empty_meas : (uniformOn ∅ : Measure Ω) = 0 := by simp [uniformOn] + +@[deprecated (since := "2024-10-09")] +alias condCount_empty_meas := uniformOn_empty_meas + +theorem uniformOn_empty {s : Set Ω} : uniformOn s ∅ = 0 := by simp + +@[deprecated (since := "2024-10-09")] +alias condCount_empty := uniformOn_empty + +theorem finite_of_uniformOn_ne_zero {s t : Set Ω} (h : uniformOn s t ≠ 0) : s.Finite := by + by_contra hs' + simp [uniformOn, cond, Measure.count_apply_infinite hs'] at h + +@[deprecated (since := "2024-10-09")] +alias finite_of_condCount_ne_zero := finite_of_uniformOn_ne_zero + +theorem uniformOn_univ [Fintype Ω] {s : Set Ω} : + uniformOn Set.univ s = Measure.count s / Fintype.card Ω := by + rw [uniformOn, cond_apply _ MeasurableSet.univ, ← ENNReal.div_eq_inv_mul, Set.univ_inter] + congr + rw [← Finset.coe_univ, Measure.count_apply, Finset.univ.tsum_subtype' fun _ => (1 : ENNReal)] + · simp [Finset.card_univ] + · exact (@Finset.coe_univ Ω _).symm ▸ MeasurableSet.univ + +@[deprecated (since := "2024-10-09")] +alias condCount_univ := uniformOn_univ + +variable [MeasurableSingletonClass Ω] + +theorem uniformOn_isProbabilityMeasure {s : Set Ω} (hs : s.Finite) (hs' : s.Nonempty) : + IsProbabilityMeasure (uniformOn s) := by + apply cond_isProbabilityMeasure_of_finite + · exact fun h => hs'.ne_empty <| Measure.empty_of_count_eq_zero h + · exact (Measure.count_apply_lt_top.2 hs).ne + +@[deprecated (since := "2024-10-09")] +alias condCount_isProbabilityMeasure := uniformOn_isProbabilityMeasure + +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, + one_mul] + split_ifs + · rw [(by simpa : ({ω} : Set Ω) ∩ t = {ω}), Measure.count_singleton] + · rw [(by simpa : ({ω} : Set Ω) ∩ t = ∅), Measure.count_empty] + +@[deprecated (since := "2024-10-09")] +alias condCount_singleton := uniformOn_singleton + +variable {s t u : Set Ω} + +theorem uniformOn_inter_self (hs : s.Finite) : uniformOn s (s ∩ t) = uniformOn s t := by + rw [uniformOn, cond_inter_self _ hs.measurableSet] + +@[deprecated (since := "2024-10-09")] +alias condCount_inter_self := uniformOn_inter_self + +theorem uniformOn_self (hs : s.Finite) (hs' : s.Nonempty) : uniformOn s s = 1 := by + rw [uniformOn, cond_apply _ hs.measurableSet, Set.inter_self, ENNReal.inv_mul_cancel] + · exact fun h => hs'.ne_empty <| Measure.empty_of_count_eq_zero h + · exact (Measure.count_apply_lt_top.2 hs).ne + +@[deprecated (since := "2024-10-09")] +alias condCount_self := uniformOn_self + +theorem uniformOn_eq_one_of (hs : s.Finite) (hs' : s.Nonempty) (ht : s ⊆ t) : + uniformOn s t = 1 := by + haveI := uniformOn_isProbabilityMeasure hs hs' + refine eq_of_le_of_not_lt prob_le_one ?_ + rw [not_lt, ← uniformOn_self hs hs'] + exact measure_mono ht + +@[deprecated (since := "2024-10-09")] +alias condCount_eq_one_of := uniformOn_eq_one_of + +theorem pred_true_of_uniformOn_eq_one (h : uniformOn s t = 1) : s ⊆ t := by + have hsf := finite_of_uniformOn_ne_zero (by rw [h]; exact one_ne_zero) + rw [uniformOn, cond_apply _ hsf.measurableSet, mul_comm] at h + replace h := ENNReal.eq_inv_of_mul_eq_one_left h + rw [inv_inv, Measure.count_apply_finite _ hsf, Measure.count_apply_finite _ (hsf.inter_of_left _), + Nat.cast_inj] at h + suffices s ∩ t = s by exact this ▸ fun x hx => hx.2 + rw [← @Set.Finite.toFinset_inj _ _ _ (hsf.inter_of_left _) hsf] + exact Finset.eq_of_subset_of_card_le (Set.Finite.toFinset_mono s.inter_subset_left) h.ge + +@[deprecated (since := "2024-10-09")] +alias pred_true_of_condCount_eq_one := pred_true_of_uniformOn_eq_one + +theorem uniformOn_eq_zero_iff (hs : s.Finite) : uniformOn s t = 0 ↔ s ∩ t = ∅ := by + simp [uniformOn, cond_apply _ hs.measurableSet, Measure.count_apply_eq_top, Set.not_infinite.2 hs, + Measure.count_apply_finite _ (hs.inter_of_left _)] + +@[deprecated (since := "2024-10-09")] +alias condCount_eq_zero_iff := uniformOn_eq_zero_iff + +theorem uniformOn_of_univ (hs : s.Finite) (hs' : s.Nonempty) : uniformOn s Set.univ = 1 := + uniformOn_eq_one_of hs hs' s.subset_univ + +@[deprecated (since := "2024-10-09")] +alias condCount_of_univ := uniformOn_of_univ + +theorem uniformOn_inter (hs : s.Finite) : + uniformOn s (t ∩ u) = uniformOn (s ∩ t) u * uniformOn s t := by + by_cases hst : s ∩ t = ∅ + · rw [hst, uniformOn_empty_meas, Measure.coe_zero, Pi.zero_apply, zero_mul, + uniformOn_eq_zero_iff hs, ← Set.inter_assoc, hst, Set.empty_inter] + rw [uniformOn, uniformOn, cond_apply _ hs.measurableSet, cond_apply _ hs.measurableSet, + cond_apply _ (hs.inter_of_left _).measurableSet, mul_comm _ (Measure.count (s ∩ t)), + ← mul_assoc, mul_comm _ (Measure.count (s ∩ t)), ← mul_assoc, ENNReal.mul_inv_cancel, one_mul, + mul_comm, Set.inter_assoc] + · rwa [← Measure.count_eq_zero_iff] at hst + · exact (Measure.count_apply_lt_top.2 <| hs.inter_of_left _).ne + +@[deprecated (since := "2024-10-09")] +alias condCount_inter := uniformOn_inter + +theorem uniformOn_inter' (hs : s.Finite) : + uniformOn s (t ∩ u) = uniformOn (s ∩ u) t * uniformOn s u := by + rw [← Set.inter_comm] + exact uniformOn_inter hs + +@[deprecated (since := "2024-10-09")] +alias condCount_inter' := uniformOn_inter' + +theorem uniformOn_union (hs : s.Finite) (htu : Disjoint t u) : + uniformOn s (t ∪ u) = uniformOn s t + uniformOn s u := by + rw [uniformOn, cond_apply _ hs.measurableSet, cond_apply _ hs.measurableSet, + cond_apply _ hs.measurableSet, Set.inter_union_distrib_left, measure_union, mul_add] + exacts [htu.mono inf_le_right inf_le_right, (hs.inter_of_left _).measurableSet] + +@[deprecated (since := "2024-10-09")] +alias condCount_union := uniformOn_union + +theorem uniformOn_compl (t : Set Ω) (hs : s.Finite) (hs' : s.Nonempty) : + uniformOn s t + uniformOn s tᶜ = 1 := by + rw [← uniformOn_union hs disjoint_compl_right, Set.union_compl_self, + (uniformOn_isProbabilityMeasure hs hs').measure_univ] + +@[deprecated (since := "2024-10-09")] +alias condCount_compl := uniformOn_compl + +theorem uniformOn_disjoint_union (hs : s.Finite) (ht : t.Finite) (hst : Disjoint s t) : + uniformOn s u * uniformOn (s ∪ t) s + uniformOn t u * uniformOn (s ∪ t) t = + uniformOn (s ∪ t) u := by + rcases s.eq_empty_or_nonempty with (rfl | hs') <;> rcases t.eq_empty_or_nonempty with (rfl | ht') + · simp + · simp [uniformOn_self ht ht'] + · simp [uniformOn_self hs hs'] + rw [uniformOn, uniformOn, uniformOn, cond_apply _ hs.measurableSet, + cond_apply _ ht.measurableSet, cond_apply _ (hs.union ht).measurableSet, + cond_apply _ (hs.union ht).measurableSet, cond_apply _ (hs.union ht).measurableSet] + conv_lhs => + rw [Set.union_inter_cancel_left, Set.union_inter_cancel_right, + mul_comm (Measure.count (s ∪ t))⁻¹, mul_comm (Measure.count (s ∪ t))⁻¹, ← mul_assoc, + ← mul_assoc, mul_comm _ (Measure.count s), mul_comm _ (Measure.count t), ← mul_assoc, + ← mul_assoc] + rw [ENNReal.mul_inv_cancel, ENNReal.mul_inv_cancel, one_mul, one_mul, ← add_mul, ← measure_union, + Set.union_inter_distrib_right, mul_comm] + exacts [hst.mono inf_le_left inf_le_left, (ht.inter_of_left _).measurableSet, + Measure.count_ne_zero ht', (Measure.count_apply_lt_top.2 ht).ne, Measure.count_ne_zero hs', + (Measure.count_apply_lt_top.2 hs).ne] + +@[deprecated (since := "2024-10-09")] +alias condCount_disjoint_union := uniformOn_disjoint_union + +/-- A version of the law of total probability for counting probabilities. -/ +theorem uniformOn_add_compl_eq (u t : Set Ω) (hs : s.Finite) : + uniformOn (s ∩ u) t * uniformOn s u + uniformOn (s ∩ uᶜ) t * uniformOn s uᶜ = + uniformOn s t := by + -- Porting note: The original proof used `conv_rhs`. However, that tactic timed out. + have : uniformOn s t = (uniformOn (s ∩ u) t * uniformOn (s ∩ u ∪ s ∩ uᶜ) (s ∩ u) + + uniformOn (s ∩ uᶜ) t * uniformOn (s ∩ u ∪ s ∩ uᶜ) (s ∩ uᶜ)) := by + rw [uniformOn_disjoint_union (hs.inter_of_left _) (hs.inter_of_left _) + (disjoint_compl_right.mono inf_le_right inf_le_right), Set.inter_union_compl] + rw [this] + simp [uniformOn_inter_self hs] + +@[deprecated (since := "2024-10-09")] +alias condCount_add_compl_eq := uniformOn_add_compl_eq + +end ProbabilityTheory diff --git a/scripts/no_lints_prime_decls.txt b/scripts/no_lints_prime_decls.txt index 16a703c2e1780a..b2fa718c5be982 100644 --- a/scripts/no_lints_prime_decls.txt +++ b/scripts/no_lints_prime_decls.txt @@ -3929,7 +3929,7 @@ ProbabilityTheory.cgf_const' ProbabilityTheory.cgf_zero' ProbabilityTheory.cond_apply' ProbabilityTheory.cond_cond_eq_cond_inter' -ProbabilityTheory.condCount_inter' +ProbabilityTheory.uniformOn_inter' ProbabilityTheory.condexp_ae_eq_integral_condexpKernel' ProbabilityTheory.condexpKernel_ae_eq_condexp' ProbabilityTheory.CondIndepSets.condIndep' From fe48a462f51be174e492e5b1af9bbfc80235e355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 11 Oct 2024 07:51:10 +0000 Subject: [PATCH 014/425] feat: `SpecialLinearGroup n R` is finite when `R` is (#17629) From GrowthInGroups --- Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean b/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean index abb3fa721cfad4..261b976d62a387 100644 --- a/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean +++ b/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean @@ -124,6 +124,9 @@ instance : Pow (SpecialLinearGroup n R) ℕ where instance : Inhabited (SpecialLinearGroup n R) := ⟨1⟩ +instance [Fintype R] [DecidableEq R] : Fintype (SpecialLinearGroup n R) := Subtype.fintype _ +instance [Finite R] : Finite (SpecialLinearGroup n R) := Subtype.finite + /-- The transpose of a matrix in `SL(n, R)` -/ def transpose (A : SpecialLinearGroup n R) : SpecialLinearGroup n R := ⟨A.1.transpose, A.1.det_transpose ▸ A.2⟩ From 7a7d5c09605f625446d7957ab54cbe9b486f0e34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 11 Oct 2024 08:08:17 +0000 Subject: [PATCH 015/425] chore(Data/List): make `List.map_const'` be simp (#17622) `List.map_const` is already simp but stated using `Function.const` rather than a plain lambda, so it never fires in my application. From LeanCamCombi --- Mathlib/Data/List/Basic.lean | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Mathlib/Data/List/Basic.lean b/Mathlib/Data/List/Basic.lean index d3d29ac80d33d6..267f3bbefd34ef 100644 --- a/Mathlib/Data/List/Basic.lean +++ b/Mathlib/Data/List/Basic.lean @@ -887,6 +887,11 @@ theorem get_set_of_ne {l : List α} {i j : ℕ} (h : i ≠ j) (a : α) /-! ### map -/ +-- `List.map_const` (the version with `Function.const` instead of a lambda) is already tagged +-- `simp` in Core +-- TODO: Upstream the tagging to Core? +attribute [simp] map_const' + @[deprecated (since := "2024-06-21")] alias map_congr := map_congr_left theorem bind_pure_eq_map (f : α → β) (l : List α) : l.bind (pure ∘ f) = map f l := From 44f45a8a0ae57f50cede148fc260cafedd71c554 Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Fri, 11 Oct 2024 08:24:28 +0000 Subject: [PATCH 016/425] chore: bump to nightly-2024-10-11 --- lean-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lean-toolchain b/lean-toolchain index 712a96012abe9b..101e9ee14ef77c 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-10 +leanprover/lean4:nightly-2024-10-11 From e4fa33c4f2bc49e66f5d06e91e21fe2279ad7e14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 11 Oct 2024 09:39:16 +0000 Subject: [PATCH 017/425] feat: `Finsupp.mapRange` of a surjective function is surjective (#17637) From PFR --- Mathlib/Data/Finsupp/Defs.lean | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Mathlib/Data/Finsupp/Defs.lean b/Mathlib/Data/Finsupp/Defs.lean index 11717314f657fc..17844597d0e122 100644 --- a/Mathlib/Data/Finsupp/Defs.lean +++ b/Mathlib/Data/Finsupp/Defs.lean @@ -714,6 +714,10 @@ theorem mapRange_comp (f : N → P) (hf : f 0 = 0) (f₂ : M → N) (hf₂ : f (g : α →₀ M) : mapRange (f ∘ f₂) h g = mapRange f hf (mapRange f₂ hf₂ g) := ext fun _ => rfl +@[simp] +lemma mapRange_mapRange (e₁ : N → P) (e₂ : M → N) (he₁ he₂) (f : α →₀ M) : + mapRange e₁ he₁ (mapRange e₂ he₂ f) = mapRange (e₁ ∘ e₂) (by simp [*]) f := ext fun _ ↦ rfl + theorem support_mapRange {f : M → N} {hf : f 0 = 0} {g : α →₀ M} : (mapRange f hf g).support ⊆ g.support := support_onFinset_subset @@ -730,6 +734,14 @@ theorem support_mapRange_of_injective {e : M → N} (he0 : e 0 = 0) (f : ι → simp only [Finsupp.mem_support_iff, Ne, Finsupp.mapRange_apply] exact he.ne_iff' he0 +/-- `Finsupp.mapRange` of a surjective function is surjective. -/ +lemma mapRange_surjective (e : M → N) (he₀ : e 0 = 0) (he : Surjective e) : + Surjective (Finsupp.mapRange (α := α) e he₀) := by + classical + let d (n : N) : M := if n = 0 then 0 else surjInv he n + have : RightInverse d e := fun n ↦ by by_cases h : n = 0 <;> simp [d, h, he₀, surjInv_eq he n] + exact fun f ↦ ⟨mapRange d (by simp [d]) f, by simp [this.comp_eq_id]⟩ + end MapRange /-! ### Declarations about `embDomain` -/ From c58520754383fac76d1620ff352a52bc509bc2f1 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Fri, 11 Oct 2024 10:10:17 +0000 Subject: [PATCH 018/425] chore: clean up after #17615 (#17617) This PR goes through the diff of #17615, which automatically replaced `erw` with `rw`, to clean up as follows: * delete obsolote comments * merge adjacent `rw` calls * restore old code that was commented out when it broke at some point but now works again Co-authored-by: Anne Baanen --- .../Algebra/MonoidAlgebra/ToDirectSum.lean | 8 +++- Mathlib/Algebra/Polynomial/Module/Basic.lean | 3 +- Mathlib/AlgebraicGeometry/Cover/Open.lean | 4 +- .../AlgebraicTopology/SimplexCategory.lean | 1 - .../CategoryTheory/GradedObject/Unitor.lean | 6 +-- Mathlib/CategoryTheory/Limits/Presheaf.lean | 3 +- Mathlib/CategoryTheory/Limits/VanKampen.lean | 2 +- .../CategoryTheory/Localization/SmallHom.lean | 6 +-- Mathlib/Data/Complex/Exponential.lean | 3 +- Mathlib/Data/Multiset/Fintype.lean | 3 +- .../LocallyRingedSpace/HasColimits.lean | 7 ++-- .../RingedSpace/PresheafedSpace/Gluing.lean | 18 +++++---- .../PresheafedSpace/HasColimits.lean | 6 +-- .../TensorProduct/Graded/External.lean | 4 +- Mathlib/RepresentationTheory/Character.lean | 2 +- .../GroupCohomology/Basic.lean | 1 - .../GroupCohomology/Resolution.lean | 40 ++++++++----------- Mathlib/RingTheory/EisensteinCriterion.lean | 3 +- Mathlib/RingTheory/Henselian.lean | 8 +--- Mathlib/RingTheory/Ideal/Operations.lean | 12 +++--- Mathlib/RingTheory/PowerSeries/Basic.lean | 6 +-- Mathlib/RingTheory/PowerSeries/Inverse.lean | 1 - Mathlib/RingTheory/Valuation/Integral.lean | 2 +- .../Category/CompHaus/Projective.lean | 5 ++- .../Category/Profinite/CofilteredLimit.lean | 1 - .../Category/Profinite/Projective.lean | 5 ++- .../Category/TopCat/Limits/Cofiltered.lean | 2 +- .../Category/TopCat/Limits/Pullbacks.lean | 6 +-- Mathlib/Topology/Gluing.lean | 7 +--- Mathlib/Topology/LocalAtTarget.lean | 4 +- Mathlib/Topology/Order/LawsonTopology.lean | 3 +- 31 files changed, 80 insertions(+), 102 deletions(-) diff --git a/Mathlib/Algebra/MonoidAlgebra/ToDirectSum.lean b/Mathlib/Algebra/MonoidAlgebra/ToDirectSum.lean index 111fe27da22937..aa57dcae344e6d 100644 --- a/Mathlib/Algebra/MonoidAlgebra/ToDirectSum.lean +++ b/Mathlib/Algebra/MonoidAlgebra/ToDirectSum.lean @@ -136,17 +136,21 @@ theorem toDirectSum_mul [DecidableEq ι] [AddMonoid ι] [Semiring M] (f g : AddM AddMonoidHom.mul_apply, Finsupp.singleAddHom_apply] -- This was not needed before leanprover/lean4#2644 erw [AddMonoidHom.compl₂_apply] + -- If we remove the next `rw`, the `erw` after it will complain (when we get an `erw` linter) + -- that it could be a `rw`. But the `erw` and `rw` will rewrite different occurrences. + -- So first get rid of the `rw`-able occurrences to force `erw` to do the expensive rewrite only. + rw [AddMonoidHom.coe_mk, AddMonoidHom.coe_mk] -- This was not needed before leanprover/lean4#2644 erw [AddMonoidHom.coe_mk] simp only [AddMonoidHom.coe_mk, ZeroHom.coe_mk, toDirectSum_single] -- This was not needed before leanprover/lean4#2644 dsimp - erw [AddMonoidAlgebra.single_mul_single, AddMonoidHom.coe_mk, ZeroHom.coe_mk, + rw [AddMonoidAlgebra.single_mul_single, AddMonoidHom.coe_mk, AddMonoidHom.coe_mk, ZeroHom.coe_mk, AddMonoidAlgebra.toDirectSum_single] simp only [AddMonoidHom.coe_comp, AddMonoidHom.coe_mul, AddMonoidHom.coe_mk, ZeroHom.coe_mk, Function.comp_apply, toDirectSum_single, AddMonoidHom.id_apply, Finsupp.singleAddHom_apply, AddMonoidHom.coe_mulLeft] - erw [DirectSum.of_mul_of, Mul.gMul_mul] + rw [DirectSum.of_mul_of, Mul.gMul_mul] end AddMonoidAlgebra diff --git a/Mathlib/Algebra/Polynomial/Module/Basic.lean b/Mathlib/Algebra/Polynomial/Module/Basic.lean index 18b3572cb7fb77..43595606fd85c4 100644 --- a/Mathlib/Algebra/Polynomial/Module/Basic.lean +++ b/Mathlib/Algebra/Polynomial/Module/Basic.lean @@ -312,8 +312,7 @@ noncomputable def comp (p : R[X]) : PolynomialModule R M →ₗ[R] PolynomialMod LinearMap.comp ((eval p).restrictScalars R) (map R[X] (lsingle R 0)) theorem comp_single (p : R[X]) (i : ℕ) (m : M) : comp p (single R i m) = p ^ i • single R 0 m := by - rw [comp_apply] - rw [map_single, eval_single] + rw [comp_apply, map_single, eval_single] rfl theorem comp_eval (p : R[X]) (q : PolynomialModule R M) (r : R) : diff --git a/Mathlib/AlgebraicGeometry/Cover/Open.lean b/Mathlib/AlgebraicGeometry/Cover/Open.lean index b529f28cce1a5e..c137272d6c0cea 100644 --- a/Mathlib/AlgebraicGeometry/Cover/Open.lean +++ b/Mathlib/AlgebraicGeometry/Cover/Open.lean @@ -73,7 +73,7 @@ def affineCover (X : Scheme.{u}) : OpenCover X where rw [Set.range_comp, Set.range_iff_surjective.mpr, Set.image_univ] · erw [Subtype.range_coe_subtype] exact (X.local_affine x).choose.2 - rw [← TopCat.epi_iff_surjective] -- now `erw` after #13170 + rw [← TopCat.epi_iff_surjective] change Epi ((SheafedSpace.forget _).map (LocallyRingedSpace.forgetToSheafedSpace.map _)) infer_instance @@ -136,7 +136,7 @@ def OpenCover.copy {X : Scheme.{u}} (𝒰 : OpenCover X) (J : Type*) (obj : J rw [e₂, Scheme.comp_val_base, TopCat.coe_comp, Set.range_comp, Set.range_iff_surjective.mpr, Set.image_univ, e₁.rightInverse_symm] · exact 𝒰.covers x - · rw [← TopCat.epi_iff_surjective]; infer_instance -- now `erw` after #13170 + · rw [← TopCat.epi_iff_surjective]; infer_instance -- Porting note: weirdly, even though no input is needed, `inferInstance` does not work -- `PresheafedSpace.IsOpenImmersion.comp` is marked as `instance` IsOpen := fun i => by rw [e₂]; exact PresheafedSpace.IsOpenImmersion.comp _ _ } diff --git a/Mathlib/AlgebraicTopology/SimplexCategory.lean b/Mathlib/AlgebraicTopology/SimplexCategory.lean index 34c222fb85e344..38c94b643e51d0 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory.lean @@ -802,7 +802,6 @@ theorem eq_comp_δ_of_not_surjective' {n : ℕ} {Δ : SimplexCategory} (θ : Δ simp only [len_mk, Category.assoc, comp_toOrderHom, OrderHom.comp_coe, Function.comp_apply] by_cases h' : θ.toOrderHom x ≤ i · simp only [σ, mkHom, Hom.toOrderHom_mk, OrderHom.coe_mk] - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 rw [Fin.predAbove_of_le_castSucc _ _ (by rwa [Fin.castSucc_castPred])] dsimp [δ] rw [Fin.succAbove_of_castSucc_lt i] diff --git a/Mathlib/CategoryTheory/GradedObject/Unitor.lean b/Mathlib/CategoryTheory/GradedObject/Unitor.lean index 265f2b3635c672..6b90c959e367c6 100644 --- a/Mathlib/CategoryTheory/GradedObject/Unitor.lean +++ b/Mathlib/CategoryTheory/GradedObject/Unitor.lean @@ -124,8 +124,8 @@ lemma mapBifunctorLeftUnitor_inv_naturality : rw [mapBifunctorLeftUnitor_inv_apply, mapBifunctorLeftUnitor_inv_apply, assoc, assoc, ι_mapBifunctorMapMap] dsimp - rw [Functor.map_id, NatTrans.id_app, id_comp] - erw [← NatTrans.naturality_assoc, ← NatTrans.naturality_assoc] + rw [Functor.map_id, NatTrans.id_app, id_comp, ← NatTrans.naturality_assoc, + ← NatTrans.naturality_assoc] rfl @[reassoc] @@ -242,7 +242,7 @@ lemma mapBifunctorRightUnitor_inv_naturality : ι_mapBifunctorMapMap] dsimp rw [Functor.map_id, id_comp, NatTrans.naturality_assoc] - erw [← NatTrans.naturality_assoc] + erw [← NatTrans.naturality_assoc e.inv] rfl @[reassoc] diff --git a/Mathlib/CategoryTheory/Limits/Presheaf.lean b/Mathlib/CategoryTheory/Limits/Presheaf.lean index e6974259db0520..8dd0215926fc0a 100644 --- a/Mathlib/CategoryTheory/Limits/Presheaf.lean +++ b/Mathlib/CategoryTheory/Limits/Presheaf.lean @@ -202,8 +202,7 @@ noncomputable def coconeOfRepresentable (P : Cᵒᵖ ⥤ Type v₁) : { app := fun x => yonedaEquiv.symm x.unop.2 naturality := fun {x₁ x₂} f => by dsimp - rw [comp_id] - rw [← yonedaEquiv_symm_map] + rw [comp_id, ← yonedaEquiv_symm_map] congr 1 rw [f.unop.2] } diff --git a/Mathlib/CategoryTheory/Limits/VanKampen.lean b/Mathlib/CategoryTheory/Limits/VanKampen.lean index 95407b52b56af6..429dea9a1687bf 100644 --- a/Mathlib/CategoryTheory/Limits/VanKampen.lean +++ b/Mathlib/CategoryTheory/Limits/VanKampen.lean @@ -701,7 +701,7 @@ theorem isVanKampenColimit_extendCofan {n : ℕ} (f : Fin (n + 1) → C) rotate_left · ext ⟨j⟩ dsimp - rw [colimit.ι_desc] -- Why? + rw [colimit.ι_desc] rfl simpa [Functor.const_obj_obj, Discrete.functor_obj, extendCofan_pt, extendCofan_ι_app, Fin.cases_succ, BinaryCofan.mk_pt, colimit.cocone_x, Cofan.mk_pt, Cofan.mk_ι_app, diff --git a/Mathlib/CategoryTheory/Localization/SmallHom.lean b/Mathlib/CategoryTheory/Localization/SmallHom.lean index 51dc3d0d28e931..bb6cb9ad837599 100644 --- a/Mathlib/CategoryTheory/Localization/SmallHom.lean +++ b/Mathlib/CategoryTheory/Localization/SmallHom.lean @@ -249,11 +249,7 @@ lemma equiv_smallHomMap (G : D₁ ⥤ D₂) (e : Φ.functor ⋙ L₂ ≅ L₁ have hγ : ∀ (X : C₁), γ.hom.app (W₁.Q.obj X) = E₂.map (β.inv.app X) ≫ α₂.hom.app (Φ.functor.obj X) ≫ e.hom.app X ≫ G.map (α₁.inv.app X) := fun X ↦ by - dsimp [γ] - rw [liftNatTrans_app] - dsimp - rw [id_comp, id_comp, comp_id] - rw [id_comp, comp_id] + simp [γ, id_comp, comp_id] simp only [Functor.map_comp, assoc] erw [← NatIso.naturality_1 γ] simp only [Functor.comp_map, ← cancel_epi (e.inv.app X), ← cancel_epi (G.map (α₁.hom.app X)), diff --git a/Mathlib/Data/Complex/Exponential.lean b/Mathlib/Data/Complex/Exponential.lean index 990585b33e180d..e3fd8a0bac2f2a 100644 --- a/Mathlib/Data/Complex/Exponential.lean +++ b/Mathlib/Data/Complex/Exponential.lean @@ -1395,7 +1395,8 @@ theorem exp_bound_div_one_sub_of_interval' {x : ℝ} (h1 : 0 < x) (h2 : x < 1) : -- Porting note: was `norm_num [Finset.sum] <;> nlinarith` -- This proof should be restored after the norm_num plugin for big operators is ported. -- (It may also need the positivity extensions in #3907.) - repeat erw [Finset.sum_range_succ] + erw [Finset.sum_range_succ] + repeat rw [Finset.sum_range_succ] norm_num [Nat.factorial] nlinarith _ < 1 / (1 - x) := by rw [lt_div_iff₀] <;> nlinarith diff --git a/Mathlib/Data/Multiset/Fintype.lean b/Mathlib/Data/Multiset/Fintype.lean index 3655745b2b53ad..369c39be150288 100644 --- a/Mathlib/Data/Multiset/Fintype.lean +++ b/Mathlib/Data/Multiset/Fintype.lean @@ -217,8 +217,7 @@ theorem Multiset.card_coe (m : Multiset α) : Fintype.card m = Multiset.card m : @[to_additive] theorem Multiset.prod_eq_prod_coe [CommMonoid α] (m : Multiset α) : m.prod = ∏ x : m, (x : α) := by congr - -- Porting note: `simp` fails with "maximum recursion depth has been reached" - rw [map_univ_coe] + simp @[to_additive] theorem Multiset.prod_eq_prod_toEnumFinset [CommMonoid α] (m : Multiset α) : diff --git a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean index 01e39630d86087..60b7cb47198e4b 100644 --- a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean +++ b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean @@ -40,10 +40,9 @@ theorem colimit_exists_rep (x : colimit (C := SheafedSpace C) F) : (isColimitOfPreserves (SheafedSpace.forget _) (colimit.isColimit F)) x instance {X Y : SheafedSpace C} (f g : X ⟶ Y) : Epi (coequalizer.π f g).base := by - rw [← - show _ = (coequalizer.π f g).base from - ι_comp_coequalizerComparison f g (SheafedSpace.forget C)] - rw [← PreservesCoequalizer.iso_hom] + rw [← show _ = (coequalizer.π f g).base from + ι_comp_coequalizerComparison f g (SheafedSpace.forget C), + ← PreservesCoequalizer.iso_hom] apply epi_comp end SheafedSpace diff --git a/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean b/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean index f109d7724c596c..93d358233ae906 100644 --- a/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean +++ b/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean @@ -369,9 +369,9 @@ def ιInvApp {i : D.J} (U : Opens (D.U i).carrier) : ((D.f k j).c.app _ ≫ (D.t j k).c.app _) ≫ (D.V (j, k)).presheaf.map (eqToHom _) rw [opensImagePreimageMap_app_assoc] simp_rw [Category.assoc] - rw [opensImagePreimageMap_app_assoc, (D.t j k).c.naturality_assoc] - rw [snd_invApp_t_app_assoc] - rw [← PresheafedSpace.comp_c_app_assoc] + rw [opensImagePreimageMap_app_assoc, (D.t j k).c.naturality_assoc, + snd_invApp_t_app_assoc, + ← PresheafedSpace.comp_c_app_assoc] -- light-blue = green is relatively easy since the part that differs does not involve -- partial inverses. have : @@ -379,19 +379,21 @@ def ιInvApp {i : D.J} (U : Opens (D.U i).carrier) : (pullbackSymmetry _ _).hom ≫ (π₁ j, i, k) ≫ D.t j i ≫ D.f i j := by rw [← 𝖣.t_fac_assoc, 𝖣.t'_comp_eq_pullbackSymmetry_assoc, pullbackSymmetry_hom_comp_snd_assoc, pullback.condition, 𝖣.t_fac_assoc] - rw [congr_app this] - rw [PresheafedSpace.comp_c_app_assoc (pullbackSymmetry _ _).hom] + rw [congr_app this, + PresheafedSpace.comp_c_app_assoc (pullbackSymmetry _ _).hom] simp_rw [Category.assoc] congr 1 - rw [← IsIso.eq_inv_comp] - rw [IsOpenImmersion.inv_invApp] + rw [← IsIso.eq_inv_comp, + IsOpenImmersion.inv_invApp] simp_rw [Category.assoc] erw [NatTrans.naturality_assoc, ← PresheafedSpace.comp_c_app_assoc, congr_app (pullbackSymmetry_hom_comp_snd _ _)] simp_rw [Category.assoc] erw [IsOpenImmersion.inv_naturality_assoc, IsOpenImmersion.inv_naturality_assoc, IsOpenImmersion.inv_naturality_assoc, IsOpenImmersion.app_invApp_assoc] - repeat' erw [← (D.V (j, k)).presheaf.map_comp] + rw [← (D.V (j, k)).presheaf.map_comp] + erw [← (D.V (j, k)).presheaf.map_comp] + repeat rw [← (D.V (j, k)).presheaf.map_comp] -- Porting note: was just `congr` exact congr_arg ((D.V (j, k)).presheaf.map ·) rfl } } diff --git a/Mathlib/Geometry/RingedSpace/PresheafedSpace/HasColimits.lean b/Mathlib/Geometry/RingedSpace/PresheafedSpace/HasColimits.lean index 748d2e9a042300..ce942b2c84104a 100644 --- a/Mathlib/Geometry/RingedSpace/PresheafedSpace/HasColimits.lean +++ b/Mathlib/Geometry/RingedSpace/PresheafedSpace/HasColimits.lean @@ -326,9 +326,9 @@ theorem colimitPresheafObjIsoComponentwiseLimit_inv_ι_app (F : J ⥤ Presheafed rw [Iso.trans_inv, Iso.trans_inv, Iso.app_inv, sheafIsoOfIso_inv, pushforwardToOfIso_app, congr_app (Iso.symm_inv _)] dsimp - rw [map_id, comp_id, assoc, assoc, assoc, NatTrans.naturality] - rw [← comp_c_app_assoc] - rw [congr_app (colimit.isoColimitCocone_ι_hom _ _), assoc] + rw [map_id, comp_id, assoc, assoc, assoc, NatTrans.naturality, + ← comp_c_app_assoc, + congr_app (colimit.isoColimitCocone_ι_hom _ _), assoc] erw [limitObjIsoLimitCompEvaluation_inv_π_app_assoc, limMap_π_assoc] -- Porting note: `convert` doesn't work due to meta variable, so change to a `suffices` block set f := _ diff --git a/Mathlib/LinearAlgebra/TensorProduct/Graded/External.lean b/Mathlib/LinearAlgebra/TensorProduct/Graded/External.lean index 03b736c1b249bb..e9896dd5d9c215 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Graded/External.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Graded/External.lean @@ -225,8 +225,8 @@ theorem gradedMul_algebraMap (x : (⨁ i, 𝒜 i) ⊗[R] (⨁ i, ℬ i)) (r : R) ext dsimp erw [tmul_of_gradedMul_of_tmul] - rw [mul_zero, uzpow_zero, one_smul, smul_tmul'] - rw [mul_one, _root_.Algebra.smul_def, Algebra.commutes] + rw [mul_zero, uzpow_zero, one_smul, smul_tmul', + mul_one, _root_.Algebra.smul_def, Algebra.commutes] rfl theorem gradedMul_one (x : (⨁ i, 𝒜 i) ⊗[R] (⨁ i, ℬ i)) : diff --git a/Mathlib/RepresentationTheory/Character.lean b/Mathlib/RepresentationTheory/Character.lean index b93a8e10f7a61e..b68c19284a62c3 100644 --- a/Mathlib/RepresentationTheory/Character.lean +++ b/Mathlib/RepresentationTheory/Character.lean @@ -89,7 +89,7 @@ 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] -- Porting note: Changed `rw` to `erw` + rw [← (isProj_averageMap V.ρ).trace] simp [character, GroupAlgebra.average, _root_.map_sum] end Group diff --git a/Mathlib/RepresentationTheory/GroupCohomology/Basic.lean b/Mathlib/RepresentationTheory/GroupCohomology/Basic.lean index 3ed7a7cdb928da..3d60e4b43bfb41 100644 --- a/Mathlib/RepresentationTheory/GroupCohomology/Basic.lean +++ b/Mathlib/RepresentationTheory/GroupCohomology/Basic.lean @@ -146,7 +146,6 @@ and the homogeneous `linearYonedaObjResolution`. -/ -- https://github.com/leanprover-community/mathlib4/issues/5164 change d n A f g = diagonalHomEquiv (n + 1) A ((resolution k G).d (n + 1) n ≫ (diagonalHomEquiv n A).symm f) g - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 rw [diagonalHomEquiv_apply, Action.comp_hom, ModuleCat.comp_def, LinearMap.comp_apply, resolution.d_eq] erw [resolution.d_of (Fin.partialProd g)] diff --git a/Mathlib/RepresentationTheory/GroupCohomology/Resolution.lean b/Mathlib/RepresentationTheory/GroupCohomology/Resolution.lean index c33b00a7615549..9d4c8627a8198a 100644 --- a/Mathlib/RepresentationTheory/GroupCohomology/Resolution.lean +++ b/Mathlib/RepresentationTheory/GroupCohomology/Resolution.lean @@ -221,14 +221,11 @@ theorem diagonalSucc_inv_single_left (g : G) (f : Gⁿ →₀ k) (r : k) : diagonalSucc_inv_single_single, hx, Finsupp.sum_single_index, mul_comm b, zero_mul, single_zero] -/ · rw [TensorProduct.tmul_zero, map_zero] - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 rw [map_zero] · intro _ _ _ _ _ hx - rw [TensorProduct.tmul_add, map_add]; rw [map_add, hx] + rw [TensorProduct.tmul_add, map_add, map_add, hx] simp_rw [lift_apply, smul_single, smul_eq_mul] - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 - rw [diagonalSucc_inv_single_single] - rw [sum_single_index, mul_comm] + rw [diagonalSucc_inv_single_single, sum_single_index, mul_comm] rw [zero_mul, single_zero] theorem diagonalSucc_inv_single_right (g : G →₀ k) (f : Gⁿ) (r : k) : @@ -240,15 +237,11 @@ theorem diagonalSucc_inv_single_right (g : G →₀ k) (f : Gⁿ) (r : k) : · intro a b x ha hb hx simp only [lift_apply, smul_single', map_add, hx, diagonalSucc_inv_single_single, TensorProduct.add_tmul, Finsupp.sum_single_index, zero_mul, single_zero] -/ - · rw [TensorProduct.zero_tmul, map_zero] - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 - rw [map_zero] + · rw [TensorProduct.zero_tmul, map_zero, map_zero] · intro _ _ _ _ _ hx - rw [TensorProduct.add_tmul, map_add]; rw [map_add, hx] + rw [TensorProduct.add_tmul, map_add, map_add, hx] simp_rw [lift_apply, smul_single'] - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 - rw [diagonalSucc_inv_single_single] - rw [sum_single_index] + rw [diagonalSucc_inv_single_single, sum_single_index] rw [zero_mul, single_zero] end Rep @@ -266,7 +259,6 @@ def ofMulActionBasisAux : (ofMulAction k G (Fin (n + 1) → G)).asModule := { (Rep.equivalenceModuleMonoidAlgebra.1.mapIso (diagonalSucc k G n).symm).toLinearEquiv with map_smul' := fun r x => by - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 rw [RingHom.id_apply, LinearEquiv.toFun_eq_coe, ← LinearEquiv.map_smul] congr 1 /- Porting note (#11039): broken proof was @@ -357,21 +349,23 @@ theorem diagonalHomEquiv_symm_apply (f : (Fin n → G) → A) (x : Fin (n + 1) Category.comp_id, Action.comp_hom, MonoidalClosed.linearHomEquivComm_symm_hom] -- Porting note: This is a sure sign that coercions for morphisms in `ModuleCat` -- are still not set up properly. - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 rw [ModuleCat.coe_comp] simp only [ModuleCat.coe_comp, Function.comp_apply] -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 erw [diagonalSucc_hom_single] - erw [TensorProduct.uncurry_apply, Finsupp.lift_apply, Finsupp.sum_single_index] - · simp only [one_smul] - erw [Representation.linHom_apply] - simp only [LinearMap.comp_apply, MonoidHom.one_apply, LinearMap.one_apply] - erw [Finsupp.llift_apply] - rw [Finsupp.lift_apply] - erw [Finsupp.sum_single_index] - · rw [one_smul] + -- The prototype linter that checks if `erw` could be replaced with `rw` would time out + -- if it replaces the next `erw`s with `rw`s. So we focus down on the relevant part. + conv_lhs => + erw [TensorProduct.uncurry_apply, Finsupp.lift_apply, Finsupp.sum_single_index] + · simp only [one_smul] + erw [Representation.linHom_apply] + simp only [LinearMap.comp_apply, MonoidHom.one_apply, LinearMap.one_apply] + erw [Finsupp.llift_apply] + rw [Finsupp.lift_apply] + erw [Finsupp.sum_single_index] + · rw [one_smul] + · rw [zero_smul] · rw [zero_smul] - · rw [zero_smul] /-- Auxiliary lemma for defining group cohomology, used to show that the isomorphism `diagonalHomEquiv` commutes with the differentials in two complexes which compute diff --git a/Mathlib/RingTheory/EisensteinCriterion.lean b/Mathlib/RingTheory/EisensteinCriterion.lean index 83a3e660fb6ae3..4db4a640eef892 100644 --- a/Mathlib/RingTheory/EisensteinCriterion.lean +++ b/Mathlib/RingTheory/EisensteinCriterion.lean @@ -34,8 +34,7 @@ theorem map_eq_C_mul_X_pow_of_forall_coeff_mem {f : R[X]} {P : Ideal R} by_cases hf0 : f = 0 · simp [hf0] rcases lt_trichotomy (n : WithBot ℕ) (degree f) with (h | h | h) - · rw [coeff_map, eq_zero_iff_mem.2 (hfP n h), coeff_C_mul, coeff_X_pow, if_neg, - mul_zero] + · rw [coeff_map, eq_zero_iff_mem.2 (hfP n h), coeff_C_mul, coeff_X_pow, if_neg, mul_zero] rintro rfl exact not_lt_of_ge degree_le_natDegree h · have : natDegree f = n := natDegree_eq_of_degree_eq_some h.symm diff --git a/Mathlib/RingTheory/Henselian.lean b/Mathlib/RingTheory/Henselian.lean index 8d679f547bc1b5..b1762c379f8243 100644 --- a/Mathlib/RingTheory/Henselian.lean +++ b/Mathlib/RingTheory/Henselian.lean @@ -229,13 +229,7 @@ instance (priority := 100) IsAdicComplete.henselianRing (R : Type*) [CommRing R] clear hmn induction' k with k ih · rw [add_zero] - rw [← add_assoc] - #adaptation_note /-- nightly-2024-03-11 - I'm not sure why the `erw` is now needed here. It looks like it should work. - It looks like a diamond between `instHAdd` on `Nat` and `AddSemigroup.toAdd` which is - used by `instHAdd` -/ - rw [hc] - rw [← add_zero (c m), sub_eq_add_neg] + rw [← add_assoc, hc, ← add_zero (c m), sub_eq_add_neg] refine ih.add ?_ symm rw [SModEq.zero, Ideal.neg_mem_iff] diff --git a/Mathlib/RingTheory/Ideal/Operations.lean b/Mathlib/RingTheory/Ideal/Operations.lean index 7d4c3d4299ed23..50211d46f660e8 100644 --- a/Mathlib/RingTheory/Ideal/Operations.lean +++ b/Mathlib/RingTheory/Ideal/Operations.lean @@ -1070,8 +1070,8 @@ theorem subset_union_prime' {R : Type u} [CommRing R] {s : Finset ι} {f : ι rw [Finset.coe_insert] at h ⊢ rw [Finset.coe_insert] at h simp only [Set.biUnion_insert] at h ⊢ - rw [← Set.union_assoc (f i : Set R)] at h - rw [Set.union_eq_self_of_subset_right hfji] at h + rw [← Set.union_assoc (f i : Set R), + Set.union_eq_self_of_subset_right hfji] at h exact h specialize ih hp' hn' h' refine ih.imp id (Or.imp id (Exists.imp fun k => ?_)) @@ -1079,8 +1079,8 @@ theorem subset_union_prime' {R : Type u} [CommRing R] {s : Finset ι} {f : ι by_cases Ha : f a ≤ f i · have h' : (I : Set R) ⊆ f i ∪ f b ∪ ⋃ j ∈ (↑t : Set ι), f j := by rw [Finset.coe_insert, Set.biUnion_insert, ← Set.union_assoc, - Set.union_right_comm (f a : Set R)] at h - rw [Set.union_eq_self_of_subset_left Ha] at h + Set.union_right_comm (f a : Set R), + Set.union_eq_self_of_subset_left Ha] at h exact h specialize ih hp.2 hn h' right @@ -1091,8 +1091,8 @@ theorem subset_union_prime' {R : Type u} [CommRing R] {s : Finset ι} {f : ι by_cases Hb : f b ≤ f i · have h' : (I : Set R) ⊆ f a ∪ f i ∪ ⋃ j ∈ (↑t : Set ι), f j := by rw [Finset.coe_insert, Set.biUnion_insert, ← Set.union_assoc, - Set.union_assoc (f a : Set R)] at h - rw [Set.union_eq_self_of_subset_left Hb] at h + Set.union_assoc (f a : Set R), + Set.union_eq_self_of_subset_left Hb] at h exact h specialize ih hp.2 hn h' rcases ih with (ih | ih | ⟨k, hkt, ih⟩) diff --git a/Mathlib/RingTheory/PowerSeries/Basic.lean b/Mathlib/RingTheory/PowerSeries/Basic.lean index 2a4286682db86d..bae1dcd02e069a 100644 --- a/Mathlib/RingTheory/PowerSeries/Basic.lean +++ b/Mathlib/RingTheory/PowerSeries/Basic.lean @@ -214,8 +214,9 @@ theorem coeff_zero_eq_constantCoeff_apply (φ : R⟦X⟧) : coeff R 0 φ = const @[simp] theorem monomial_zero_eq_C : ⇑(monomial R 0) = C R := by - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 - erw [monomial, Finsupp.single_zero, MvPowerSeries.monomial_zero_eq_C] + -- This used to be `rw`, but we need `rw; rfl` after leanprover/lean4#2644 + rw [monomial, Finsupp.single_zero, MvPowerSeries.monomial_zero_eq_C] + rfl theorem monomial_zero_eq_C_apply (a : R) : monomial R 0 a = C R a := by simp @@ -251,7 +252,6 @@ theorem coeff_X (n : ℕ) : coeff R n (X : R⟦X⟧) = if n = 1 then 1 else 0 := @[simp] theorem coeff_zero_X : coeff R 0 (X : R⟦X⟧) = 0 := by - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 rw [coeff, Finsupp.single_zero, X, MvPowerSeries.coeff_zero_X] @[simp] diff --git a/Mathlib/RingTheory/PowerSeries/Inverse.lean b/Mathlib/RingTheory/PowerSeries/Inverse.lean index efeddee8853c4f..b08f4125a38a02 100644 --- a/Mathlib/RingTheory/PowerSeries/Inverse.lean +++ b/Mathlib/RingTheory/PowerSeries/Inverse.lean @@ -54,7 +54,6 @@ theorem coeff_inv_aux (n : ℕ) (a : R) (φ : R⟦X⟧) : -a * ∑ x ∈ antidiagonal n, if x.2 < n then coeff R x.1 φ * coeff R x.2 (inv.aux a φ) else 0 := by - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 rw [coeff, inv.aux, MvPowerSeries.coeff_inv_aux] simp only [Finsupp.single_eq_zero] split_ifs; · rfl diff --git a/Mathlib/RingTheory/Valuation/Integral.lean b/Mathlib/RingTheory/Valuation/Integral.lean index 8806cf38ae2ad8..c8e1a11e3d9703 100644 --- a/Mathlib/RingTheory/Valuation/Integral.lean +++ b/Mathlib/RingTheory/Valuation/Integral.lean @@ -38,7 +38,7 @@ theorem mem_of_integral {x : R} (hx : IsIntegral O x) : x ∈ v.integer := one_mul (v x ^ p.natDegree)] cases' (hv.2 <| p.coeff i).lt_or_eq with hvpi hvpi · exact mul_lt_mul₀ hvpi (pow_lt_pow_right₀ hvx <| Finset.mem_range.1 hi) - · rw [hvpi]; rw [one_mul, one_mul]; exact pow_lt_pow_right₀ hvx (Finset.mem_range.1 hi) + · rw [hvpi, one_mul, one_mul]; exact pow_lt_pow_right₀ hvx (Finset.mem_range.1 hi) protected theorem integralClosure : integralClosure O R = ⊥ := bot_unique fun _ hr => diff --git a/Mathlib/Topology/Category/CompHaus/Projective.lean b/Mathlib/Topology/Category/CompHaus/Projective.lean index 97532c9b45d963..def47e5abc989b 100644 --- a/Mathlib/Topology/Category/CompHaus/Projective.lean +++ b/Mathlib/Topology/Category/CompHaus/Projective.lean @@ -51,8 +51,9 @@ instance projective_ultrafilter (X : Type*) : Projective (of <| Ultrafilter X) w -- The next two lines should not be needed. let g'' : ContinuousMap Y Z := g have : g'' ∘ g' = id := hg'.comp_eq_id - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 - erw [comp_assoc, ultrafilter_extend_extends, ← comp_assoc, this, id_comp] + -- This used to be `rw`, but we need `rw; rfl` after leanprover/lean4#2644 + rw [comp_assoc, ultrafilter_extend_extends, ← comp_assoc, this, id_comp] + rfl /-- For any compact Hausdorff space `X`, the natural map `Ultrafilter X → X` is a projective presentation. -/ diff --git a/Mathlib/Topology/Category/Profinite/CofilteredLimit.lean b/Mathlib/Topology/Category/Profinite/CofilteredLimit.lean index 52531dbcc31805..fb9774c83263f6 100644 --- a/Mathlib/Topology/Category/Profinite/CofilteredLimit.lean +++ b/Mathlib/Topology/Category/Profinite/CofilteredLimit.lean @@ -168,7 +168,6 @@ theorem exists_locallyConstant_finite_nonempty {α : Type*} [Finite α] [Nonempt dsimp [σ] have h1 : ι (f x) = gg (C.π.app j x) := by change f.map (fun a b => if a = b then (0 : Fin 2) else 1) x = _ - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 rw [h] rfl have h2 : ∃ a : α, ι a = gg (C.π.app j x) := ⟨f x, h1⟩ diff --git a/Mathlib/Topology/Category/Profinite/Projective.lean b/Mathlib/Topology/Category/Profinite/Projective.lean index 98eb2deeef7fc0..55521c4ffef710 100644 --- a/Mathlib/Topology/Category/Profinite/Projective.lean +++ b/Mathlib/Topology/Category/Profinite/Projective.lean @@ -50,8 +50,9 @@ instance projective_ultrafilter (X : Type u) : Projective (of <| Ultrafilter X) -- Porting note: same fix as in `Topology.Category.CompHaus.Projective` let g'' : ContinuousMap Y Z := g have : g'' ∘ g' = id := hg'.comp_eq_id - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 - erw [comp_assoc, ultrafilter_extend_extends, ← comp_assoc, this, id_comp] + -- This used to be `rw`, but we need `rw; rfl` after leanprover/lean4#2644 + rw [comp_assoc, ultrafilter_extend_extends, ← comp_assoc, this, id_comp] + rfl /-- For any profinite `X`, the natural map `Ultrafilter X → X` is a projective presentation. -/ def projectivePresentation (X : Profinite.{u}) : ProjectivePresentation X where diff --git a/Mathlib/Topology/Category/TopCat/Limits/Cofiltered.lean b/Mathlib/Topology/Category/TopCat/Limits/Cofiltered.lean index 4c078fb156fe75..dc77a067581bdc 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Cofiltered.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Cofiltered.lean @@ -113,7 +113,7 @@ theorem isTopologicalBasis_cofiltered_limit (hC : IsLimit C) (T : ∀ j, Set (Se rw [dif_pos he, ← Set.preimage_comp] apply congrFun apply congrArg - rw [← coe_comp, D.w] -- now `erw` after #13170 + rw [← coe_comp, D.w] rfl end CofilteredLimit diff --git a/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean b/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean index 78498284f1cae2..3d1a8ae947989e 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean @@ -315,8 +315,7 @@ theorem fst_embedding_of_right_embedding {X Y S : TopCat} (f : X ⟶ S) {g : Y theorem embedding_of_pullback_embeddings {X Y S : TopCat} {f : X ⟶ S} {g : Y ⟶ S} (H₁ : Embedding f) (H₂ : Embedding g) : Embedding (limit.π (cospan f g) WalkingCospan.one) := by convert H₂.comp (snd_embedding_of_left_embedding H₁ g) - rw [← coe_comp] - rw [← limit.w _ WalkingCospan.Hom.inr] + rw [← coe_comp, ← limit.w _ WalkingCospan.Hom.inr] rfl theorem snd_openEmbedding_of_left_openEmbedding {X Y S : TopCat} {f : X ⟶ S} (H : OpenEmbedding f) @@ -340,8 +339,7 @@ theorem openEmbedding_of_pullback_open_embeddings {X Y S : TopCat} {f : X ⟶ S} (H₁ : OpenEmbedding f) (H₂ : OpenEmbedding g) : OpenEmbedding (limit.π (cospan f g) WalkingCospan.one) := by convert H₂.comp (snd_openEmbedding_of_left_openEmbedding H₁ g) - rw [← coe_comp] - rw [← limit.w _ WalkingCospan.Hom.inr] + rw [← coe_comp, ← limit.w _ WalkingCospan.Hom.inr] rfl theorem fst_iso_of_right_embedding_range_subset {X Y S : TopCat} (f : X ⟶ S) {g : Y ⟶ S} diff --git a/Mathlib/Topology/Gluing.lean b/Mathlib/Topology/Gluing.lean index 293a6154b6e849..c6d7656eb38bc8 100644 --- a/Mathlib/Topology/Gluing.lean +++ b/Mathlib/Topology/Gluing.lean @@ -376,7 +376,7 @@ def mk' (h : MkCore.{u}) : TopCat.GlueData where simp only [Iso.inv_hom_id_assoc, Category.assoc, Category.id_comp] rw [← Iso.eq_inv_comp, Iso.inv_hom_id] ext1 ⟨⟨⟨x, hx⟩, ⟨x', hx'⟩⟩, rfl : x = x'⟩ - -- The next 9 tactics (up to `convert ...` were a single `rw` before leanprover/lean4#2644 + -- The next 6 tactics (up to `convert ...` were a single `rw` before leanprover/lean4#2644 -- rw [comp_app, ContinuousMap.coe_mk, comp_app, id_app, ContinuousMap.coe_mk, Subtype.mk_eq_mk, -- Prod.mk.inj_iff, Subtype.mk_eq_mk, Subtype.ext_iff, and_self_iff] erw [comp_app] --, comp_app, id_app] -- now `erw` after #13170 @@ -385,10 +385,7 @@ def mk' (h : MkCore.{u}) : TopCat.GlueData where erw [id_app] rw [ContinuousMap.coe_mk] erw [Subtype.mk_eq_mk] - rw [Prod.mk.inj_iff] - rw [Subtype.mk_eq_mk] - rw [Subtype.ext_iff] - rw [and_self_iff] + rw [Prod.mk.inj_iff, Subtype.mk_eq_mk, Subtype.ext_iff, and_self_iff] convert congr_arg Subtype.val (h.t_inv k i ⟨x, hx'⟩) using 3 refine Subtype.ext ?_ exact h.cocycle i j k ⟨x, hx⟩ hx' diff --git a/Mathlib/Topology/LocalAtTarget.lean b/Mathlib/Topology/LocalAtTarget.lean index 5940dff2f1fa65..184b90a9c30e40 100644 --- a/Mathlib/Topology/LocalAtTarget.lean +++ b/Mathlib/Topology/LocalAtTarget.lean @@ -150,8 +150,8 @@ theorem inducing_iff_inducing_of_iSup_eq_top (h : Continuous f) : (show f x ∈ iSup U by rw [hU] trivial) - rw [← OpenEmbedding.map_nhds_eq (h.1 _ (U i).2).openEmbedding_subtype_val ⟨x, hi⟩] - rw [(H i) ⟨x, hi⟩, Filter.subtype_coe_map_comap, Function.comp_apply, Subtype.coe_mk, + rw [← OpenEmbedding.map_nhds_eq (h.1 _ (U i).2).openEmbedding_subtype_val ⟨x, hi⟩, + (H i) ⟨x, hi⟩, Filter.subtype_coe_map_comap, Function.comp_apply, Subtype.coe_mk, inf_eq_left, Filter.le_principal_iff] exact Filter.preimage_mem_comap ((U i).2.mem_nhds hi) diff --git a/Mathlib/Topology/Order/LawsonTopology.lean b/Mathlib/Topology/Order/LawsonTopology.lean index b3eba14013cc6d..945cc85292c34c 100644 --- a/Mathlib/Topology/Order/LawsonTopology.lean +++ b/Mathlib/Topology/Order/LawsonTopology.lean @@ -94,8 +94,7 @@ protected theorem isTopologicalBasis : TopologicalSpace.IsTopologicalBasis (laws convert IsTopologicalBasis.inf_induced IsLower.isTopologicalBasis (isTopologicalBasis_opens (α := WithScott α)) WithLower.toLower WithScott.toScott - rw [@topology_eq_lawson α _ _ _] - rw [lawson] + rw [@topology_eq_lawson α _ _ _, lawson] apply (congrArg₂ Inf.inf _) _ · letI _ := lower α; exact @IsLower.withLowerHomeomorph α ‹_› (lower α) ⟨rfl⟩ |>.inducing.induced letI _ := scott α; exact @IsScott.withScottHomeomorph α _ (scott α) ⟨rfl⟩ |>.inducing.induced From f10aec8053afd9e3105aa2b573cf8860dd12a90b Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Fri, 11 Oct 2024 10:22:22 +0000 Subject: [PATCH 019/425] Trigger CI for https://github.com/leanprover/lean4/pull/5323 --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index fce16b8e759ec8..16024e84feae23 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "e2a07df557ce580c0daa5213b5272ba8259e5d81", + "rev": "8c7405ecb6b595cac0d4fe28de9b1c4b7646cf45", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "lean-pr-testing-5323", From b74cd078414f46a72f8c5e41a79d382df9f860b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 11 Oct 2024 11:07:01 +0000 Subject: [PATCH 020/425] =?UTF-8?q?feat:=20`=20PUnit=20=C3=97=20=CE=B1=20?= =?UTF-8?q?=E2=89=83=E1=B5=90=20=CE=B1`=20(#17640)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From PFR --- Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean b/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean index 5cb861c7dd95af..295f11d4408f21 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean @@ -352,6 +352,18 @@ def prodAssoc : (α × β) × γ ≃ᵐ α × β × γ where measurable_toFun := measurable_fst.fst.prod_mk <| measurable_fst.snd.prod_mk measurable_snd measurable_invFun := (measurable_fst.prod_mk measurable_snd.fst).prod_mk measurable_snd.snd +/-- `PUnit` is a left identity for product of measurable spaces up to a measurable equivalence. -/ +def punitProd : PUnit × α ≃ᵐ α where + toEquiv := Equiv.punitProd α + measurable_toFun := measurable_snd + measurable_invFun := measurable_prod_mk_left + +/-- `PUnit` is a right identity for product of measurable spaces up to a measurable equivalence. -/ +def prodPUnit : α × PUnit ≃ᵐ α where + toEquiv := Equiv.prodPUnit α + measurable_toFun := measurable_fst + measurable_invFun := measurable_prod_mk_right + variable [MeasurableSpace δ] in /-- Sums of measurable spaces are symmetric. -/ def sumCongr (ab : α ≃ᵐ β) (cd : γ ≃ᵐ δ) : α ⊕ γ ≃ᵐ β ⊕ δ where From b22ecdf40e7d211408d8f9ef6b530503aea6fe7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 11 Oct 2024 11:28:34 +0000 Subject: [PATCH 021/425] feat: `essSup` of the uniform measure (#17463) From LeanAPAP --- Mathlib/MeasureTheory/Function/EssSup.lean | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Mathlib/MeasureTheory/Function/EssSup.lean b/Mathlib/MeasureTheory/Function/EssSup.lean index 503c49f68e8dfe..08d14b549d3b7d 100644 --- a/Mathlib/MeasureTheory/Function/EssSup.lean +++ b/Mathlib/MeasureTheory/Function/EssSup.lean @@ -6,6 +6,7 @@ Authors: Rémy Degenne import Mathlib.MeasureTheory.Constructions.BorelSpace.Order import Mathlib.MeasureTheory.Measure.Count import Mathlib.Order.Filter.ENNReal +import Mathlib.Probability.UniformOn /-! # Essential supremum and infimum @@ -28,9 +29,8 @@ sense). We do not define that quantity here, which is simply the supremum of a m -/ -open MeasureTheory Filter Set TopologicalSpace - -open ENNReal MeasureTheory NNReal +open Filter MeasureTheory ProbabilityTheory Set TopologicalSpace +open scoped ENNReal NNReal variable {α β : Type*} {m : MeasurableSpace α} {μ ν : Measure α} @@ -94,6 +94,14 @@ variable [MeasurableSingletonClass α] @[simp] lemma essInf_count_eq_ciInf (hf : BddBelow (Set.range f)) : essInf f .count = ⨅ a, f a := essInf_eq_ciInf (by simp) hf +@[simp] lemma essSup_uniformOn_eq_ciSup [Finite α] (hf : BddAbove (Set.range f)) : + essSup f (uniformOn univ) = ⨆ a, f a := + essSup_eq_ciSup (by simp [uniformOn, cond_apply, Set.finite_univ]) hf + +@[simp] lemma essInf_cond_count_eq_ciInf [Finite α] (hf : BddBelow (Set.range f)) : + essInf f (uniformOn univ) = ⨅ a, f a := + essInf_eq_ciInf (by simp [uniformOn, cond_apply, Set.finite_univ]) hf + end ConditionallyCompleteLattice section ConditionallyCompleteLinearOrder From eab6727ca49cce8f312fd92d643fa886d2b48029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Fri, 11 Oct 2024 12:11:18 +0000 Subject: [PATCH 022/425] doc(SetTheory/Ordinal/Arithmetic): update module docs (#17603) `enumOrd` is no longer defined in this file. --- Mathlib/SetTheory/Ordinal/Arithmetic.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/SetTheory/Ordinal/Arithmetic.lean b/Mathlib/SetTheory/Ordinal/Arithmetic.lean index e1d505331432e8..6752c67f0e1ccd 100644 --- a/Mathlib/SetTheory/Ordinal/Arithmetic.lean +++ b/Mathlib/SetTheory/Ordinal/Arithmetic.lean @@ -40,7 +40,6 @@ Some properties of the operations are also used to discuss general tools on ordi * `IsNormal`: a function `f : Ordinal → Ordinal` satisfies `IsNormal` if it is strictly increasing and order-continuous, i.e., the image `f o` of a limit ordinal `o` is the sup of `f a` for `a < o`. -* `enumOrd`: enumerates an unbounded set of ordinals by the ordinals themselves. * `sup`, `lsub`: the supremum / least strict upper bound of an indexed family of ordinals in `Type u`, as an ordinal in `Type u`. * `bsup`, `blsub`: the supremum / least strict upper bound of a set of ordinals indexed by ordinals From 13c52d66bee8cc12be90d97f0efd6b63d5dc1b39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Fri, 11 Oct 2024 12:40:15 +0000 Subject: [PATCH 023/425] chore(SetTheory/Cardinal/Ordinal): split file (#16990) We split this file into two: - `Cardinal/Aleph`: contains the definitions for the aleph and beth functions (and soon, the omega function). - `Cardinal/Arithmetic`: any results on cardinal arithmetic that depend on `c * c = c` (which requires some basic properties of ordinals to be proven) These files are otherwise unchanged, with the exception of tweaking some section headers. --- Mathlib.lean | 3 +- Mathlib/Algebra/Quaternion.lean | 2 +- Mathlib/Data/W/Cardinal.lean | 2 +- Mathlib/ModelTheory/Encoding.lean | 2 +- Mathlib/Order/Filter/CardinalInter.lean | 2 +- Mathlib/Order/Filter/Cocardinal.lean | 2 +- .../RingTheory/Localization/Cardinality.lean | 2 +- Mathlib/SetTheory/Cardinal/Aleph.lean | 424 ++++++++++++++++ .../{Ordinal.lean => Arithmetic.lean} | 466 +----------------- Mathlib/SetTheory/Cardinal/Cofinality.lean | 2 +- Mathlib/SetTheory/Cardinal/Continuum.lean | 2 +- .../SetTheory/Cardinal/CountableCover.lean | 2 +- Mathlib/SetTheory/Cardinal/Divisibility.lean | 2 +- Mathlib/SetTheory/Cardinal/Finsupp.lean | 2 +- Mathlib/SetTheory/Ordinal/Arithmetic.lean | 20 + 15 files changed, 478 insertions(+), 457 deletions(-) create mode 100644 Mathlib/SetTheory/Cardinal/Aleph.lean rename Mathlib/SetTheory/Cardinal/{Ordinal.lean => Arithmetic.lean} (67%) diff --git a/Mathlib.lean b/Mathlib.lean index 4e58a18529e1dc..0b8cc14aff2ab9 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4141,6 +4141,8 @@ import Mathlib.RingTheory.WittVector.Truncated import Mathlib.RingTheory.WittVector.Verschiebung import Mathlib.RingTheory.WittVector.WittPolynomial import Mathlib.RingTheory.ZMod +import Mathlib.SetTheory.Cardinal.Aleph +import Mathlib.SetTheory.Cardinal.Arithmetic import Mathlib.SetTheory.Cardinal.Basic import Mathlib.SetTheory.Cardinal.Cofinality import Mathlib.SetTheory.Cardinal.Continuum @@ -4149,7 +4151,6 @@ import Mathlib.SetTheory.Cardinal.Divisibility import Mathlib.SetTheory.Cardinal.ENat import Mathlib.SetTheory.Cardinal.Finite import Mathlib.SetTheory.Cardinal.Finsupp -import Mathlib.SetTheory.Cardinal.Ordinal import Mathlib.SetTheory.Cardinal.PartENat import Mathlib.SetTheory.Cardinal.SchroederBernstein import Mathlib.SetTheory.Cardinal.Subfield diff --git a/Mathlib/Algebra/Quaternion.lean b/Mathlib/Algebra/Quaternion.lean index f78db6c9f424a3..05c61e0d4e5308 100644 --- a/Mathlib/Algebra/Quaternion.lean +++ b/Mathlib/Algebra/Quaternion.lean @@ -7,7 +7,7 @@ import Mathlib.Algebra.Algebra.Equiv import Mathlib.LinearAlgebra.Dimension.StrongRankCondition import Mathlib.LinearAlgebra.FreeModule.Basic import Mathlib.LinearAlgebra.FreeModule.Finite.Basic -import Mathlib.SetTheory.Cardinal.Ordinal +import Mathlib.SetTheory.Cardinal.Arithmetic /-! # Quaternions diff --git a/Mathlib/Data/W/Cardinal.lean b/Mathlib/Data/W/Cardinal.lean index 911d370ca2ef11..5841bc9d66bd18 100644 --- a/Mathlib/Data/W/Cardinal.lean +++ b/Mathlib/Data/W/Cardinal.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Chris Hughes -/ import Mathlib.Data.W.Basic -import Mathlib.SetTheory.Cardinal.Ordinal +import Mathlib.SetTheory.Cardinal.Arithmetic /-! # Cardinality of W-types diff --git a/Mathlib/ModelTheory/Encoding.lean b/Mathlib/ModelTheory/Encoding.lean index a9157aba577e84..b8219e55752e1e 100644 --- a/Mathlib/ModelTheory/Encoding.lean +++ b/Mathlib/ModelTheory/Encoding.lean @@ -6,7 +6,7 @@ Authors: Aaron Anderson import Mathlib.Computability.Encoding import Mathlib.Logic.Small.List import Mathlib.ModelTheory.Syntax -import Mathlib.SetTheory.Cardinal.Ordinal +import Mathlib.SetTheory.Cardinal.Arithmetic /-! # Encodings and Cardinality of First-Order Syntax diff --git a/Mathlib/Order/Filter/CardinalInter.lean b/Mathlib/Order/Filter/CardinalInter.lean index df6c37ffccbb72..def8ba80b0a80c 100644 --- a/Mathlib/Order/Filter/CardinalInter.lean +++ b/Mathlib/Order/Filter/CardinalInter.lean @@ -5,7 +5,7 @@ Authors: Josha Dekker -/ import Mathlib.Order.Filter.Basic import Mathlib.Order.Filter.CountableInter -import Mathlib.SetTheory.Cardinal.Ordinal +import Mathlib.SetTheory.Cardinal.Arithmetic import Mathlib.SetTheory.Cardinal.Cofinality /-! diff --git a/Mathlib/Order/Filter/Cocardinal.lean b/Mathlib/Order/Filter/Cocardinal.lean index ede785eb18061f..b0fed85fce86ea 100644 --- a/Mathlib/Order/Filter/Cocardinal.lean +++ b/Mathlib/Order/Filter/Cocardinal.lean @@ -6,7 +6,7 @@ Authors: Josha Dekker import Mathlib.Order.Filter.Cofinite import Mathlib.Order.Filter.CountableInter import Mathlib.Order.Filter.CardinalInter -import Mathlib.SetTheory.Cardinal.Ordinal +import Mathlib.SetTheory.Cardinal.Arithmetic import Mathlib.SetTheory.Cardinal.Cofinality import Mathlib.Order.Filter.Bases diff --git a/Mathlib/RingTheory/Localization/Cardinality.lean b/Mathlib/RingTheory/Localization/Cardinality.lean index fbe15f047e6b10..1c11c039219ddf 100644 --- a/Mathlib/RingTheory/Localization/Cardinality.lean +++ b/Mathlib/RingTheory/Localization/Cardinality.lean @@ -3,7 +3,7 @@ Copyright (c) 2022 Eric Rodriguez. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Eric Rodriguez -/ -import Mathlib.SetTheory.Cardinal.Ordinal +import Mathlib.SetTheory.Cardinal.Arithmetic import Mathlib.RingTheory.Artinian /-! diff --git a/Mathlib/SetTheory/Cardinal/Aleph.lean b/Mathlib/SetTheory/Cardinal/Aleph.lean new file mode 100644 index 00000000000000..a2d762c20d204d --- /dev/null +++ b/Mathlib/SetTheory/Cardinal/Aleph.lean @@ -0,0 +1,424 @@ +/- +Copyright (c) 2017 Johannes Hölzl. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Johannes Hölzl, Mario Carneiro, Floris van Doorn +-/ +import Mathlib.Order.Bounded +import Mathlib.SetTheory.Cardinal.PartENat +import Mathlib.SetTheory.Ordinal.Arithmetic + +/-! +# Aleph and beth functions + +* The function `Cardinal.aleph'` gives the cardinals listed by their ordinal index. + `aleph' n = n`, `aleph' ω = ℵ₀`, `aleph' (ω + 1) = succ ℵ₀`, etc. + It is an order isomorphism between ordinals and cardinals. +* The function `Cardinal.aleph` gives the infinite cardinals listed by their + ordinal index. `aleph 0 = ℵ₀`, `aleph 1 = succ ℵ₀` is the first + uncountable cardinal, and so on. The notation `ω_` combines the latter with `Cardinal.ord`, + giving an enumeration of (infinite) initial ordinals. + Thus `ω_ 0 = ω` and `ω₁ = ω_ 1` is the first uncountable ordinal. +* The function `Cardinal.beth` enumerates the Beth cardinals. `beth 0 = ℵ₀`, + `beth (succ o) = 2 ^ beth o`, and for a limit ordinal `o`, `beth o` is the supremum of `beth a` + for `a < o`. +-/ + +assert_not_exists Module +assert_not_exists Finsupp +assert_not_exists Cardinal.mul_eq_self + +noncomputable section + +open Function Set Cardinal Equiv Order Ordinal + +universe u v w + +namespace Cardinal + +/-! ### Aleph cardinals -/ + +/-- The `aleph'` function gives the cardinals listed by their ordinal index. `aleph' n = n`, +`aleph' ω = ℵ₀`, `aleph' (ω + 1) = succ ℵ₀`, etc. + +For the more common aleph function skipping over finite cardinals, see `Cardinal.aleph`. -/ +def aleph' : Ordinal.{u} ≃o Cardinal.{u} := by + let f := RelEmbedding.collapse Cardinal.ord.orderEmbedding.ltEmbedding.{u} + refine (OrderIso.ofRelIsoLT <| RelIso.ofSurjective f ?_).symm + apply f.eq_or_principal.resolve_right + rintro ⟨o, e⟩ + have : ∀ c, f c < o := fun c => (e _).1 ⟨_, rfl⟩ + refine Ordinal.inductionOn o ?_ this + intro α r _ h + let s := ⨆ a, invFun f (Ordinal.typein r a) + apply (lt_succ s).not_le + have I : Injective f := f.toEmbedding.injective + simpa only [typein_enum, leftInverse_invFun I (succ s)] using + le_ciSup + (Cardinal.bddAbove_range.{u, u} fun a : α => invFun f (Ordinal.typein r a)) + (Ordinal.enum r ⟨_, h (succ s)⟩) + +/-- The `aleph'` index function, which gives the ordinal index of a cardinal. + (The `aleph'` part is because unlike `aleph` this counts also the + finite stages. So `alephIdx n = n`, `alephIdx ω = ω`, + `alephIdx ℵ₁ = ω + 1` and so on.) + In this definition, we register additionally that this function is an initial segment, + i.e., it is order preserving and its range is an initial segment of the ordinals. + For the basic function version, see `alephIdx`. + For an upgraded version stating that the range is everything, see `AlephIdx.rel_iso`. -/ +@[deprecated aleph' (since := "2024-08-28")] +def alephIdx.initialSeg : @InitialSeg Cardinal Ordinal (· < ·) (· < ·) := + @RelEmbedding.collapse Cardinal Ordinal (· < ·) (· < ·) _ Cardinal.ord.orderEmbedding.ltEmbedding + +/-- The `aleph'` index function, which gives the ordinal index of a cardinal. + (The `aleph'` part is because unlike `aleph` this counts also the + finite stages. So `alephIdx n = n`, `alephIdx ℵ₀ = ω`, + `alephIdx ℵ₁ = ω + 1` and so on.) + In this version, we register additionally that this function is an order isomorphism + between cardinals and ordinals. + For the basic function version, see `alephIdx`. -/ +@[deprecated aleph' (since := "2024-08-28")] +def alephIdx.relIso : @RelIso Cardinal.{u} Ordinal.{u} (· < ·) (· < ·) := + aleph'.symm.toRelIsoLT + +/-- The `aleph'` index function, which gives the ordinal index of a cardinal. + (The `aleph'` part is because unlike `aleph` this counts also the + finite stages. So `alephIdx n = n`, `alephIdx ω = ω`, + `alephIdx ℵ₁ = ω + 1` and so on.) + For an upgraded version stating that the range is everything, see `AlephIdx.rel_iso`. -/ +@[deprecated aleph' (since := "2024-08-28")] +def alephIdx : Cardinal → Ordinal := + aleph'.symm + +set_option linter.deprecated false in +@[deprecated (since := "2024-08-28")] +theorem alephIdx.initialSeg_coe : (alephIdx.initialSeg : Cardinal → Ordinal) = alephIdx := + rfl + +set_option linter.deprecated false in +@[deprecated (since := "2024-08-28")] +theorem alephIdx_lt {a b} : alephIdx a < alephIdx b ↔ a < b := + alephIdx.initialSeg.toRelEmbedding.map_rel_iff + +set_option linter.deprecated false in +@[deprecated (since := "2024-08-28")] +theorem alephIdx_le {a b} : alephIdx a ≤ alephIdx b ↔ a ≤ b := by + rw [← not_lt, ← not_lt, alephIdx_lt] + +set_option linter.deprecated false in +@[deprecated (since := "2024-08-28")] +theorem alephIdx.init {a b} : b < alephIdx a → ∃ c, alephIdx c = b := + alephIdx.initialSeg.init + +set_option linter.deprecated false in +@[deprecated (since := "2024-08-28")] +theorem alephIdx.relIso_coe : (alephIdx.relIso : Cardinal → Ordinal) = alephIdx := + rfl + +@[simp] +theorem type_cardinal : @type Cardinal (· < ·) _ = Ordinal.univ.{u, u + 1} := by + rw [Ordinal.univ_id] + exact Quotient.sound ⟨aleph'.symm.toRelIsoLT⟩ + +@[simp] +theorem mk_cardinal : #Cardinal = univ.{u, u + 1} := by + simpa only [card_type, card_univ] using congr_arg card type_cardinal + +/-- The `aleph'` function gives the cardinals listed by their ordinal + index, and is the inverse of `aleph_idx`. + `aleph' n = n`, `aleph' ω = ω`, `aleph' (ω + 1) = succ ℵ₀`, etc. + In this version, we register additionally that this function is an order isomorphism + between ordinals and cardinals. + For the basic function version, see `aleph'`. -/ +@[deprecated aleph' (since := "2024-08-28")] +def Aleph'.relIso := + aleph' + +set_option linter.deprecated false in +@[deprecated (since := "2024-08-28")] +theorem aleph'.relIso_coe : (Aleph'.relIso : Ordinal → Cardinal) = aleph' := + rfl + +theorem aleph'_lt {o₁ o₂ : Ordinal} : aleph' o₁ < aleph' o₂ ↔ o₁ < o₂ := + aleph'.lt_iff_lt + +theorem aleph'_le {o₁ o₂ : Ordinal} : aleph' o₁ ≤ aleph' o₂ ↔ o₁ ≤ o₂ := + aleph'.le_iff_le + +theorem aleph'_max (o₁ o₂ : Ordinal) : aleph' (max o₁ o₂) = max (aleph' o₁) (aleph' o₂) := + aleph'.monotone.map_max + +set_option linter.deprecated false in +@[deprecated (since := "2024-08-28")] +theorem aleph'_alephIdx (c : Cardinal) : aleph' c.alephIdx = c := + Cardinal.alephIdx.relIso.toEquiv.symm_apply_apply c + +set_option linter.deprecated false in +@[deprecated (since := "2024-08-28")] +theorem alephIdx_aleph' (o : Ordinal) : (aleph' o).alephIdx = o := + Cardinal.alephIdx.relIso.toEquiv.apply_symm_apply o + +@[simp] +theorem aleph'_zero : aleph' 0 = 0 := + aleph'.map_bot + +@[simp] +theorem aleph'_succ (o : Ordinal) : aleph' (succ o) = succ (aleph' o) := + aleph'.map_succ o + +@[simp] +theorem aleph'_nat : ∀ n : ℕ, aleph' n = n + | 0 => aleph'_zero + | n + 1 => show aleph' (succ n) = n.succ by rw [aleph'_succ, aleph'_nat n, nat_succ] + +theorem aleph'_le_of_limit {o : Ordinal} (l : o.IsLimit) {c} : + aleph' o ≤ c ↔ ∀ o' < o, aleph' o' ≤ c := + ⟨fun h o' h' => (aleph'_le.2 <| h'.le).trans h, fun h => by + rw [← aleph'.apply_symm_apply c, aleph'_le, limit_le l] + intro x h' + rw [← aleph'_le, aleph'.apply_symm_apply] + exact h _ h'⟩ + +theorem aleph'_limit {o : Ordinal} (ho : o.IsLimit) : aleph' o = ⨆ a : Iio o, aleph' a := by + refine le_antisymm ?_ (ciSup_le' fun i => aleph'_le.2 (le_of_lt i.2)) + rw [aleph'_le_of_limit ho] + exact fun a ha => le_ciSup (bddAbove_of_small _) (⟨a, ha⟩ : Iio o) + +@[simp] +theorem aleph'_omega0 : aleph' ω = ℵ₀ := + eq_of_forall_ge_iff fun c => by + simp only [aleph'_le_of_limit omega0_isLimit, lt_omega0, exists_imp, aleph0_le] + exact forall_swap.trans (forall_congr' fun n => by simp only [forall_eq, aleph'_nat]) + +@[deprecated (since := "2024-09-30")] +alias aleph'_omega := aleph'_omega0 + +set_option linter.deprecated false in +/-- `aleph'` and `aleph_idx` form an equivalence between `Ordinal` and `Cardinal` -/ +@[deprecated aleph' (since := "2024-08-28")] +def aleph'Equiv : Ordinal ≃ Cardinal := + ⟨aleph', alephIdx, alephIdx_aleph', aleph'_alephIdx⟩ + +/-- The `aleph` function gives the infinite cardinals listed by their ordinal index. `aleph 0 = ℵ₀`, +`aleph 1 = succ ℵ₀` is the first uncountable cardinal, and so on. + +For a version including finite cardinals, see `Cardinal.aleph'`. -/ +def aleph : Ordinal ↪o Cardinal := + (OrderEmbedding.addLeft ω).trans aleph'.toOrderEmbedding + +theorem aleph_eq_aleph' (o : Ordinal) : aleph o = aleph' (ω + o) := + rfl + +theorem aleph_lt {o₁ o₂ : Ordinal} : aleph o₁ < aleph o₂ ↔ o₁ < o₂ := + aleph.lt_iff_lt + +theorem aleph_le {o₁ o₂ : Ordinal} : aleph o₁ ≤ aleph o₂ ↔ o₁ ≤ o₂ := + aleph.le_iff_le + +theorem aleph_max (o₁ o₂ : Ordinal) : aleph (max o₁ o₂) = max (aleph o₁) (aleph o₂) := + aleph.monotone.map_max + +@[deprecated aleph_max (since := "2024-08-28")] +theorem max_aleph_eq (o₁ o₂ : Ordinal) : max (aleph o₁) (aleph o₂) = aleph (max o₁ o₂) := + (aleph_max o₁ o₂).symm + +@[simp] +theorem aleph_succ (o : Ordinal) : aleph (succ o) = succ (aleph o) := by + rw [aleph_eq_aleph', add_succ, aleph'_succ, aleph_eq_aleph'] + +@[simp] +theorem aleph_zero : aleph 0 = ℵ₀ := by rw [aleph_eq_aleph', add_zero, aleph'_omega0] + +theorem aleph_limit {o : Ordinal} (ho : o.IsLimit) : aleph o = ⨆ a : Iio o, aleph a := by + apply le_antisymm _ (ciSup_le' _) + · rw [aleph_eq_aleph', aleph'_limit (ho.add _)] + refine ciSup_mono' (bddAbove_of_small _) ?_ + rintro ⟨i, hi⟩ + cases' lt_or_le i ω with h h + · rcases lt_omega0.1 h with ⟨n, rfl⟩ + use ⟨0, ho.pos⟩ + simpa using (nat_lt_aleph0 n).le + · exact ⟨⟨_, (sub_lt_of_le h).2 hi⟩, aleph'_le.2 (le_add_sub _ _)⟩ + · exact fun i => aleph_le.2 (le_of_lt i.2) + +theorem aleph0_le_aleph' {o : Ordinal} : ℵ₀ ≤ aleph' o ↔ ω ≤ o := by rw [← aleph'_omega0, aleph'_le] + +theorem aleph0_le_aleph (o : Ordinal) : ℵ₀ ≤ aleph o := by + rw [aleph_eq_aleph', aleph0_le_aleph'] + apply Ordinal.le_add_right + +theorem aleph'_pos {o : Ordinal} (ho : 0 < o) : 0 < aleph' o := by rwa [← aleph'_zero, aleph'_lt] + +theorem aleph_pos (o : Ordinal) : 0 < aleph o := + aleph0_pos.trans_le (aleph0_le_aleph o) + +@[simp] +theorem aleph_toNat (o : Ordinal) : toNat (aleph o) = 0 := + toNat_apply_of_aleph0_le <| aleph0_le_aleph o + +@[simp] +theorem aleph_toPartENat (o : Ordinal) : toPartENat (aleph o) = ⊤ := + toPartENat_apply_of_aleph0_le <| aleph0_le_aleph o + +instance nonempty_toType_aleph (o : Ordinal) : Nonempty (aleph o).ord.toType := by + rw [toType_nonempty_iff_ne_zero, ← ord_zero] + exact fun h => (ord_injective h).not_gt (aleph_pos o) + +theorem ord_aleph_isLimit (o : Ordinal) : (aleph o).ord.IsLimit := + ord_isLimit <| aleph0_le_aleph _ + +instance (o : Ordinal) : NoMaxOrder (aleph o).ord.toType := + toType_noMax_of_succ_lt (ord_aleph_isLimit o).2 + +theorem exists_aleph {c : Cardinal} : ℵ₀ ≤ c ↔ ∃ o, c = aleph o := + ⟨fun h => + ⟨aleph'.symm c - ω, by + rw [aleph_eq_aleph', Ordinal.add_sub_cancel_of_le, aleph'.apply_symm_apply] + rwa [← aleph0_le_aleph', aleph'.apply_symm_apply]⟩, + fun ⟨o, e⟩ => e.symm ▸ aleph0_le_aleph _⟩ + +theorem aleph'_isNormal : IsNormal (ord ∘ aleph') := + ⟨fun o => ord_lt_ord.2 <| aleph'_lt.2 <| lt_succ o, fun o l a => by + simp [ord_le, aleph'_le_of_limit l]⟩ + +theorem aleph_isNormal : IsNormal (ord ∘ aleph) := + aleph'_isNormal.trans <| add_isNormal ω + +theorem succ_aleph0 : succ ℵ₀ = aleph 1 := by rw [← aleph_zero, ← aleph_succ, Ordinal.succ_zero] + +theorem aleph0_lt_aleph_one : ℵ₀ < aleph 1 := by + rw [← succ_aleph0] + apply lt_succ + +theorem countable_iff_lt_aleph_one {α : Type*} (s : Set α) : s.Countable ↔ #s < aleph 1 := by + rw [← succ_aleph0, lt_succ_iff, le_aleph0_iff_set_countable] + +section deprecated + +set_option linter.deprecated false + +-- TODO: these lemmas should be stated in terms of the `ω` function and of an `IsInitial` predicate, +-- neither of which currently exist. +-- +-- They should also use `¬ BddAbove` instead of `Unbounded (· < ·)`. + +/-- Ordinals that are cardinals are unbounded. -/ +@[deprecated (since := "2024-09-24")] +theorem ord_card_unbounded : Unbounded (· < ·) { b : Ordinal | b.card.ord = b } := + unbounded_lt_iff.2 fun a => + ⟨_, + ⟨by + dsimp + rw [card_ord], (lt_ord_succ_card a).le⟩⟩ + +@[deprecated (since := "2024-09-24")] +theorem eq_aleph'_of_eq_card_ord {o : Ordinal} (ho : o.card.ord = o) : ∃ a, (aleph' a).ord = o := + ⟨aleph'.symm o.card, by simpa using ho⟩ + +/-- Infinite ordinals that are cardinals are unbounded. -/ +@[deprecated (since := "2024-09-24")] +theorem ord_card_unbounded' : Unbounded (· < ·) { b : Ordinal | b.card.ord = b ∧ ω ≤ b } := + (unbounded_lt_inter_le ω).2 ord_card_unbounded + +@[deprecated (since := "2024-09-24")] +theorem eq_aleph_of_eq_card_ord {o : Ordinal} (ho : o.card.ord = o) (ho' : ω ≤ o) : + ∃ a, (aleph a).ord = o := by + cases' eq_aleph'_of_eq_card_ord ho with a ha + use a - ω + rwa [aleph_eq_aleph', Ordinal.add_sub_cancel_of_le] + rwa [← aleph0_le_aleph', ← ord_le_ord, ha, ord_aleph0] + +end deprecated + +/-! ### Beth cardinals -/ + +/-- Beth numbers are defined so that `beth 0 = ℵ₀`, `beth (succ o) = 2 ^ (beth o)`, and when `o` is +a limit ordinal, `beth o` is the supremum of `beth o'` for `o' < o`. + +Assuming the generalized continuum hypothesis, which is undecidable in ZFC, `beth o = aleph o` for +every `o`. -/ +def beth (o : Ordinal.{u}) : Cardinal.{u} := + limitRecOn o aleph0 (fun _ x => (2 : Cardinal) ^ x) fun a _ IH => ⨆ b : Iio a, IH b.1 b.2 + +@[simp] +theorem beth_zero : beth 0 = aleph0 := + limitRecOn_zero _ _ _ + +@[simp] +theorem beth_succ (o : Ordinal) : beth (succ o) = 2 ^ beth o := + limitRecOn_succ _ _ _ _ + +theorem beth_limit {o : Ordinal} : o.IsLimit → beth o = ⨆ a : Iio o, beth a := + limitRecOn_limit _ _ _ _ + +theorem beth_strictMono : StrictMono beth := by + intro a b + induction' b using Ordinal.induction with b IH generalizing a + intro h + rcases zero_or_succ_or_limit b with (rfl | ⟨c, rfl⟩ | hb) + · exact (Ordinal.not_lt_zero a h).elim + · rw [lt_succ_iff] at h + rw [beth_succ] + apply lt_of_le_of_lt _ (cantor _) + rcases eq_or_lt_of_le h with (rfl | h) + · rfl + exact (IH c (lt_succ c) h).le + · apply (cantor _).trans_le + rw [beth_limit hb, ← beth_succ] + exact le_ciSup (bddAbove_of_small _) (⟨_, hb.succ_lt h⟩ : Iio b) + +theorem beth_mono : Monotone beth := + beth_strictMono.monotone + +@[simp] +theorem beth_lt {o₁ o₂ : Ordinal} : beth o₁ < beth o₂ ↔ o₁ < o₂ := + beth_strictMono.lt_iff_lt + +@[simp] +theorem beth_le {o₁ o₂ : Ordinal} : beth o₁ ≤ beth o₂ ↔ o₁ ≤ o₂ := + beth_strictMono.le_iff_le + +theorem aleph_le_beth (o : Ordinal) : aleph o ≤ beth o := by + induction o using limitRecOn with + | H₁ => simp + | H₂ o h => + rw [aleph_succ, beth_succ, succ_le_iff] + exact (cantor _).trans_le (power_le_power_left two_ne_zero h) + | H₃ o ho IH => + rw [aleph_limit ho, beth_limit ho] + exact ciSup_mono (bddAbove_of_small _) fun x => IH x.1 x.2 + +theorem aleph0_le_beth (o : Ordinal) : ℵ₀ ≤ beth o := + (aleph0_le_aleph o).trans <| aleph_le_beth o + +theorem beth_pos (o : Ordinal) : 0 < beth o := + aleph0_pos.trans_le <| aleph0_le_beth o + +theorem beth_ne_zero (o : Ordinal) : beth o ≠ 0 := + (beth_pos o).ne' + +theorem beth_normal : IsNormal.{u} fun o => (beth o).ord := + (isNormal_iff_strictMono_limit _).2 + ⟨ord_strictMono.comp beth_strictMono, fun o ho a ha => by + rw [beth_limit ho, ord_le] + exact ciSup_le' fun b => ord_le.1 (ha _ b.2)⟩ + +end Cardinal + +/-! ### Omega ordinals -/ + +namespace Ordinal + +/-- +`ω_ o` is a notation for the *initial ordinal* of cardinality +`aleph o`. Thus, for example `ω_ 0 = ω`. +-/ +scoped notation "ω_" o => ord <| aleph o + +/-- +`ω₁` is the first uncountable ordinal. +-/ +scoped notation "ω₁" => ord <| aleph 1 + +lemma omega_lt_omega1 : ω < ω₁ := ord_aleph0.symm.trans_lt (ord_lt_ord.mpr (aleph0_lt_aleph_one)) + +end Ordinal diff --git a/Mathlib/SetTheory/Cardinal/Ordinal.lean b/Mathlib/SetTheory/Cardinal/Arithmetic.lean similarity index 67% rename from Mathlib/SetTheory/Cardinal/Ordinal.lean rename to Mathlib/SetTheory/Cardinal/Arithmetic.lean index 2126055537d6ce..4bb8721a053d7a 100644 --- a/Mathlib/SetTheory/Cardinal/Ordinal.lean +++ b/Mathlib/SetTheory/Cardinal/Arithmetic.lean @@ -3,37 +3,22 @@ Copyright (c) 2017 Johannes Hölzl. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Johannes Hölzl, Mario Carneiro, Floris van Doorn -/ -import Mathlib.Order.Bounded -import Mathlib.SetTheory.Cardinal.PartENat +import Mathlib.SetTheory.Cardinal.Aleph import Mathlib.SetTheory.Ordinal.Principal -import Mathlib.SetTheory.Ordinal.Enum import Mathlib.Tactic.Linarith /-! -# Cardinals and ordinals +# Cardinal arithmetic -Relationships between cardinals and ordinals, properties of cardinals that are proved -using ordinals. - -## Main definitions - -* The function `Cardinal.aleph'` gives the cardinals listed by their ordinal index. - `aleph' n = n`, `aleph' ω = ℵ₀`, `aleph' (ω + 1) = succ ℵ₀`, etc. - It is an order isomorphism between ordinals and cardinals. -* The function `Cardinal.aleph` gives the infinite cardinals listed by their - ordinal index. `aleph 0 = ℵ₀`, `aleph 1 = succ ℵ₀` is the first - uncountable cardinal, and so on. The notation `ω_` combines the latter with `Cardinal.ord`, - giving an enumeration of (infinite) initial ordinals. - Thus `ω_ 0 = ω` and `ω₁ = ω_ 1` is the first uncountable ordinal. -* The function `Cardinal.beth` enumerates the Beth cardinals. `beth 0 = ℵ₀`, - `beth (succ o) = 2 ^ beth o`, and for a limit ordinal `o`, `beth o` is the supremum of `beth a` - for `a < o`. +Arithmetic operations on cardinals are defined in `SetTheory/Cardinal/Basic.lean`. However, proving +the important theorem `c * c = c` for infinite cardinals and its corollaries requires the use of +ordinal numbers. This is done within this file. ## Main statements * `Cardinal.mul_eq_max` and `Cardinal.add_eq_max` state that the product (resp. sum) of two infinite cardinals is just their maximum. Several variations around this fact are also given. -* `Cardinal.mk_list_eq_mk` : when `α` is infinite, `α` and `List α` have the same cardinality. +* `Cardinal.mk_list_eq_mk`: when `α` is infinite, `α` and `List α` have the same cardinality. ## Tags @@ -51,398 +36,8 @@ universe u v w namespace Cardinal -section UsingOrdinals - -theorem ord_isLimit {c} (co : ℵ₀ ≤ c) : (ord c).IsLimit := by - refine ⟨fun h => aleph0_ne_zero ?_, fun a => lt_imp_lt_of_le_imp_le fun h => ?_⟩ - · rw [← Ordinal.le_zero, ord_le] at h - simpa only [card_zero, nonpos_iff_eq_zero] using co.trans h - · rw [ord_le] at h ⊢ - rwa [← @add_one_of_aleph0_le (card a), ← card_succ] - rw [← ord_le, ← le_succ_of_isLimit, ord_le] - · exact co.trans h - · rw [ord_aleph0] - exact omega0_isLimit - -theorem noMaxOrder {c} (h : ℵ₀ ≤ c) : NoMaxOrder c.ord.toType := - toType_noMax_of_succ_lt (ord_isLimit h).2 - -/-! ### Aleph cardinals -/ - -section aleph - -/-- The `aleph'` function gives the cardinals listed by their ordinal index. `aleph' n = n`, -`aleph' ω = ℵ₀`, `aleph' (ω + 1) = succ ℵ₀`, etc. - -For the more common aleph function skipping over finite cardinals, see `Cardinal.aleph`. -/ -def aleph' : Ordinal.{u} ≃o Cardinal.{u} := by - let f := RelEmbedding.collapse Cardinal.ord.orderEmbedding.ltEmbedding.{u} - refine (OrderIso.ofRelIsoLT <| RelIso.ofSurjective f ?_).symm - apply f.eq_or_principal.resolve_right - rintro ⟨o, e⟩ - have : ∀ c, f c < o := fun c => (e _).1 ⟨_, rfl⟩ - refine Ordinal.inductionOn o ?_ this - intro α r _ h - let s := ⨆ a, invFun f (Ordinal.typein r a) - apply (lt_succ s).not_le - have I : Injective f := f.toEmbedding.injective - simpa only [typein_enum, leftInverse_invFun I (succ s)] using - le_ciSup - (Cardinal.bddAbove_range.{u, u} fun a : α => invFun f (Ordinal.typein r a)) - (Ordinal.enum r ⟨_, h (succ s)⟩) - -/-- The `aleph'` index function, which gives the ordinal index of a cardinal. - (The `aleph'` part is because unlike `aleph` this counts also the - finite stages. So `alephIdx n = n`, `alephIdx ω = ω`, - `alephIdx ℵ₁ = ω + 1` and so on.) - In this definition, we register additionally that this function is an initial segment, - i.e., it is order preserving and its range is an initial segment of the ordinals. - For the basic function version, see `alephIdx`. - For an upgraded version stating that the range is everything, see `AlephIdx.rel_iso`. -/ -@[deprecated aleph' (since := "2024-08-28")] -def alephIdx.initialSeg : @InitialSeg Cardinal Ordinal (· < ·) (· < ·) := - @RelEmbedding.collapse Cardinal Ordinal (· < ·) (· < ·) _ Cardinal.ord.orderEmbedding.ltEmbedding - -/-- The `aleph'` index function, which gives the ordinal index of a cardinal. - (The `aleph'` part is because unlike `aleph` this counts also the - finite stages. So `alephIdx n = n`, `alephIdx ℵ₀ = ω`, - `alephIdx ℵ₁ = ω + 1` and so on.) - In this version, we register additionally that this function is an order isomorphism - between cardinals and ordinals. - For the basic function version, see `alephIdx`. -/ -@[deprecated aleph' (since := "2024-08-28")] -def alephIdx.relIso : @RelIso Cardinal.{u} Ordinal.{u} (· < ·) (· < ·) := - aleph'.symm.toRelIsoLT - -/-- The `aleph'` index function, which gives the ordinal index of a cardinal. - (The `aleph'` part is because unlike `aleph` this counts also the - finite stages. So `alephIdx n = n`, `alephIdx ω = ω`, - `alephIdx ℵ₁ = ω + 1` and so on.) - For an upgraded version stating that the range is everything, see `AlephIdx.rel_iso`. -/ -@[deprecated aleph' (since := "2024-08-28")] -def alephIdx : Cardinal → Ordinal := - aleph'.symm - -set_option linter.deprecated false in -@[deprecated (since := "2024-08-28")] -theorem alephIdx.initialSeg_coe : (alephIdx.initialSeg : Cardinal → Ordinal) = alephIdx := - rfl - -set_option linter.deprecated false in -@[deprecated (since := "2024-08-28")] -theorem alephIdx_lt {a b} : alephIdx a < alephIdx b ↔ a < b := - alephIdx.initialSeg.toRelEmbedding.map_rel_iff - -set_option linter.deprecated false in -@[deprecated (since := "2024-08-28")] -theorem alephIdx_le {a b} : alephIdx a ≤ alephIdx b ↔ a ≤ b := by - rw [← not_lt, ← not_lt, alephIdx_lt] - -set_option linter.deprecated false in -@[deprecated (since := "2024-08-28")] -theorem alephIdx.init {a b} : b < alephIdx a → ∃ c, alephIdx c = b := - alephIdx.initialSeg.init - -set_option linter.deprecated false in -@[deprecated (since := "2024-08-28")] -theorem alephIdx.relIso_coe : (alephIdx.relIso : Cardinal → Ordinal) = alephIdx := - rfl - -@[simp] -theorem type_cardinal : @type Cardinal (· < ·) _ = Ordinal.univ.{u, u + 1} := by - rw [Ordinal.univ_id] - exact Quotient.sound ⟨aleph'.symm.toRelIsoLT⟩ - -@[simp] -theorem mk_cardinal : #Cardinal = univ.{u, u + 1} := by - simpa only [card_type, card_univ] using congr_arg card type_cardinal - -/-- The `aleph'` function gives the cardinals listed by their ordinal - index, and is the inverse of `aleph_idx`. - `aleph' n = n`, `aleph' ω = ω`, `aleph' (ω + 1) = succ ℵ₀`, etc. - In this version, we register additionally that this function is an order isomorphism - between ordinals and cardinals. - For the basic function version, see `aleph'`. -/ -@[deprecated aleph' (since := "2024-08-28")] -def Aleph'.relIso := - aleph' - -set_option linter.deprecated false in -@[deprecated (since := "2024-08-28")] -theorem aleph'.relIso_coe : (Aleph'.relIso : Ordinal → Cardinal) = aleph' := - rfl - -theorem aleph'_lt {o₁ o₂ : Ordinal} : aleph' o₁ < aleph' o₂ ↔ o₁ < o₂ := - aleph'.lt_iff_lt - -theorem aleph'_le {o₁ o₂ : Ordinal} : aleph' o₁ ≤ aleph' o₂ ↔ o₁ ≤ o₂ := - aleph'.le_iff_le - -theorem aleph'_max (o₁ o₂ : Ordinal) : aleph' (max o₁ o₂) = max (aleph' o₁) (aleph' o₂) := - aleph'.monotone.map_max - -set_option linter.deprecated false in -@[deprecated (since := "2024-08-28")] -theorem aleph'_alephIdx (c : Cardinal) : aleph' c.alephIdx = c := - Cardinal.alephIdx.relIso.toEquiv.symm_apply_apply c - -set_option linter.deprecated false in -@[deprecated (since := "2024-08-28")] -theorem alephIdx_aleph' (o : Ordinal) : (aleph' o).alephIdx = o := - Cardinal.alephIdx.relIso.toEquiv.apply_symm_apply o - -@[simp] -theorem aleph'_zero : aleph' 0 = 0 := - aleph'.map_bot - -@[simp] -theorem aleph'_succ (o : Ordinal) : aleph' (succ o) = succ (aleph' o) := - aleph'.map_succ o - -@[simp] -theorem aleph'_nat : ∀ n : ℕ, aleph' n = n - | 0 => aleph'_zero - | n + 1 => show aleph' (succ n) = n.succ by rw [aleph'_succ, aleph'_nat n, nat_succ] - -theorem aleph'_le_of_limit {o : Ordinal} (l : o.IsLimit) {c} : - aleph' o ≤ c ↔ ∀ o' < o, aleph' o' ≤ c := - ⟨fun h o' h' => (aleph'_le.2 <| h'.le).trans h, fun h => by - rw [← aleph'.apply_symm_apply c, aleph'_le, limit_le l] - intro x h' - rw [← aleph'_le, aleph'.apply_symm_apply] - exact h _ h'⟩ - -theorem aleph'_limit {o : Ordinal} (ho : o.IsLimit) : aleph' o = ⨆ a : Iio o, aleph' a := by - refine le_antisymm ?_ (ciSup_le' fun i => aleph'_le.2 (le_of_lt i.2)) - rw [aleph'_le_of_limit ho] - exact fun a ha => le_ciSup (bddAbove_of_small _) (⟨a, ha⟩ : Iio o) - -@[simp] -theorem aleph'_omega0 : aleph' ω = ℵ₀ := - eq_of_forall_ge_iff fun c => by - simp only [aleph'_le_of_limit omega0_isLimit, lt_omega0, exists_imp, aleph0_le] - exact forall_swap.trans (forall_congr' fun n => by simp only [forall_eq, aleph'_nat]) - -@[deprecated (since := "2024-09-30")] -alias aleph'_omega := aleph'_omega0 - -set_option linter.deprecated false in -/-- `aleph'` and `aleph_idx` form an equivalence between `Ordinal` and `Cardinal` -/ -@[deprecated aleph' (since := "2024-08-28")] -def aleph'Equiv : Ordinal ≃ Cardinal := - ⟨aleph', alephIdx, alephIdx_aleph', aleph'_alephIdx⟩ - -/-- The `aleph` function gives the infinite cardinals listed by their ordinal index. `aleph 0 = ℵ₀`, -`aleph 1 = succ ℵ₀` is the first uncountable cardinal, and so on. - -For a version including finite cardinals, see `Cardinal.aleph'`. -/ -def aleph : Ordinal ↪o Cardinal := - (OrderEmbedding.addLeft ω).trans aleph'.toOrderEmbedding - -theorem aleph_eq_aleph' (o : Ordinal) : aleph o = aleph' (ω + o) := - rfl - -theorem aleph_lt {o₁ o₂ : Ordinal} : aleph o₁ < aleph o₂ ↔ o₁ < o₂ := - aleph.lt_iff_lt - -theorem aleph_le {o₁ o₂ : Ordinal} : aleph o₁ ≤ aleph o₂ ↔ o₁ ≤ o₂ := - aleph.le_iff_le - -theorem aleph_max (o₁ o₂ : Ordinal) : aleph (max o₁ o₂) = max (aleph o₁) (aleph o₂) := - aleph.monotone.map_max - -@[deprecated aleph_max (since := "2024-08-28")] -theorem max_aleph_eq (o₁ o₂ : Ordinal) : max (aleph o₁) (aleph o₂) = aleph (max o₁ o₂) := - (aleph_max o₁ o₂).symm - -@[simp] -theorem aleph_succ (o : Ordinal) : aleph (succ o) = succ (aleph o) := by - rw [aleph_eq_aleph', add_succ, aleph'_succ, aleph_eq_aleph'] - -@[simp] -theorem aleph_zero : aleph 0 = ℵ₀ := by rw [aleph_eq_aleph', add_zero, aleph'_omega0] - -theorem aleph_limit {o : Ordinal} (ho : o.IsLimit) : aleph o = ⨆ a : Iio o, aleph a := by - apply le_antisymm _ (ciSup_le' _) - · rw [aleph_eq_aleph', aleph'_limit (ho.add _)] - refine ciSup_mono' (bddAbove_of_small _) ?_ - rintro ⟨i, hi⟩ - cases' lt_or_le i ω with h h - · rcases lt_omega0.1 h with ⟨n, rfl⟩ - use ⟨0, ho.pos⟩ - simpa using (nat_lt_aleph0 n).le - · exact ⟨⟨_, (sub_lt_of_le h).2 hi⟩, aleph'_le.2 (le_add_sub _ _)⟩ - · exact fun i => aleph_le.2 (le_of_lt i.2) - -theorem aleph0_le_aleph' {o : Ordinal} : ℵ₀ ≤ aleph' o ↔ ω ≤ o := by rw [← aleph'_omega0, aleph'_le] - -theorem aleph0_le_aleph (o : Ordinal) : ℵ₀ ≤ aleph o := by - rw [aleph_eq_aleph', aleph0_le_aleph'] - apply Ordinal.le_add_right - -theorem aleph'_pos {o : Ordinal} (ho : 0 < o) : 0 < aleph' o := by rwa [← aleph'_zero, aleph'_lt] - -theorem aleph_pos (o : Ordinal) : 0 < aleph o := - aleph0_pos.trans_le (aleph0_le_aleph o) - -@[simp] -theorem aleph_toNat (o : Ordinal) : toNat (aleph o) = 0 := - toNat_apply_of_aleph0_le <| aleph0_le_aleph o - -@[simp] -theorem aleph_toPartENat (o : Ordinal) : toPartENat (aleph o) = ⊤ := - toPartENat_apply_of_aleph0_le <| aleph0_le_aleph o - -instance nonempty_toType_aleph (o : Ordinal) : Nonempty (aleph o).ord.toType := by - rw [toType_nonempty_iff_ne_zero, ← ord_zero] - exact fun h => (ord_injective h).not_gt (aleph_pos o) - -theorem ord_aleph_isLimit (o : Ordinal) : (aleph o).ord.IsLimit := - ord_isLimit <| aleph0_le_aleph _ - -instance (o : Ordinal) : NoMaxOrder (aleph o).ord.toType := - toType_noMax_of_succ_lt (ord_aleph_isLimit o).2 - -theorem exists_aleph {c : Cardinal} : ℵ₀ ≤ c ↔ ∃ o, c = aleph o := - ⟨fun h => - ⟨aleph'.symm c - ω, by - rw [aleph_eq_aleph', Ordinal.add_sub_cancel_of_le, aleph'.apply_symm_apply] - rwa [← aleph0_le_aleph', aleph'.apply_symm_apply]⟩, - fun ⟨o, e⟩ => e.symm ▸ aleph0_le_aleph _⟩ - -theorem aleph'_isNormal : IsNormal (ord ∘ aleph') := - ⟨fun o => ord_lt_ord.2 <| aleph'_lt.2 <| lt_succ o, fun o l a => by - simp [ord_le, aleph'_le_of_limit l]⟩ - -theorem aleph_isNormal : IsNormal (ord ∘ aleph) := - aleph'_isNormal.trans <| add_isNormal ω - -theorem succ_aleph0 : succ ℵ₀ = aleph 1 := by rw [← aleph_zero, ← aleph_succ, Ordinal.succ_zero] - -theorem aleph0_lt_aleph_one : ℵ₀ < aleph 1 := by - rw [← succ_aleph0] - apply lt_succ - -theorem countable_iff_lt_aleph_one {α : Type*} (s : Set α) : s.Countable ↔ #s < aleph 1 := by - rw [← succ_aleph0, lt_succ_iff, le_aleph0_iff_set_countable] - -section deprecated - -set_option linter.deprecated false - --- TODO: these lemmas should be stated in terms of the `ω` function and of an `IsInitial` predicate, --- neither of which currently exist. --- --- They should also use `¬ BddAbove` instead of `Unbounded (· < ·)`. - -/-- Ordinals that are cardinals are unbounded. -/ -@[deprecated (since := "2024-09-24")] -theorem ord_card_unbounded : Unbounded (· < ·) { b : Ordinal | b.card.ord = b } := - unbounded_lt_iff.2 fun a => - ⟨_, - ⟨by - dsimp - rw [card_ord], (lt_ord_succ_card a).le⟩⟩ - -@[deprecated (since := "2024-09-24")] -theorem eq_aleph'_of_eq_card_ord {o : Ordinal} (ho : o.card.ord = o) : ∃ a, (aleph' a).ord = o := - ⟨aleph'.symm o.card, by simpa using ho⟩ - -/-- Infinite ordinals that are cardinals are unbounded. -/ -@[deprecated (since := "2024-09-24")] -theorem ord_card_unbounded' : Unbounded (· < ·) { b : Ordinal | b.card.ord = b ∧ ω ≤ b } := - (unbounded_lt_inter_le ω).2 ord_card_unbounded - -@[deprecated (since := "2024-09-24")] -theorem eq_aleph_of_eq_card_ord {o : Ordinal} (ho : o.card.ord = o) (ho' : ω ≤ o) : - ∃ a, (aleph a).ord = o := by - cases' eq_aleph'_of_eq_card_ord ho with a ha - use a - ω - rwa [aleph_eq_aleph', Ordinal.add_sub_cancel_of_le] - rwa [← aleph0_le_aleph', ← ord_le_ord, ha, ord_aleph0] - -end deprecated - -end aleph - -/-! ### Beth cardinals -/ -section beth - -/-- Beth numbers are defined so that `beth 0 = ℵ₀`, `beth (succ o) = 2 ^ (beth o)`, and when `o` is -a limit ordinal, `beth o` is the supremum of `beth o'` for `o' < o`. - -Assuming the generalized continuum hypothesis, which is undecidable in ZFC, `beth o = aleph o` for -every `o`. -/ -def beth (o : Ordinal.{u}) : Cardinal.{u} := - limitRecOn o aleph0 (fun _ x => (2 : Cardinal) ^ x) fun a _ IH => ⨆ b : Iio a, IH b.1 b.2 - -@[simp] -theorem beth_zero : beth 0 = aleph0 := - limitRecOn_zero _ _ _ - -@[simp] -theorem beth_succ (o : Ordinal) : beth (succ o) = 2 ^ beth o := - limitRecOn_succ _ _ _ _ - -theorem beth_limit {o : Ordinal} : o.IsLimit → beth o = ⨆ a : Iio o, beth a := - limitRecOn_limit _ _ _ _ - -theorem beth_strictMono : StrictMono beth := by - intro a b - induction' b using Ordinal.induction with b IH generalizing a - intro h - rcases zero_or_succ_or_limit b with (rfl | ⟨c, rfl⟩ | hb) - · exact (Ordinal.not_lt_zero a h).elim - · rw [lt_succ_iff] at h - rw [beth_succ] - apply lt_of_le_of_lt _ (cantor _) - rcases eq_or_lt_of_le h with (rfl | h) - · rfl - exact (IH c (lt_succ c) h).le - · apply (cantor _).trans_le - rw [beth_limit hb, ← beth_succ] - exact le_ciSup (bddAbove_of_small _) (⟨_, hb.succ_lt h⟩ : Iio b) - -theorem beth_mono : Monotone beth := - beth_strictMono.monotone - -@[simp] -theorem beth_lt {o₁ o₂ : Ordinal} : beth o₁ < beth o₂ ↔ o₁ < o₂ := - beth_strictMono.lt_iff_lt - -@[simp] -theorem beth_le {o₁ o₂ : Ordinal} : beth o₁ ≤ beth o₂ ↔ o₁ ≤ o₂ := - beth_strictMono.le_iff_le - -theorem aleph_le_beth (o : Ordinal) : aleph o ≤ beth o := by - induction o using limitRecOn with - | H₁ => simp - | H₂ o h => - rw [aleph_succ, beth_succ, succ_le_iff] - exact (cantor _).trans_le (power_le_power_left two_ne_zero h) - | H₃ o ho IH => - rw [aleph_limit ho, beth_limit ho] - exact ciSup_mono (bddAbove_of_small _) fun x => IH x.1 x.2 - -theorem aleph0_le_beth (o : Ordinal) : ℵ₀ ≤ beth o := - (aleph0_le_aleph o).trans <| aleph_le_beth o - -theorem beth_pos (o : Ordinal) : 0 < beth o := - aleph0_pos.trans_le <| aleph0_le_beth o - -theorem beth_ne_zero (o : Ordinal) : beth o ≠ 0 := - (beth_pos o).ne' - -theorem beth_normal : IsNormal.{u} fun o => (beth o).ord := - (isNormal_iff_strictMono_limit _).2 - ⟨ord_strictMono.comp beth_strictMono, fun o ho a ha => by - rw [beth_limit ho, ord_le] - exact ciSup_le' fun b => ord_le.1 (ha _ b.2)⟩ - -end beth - /-! ### Properties of `mul` -/ -section mulOrdinals +section mul /-- If `α` is an infinite type, then `α × α` and `α` have the same cardinality. -/ theorem mul_eq_self {c : Cardinal} (h : ℵ₀ ≤ c) : c * c = c := by @@ -491,13 +86,6 @@ theorem mul_eq_self {c : Cardinal} (h : ℵ₀ ≤ c) : c * c = c := by rw [mk'_def, e] apply typein_lt_type -end mulOrdinals - -end UsingOrdinals - -/-! Properties of `mul`, not requiring ordinals -/ -section mul - /-- If `α` and `β` are infinite types, then the cardinality of `α × β` is the maximum of the cardinalities of `α` and `β`. -/ theorem mul_eq_max {a b : Cardinal} (ha : ℵ₀ ≤ a) (hb : ℵ₀ ≤ b) : a * b = max a b := @@ -768,6 +356,7 @@ protected theorem eq_of_add_eq_add_right {a b c : Cardinal} (h : a + b = c + b) end add +/-! ### Properties of `ciSup` -/ section ciSup variable {ι : Type u} {ι' : Type w} (f : ι → Cardinal.{v}) @@ -828,6 +417,9 @@ protected theorem ciSup_mul_ciSup (g : ι' → Cardinal.{v}) : end ciSup +/-! ### Properties of `aleph` -/ +section aleph + @[simp] theorem aleph_add_aleph (o₁ o₂ : Ordinal) : aleph o₁ + aleph o₂ = aleph (max o₁ o₂) := by rw [Cardinal.add_eq_max (aleph0_le_aleph o₁), aleph_max] @@ -872,8 +464,10 @@ theorem add_one_le_add_one_iff {α β : Cardinal} : α + 1 ≤ β + 1 ↔ α ≤ @[deprecated (since := "2024-02-12")] alias add_one_le_add_one_iff_of_lt_aleph_0 := add_one_le_add_one_iff -/-! ### Properties about power -/ -section pow +end aleph + +/-! ### Properties about `power` -/ +section power theorem pow_le {κ μ : Cardinal.{u}} (H1 : ℵ₀ ≤ κ) (H2 : μ < ℵ₀) : κ ^ μ ≤ κ := let ⟨n, H3⟩ := lt_aleph0.1 H2 @@ -948,7 +542,7 @@ theorem powerlt_aleph0_le (c : Cardinal) : c ^< ℵ₀ ≤ max c ℵ₀ := by rw [powerlt_le] exact fun c' hc' => (power_lt_aleph0 h hc').le.trans (le_max_right _ _) -end pow +end power /-! ### Computing cardinality of various types -/ section computing @@ -1192,6 +786,7 @@ theorem mk_compl_eq_mk_compl_finite_same {α : Type u} [Finite α] {s t : Set α end compl /-! ### Extending an injection to an equiv -/ +section extend theorem extend_function {α β : Type*} {s : Set α} (f : s ↪ β) (h : Nonempty ((sᶜ : Set α) ≃ ((range f)ᶜ : Set β))) : ∃ g : α ≃ β, ∀ x : s, g x = f x := by @@ -1221,31 +816,17 @@ theorem extend_function_of_lt {α β : Type*} {s : Set α} (f : s ↪ β) (hs : rwa [mk_compl_of_infinite s hs, mk_compl_of_infinite] rwa [← lift_lt, mk_range_eq_of_injective f.injective, ← h, lift_lt] -end Cardinal - -section Initial - -namespace Ordinal - -/-- -`ω_ o` is a notation for the *initial ordinal* of cardinality -`aleph o`. Thus, for example `ω_ 0 = ω`. --/ -scoped notation "ω_" o => ord <| aleph o - -/-- -`ω₁` is the first uncountable ordinal. --/ -scoped notation "ω₁" => ord <| aleph 1 +end extend -lemma omega0_lt_omega1 : ω < ω₁ := ord_aleph0.symm.trans_lt (ord_lt_ord.mpr (aleph0_lt_aleph_one)) +end Cardinal -section OrdinalIndices /-! ### Cardinal operations with ordinal indices Results on cardinality of ordinal-indexed families of sets. -/ + +namespace Ordinal namespace Cardinal open scoped Cardinal @@ -1263,9 +844,4 @@ lemma mk_iUnion_Ordinal_le_of_le {β : Type*} {o : Ordinal} {c : Cardinal} exact mul_le_mul' ho <| ciSup_le' <| (hA _ <| typein_lt_self ·) end Cardinal - -end OrdinalIndices - end Ordinal - -end Initial diff --git a/Mathlib/SetTheory/Cardinal/Cofinality.lean b/Mathlib/SetTheory/Cardinal/Cofinality.lean index 53bfb76a4a06ee..2452d83508b788 100644 --- a/Mathlib/SetTheory/Cardinal/Cofinality.lean +++ b/Mathlib/SetTheory/Cardinal/Cofinality.lean @@ -3,7 +3,7 @@ Copyright (c) 2017 Mario Carneiro. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Mario Carneiro, Floris van Doorn, Violeta Hernández Palacios -/ -import Mathlib.SetTheory.Cardinal.Ordinal +import Mathlib.SetTheory.Cardinal.Arithmetic import Mathlib.SetTheory.Ordinal.FixedPoint /-! diff --git a/Mathlib/SetTheory/Cardinal/Continuum.lean b/Mathlib/SetTheory/Cardinal/Continuum.lean index 9aeb9a15becb84..fa8694e0661e53 100644 --- a/Mathlib/SetTheory/Cardinal/Continuum.lean +++ b/Mathlib/SetTheory/Cardinal/Continuum.lean @@ -3,7 +3,7 @@ Copyright (c) 2021 Yury Kudryashov. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Yury Kudryashov -/ -import Mathlib.SetTheory.Cardinal.Ordinal +import Mathlib.SetTheory.Cardinal.Arithmetic /-! # Cardinality of continuum diff --git a/Mathlib/SetTheory/Cardinal/CountableCover.lean b/Mathlib/SetTheory/Cardinal/CountableCover.lean index 65caa5dd364f59..16eb4b46b329ca 100644 --- a/Mathlib/SetTheory/Cardinal/CountableCover.lean +++ b/Mathlib/SetTheory/Cardinal/CountableCover.lean @@ -3,7 +3,7 @@ Copyright (c) 2023 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.SetTheory.Cardinal.Ordinal +import Mathlib.SetTheory.Cardinal.Arithmetic import Mathlib.Order.Filter.Basic /-! diff --git a/Mathlib/SetTheory/Cardinal/Divisibility.lean b/Mathlib/SetTheory/Cardinal/Divisibility.lean index 4dac7f8531de2f..6a176f3246b65f 100644 --- a/Mathlib/SetTheory/Cardinal/Divisibility.lean +++ b/Mathlib/SetTheory/Cardinal/Divisibility.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Eric Rodriguez -/ import Mathlib.Algebra.IsPrimePow -import Mathlib.SetTheory.Cardinal.Ordinal +import Mathlib.SetTheory.Cardinal.Arithmetic import Mathlib.Tactic.WLOG /-! diff --git a/Mathlib/SetTheory/Cardinal/Finsupp.lean b/Mathlib/SetTheory/Cardinal/Finsupp.lean index d62685c418254e..b8d207a9558208 100644 --- a/Mathlib/SetTheory/Cardinal/Finsupp.lean +++ b/Mathlib/SetTheory/Cardinal/Finsupp.lean @@ -3,7 +3,7 @@ Copyright (c) 2022 Violeta Hernández Palacios. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Violeta Hernández Palacios, Junyan Xu -/ -import Mathlib.SetTheory.Cardinal.Ordinal +import Mathlib.SetTheory.Cardinal.Arithmetic import Mathlib.Data.Finsupp.Basic import Mathlib.Data.Finsupp.Multiset diff --git a/Mathlib/SetTheory/Ordinal/Arithmetic.lean b/Mathlib/SetTheory/Ordinal/Arithmetic.lean index 6752c67f0e1ccd..c98fcecd35665c 100644 --- a/Mathlib/SetTheory/Ordinal/Arithmetic.lean +++ b/Mathlib/SetTheory/Ordinal/Arithmetic.lean @@ -2375,6 +2375,26 @@ theorem sup_mul_nat (o : Ordinal) : (sup fun n : ℕ => o * n) = o * ω := by end Ordinal +namespace Cardinal + +open Ordinal + +theorem ord_isLimit {c} (co : ℵ₀ ≤ c) : (ord c).IsLimit := by + refine ⟨fun h => aleph0_ne_zero ?_, fun a => lt_imp_lt_of_le_imp_le fun h => ?_⟩ + · rw [← Ordinal.le_zero, ord_le] at h + simpa only [card_zero, nonpos_iff_eq_zero] using co.trans h + · rw [ord_le] at h ⊢ + rwa [← @add_one_of_aleph0_le (card a), ← card_succ] + rw [← ord_le, ← le_succ_of_isLimit, ord_le] + · exact co.trans h + · rw [ord_aleph0] + exact Ordinal.omega0_isLimit + +theorem noMaxOrder {c} (h : ℵ₀ ≤ c) : NoMaxOrder c.ord.toType := + toType_noMax_of_succ_lt (ord_isLimit h).2 + +end Cardinal + variable {α : Type u} {r : α → α → Prop} {a b : α} namespace Acc From 8600b594b8d31d759a70207309d292e4fd038f54 Mon Sep 17 00:00:00 2001 From: Dagur Asgeirsson Date: Fri, 11 Oct 2024 12:40:16 +0000 Subject: [PATCH 024/425] fix(Condensed): remove unnecessary @ (#17642) --- 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 3bcf129729c300..5657c6d51579e1 100644 --- a/Mathlib/Condensed/Discrete/Module.lean +++ b/Mathlib/Condensed/Discrete/Module.lean @@ -92,7 +92,7 @@ instance (M : ModuleCat R) : IsIso ((forget R).map ((discreteUnderlyingAdj (ModuleCat R)).counit.app ((functor R).obj M))) := by dsimp [Condensed.forget, discreteUnderlyingAdj] rw [← constantSheafAdj_counit_w] - refine @IsIso.comp_isIso _ _ _ _ _ _ _ inferInstance ?_ + refine IsIso.comp_isIso' inferInstance ?_ have : (constantSheaf (coherentTopology CompHaus) (Type (u + 1))).Faithful := inferInstanceAs (discrete _).Faithful have : (constantSheaf (coherentTopology CompHaus) (Type (u + 1))).Full := @@ -205,7 +205,7 @@ instance (M : ModuleCat R) : ((functor R).obj M))) := by dsimp [LightCondensed.forget, discreteUnderlyingAdj] rw [← constantSheafAdj_counit_w] - refine @IsIso.comp_isIso _ _ _ _ _ _ _ inferInstance ?_ + refine IsIso.comp_isIso' inferInstance ?_ have : (constantSheaf (coherentTopology LightProfinite) (Type u)).Faithful := inferInstanceAs (discrete _).Faithful have : (constantSheaf (coherentTopology LightProfinite) (Type u)).Full := From 9a934121c2756d98feab3cf79738ab3121d96deb Mon Sep 17 00:00:00 2001 From: Dagur Asgeirsson Date: Fri, 11 Oct 2024 12:40:18 +0000 Subject: [PATCH 025/425] fix(CategoryTheory/Sites): typos in module docstring of `PreservesSheafification` file (#17643) --- Mathlib/CategoryTheory/Sites/PreservesSheafification.lean | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/CategoryTheory/Sites/PreservesSheafification.lean b/Mathlib/CategoryTheory/Sites/PreservesSheafification.lean index ee99ef8e05d4a9..7e02c805dd32b6 100644 --- a/Mathlib/CategoryTheory/Sites/PreservesSheafification.lean +++ b/Mathlib/CategoryTheory/Sites/PreservesSheafification.lean @@ -8,7 +8,7 @@ import Mathlib.CategoryTheory.Sites.CompatibleSheafification import Mathlib.CategoryTheory.Sites.Whiskering import Mathlib.CategoryTheory.Sites.Sheafification -/-! # Functors which preserves sheafification +/-! # Functors which preserve sheafification In this file, given a Grothendieck topology `J` on `C` and `F : A ⥤ B`, we define a type class `J.PreservesSheafification F`. We say that `F` preserves @@ -20,7 +20,7 @@ this property for the map from any presheaf `P` to its associated sheaf, see In general, we define `Sheaf.composeAndSheafify J F : Sheaf J A ⥤ Sheaf J B` as the functor which sends a sheaf `G` to the sheafification of the composition `G.val ⋙ F`. -It `J.PreservesSheafification F`, we show that this functor can also be thought +If `J.PreservesSheafification F`, we show that this functor can also be thought of as the localization of the functor `_ ⋙ F` on presheaves: we construct an isomorphism `presheafToSheafCompComposeAndSheafifyIso` between `presheafToSheaf J A ⋙ Sheaf.composeAndSheafify J F` and @@ -29,7 +29,7 @@ as the localization of the functor `_ ⋙ F` on presheaves: we construct an isom Moreover, if we assume `J.HasSheafCompose F`, we obtain an isomorphism `sheafifyComposeIso J F P : sheafify J (P ⋙ F) ≅ sheafify J P ⋙ F`. -We show that under suitable assumptions, the forget functor from a concrete +We show that under suitable assumptions, the forgetful functor from a concrete category preserves sheafification; this holds more generally for functors between such concrete categories which commute both with suitable limits and colimits. From 15074a610b6379f345911dfab797f3b073fc5f62 Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Fri, 11 Oct 2024 13:11:00 +0000 Subject: [PATCH 026/425] feat(AlgebraicGeometry): factorization of morphisms with affine target (#15033) --- Mathlib/AlgebraicGeometry/AffineScheme.lean | 111 ++++++++++++++++++ .../GammaSpecAdjunction.lean | 10 ++ 2 files changed, 121 insertions(+) diff --git a/Mathlib/AlgebraicGeometry/AffineScheme.lean b/Mathlib/AlgebraicGeometry/AffineScheme.lean index c2d4e1cdc1f432..121a41fc2382f8 100644 --- a/Mathlib/AlgebraicGeometry/AffineScheme.lean +++ b/Mathlib/AlgebraicGeometry/AffineScheme.lean @@ -8,6 +8,7 @@ import Mathlib.AlgebraicGeometry.Restrict import Mathlib.AlgebraicGeometry.Cover.Open import Mathlib.CategoryTheory.Limits.Opposites import Mathlib.RingTheory.Localization.InvSubmonoid +import Mathlib.RingTheory.RingHom.Surjective /-! # Affine schemes @@ -113,6 +114,13 @@ def arrowIsoSpecΓOfIsAffine {X Y : Scheme} [IsAffine X] [IsAffine Y] (f : X ⟶ Arrow.mk f ≅ Arrow.mk (Spec.map (Scheme.Γ.map f.op)) := Arrow.isoMk X.isoSpec Y.isoSpec (ΓSpec.adjunction.unit_naturality _) +/-- If `f : A ⟶ B` is a ring homomorphism, the corresponding arrow is isomorphic +to the arrow of the morphism induced on global sections by the map on prime spectra. -/ +def arrowIsoΓSpecOfIsAffine {A B : CommRingCat} (f : A ⟶ B) : + Arrow.mk f ≅ Arrow.mk ((Spec.map f).app ⊤) := + Arrow.isoMk (Scheme.ΓSpecIso _).symm (Scheme.ΓSpecIso _).symm + (Scheme.ΓSpecIso_inv_naturality f).symm + namespace AffineScheme /-- The `Spec` functor into the category of affine schemes. -/ @@ -713,6 +721,109 @@ lemma Scheme.eq_zeroLocus_of_isClosed_of_isAffine (X : Scheme.{u}) [IsAffine X] end ZeroLocus +section Factorization + +variable {X : Scheme.{u}} {A : CommRingCat} + +/-- If `X ⟶ Spec A` is a morphism of schemes, then `Spec` of `A ⧸ specTargetImage f` +is the scheme-theoretic image of `f`. For this quotient as an object of `CommRingCat` see +`specTargetImage` below. -/ +def specTargetImageIdeal (f : X ⟶ Spec A) : Ideal A := + (RingHom.ker <| (((ΓSpec.adjunction).homEquiv X (op A)).symm f).unop) + +/-- If `X ⟶ Spec A` is a morphism of schemes, then `Spec` of `specTargetImage f` is the +scheme-theoretic image of `f` and `f` factors as +`specTargetImageFactorization f ≫ Spec.map (specTargetImageRingHom f)` +(see `specTargetImageFactorization_comp`). -/ +def specTargetImage (f : X ⟶ Spec A) : CommRingCat := + CommRingCat.of (A ⧸ specTargetImageIdeal f) + +/-- If `f : X ⟶ Spec A` is a morphism of schemes, then `f` factors via +the inclusion of `Spec (specTargetImage f)` into `X`. -/ +def specTargetImageFactorization (f : X ⟶ Spec A) : X ⟶ Spec (specTargetImage f) := + (ΓSpec.adjunction).homEquiv X (op <| specTargetImage f) (Opposite.op (RingHom.kerLift _)) + +/-- If `f : X ⟶ Spec A` is a morphism of schemes, the induced morphism on spectra of +`specTargetImageRingHom f` is the inclusion of the scheme-theoretic image of `f` into `Spec A`. -/ +def specTargetImageRingHom (f : X ⟶ Spec A) : A ⟶ specTargetImage f := + Ideal.Quotient.mk (specTargetImageIdeal f) + +variable (f : X ⟶ Spec A) + +lemma specTargetImageRingHom_surjective : Function.Surjective (specTargetImageRingHom f) := + Ideal.Quotient.mk_surjective + +lemma specTargetImageFactorization_app_injective : + Function.Injective <| (specTargetImageFactorization f).app ⊤ := by + let φ : A ⟶ Γ(X, ⊤) := (((ΓSpec.adjunction).homEquiv X (op A)).symm f).unop + let φ' : specTargetImage f ⟶ Scheme.Γ.obj (op X) := RingHom.kerLift φ + show Function.Injective <| ((ΓSpec.adjunction.homEquiv X _) φ'.op).app ⊤ + rw [ΓSpec_adjunction_homEquiv_eq] + apply (RingHom.kerLift_injective φ).comp + exact ((ConcreteCategory.isIso_iff_bijective (Scheme.ΓSpecIso _).hom).mp inferInstance).injective + +@[reassoc (attr := simp)] +lemma specTargetImageFactorization_comp : + specTargetImageFactorization f ≫ Spec.map (specTargetImageRingHom f) = f := by + let φ : A ⟶ Γ(X, ⊤) := (((ΓSpec.adjunction).homEquiv X (op A)).symm f).unop + let φ' : specTargetImage f ⟶ Scheme.Γ.obj (op X) := RingHom.kerLift φ + apply ((ΓSpec.adjunction).homEquiv X (op A)).symm.injective + apply Opposite.unop_injective + rw [Adjunction.homEquiv_naturality_left_symm, Adjunction.homEquiv_counit] + change (_ ≫ _) ≫ _ = φ + erw [← Spec_Γ_naturality] + rw [Category.assoc] + erw [ΓSpecIso_inv_ΓSpec_adjunction_homEquiv φ'] + ext a + apply RingHom.kerLift_mk + +open RingHom + +variable {Y : Scheme.{u}} [IsAffine Y] (f : X ⟶ Y) + +/-- The scheme-theoretic image of a morphism `f : X ⟶ Y` with affine target. +`f` factors as `affineTargetImageFactorization f ≫ affineTargetImageInclusion f` +(see `affineTargetImageFactorization_comp`). -/ +def affineTargetImage (f : X ⟶ Y) : Scheme.{u} := + Spec <| specTargetImage (f ≫ Y.isoSpec.hom) + +instance : IsAffine (affineTargetImage f) := inferInstanceAs <| IsAffine <| Spec _ + +/-- The inclusion of the scheme-theoretic image of a morphism with affine target. -/ +def affineTargetImageInclusion (f : X ⟶ Y) : affineTargetImage f ⟶ Y := + Spec.map (specTargetImageRingHom (f ≫ Y.isoSpec.hom)) ≫ Y.isoSpec.inv + +lemma affineTargetImageInclusion_app_surjective : + Function.Surjective <| (affineTargetImageInclusion f).app ⊤ := by + simp only [Scheme.comp_coeBase, Opens.map_comp_obj, Opens.map_top, Scheme.comp_app, + CommRingCat.coe_comp, affineTargetImageInclusion] + apply Function.Surjective.comp + · haveI : (toMorphismProperty (fun f ↦ Function.Surjective f)).RespectsIso := by + rw [← toMorphismProperty_respectsIso_iff] + exact surjective_respectsIso + exact (MorphismProperty.arrow_mk_iso_iff + (toMorphismProperty (fun f ↦ Function.Surjective f)) + (arrowIsoΓSpecOfIsAffine (specTargetImageRingHom (f ≫ Y.isoSpec.hom))).symm).mpr <| + specTargetImageRingHom_surjective (f ≫ Y.isoSpec.hom) + · apply Function.Bijective.surjective + apply ConcreteCategory.bijective_of_isIso + +/-- The induced morphism from `X` to the scheme-theoretic image +of a morphism `f : X ⟶ Y` with affine target. -/ +def affineTargetImageFactorization (f : X ⟶ Y) : X ⟶ affineTargetImage f := + specTargetImageFactorization (f ≫ Y.isoSpec.hom) + +lemma affineTargetImageFactorization_app_injective : + Function.Injective <| (affineTargetImageFactorization f).app ⊤ := + specTargetImageFactorization_app_injective (f ≫ Y.isoSpec.hom) + +@[reassoc (attr := simp)] +lemma affineTargetImageFactorization_comp : + affineTargetImageFactorization f ≫ affineTargetImageInclusion f = f := by + simp [affineTargetImageFactorization, affineTargetImageInclusion] + +end Factorization + section Stalks /-- Variant of `AlgebraicGeometry.localRingHom_comp_stalkIso` for `Spec.map`. -/ diff --git a/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean b/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean index 69f5dfeb240610..c046a874c7a029 100644 --- a/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean +++ b/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean @@ -455,6 +455,16 @@ theorem toOpen_toSpecΓ_app {X : Scheme.{u}} (U) : dsimp exact Category.id_comp _ +lemma ΓSpecIso_inv_ΓSpec_adjunction_homEquiv {X : Scheme.{u}} {B : CommRingCat} (φ : B ⟶ Γ(X, ⊤)) : + (Scheme.ΓSpecIso B).inv ≫ ((ΓSpec.adjunction.homEquiv X (op B)) φ.op).app ⊤ = φ := by + simp only [Adjunction.homEquiv_apply, Scheme.Spec_map, Opens.map_top, Scheme.comp_app] + simp + +lemma ΓSpec_adjunction_homEquiv_eq {X : Scheme.{u}} {B : CommRingCat} (φ : B ⟶ Γ(X, ⊤)) : + (((ΓSpec.adjunction.homEquiv X (op B)) φ.op).app ⊤) = (Scheme.ΓSpecIso B).hom ≫ φ := by + simp_rw [← ΓSpecIso_inv_ΓSpec_adjunction_homEquiv φ] + simp + theorem ΓSpecIso_obj_hom {X : Scheme.{u}} (U : X.Opens) : (Scheme.ΓSpecIso Γ(X, U)).hom = (Spec.map U.topIso.inv).app ⊤ ≫ U.toScheme.toSpecΓ.app ⊤ ≫ U.topIso.hom := by simp From 8839a89f2e68791ecfb4389f6bf12562ef239f30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 11 Oct 2024 13:11:01 +0000 Subject: [PATCH 027/425] feat: L2 inner product of finite sequences (#16447) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define the weighted L2 inner product of functions `f g : ∀ i, E i` where `ι` is a fintype and the `E i` are `𝕜`-inner product spaces where `𝕜` is `RCLike` as `∑ i, w i • inner (f i) (g i)`. This "duplicates" `inner` but is necessary because there are two useful (to discrete analysis) inner products on `G → R` given inner products on `R` and `Fintype G`, namely * the usual "discrete" inner product `∑ i, conj (f i) * g i` * the less usual but nevertheless crucial "compact" inner product `𝔼 i, conj (f i) * g i` From LeanAPAP --- Mathlib.lean | 1 + Mathlib/Analysis/RCLike/Inner.lean | 163 +++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 Mathlib/Analysis/RCLike/Inner.lean diff --git a/Mathlib.lean b/Mathlib.lean index 0b8cc14aff2ab9..005a1598915ad2 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1316,6 +1316,7 @@ import Mathlib.Analysis.PSeries import Mathlib.Analysis.PSeriesComplex import Mathlib.Analysis.Quaternion import Mathlib.Analysis.RCLike.Basic +import Mathlib.Analysis.RCLike.Inner import Mathlib.Analysis.RCLike.Lemmas import Mathlib.Analysis.Seminorm import Mathlib.Analysis.SpecialFunctions.Arsinh diff --git a/Mathlib/Analysis/RCLike/Inner.lean b/Mathlib/Analysis/RCLike/Inner.lean new file mode 100644 index 00000000000000..4136cd8069e82d --- /dev/null +++ b/Mathlib/Analysis/RCLike/Inner.lean @@ -0,0 +1,163 @@ +/- +Copyright (c) 2023 Yaël Dilies. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Yaël Dilies +-/ +import Mathlib.Analysis.InnerProductSpace.PiL2 + +/-! +# L2 inner product of finite sequences + +This file defines the weighted L2 inner product of functions `f g : ι → R` where `ι` is a fintype as +`∑ i, conj (f i) * g i`. This convention (conjugation on the left) matches the inner product coming +from `RCLike.innerProductSpace`. + +## TODO + +* Build a non-instance `InnerProductSpace` from `wInner`. +* `cWeight` is a poor name. Can we find better? It doesn't hugely matter for typing, since it's + hidden behind the `⟪f, g⟫ₙ_[𝕝] `notation, but it does show up in lemma names + `⟪f, g⟫_[𝕝, cWeight]` is called `wInner_cWeight`. Maybe we should introduce some naming + convention, similarly to `MeasureTheory.average`? +-/ + +open Finset Function Real +open scoped BigOperators ComplexConjugate ComplexOrder ENNReal NNReal NNRat + +variable {ι κ 𝕜 : Type*} {E : ι → Type*} [Fintype ι] + +namespace RCLike +variable [RCLike 𝕜] + +section Pi +variable [∀ i, SeminormedAddCommGroup (E i)] [∀ i, InnerProductSpace 𝕜 (E i)] {w : ι → ℝ} + +/-- Weighted inner product giving rise to the L2 norm. -/ +def wInner (w : ι → ℝ) (f g : ∀ i, E i) : 𝕜 := ∑ i, w i • inner (f i) (g i) + +/-- The weight function making `wInner` into the compact inner product. -/ +noncomputable abbrev cWeight : ι → ℝ := Function.const _ (Fintype.card ι)⁻¹ + +@[inherit_doc] notation "⟪" f ", " g "⟫_[" 𝕝 ", " w "]" => wInner (𝕜 := 𝕝) w f g + +/-- Discrete inner product giving rise to the discrete L2 norm. -/ +notation "⟪" f ", " g "⟫_[" 𝕝 "]" => ⟪f, g⟫_[𝕝, 1] + +/-- Compact inner product giving rise to the compact L2 norm. -/ +notation "⟪" f ", " g "⟫ₙ_[" 𝕝 "]" => ⟪f, g⟫_[𝕝, cWeight] + +lemma wInner_cWeight_eq_smul_wInner_one (f g : ∀ i, E i) : + ⟪f, g⟫ₙ_[𝕜] = (Fintype.card ι : ℚ≥0)⁻¹ • ⟪f, g⟫_[𝕜] := by + simp [wInner, smul_sum, ← NNRat.cast_smul_eq_nnqsmul ℝ] + +@[simp] lemma conj_wInner_symm (w : ι → ℝ) (f g : ∀ i, E i) : + conj ⟪f, g⟫_[𝕜, w] = ⟪g, f⟫_[𝕜, w] := by + simp [wInner, map_sum, inner_conj_symm, rclike_simps] + +@[simp] lemma wInner_zero_left (w : ι → ℝ) (g : ∀ i, E i) : ⟪0, g⟫_[𝕜, w] = 0 := by simp [wInner] +@[simp] lemma wInner_zero_right (w : ι → ℝ) (f : ∀ i, E i) : ⟪f, 0⟫_[𝕜, w] = 0 := by simp [wInner] + +lemma wInner_add_left (w : ι → ℝ) (f₁ f₂ g : ∀ i, E i) : + ⟪f₁ + f₂, g⟫_[𝕜, w] = ⟪f₁, g⟫_[𝕜, w] + ⟪f₂, g⟫_[𝕜, w] := by + simp [wInner, inner_add_left, smul_add, sum_add_distrib] + +lemma wInner_add_right (w : ι → ℝ) (f g₁ g₂ : ∀ i, E i) : + ⟪f, g₁ + g₂⟫_[𝕜, w] = ⟪f, g₁⟫_[𝕜, w] + ⟪f, g₂⟫_[𝕜, w] := by + simp [wInner, inner_add_right, smul_add, sum_add_distrib] + +@[simp] lemma wInner_neg_left (w : ι → ℝ) (f g : ∀ i, E i) : ⟪-f, g⟫_[𝕜, w] = -⟪f, g⟫_[𝕜, w] := by + simp [wInner] + +@[simp] lemma wInner_neg_right (w : ι → ℝ) (f g : ∀ i, E i) : ⟪f, -g⟫_[𝕜, w] = -⟪f, g⟫_[𝕜, w] := by + simp [wInner] + +lemma wInner_sub_left (w : ι → ℝ) (f₁ f₂ g : ∀ i, E i) : + ⟪f₁ - f₂, g⟫_[𝕜, w] = ⟪f₁, g⟫_[𝕜, w] - ⟪f₂, g⟫_[𝕜, w] := by + simp_rw [sub_eq_add_neg, wInner_add_left, wInner_neg_left] + +lemma wInner_sub_right (w : ι → ℝ) (f g₁ g₂ : ∀ i, E i) : + ⟪f, g₁ - g₂⟫_[𝕜, w] = ⟪f, g₁⟫_[𝕜, w] - ⟪f, g₂⟫_[𝕜, w] := by + simp_rw [sub_eq_add_neg, wInner_add_right, wInner_neg_right] + +@[simp] lemma wInner_of_isEmpty [IsEmpty ι] (w : ι → ℝ) (f g : ∀ i, E i) : ⟪f, g⟫_[𝕜, w] = 0 := by + simp [Subsingleton.elim f 0] + +lemma wInner_smul_left {𝕝 : Type*} [CommSemiring 𝕝] [StarRing 𝕝] [Algebra 𝕝 𝕜] [StarModule 𝕝 𝕜] + [SMulCommClass ℝ 𝕝 𝕜] [∀ i, Module 𝕝 (E i)] [∀ i, IsScalarTower 𝕝 𝕜 (E i)] (c : 𝕝) + (w : ι → ℝ) (f g : ∀ i, E i) : ⟪c • f, g⟫_[𝕜, w] = star c • ⟪f, g⟫_[𝕜, w] := by + simp_rw [wInner, Pi.smul_apply, inner_smul_left_eq_star_smul, starRingEnd_apply, smul_sum, + smul_comm (w _)] + +lemma wInner_smul_right {𝕝 : Type*} [CommSemiring 𝕝] [StarRing 𝕝] [Algebra 𝕝 𝕜] [StarModule 𝕝 𝕜] + [SMulCommClass ℝ 𝕝 𝕜] [∀ i, Module 𝕝 (E i)] [∀ i, IsScalarTower 𝕝 𝕜 (E i)] (c : 𝕝) + (w : ι → ℝ) (f g : ∀ i, E i) : ⟪f, c • g⟫_[𝕜, w] = c • ⟪f, g⟫_[𝕜, w] := by + simp_rw [wInner, Pi.smul_apply, inner_smul_right_eq_smul, smul_sum, smul_comm] + +lemma mul_wInner_left (c : 𝕜) (w : ι → ℝ) (f g : ∀ i, E i) : + c * ⟪f, g⟫_[𝕜, w] = ⟪star c • f, g⟫_[𝕜, w] := by rw [wInner_smul_left, star_star, smul_eq_mul] + +lemma wInner_one_eq_sum (f g : ∀ i, E i) : ⟪f, g⟫_[𝕜] = ∑ i, inner (f i) (g i) := by simp [wInner] +lemma wInner_cWeight_eq_expect (f g : ∀ i, E i) : ⟪f, g⟫ₙ_[𝕜] = 𝔼 i, inner (f i) (g i) := by + simp [wInner, expect, smul_sum, ← NNRat.cast_smul_eq_nnqsmul ℝ] + +end Pi + +section Function +variable {w : ι → ℝ} {f g : ι → 𝕜} + +lemma wInner_const_left (a : 𝕜) (f : ι → 𝕜) : + ⟪const _ a, f⟫_[𝕜, w] = conj a * ∑ i, w i • f i := by simp [wInner, const_apply, mul_sum] + +lemma wInner_const_right (f : ι → 𝕜) (a : 𝕜) : + ⟪f, const _ a⟫_[𝕜, w] = (∑ i, w i • conj (f i)) * a := by simp [wInner, const_apply, sum_mul] + +@[simp] lemma wInner_one_const_left (a : 𝕜) (f : ι → 𝕜) : + ⟪const _ a, f⟫_[𝕜] = conj a * ∑ i, f i := by simp [wInner_one_eq_sum, mul_sum] + +@[simp] lemma wInner_one_const_right (f : ι → 𝕜) (a : 𝕜) : + ⟪f, const _ a⟫_[𝕜] = (∑ i, conj (f i)) * a := by simp [wInner_one_eq_sum, sum_mul] + +@[simp] lemma wInner_cWeight_const_left (a : 𝕜) (f : ι → 𝕜) : + ⟪const _ a, f⟫ₙ_[𝕜] = conj a * 𝔼 i, f i := by simp [wInner_cWeight_eq_expect, mul_expect] + +@[simp] lemma wInner_cWeight_const_right (f : ι → 𝕜) (a : 𝕜) : + ⟪f, const _ a⟫ₙ_[𝕜] = (𝔼 i, conj (f i)) * a := by simp [wInner_cWeight_eq_expect, expect_mul] + +lemma wInner_one_eq_inner (f g : ι → 𝕜) : + ⟪f, g⟫_[𝕜, 1] = inner ((WithLp.equiv 2 _).symm f) ((WithLp.equiv 2 _).symm g) := by + simp [wInner] + +lemma inner_eq_wInner_one (f g : PiLp 2 fun _i : ι ↦ 𝕜) : + inner f g = ⟪WithLp.equiv 2 _ f, WithLp.equiv 2 _ g⟫_[𝕜, 1] := by simp [wInner] + +lemma linearIndependent_of_ne_zero_of_wInner_one_eq_zero {f : κ → ι → 𝕜} (hf : ∀ k, f k ≠ 0) + (hinner : Pairwise fun k₁ k₂ ↦ ⟪f k₁, f k₂⟫_[𝕜] = 0) : LinearIndependent 𝕜 f := by + simp_rw [wInner_one_eq_inner] at hinner + have := linearIndependent_of_ne_zero_of_inner_eq_zero ?_ hinner + exacts [this, hf] + +lemma linearIndependent_of_ne_zero_of_wInner_cWeight_eq_zero {f : κ → ι → 𝕜} (hf : ∀ k, f k ≠ 0) + (hinner : Pairwise fun k₁ k₂ ↦ ⟪f k₁, f k₂⟫ₙ_[𝕜] = 0) : LinearIndependent 𝕜 f := by + cases isEmpty_or_nonempty ι + · have : IsEmpty κ := ⟨fun k ↦ hf k <| Subsingleton.elim ..⟩ + exact linearIndependent_empty_type + · exact linearIndependent_of_ne_zero_of_wInner_one_eq_zero hf <| by + simpa [wInner_cWeight_eq_smul_wInner_one, ← NNRat.cast_smul_eq_nnqsmul 𝕜] using hinner + +lemma wInner_nonneg (hw : 0 ≤ w) (hf : 0 ≤ f) (hg : 0 ≤ g) : 0 ≤ ⟪f, g⟫_[𝕜, w] := + sum_nonneg fun _ _ ↦ smul_nonneg (hw _) <| mul_nonneg (star_nonneg_iff.2 (hf _)) (hg _) + +lemma norm_wInner_le (hw : 0 ≤ w) : ‖⟪f, g⟫_[𝕜, w]‖ ≤ ⟪fun i ↦ ‖f i‖, fun i ↦ ‖g i‖⟫_[ℝ, w] := + (norm_sum_le ..).trans_eq <| sum_congr rfl fun i _ ↦ by + simp [Algebra.smul_def, norm_mul, abs_of_nonneg (hw i)] + +end Function + +section Real +variable {w f g : ι → ℝ} + +lemma abs_wInner_le (hw : 0 ≤ w) : |⟪f, g⟫_[ℝ, w]| ≤ ⟪|f|, |g|⟫_[ℝ, w] := by + simpa using norm_wInner_le (𝕜 := ℝ) hw + +end Real +end RCLike From 69715a18d023c39d5340466ef6620327bfe3983a Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Fri, 11 Oct 2024 13:11:02 +0000 Subject: [PATCH 028/425] feat(Measure/WithDensityFinite): redefine `Measure.toFinite` (#17421) - Redefine `Measure.toFinite` using `exists_isFiniteMeasure_absolutelyContinuous`. - Redefine `Measure.densityToFinite` as `rnDeriv`, deprecate it. - Drop some lemmas about `toFiniteAux`. - Simplify proofs. --- .../MeasureTheory/Measure/Typeclasses.lean | 11 +- .../Measure/WithDensityFinite.lean | 174 ++++++++---------- 2 files changed, 77 insertions(+), 108 deletions(-) diff --git a/Mathlib/MeasureTheory/Measure/Typeclasses.lean b/Mathlib/MeasureTheory/Measure/Typeclasses.lean index 21a35d7e02dd31..9268fb84188248 100644 --- a/Mathlib/MeasureTheory/Measure/Typeclasses.lean +++ b/Mathlib/MeasureTheory/Measure/Typeclasses.lean @@ -558,15 +558,14 @@ instance isFiniteMeasure_sFiniteSeq [h : SFinite μ] (n : ℕ) : IsFiniteMeasure lemma sum_sFiniteSeq (μ : Measure α) [h : SFinite μ] : sum (sFiniteSeq μ) = μ := h.1.choose_spec.2.symm +lemma sFiniteSeq_le (μ : Measure α) [SFinite μ] (n : ℕ) : sFiniteSeq μ n ≤ μ := + (le_sum _ n).trans (sum_sFiniteSeq μ).le + instance : SFinite (0 : Measure α) := ⟨fun _ ↦ 0, inferInstance, by rw [Measure.sum_zero]⟩ @[simp] -lemma sFiniteSeq_zero (n : ℕ) : sFiniteSeq (0 : Measure α) n = 0 := by - ext s hs - have h : ∑' n, sFiniteSeq (0 : Measure α) n s = 0 := by - simp [← Measure.sum_apply _ hs, sum_sFiniteSeq] - simp only [ENNReal.tsum_eq_zero] at h - exact h n +lemma sFiniteSeq_zero (n : ℕ) : sFiniteSeq (0 : Measure α) n = 0 := + bot_unique <| sFiniteSeq_le _ _ /-- A countable sum of finite measures is s-finite. This lemma is superseded by the instance below. -/ diff --git a/Mathlib/MeasureTheory/Measure/WithDensityFinite.lean b/Mathlib/MeasureTheory/Measure/WithDensityFinite.lean index 955c03a3c14545..5b496cf711c4d7 100644 --- a/Mathlib/MeasureTheory/Measure/WithDensityFinite.lean +++ b/Mathlib/MeasureTheory/Measure/WithDensityFinite.lean @@ -9,16 +9,16 @@ import Mathlib.Probability.ConditionalProbability /-! # s-finite measures can be written as `withDensity` of a finite measure -If `μ` is an s-finite measure, then there exists a finite measure `μ.toFinite` and a measurable -function `densityToFinite μ` such that `μ = μ.toFinite.withDensity μ.densityToFinite`. If `μ` is -zero this is the zero measure, and otherwise we can choose a probability measure for `μ.toFinite`. +If `μ` is an s-finite measure, then there exists a finite measure `μ.toFinite` +such that a set is `μ`-null iff it is `μ.toFinite`-null. +In particular, `MeasureTheory.ae μ.toFinite = MeasureTheory.ae μ` and `μ.toFinite = 0` iff `μ = 0`. +As a corollary, `μ` can be represented as `μ.toFinite.withDensity (μ.rnDeriv μ.toFinite)`. -That measure is not unique, and in particular our implementation leads to `μ.toFinite ≠ μ` even if -`μ` is a probability measure. +Our definition of `MeasureTheory.Measure.toFinite` ensures some extra properties: -We use this construction to define a set `μ.sigmaFiniteSet`, such that `μ.restrict μ.sigmaFiniteSet` -is sigma-finite, and for all measurable sets `s ⊆ μ.sigmaFiniteSetᶜ`, either `μ s = 0` -or `μ s = ∞`. +- if `μ` is a finite measure, then `μ.toFinite = μ[|univ] = (μ univ)⁻¹ • μ`; +- in particular, `μ.toFinite = μ` for a probability measure; +- if `μ ≠ 0`, then `μ.toFinite` is a probability measure. ## Main definitions @@ -26,18 +26,19 @@ In these definitions and the results below, `μ` is an s-finite measure (`SFinit * `MeasureTheory.Measure.toFinite`: a finite measure with `μ ≪ μ.toFinite` and `μ.toFinite ≪ μ`. If `μ ≠ 0`, this is a probability measure. -* `MeasureTheory.Measure.densityToFinite`: a measurable function such that - `μ = μ.toFinite.withDensity μ.densityToFinite`. +* `MeasureTheory.Measure.densityToFinite` (deprecated, use `MeasureTheory.Measure.rnDeriv`): + the Radon-Nikodym derivative of `μ.toFinite` with respect to `μ`. ## Main statements * `absolutelyContinuous_toFinite`: `μ ≪ μ.toFinite`. * `toFinite_absolutelyContinuous`: `μ.toFinite ≪ μ`. -* `withDensity_densitytoFinite`: `μ.toFinite.withDensity μ.densityToFinite = μ`. +* `ae_toFinite`: `ae μ.toFinite = ae μ`. -/ -open scoped ENNReal +open Set +open scoped ENNReal ProbabilityTheory namespace MeasureTheory @@ -45,129 +46,98 @@ variable {α : Type*} {mα : MeasurableSpace α} {μ : Measure α} /-- Auxiliary definition for `MeasureTheory.Measure.toFinite`. -/ noncomputable def Measure.toFiniteAux (μ : Measure α) [SFinite μ] : Measure α := - Measure.sum (fun n ↦ (2 ^ (n + 1) * sFiniteSeq μ n Set.univ)⁻¹ • sFiniteSeq μ n) + letI := Classical.dec + if IsFiniteMeasure μ then μ else (exists_isFiniteMeasure_absolutelyContinuous μ).choose /-- A finite measure obtained from an s-finite measure `μ`, such that `μ = μ.toFinite.withDensity μ.densityToFinite` (see `withDensity_densitytoFinite`). If `μ` is non-zero, this is a probability measure. -/ noncomputable def Measure.toFinite (μ : Measure α) [SFinite μ] : Measure α := - ProbabilityTheory.cond μ.toFiniteAux Set.univ + μ.toFiniteAux[|univ] + +@[local simp] +lemma ae_toFiniteAux [SFinite μ] : ae μ.toFiniteAux = ae μ := by + rw [Measure.toFiniteAux] + split_ifs + · simp + · obtain ⟨_, h₁, h₂⟩ := (exists_isFiniteMeasure_absolutelyContinuous μ).choose_spec + exact h₂.ae_le.antisymm h₁.ae_le + +@[local instance] +theorem isFiniteMeasure_toFiniteAux [SFinite μ] : IsFiniteMeasure μ.toFiniteAux := by + rw [Measure.toFiniteAux] + split_ifs + · assumption + · exact (exists_isFiniteMeasure_absolutelyContinuous μ).choose_spec.1 -lemma toFiniteAux_apply (μ : Measure α) [SFinite μ] (s : Set α) : - μ.toFiniteAux s = ∑' n, (2 ^ (n + 1) * sFiniteSeq μ n Set.univ)⁻¹ * sFiniteSeq μ n s := by - rw [Measure.toFiniteAux, Measure.sum_apply_of_countable]; rfl - -lemma toFinite_apply (μ : Measure α) [SFinite μ] (s : Set α) : - μ.toFinite s = (μ.toFiniteAux Set.univ)⁻¹ * μ.toFiniteAux s := by - rw [Measure.toFinite, ProbabilityTheory.cond_apply _ MeasurableSet.univ, Set.univ_inter] - -lemma toFiniteAux_zero : Measure.toFiniteAux (0 : Measure α) = 0 := by - ext s - simp [toFiniteAux_apply] +@[simp] +lemma ae_toFinite [SFinite μ] : ae μ.toFinite = ae μ := by + simp [Measure.toFinite, ProbabilityTheory.cond] @[simp] -lemma toFinite_zero : Measure.toFinite (0 : Measure α) = 0 := by - simp [Measure.toFinite, toFiniteAux_zero] - -lemma toFiniteAux_eq_zero_iff [SFinite μ] : μ.toFiniteAux = 0 ↔ μ = 0 := by - refine ⟨fun h ↦ ?_, fun h ↦ by simp [h, toFiniteAux_zero]⟩ - ext s hs - rw [Measure.ext_iff] at h - specialize h s hs - simp only [toFiniteAux_apply, Measure.coe_zero, Pi.zero_apply, - ENNReal.tsum_eq_zero, mul_eq_zero, ENNReal.inv_eq_zero] at h - rw [← sum_sFiniteSeq μ, Measure.sum_apply _ hs] - simp only [Measure.coe_zero, Pi.zero_apply, ENNReal.tsum_eq_zero] - intro n - specialize h n - simpa [ENNReal.mul_eq_top, measure_ne_top] using h - -lemma toFiniteAux_univ_le_one (μ : Measure α) [SFinite μ] : μ.toFiniteAux Set.univ ≤ 1 := by - rw [toFiniteAux_apply] - have h_le_pow : ∀ n, (2 ^ (n + 1) * sFiniteSeq μ n Set.univ)⁻¹ * sFiniteSeq μ n Set.univ - ≤ (2 ^ (n + 1))⁻¹ := by - intro n - by_cases h_zero : sFiniteSeq μ n = 0 - · simp [h_zero] - · rw [ENNReal.le_inv_iff_mul_le, mul_assoc, mul_comm (sFiniteSeq μ n Set.univ), - ENNReal.inv_mul_cancel] - · simp [h_zero] - · exact ENNReal.mul_ne_top (by simp) (measure_ne_top _ _) - refine (tsum_le_tsum h_le_pow ENNReal.summable ENNReal.summable).trans ?_ - simp [ENNReal.inv_pow, ENNReal.tsum_geometric_add_one, ENNReal.inv_mul_cancel] - -instance [SFinite μ] : IsFiniteMeasure μ.toFiniteAux := - ⟨(toFiniteAux_univ_le_one μ).trans_lt ENNReal.one_lt_top⟩ +lemma toFinite_apply_eq_zero_iff [SFinite μ] {s : Set α} : μ.toFinite s = 0 ↔ μ s = 0 := by + simp only [← compl_mem_ae_iff, ae_toFinite] @[simp] lemma toFinite_eq_zero_iff [SFinite μ] : μ.toFinite = 0 ↔ μ = 0 := by - simp [Measure.toFinite, measure_ne_top μ.toFiniteAux Set.univ, toFiniteAux_eq_zero_iff] + simp_rw [← Measure.measure_univ_eq_zero, toFinite_apply_eq_zero_iff] + +@[simp] +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] + infer_instance instance [SFinite μ] : IsFiniteMeasure μ.toFinite := by rw [Measure.toFinite] infer_instance -instance [SFinite μ] [h_zero : NeZero μ] : IsProbabilityMeasure μ.toFinite := by - refine ProbabilityTheory.cond_isProbabilityMeasure μ.toFiniteAux ?_ - simp [toFiniteAux_eq_zero_iff, h_zero.out] +instance [SFinite μ] [NeZero μ] : IsProbabilityMeasure μ.toFinite := by + apply ProbabilityTheory.cond_isProbabilityMeasure + simp [ne_eq, ← compl_mem_ae_iff, ae_toFiniteAux] -lemma sFiniteSeq_absolutelyContinuous_toFiniteAux (μ : Measure α) [SFinite μ] (n : ℕ) : - sFiniteSeq μ n ≪ μ.toFiniteAux := by - refine Measure.absolutelyContinuous_sum_right n (Measure.absolutelyContinuous_smul ?_) - simp only [ne_eq, ENNReal.inv_eq_zero] - exact ENNReal.mul_ne_top (by simp) (measure_ne_top _ _) - -lemma toFiniteAux_absolutelyContinuous_toFinite (μ : Measure α) [SFinite μ] : - μ.toFiniteAux ≪ μ.toFinite := ProbabilityTheory.absolutelyContinuous_cond_univ +lemma absolutelyContinuous_toFinite (μ : Measure α) [SFinite μ] : μ ≪ μ.toFinite := + Measure.ae_le_iff_absolutelyContinuous.mp ae_toFinite.ge lemma sFiniteSeq_absolutelyContinuous_toFinite (μ : Measure α) [SFinite μ] (n : ℕ) : sFiniteSeq μ n ≪ μ.toFinite := - (sFiniteSeq_absolutelyContinuous_toFiniteAux μ n).trans - (toFiniteAux_absolutelyContinuous_toFinite μ) - -lemma absolutelyContinuous_toFinite (μ : Measure α) [SFinite μ] : μ ≪ μ.toFinite := by - conv_lhs => rw [← sum_sFiniteSeq μ] - exact Measure.absolutelyContinuous_sum_left (sFiniteSeq_absolutelyContinuous_toFinite μ) + (sFiniteSeq_le μ n).absolutelyContinuous.trans (absolutelyContinuous_toFinite μ) -lemma toFinite_absolutelyContinuous (μ : Measure α) [SFinite μ] : μ.toFinite ≪ μ := by - conv_rhs => rw [← sum_sFiniteSeq μ] - refine Measure.AbsolutelyContinuous.mk (fun s hs hs0 ↦ ?_) - simp only [Measure.sum_apply _ hs, ENNReal.tsum_eq_zero] at hs0 - simp [toFinite_apply, toFiniteAux_apply, hs0] +lemma toFinite_absolutelyContinuous (μ : Measure α) [SFinite μ] : μ.toFinite ≪ μ := + Measure.ae_le_iff_absolutelyContinuous.mp ae_toFinite.le /-- A measurable function such that `μ.toFinite.withDensity μ.densityToFinite = μ`. See `withDensity_densitytoFinite`. -/ -noncomputable -def Measure.densityToFinite (μ : Measure α) [SFinite μ] (a : α) : ℝ≥0∞ := - ∑' n, (sFiniteSeq μ n).rnDeriv μ.toFinite a +@[deprecated rnDeriv (since := "2024-10-04")] +noncomputable def Measure.densityToFinite (μ : Measure α) [SFinite μ] (a : α) : ℝ≥0∞ := + μ.rnDeriv μ.toFinite a +set_option linter.deprecated false in +@[deprecated (since := "2024-10-04")] lemma densityToFinite_def (μ : Measure α) [SFinite μ] : - μ.densityToFinite = fun a ↦ ∑' n, (sFiniteSeq μ n).rnDeriv μ.toFinite a := rfl + μ.densityToFinite = μ.rnDeriv μ.toFinite := + rfl +set_option linter.deprecated false in +@[deprecated Measure.measurable_rnDeriv (since := "2024-10-04")] lemma measurable_densityToFinite (μ : Measure α) [SFinite μ] : Measurable μ.densityToFinite := - Measurable.ennreal_tsum fun _ ↦ Measure.measurable_rnDeriv _ _ + Measure.measurable_rnDeriv _ _ +set_option linter.deprecated false in +@[deprecated Measure.withDensity_rnDeriv_eq (since := "2024-10-04")] theorem withDensity_densitytoFinite (μ : Measure α) [SFinite μ] : - μ.toFinite.withDensity μ.densityToFinite = μ := by - have : (μ.toFinite.withDensity fun a ↦ ∑' n, (sFiniteSeq μ n).rnDeriv μ.toFinite a) - = μ.toFinite.withDensity (∑' n, (sFiniteSeq μ n).rnDeriv μ.toFinite) := by - congr with a - rw [ENNReal.tsum_apply] - rw [densityToFinite_def, this, withDensity_tsum (fun i ↦ Measure.measurable_rnDeriv _ _)] - conv_rhs => rw [← sum_sFiniteSeq μ] - congr with n - rw [Measure.withDensity_rnDeriv_eq] - exact sFiniteSeq_absolutelyContinuous_toFinite μ n + μ.toFinite.withDensity μ.densityToFinite = μ := + Measure.withDensity_rnDeriv_eq _ _ (absolutelyContinuous_toFinite _) +set_option linter.deprecated false in +@[deprecated Measure.rnDeriv_lt_top (since := "2024-10-04")] lemma densityToFinite_ae_lt_top (μ : Measure α) [SigmaFinite μ] : - ∀ᵐ x ∂μ, μ.densityToFinite x < ∞ := by - refine ae_of_forall_measure_lt_top_ae_restrict _ (fun s _ hμs ↦ ?_) - suffices ∀ᵐ x ∂μ.toFinite.restrict s, μ.densityToFinite x < ∞ from - (absolutelyContinuous_toFinite μ).restrict _ this - refine ae_lt_top (measurable_densityToFinite μ) ?_ - rw [← withDensity_apply', withDensity_densitytoFinite] - exact hμs.ne + ∀ᵐ x ∂μ, μ.densityToFinite x < ∞ := + (absolutelyContinuous_toFinite μ).ae_le <| Measure.rnDeriv_lt_top _ _ +set_option linter.deprecated false in +@[deprecated Measure.rnDeriv_ne_top (since := "2024-10-04")] lemma densityToFinite_ae_ne_top (μ : Measure α) [SigmaFinite μ] : ∀ᵐ x ∂μ, μ.densityToFinite x ≠ ∞ := (densityToFinite_ae_lt_top μ).mono (fun _ hx ↦ hx.ne) From 49ed4bea5dc1c603e9e3364eb6cfda8c22b4e5f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 11 Oct 2024 13:32:07 +0000 Subject: [PATCH 029/425] chore: remove "removed `@[simp]` to avoid a `simpNF` linter error" porting notes (#17648) These notes are outdated (the simp-nf linter does not error when making these simp), and David told me that these lemmas were not good simp lemmas anyway. [Zulip](https://leanprover.zulipchat.com/#narrow/stream/263328-triage/topic/issue.20!4.2310759.3A.20Porting.20note.3A.20removed.20.60.40.5Bsimp.5D.60.20to.20avoid.20.2E.2E.2E/near/476173526) Closes #10759. --- Mathlib/AlgebraicGeometry/EllipticCurve/Affine.lean | 9 --------- Mathlib/AlgebraicGeometry/EllipticCurve/Group.lean | 7 ------- Mathlib/AlgebraicGeometry/EllipticCurve/Weierstrass.lean | 8 -------- 3 files changed, 24 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine.lean index d3cc6dc2264fea..fc127a34958cc7 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Affine.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Affine.lean @@ -164,7 +164,6 @@ lemma irreducible_polynomial [IsDomain R] : Irreducible W.polynomial := by iterate 2 rw [degree_add_eq_right_of_degree_lt] <;> simp only [h] <;> decide iterate 2 rw [degree_add_eq_left_of_degree_lt] <;> simp only [h] <;> decide --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error lemma evalEval_polynomial (x y : R) : W.polynomial.evalEval x y = y ^ 2 + W.a₁ * x * y + W.a₃ * y - (x ^ 3 + W.a₂ * x ^ 2 + W.a₄ * x + W.a₆) := by simp only [polynomial] @@ -183,7 +182,6 @@ lemma equation_iff' (x y : R) : W.Equation x y ↔ y ^ 2 + W.a₁ * x * y + W.a₃ * y - (x ^ 3 + W.a₂ * x ^ 2 + W.a₄ * x + W.a₆) = 0 := by rw [Equation, evalEval_polynomial] --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error lemma equation_iff (x y : R) : W.Equation x y ↔ y ^ 2 + W.a₁ * x * y + W.a₃ * y = x ^ 3 + W.a₂ * x ^ 2 + W.a₄ * x + W.a₆ := by rw [equation_iff', sub_eq_zero] @@ -210,7 +208,6 @@ TODO: define this in terms of `Polynomial.derivative`. -/ noncomputable def polynomialX : R[X][Y] := C (C W.a₁) * Y - C (C 3 * X ^ 2 + C (2 * W.a₂) * X + C W.a₄) --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error lemma evalEval_polynomialX (x y : R) : W.polynomialX.evalEval x y = W.a₁ * y - (3 * x ^ 2 + 2 * W.a₂ * x + W.a₄) := by simp only [polynomialX] @@ -226,7 +223,6 @@ TODO: define this in terms of `Polynomial.derivative`. -/ noncomputable def polynomialY : R[X][Y] := C (C 2) * Y + C (C W.a₁ * X + C W.a₃) --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error lemma evalEval_polynomialY (x y : R) : W.polynomialY.evalEval x y = 2 * y + W.a₁ * x + W.a₃ := by simp only [polynomialY] @@ -256,7 +252,6 @@ lemma nonsingular_iff' (x y : R) : W.Nonsingular x y ↔ W.Equation x y ∧ (W.a₁ * y - (3 * x ^ 2 + 2 * W.a₂ * x + W.a₄) ≠ 0 ∨ 2 * y + W.a₁ * x + W.a₃ ≠ 0) := by rw [Nonsingular, equation_iff', evalEval_polynomialX, evalEval_polynomialY] --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error lemma nonsingular_iff (x y : R) : W.Nonsingular x y ↔ W.Equation x y ∧ (W.a₁ * y ≠ 3 * x ^ 2 + 2 * W.a₂ * x + W.a₄ ∨ y ≠ -y - W.a₁ * x - W.a₃) := by rw [nonsingular_iff', sub_ne_zero, ← sub_ne_zero (a := y)] @@ -314,7 +309,6 @@ lemma negY_negY (x y : R) : W.negY x (W.negY x y) = y := by simp only [negY] ring1 --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error lemma eval_negPolynomial (x y : R) : W.negPolynomial.evalEval x y = W.negY x y := by rw [negY, sub_sub, negPolynomial] eval_simp @@ -609,7 +603,6 @@ instance : Inhabited W.Point := instance : Zero W.Point := ⟨zero⟩ --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error lemma zero_def : (zero : W.Point) = 0 := rfl @@ -625,7 +618,6 @@ def neg : W.Point → W.Point instance : Neg W.Point := ⟨neg⟩ --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error lemma neg_def (P : W.Point) : P.neg = -P := rfl @@ -656,7 +648,6 @@ noncomputable def add : W.Point → W.Point → W.Point noncomputable instance instAddPoint : Add W.Point := ⟨add⟩ --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error lemma add_def (P Q : W.Point) : P.add Q = P + Q := rfl diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Group.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Group.lean index 28d32c6a3fea55..d81a89407576b5 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Group.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Group.lean @@ -213,7 +213,6 @@ section Ring /-! ### Ideals in the coordinate ring over a ring -/ --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error /-- The class of the element $X - x$ in $R[W]$ for some $x \in R$. -/ noncomputable def XClass (x : R) : W.CoordinateRing := mk W <| C <| X - C x @@ -222,7 +221,6 @@ lemma XClass_ne_zero [Nontrivial R] (x : R) : XClass W x ≠ 0 := AdjoinRoot.mk_ne_zero_of_natDegree_lt W.monic_polynomial (C_ne_zero.mpr <| X_sub_C_ne_zero x) <| by rw [natDegree_polynomial, natDegree_C]; norm_num1 --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error /-- The class of the element $Y - y(X)$ in $R[W]$ for some $y(X) \in R[X]$. -/ noncomputable def YClass (y : R[X]) : W.CoordinateRing := mk W <| Y - C y @@ -235,17 +233,14 @@ lemma C_addPolynomial (x y L : R) : mk W (C <| W.addPolynomial x y L) = mk W ((Y - C (linePolynomial x y L)) * (W.negPolynomial - C (linePolynomial x y L))) := AdjoinRoot.mk_eq_mk.mpr ⟨1, by rw [W.C_addPolynomial, add_sub_cancel_left, mul_one]⟩ --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error /-- The ideal $\langle X - x \rangle$ of $R[W]$ for some $x \in R$. -/ noncomputable def XIdeal (x : R) : Ideal W.CoordinateRing := span {XClass W x} --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error /-- The ideal $\langle Y - y(X) \rangle$ of $R[W]$ for some $y(X) \in R[X]$. -/ noncomputable def YIdeal (y : R[X]) : Ideal W.CoordinateRing := span {YClass W y} --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error /-- The ideal $\langle X - x, Y - y(X) \rangle$ of $R[W]$ for some $x \in R$ and $y(X) \in R[X]$. -/ noncomputable def XYIdeal (x : R) (y : R[X]) : Ideal W.CoordinateRing := span {XClass W x, YClass W y} @@ -387,7 +382,6 @@ lemma XYIdeal_mul_XYIdeal {x₁ x₂ y₁ y₂ : F} (h₁ : W.Equation x₁ y₁ C_simp ring1 --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error /-- The non-zero fractional ideal $\langle X - x, Y - y \rangle$ of $F(W)$ for some $x, y \in F$. -/ noncomputable def XYIdeal' {x y : F} (h : W.Nonsingular x y) : (FractionalIdeal W.CoordinateRing⁰ W.FunctionField)ˣ := @@ -518,7 +512,6 @@ noncomputable def toClass : W.Point →+ Additive (ClassGroup W.CoordinateRing) rw [add_of_imp h] exact (CoordinateRing.mk_XYIdeal'_mul_mk_XYIdeal' h₁ h₂ h).symm --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error lemma toClass_zero : toClass (0 : W.Point) = 0 := rfl diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Weierstrass.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Weierstrass.lean index 87e3695c1b4d9c..9d730cf3c9239d 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Weierstrass.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Weierstrass.lean @@ -103,22 +103,18 @@ section Quantity /-! ### Standard quantities -/ --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error /-- The `b₂` coefficient of a Weierstrass curve. -/ def b₂ : R := W.a₁ ^ 2 + 4 * W.a₂ --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error /-- The `b₄` coefficient of a Weierstrass curve. -/ def b₄ : R := 2 * W.a₄ + W.a₁ * W.a₃ --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error /-- The `b₆` coefficient of a Weierstrass curve. -/ def b₆ : R := W.a₃ ^ 2 + 4 * W.a₆ --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error /-- The `b₈` coefficient of a Weierstrass curve. -/ def b₈ : R := W.a₁ ^ 2 * W.a₆ + 4 * W.a₂ * W.a₆ - W.a₁ * W.a₃ * W.a₄ + W.a₂ * W.a₃ ^ 2 - W.a₄ ^ 2 @@ -127,17 +123,14 @@ lemma b_relation : 4 * W.b₈ = W.b₂ * W.b₆ - W.b₄ ^ 2 := by simp only [b₂, b₄, b₆, b₈] ring1 --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error /-- The `c₄` coefficient of a Weierstrass curve. -/ def c₄ : R := W.b₂ ^ 2 - 24 * W.b₄ --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error /-- The `c₆` coefficient of a Weierstrass curve. -/ def c₆ : R := -W.b₂ ^ 3 + 36 * W.b₂ * W.b₄ - 216 * W.b₆ --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error /-- The discriminant `Δ` of a Weierstrass curve. If `R` is a field, then this polynomial vanishes if and only if the cubic curve cut out by this equation is singular. Sometimes only defined up to sign in the literature; we choose the sign used by the LMFDB. For more discussion, see @@ -438,7 +431,6 @@ theorem ext {x y : EllipticCurve R} (h₁ : x.a₁ = y.a₁) (h₂ : x.a₂ = y. variable (E : EllipticCurve R) --- Porting note (#10619): removed `@[simp]` to avoid a `simpNF` linter error /-- The j-invariant `j` of an elliptic curve, which is invariant under isomorphisms over `R`. -/ def j : R := E.Δ'⁻¹ * E.c₄ ^ 3 From 49e560760d992f9cf930b582a911e74a9719e886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 11 Oct 2024 13:41:08 +0000 Subject: [PATCH 030/425] feat: the complement of a null set has full measure (#17644) From PFR --- Mathlib/MeasureTheory/Measure/NullMeasurable.lean | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mathlib/MeasureTheory/Measure/NullMeasurable.lean b/Mathlib/MeasureTheory/Measure/NullMeasurable.lean index 09e4f3a49eccb2..3f2767ff07960a 100644 --- a/Mathlib/MeasureTheory/Measure/NullMeasurable.lean +++ b/Mathlib/MeasureTheory/Measure/NullMeasurable.lean @@ -280,6 +280,9 @@ theorem measure_union₀' (hs : NullMeasurableSet s μ) (hd : AEDisjoint μ s t) theorem measure_add_measure_compl₀ {s : Set α} (hs : NullMeasurableSet s μ) : μ s + μ sᶜ = μ univ := by rw [← measure_union₀' hs aedisjoint_compl_right, union_compl_self] +lemma measure_of_measure_compl_eq_zero (hs : μ sᶜ = 0) : μ s = μ Set.univ := by + simpa [hs] using measure_add_measure_compl₀ <| .of_compl <| .of_null hs + section MeasurableSingletonClass variable [MeasurableSingletonClass (NullMeasurableSpace α μ)] From 98e84e264487deeeb823fa5c5def8d9a40954751 Mon Sep 17 00:00:00 2001 From: Kyle Miller Date: Fri, 11 Oct 2024 14:04:34 +0000 Subject: [PATCH 031/425] chore: address `@[elab_as_elim]` porting notes (#17625) - Now Lean 4 supports complex discriminants, so this PR re-enables `@[elab_as_elim]` for these eliminators. These should be reviewed to decide whether they should be `@[elab_as_elim]`, since this elaborator requires an expected type to function, so is more restrictive. - Functions that return something non-dependent should never be `@[elab_as_elim]`, since this case doesn't need anything special for successful elaboration. Plus, `@[elab_as_elim]` would make it more likely to fail. --- Mathlib/Computability/Reduce.lean | 9 +++------ Mathlib/Computability/TuringMachine.lean | 1 - Mathlib/Data/Finmap.lean | 2 -- Mathlib/Data/Ordmap/Ordset.lean | 4 ++-- Mathlib/Data/Quot.lean | 5 ----- Mathlib/FieldTheory/PerfectClosure.lean | 1 - Mathlib/GroupTheory/MonoidLocalization/Basic.lean | 4 ---- Mathlib/LinearAlgebra/Determinant.lean | 2 +- Mathlib/Logic/Basic.lean | 2 -- Mathlib/Logic/Encodable/Lattice.lean | 3 +-- Mathlib/RingTheory/UniqueFactorizationDomain.lean | 3 +-- 11 files changed, 8 insertions(+), 28 deletions(-) diff --git a/Mathlib/Computability/Reduce.lean b/Mathlib/Computability/Reduce.lean index 2b3eb7f41f3c91..131ccd8fadbc5f 100644 --- a/Mathlib/Computability/Reduce.lean +++ b/Mathlib/Computability/Reduce.lean @@ -311,9 +311,7 @@ protected theorem ind_on {C : ManyOneDegree → Prop} (d : ManyOneDegree) (h : ∀ p : Set ℕ, C (of p)) : C d := Quotient.inductionOn' d h -/-- Lifts a function on sets of natural numbers to many-one degrees. --/ --- @[elab_as_elim] -- Porting note: unexpected eliminator resulting type +/-- Lifts a function on sets of natural numbers to many-one degrees. -/ protected abbrev liftOn {φ} (d : ManyOneDegree) (f : Set ℕ → φ) (h : ∀ p q, ManyOneEquiv p q → f p = f q) : φ := Quotient.liftOn' d f h @@ -323,9 +321,8 @@ protected theorem liftOn_eq {φ} (p : Set ℕ) (f : Set ℕ → φ) (h : ∀ p q, ManyOneEquiv p q → f p = f q) : (of p).liftOn f h = f p := rfl -/-- Lifts a binary function on sets of natural numbers to many-one degrees. --/ -@[reducible, simp] -- @[elab_as_elim] -- Porting note: unexpected eliminator resulting type +/-- Lifts a binary function on sets of natural numbers to many-one degrees. -/ +@[reducible, simp] protected def liftOn₂ {φ} (d₁ d₂ : ManyOneDegree) (f : Set ℕ → Set ℕ → φ) (h : ∀ p₁ p₂ q₁ q₂, ManyOneEquiv p₁ p₂ → ManyOneEquiv q₁ q₂ → f p₁ q₁ = f p₂ q₂) : φ := d₁.liftOn (fun p => d₂.liftOn (f p) fun q₁ q₂ hq => h _ _ _ _ (by rfl) hq) diff --git a/Mathlib/Computability/TuringMachine.lean b/Mathlib/Computability/TuringMachine.lean index 73b365b5200ee5..0309fcce41a02c 100644 --- a/Mathlib/Computability/TuringMachine.lean +++ b/Mathlib/Computability/TuringMachine.lean @@ -178,7 +178,6 @@ instance ListBlank.hasEmptyc {Γ} [Inhabited Γ] : EmptyCollection (ListBlank Γ /-- A modified version of `Quotient.liftOn'` specialized for `ListBlank`, with the stronger precondition `BlankExtends` instead of `BlankRel`. -/ --- Porting note: Removed `@[elab_as_elim]` protected abbrev ListBlank.liftOn {Γ} [Inhabited Γ] {α} (l : ListBlank Γ) (f : List Γ → α) (H : ∀ a b, BlankExtends a b → f a = f b) : α := l.liftOn' f <| by rintro a b (h | h) <;> [exact H _ _ h; exact (H _ _ h).symm] diff --git a/Mathlib/Data/Finmap.lean b/Mathlib/Data/Finmap.lean index 770bb27ffee010..c4d3fe1b9820d8 100644 --- a/Mathlib/Data/Finmap.lean +++ b/Mathlib/Data/Finmap.lean @@ -88,7 +88,6 @@ lemma nodup_entries (f : Finmap β) : f.entries.Nodup := f.nodupKeys.nodup /-! ### Lifting from AList -/ /-- Lift a permutation-respecting function on `AList` to `Finmap`. -/ --- @[elab_as_elim] Porting note: we can't add `elab_as_elim` attr in this type def liftOn {γ} (s : Finmap β) (f : AList β → γ) (H : ∀ a b : AList β, a.entries ~ b.entries → f a = f b) : γ := by refine @@ -108,7 +107,6 @@ theorem liftOn_toFinmap {γ} (s : AList β) (f : AList β → γ) (H) : liftOn rfl /-- Lift a permutation-respecting function on 2 `AList`s to 2 `Finmap`s. -/ --- @[elab_as_elim] Porting note: we can't add `elab_as_elim` attr in this type def liftOn₂ {γ} (s₁ s₂ : Finmap β) (f : AList β → AList β → γ) (H : ∀ a₁ b₁ a₂ b₂ : AList β, a₁.entries ~ a₂.entries → b₁.entries ~ b₂.entries → f a₁ b₁ = f a₂ b₂) : γ := diff --git a/Mathlib/Data/Ordmap/Ordset.lean b/Mathlib/Data/Ordmap/Ordset.lean index 48b8308610ed94..ca4d7b8c2efab7 100644 --- a/Mathlib/Data/Ordmap/Ordset.lean +++ b/Mathlib/Data/Ordmap/Ordset.lean @@ -530,12 +530,12 @@ theorem splitMax_eq : | _, l, x, nil => rfl | _, l, x, node ls ll lx lr => by rw [splitMax', splitMax_eq ls ll lx lr, findMax', eraseMax] --- @[elab_as_elim] -- Porting note: unexpected eliminator resulting type +@[elab_as_elim] theorem findMin'_all {P : α → Prop} : ∀ (t) (x : α), All P t → P x → P (findMin' t x) | nil, _x, _, hx => hx | node _ ll lx _, _, ⟨h₁, h₂, _⟩, _ => findMin'_all ll lx h₁ h₂ --- @[elab_as_elim] -- Porting note: unexpected eliminator resulting type +@[elab_as_elim] theorem findMax'_all {P : α → Prop} : ∀ (x : α) (t), P x → All P t → P (findMax' x t) | _x, nil, hx, _ => hx | _, node _ _ lx lr, _, ⟨_, h₂, h₃⟩ => findMax'_all lx lr h₂ h₃ diff --git a/Mathlib/Data/Quot.lean b/Mathlib/Data/Quot.lean index fe065e114788fc..05fbfe253206f8 100644 --- a/Mathlib/Data/Quot.lean +++ b/Mathlib/Data/Quot.lean @@ -109,7 +109,6 @@ theorem liftOn_mk (a : α) (f : α → γ) (h : ∀ a₁ a₂, r a₁ a₂ → f ⟨fun hf => hf.comp Quot.exists_rep, fun hf y => let ⟨x, hx⟩ := hf y; ⟨Quot.mk _ x, hx⟩⟩ /-- Descends a function `f : α → β → γ` to quotients of `α` and `β`. -/ --- Porting note: removed `@[elab_as_elim]`, gave "unexpected resulting type γ" -- porting note (#11083): removed `@[reducible]` because it caused extremely slow `simp` protected def lift₂ (f : α → β → γ) (hr : ∀ a b₁ b₂, s b₁ b₂ → f a b₁ = f a b₂) (hs : ∀ a₁ a₂ b, r a₁ a₂ → f a₁ b = f a₂ b) (q₁ : Quot r) (q₂ : Quot s) : γ := @@ -123,7 +122,6 @@ theorem lift₂_mk (f : α → β → γ) (hr : ∀ a b₁ b₂, s b₁ b₂ → rfl /-- Descends a function `f : α → β → γ` to quotients of `α` and `β` and applies it. -/ --- porting note (#11083): removed `@[elab_as_elim]`, gave "unexpected resulting type γ" -- porting note (#11083): removed `@[reducible]` because it caused extremely slow `simp` protected def liftOn₂ (p : Quot r) (q : Quot s) (f : α → β → γ) (hr : ∀ a b₁ b₂, s b₁ b₂ → f a b₁ = f a b₂) (hs : ∀ a₁ a₂ b, r a₁ a₂ → f a₁ b = f a₂ b) : γ := @@ -451,7 +449,6 @@ protected theorem lift_mk (f : α → β) (c) (a : α) : lift f c (mk a) = f a : rfl /-- Lift a constant function on `q : Trunc α`. -/ --- Porting note: removed `@[elab_as_elim]` because it gave "unexpected eliminator resulting type" -- porting note (#11083): removed `@[reducible]` because it caused extremely slow `simp` protected def liftOn (q : Trunc α) (f : α → β) (c : ∀ a b : α, f a = f b) : β := lift f c q @@ -560,7 +557,6 @@ theorem surjective_Quotient_mk'' : Function.Surjective (Quotient.mk'' : α → Q /-- A version of `Quotient.liftOn` taking `{s : Setoid α}` as an implicit argument instead of an instance argument. -/ --- Porting note: removed `@[elab_as_elim]` because it gave "unexpected eliminator resulting type" -- porting note (#11083): removed `@[reducible]` because it caused extremely slow `simp` protected def liftOn' (q : Quotient s₁) (f : α → φ) (h : ∀ a b, s₁ a b → f a = f b) : φ := @@ -577,7 +573,6 @@ protected theorem liftOn'_mk'' (f : α → φ) (h) (x : α) : /-- A version of `Quotient.liftOn₂` taking `{s₁ : Setoid α} {s₂ : Setoid β}` as implicit arguments instead of instance arguments. -/ --- Porting note: removed `@[elab_as_elim]` because it gave "unexpected eliminator resulting type" -- porting note (#11083): removed `@[reducible]` because it caused extremely slow `simp` protected def liftOn₂' (q₁ : Quotient s₁) (q₂ : Quotient s₂) (f : α → β → γ) (h : ∀ a₁ a₂ b₁ b₂, s₁ a₁ b₁ → s₂ a₂ b₂ → f a₁ a₂ = f b₁ b₂) : γ := diff --git a/Mathlib/FieldTheory/PerfectClosure.lean b/Mathlib/FieldTheory/PerfectClosure.lean index df62d0fc00813b..50b237cb61ab01 100644 --- a/Mathlib/FieldTheory/PerfectClosure.lean +++ b/Mathlib/FieldTheory/PerfectClosure.lean @@ -92,7 +92,6 @@ theorem quot_mk_eq_mk (x : ℕ × K) : (Quot.mk (R K p) x : PerfectClosure K p) variable {K p} /-- Lift a function `ℕ × K → L` to a function on `PerfectClosure K p`. -/ --- Porting note: removed `@[elab_as_elim]` for "unexpected eliminator resulting type L" def liftOn {L : Type*} (x : PerfectClosure K p) (f : ℕ × K → L) (hf : ∀ x y, R K p x y → f x = f y) : L := Quot.liftOn x f hf diff --git a/Mathlib/GroupTheory/MonoidLocalization/Basic.lean b/Mathlib/GroupTheory/MonoidLocalization/Basic.lean index b5db348da57a72..aae0ac762fc973 100644 --- a/Mathlib/GroupTheory/MonoidLocalization/Basic.lean +++ b/Mathlib/GroupTheory/MonoidLocalization/Basic.lean @@ -268,8 +268,6 @@ theorem ndrec_mk {p : Localization S → Sort u} (f : ∀ (a : M) (b : S), p (mk /-- Non-dependent recursion principle for localizations: given elements `f a b : p` for all `a b`, such that `r S (a, b) (c, d)` implies `f a b = f c d`, then `f` is defined on the whole `Localization S`. -/ --- Porting note: the attribute `elab_as_elim` fails with `unexpected eliminator resulting type p` --- @[to_additive (attr := elab_as_elim) @[to_additive "Non-dependent recursion principle for `AddLocalization`s: given elements `f a b : p` for all `a b`, such that `r S (a, b) (c, d)` implies `f a b = f c d`, @@ -293,8 +291,6 @@ theorem induction_on {p : Localization S → Prop} (x) (H : ∀ y : M × S, p (m /-- Non-dependent recursion principle for localizations: given elements `f x y : p` for all `x` and `y`, such that `r S x x'` and `r S y y'` implies `f x y = f x' y'`, then `f` is defined on the whole `Localization S`. -/ --- Porting note: the attribute `elab_as_elim` fails with `unexpected eliminator resulting type p` --- @[to_additive (attr := elab_as_elim) @[to_additive "Non-dependent recursion principle for localizations: given elements `f x y : p` for all `x` and `y`, such that `r S x x'` and `r S y y'` implies `f x y = f x' y'`, diff --git a/Mathlib/LinearAlgebra/Determinant.lean b/Mathlib/LinearAlgebra/Determinant.lean index 8f8edaca16e329..dc9936ab62f2ac 100644 --- a/Mathlib/LinearAlgebra/Determinant.lean +++ b/Mathlib/LinearAlgebra/Determinant.lean @@ -207,7 +207,7 @@ theorem det_toLin' (f : Matrix ι ι R) : LinearMap.det (Matrix.toLin' f) = Matr /-- To show `P (LinearMap.det f)` it suffices to consider `P (Matrix.det (toMatrix _ _ f))` and `P 1`. -/ --- @[elab_as_elim] -- Porting note: This attr can't be applied. +@[elab_as_elim] 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 diff --git a/Mathlib/Logic/Basic.lean b/Mathlib/Logic/Basic.lean index 538530f266a43c..b4258e60f795c9 100644 --- a/Mathlib/Logic/Basic.lean +++ b/Mathlib/Logic/Basic.lean @@ -683,7 +683,6 @@ 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 satisfying the predicate. -/ --- @[elab_as_elim] -- FIXME noncomputable def existsCases {α C : Sort*} {p : α → Prop} (H0 : C) (H : ∀ a, p a → C) : C := if h : ∃ a, p a then H (Classical.choose h) (Classical.choose_spec h) else H0 @@ -743,7 +742,6 @@ end Classical /-- This function has the same type as `Exists.recOn`, and can be used to case on an equality, but `Exists.recOn` can only eliminate into Prop, while this version eliminates into any universe using the axiom of choice. -/ --- @[elab_as_elim] -- FIXME noncomputable def Exists.classicalRecOn {α : Sort*} {p : α → Prop} (h : ∃ a, p a) {C : Sort*} (H : ∀ a, p a → C) : C := H (Classical.choose h) (Classical.choose_spec h) diff --git a/Mathlib/Logic/Encodable/Lattice.lean b/Mathlib/Logic/Encodable/Lattice.lean index 61e01cc0053a45..039681749b5762 100644 --- a/Mathlib/Logic/Encodable/Lattice.lean +++ b/Mathlib/Logic/Encodable/Lattice.lean @@ -33,8 +33,7 @@ theorem iSup_decode₂ [CompleteLattice α] (f : β → α) : theorem iUnion_decode₂ (f : β → Set α) : ⋃ (i : ℕ) (b ∈ decode₂ β i), f b = ⋃ b, f b := iSup_decode₂ f -/- Porting note: `@[elab_as_elim]` gives `unexpected eliminator resulting type`. -/ ---@[elab_as_elim] +@[elab_as_elim] theorem iUnion_decode₂_cases {f : β → Set α} {C : Set α → Prop} (H0 : C ∅) (H1 : ∀ b, C (f b)) {n} : C (⋃ b ∈ decode₂ β n, f b) := match decode₂ β n with diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain.lean b/Mathlib/RingTheory/UniqueFactorizationDomain.lean index ee5e511abe6876..ab4db15117b064 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain.lean @@ -1027,7 +1027,7 @@ theorem prime_pow_coprime_prod_of_coprime_insert [DecidableEq α] {s : Finset α /-- If `P` holds for units and powers of primes, and `P x ∧ P y` for coprime `x, y` implies `P (x * y)`, then `P` holds on a product of powers of distinct primes. -/ --- @[elab_as_elim] Porting note: commented out +@[elab_as_elim] theorem induction_on_prime_power {P : α → Prop} (s : Finset α) (i : α → ℕ) (is_prime : ∀ p ∈ s, Prime p) (is_coprime : ∀ᵉ (p ∈ s) (q ∈ s), p ∣ q → p = q) (h1 : ∀ {x}, IsUnit x → P x) (hpr : ∀ {p} (i : ℕ), Prime p → P (p ^ i)) @@ -1066,7 +1066,6 @@ theorem induction_on_coprime {P : α → Prop} (a : α) (h0 : P 0) (h1 : ∀ {x} /-- If `f` maps `p ^ i` to `(f p) ^ i` for primes `p`, and `f` is multiplicative on coprime elements, then `f` is multiplicative on all products of primes. -/ --- @[elab_as_elim] Porting note: commented out theorem multiplicative_prime_power {f : α → β} (s : Finset α) (i j : α → ℕ) (is_prime : ∀ p ∈ s, Prime p) (is_coprime : ∀ᵉ (p ∈ s) (q ∈ s), p ∣ q → p = q) (h1 : ∀ {x y}, IsUnit y → f (x * y) = f x * f y) From 25d205769ef5f6a3f231d404b7f433ae27250ed5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Fri, 11 Oct 2024 15:01:36 +0000 Subject: [PATCH 032/425] feat(SetTheory/Cardinal/Basic): `Cardinal.liftInitialSeg` (#16958) We introduce an `InitialSeg` version of `Cardinal.lift` and use it to golf down the `lift` API. --- Mathlib/SetTheory/Cardinal/Basic.lean | 73 ++++++++++++---------- Mathlib/SetTheory/Cardinal/Cofinality.lean | 2 +- Mathlib/SetTheory/Ordinal/Basic.lean | 5 +- 3 files changed, 42 insertions(+), 38 deletions(-) diff --git a/Mathlib/SetTheory/Cardinal/Basic.lean b/Mathlib/SetTheory/Cardinal/Basic.lean index 170827f6686473..0000f54003d7c0 100644 --- a/Mathlib/SetTheory/Cardinal/Basic.lean +++ b/Mathlib/SetTheory/Cardinal/Basic.lean @@ -6,6 +6,7 @@ Authors: Johannes Hölzl, Mario Carneiro, Floris van Doorn import Mathlib.Data.Fintype.BigOperators import Mathlib.Data.Set.Countable import Mathlib.Logic.Small.Set +import Mathlib.Order.InitialSeg import Mathlib.Order.SuccPred.CompleteLinearOrder import Mathlib.SetTheory.Cardinal.SchroederBernstein import Mathlib.Algebra.Order.Ring.Nat @@ -79,7 +80,7 @@ Cantor's theorem, König's theorem, Konig's theorem assert_not_exists Field open Mathlib (Vector) -open Function Set Order +open Function Order Set noncomputable section @@ -305,12 +306,6 @@ we provide this statement separately so you don't have to solve the specializati theorem lift_mk_eq' {α : Type u} {β : Type v} : lift.{v} #α = lift.{u} #β ↔ Nonempty (α ≃ β) := lift_mk_eq.{u, v, 0} -@[simp] -theorem lift_le {a b : Cardinal.{v}} : lift.{u, v} a ≤ lift.{u, v} b ↔ a ≤ b := - inductionOn₂ a b fun α β => by - rw [← lift_umax] - exact lift_mk_le.{u} - -- Porting note: simpNF is not happy with universe levels. @[simp, nolint simpNF] theorem lift_mk_shrink (α : Type u) [Small.{v} α] : @@ -327,32 +322,48 @@ theorem lift_mk_shrink'' (α : Type max u v) [Small.{v} α] : Cardinal.lift.{u} #(Shrink.{v} α) = #α := by rw [← lift_umax', lift_mk_shrink.{max u v, v, 0} α, ← lift_umax, lift_id] +/-- `Cardinal.lift` as an `InitialSeg`. -/ +@[simps!] +def liftInitialSeg : Cardinal.{u} ≤i Cardinal.{max u v} := by + refine ⟨(OrderEmbedding.ofMapLEIff lift ?_).ltEmbedding, ?_⟩ <;> intro a b + · refine inductionOn₂ a b fun _ _ ↦ ?_ + rw [← lift_umax, lift_mk_le.{v, u, u}, le_def] + · refine inductionOn₂ a b fun α β h ↦ ?_ + obtain ⟨e⟩ := h.le + replace e := e.congr (Equiv.refl β) Equiv.ulift + refine ⟨#(range e), mk_congr (Equiv.ulift.trans <| Equiv.symm ?_)⟩ + apply (e.codRestrict _ mem_range_self).equivOfSurjective + rintro ⟨a, ⟨b, rfl⟩⟩ + exact ⟨b, rfl⟩ + +theorem mem_range_of_le_lift {a : Cardinal.{u}} {b : Cardinal.{max u v}} : + b ≤ lift.{v, u} a → b ∈ Set.range lift.{v, u} := + liftInitialSeg.mem_range_of_le + +@[deprecated mem_range_of_le_lift (since := "2024-10-07")] theorem lift_down {a : Cardinal.{u}} {b : Cardinal.{max u v}} : - b ≤ lift.{v,u} a → ∃ a', lift.{v,u} a' = b := - inductionOn₂ a b fun α β => by - rw [← lift_id #β, ← lift_umax, ← lift_umax.{u, v}, lift_mk_le.{v}] - exact fun ⟨f⟩ => - ⟨#(Set.range f), - Eq.symm <| lift_mk_eq.{_, _, v}.2 - ⟨Function.Embedding.equivOfSurjective (Embedding.codRestrict _ f Set.mem_range_self) - fun ⟨a, ⟨b, e⟩⟩ => ⟨b, Subtype.eq e⟩⟩⟩ - --- Porting note: changed `simps` to `simps!` because the linter told to do so. + b ≤ lift.{v, u} a → ∃ a', lift.{v, u} a' = b := + mem_range_of_le_lift + /-- `Cardinal.lift` as an `OrderEmbedding`. -/ -@[simps! (config := .asFn)] +@[deprecated Cardinal.liftInitialSeg (since := "2024-10-07")] def liftOrderEmbedding : Cardinal.{v} ↪o Cardinal.{max v u} := - OrderEmbedding.ofMapLEIff lift.{u, v} fun _ _ => lift_le + liftInitialSeg.toOrderEmbedding theorem lift_injective : Injective lift.{u, v} := - liftOrderEmbedding.injective + liftInitialSeg.injective @[simp] theorem lift_inj {a b : Cardinal.{u}} : lift.{v, u} a = lift.{v, u} b ↔ a = b := lift_injective.eq_iff +@[simp] +theorem lift_le {a b : Cardinal.{v}} : lift.{u} a ≤ lift.{u} b ↔ a ≤ b := + liftInitialSeg.le_iff_le + @[simp] theorem lift_lt {a b : Cardinal.{u}} : lift.{v, u} a < lift.{v, u} b ↔ a < b := - liftOrderEmbedding.lt_iff_lt + liftInitialSeg.lt_iff_lt theorem lift_strictMono : StrictMono lift := fun _ _ => lift_lt.2 @@ -374,18 +385,12 @@ theorem lift_umax_eq {a : Cardinal.{u}} {b : Cardinal.{v}} : rw [← lift_lift.{v, w, u}, ← lift_lift.{u, w, v}, lift_inj] theorem le_lift_iff {a : Cardinal.{u}} {b : Cardinal.{max u v}} : - b ≤ lift.{v, u} a ↔ ∃ a', lift.{v, u} a' = b ∧ a' ≤ a := - ⟨fun h => - let ⟨a', e⟩ := lift_down h - ⟨a', e, lift_le.1 <| e.symm ▸ h⟩, - fun ⟨_, e, h⟩ => e ▸ lift_le.2 h⟩ + b ≤ lift.{v, u} a ↔ ∃ a' ≤ a, lift.{v, u} a' = b := + liftInitialSeg.le_apply_iff theorem lt_lift_iff {a : Cardinal.{u}} {b : Cardinal.{max u v}} : - b < lift.{v, u} a ↔ ∃ a', lift.{v, u} a' = b ∧ a' < a := - ⟨fun h => - let ⟨a', e⟩ := lift_down h.le - ⟨a', e, lift_lt.1 <| e.symm ▸ h⟩, - fun ⟨_, e, h⟩ => e ▸ lift_lt.2 h⟩ + b < lift.{v, u} a ↔ ∃ a' < a, lift.{v, u} a' = b := + liftInitialSeg.lt_apply_iff /-! ### Basic cardinals -/ @@ -784,7 +789,7 @@ theorem add_one_le_succ (c : Cardinal.{u}) : c + 1 ≤ succ c := by theorem lift_succ (a) : lift.{v, u} (succ a) = succ (lift.{v, u} a) := le_antisymm (le_of_not_gt fun h => by - rcases lt_lift_iff.1 h with ⟨b, e, h⟩ + rcases lt_lift_iff.1 h with ⟨b, h, e⟩ rw [lt_succ_iff, ← lift_le, e] at h exact h.not_lt (lt_succ _)) (succ_le_of_lt <| lift_lt.2 <| lt_succ a) @@ -1006,7 +1011,7 @@ theorem lift_sSup {s : Set Cardinal} (hs : BddAbove s) : apply ((le_csSup_iff' (bddAbove_image.{_,u} _ hs)).2 fun c hc => _).antisymm (csSup_le' _) · intro c hc by_contra h - obtain ⟨d, rfl⟩ := Cardinal.lift_down (not_le.1 h).le + obtain ⟨d, rfl⟩ := Cardinal.mem_range_of_le_lift (not_le.1 h).le simp_rw [lift_le] at h hc rw [csSup_le_iff' hs] at h exact h fun a ha => lift_le.1 <| hc (mem_image_of_mem _ ha) @@ -1417,7 +1422,7 @@ theorem one_le_aleph0 : 1 ≤ ℵ₀ := theorem lt_aleph0 {c : Cardinal} : c < ℵ₀ ↔ ∃ n : ℕ, c = n := ⟨fun h => by - rcases lt_lift_iff.1 h with ⟨c, rfl, h'⟩ + rcases lt_lift_iff.1 h with ⟨c, h', rfl⟩ rcases le_mk_iff_exists_set.1 h'.1 with ⟨S, rfl⟩ suffices S.Finite by lift S to Finset ℕ using this diff --git a/Mathlib/SetTheory/Cardinal/Cofinality.lean b/Mathlib/SetTheory/Cardinal/Cofinality.lean index 2452d83508b788..55b3d56e3120c5 100644 --- a/Mathlib/SetTheory/Cardinal/Cofinality.lean +++ b/Mathlib/SetTheory/Cardinal/Cofinality.lean @@ -712,7 +712,7 @@ theorem cof_univ : cof univ.{u, v} = Cardinal.univ.{u, v} := rcases @cof_eq Ordinal.{u} (· < ·) _ with ⟨S, H, Se⟩ rw [univ, ← lift_cof, ← Cardinal.lift_lift.{u+1, v, u}, Cardinal.lift_lt, ← Se] refine lt_of_not_ge fun h => ?_ - cases' Cardinal.lift_down h with a e + cases' Cardinal.mem_range_of_le_lift h with a e refine Quotient.inductionOn a (fun α e => ?_) e cases' Quotient.exact e with f have f := Equiv.ulift.symm.trans f diff --git a/Mathlib/SetTheory/Ordinal/Basic.lean b/Mathlib/SetTheory/Ordinal/Basic.lean index f8582f2d2762d5..d2993ff4d2f73f 100644 --- a/Mathlib/SetTheory/Ordinal/Basic.lean +++ b/Mathlib/SetTheory/Ordinal/Basic.lean @@ -5,7 +5,6 @@ Authors: Mario Carneiro, Floris van Doorn -/ import Mathlib.Algebra.Order.SuccPred import Mathlib.Data.Sum.Order -import Mathlib.Order.InitialSeg import Mathlib.SetTheory.Cardinal.Basic import Mathlib.Tactic.PPWithUniv @@ -661,7 +660,7 @@ theorem lift_card (a) : Cardinal.lift.{u,v} (card a)= card (lift.{u,v} a) := theorem lift_down' {a : Cardinal.{u}} {b : Ordinal.{max u v}} (h : card.{max u v} b ≤ Cardinal.lift.{v,u} a) : ∃ a', lift.{v,u} a' = b := - let ⟨c, e⟩ := Cardinal.lift_down h + let ⟨c, e⟩ := Cardinal.mem_range_of_le_lift h Cardinal.inductionOn c (fun α => inductionOn b fun β s _ e' => by @@ -1320,7 +1319,7 @@ theorem lt_univ {c} : c < univ.{u, u + 1} ↔ ∃ c', c = lift.{u + 1, u} c' := theorem lt_univ' {c} : c < univ.{u, v} ↔ ∃ c', c = lift.{max (u + 1) v, u} c' := ⟨fun h => by - let ⟨a, e, h'⟩ := lt_lift_iff.1 h + let ⟨a, h', e⟩ := lt_lift_iff.1 h rw [← univ_id] at h' rcases lt_univ.{u}.1 h' with ⟨c', rfl⟩ exact ⟨c', by simp only [e.symm, lift_lift]⟩, fun ⟨c', e⟩ => e.symm ▸ lift_lt_univ' _⟩ From 683a462b8062ecb066f5ba59c06ca69997725bf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 11 Oct 2024 15:01:37 +0000 Subject: [PATCH 033/425] chore: generalise `zpow` lemmas from `LinearOrderedSemifield` to `GroupWithZero` (#17539) --- Mathlib/Algebra/Order/Archimedean/Basic.lean | 8 +- Mathlib/Algebra/Order/Field/Power.lean | 78 +++++++--------- .../Order/GroupWithZero/Unbundled.lean | 88 +++++++++++++++++-- Mathlib/Algebra/Order/Positive/Field.lean | 2 +- .../Convex/SpecificFunctions/Deriv.lean | 2 +- .../Analysis/Distribution/SchwartzSpace.lean | 2 +- Mathlib/Analysis/Hofer.lean | 2 +- Mathlib/Analysis/Seminorm.lean | 2 +- .../Analysis/SpecialFunctions/Bernstein.lean | 1 + Mathlib/Analysis/SpecificLimits/Normed.lean | 2 +- .../AkraBazzi/GrowsPolynomially.lean | 4 +- Mathlib/Data/Int/Log.lean | 22 +++-- Mathlib/Data/Int/WithZero.lean | 4 +- Mathlib/Data/NNReal/Basic.lean | 4 +- .../Integral/CircleIntegral.lean | 2 +- .../NumberTheory/Padics/PadicIntegers.lean | 11 ++- Mathlib/NumberTheory/Padics/PadicNorm.lean | 25 ++---- Mathlib/NumberTheory/Padics/PadicNumbers.lean | 19 ++-- Mathlib/NumberTheory/Padics/RingHoms.lean | 2 +- 19 files changed, 168 insertions(+), 112 deletions(-) diff --git a/Mathlib/Algebra/Order/Archimedean/Basic.lean b/Mathlib/Algebra/Order/Archimedean/Basic.lean index 576accb749d8c9..4d20bc04708f5f 100644 --- a/Mathlib/Algebra/Order/Archimedean/Basic.lean +++ b/Mathlib/Algebra/Order/Archimedean/Basic.lean @@ -3,7 +3,7 @@ Copyright (c) 2018 Mario Carneiro. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Mario Carneiro -/ -import Mathlib.Algebra.Order.Field.Power +import Mathlib.Algebra.Order.Ring.Pow import Mathlib.Data.Int.LeastGreatest import Mathlib.Data.Rat.Floor import Mathlib.Data.NNRat.Defs @@ -246,7 +246,7 @@ theorem exists_mem_Ico_zpow (hx : 0 < x) (hy : 1 < y) : ∃ n : ℤ, x ∈ Ico ( have hb : ∃ b : ℤ, ∀ m, y ^ m ≤ x → m ≤ b := ⟨M, fun m hm => le_of_not_lt fun hlt => - not_lt_of_ge (zpow_le_of_le hy.le hlt.le) + not_lt_of_ge (zpow_le_zpow_right₀ hy.le hlt.le) (lt_of_le_of_lt hm (by rwa [← zpow_natCast] at hM))⟩ let ⟨n, hn₁, hn₂⟩ := Int.exists_greatest_of_bdd hb he ⟨n, hn₁, lt_of_not_ge fun hge => not_le_of_gt (Int.lt_succ _) (hn₂ _ hge)⟩ @@ -257,8 +257,8 @@ but with ≤ and < the other way around. -/ theorem exists_mem_Ioc_zpow (hx : 0 < x) (hy : 1 < y) : ∃ n : ℤ, x ∈ Ioc (y ^ n) (y ^ (n + 1)) := let ⟨m, hle, hlt⟩ := exists_mem_Ico_zpow (inv_pos.2 hx) hy have hyp : 0 < y := lt_trans zero_lt_one hy - ⟨-(m + 1), by rwa [zpow_neg, inv_lt_comm₀ (zpow_pos_of_pos hyp _) hx], by - rwa [neg_add, neg_add_cancel_right, zpow_neg, le_inv_comm₀ hx (zpow_pos_of_pos hyp _)]⟩ + ⟨-(m + 1), by rwa [zpow_neg, inv_lt_comm₀ (zpow_pos hyp _) hx], by + rwa [neg_add, neg_add_cancel_right, zpow_neg, le_inv_comm₀ hx (zpow_pos hyp _)]⟩ /-- For any `y < 1` and any positive `x`, there exists `n : ℕ` with `y ^ n < x`. -/ theorem exists_pow_lt_of_lt_one (hx : 0 < x) (hy : y < 1) : ∃ n : ℕ, y ^ n < x := by diff --git a/Mathlib/Algebra/Order/Field/Power.lean b/Mathlib/Algebra/Order/Field/Power.lean index 70c83a1869e07c..67ff27a9c705f3 100644 --- a/Mathlib/Algebra/Order/Field/Power.lean +++ b/Mathlib/Algebra/Order/Field/Power.lean @@ -24,80 +24,68 @@ variable [LinearOrderedSemifield α] {a b c d e : α} {m n : ℤ} /-! ### Integer powers -/ -@[gcongr] -theorem zpow_le_of_le (ha : 1 ≤ a) (h : m ≤ n) : a ^ m ≤ a ^ n := by - have ha₀ : 0 < a := one_pos.trans_le ha - lift n - m to ℕ using sub_nonneg.2 h with k hk - calc - a ^ m = a ^ m * 1 := (mul_one _).symm - _ ≤ a ^ m * a ^ k := - mul_le_mul_of_nonneg_left (one_le_pow₀ ha) (zpow_nonneg ha₀.le _) - _ = a ^ n := by rw [← zpow_natCast, ← zpow_add₀ ha₀.ne', hk, add_sub_cancel] +@[deprecated zpow_le_zpow_right₀ (since := "2024-10-08")] +theorem zpow_le_of_le (ha : 1 ≤ a) (h : m ≤ n) : a ^ m ≤ a ^ n := zpow_le_zpow_right₀ ha h +@[deprecated zpow_le_one_of_nonpos₀ (since := "2024-10-08")] theorem zpow_le_one_of_nonpos (ha : 1 ≤ a) (hn : n ≤ 0) : a ^ n ≤ 1 := - (zpow_le_of_le ha hn).trans_eq <| zpow_zero _ + zpow_le_one_of_nonpos₀ ha hn +@[deprecated one_le_zpow₀ (since := "2024-10-08")] theorem one_le_zpow_of_nonneg (ha : 1 ≤ a) (hn : 0 ≤ n) : 1 ≤ a ^ n := - (zpow_zero _).symm.trans_le <| zpow_le_of_le ha hn + one_le_zpow₀ ha hn -protected theorem Nat.zpow_pos_of_pos {a : ℕ} (h : 0 < a) (n : ℤ) : 0 < (a : α) ^ n := by - apply zpow_pos_of_pos - exact mod_cast h +@[deprecated zpow_pos (since := "2024-10-08")] +protected theorem Nat.zpow_pos_of_pos {a : ℕ} (h : 0 < a) (n : ℤ) : 0 < (a : α) ^ n := + zpow_pos (mod_cast h) _ +@[deprecated zpow_ne_zero (since := "2024-10-08")] theorem Nat.zpow_ne_zero_of_pos {a : ℕ} (h : 0 < a) (n : ℤ) : (a : α) ^ n ≠ 0 := - (Nat.zpow_pos_of_pos h n).ne' + zpow_ne_zero _ (mod_cast h.ne') -theorem one_lt_zpow (ha : 1 < a) : ∀ n : ℤ, 0 < n → 1 < a ^ n - | (n : ℕ), h => (zpow_natCast _ _).symm.subst (one_lt_pow₀ ha <| Int.natCast_ne_zero.mp h.ne') - | -[_+1], h => ((Int.negSucc_not_pos _).mp h).elim +@[deprecated one_lt_zpow₀ (since := "2024-10-08")] +theorem one_lt_zpow (ha : 1 < a) (n : ℤ) (hn : 0 < n) : 1 < a ^ n := one_lt_zpow₀ ha hn +@[deprecated zpow_right_strictMono₀ (since := "2024-10-08")] theorem zpow_strictMono (hx : 1 < a) : StrictMono (a ^ · : ℤ → α) := - strictMono_int_of_lt_succ fun n => - have xpos : 0 < a := zero_lt_one.trans hx - calc - a ^ n < a ^ n * a := lt_mul_of_one_lt_right (zpow_pos_of_pos xpos _) hx - _ = a ^ (n + 1) := (zpow_add_one₀ xpos.ne' _).symm + zpow_right_strictMono₀ hx +@[deprecated zpow_right_strictAnti₀ (since := "2024-10-08")] theorem zpow_strictAnti (h₀ : 0 < a) (h₁ : a < 1) : StrictAnti (a ^ · : ℤ → α) := - strictAnti_int_of_succ_lt fun n => - calc - a ^ (n + 1) = a ^ n * a := zpow_add_one₀ h₀.ne' _ - _ < a ^ n * 1 := (mul_lt_mul_left <| zpow_pos_of_pos h₀ _).2 h₁ - _ = a ^ n := mul_one _ + zpow_right_strictAnti₀ h₀ h₁ -@[simp] +@[deprecated zpow_lt_zpow_iff_right₀ (since := "2024-10-08")] theorem zpow_lt_iff_lt (hx : 1 < a) : a ^ m < a ^ n ↔ m < n := - (zpow_strictMono hx).lt_iff_lt + zpow_lt_zpow_iff_right₀ hx -@[gcongr] alias ⟨_, GCongr.zpow_lt_of_lt⟩ := zpow_lt_iff_lt +@[deprecated (since := "2024-02-10")] alias ⟨_, zpow_lt_of_lt⟩ := zpow_lt_iff_lt -@[deprecated (since := "2024-02-10")] alias zpow_lt_of_lt := GCongr.zpow_lt_of_lt - -@[simp] +@[deprecated zpow_le_zpow_iff_right₀ (since := "2024-10-08")] theorem zpow_le_iff_le (hx : 1 < a) : a ^ m ≤ a ^ n ↔ m ≤ n := - (zpow_strictMono hx).le_iff_le + zpow_le_zpow_iff_right₀ hx -@[simp] +@[deprecated div_le_self (since := "2024-10-08")] theorem div_pow_le (ha : 0 ≤ a) (hb : 1 ≤ b) (k : ℕ) : a / b ^ k ≤ a := div_le_self ha <| one_le_pow₀ hb -theorem zpow_injective (h₀ : 0 < a) (h₁ : a ≠ 1) : Injective (a ^ · : ℤ → α) := by - rcases h₁.lt_or_lt with (H | H) - · exact (zpow_strictAnti h₀ H).injective - · exact (zpow_strictMono H).injective +@[deprecated zpow_right_injective₀ (since := "2024-10-08")] +theorem zpow_injective (h₀ : 0 < a) (h₁ : a ≠ 1) : Injective (a ^ · : ℤ → α) := + zpow_right_injective₀ h₀ h₁ -@[simp] +@[deprecated zpow_right_inj₀ (since := "2024-10-08")] theorem zpow_inj (h₀ : 0 < a) (h₁ : a ≠ 1) : a ^ m = a ^ n ↔ m = n := - (zpow_injective h₀ h₁).eq_iff + zpow_right_inj₀ h₀ h₁ +@[deprecated (since := "2024-10-08")] theorem zpow_le_max_of_min_le {x : α} (hx : 1 ≤ x) {a b c : ℤ} (h : min a b ≤ c) : x ^ (-c) ≤ max (x ^ (-a)) (x ^ (-b)) := - have : Antitone fun n : ℤ => x ^ (-n) := fun _ _ h => zpow_le_of_le hx (neg_le_neg h) + have : Antitone fun n : ℤ => x ^ (-n) := fun _ _ h => zpow_le_zpow_right₀ hx (neg_le_neg h) (this h).trans_eq this.map_min +@[deprecated (since := "2024-10-08")] theorem zpow_le_max_iff_min_le {x : α} (hx : 1 < x) {a b c : ℤ} : x ^ (-c) ≤ max (x ^ (-a)) (x ^ (-b)) ↔ min a b ≤ c := by - simp_rw [le_max_iff, min_le_iff, zpow_le_iff_le hx, neg_le_neg_iff] + simp_rw [le_max_iff, min_le_iff, zpow_le_zpow_iff_right₀ hx, neg_le_neg_iff] end LinearOrderedSemifield @@ -205,7 +193,7 @@ def evalZPow : PositivityExt where eval {u α} zα pα e := do let _a ← synthInstanceQ (q(LinearOrderedSemifield $α) : Q(Type u)) haveI' : $e =Q $a ^ $b := ⟨⟩ assumeInstancesCommute - pure (.positive q(zpow_pos_of_pos $pa $b)) + pure (.positive q(zpow_pos $pa $b)) catch e : Exception => trace[Tactic.positivity.failure] "{e.toMessageData}" let oα ← synthInstanceQ q(LinearOrderedSemifield $α) diff --git a/Mathlib/Algebra/Order/GroupWithZero/Unbundled.lean b/Mathlib/Algebra/Order/GroupWithZero/Unbundled.lean index d89b2b8a4fc2bf..b238cd2ab171e0 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Unbundled.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Unbundled.lean @@ -84,6 +84,8 @@ for a discussion about this notation, and whether to enable it globally (note th currently global but broken, hence actually only works locally). -/ +open Function + variable {M₀ G₀ : Type*} (α : Type*) set_option quotPrecheck false in @@ -1189,12 +1191,14 @@ lemma zpow_nonneg [PosMulMono G₀] (ha : 0 ≤ a) : ∀ n : ℤ, 0 ≤ a ^ n | (n : ℕ) => by rw [zpow_natCast]; exact pow_nonneg ha _ |-(n + 1 : ℕ) => by rw [zpow_neg, inv_nonneg, zpow_natCast]; exact pow_nonneg ha _ -lemma zpow_pos_of_pos [PosMulStrictMono G₀] (ha : 0 < a) : ∀ n : ℤ, 0 < a ^ n +lemma zpow_pos [PosMulStrictMono G₀] (ha : 0 < a) : ∀ n : ℤ, 0 < a ^ n | (n : ℕ) => by rw [zpow_natCast]; exact pow_pos ha _ |-(n + 1 : ℕ) => by rw [zpow_neg, inv_pos, zpow_natCast]; exact pow_pos ha _ +@[deprecated (since := "2024-10-08")] alias zpow_pos_of_pos := zpow_pos + section PosMulMono -variable [PosMulMono G₀] +variable [PosMulMono G₀] {m n : ℤ} /-- See `le_inv_mul_iff₀'` for a version with multiplication on the other side. -/ lemma le_inv_mul_iff₀ (hc : 0 < c) : a ≤ c⁻¹ * b ↔ c * a ≤ b where @@ -1242,6 +1246,34 @@ lemma inv_mul_le_of_le_mul₀ (hb : 0 ≤ b) (hc : 0 ≤ c) (h : a ≤ b * c) : lemma inv_mul_le_one_of_le₀ (h : a ≤ b) (hb : 0 ≤ b) : b⁻¹ * a ≤ 1 := inv_mul_le_of_le_mul₀ hb zero_le_one <| by rwa [mul_one] +lemma zpow_right_mono₀ (ha : 1 ≤ a) : Monotone fun n : ℤ ↦ a ^ n := by + refine monotone_int_of_le_succ fun n ↦ ?_ + rw [zpow_add_one₀ (zero_lt_one.trans_le ha).ne'] + exact le_mul_of_one_le_right (zpow_nonneg (zero_le_one.trans ha) _) ha + +lemma zpow_right_anti₀ (ha₀ : 0 < a) (ha₁ : a ≤ 1) : Antitone fun n : ℤ ↦ a ^ n := by + refine antitone_int_of_succ_le fun n ↦ ?_ + rw [zpow_add_one₀ ha₀.ne'] + exact mul_le_of_le_one_right (zpow_nonneg ha₀.le _) ha₁ + +@[gcongr] +lemma zpow_le_zpow_right₀ (ha : 1 ≤ a) (hmn : m ≤ n) : a ^ m ≤ a ^ n := zpow_right_mono₀ ha hmn + +@[gcongr] +lemma zpow_le_zpow_right_of_le_one₀ (ha₀ : 0 < a) (ha₁ : a ≤ 1) (hmn : m ≤ n) : a ^ n ≤ a ^ m := + zpow_right_anti₀ ha₀ ha₁ hmn + +lemma one_le_zpow₀ (ha : 1 ≤ a) (hn : 0 ≤ n) : 1 ≤ a ^ n := by simpa using zpow_right_mono₀ ha hn + +lemma zpow_le_one₀ (ha₀ : 0 < a) (ha₁ : a ≤ 1) (hn : 0 ≤ n) : a ^ n ≤ 1 := by + simpa using zpow_right_anti₀ ha₀ ha₁ hn + +lemma zpow_le_one_of_nonpos₀ (ha : 1 ≤ a) (hn : n ≤ 0) : a ^ n ≤ 1 := by + simpa using zpow_right_mono₀ ha hn + +lemma one_le_zpow_of_nonpos₀ (ha₀ : 0 < a) (ha₁ : a ≤ 1) (hn : n ≤ 0) : 1 ≤ a ^ n := by + simpa using zpow_right_anti₀ ha₀ ha₁ hn + end PosMulMono section MulPosMono @@ -1331,7 +1363,7 @@ lemma le_inv_of_le_inv₀ (ha : 0 < a) (h : a ≤ b⁻¹) : b ≤ a⁻¹ := end MulPosMono section PosMulStrictMono -variable [PosMulStrictMono G₀] +variable [PosMulStrictMono G₀] {m n : ℤ} /-- See `lt_inv_mul_iff₀'` for a version with multiplication on the other side. -/ lemma lt_inv_mul_iff₀ (hc : 0 < c) : a < c⁻¹ * b ↔ c * a < b where @@ -1360,6 +1392,42 @@ lemma one_lt_inv_iff₀ : 1 < a⁻¹ ↔ 0 < a ∧ a < 1 where mp h := ⟨inv_pos.1 (zero_lt_one.trans h), inv_inv a ▸ (inv_lt_one₀ <| zero_lt_one.trans h).2 h⟩ mpr h := (one_lt_inv₀ h.1).2 h.2 +lemma zpow_right_strictMono₀ (ha : 1 < a) : StrictMono fun n : ℤ ↦ a ^ n := by + refine strictMono_int_of_lt_succ fun n ↦ ?_ + rw [zpow_add_one₀ (zero_lt_one.trans ha).ne'] + exact lt_mul_of_one_lt_right (zpow_pos (zero_lt_one.trans ha) _) ha + +lemma zpow_right_strictAnti₀ (ha₀ : 0 < a) (ha₁ : a < 1) : StrictAnti fun n : ℤ ↦ a ^ n := by + refine strictAnti_int_of_succ_lt fun n ↦ ?_ + rw [zpow_add_one₀ ha₀.ne'] + exact mul_lt_of_lt_one_right (zpow_pos ha₀ _) ha₁ + +@[gcongr] +lemma zpow_lt_zpow_right₀ (ha : 1 < a) (hmn : m < n) : a ^ m < a ^ n := + zpow_right_strictMono₀ ha hmn + +@[gcongr] +lemma zpow_lt_zpow_right_of_lt_one₀ (ha₀ : 0 < a) (ha₁ : a ≤ 1) (hmn : m ≤ n) : a ^ n ≤ a ^ m := + zpow_right_anti₀ ha₀ ha₁ hmn + +lemma one_lt_zpow₀ (ha : 1 < a) (hn : 0 < n) : 1 < a ^ n := by + simpa using zpow_right_strictMono₀ ha hn + +lemma zpow_lt_one₀ (ha₀ : 0 < a) (ha₁ : a < 1) (hn : 0 < n) : a ^ n < 1 := by + simpa using zpow_right_strictAnti₀ ha₀ ha₁ hn + +lemma zpow_lt_one_of_neg₀ (ha : 1 < a) (hn : n < 0) : a ^ n < 1 := by + simpa using zpow_right_strictMono₀ ha hn + +lemma one_lt_zpow_of_neg₀ (ha₀ : 0 < a) (ha₁ : a < 1) (hn : n < 0) : 1 < a ^ n := by + simpa using zpow_right_strictAnti₀ ha₀ ha₁ hn + +@[simp] lemma zpow_le_zpow_iff_right₀ (ha : 1 < a) : a ^ m ≤ a ^ n ↔ m ≤ n := + (zpow_right_strictMono₀ ha).le_iff_le + +@[simp] lemma zpow_lt_zpow_iff_right₀ (ha : 1 < a) : a ^ m < a ^ n ↔ m < n := + (zpow_right_strictMono₀ ha).lt_iff_lt + end PosMulStrictMono section MulPosStrictMono @@ -1428,12 +1496,22 @@ lemma one_div_nonpos : 1 / a ≤ 0 ↔ a ≤ 0 := one_div a ▸ inv_nonpos lemma div_nonpos_of_nonneg_of_nonpos [PosMulMono G₀] (ha : 0 ≤ a) (hb : b ≤ 0) : a / b ≤ 0 := by rw [div_eq_mul_inv]; exact mul_nonpos_of_nonneg_of_nonpos ha (inv_nonpos.2 hb) -lemma inv_lt_one_iff₀ [PosMulStrictMono G₀] : a⁻¹ < 1 ↔ a ≤ 0 ∨ 1 < a := by +variable [PosMulStrictMono G₀] {m n : ℤ} + +lemma inv_lt_one_iff₀ : a⁻¹ < 1 ↔ a ≤ 0 ∨ 1 < a := by simp_rw [← not_le, one_le_inv_iff₀, not_and_or, not_lt] -lemma inv_le_one_iff₀ [PosMulStrictMono G₀] : a⁻¹ ≤ 1 ↔ a ≤ 0 ∨ 1 ≤ a := by +lemma inv_le_one_iff₀ : a⁻¹ ≤ 1 ↔ a ≤ 0 ∨ 1 ≤ a := by simp only [← not_lt, one_lt_inv_iff₀, not_and_or] +lemma zpow_right_injective₀ (ha₀ : 0 < a) (ha₁ : a ≠ 1) : Injective fun n : ℤ ↦ a ^ n := by + obtain ha₁ | ha₁ := ha₁.lt_or_lt + · exact (zpow_right_strictAnti₀ ha₀ ha₁).injective + · exact (zpow_right_strictMono₀ ha₁).injective + +@[simp] lemma zpow_right_inj₀ (ha₀ : 0 < a) (ha₁ : a ≠ 1) : a ^ m = a ^ n ↔ m = n := + (zpow_right_injective₀ ha₀ ha₁).eq_iff + end GroupWithZero.LinearOrder section CommSemigroupHasZero diff --git a/Mathlib/Algebra/Order/Positive/Field.lean b/Mathlib/Algebra/Order/Positive/Field.lean index 3a053adc33a18e..5d1fc0b3817609 100644 --- a/Mathlib/Algebra/Order/Positive/Field.lean +++ b/Mathlib/Algebra/Order/Positive/Field.lean @@ -25,7 +25,7 @@ theorem coe_inv (x : { x : K // 0 < x }) : ↑x⁻¹ = (x⁻¹ : K) := rfl instance : Pow { x : K // 0 < x } ℤ := - ⟨fun x n => ⟨(x : K) ^ n, zpow_pos_of_pos x.2 _⟩⟩ + ⟨fun x n => ⟨(x : K) ^ n, zpow_pos x.2 _⟩⟩ @[simp] theorem coe_zpow (x : { x : K // 0 < x }) (n : ℤ) : ↑(x ^ n) = (x : K) ^ n := diff --git a/Mathlib/Analysis/Convex/SpecificFunctions/Deriv.lean b/Mathlib/Analysis/Convex/SpecificFunctions/Deriv.lean index 9d5442089d9219..981b12a32e26c0 100644 --- a/Mathlib/Analysis/Convex/SpecificFunctions/Deriv.lean +++ b/Mathlib/Analysis/Convex/SpecificFunctions/Deriv.lean @@ -96,7 +96,7 @@ theorem strictConvexOn_zpow {m : ℤ} (hm₀ : m ≠ 0) (hm₁ : m ≠ 1) : intro x hx rw [mem_Ioi] at hx rw [iter_deriv_zpow] - refine mul_pos ?_ (zpow_pos_of_pos hx _) + refine mul_pos ?_ (zpow_pos hx _) norm_cast refine int_prod_range_pos (by decide) fun hm => ?_ rw [← Finset.coe_Ico] at hm diff --git a/Mathlib/Analysis/Distribution/SchwartzSpace.lean b/Mathlib/Analysis/Distribution/SchwartzSpace.lean index 0539009beca035..ba8aae073aff97 100644 --- a/Mathlib/Analysis/Distribution/SchwartzSpace.lean +++ b/Mathlib/Analysis/Distribution/SchwartzSpace.lean @@ -139,7 +139,7 @@ theorem isBigO_cocompact_zpow_neg_nat (k : ℕ) : refine ⟨d, Filter.Eventually.filter_mono Filter.cocompact_le_cofinite ?_⟩ refine (Filter.eventually_cofinite_ne 0).mono fun x hx => ?_ rw [Real.norm_of_nonneg (zpow_nonneg (norm_nonneg _) _), zpow_neg, ← div_eq_mul_inv, le_div_iff₀'] - exacts [hd' x, zpow_pos_of_pos (norm_pos_iff.mpr hx) _] + exacts [hd' x, zpow_pos (norm_pos_iff.mpr hx) _] theorem isBigO_cocompact_rpow [ProperSpace E] (s : ℝ) : f =O[cocompact E] fun x => ‖x‖ ^ s := by diff --git a/Mathlib/Analysis/Hofer.lean b/Mathlib/Analysis/Hofer.lean index 3224c5efddfd7f..8d5fda97eb89ea 100644 --- a/Mathlib/Analysis/Hofer.lean +++ b/Mathlib/Analysis/Hofer.lean @@ -35,7 +35,7 @@ theorem hofer {X : Type*} [MetricSpace X] [CompleteSpace X] (x : X) (ε : ℝ) ( ∃ y, d x' y ≤ ε / 2 ^ k ∧ 2 * ϕ x' < ϕ y := by intro k x' push_neg at H - have := H (ε / 2 ^ k) (by positivity) x' (by simp [ε_pos.le, one_le_two]) + 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⟩ choose! F hF using H diff --git a/Mathlib/Analysis/Seminorm.lean b/Mathlib/Analysis/Seminorm.lean index c59be01c216894..a448a13eadcc87 100644 --- a/Mathlib/Analysis/Seminorm.lean +++ b/Mathlib/Analysis/Seminorm.lean @@ -1190,7 +1190,7 @@ lemma rescale_to_shell_zpow (p : Seminorm 𝕜 E) {c : 𝕜} (hc : 1 < ‖c‖) · show ε / ‖c‖ ≤ p (c ^ (-(n + 1)) • x) rw [zpow_neg, div_le_iff₀ cpos, map_smul_eq_mul, norm_inv, norm_zpow, zpow_add₀ (ne_of_gt cpos), zpow_one, mul_inv_rev, mul_comm, ← mul_assoc, ← mul_assoc, mul_inv_cancel₀ (ne_of_gt cpos), - one_mul, ← div_eq_inv_mul, le_div_iff₀ (zpow_pos_of_pos cpos _), mul_comm] + one_mul, ← div_eq_inv_mul, le_div_iff₀ (zpow_pos cpos _), mul_comm] exact (le_div_iff₀ εpos).1 hn.1 · show ‖(c ^ (-(n + 1)))‖⁻¹ ≤ ε⁻¹ * ‖c‖ * p x have : ε⁻¹ * ‖c‖ * p x = ε⁻¹ * p x * ‖c‖ := by ring diff --git a/Mathlib/Analysis/SpecialFunctions/Bernstein.lean b/Mathlib/Analysis/SpecialFunctions/Bernstein.lean index 50a7c0ab65155e..a38081bf155828 100644 --- a/Mathlib/Analysis/SpecialFunctions/Bernstein.lean +++ b/Mathlib/Analysis/SpecialFunctions/Bernstein.lean @@ -3,6 +3,7 @@ Copyright (c) 2021 Kim Morrison. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Kim Morrison -/ +import Mathlib.Algebra.Order.Field.Power import Mathlib.Analysis.SpecificLimits.Basic import Mathlib.RingTheory.Polynomial.Bernstein import Mathlib.Topology.ContinuousMap.Polynomial diff --git a/Mathlib/Analysis/SpecificLimits/Normed.lean b/Mathlib/Analysis/SpecificLimits/Normed.lean index 525b05e39a0cf0..ba7281ba264e25 100644 --- a/Mathlib/Analysis/SpecificLimits/Normed.lean +++ b/Mathlib/Analysis/SpecificLimits/Normed.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Anatole Dedecker, Sébastien Gouëzel, Yury Kudryashov, Dylan MacKenzie, Patrick Massot -/ import Mathlib.Algebra.BigOperators.Module -import Mathlib.Algebra.Order.Field.Basic +import Mathlib.Algebra.Order.Field.Power import Mathlib.Analysis.Asymptotics.Asymptotics import Mathlib.Analysis.Normed.Field.InfiniteSum import Mathlib.Analysis.Normed.Module.Basic diff --git a/Mathlib/Computability/AkraBazzi/GrowsPolynomially.lean b/Mathlib/Computability/AkraBazzi/GrowsPolynomially.lean index aace8634bc1a84..f9b3f66acc2b82 100644 --- a/Mathlib/Computability/AkraBazzi/GrowsPolynomially.lean +++ b/Mathlib/Computability/AkraBazzi/GrowsPolynomially.lean @@ -131,7 +131,7 @@ lemma eventually_zero_of_frequently_zero (hf : GrowsPolynomially f) (hf' : ∃ refine hmain ⌊-logb 2 (x / x₀)⌋₊ x le_rfl ⟨?lb, ?ub⟩ case lb => rw [← le_div_iff₀ x₀_pos] - refine (logb_le_logb (b := 2) (by norm_num) (zpow_pos_of_pos (by norm_num) _) + refine (logb_le_logb (b := 2) (by norm_num) (zpow_pos (by norm_num) _) (by positivity)).mp ?_ rw [← rpow_intCast, logb_rpow (by norm_num) (by norm_num), ← neg_le_neg_iff] simp only [Int.cast_sub, Int.cast_neg, Int.cast_natCast, Int.cast_one, neg_sub, sub_neg_eq_add] @@ -140,7 +140,7 @@ lemma eventually_zero_of_frequently_zero (hf : GrowsPolynomially f) (hf' : ∃ case ub => rw [← div_le_iff₀ x₀_pos] refine (logb_le_logb (b := 2) (by norm_num) (by positivity) - (zpow_pos_of_pos (by norm_num) _)).mp ?_ + (zpow_pos (by norm_num) _)).mp ?_ rw [← rpow_intCast, logb_rpow (by norm_num) (by norm_num), ← neg_le_neg_iff] simp only [Int.cast_neg, Int.cast_natCast, neg_neg] have : 0 ≤ -logb 2 (x / x₀) := by diff --git a/Mathlib/Data/Int/Log.lean b/Mathlib/Data/Int/Log.lean index ac78731f26da46..e6f5f9f4571594 100644 --- a/Mathlib/Data/Int/Log.lean +++ b/Mathlib/Data/Int/Log.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Eric Wieser -/ import Mathlib.Algebra.Order.Floor -import Mathlib.Algebra.Order.Field.Power import Mathlib.Data.Nat.Log /-! @@ -135,12 +134,11 @@ theorem log_one_left (r : R) : log 1 r = 0 := by -- Porting note: needed to replace b ^ z with (b : R) ^ z in the below theorem log_zpow {b : ℕ} (hb : 1 < b) (z : ℤ) : log b ((b : R) ^ z : R) = z := by obtain ⟨n, rfl | rfl⟩ := Int.eq_nat_or_neg z - · rw [log_of_one_le_right _ (one_le_zpow_of_nonneg _ <| Int.natCast_nonneg _), zpow_natCast, ← - Nat.cast_pow, Nat.floor_natCast, Nat.log_pow hb] - exact mod_cast hb.le - · rw [log_of_right_le_one _ (zpow_le_one_of_nonpos _ <| neg_nonpos.mpr (Int.natCast_nonneg _)), + · rw [log_of_one_le_right _ (one_le_zpow₀ (mod_cast hb.le) <| Int.natCast_nonneg _), zpow_natCast, + ← Nat.cast_pow, Nat.floor_natCast, Nat.log_pow hb] + · rw [log_of_right_le_one _ (zpow_le_one_of_nonpos₀ (mod_cast hb.le) <| + neg_nonpos.2 (Int.natCast_nonneg _)), zpow_neg, inv_inv, zpow_natCast, ← Nat.cast_pow, Nat.ceil_natCast, Nat.clog_pow _ _ hb] - exact mod_cast hb.le @[mono] theorem log_mono_right {b : ℕ} {r₁ r₂ : R} (h₀ : 0 < r₁) (h : r₁ ≤ r₂) : log b r₁ ≤ log b r₂ := by @@ -160,10 +158,10 @@ variable (R) def zpowLogGi {b : ℕ} (hb : 1 < b) : GaloisCoinsertion (fun z : ℤ => - Subtype.mk ((b : R) ^ z) <| zpow_pos_of_pos (mod_cast zero_lt_one.trans hb) z) + Subtype.mk ((b : R) ^ z) <| zpow_pos (mod_cast zero_lt_one.trans hb) z) fun r : Set.Ioi (0 : R) => Int.log b (r : R) := GaloisCoinsertion.monotoneIntro (fun r₁ _ => log_mono_right r₁.2) - (fun _ _ hz => Subtype.coe_le_coe.mp <| (zpow_strictMono <| mod_cast hb).monotone hz) + (fun _ _ hz => Subtype.coe_le_coe.mp <| (zpow_right_strictMono₀ <| mod_cast hb).monotone hz) (fun r => Subtype.coe_le_coe.mp <| zpow_log_le_self hb r.2) fun _ => log_zpow (R := R) hb _ variable {R} @@ -235,7 +233,7 @@ theorem self_le_zpow_clog {b : ℕ} (hb : 1 < b) (r : R) : r ≤ (b : R) ^ clog rcases le_or_lt r 0 with hr | hr · rw [clog_of_right_le_zero _ hr, zpow_zero] exact hr.trans zero_le_one - rw [← neg_log_inv_eq_clog, zpow_neg, le_inv_comm₀ hr (zpow_pos_of_pos _ _)] + rw [← neg_log_inv_eq_clog, zpow_neg, le_inv_comm₀ hr (zpow_pos ..)] · exact zpow_log_le_self hb (inv_pos.mpr hr) · exact Nat.cast_pos.mpr (zero_le_one.trans_lt hb) @@ -243,7 +241,7 @@ theorem zpow_pred_clog_lt_self {b : ℕ} {r : R} (hb : 1 < b) (hr : 0 < r) : (b : R) ^ (clog b r - 1) < r := by rw [← neg_log_inv_eq_clog, ← neg_add', zpow_neg, inv_lt_comm₀ _ hr] · exact lt_zpow_succ_log_self hb _ - · exact zpow_pos_of_pos (Nat.cast_pos.mpr <| zero_le_one.trans_lt hb) _ + · exact zpow_pos (Nat.cast_pos.mpr <| zero_le_one.trans_lt hb) _ @[simp] theorem clog_zero_right (b : ℕ) : clog b (0 : R) = 0 := @@ -278,9 +276,9 @@ variable (R) /-- Over suitable subtypes, `Int.clog` and `zpow` form a galois insertion -/ def clogZPowGi {b : ℕ} (hb : 1 < b) : GaloisInsertion (fun r : Set.Ioi (0 : R) => Int.clog b (r : R)) fun z : ℤ => - ⟨(b : R) ^ z, zpow_pos_of_pos (mod_cast zero_lt_one.trans hb) z⟩ := + ⟨(b : R) ^ z, zpow_pos (mod_cast zero_lt_one.trans hb) z⟩ := GaloisInsertion.monotoneIntro - (fun _ _ hz => Subtype.coe_le_coe.mp <| (zpow_strictMono <| mod_cast hb).monotone hz) + (fun _ _ hz => Subtype.coe_le_coe.mp <| (zpow_right_strictMono₀ <| mod_cast hb).monotone hz) (fun r₁ _ => clog_mono_right r₁.2) (fun _ => Subtype.coe_le_coe.mp <| self_le_zpow_clog hb _) fun _ => clog_zpow (R := R) hb _ diff --git a/Mathlib/Data/Int/WithZero.lean b/Mathlib/Data/Int/WithZero.lean index 3cf41e5f88e38d..ec6f9a4c79ab05 100644 --- a/Mathlib/Data/Int/WithZero.lean +++ b/Mathlib/Data/Int/WithZero.lean @@ -82,9 +82,9 @@ theorem toNNReal_strictMono {e : NNReal} (he : 1 < e) : simp only [toNNReal, MonoidWithZeroHom.coe_mk, ZeroHom.coe_mk] split_ifs with hx hy hy · simp only [hy, not_lt_zero'] at hxy - · exact NNReal.zpow_pos (ne_zero_of_lt he) _ + · exact zpow_pos he.bot_lt _ · simp only [hy, not_lt_zero'] at hxy - · rw [zpow_lt_iff_lt he, Multiplicative.toAdd_lt, ← WithZero.coe_lt_coe, WithZero.coe_unzero hx, + · rw [zpow_lt_zpow_iff_right₀ he, Multiplicative.toAdd_lt, ← coe_lt_coe, coe_unzero hx, WithZero.coe_unzero hy] exact hxy diff --git a/Mathlib/Data/NNReal/Basic.lean b/Mathlib/Data/NNReal/Basic.lean index 0b975180adee61..bf80f11181f55d 100644 --- a/Mathlib/Data/NNReal/Basic.lean +++ b/Mathlib/Data/NNReal/Basic.lean @@ -903,8 +903,8 @@ theorem _root_.Real.toNNReal_div' {x y : ℝ} (hy : 0 ≤ y) : theorem inv_lt_one_iff {x : ℝ≥0} (hx : x ≠ 0) : x⁻¹ < 1 ↔ 1 < x := by rw [← one_div, div_lt_iff₀ hx.bot_lt, one_mul] -theorem zpow_pos {x : ℝ≥0} (hx : x ≠ 0) (n : ℤ) : 0 < x ^ n := - zpow_pos_of_pos hx.bot_lt _ +@[deprecated zpow_pos (since := "2024-10-08")] +protected theorem zpow_pos {x : ℝ≥0} (hx : x ≠ 0) (n : ℤ) : 0 < x ^ n := zpow_pos hx.bot_lt _ theorem inv_lt_inv {x y : ℝ≥0} (hx : x ≠ 0) (h : x < y) : y⁻¹ < x⁻¹ := inv_strictAnti₀ hx.bot_lt h diff --git a/Mathlib/MeasureTheory/Integral/CircleIntegral.lean b/Mathlib/MeasureTheory/Integral/CircleIntegral.lean index 673ac92017bbf5..bd267c4c74fe6b 100644 --- a/Mathlib/MeasureTheory/Integral/CircleIntegral.lean +++ b/Mathlib/MeasureTheory/Integral/CircleIntegral.lean @@ -286,7 +286,7 @@ theorem circleIntegrable_sub_zpow_iff {c w : ℂ} {R : ℝ} {n : ℤ} : not_false_iff] using this have : x ∈ Ioo (0 : ℝ) 1 := by simpa [x, and_comm] using hθ' rw [← zpow_neg_one] - refine (zpow_strictAnti this.1 this.2).le_iff_le.2 (Int.lt_add_one_iff.1 ?_); exact hn + refine (zpow_right_strictAnti₀ this.1 this.2).le_iff_le.2 (Int.lt_add_one_iff.1 ?_); exact hn · rintro (rfl | H) exacts [circleIntegrable_zero_radius, ((continuousOn_id.sub continuousOn_const).zpow₀ _ fun z hz => diff --git a/Mathlib/NumberTheory/Padics/PadicIntegers.lean b/Mathlib/NumberTheory/Padics/PadicIntegers.lean index a7add4280a7e7e..798a8c9d36b412 100644 --- a/Mathlib/NumberTheory/Padics/PadicIntegers.lean +++ b/Mathlib/NumberTheory/Padics/PadicIntegers.lean @@ -304,7 +304,7 @@ variable (p : ℕ) [hp : Fact p.Prime] theorem exists_pow_neg_lt {ε : ℝ} (hε : 0 < ε) : ∃ k : ℕ, (p : ℝ) ^ (-(k : ℤ)) < ε := by obtain ⟨k, hk⟩ := exists_nat_gt ε⁻¹ use k - rw [← inv_lt_inv₀ hε (_root_.zpow_pos_of_pos _ _)] + rw [← inv_lt_inv₀ hε (zpow_pos _ _)] · rw [zpow_neg, inv_inv, zpow_natCast] apply lt_of_lt_of_le hk norm_cast @@ -356,7 +356,7 @@ theorem valuation_nonneg (x : ℤ_[p]) : 0 ≤ x.valuation := by by_cases hx : x = 0 · simp [hx] have h : (1 : ℝ) < p := mod_cast hp.1.one_lt - rw [← neg_nonpos, ← (zpow_strictMono h).le_iff_le] + rw [← neg_nonpos, ← (zpow_right_strictMono₀ h).le_iff_le] show (p : ℝ) ^ (-valuation x) ≤ (p : ℝ) ^ (0 : ℤ) rw [← norm_eq_pow_val hx] simpa using x.property @@ -373,7 +373,7 @@ theorem valuation_p_pow_mul (n : ℕ) (c : ℤ_[p]) (hc : c ≠ 0) : exact_mod_cast pow_eq_zero hc · exact hc rwa [norm_eq_pow_val aux, norm_p_pow, norm_eq_pow_val hc, ← zpow_add₀, ← neg_add, - zpow_inj, neg_inj] at this + zpow_right_inj₀, neg_inj] at this · exact mod_cast hp.1.pos · exact mod_cast hp.1.ne_one · exact mod_cast hp.1.ne_zero @@ -433,8 +433,7 @@ See `unitCoeff_spec`. -/ def unitCoeff {x : ℤ_[p]} (hx : x ≠ 0) : ℤ_[p]ˣ := let u : ℚ_[p] := x * (p : ℚ_[p]) ^ (-x.valuation) have hu : ‖u‖ = 1 := by - simp [u, hx, Nat.zpow_ne_zero_of_pos (mod_cast hp.1.pos) x.valuation, norm_eq_pow_val, - zpow_neg, inv_mul_cancel] + simp [u, hx, zpow_ne_zero (G₀ := ℝ) _ (Nat.cast_ne_zero.2 hp.1.pos.ne'), norm_eq_pow_val] mkUnits hu @[simp] @@ -569,7 +568,7 @@ instance : IsAdicComplete (maximalIdeal ℤ_[p]) ℤ_[p] where exact hx hn · refine ⟨x'.lim, fun n => ?_⟩ have : (0 : ℝ) < (p : ℝ) ^ (-n : ℤ) := by - apply zpow_pos_of_pos + apply zpow_pos exact mod_cast hp.1.pos obtain ⟨i, hi⟩ := equiv_def₃ (equiv_lim x') this by_cases hin : i ≤ n diff --git a/Mathlib/NumberTheory/Padics/PadicNorm.lean b/Mathlib/NumberTheory/Padics/PadicNorm.lean index c61676a7816b87..311b2e21e81be0 100644 --- a/Mathlib/NumberTheory/Padics/PadicNorm.lean +++ b/Mathlib/NumberTheory/Padics/PadicNorm.lean @@ -3,7 +3,6 @@ Copyright (c) 2018 Robert Y. Lewis. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Robert Y. Lewis -/ -import Mathlib.Algebra.Order.Field.Power import Mathlib.NumberTheory.Padics.PadicVal.Basic /-! @@ -143,17 +142,11 @@ protected theorem div (q r : ℚ) : padicNorm p (q / r) = padicNorm p q / padicN else eq_div_of_mul_eq (padicNorm.nonzero hr) (by rw [← padicNorm.mul, div_mul_cancel₀ _ hr]) /-- The `p`-adic norm of an integer is at most `1`. -/ -protected theorem of_int (z : ℤ) : padicNorm p z ≤ 1 := - if hz : z = 0 then by simp [hz, zero_le_one] - else by - unfold padicNorm - rw [if_neg _] - · refine zpow_le_one_of_nonpos ?_ ?_ - · exact mod_cast le_of_lt hp.1.one_lt - · rw [padicValRat.of_int, neg_nonpos] - norm_cast - simp - exact mod_cast hz +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)] + 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) : padicNorm p (q + r) ≤ max (padicNorm p q) (padicNorm p r) := @@ -168,7 +161,7 @@ private theorem nonarchimedean_aux {q r : ℚ} (h : padicValRat p q ≤ padicVal unfold padicNorm; split_ifs apply le_max_iff.2 left - apply zpow_le_of_le + apply zpow_le_zpow_right₀ · exact mod_cast le_of_lt hp.1.one_lt · apply neg_le_neg have : padicValRat p q = min (padicValRat p q) (padicValRat p r) := (min_eq_left h).symm @@ -232,7 +225,7 @@ theorem dvd_iff_norm_le {n : ℕ} {z : ℤ} : ↑(p ^ n) ∣ z ↔ padicNorm p z unfold padicNorm; split_ifs with hz · norm_cast at hz simp [hz] - · rw [zpow_le_iff_le, neg_le_neg_iff, padicValRat.of_int, + · rw [zpow_le_zpow_iff_right₀, neg_le_neg_iff, padicValRat.of_int, padicValInt.of_ne_one_ne_zero hp.1.ne_one _] · norm_cast rw [← PartENat.coe_le_coe, PartENat.natCast_get, ← multiplicity.pow_dvd_iff_le_multiplicity, @@ -255,10 +248,10 @@ theorem int_eq_one_iff (m : ℤ) : padicNorm p m = 1 ↔ ¬(p : ℤ) ∣ m := by intro h exact (Nat.not_lt_zero p h).elim · have : 1 < (p : ℚ) := by norm_cast; exact Nat.Prime.one_lt (Fact.out : Nat.Prime p) - rw [← zpow_neg_one, zpow_lt_iff_lt this] + rw [← zpow_neg_one, zpow_lt_zpow_iff_right₀ this] have : 0 ≤ padicValRat p m := by simp only [of_int, Nat.cast_nonneg] intro h - rw [← zpow_zero (p : ℚ), zpow_inj] <;> linarith + rw [← zpow_zero (p : ℚ), zpow_right_inj₀] <;> linarith theorem int_lt_one_iff (m : ℤ) : padicNorm p m < 1 ↔ (p : ℤ) ∣ m := by rw [← not_iff_not, ← int_eq_one_iff, eq_iff_le_not_lt] diff --git a/Mathlib/NumberTheory/Padics/PadicNumbers.lean b/Mathlib/NumberTheory/Padics/PadicNumbers.lean index ff2f78e73d60b7..33559d1491dfe9 100644 --- a/Mathlib/NumberTheory/Padics/PadicNumbers.lean +++ b/Mathlib/NumberTheory/Padics/PadicNumbers.lean @@ -211,7 +211,7 @@ theorem norm_eq_pow_val {f : PadicSeq p} (hf : ¬f ≈ 0) : f.norm = (p : ℚ) ^ theorem val_eq_iff_norm_eq {f g : PadicSeq p} (hf : ¬f ≈ 0) (hg : ¬g ≈ 0) : f.valuation = g.valuation ↔ f.norm = g.norm := by - rw [norm_eq_pow_val hf, norm_eq_pow_val hg, ← neg_inj, zpow_inj] + rw [norm_eq_pow_val hf, norm_eq_pow_val hg, ← neg_inj, zpow_right_inj₀] · exact mod_cast (Fact.out : p.Prime).pos · exact mod_cast (Fact.out : p.Prime).ne_one @@ -971,7 +971,7 @@ theorem norm_eq_pow_val {x : ℚ_[p]} : x ≠ 0 → ‖x‖ = (p : ℝ) ^ (-x.va @[simp] theorem valuation_p : valuation (p : ℚ_[p]) = 1 := by have h : (1 : ℝ) < p := mod_cast (Fact.out : p.Prime).one_lt - refine neg_injective ((zpow_strictMono h).injective <| (norm_eq_pow_val ?_).symm.trans ?_) + refine neg_injective ((zpow_right_strictMono₀ h).injective <| (norm_eq_pow_val ?_).symm.trans ?_) · exact mod_cast (Fact.out : p.Prime).ne_zero · simp @@ -987,8 +987,9 @@ theorem valuation_map_add {x y : ℚ_[p]} (hxy : x + y ≠ 0) : have hp_one : (1 : ℝ) < p := by rw [← Nat.cast_one, Nat.cast_lt] exact Nat.Prime.one_lt hp.elim - rwa [norm_eq_pow_val hx, norm_eq_pow_val hy, norm_eq_pow_val hxy, - zpow_le_max_iff_min_le hp_one] at h_norm + rwa [norm_eq_pow_val hx, norm_eq_pow_val hy, norm_eq_pow_val hxy, le_max_iff, + zpow_le_zpow_iff_right₀ hp_one, zpow_le_zpow_iff_right₀ hp_one, neg_le_neg_iff, + neg_le_neg_iff, ← min_le_iff] at h_norm @[simp] theorem valuation_map_mul {x y : ℚ_[p]} (hx : x ≠ 0) (hy : y ≠ 0) : @@ -1001,7 +1002,7 @@ theorem valuation_map_mul {x y : ℚ_[p]} (hx : x ≠ 0) (hy : y ≠ 0) : rw [← Nat.cast_zero, Nat.cast_lt] exact Nat.Prime.pos hp.elim rw [norm_eq_pow_val hx, norm_eq_pow_val hy, norm_eq_pow_val (mul_ne_zero hx hy), ← - zpow_add₀ (ne_of_gt hp_pos), zpow_inj hp_pos hp_ne_one, ← neg_add, neg_inj] at h_norm + zpow_add₀ (ne_of_gt hp_pos), zpow_right_inj₀ hp_pos hp_ne_one, ← neg_add, neg_inj] at h_norm exact h_norm open Classical in @@ -1059,14 +1060,12 @@ section NormLEIff theorem norm_le_pow_iff_norm_lt_pow_add_one (x : ℚ_[p]) (n : ℤ) : ‖x‖ ≤ (p : ℝ) ^ n ↔ ‖x‖ < (p : ℝ) ^ (n + 1) := by - have aux : ∀ n : ℤ, 0 < ((p : ℝ) ^ n) := by - apply Nat.zpow_pos_of_pos - exact hp.1.pos + have aux (n : ℤ) : 0 < ((p : ℝ) ^ n) := zpow_pos (mod_cast hp.1.pos) _ by_cases hx0 : x = 0 · simp [hx0, norm_zero, aux, le_of_lt (aux _)] rw [norm_eq_pow_val hx0] have h1p : 1 < (p : ℝ) := mod_cast hp.1.one_lt - have H := zpow_strictMono h1p + have H := zpow_right_strictMono₀ h1p rw [H.le_iff_le, H.lt_iff_lt, Int.lt_add_one_iff] theorem norm_lt_pow_iff_norm_le_pow_sub_one (x : ℚ_[p]) (n : ℤ) : @@ -1076,7 +1075,7 @@ theorem norm_lt_pow_iff_norm_le_pow_sub_one (x : ℚ_[p]) (n : ℤ) : theorem norm_le_one_iff_val_nonneg (x : ℚ_[p]) : ‖x‖ ≤ 1 ↔ 0 ≤ x.valuation := by by_cases hx : x = 0 · simp only [hx, norm_zero, valuation_zero, zero_le_one, le_refl] - · rw [norm_eq_pow_val hx, ← zpow_zero (p : ℝ), zpow_le_iff_le, Right.neg_nonpos_iff] + · rw [norm_eq_pow_val hx, ← zpow_zero (p : ℝ), zpow_le_zpow_iff_right₀, Right.neg_nonpos_iff] exact Nat.one_lt_cast.2 (Nat.Prime.one_lt' p).1 end NormLEIff diff --git a/Mathlib/NumberTheory/Padics/RingHoms.lean b/Mathlib/NumberTheory/Padics/RingHoms.lean index 8f65a9cbc788ec..9458144550aafa 100644 --- a/Mathlib/NumberTheory/Padics/RingHoms.lean +++ b/Mathlib/NumberTheory/Padics/RingHoms.lean @@ -589,7 +589,7 @@ theorem lift_sub_val_mem_span (r : R) (n : ℕ) : lift f_compat r - (f n r).val ∈ (Ideal.span {(p : ℤ_[p]) ^ n}) := by obtain ⟨k, hk⟩ := limNthHom_spec f_compat r _ - (show (0 : ℝ) < (p : ℝ) ^ (-n : ℤ) from Nat.zpow_pos_of_pos hp_prime.1.pos _) + (show (0 : ℝ) < (p : ℝ) ^ (-n : ℤ) from zpow_pos (mod_cast hp_prime.1.pos) _) have := le_of_lt (hk (max n k) (le_max_right _ _)) rw [norm_le_pow_iff_mem_span_pow] at this dsimp [lift] From 85cf1f190af7b00a5990fd5644f9a28c188eb4a6 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Fri, 11 Oct 2024 15:01:38 +0000 Subject: [PATCH 034/425] chore(NumberTheory/Fermat): rename `fermat` to `Nat.fermatNumber` (#17618) (And also namespace and rename the lemmas about them.) As discussed in the reviewers chatroom. Co-authored-by: Anne Baanen --- Mathlib/NumberTheory/Fermat.lean | 53 ++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/Mathlib/NumberTheory/Fermat.lean b/Mathlib/NumberTheory/Fermat.lean index 44baf9e97d92a8..0fcd105b0a6009 100644 --- a/Mathlib/NumberTheory/Fermat.lean +++ b/Mathlib/NumberTheory/Fermat.lean @@ -12,59 +12,66 @@ import Mathlib.Tactic.Ring.RingNF /-! # Fermat numbers -The Fermat numbers are a sequence of natural numbers defined as `fermat n = 2^(2^n) + 1`, for all -natural numbers `n`. +The Fermat numbers are a sequence of natural numbers defined as `Nat.fermatNumber n = 2^(2^n) + 1`, +for all natural numbers `n`. ## Main theorems -- `coprime_fermat_fermat`: two distinct Fermat numbers are coprime. +- `Nat.coprime_fermatNumber_fermatNumber`: two distinct Fermat numbers are coprime. -/ -open Nat Finset +namespace Nat + +open Finset open scoped BigOperators /-- Fermat numbers: the `n`-th Fermat number is defined as `2^(2^n) + 1`. -/ -def fermat (n : ℕ) : ℕ := 2 ^ (2 ^ n) + 1 +def fermatNumber (n : ℕ) : ℕ := 2 ^ (2 ^ n) + 1 -@[simp] theorem fermat_zero : fermat 0 = 3 := rfl -@[simp] theorem fermat_one : fermat 1 = 5 := rfl -@[simp] theorem fermat_two : fermat 2 = 17 := rfl +@[simp] theorem fermatNumber_zero : fermatNumber 0 = 3 := rfl +@[simp] theorem fermatNumber_one : fermatNumber 1 = 5 := rfl +@[simp] theorem fermatNumber_two : fermatNumber 2 = 17 := rfl -theorem strictMono_fermat : StrictMono fermat := by +theorem strictMono_fermatNumber : StrictMono fermatNumber := by intro m n - simp only [fermat, add_lt_add_iff_right, pow_lt_pow_iff_right (one_lt_two : 1 < 2), imp_self] + simp only [fermatNumber, add_lt_add_iff_right, pow_lt_pow_iff_right (one_lt_two : 1 < 2), + imp_self] -theorem two_lt_fermat (n : ℕ) : 2 < fermat n := by +theorem two_lt_fermatNumber (n : ℕ) : 2 < fermatNumber n := by cases n · simp - · exact lt_of_succ_lt <| strictMono_fermat <| zero_lt_succ _ + · exact lt_of_succ_lt <| strictMono_fermatNumber <| zero_lt_succ _ -theorem odd_fermat (n : ℕ) : Odd (fermat n) := +theorem odd_fermatNumber (n : ℕ) : Odd (fermatNumber n) := (even_pow.mpr ⟨even_two, (pow_pos two_pos n).ne'⟩).add_one -theorem fermat_product (n : ℕ) : ∏ k in range n, fermat k = fermat n - 2 := by +theorem fermatNumber_product (n : ℕ) : ∏ k in range n, fermatNumber k = fermatNumber n - 2 := by induction' n with n hn · rfl - rw [prod_range_succ, hn, fermat, fermat, mul_comm, + rw [prod_range_succ, hn, fermatNumber, fermatNumber, mul_comm, (show 2 ^ 2 ^ n + 1 - 2 = 2 ^ 2 ^ n - 1 by omega), ← sq_sub_sq] ring_nf omega -theorem fermat_eq_prod_add_two (n : ℕ) : fermat n = (∏ k in range n, fermat k) + 2 := by - rw [fermat_product, Nat.sub_add_cancel] - exact le_of_lt <| two_lt_fermat _ +theorem fermatNumber_eq_prod_add_two (n : ℕ) : + fermatNumber n = (∏ k in range n, fermatNumber k) + 2 := by + rw [fermatNumber_product, Nat.sub_add_cancel] + exact le_of_lt <| two_lt_fermatNumber _ /-- **Goldbach's theorem** : no two distinct Fermat numbers share a common factor greater than one. From a letter to Euler, see page 37 in [juskevic2022]. -/ -theorem coprime_fermat_fermat {k n : ℕ} (h : k ≠ n) : Coprime (fermat n) (fermat k) := by +theorem coprime_fermatNumber_fermatNumber {k n : ℕ} (h : k ≠ n) : + Coprime (fermatNumber n) (fermatNumber k) := by wlog hkn : k < n · simpa only [coprime_comm] using this h.symm (by omega) - let m := (fermat n).gcd (fermat k) - have h_n : m ∣ fermat n := (fermat n).gcd_dvd_left (fermat k) + let m := (fermatNumber n).gcd (fermatNumber k) + have h_n : m ∣ fermatNumber n := (fermatNumber n).gcd_dvd_left (fermatNumber k) have h_m : m ∣ 2 := (Nat.dvd_add_right <| (gcd_dvd_right _ _).trans <| dvd_prod_of_mem _ - <| mem_range.mpr hkn).mp <| fermat_eq_prod_add_two _ ▸ h_n + <| mem_range.mpr hkn).mp <| fermatNumber_eq_prod_add_two _ ▸ h_n refine ((dvd_prime prime_two).mp h_m).elim id (fun h_two ↦ ?_) - exact ((odd_fermat _).not_two_dvd_nat (h_two ▸ h_n)).elim + exact ((odd_fermatNumber _).not_two_dvd_nat (h_two ▸ h_n)).elim + + end Nat From 69c6cf5e7728fc575c896b3fc5eb308e9483de1d Mon Sep 17 00:00:00 2001 From: FR Date: Fri, 11 Oct 2024 15:48:41 +0000 Subject: [PATCH 035/425] perf: use implicit parameters in `SMul` hierarchy (#17582) --- Mathlib/Algebra/Algebra/Defs.lean | 3 ++- Mathlib/Algebra/Module/Defs.lean | 3 ++- Mathlib/Algebra/Ring/Action/Basic.lean | 3 ++- Mathlib/Algebra/SMulWithZero.lean | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Algebra/Defs.lean b/Mathlib/Algebra/Algebra/Defs.lean index 0393439d7bb1ff..9683ddd51e1768 100644 --- a/Mathlib/Algebra/Algebra/Defs.lean +++ b/Mathlib/Algebra/Algebra/Defs.lean @@ -237,7 +237,8 @@ theorem algebra_ext {R : Type*} [CommSemiring R] {A : Type*} [Semiring A] (P Q : congr -- see Note [lower instance priority] -instance (priority := 200) toModule : Module R A where +instance (priority := 200) toModule {R A} {_ : CommSemiring R} {_ : Semiring A} [Algebra R A] : + Module R A where one_smul _ := by simp [smul_def'] mul_smul := by simp [smul_def', mul_assoc] smul_add := by simp [smul_def', mul_add] diff --git a/Mathlib/Algebra/Module/Defs.lean b/Mathlib/Algebra/Module/Defs.lean index a80f140f53d262..f810b34644f19d 100644 --- a/Mathlib/Algebra/Module/Defs.lean +++ b/Mathlib/Algebra/Module/Defs.lean @@ -67,7 +67,8 @@ variable [Semiring R] [AddCommMonoid M] [Module R M] (r s : R) (x y : M) -- see Note [lower instance priority] /-- A module over a semiring automatically inherits a `MulActionWithZero` structure. -/ -instance (priority := 100) Module.toMulActionWithZero : MulActionWithZero R M := +instance (priority := 100) Module.toMulActionWithZero + {R M} {_ : Semiring R} {_ : AddCommMonoid M} [Module R M] : MulActionWithZero R M := { (inferInstance : MulAction R M) with smul_zero := smul_zero zero_smul := Module.zero_smul } diff --git a/Mathlib/Algebra/Ring/Action/Basic.lean b/Mathlib/Algebra/Ring/Action/Basic.lean index d085e72efe2c3c..8466b8daf17c71 100644 --- a/Mathlib/Algebra/Ring/Action/Basic.lean +++ b/Mathlib/Algebra/Ring/Action/Basic.lean @@ -46,7 +46,8 @@ variable (M N : Type*) [Monoid M] [Monoid N] variable (R : Type v) [Semiring R] -- note we could not use `extends` since these typeclasses are made with `old_structure_cmd` -instance (priority := 100) MulSemiringAction.toMulDistribMulAction [h : MulSemiringAction M R] : +instance (priority := 100) MulSemiringAction.toMulDistribMulAction + (M R) {_ : Monoid M} {_ : Semiring R} [h : MulSemiringAction M R] : MulDistribMulAction M R := { h with } diff --git a/Mathlib/Algebra/SMulWithZero.lean b/Mathlib/Algebra/SMulWithZero.lean index ae84ec92e750df..b897e154bd18f1 100644 --- a/Mathlib/Algebra/SMulWithZero.lean +++ b/Mathlib/Algebra/SMulWithZero.lean @@ -126,7 +126,8 @@ class MulActionWithZero extends MulAction R M where zero_smul : ∀ m : M, (0 : R) • m = 0 -- see Note [lower instance priority] -instance (priority := 100) MulActionWithZero.toSMulWithZero [m : MulActionWithZero R M] : +instance (priority := 100) MulActionWithZero.toSMulWithZero + (R M) {_ : MonoidWithZero R} {_ : Zero M} [m : MulActionWithZero R M] : SMulWithZero R M := { m with } From ee31f16e67e4c4fb8adf5e421aedb27566798d78 Mon Sep 17 00:00:00 2001 From: Thomas Zhu Date: Fri, 11 Oct 2024 16:35:28 +0000 Subject: [PATCH 036/425] chore(Tactic/Polyrith): remove Python `requests` dependency in SageMath call (#17605) * Replaced the `requests` library needed by the Python script for SageMath API call, with native library `urllib.request`. * E.g. if the user has no `pip install` rights, such as evaluation on a shared server * Added explicit `User-Agent` header to SageMath requests: `LeanProver (https://leanprover-community.github.io/)`. Previously, it was the default used by Python requests package `python-requests/...`. Co-authored-by: Thomas Zhu <29544653+hanwenzhu@users.noreply.github.com> --- Mathlib/Tactic/Polyrith.lean | 1 - scripts/polyrith_sage.py | 21 ++++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Mathlib/Tactic/Polyrith.lean b/Mathlib/Tactic/Polyrith.lean index f20d12e722d991..1b3ef56ab08c83 100644 --- a/Mathlib/Tactic/Polyrith.lean +++ b/Mathlib/Tactic/Polyrith.lean @@ -392,7 +392,6 @@ Notes: Many thanks to the Sage team and organization for allowing this use. * This tactic assumes that the user has `python3` installed and available on the path. (Test by opening a terminal and executing `python3 --version`.) - It also assumes that the `requests` library is installed: `python3 -m pip install requests`. Examples: diff --git a/scripts/polyrith_sage.py b/scripts/polyrith_sage.py index 42f7f58ccc7fd1..9833e5923864e0 100644 --- a/scripts/polyrith_sage.py +++ b/scripts/polyrith_sage.py @@ -1,10 +1,13 @@ # This file is part of the `polyrith` tactic in `src/tactic/polyrith.lean`. # It interfaces between Lean and the Sage web interface. -import requests import json -import sys from os.path import join, dirname +import sys +from typing import Dict, Any +import urllib.error +import urllib.parse +import urllib.request # These functions are used to format the output of Sage for parsing in Lean. # They are stored here as a string since they are passed to Sage via the web API. @@ -59,15 +62,19 @@ def __init__(self, ename, evalue, message='Error in Sage communication'): self.message = message super().__init__(self.message) -def parse_response(resp: str) -> str: +def parse_response(resp: str) -> Dict[str, Any]: exp, data = resp.split(';', 1) return dict(power=int(exp), coeffs=json.loads(data)) -def evaluate_in_sage(query: str) -> str: - data = {'code': query} - headers = {'content-type': 'application/x-www-form-urlencoded'} - response = requests.post('https://sagecell.sagemath.org/service', data, headers=headers).json() +def evaluate_in_sage(query: str) -> Dict[str, Any]: + data = urllib.parse.urlencode({'code': query}).encode('utf-8') + headers = {'Content-Type': 'application/x-www-form-urlencoded', + 'User-Agent': 'LeanProver (https://leanprover-community.github.io/)'} + req = urllib.request.Request('https://sagecell.sagemath.org/service', data=data, headers=headers) + with urllib.request.urlopen(req) as response: + response_data = response.read().decode() + response = json.loads(response_data) if response['success']: return parse_response(response.get('stdout')) elif 'execute_reply' in response and 'ename' in response['execute_reply'] and 'evalue' in response['execute_reply']: From d3599bdfd345f7aa6879215c54c53e386b3a0e6d Mon Sep 17 00:00:00 2001 From: Kyle Miller Date: Fri, 11 Oct 2024 18:13:14 +0000 Subject: [PATCH 037/425] chore: more adaptations for lean4#5542 (#17655) In [lean4#5542](https://github.com/leanprover/lean4/pull/5542) we are deprecating `inductive ... :=`, `structure ... :=`, and `class ... :=` for their `... where` counterparts. Continuation of #17564. --- Mathlib/Analysis/NormedSpace/HahnBanach/SeparatingDual.lean | 2 +- Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean | 4 ++-- Mathlib/RingTheory/Algebraic.lean | 4 ++-- Mathlib/RingTheory/IntegralClosure/Algebra/Defs.lean | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Mathlib/Analysis/NormedSpace/HahnBanach/SeparatingDual.lean b/Mathlib/Analysis/NormedSpace/HahnBanach/SeparatingDual.lean index af94c78f743e06..b63ecf7d25efcd 100644 --- a/Mathlib/Analysis/NormedSpace/HahnBanach/SeparatingDual.lean +++ b/Mathlib/Analysis/NormedSpace/HahnBanach/SeparatingDual.lean @@ -26,7 +26,7 @@ equivalences acts transitively on the set of nonzero vectors. registers that continuous linear forms on `E` separate points of `E`. -/ @[mk_iff separatingDual_def] class SeparatingDual (R V : Type*) [Ring R] [AddCommGroup V] [TopologicalSpace V] - [TopologicalSpace R] [Module R V] : Prop := + [TopologicalSpace R] [Module R V] : Prop where /-- Any nonzero vector can be mapped by a continuous linear map to a nonzero scalar. -/ exists_ne_zero' : ∀ (x : V), x ≠ 0 → ∃ f : V →L[R] R, f x ≠ 0 diff --git a/Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean b/Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean index cd5425670e3161..5f9e2e892db191 100644 --- a/Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean +++ b/Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean @@ -235,7 +235,7 @@ variable {f : α × β → ℚ → ℝ} conditions are the same, but the limit properties of `IsRatCondKernelCDF` are replaced by limits of integrals. -/ structure IsRatCondKernelCDFAux (f : α × β → ℚ → ℝ) (κ : Kernel α (β × ℝ)) (ν : Kernel α β) : - Prop := + Prop where measurable : Measurable f mono' (a : α) {q r : ℚ} (_hqr : q ≤ r) : ∀ᵐ c ∂(ν a), f (a, c) q ≤ f (a, c) r nonneg' (a : α) (q : ℚ) : ∀ᵐ c ∂(ν a), 0 ≤ f (a, c) q @@ -425,7 +425,7 @@ respect to `ν` if it is measurable, tends to 0 at -∞ and to 1 at +∞ for all `fun b ↦ f (a, b) x` is `(ν a)`-integrable for all `a : α` and `x : ℝ` and for all measurable sets `s : Set β`, `∫ b in s, f (a, b) x ∂(ν a) = (κ a (s ×ˢ Iic x)).toReal`. -/ structure IsCondKernelCDF (f : α × β → StieltjesFunction) (κ : Kernel α (β × ℝ)) (ν : Kernel α β) : - Prop := + Prop where measurable (x : ℝ) : Measurable fun p ↦ f p x integrable (a : α) (x : ℝ) : Integrable (fun b ↦ f (a, b) x) (ν a) tendsto_atTop_one (p : α × β) : Tendsto (f p) atTop (𝓝 1) diff --git a/Mathlib/RingTheory/Algebraic.lean b/Mathlib/RingTheory/Algebraic.lean index 67c966cf31c265..20fba6c16cb72c 100644 --- a/Mathlib/RingTheory/Algebraic.lean +++ b/Mathlib/RingTheory/Algebraic.lean @@ -48,11 +48,11 @@ def Subalgebra.IsAlgebraic (S : Subalgebra R A) : Prop := variable (R A) /-- An algebra is algebraic if all its elements are algebraic. -/ -protected class Algebra.IsAlgebraic : Prop := +protected class Algebra.IsAlgebraic : Prop where isAlgebraic : ∀ x : A, IsAlgebraic R x /-- An algebra is transcendental if some element is transcendental. -/ -protected class Algebra.Transcendental : Prop := +protected class Algebra.Transcendental : Prop where transcendental : ∃ x : A, Transcendental R x variable {R A} diff --git a/Mathlib/RingTheory/IntegralClosure/Algebra/Defs.lean b/Mathlib/RingTheory/IntegralClosure/Algebra/Defs.lean index 8e9ef7deed80b9..58e184777c8f9e 100644 --- a/Mathlib/RingTheory/IntegralClosure/Algebra/Defs.lean +++ b/Mathlib/RingTheory/IntegralClosure/Algebra/Defs.lean @@ -29,7 +29,7 @@ variable [Algebra R A] (R) variable (A) /-- An algebra is integral if every element of the extension is integral over the base ring. -/ -protected class Algebra.IsIntegral : Prop := +protected class Algebra.IsIntegral : Prop where isIntegral : ∀ x : A, IsIntegral R x variable {R A} From ae22b2a2e15bd80aa1472ec0cc5f25c043db4f5f Mon Sep 17 00:00:00 2001 From: D-Thomine <100795491+D-Thomine@users.noreply.github.com> Date: Fri, 11 Oct 2024 18:32:47 +0000 Subject: [PATCH 038/425] feat(Dynamics.TopologicalEntropy.Semiconj): topological entropy and semiconjugacies (#17387) Fourth PR in a sequence to implement the notion of topological entropy for maps using Bowen-Dinaburg's formalism. This file deals with the entropy of two systems related by a semiconjugacy. - [x] Dynamical uniformities - [x] Topological entropy via covers - [x] Topological entropy via nets - [x] Behaviour under semiconjugacy - [ ] Behaviour for subsets and unions - [ ] Behaviour under products - [ ] Full shift There is only one new file, `Dynamics.TopologicalEntropy.Semiconj`, which is quite short (200 lines including the documentation), and no other modification. I must say I am quite pleased by `coverEntropy_image`. Paging @pitmonticone @sgouezel Co-authored-by: Pietro Monticone <38562595+pitmonticone@users.noreply.github.com> --- Mathlib.lean | 1 + .../Dynamics/TopologicalEntropy/Semiconj.lean | 231 ++++++++++++++++++ 2 files changed, 232 insertions(+) create mode 100644 Mathlib/Dynamics/TopologicalEntropy/Semiconj.lean diff --git a/Mathlib.lean b/Mathlib.lean index 005a1598915ad2..945eeef5e10985 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2674,6 +2674,7 @@ import Mathlib.Dynamics.PeriodicPts import Mathlib.Dynamics.TopologicalEntropy.CoverEntropy import Mathlib.Dynamics.TopologicalEntropy.DynamicalEntourage import Mathlib.Dynamics.TopologicalEntropy.NetEntropy +import Mathlib.Dynamics.TopologicalEntropy.Semiconj import Mathlib.FieldTheory.AbelRuffini import Mathlib.FieldTheory.AbsoluteGaloisGroup import Mathlib.FieldTheory.Adjoin diff --git a/Mathlib/Dynamics/TopologicalEntropy/Semiconj.lean b/Mathlib/Dynamics/TopologicalEntropy/Semiconj.lean new file mode 100644 index 00000000000000..66d3c3288216bb --- /dev/null +++ b/Mathlib/Dynamics/TopologicalEntropy/Semiconj.lean @@ -0,0 +1,231 @@ +/- +Copyright (c) 2024 Damien Thomine. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Damien Thomine, Pietro Monticone +-/ +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 `φ`: + + +``` +X ---S--> X +| | +φ φ +| | +v v +Y ---T--> Y +``` + +We relate the topological entropy of a subset `F ⊆ X` with the topological entropy +of its image `φ '' F ⊆ Y`. + +The best-known theorem is that, if all maps are uniformly continuous, then +`coverEntropy T (φ '' F) ≤ coverEntropy S F`. This is theorem +`coverEntropy_image_le_of_uniformContinuous` herein. We actually prove the much more general +statement that `coverEntropy T (φ '' F) = coverEntropy S F` if `X` is endowed with the pullback +by `φ` of the uniform structure of `Y`. + +This more general statement has another direct consequence: if `F` is `S`-invariant, then the +topological entropy of the restriction of `S` to `F` is exactly `coverEntropy S F`. This +corollary is essential: in most references, the entropy of an invariant subset (or subsystem) `F` is +defined as the entropy of the restriction to `F` of the system. We chose instead to give a direct +definition of the topological entropy of a subset, so as to avoid working with subtypes. Theorem +`coverEntropy_restrict` shows that this choice is coherent with the literature. + +## Implementation notes +We use only the definition of the topological entropy using covers; the simplest version of +`IsDynCoverOf.image` for nets fails. + +## Main results +- `coverEntropy_image_of_comap`/`coverEntropyInf_image_of_comap`: the entropy of `φ '' F` equals +the entropy of `F` if `X` is endowed with the pullback by `φ` of the uniform structure of `Y`. +- `coverEntropy_image_le_of_uniformContinuous`/`coverEntropyInf_image_le_of_uniformContinuous`: +the entropy of `φ '' F` is lower than the entropy of `F` if `φ` is uniformly continuous. +- `coverEntropy_restrict`: the entropy of the restriction of `S` to an invariant set `F` is +`coverEntropy S F`. + +## Tags +entropy, semiconjugacy +-/ + +namespace Dynamics + +open Function Prod Set Uniformity UniformSpace + +variable {X Y : Type*} {S : X → X} {T : Y → Y} {φ : X → Y} + +lemma IsDynCoverOf.image (h : Semiconj φ S T) {F : Set X} {V : Set (Y × Y)} {n : ℕ} {s : Set X} + (h' : IsDynCoverOf S F ((map φ φ) ⁻¹' V) n s) : + IsDynCoverOf T (φ '' F) V n (φ '' s) := by + simp only [IsDynCoverOf, image_subset_iff, preimage_iUnion₂, biUnion_image] + refine h'.trans (iUnion₂_mono fun i _ ↦ subset_of_eq ?_) + rw [← h.preimage_dynEntourage V n, ball_preimage] + +lemma IsDynCoverOf.preimage (h : Semiconj φ S T) {F : Set X} {V : Set (Y × Y)} + (V_symm : SymmetricRel V) {n : ℕ} {t : Finset Y} (h' : IsDynCoverOf T (φ '' F) V n t) : + ∃ s : Finset X, IsDynCoverOf S F ((map φ φ) ⁻¹' (V ○ V)) n s ∧ s.card ≤ t.card := by + classical + rcases isEmpty_or_nonempty X with _ | _ + · exact ⟨∅, eq_empty_of_isEmpty F ▸ ⟨isDynCoverOf_empty, Finset.card_empty ▸ zero_le t.card⟩⟩ + -- If `t` is a dynamical cover of `φ '' F`, then we want to choose one preimage by `φ` for each + -- element of `t`. This is complicated by the fact that `t` may not be a subset of `φ '' F`, + -- and may not even be in the range of `φ`. Hence, we first modify `t` to make it a subset + -- of `φ '' F`. This requires taking larger entourages. + rcases h'.nonempty_inter with ⟨s, s_cover, s_card, s_inter⟩ + choose! g gs_cover using fun (x : Y) (h : x ∈ s) ↦ nonempty_def.1 (s_inter x h) + choose! f f_section using fun (y : Y) (a : y ∈ φ '' F) ↦ a + refine ⟨s.image (f ∘ g), And.intro ?_ (Finset.card_image_le.trans s_card)⟩ + simp only [IsDynCoverOf, Finset.mem_coe, image_subset_iff, preimage_iUnion₂] at s_cover ⊢ + apply s_cover.trans + rw [← h.preimage_dynEntourage (V ○ V) n, Finset.set_biUnion_finset_image] + refine iUnion₂_mono fun i i_s ↦ ?_ + rw [comp_apply, ball_preimage, (f_section (g i) (gs_cover i i_s).2).2] + refine preimage_mono fun x x_i ↦ mem_ball_dynEntourage_comp T n V_symm x (g i) ⟨i, ?_⟩ + replace gs_cover := (gs_cover i i_s).1 + rw [mem_ball_symmetry (V_symm.dynEntourage T n)] at x_i gs_cover + exact ⟨x_i, gs_cover⟩ + +lemma le_coverMincard_image (h : Semiconj φ S T) (F : Set X) {V : Set (Y × Y)} + (V_symm : SymmetricRel V) (n : ℕ) : + coverMincard S F ((map φ φ) ⁻¹' (V ○ V)) n ≤ coverMincard T (φ '' F) V n := by + rcases eq_top_or_lt_top (coverMincard T (φ '' F) V n) with h' | h' + · exact h' ▸ le_top + rcases (coverMincard_finite_iff T (φ '' F) V n).1 h' with ⟨t, t_cover, t_card⟩ + rcases t_cover.preimage h V_symm with ⟨s, s_cover, s_card⟩ + rw [← t_card] + exact s_cover.coverMincard_le_card.trans (WithTop.coe_le_coe.2 s_card) + +lemma coverMincard_image_le (h : Semiconj φ S T) (F : Set X) (V : Set (Y × Y)) (n : ℕ) : + coverMincard T (φ '' F) V n ≤ coverMincard S F ((map φ φ) ⁻¹' V) n := by + classical + rcases eq_top_or_lt_top (coverMincard S F ((map φ φ) ⁻¹' V) n) with h' | h' + · exact h' ▸ le_top + rcases (coverMincard_finite_iff S F ((map φ φ) ⁻¹' V) n).1 h' with ⟨s, s_cover, s_card⟩ + rw [← s_card] + have := s_cover.image h + rw [← s.coe_image] at this + exact this.coverMincard_le_card.trans (WithTop.coe_le_coe.2 s.card_image_le) + +open ENNReal EReal Filter + +lemma le_coverEntropyEntourage_image (h : Semiconj φ S T) (F : Set X) {V : Set (Y × Y)} + (V_symm : SymmetricRel V) : + coverEntropyEntourage S F ((map φ φ) ⁻¹' (V ○ V)) ≤ coverEntropyEntourage T (φ '' F) V := + limsup_le_limsup (Eventually.of_forall fun n ↦ (monotone_div_right_of_nonneg (Nat.cast_nonneg' n) + (log_monotone (ENat.toENNReal_mono (le_coverMincard_image h F V_symm n))))) + +lemma le_coverEntropyInfEntourage_image (h : Semiconj φ S T) (F : Set X) {V : Set (Y × Y)} + (V_symm : SymmetricRel V) : + coverEntropyInfEntourage S F ((map φ φ) ⁻¹' (V ○ V)) ≤ coverEntropyInfEntourage T (φ '' F) V := + liminf_le_liminf (Eventually.of_forall fun n ↦ (monotone_div_right_of_nonneg (Nat.cast_nonneg' n) + (log_monotone (ENat.toENNReal_mono (le_coverMincard_image h F V_symm n))))) + +lemma coverEntropyEntourage_image_le (h : Semiconj φ S T) (F : Set X) (V : Set (Y × Y)) : + coverEntropyEntourage T (φ '' F) V ≤ coverEntropyEntourage S F ((map φ φ) ⁻¹' V) := + limsup_le_limsup (Eventually.of_forall fun n ↦ (monotone_div_right_of_nonneg (Nat.cast_nonneg' n) + (log_monotone (ENat.toENNReal_mono (coverMincard_image_le h F V n))))) + +lemma coverEntropyInfEntourage_image_le (h : Semiconj φ S T) (F : Set X) (V : Set (Y × Y)) : + coverEntropyInfEntourage T (φ '' F) V ≤ coverEntropyInfEntourage S F ((map φ φ) ⁻¹' V) := + liminf_le_liminf (Eventually.of_forall fun n ↦ (monotone_div_right_of_nonneg (Nat.cast_nonneg' n) + (log_monotone (ENat.toENNReal_mono (coverMincard_image_le h F V n))))) + +/-- The entropy of `φ '' F` equals the entropy of `F` if `X` is endowed with the pullback by `φ` + of the uniform structure of `Y`.-/ +theorem coverEntropy_image_of_comap (u : UniformSpace Y) {S : X → X} {T : Y → Y} {φ : X → Y} + (h : Semiconj φ S T) (F : Set X) : + coverEntropy T (φ '' F) = @coverEntropy X (comap φ u) S F := by + apply le_antisymm + · refine iSup₂_le fun V V_uni ↦ (coverEntropyEntourage_image_le h F V).trans ?_ + apply @coverEntropyEntourage_le_coverEntropy X (comap φ u) S F + rw [uniformity_comap φ, mem_comap] + exact ⟨V, V_uni, Subset.rfl⟩ + · refine iSup₂_le fun U U_uni ↦ ?_ + simp only [uniformity_comap φ, mem_comap] at U_uni + rcases U_uni with ⟨V, V_uni, V_sub⟩ + rcases comp_symm_mem_uniformity_sets V_uni with ⟨W, W_uni, W_symm, W_V⟩ + apply (coverEntropyEntourage_antitone S F ((preimage_mono W_V).trans V_sub)).trans + apply (le_coverEntropyEntourage_image h F W_symm).trans + exact coverEntropyEntourage_le_coverEntropy T (φ '' F) W_uni + +/-- The entropy of `φ '' F` equals the entropy of `F` if `X` is endowed with the pullback by `φ` + of the uniform structure of `Y`. This version uses a `liminf`.-/ +theorem coverEntropyInf_image_of_comap (u : UniformSpace Y) {S : X → X} {T : Y → Y} {φ : X → Y} + (h : Semiconj φ S T) (F : Set X) : + coverEntropyInf T (φ '' F) = @coverEntropyInf X (comap φ u) S F := by + apply le_antisymm + · refine iSup₂_le fun V V_uni ↦ (coverEntropyInfEntourage_image_le h F V).trans ?_ + apply @coverEntropyInfEntourage_le_coverEntropyInf X (comap φ u) S F + rw [uniformity_comap φ, mem_comap] + exact ⟨V, V_uni, Subset.rfl⟩ + · refine iSup₂_le fun U U_uni ↦ ?_ + simp only [uniformity_comap φ, mem_comap] at U_uni + rcases U_uni with ⟨V, V_uni, V_sub⟩ + rcases comp_symm_mem_uniformity_sets V_uni with ⟨W, W_uni, W_symm, W_V⟩ + apply (coverEntropyInfEntourage_antitone S F ((preimage_mono W_V).trans V_sub)).trans + apply (le_coverEntropyInfEntourage_image h F W_symm).trans + exact coverEntropyInfEntourage_le_coverEntropyInf T (φ '' F) W_uni + +open Subtype + +lemma coverEntropy_restrict_subset [UniformSpace X] {T : X → X} {F G : Set X} (hF : F ⊆ G) + (hG : MapsTo T G G) : + coverEntropy (hG.restrict T G G) (val ⁻¹' F) = coverEntropy T F := by + rw [← coverEntropy_image_of_comap _ hG.val_restrict_apply (val ⁻¹' F), image_preimage_coe G F, + inter_eq_right.2 hF] + +lemma coverEntropyInf_restrict_subset [UniformSpace X] {T : X → X} {F G : Set X} (hF : F ⊆ G) + (hG : MapsTo T G G) : + coverEntropyInf (hG.restrict T G G) (val ⁻¹' F) = coverEntropyInf T F := by + rw [← coverEntropyInf_image_of_comap _ hG.val_restrict_apply (val ⁻¹' F), image_preimage_coe G F, + inter_eq_right.2 hF] + +/-- The entropy of the restriction of `T` to an invariant set `F` is `coverEntropy S F`. This +theorem justifies our definition of `coverEntropy T F`.-/ +theorem coverEntropy_restrict [UniformSpace X] {T : X → X} {F : Set X} (h : MapsTo T F F) : + coverEntropy (h.restrict T F F) univ = coverEntropy T F := by + rw [← coverEntropy_restrict_subset Subset.rfl h, coe_preimage_self F] + +/-- The entropy of `φ '' F` is lower than entropy of `F` if `φ` is uniformly continuous.-/ +theorem coverEntropy_image_le_of_uniformContinuous [UniformSpace X] [UniformSpace Y] {S : X → X} + {T : Y → Y} {φ : X → Y} (h : Semiconj φ S T) (h' : UniformContinuous φ) (F : Set X) : + coverEntropy T (φ '' F) ≤ coverEntropy S F := by + rw [coverEntropy_image_of_comap _ h F] + exact coverEntropy_antitone S F (uniformContinuous_iff.1 h') + +/-- The entropy of `φ '' F` is lower than entropy of `F` if `φ` is uniformly continuous. This + version uses a `liminf`.-/ +theorem coverEntropyInf_image_le_of_uniformContinuous [UniformSpace X] [UniformSpace Y] {S : X → X} + {T : Y → Y} {φ : X → Y} (h : Semiconj φ S T) (h' : UniformContinuous φ) (F : Set X) : + coverEntropyInf T (φ '' F) ≤ coverEntropyInf S F := by + rw [coverEntropyInf_image_of_comap _ h F] + exact coverEntropyInf_antitone S F (uniformContinuous_iff.1 h') + +lemma coverEntropy_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) : + 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 + intro x + rw [G.restrict_apply, G.restrict_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] + +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 + intro a + rw [G.restrict_apply, G.restrict_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] + +end Dynamics From 2a15456076f273ef07c0d472a0f9085a8811a72c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Fri, 11 Oct 2024 19:55:05 +0000 Subject: [PATCH 039/425] chore(SetTheory/Ordinal/Exponential): `Ordinal.log` cleanup (#17635) We do the following: - Make the definition of `log` a non-dependent `if`. - Private `log_nonempty`. - Deprecate `log_of_not_one_lt_left` in favor of `log_of_left_le_one`. - Remove an unnecessary argument from `log_mod_opow_log_lt_log_self`. - Drive-by proof cleanup. --- .../SetTheory/Ordinal/CantorNormalForm.lean | 2 +- Mathlib/SetTheory/Ordinal/Exponential.lean | 72 ++++++++++--------- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/Mathlib/SetTheory/Ordinal/CantorNormalForm.lean b/Mathlib/SetTheory/Ordinal/CantorNormalForm.lean index 1013da5c56c463..563ef369b373b9 100644 --- a/Mathlib/SetTheory/Ordinal/CantorNormalForm.lean +++ b/Mathlib/SetTheory/Ordinal/CantorNormalForm.lean @@ -139,6 +139,6 @@ theorem CNF_sorted (b o : Ordinal) : ((CNF b o).map Prod.fst).Sorted (· > ·) : refine ⟨fun a H ↦ ?_, IH⟩ rw [mem_map] at H rcases H with ⟨⟨a, a'⟩, H, rfl⟩ - exact (CNF_fst_le_log H).trans_lt (log_mod_opow_log_lt_log_self hb ho hbo) + exact (CNF_fst_le_log H).trans_lt (log_mod_opow_log_lt_log_self hb hbo) end Ordinal diff --git a/Mathlib/SetTheory/Ordinal/Exponential.lean b/Mathlib/SetTheory/Ordinal/Exponential.lean index 25fc214a5ce321..b00223b311dabe 100644 --- a/Mathlib/SetTheory/Ordinal/Exponential.lean +++ b/Mathlib/SetTheory/Ordinal/Exponential.lean @@ -245,37 +245,37 @@ theorem opow_mul_add_lt_opow_succ {b u v w : Ordinal} (hvb : v < b) (hw : w < b /-- The ordinal logarithm is the solution `u` to the equation `x = b ^ u * v + w` where `v < b` and - `w < b ^ u`. -/ +`w < b ^ u`. -/ @[pp_nodot] def log (b : Ordinal) (x : Ordinal) : Ordinal := - if _h : 1 < b then pred (sInf { o | x < b ^ o }) else 0 + if 1 < b then pred (sInf { o | x < b ^ o }) else 0 /-- The set in the definition of `log` is nonempty. -/ -theorem log_nonempty {b x : Ordinal} (h : 1 < b) : { o : Ordinal | x < b ^ o }.Nonempty := +private theorem log_nonempty {b x : Ordinal} (h : 1 < b) : { o : Ordinal | x < b ^ o }.Nonempty := ⟨_, succ_le_iff.1 (right_le_opow _ h)⟩ -theorem log_def {b : Ordinal} (h : 1 < b) (x : Ordinal) : - log b x = pred (sInf { o | x < b ^ o }) := by simp only [log, dif_pos h] +theorem log_def {b : Ordinal} (h : 1 < b) (x : Ordinal) : log b x = pred (sInf { o | x < b ^ o }) := + if_pos h -theorem log_of_not_one_lt_left {b : Ordinal} (h : ¬1 < b) (x : Ordinal) : log b x = 0 := by - simp only [log, dif_neg h] +theorem log_of_left_le_one {b : Ordinal} (h : b ≤ 1) (x : Ordinal) : log b x = 0 := + if_neg h.not_lt -theorem log_of_left_le_one {b : Ordinal} (h : b ≤ 1) : ∀ x, log b x = 0 := - log_of_not_one_lt_left h.not_lt +@[deprecated log_of_left_le_one (since := "2024-10-10")] +theorem log_of_not_one_lt_left {b : Ordinal} (h : ¬1 < b) (x : Ordinal) : log b x = 0 := by + simp only [log, if_neg h] @[simp] theorem log_zero_left : ∀ b, log 0 b = 0 := log_of_left_le_one zero_le_one @[simp] -theorem log_zero_right (b : Ordinal) : log b 0 = 0 := - if b1 : 1 < b then by - rw [log_def b1, ← Ordinal.le_zero, pred_le] +theorem log_zero_right (b : Ordinal) : log b 0 = 0 := by + obtain hb | hb := lt_or_le 1 b + · rw [log_def hb, ← Ordinal.le_zero, pred_le, succ_zero] apply csInf_le' - dsimp - rw [succ_zero, opow_one] - exact zero_lt_one.trans b1 - else by simp only [log_of_not_one_lt_left b1] + rw [mem_setOf, opow_one] + exact bot_lt_of_lt hb + · rw [log_of_left_le_one hb] @[simp] theorem log_one_left : ∀ b, log 1 b = 0 := @@ -284,7 +284,7 @@ theorem log_one_left : ∀ b, log 1 b = 0 := theorem succ_log_def {b x : Ordinal} (hb : 1 < b) (hx : x ≠ 0) : succ (log b x) = sInf { o : Ordinal | x < b ^ o } := by let t := sInf { o : Ordinal | x < b ^ o } - have : x < (b^t) := csInf_mem (log_nonempty hb) + have : x < b ^ t := csInf_mem (log_nonempty hb) rcases zero_or_succ_or_limit t with (h | h | h) · refine ((one_le_iff_ne_zero.2 hx).not_lt ?_).elim simpa only [h, opow_zero] using this @@ -383,34 +383,37 @@ theorem log_eq_zero {b o : Ordinal} (hbo : o < b) : log b o = 0 := by · rwa [← Ordinal.le_zero, ← lt_succ_iff, succ_zero, ← lt_opow_iff_log_lt hb ho, opow_one] @[mono] -theorem log_mono_right (b : Ordinal) {x y : Ordinal} (xy : x ≤ y) : log b x ≤ log b y := - if hx : x = 0 then by simp only [hx, log_zero_right, Ordinal.zero_le] - else - if hb : 1 < b then - (opow_le_iff_le_log hb (lt_of_lt_of_le (Ordinal.pos_iff_ne_zero.2 hx) xy).ne').1 <| +theorem log_mono_right (b : Ordinal) {x y : Ordinal} (xy : x ≤ y) : log b x ≤ log b y := by + obtain rfl | hx := eq_or_ne x 0 + · simp_rw [log_zero_right, Ordinal.zero_le] + · obtain hb | hb := lt_or_le 1 b + · exact (opow_le_iff_le_log hb (hx.bot_lt.trans_le xy).ne').1 <| (opow_log_le_self _ hx).trans xy - else by simp only [log_of_not_one_lt_left hb, Ordinal.zero_le] + · rw [log_of_left_le_one hb, log_of_left_le_one hb] -theorem log_le_self (b x : Ordinal) : log b x ≤ x := - if hx : x = 0 then by simp only [hx, log_zero_right, Ordinal.zero_le] - else - if hb : 1 < b then (right_le_opow _ hb).trans (opow_log_le_self b hx) - else by simp only [log_of_not_one_lt_left hb, Ordinal.zero_le] +theorem log_le_self (b x : Ordinal) : log b x ≤ x := by + obtain rfl | hx := eq_or_ne x 0 + · rw [log_zero_right] + · obtain hb | hb := lt_or_le 1 b + · exact (right_le_opow _ hb).trans (opow_log_le_self b hx) + · simp_rw [log_of_left_le_one hb, Ordinal.zero_le] @[simp] -theorem log_one_right (b : Ordinal) : log b 1 = 0 := - if hb : 1 < b then log_eq_zero hb else log_of_not_one_lt_left hb 1 +theorem log_one_right (b : Ordinal) : log b 1 = 0 := by + obtain hb | hb := lt_or_le 1 b + · exact log_eq_zero hb + · exact log_of_left_le_one hb 1 theorem mod_opow_log_lt_self (b : Ordinal) {o : Ordinal} (ho : o ≠ 0) : o % (b ^ log b o) < o := by rcases eq_or_ne b 0 with (rfl | hb) · simpa using Ordinal.pos_iff_ne_zero.2 ho · exact (mod_lt _ <| opow_ne_zero _ hb).trans_le (opow_log_le_self _ ho) -theorem log_mod_opow_log_lt_log_self {b o : Ordinal} (hb : 1 < b) (ho : o ≠ 0) (hbo : b ≤ o) : +theorem log_mod_opow_log_lt_log_self {b o : Ordinal} (hb : 1 < b) (hbo : b ≤ o) : log b (o % (b ^ log b o)) < log b o := by rcases eq_or_ne (o % (b ^ log b o)) 0 with h | h · rw [h, log_zero_right] - apply log_pos hb ho hbo + exact log_pos hb (one_le_iff_ne_zero.1 (hb.le.trans hbo)) hbo · rw [← succ_le_iff, succ_log_def hb h] apply csInf_le' apply mod_lt @@ -462,11 +465,10 @@ theorem div_opow_log_lt {b : Ordinal} (o : Ordinal) (hb : 1 < b) : o / (b ^ log theorem add_log_le_log_mul {x y : Ordinal} (b : Ordinal) (hx : x ≠ 0) (hy : y ≠ 0) : log b x + log b y ≤ log b (x * y) := by - by_cases hb : 1 < b + obtain hb | hb := lt_or_le 1 b · rw [← opow_le_iff_le_log hb (mul_ne_zero hx hy), opow_add] exact mul_le_mul' (opow_log_le_self b hx) (opow_log_le_self b hy) - -- Porting note: `le_refl` is required. - simp only [log_of_not_one_lt_left hb, zero_add, le_refl] + · simpa only [log_of_left_le_one hb, zero_add] using le_rfl /-! ### Interaction with `Nat.cast` -/ From cd0f1a31c4ef1753507a527e8626d825c1c86900 Mon Sep 17 00:00:00 2001 From: Sebastian Ullrich Date: Fri, 11 Oct 2024 20:24:03 +0000 Subject: [PATCH 040/425] chore(scripts/bench): benchmark with `--no-cache` (#17572) There appears to be some incompatibility with executables downloaded from the cloud cache on NixOS, which broke the speedcenter. We used to benchmark all dependencies before the upgrade to 4.13.0-rc1, so let's go back to doing that. --- scripts/bench/temci-config.run.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/bench/temci-config.run.yml b/scripts/bench/temci-config.run.yml index dd8af5f9c062a3..9fdeceaa83cda7 100644 --- a/scripts/bench/temci-config.run.yml +++ b/scripts/bench/temci-config.run.yml @@ -6,7 +6,8 @@ properties: ['wall-clock', 'task-clock', 'instructions:u', 'branches', 'branch-misses'] rusage_properties: ['maxrss'] cmd: | - bash -c 'set -eo pipefail; lake clean && LEAN_PATH=$(lean --print-libdir) lake build -v --lean ./scripts/bench/fake-root/bin/lean | ./scripts/bench/accumulate_profile.py | grep -v took' + # use build cache for proofwidgets, but not for anything else + bash -c 'set -eo pipefail; lake clean 1>&2 && LEAN_PATH=$(lean --print-libdir) lake build proofwidgets 1>&2 && rm .lake/packages/batteries/.lake/build/bin/runLinter 1>&2 && lake build --no-cache -v --lean ./scripts/bench/fake-root/bin/lean | ./scripts/bench/accumulate_profile.py | grep -v took' parse_output: true runs: 1 - attributes: From 9ba2d95ba478bcccea37c7f1f84932d364d9b314 Mon Sep 17 00:00:00 2001 From: grunweg Date: Fri, 11 Oct 2024 20:34:39 +0000 Subject: [PATCH 041/425] chore: uniformise more copyright headers (#17660) The comment in `Data/Finset/Sym` is a porting artifact and can just be removed. Pre-requisite for rewriting the copyright header linter in Lean in #16574. --- Mathlib/Data/Finset/Sym.lean | 2 -- Mathlib/GroupTheory/GroupAction/Hom.lean | 1 - Mathlib/RepresentationTheory/GroupCohomology/LowDegree.lean | 1 - Mathlib/Tactic/CategoryTheory/Slice.lean | 1 - 4 files changed, 5 deletions(-) diff --git a/Mathlib/Data/Finset/Sym.lean b/Mathlib/Data/Finset/Sym.lean index c591056cea7ffb..f7fe2a928b7c4b 100644 --- a/Mathlib/Data/Finset/Sym.lean +++ b/Mathlib/Data/Finset/Sym.lean @@ -2,8 +2,6 @@ Copyright (c) 2021 Yaël Dillies. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Yaël Dillies - -[`data.finset.sym`@`98e83c3d541c77cdb7da20d79611a780ff8e7d90`..`02ba8949f486ebecf93fe7460f1ed0564b5e442c`](https://leanprover-community.github.io/mathlib-port-status/file/data/finset/sym?range=98e83c3d541c77cdb7da20d79611a780ff8e7d90..02ba8949f486ebecf93fe7460f1ed0564b5e442c) -/ import Mathlib.Data.Finset.Lattice import Mathlib.Data.Fintype.Vector diff --git a/Mathlib/GroupTheory/GroupAction/Hom.lean b/Mathlib/GroupTheory/GroupAction/Hom.lean index 2a9db62dd963ac..e2fc5be8f79d8d 100644 --- a/Mathlib/GroupTheory/GroupAction/Hom.lean +++ b/Mathlib/GroupTheory/GroupAction/Hom.lean @@ -2,7 +2,6 @@ Copyright (c) 2020 Kenny Lau. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Kenny Lau, Antoine Chambert-Loir - -/ import Mathlib.Algebra.Module.Defs diff --git a/Mathlib/RepresentationTheory/GroupCohomology/LowDegree.lean b/Mathlib/RepresentationTheory/GroupCohomology/LowDegree.lean index 7cd53f1275514d..f8101f22d3a293 100644 --- a/Mathlib/RepresentationTheory/GroupCohomology/LowDegree.lean +++ b/Mathlib/RepresentationTheory/GroupCohomology/LowDegree.lean @@ -2,7 +2,6 @@ Copyright (c) 2023 Amelia Livingston. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Amelia Livingston, Joël Riou - -/ import Mathlib.Algebra.Homology.ShortComplex.ModuleCat import Mathlib.RepresentationTheory.GroupCohomology.Basic diff --git a/Mathlib/Tactic/CategoryTheory/Slice.lean b/Mathlib/Tactic/CategoryTheory/Slice.lean index f3f88410158c65..d0c2105619b6e2 100644 --- a/Mathlib/Tactic/CategoryTheory/Slice.lean +++ b/Mathlib/Tactic/CategoryTheory/Slice.lean @@ -2,7 +2,6 @@ Copyright (c) 2018 Kim Morrison. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Kim Morrison - -/ import Mathlib.CategoryTheory.Category.Basic import Mathlib.Tactic.Conv From c35f067077ad7e27b7545e804de9ec7f477aa938 Mon Sep 17 00:00:00 2001 From: grunweg Date: Sat, 12 Oct 2024 00:58:04 +0000 Subject: [PATCH 042/425] chore(bors.toml): remove obsolete label (#17664) There does not exist an 'not-ready-to-merge' label; the awaiting-CI label has a similar role (and is in that list). --- bors.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bors.toml b/bors.toml index 6f0bc95fdaa7ad..a94f6e08beeac7 100644 --- a/bors.toml +++ b/bors.toml @@ -1,7 +1,7 @@ status = ["Build", "Lint style"] use_squash_merge = true timeout_sec = 28800 -block_labels = ["not-ready-to-merge", "WIP", "blocked-by-other-PR", "merge-conflict", "awaiting-CI"] +block_labels = ["WIP", "blocked-by-other-PR", "merge-conflict", "awaiting-CI"] delete_merged_branches = true update_base_for_deletes = true cut_body_after = "---" From 33614d2cb15037f82b0d88b34c805b0ed29def25 Mon Sep 17 00:00:00 2001 From: Andrew Yang Date: Sat, 12 Oct 2024 05:37:39 +0000 Subject: [PATCH 043/425] feat(AlgebraicGeometry): API for affine opens (#15259) --- Mathlib/AlgebraicGeometry/AffineScheme.lean | 123 ++++++++++++++---- .../GammaSpecAdjunction.lean | 4 + 2 files changed, 102 insertions(+), 25 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AffineScheme.lean b/Mathlib/AlgebraicGeometry/AffineScheme.lean index 121a41fc2382f8..fbc5e7b02e459d 100644 --- a/Mathlib/AlgebraicGeometry/AffineScheme.lean +++ b/Mathlib/AlgebraicGeometry/AffineScheme.lean @@ -121,6 +121,18 @@ def arrowIsoΓSpecOfIsAffine {A B : CommRingCat} (f : A ⟶ B) : Arrow.isoMk (Scheme.ΓSpecIso _).symm (Scheme.ΓSpecIso _).symm (Scheme.ΓSpecIso_inv_naturality f).symm +theorem Scheme.isoSpec_Spec (R : CommRingCat.{u}) : + (Spec R).isoSpec = Scheme.Spec.mapIso (Scheme.ΓSpecIso R).op := + Iso.ext (SpecMap_ΓSpecIso_hom R).symm + +@[simp] theorem Scheme.isoSpec_Spec_hom (R : CommRingCat.{u}) : + (Spec R).isoSpec.hom = Spec.map (Scheme.ΓSpecIso R).hom := + (SpecMap_ΓSpecIso_hom R).symm + +@[simp] theorem Scheme.isoSpec_Spec_inv (R : CommRingCat.{u}) : + (Spec R).isoSpec.inv = Spec.map (Scheme.ΓSpecIso R).inv := + congr($(isoSpec_Spec R).inv) + namespace AffineScheme /-- The `Spec` functor into the category of affine schemes. -/ @@ -259,23 +271,60 @@ namespace IsAffineOpen variable {X Y : Scheme.{u}} {U : X.Opens} (hU : IsAffineOpen U) (f : Γ(X, U)) +attribute [-simp] eqToHom_op in +/-- The isomorphism `U ≅ Spec Γ(X, U)` for an affine `U`. -/ +@[simps! (config := .lemmasOnly) hom inv] +def isoSpec : + ↑U ≅ Spec Γ(X, U) := + haveI : IsAffine U := hU + U.toScheme.isoSpec ≪≫ Scheme.Spec.mapIso + (X.presheaf.mapIso (eqToIso U.openEmbedding_obj_top).op).op + +open LocalRing in +lemma isoSpec_hom_val_base_apply (x : U) : + hU.isoSpec.hom.1.base x = (Spec.map (X.presheaf.germ _ x x.2)).val.base (closedPoint _) := by + dsimp [IsAffineOpen.isoSpec_hom, Scheme.isoSpec_hom, Scheme.toSpecΓ_val_base] + rw [← Scheme.comp_val_base_apply, ← Spec.map_comp, + (Iso.eq_comp_inv _).mpr (Scheme.Opens.germ_stalkIso_hom U (V := ⊤) x trivial), + X.presheaf.germ_res_assoc, Spec.map_comp, Scheme.comp_val_base_apply] + congr 1 + have := isLocalRingHom_of_isIso (U.stalkIso x).inv + exact LocalRing.comap_closedPoint (U.stalkIso x).inv + +lemma isoSpec_inv_app_top : + hU.isoSpec.inv.app ⊤ = U.topIso.hom ≫ (Scheme.ΓSpecIso Γ(X, U)).inv := by + simp only [Scheme.Opens.toScheme_presheaf_obj, isoSpec_inv, Scheme.isoSpec, asIso_inv, + Scheme.comp_coeBase, Opens.map_comp_obj, Opens.map_top, Scheme.comp_app, Scheme.inv_app_top, + Scheme.Opens.topIso_hom, Scheme.ΓSpecIso_inv_naturality, IsIso.inv_comp_eq] + rw [Scheme.toSpecΓ_app_top] + erw [Iso.hom_inv_id_assoc] + +lemma isoSpec_hom_app_top : + hU.isoSpec.hom.app ⊤ = (Scheme.ΓSpecIso Γ(X, U)).hom ≫ U.topIso.inv := by + have := congr(inv $hU.isoSpec_inv_app_top) + rw [IsIso.inv_comp, IsIso.Iso.inv_inv, IsIso.Iso.inv_hom] at this + have := (Scheme.Γ.map_inv hU.isoSpec.inv.op).trans this + rwa [← op_inv, IsIso.Iso.inv_inv] at this + /-- The open immersion `Spec Γ(X, U) ⟶ X` for an affine `U`. -/ def fromSpec : Spec Γ(X, U) ⟶ X := haveI : IsAffine U := hU - Spec.map (X.presheaf.map (eqToHom U.openEmbedding_obj_top.symm).op) ≫ - U.toScheme.isoSpec.inv ≫ U.ι + hU.isoSpec.inv ≫ U.ι instance isOpenImmersion_fromSpec : IsOpenImmersion hU.fromSpec := by delta fromSpec infer_instance +@[reassoc (attr := simp)] +lemma isoSpec_inv_ι : hU.isoSpec.inv ≫ U.ι = hU.fromSpec := rfl + @[simp] theorem range_fromSpec : Set.range hU.fromSpec.1.base = (U : Set X) := by - delta IsAffineOpen.fromSpec; dsimp - rw [Function.comp_assoc, Set.range_comp, Set.range_iff_surjective.mpr, Set.image_univ] + delta IsAffineOpen.fromSpec; dsimp [IsAffineOpen.isoSpec_inv] + rw [Set.range_comp, Set.range_iff_surjective.mpr, Set.image_univ] · exact Subtype.range_coe erw [← coe_comp, ← TopCat.epi_iff_surjective] -- now `erw` after #13170 infer_instance @@ -289,9 +338,37 @@ theorem map_fromSpec {V : X.Opens} (hV : IsAffineOpen V) (f : op U ⟶ op V) : have : IsAffine (X.restrictFunctor.obj U).left := hU haveI : IsAffine _ := hV conv_rhs => - rw [fromSpec, ← X.restrictFunctor_map_ofRestrict f.unop, ← Scheme.isoSpec_inv_naturality_assoc, + rw [fromSpec, ← X.restrictFunctor_map_ofRestrict f.unop, isoSpec_inv, Category.assoc, + ← Scheme.isoSpec_inv_naturality_assoc, ← Spec.map_comp_assoc, Scheme.restrictFunctor_map_app, ← Functor.map_comp] - rw [fromSpec, ← Spec.map_comp_assoc, ← Functor.map_comp] + rw [fromSpec, isoSpec_inv, Category.assoc, ← Spec.map_comp_assoc, ← Functor.map_comp] + rfl + +@[reassoc] +lemma Spec_map_appLE_fromSpec (f : X ⟶ Y) {V : X.Opens} {U : Y.Opens} + (hU : IsAffineOpen U) (hV : IsAffineOpen V) (i : V ≤ f ⁻¹ᵁ U) : + Spec.map (f.appLE U V i) ≫ hU.fromSpec = hV.fromSpec ≫ f := by + have : IsAffine U := hU + simp only [IsAffineOpen.fromSpec, Category.assoc, isoSpec_inv] + rw [← Scheme.restrictFunctor_map_ofRestrict (homOfLE i), Category.assoc, ← morphismRestrict_ι, + ← Category.assoc _ (f ∣_ U) U.ι, ← @Scheme.isoSpec_inv_naturality_assoc, + ← Spec.map_comp_assoc, ← Spec.map_comp_assoc, Scheme.comp_app, morphismRestrict_app, + Scheme.restrictFunctor_map_app, Scheme.Hom.app_eq_appLE, Scheme.Hom.appLE_map, + Scheme.Hom.appLE_map, Scheme.Hom.appLE_map, Scheme.Hom.map_appLE] + +lemma fromSpec_top [IsAffine X] : (isAffineOpen_top X).fromSpec = X.isoSpec.inv := by + rw [fromSpec, isoSpec_inv, Category.assoc, ← @Scheme.isoSpec_inv_naturality, Scheme.Opens.ι_app, + ← Spec.map_comp_assoc, ← X.presheaf.map_comp, ← op_comp, eqToHom_comp_homOfLE, + ← eqToHom_eq_homOfLE rfl, eqToHom_refl, op_id, X.presheaf.map_id, Spec.map_id, Category.id_comp] + +lemma fromSpec_app_of_le (V : X.Opens) (h : U ≤ V) : + hU.fromSpec.app V = X.presheaf.map (homOfLE h).op ≫ + (Scheme.ΓSpecIso Γ(X, U)).inv ≫ (Spec _).presheaf.map (homOfLE le_top).op := by + have : U.ι ⁻¹ᵁ V = ⊤ := eq_top_iff.mpr fun x _ ↦ h x.2 + rw [IsAffineOpen.fromSpec, Scheme.comp_app, Scheme.Opens.ι_app, Scheme.app_eq _ this, + IsAffineOpen.isoSpec_inv_app_top] + simp only [Scheme.Opens.toScheme_presheaf_map, Scheme.Opens.topIso_hom, + Category.assoc, ← X.presheaf.map_comp_assoc] rfl include hU in @@ -362,22 +439,20 @@ theorem fromSpec_preimage_self : rw [Opens.map_coe, Opens.coe_top, ← hU.range_fromSpec, ← Set.image_univ] exact Set.preimage_image_eq _ PresheafedSpace.IsOpenImmersion.base_open.inj -theorem SpecΓIdentity_hom_app_fromSpec : +theorem ΓSpecIso_hom_fromSpec_app : (Scheme.ΓSpecIso Γ(X, U)).hom ≫ hU.fromSpec.app U = (Spec Γ(X, U)).presheaf.map (eqToHom hU.fromSpec_preimage_self).op := by - simp only [fromSpec, Scheme.isoSpec, asIso_inv, Scheme.comp_coeBase, Opens.map_comp_obj, - ΓSpecIso_obj_hom, Scheme.Opens.topIso_inv, Opens.map_top, Scheme.Opens.topIso_hom, - Scheme.comp_app, Scheme.Opens.ι_app_self, unop_op, Category.assoc, ← Functor.map_comp_assoc, ← - op_comp, eqToHom_trans, Scheme.Opens.eq_presheaf_map_eqToHom, Scheme.Hom.naturality_assoc, - Scheme.inv_app_top, IsIso.hom_inv_id_assoc] - simp only [eqToHom_op, eqToHom_map, Spec.map_eqToHom, eqToHom_unop, - Scheme.Spec_map_presheaf_map_eqToHom, eqToHom_trans] + simp only [fromSpec, Scheme.comp_coeBase, Opens.map_comp_obj, Scheme.comp_app, + Scheme.Opens.ι_app_self, eqToHom_op, Scheme.app_eq _ U.ι_preimage_self, + Scheme.Opens.toScheme_presheaf_map, eqToHom_unop, eqToHom_map U.ι.opensFunctor, Opens.map_top, + isoSpec_inv_app_top, Scheme.Opens.topIso_hom, Category.assoc, ← Functor.map_comp_assoc, + eqToHom_trans, eqToHom_refl, X.presheaf.map_id, Category.id_comp, Iso.hom_inv_id_assoc] @[elementwise] theorem fromSpec_app_self : hU.fromSpec.app U = (Scheme.ΓSpecIso Γ(X, U)).inv ≫ (Spec Γ(X, U)).presheaf.map (eqToHom hU.fromSpec_preimage_self).op := by - rw [← hU.SpecΓIdentity_hom_app_fromSpec, Iso.inv_hom_id_assoc] + rw [← hU.ΓSpecIso_hom_fromSpec_app, Iso.inv_hom_id_assoc] theorem fromSpec_preimage_basicOpen' : hU.fromSpec ⁻¹ᵁ X.basicOpen f = (Spec Γ(X, U)).basicOpen ((Scheme.ΓSpecIso Γ(X, U)).inv f) := by @@ -532,20 +607,18 @@ theorem _root_.AlgebraicGeometry.exists_basicOpen_le_affine_inter /-- The prime ideal of `𝒪ₓ(U)` corresponding to a point `x : U`. -/ noncomputable def primeIdealOf (x : U) : PrimeSpectrum Γ(X, U) := - ((@Scheme.isoSpec U hU).hom ≫ - Spec.map (X.presheaf.map (eqToHom U.openEmbedding_obj_top).op)).1.base x + hU.isoSpec.hom.1.base x theorem fromSpec_primeIdealOf (x : U) : hU.fromSpec.val.base (hU.primeIdealOf x) = x.1 := by dsimp only [IsAffineOpen.fromSpec, Subtype.coe_mk, IsAffineOpen.primeIdealOf] - -- Porting note: in the porting note of `Scheme.comp_val_base`, it says that `elementwise` is - -- unnecessary, indeed, the linter did not like it, so I just use `elementwise_of%` instead of - -- adding the corresponding lemma in `Scheme.lean` file - erw [← elementwise_of% Scheme.comp_val_base] -- now `erw` after #13170 - simp only [Scheme.Opens.toScheme_presheaf_obj, Category.assoc, ← Spec.map_comp_assoc, - ← Functor.map_comp, ← op_comp, eqToHom_trans, eqToHom_refl, op_id, - CategoryTheory.Functor.map_id, Spec.map_id, Category.id_comp, Iso.hom_inv_id_assoc] - rfl -- `rfl` was not needed before #13170 + rw [← Scheme.comp_val_base_apply, Iso.hom_inv_id_assoc] + rfl + +open LocalRing in +theorem primeIdealOf_eq_map_closedPoint (x : U) : + hU.primeIdealOf x = (Spec.map (X.presheaf.germ _ x x.2)).val.base (closedPoint _) := + hU.isoSpec_hom_val_base_apply _ theorem isLocalization_stalk' (y : PrimeSpectrum Γ(X, U)) (hy : hU.fromSpec.1.base y ∈ U) : @IsLocalization.AtPrime diff --git a/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean b/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean index c046a874c7a029..7bd7ef196c89a8 100644 --- a/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean +++ b/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean @@ -413,6 +413,10 @@ instance isIso_adjunction_counit : IsIso ΓSpec.adjunction.counit := by end ΓSpec +theorem Scheme.toSpecΓ_val_base (X : Scheme.{u}) (x) : + (Scheme.toSpecΓ X).1.base x = + (Spec.map (X.presheaf.germ ⊤ x trivial)).1.base (LocalRing.closedPoint _) := rfl + @[reassoc (attr := simp)] theorem Scheme.toSpecΓ_naturality {X Y : Scheme.{u}} (f : X ⟶ Y) : f ≫ Y.toSpecΓ = X.toSpecΓ ≫ Spec.map (f.app ⊤) := From db094871afb9880e24c7558524a392fc998b96da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Degenne?= Date: Sat, 12 Oct 2024 06:29:42 +0000 Subject: [PATCH 044/425] feat(Probability/Kernel): the kernel Radon-Nikodym derivative and singular part are unique (#17591) --- Mathlib/Probability/Kernel/RadonNikodym.lean | 50 ++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/Mathlib/Probability/Kernel/RadonNikodym.lean b/Mathlib/Probability/Kernel/RadonNikodym.lean index d99f2e27d910e6..9b011fdfed3240 100644 --- a/Mathlib/Probability/Kernel/RadonNikodym.lean +++ b/Mathlib/Probability/Kernel/RadonNikodym.lean @@ -402,6 +402,8 @@ lemma rnDeriv_add_singularPart (κ η : Kernel α γ) [IsFiniteKernel κ] [IsFin zero_add, withDensity_rnDeriv_of_subset_compl_mutuallySingularSetSlice (hs.diff hm) (diff_subset_iff.mpr (by simp)), add_comm] +section EqZeroIff + lemma singularPart_eq_zero_iff_apply_eq_zero (κ η : Kernel α γ) [IsFiniteKernel κ] [IsFiniteKernel η] (a : α) : singularPart κ η a = 0 ↔ singularPart κ η a (mutuallySingularSetSlice κ η a) = 0 := by @@ -466,6 +468,8 @@ lemma withDensity_rnDeriv_eq_zero_iff_measure_eq_zero (κ η : Kernel α γ) rw [← h_eq_add] exact withDensity_rnDeriv_eq_zero_iff_apply_eq_zero κ η a +end EqZeroIff + /-- The set of points `a : α` such that `κ a ≪ η a` is measurable. -/ @[measurability] lemma measurableSet_absolutelyContinuous (κ η : Kernel α γ) [IsFiniteKernel κ] [IsFiniteKernel η] : @@ -484,4 +488,50 @@ lemma measurableSet_mutuallySingular (κ η : Kernel α γ) [IsFiniteKernel κ] exact measurable_kernel_prod_mk_left (measurableSet_mutuallySingularSet κ η).compl (measurableSet_singleton 0) +@[simp] +lemma singularPart_self (κ : Kernel α γ) [IsFiniteKernel κ] : κ.singularPart κ = 0 := by + ext : 1; rw [zero_apply, singularPart_eq_zero_iff_absolutelyContinuous] + +section Unique + +variable {ξ : Kernel α γ} {f : α → γ → ℝ≥0∞} [IsFiniteKernel η] + +omit hαγ in +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] + exact (κ a).eq_rnDeriv₀ (hf.comp measurable_prod_mk_left).aemeasurable hξ this + +omit hαγ in +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] + exact (κ a).eq_singularPart (hf.comp measurable_prod_mk_left) hξ this + +variable [IsFiniteKernel κ] {a : α} + +lemma rnDeriv_eq_rnDeriv_measure : rnDeriv κ η a =ᵐ[η a] ∂(κ a)/∂(η a) := + eq_rnDeriv_measure (rnDeriv_add_singularPart κ η).symm (measurable_rnDeriv κ η) a + (mutuallySingular_singularPart κ η a) + +lemma singularPart_eq_singularPart_measure : singularPart κ η a = (κ a).singularPart (η a) := + eq_singularPart_measure (rnDeriv_add_singularPart κ η).symm (measurable_rnDeriv κ η) a + (mutuallySingular_singularPart κ η a) + +lemma eq_rnDeriv (h : κ = η.withDensity f + ξ) + (hf : Measurable (Function.uncurry f)) (a : α) (hξ : ξ a ⟂ₘ η a) : + f a =ᵐ[η a] rnDeriv κ η a := + (eq_rnDeriv_measure h hf a hξ).trans rnDeriv_eq_rnDeriv_measure.symm + +lemma eq_singularPart (h : κ = η.withDensity f + ξ) + (hf : Measurable (Function.uncurry f)) (a : α) (hξ : ξ a ⟂ₘ η a) : + ξ a = singularPart κ η a := + (eq_singularPart_measure h hf a hξ).trans singularPart_eq_singularPart_measure.symm + +end Unique + end ProbabilityTheory.Kernel From 3f143f7d601c67106b3b9f38eba31a9f2f1b3c6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Degenne?= Date: Sat, 12 Oct 2024 06:38:53 +0000 Subject: [PATCH 045/425] feat(Probability/Kernel): simple lemmas about composition of kernels (#17596) --- Mathlib/Probability/Kernel/Composition.lean | 39 ++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/Mathlib/Probability/Kernel/Composition.lean b/Mathlib/Probability/Kernel/Composition.lean index 513325918f94f9..aa3839f4407e93 100644 --- a/Mathlib/Probability/Kernel/Composition.lean +++ b/Mathlib/Probability/Kernel/Composition.lean @@ -1029,7 +1029,7 @@ section Comp /-! ### Composition of two kernels -/ -variable {γ : Type*} {mγ : MeasurableSpace γ} {f : β → γ} {g : γ → α} +variable {γ δ : Type*} {mγ : MeasurableSpace γ} {mδ : MeasurableSpace δ} {f : β → γ} {g : γ → α} /-- Composition of two kernels. -/ noncomputable def comp (η : Kernel β γ) (κ : Kernel α β) : Kernel α γ where @@ -1046,6 +1046,10 @@ theorem comp_apply' (η : Kernel β γ) (κ : Kernel α β) (a : α) {s : Set γ (η ∘ₖ κ) a s = ∫⁻ b, η b s ∂κ a := by rw [comp_apply, Measure.bind_apply hs (Kernel.measurable _)] +@[simp] lemma zero_comp (κ : Kernel α β) : (0 : Kernel β γ) ∘ₖ κ = 0 := by ext; simp [comp_apply] + +@[simp] lemma comp_zero (κ : Kernel β γ) : κ ∘ₖ (0 : Kernel α β) = 0 := by ext; simp [comp_apply] + theorem comp_eq_snd_compProd (η : Kernel β γ) [IsSFiniteKernel η] (κ : Kernel α β) [IsSFiniteKernel κ] : η ∘ₖ κ = snd (κ ⊗ₖ prodMkLeft α η) := by ext a s hs @@ -1085,6 +1089,10 @@ theorem comp_deterministic_eq_comap (κ : Kernel α β) (hg : Measurable g) : simp_rw [comap_apply' _ _ _ s, comp_apply' _ _ _ hs, deterministic_apply hg a, lintegral_dirac' _ (Kernel.measurable_coe κ hs)] +lemma deterministic_comp_deterministic (hf : Measurable f) (hg : Measurable g) : + (deterministic g hg) ∘ₖ (deterministic f hf) = deterministic (g ∘ f) (hg.comp hf) := by + ext; simp [comp_deterministic_eq_comap, comap_apply, deterministic_apply] + lemma const_comp (μ : Measure γ) (κ : Kernel α β) : const β μ ∘ₖ κ = fun a ↦ (κ a) Set.univ • μ := by ext _ _ hs @@ -1096,6 +1104,29 @@ lemma const_comp' (μ : Measure γ) (κ : Kernel α β) [IsMarkovKernel κ] : const β μ ∘ₖ κ = const α μ := by ext; simp_rw [const_comp, measure_univ, one_smul, const_apply] +lemma map_comp (κ : Kernel α β) (η : Kernel β γ) (f : γ → δ) : + (η ∘ₖ κ).map f = (η.map f) ∘ₖ κ := by + by_cases hf : Measurable f + · ext a s hs + rw [map_apply' _ hf _ hs, comp_apply', comp_apply' _ _ _ hs] + · simp_rw [map_apply' _ hf _ hs] + · exact hf hs + · simp [map_of_not_measurable _ hf] + +lemma fst_comp (κ : Kernel α β) (η : Kernel β (γ × δ)) : (η ∘ₖ κ).fst = η.fst ∘ₖ κ := by + simp [fst_eq, map_comp κ η _] + +lemma snd_comp (κ : Kernel α β) (η : Kernel β (γ × δ)) : (η ∘ₖ κ).snd = η.snd ∘ₖ κ := by + simp_rw [snd_eq, map_comp κ η _] + +@[simp] lemma snd_compProd_prodMkLeft + (κ : Kernel α β) (η : Kernel β γ) [IsSFiniteKernel κ] [IsSFiniteKernel η] : + snd (κ ⊗ₖ prodMkLeft α η) = η ∘ₖ κ := by + ext a s hs + rw [snd_apply' _ _ hs, compProd_apply, comp_apply' _ _ _ hs] + · rfl + · exact measurable_snd hs + end Comp section Prod @@ -1158,6 +1189,12 @@ instance IsSFiniteKernel.prod (κ : Kernel α β) (η : Kernel α γ) : snd (κ ×ₖ η) = η := by ext x; simp [snd_apply, prod_apply] +lemma deterministic_prod_deterministic {f : α → β} {g : α → γ} + (hf : Measurable f) (hg : Measurable g) : + deterministic f hf ×ₖ deterministic g hg + = deterministic (fun a ↦ (f a, g a)) (hf.prod_mk hg) := by + ext; simp_rw [prod_apply, deterministic_apply, Measure.dirac_prod_dirac] + end Prod end Kernel end ProbabilityTheory From 21dee83ef7f19a925e480b41b9b2af6eeac0fea8 Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Sat, 12 Oct 2024 06:38:54 +0000 Subject: [PATCH 046/425] =?UTF-8?q?chore(*):=20assume=20`[Nonempty=20?= =?UTF-8?q?=CE=B1]=20[Subsingleton=20=CE=B1]`=20instead=20of=20`Unique=20?= =?UTF-8?q?=CE=B1`=20(#17670)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Mathlib/Analysis/Convex/Basic.lean | 3 ++- Mathlib/Logic/Unique.lean | 6 +++++- Mathlib/SetTheory/Cardinal/Basic.lean | 4 ++-- Mathlib/SetTheory/Cardinal/Finite.lean | 8 ++++---- Mathlib/SetTheory/Ordinal/Basic.lean | 11 +++++------ Mathlib/Topology/Homotopy/Contractible.lean | 6 +++--- Mathlib/Topology/TietzeExtension.lean | 6 +++--- 7 files changed, 24 insertions(+), 20 deletions(-) diff --git a/Mathlib/Analysis/Convex/Basic.lean b/Mathlib/Analysis/Convex/Basic.lean index a06894150ee983..3c3fc373308f38 100644 --- a/Mathlib/Analysis/Convex/Basic.lean +++ b/Mathlib/Analysis/Convex/Basic.lean @@ -605,7 +605,8 @@ theorem convex_stdSimplex : Convex 𝕜 (stdSimplex 𝕜 ι) := by lemma stdSimplex_of_isEmpty_index [IsEmpty ι] [Nontrivial 𝕜] : stdSimplex 𝕜 ι = ∅ := eq_empty_of_forall_not_mem <| by rintro f ⟨-, hf⟩; simp at hf -lemma stdSimplex_unique [Unique ι] : stdSimplex 𝕜 ι = {fun _ ↦ 1} := by +lemma stdSimplex_unique [Nonempty ι] [Subsingleton ι] : stdSimplex 𝕜 ι = {fun _ ↦ 1} := by + cases nonempty_unique ι refine eq_singleton_iff_unique_mem.2 ⟨⟨fun _ ↦ zero_le_one, Fintype.sum_unique _⟩, ?_⟩ rintro f ⟨-, hf⟩ rw [Fintype.sum_unique] at hf diff --git a/Mathlib/Logic/Unique.lean b/Mathlib/Logic/Unique.lean index 678d68e2ff016f..5aad9af23a0149 100644 --- a/Mathlib/Logic/Unique.lean +++ b/Mathlib/Logic/Unique.lean @@ -141,10 +141,14 @@ abbrev mk' (α : Sort u) [h₁ : Inhabited α] [Subsingleton α] : Unique α := end Unique +theorem nonempty_unique (α : Sort u) [Subsingleton α] [Nonempty α] : Nonempty (Unique α) := by + inhabit α + exact ⟨Unique.mk' α⟩ + theorem unique_iff_subsingleton_and_nonempty (α : Sort u) : Nonempty (Unique α) ↔ Subsingleton α ∧ Nonempty α := ⟨fun ⟨u⟩ ↦ by constructor <;> exact inferInstance, - fun ⟨hs, hn⟩ ↦ ⟨by inhabit α; exact Unique.mk' α⟩⟩ + fun ⟨hs, hn⟩ ↦ nonempty_unique α⟩ variable {α : Sort*} diff --git a/Mathlib/SetTheory/Cardinal/Basic.lean b/Mathlib/SetTheory/Cardinal/Basic.lean index 0000f54003d7c0..2b1f5b5347d2fd 100644 --- a/Mathlib/SetTheory/Cardinal/Basic.lean +++ b/Mathlib/SetTheory/Cardinal/Basic.lean @@ -432,8 +432,8 @@ instance : One Cardinal.{u} := instance : Nontrivial Cardinal.{u} := ⟨⟨1, 0, mk_ne_zero _⟩⟩ -theorem mk_eq_one (α : Type u) [Unique α] : #α = 1 := - (Equiv.equivOfUnique α (ULift (Fin 1))).cardinal_eq +theorem mk_eq_one (α : Type u) [Subsingleton α] [Nonempty α] : #α = 1 := + let ⟨_⟩ := nonempty_unique α; (Equiv.equivOfUnique α (ULift (Fin 1))).cardinal_eq theorem le_one_iff_subsingleton {α : Type u} : #α ≤ 1 ↔ Subsingleton α := ⟨fun ⟨f⟩ => ⟨fun _ _ => f.injective (Subsingleton.elim _ _)⟩, fun ⟨h⟩ => diff --git a/Mathlib/SetTheory/Cardinal/Finite.lean b/Mathlib/SetTheory/Cardinal/Finite.lean index 08b850cedaa5a2..54b12ce1da78fd 100644 --- a/Mathlib/SetTheory/Cardinal/Finite.lean +++ b/Mathlib/SetTheory/Cardinal/Finite.lean @@ -177,13 +177,13 @@ theorem card_of_subsingleton (a : α) [Subsingleton α] : Nat.card α = 1 := by letI := Fintype.ofSubsingleton a rw [card_eq_fintype_card, Fintype.card_ofSubsingleton a] --- @[simp] -- Porting note (#10618): simp can prove this -theorem card_unique [Unique α] : Nat.card α = 1 := - card_of_subsingleton default - theorem card_eq_one_iff_unique : Nat.card α = 1 ↔ Subsingleton α ∧ Nonempty α := Cardinal.toNat_eq_one_iff_unique +@[simp] +theorem card_unique [Nonempty α] [Subsingleton α] : Nat.card α = 1 := by + simp [card_eq_one_iff_unique, *] + theorem card_eq_one_iff_exists : Nat.card α = 1 ↔ ∃ x : α, ∀ y : α, y = x := by rw [card_eq_one_iff_unique] exact ⟨fun ⟨s, ⟨a⟩⟩ ↦ ⟨a, fun x ↦ s.elim x a⟩, fun ⟨x, h⟩ ↦ ⟨subsingleton_of_forall_eq x h, ⟨x⟩⟩⟩ diff --git a/Mathlib/SetTheory/Ordinal/Basic.lean b/Mathlib/SetTheory/Ordinal/Basic.lean index d2993ff4d2f73f..633dfc776c196d 100644 --- a/Mathlib/SetTheory/Ordinal/Basic.lean +++ b/Mathlib/SetTheory/Ordinal/Basic.lean @@ -190,15 +190,14 @@ theorem type_pEmpty : type (@EmptyRelation PEmpty) = 0 := theorem type_empty : type (@EmptyRelation Empty) = 0 := type_eq_zero_of_empty _ -theorem type_eq_one_of_unique (r) [IsWellOrder α r] [Unique α] : type r = 1 := - (RelIso.relIsoOfUniqueOfIrrefl r _).ordinal_type_eq +theorem type_eq_one_of_unique (r) [IsWellOrder α r] [Nonempty α] [Subsingleton α] : type r = 1 := by + cases nonempty_unique α + exact (RelIso.relIsoOfUniqueOfIrrefl r _).ordinal_type_eq @[simp] theorem type_eq_one_iff_unique [IsWellOrder α r] : type r = 1 ↔ Nonempty (Unique α) := - ⟨fun h => - let ⟨s⟩ := type_eq.1 h - ⟨s.toEquiv.unique⟩, - fun ⟨h⟩ => @type_eq_one_of_unique α r _ h⟩ + ⟨fun h ↦ let ⟨s⟩ := type_eq.1 h; ⟨s.toEquiv.unique⟩, + fun ⟨_⟩ ↦ type_eq_one_of_unique r⟩ theorem type_pUnit : type (@EmptyRelation PUnit) = 1 := rfl diff --git a/Mathlib/Topology/Homotopy/Contractible.lean b/Mathlib/Topology/Homotopy/Contractible.lean index 34bf5c1a001851..42461b28209d2f 100644 --- a/Mathlib/Topology/Homotopy/Contractible.lean +++ b/Mathlib/Topology/Homotopy/Contractible.lean @@ -91,9 +91,9 @@ protected theorem Homeomorph.contractibleSpace_iff (e : X ≃ₜ Y) : namespace ContractibleSpace -instance [Unique Y] : ContractibleSpace Y := by - have : ContractibleSpace (Unit) := ⟨⟨HomotopyEquiv.refl Unit⟩⟩ - apply (Homeomorph.homeomorphOfUnique Y Unit).contractibleSpace +instance [Nonempty Y] [Subsingleton Y] : ContractibleSpace Y := + let ⟨_⟩ := nonempty_unique Y + ⟨⟨(Homeomorph.homeomorphOfUnique Y Unit).toHomotopyEquiv⟩⟩ variable (X Y) in theorem hequiv [ContractibleSpace X] [ContractibleSpace Y] : diff --git a/Mathlib/Topology/TietzeExtension.lean b/Mathlib/Topology/TietzeExtension.lean index b1e175559e9fdf..c707446315731c 100644 --- a/Mathlib/Topology/TietzeExtension.lean +++ b/Mathlib/Topology/TietzeExtension.lean @@ -126,9 +126,9 @@ instance Prod.instTietzeExtension {Y : Type v} {Z : Type w} [TopologicalSpace Y] obtain ⟨g₂, hg₂⟩ := (ContinuousMap.snd.comp f).exists_restrict_eq hs exact ⟨g₁.prodMk g₂, by ext1 x; congrm(($(hg₁) x), $(hg₂) x)⟩ -instance Unique.instTietzeExtension {Y : Type v} [TopologicalSpace Y] [Unique Y] : - TietzeExtension.{u, v} Y where - exists_restrict_eq' _ _ f := ⟨.const _ default, by ext; subsingleton⟩ +instance Unique.instTietzeExtension {Y : Type v} [TopologicalSpace Y] + [Nonempty Y] [Subsingleton Y] : TietzeExtension.{u, v} Y where + exists_restrict_eq' _ _ f := ‹Nonempty Y›.elim fun y ↦ ⟨.const _ y, by ext; subsingleton⟩ /-- Any retract of a `TietzeExtension` space is one itself. -/ theorem TietzeExtension.of_retract {Y : Type v} {Z : Type w} [TopologicalSpace Y] From 52e14c088046bc1fb62f598492d04cbfa9957981 Mon Sep 17 00:00:00 2001 From: Kexing Ying Date: Sat, 12 Oct 2024 07:45:40 +0000 Subject: [PATCH 047/425] =?UTF-8?q?feat(HolderNorm):=20Define=20the=20H?= =?UTF-8?q?=C3=B6lder=20norm=20(#16711)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kexing Ying --- Mathlib.lean | 1 + Mathlib/Topology/MetricSpace/HolderNorm.lean | 265 +++++++++++++++++++ 2 files changed, 266 insertions(+) create mode 100644 Mathlib/Topology/MetricSpace/HolderNorm.lean diff --git a/Mathlib.lean b/Mathlib.lean index 945eeef5e10985..f81b6f5cdb74f3 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4732,6 +4732,7 @@ import Mathlib.Topology.MetricSpace.GromovHausdorffRealized import Mathlib.Topology.MetricSpace.HausdorffDimension import Mathlib.Topology.MetricSpace.HausdorffDistance import Mathlib.Topology.MetricSpace.Holder +import Mathlib.Topology.MetricSpace.HolderNorm import Mathlib.Topology.MetricSpace.Infsep import Mathlib.Topology.MetricSpace.IsometricSMul import Mathlib.Topology.MetricSpace.Isometry diff --git a/Mathlib/Topology/MetricSpace/HolderNorm.lean b/Mathlib/Topology/MetricSpace/HolderNorm.lean new file mode 100644 index 00000000000000..2081edf7d838d3 --- /dev/null +++ b/Mathlib/Topology/MetricSpace/HolderNorm.lean @@ -0,0 +1,265 @@ +/- +Copyright (c) 2024 Kexing Ying. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Kexing Ying +-/ +import Mathlib.Topology.MetricSpace.Holder + +/-! +# Hölder norm + +This file defines the Hölder (semi-)norm for Hölder functions alongside some basic properties. +The `r`-Hölder norm of a function `f : X → Y` between two metric spaces is the least non-negative +real number `C` for which `f` is `r`-Hölder continuous with constant `C`, i.e. it is the least `C` +for which `WithHolder C r f` is true. + +## Main definitions + +* `eHolderNorm r f`: `r`-Hölder (semi-)norm in `ℝ≥0∞` of a function `f`. +* `nnHolderNorm r f`: `r`-Hölder (semi-)norm in `ℝ≥0` of a function `f`. +* `MemHolder r f`: Predicate for a function `f` being `r`-Hölder continuous. + +## Main results + +* `eHolderNorm_eq_zero`: the Hölder norm of a function is zero if and only if it is constant. +* `MemHolder.holderWith`: The Hölder norm of a Hölder function `f` is a Hölder constant of `f`. + +## Tags + +Hölder norm, Hoelder norm, Holder norm + +-/ + +variable {X Y Z : Type*} + +open Filter Set + +open NNReal ENNReal Topology + +section PseudoEMetricSpace + +variable [PseudoEMetricSpace X] [PseudoEMetricSpace Y] {r : ℝ≥0} {f : X → Y} + +/-- The `r`-Hölder (semi-)norm in `ℝ≥0∞` of a function `f` is the least non-negative real +number `C` for which `f` is `r`-Hölder continuous with constant `C`. This is `∞` if no such +non-negative real exists. -/ +noncomputable +def eHolderNorm (r : ℝ≥0) (f : X → Y) : ℝ≥0∞ := ⨅ (C) (_ : HolderWith C r f), C + +/-- The `r`-Hölder (semi)norm in `ℝ≥0`. -/ +noncomputable +def nnHolderNorm (r : ℝ≥0) (f : X → Y) : ℝ≥0 := (eHolderNorm r f).toNNReal + +/-- A function `f` is `MemHolder r f` if it is Hölder continuous. Namely, `f` has a finite +`r`-Hölder constant. This is equivalent to `f` having finite Hölder norm. +c.f. `memHolder_iff`. -/ +def MemHolder (r : ℝ≥0) (f : X → Y) : Prop := ∃ C, HolderWith C r f + +lemma HolderWith.memHolder {C : ℝ≥0} (hf : HolderWith C r f) : MemHolder r f := ⟨C, hf⟩ + +@[simp] lemma eHolderNorm_lt_top : eHolderNorm r f < ∞ ↔ MemHolder r f := by + refine ⟨fun h => ?_, + fun hf => let ⟨C, hC⟩ := hf; iInf_lt_top.2 ⟨C, iInf_lt_top.2 ⟨hC, coe_lt_top⟩⟩⟩ + simp_rw [eHolderNorm, iInf_lt_top] at h + exact let ⟨C, hC, _⟩ := h; ⟨C, hC⟩ + +lemma eHolderNorm_ne_top : eHolderNorm r f ≠ ∞ ↔ MemHolder r f := by + rw [← eHolderNorm_lt_top, lt_top_iff_ne_top] + +@[simp] lemma eHolderNorm_eq_top : eHolderNorm r f = ∞ ↔ ¬ MemHolder r f := by + rw [← eHolderNorm_ne_top, not_not] + +protected alias ⟨_, MemHolder.eHolderNorm_lt_top⟩ := eHolderNorm_lt_top +protected alias ⟨_, MemHolder.eHolderNorm_ne_top⟩ := eHolderNorm_ne_top + +lemma coe_nnHolderNorm_le_eHolderNorm {r : ℝ≥0} {f : X → Y} : + (nnHolderNorm r f : ℝ≥0∞) ≤ eHolderNorm r f := + coe_toNNReal_le_self + +variable (X) in +@[simp] +lemma eHolderNorm_const (r : ℝ≥0) (c : Y) : eHolderNorm r (Function.const X c) = 0 := by + rw [eHolderNorm, ← ENNReal.bot_eq_zero, iInf₂_eq_bot] + exact fun C' hC' => ⟨0, .const, hC'⟩ + +variable (X) in +@[simp] +lemma eHolderNorm_zero [Zero Y] (r : ℝ≥0) : eHolderNorm r (0 : X → Y) = 0 := + eHolderNorm_const X r 0 + +variable (X) in +@[simp] +lemma nnHolderNorm_const (r : ℝ≥0) (c : Y) : nnHolderNorm r (Function.const X c) = 0 := by + refine le_antisymm (ENNReal.coe_le_coe.1 <| + le_trans coe_nnHolderNorm_le_eHolderNorm ?_) (zero_le _) + rw [eHolderNorm_const] + rfl + +variable (X) in +@[simp] +lemma nnHolderNorm_zero [Zero Y] (r : ℝ≥0) : nnHolderNorm r (0 : X → Y) = 0 := + nnHolderNorm_const X r 0 + +attribute [simp] eHolderNorm_const eHolderNorm_zero + +lemma eHolderNorm_of_isEmpty [hX : IsEmpty X] : + eHolderNorm r f = 0 := by + rw [eHolderNorm, ← ENNReal.bot_eq_zero, iInf₂_eq_bot] + exact fun ε hε => ⟨0, .of_isEmpty, hε⟩ + +lemma HolderWith.eHolderNorm_le {C : ℝ≥0} (hf : HolderWith C r f) : + eHolderNorm r f ≤ C := + iInf₂_le C hf + +/-- See also `memHolder_const` for the version with the spelling `fun _ ↦ c`. -/ +@[simp] +lemma memHolder_const {c : Y} : MemHolder r (Function.const X c) := + (HolderWith.const (C := 0)).memHolder + +/-- Version of `memHolder_const` with the spelling `fun _ ↦ c` for the constant function. -/ +@[simp] +lemma memHolder_const' {c : Y} : MemHolder r (fun _ ↦ c : X → Y) := + memHolder_const + +@[simp] +lemma memHolder_zero [Zero Y] : MemHolder r (0 : X → Y) := + memHolder_const + +end PseudoEMetricSpace + +section MetricSpace + +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₂ => ?_ + by_cases hx : x₁ = x₂ + · rw [hx] + · rw [eHolderNorm, ← ENNReal.bot_eq_zero, iInf₂_eq_bot] at h + rw [← edist_eq_zero, ← le_zero_iff] + refine le_of_forall_lt' fun b hb => ?_ + obtain ⟨C, hC, hC'⟩ := h (b / edist x₁ x₂ ^ (r : ℝ)) + (ENNReal.div_pos hb.ne.symm (ENNReal.rpow_lt_top_of_nonneg zero_le_coe + (edist_lt_top x₁ x₂).ne).ne) + exact lt_of_le_of_lt (hC x₁ x₂) <| ENNReal.mul_lt_of_lt_div hC' + · intro h + cases' isEmpty_or_nonempty X with hX hX + · haveI := hX + exact eHolderNorm_of_isEmpty + · rw [← eHolderNorm_const X r (f hX.some)] + congr + simp [funext_iff, h _ hX.some] + +lemma MemHolder.holderWith {r : ℝ≥0} {f : X → Y} (hf : MemHolder r f) : + HolderWith (nnHolderNorm r f) r f := by + intros x₁ x₂ + by_cases hx : x₁ = x₂ + · simp only [hx, edist_self, zero_le] + rw [nnHolderNorm, eHolderNorm, coe_toNNReal] + swap; exact hf.eHolderNorm_lt_top.ne + have h₁ : edist x₁ x₂ ^ (r : ℝ) ≠ 0 := + (Ne.symm <| ne_of_lt <| ENNReal.rpow_pos (edist_pos.2 hx) (edist_lt_top x₁ x₂).ne) + have h₂ : edist x₁ x₂ ^ (r : ℝ) ≠ ∞ := by + simp [(edist_lt_top x₁ x₂).ne] + rw [← ENNReal.div_le_iff h₁ h₂] + refine le_iInf₂ fun C hC => ?_ + rw [ENNReal.div_le_iff h₁ h₂] + exact hC x₁ x₂ + +lemma memHolder_iff_holderWith {r : ℝ≥0} {f : X → Y} : + MemHolder r f ↔ HolderWith (nnHolderNorm r f) r f := + ⟨MemHolder.holderWith, HolderWith.memHolder⟩ + +lemma MemHolder.coe_nnHolderNorm_eq_eHolderNorm + {r : ℝ≥0} {f : X → Y} (hf : MemHolder r f) : + (nnHolderNorm r f : ℝ≥0∞) = eHolderNorm r f := by + rw [nnHolderNorm, coe_toNNReal] + exact ne_of_lt <| lt_of_le_of_lt hf.holderWith.eHolderNorm_le <| coe_lt_top + +lemma HolderWith.nnholderNorm_le {C r : ℝ≥0} {f : X → Y} (hf : HolderWith C r f) : + nnHolderNorm r f ≤ C := by + rw [← ENNReal.coe_le_coe, hf.memHolder.coe_nnHolderNorm_eq_eHolderNorm] + exact hf.eHolderNorm_le + +lemma MemHolder.comp {r s : ℝ≥0} {Z : Type*} [MetricSpace Z] {f : Z → X} {g : X → Y} + (hf : MemHolder r f) (hg : MemHolder s g) : MemHolder (s * r) (g ∘ f) := + (hg.holderWith.comp hf.holderWith).memHolder + +lemma MemHolder.nnHolderNorm_eq_zero {r : ℝ≥0} {f : X → Y} (hf : MemHolder r f) : + nnHolderNorm r f = 0 ↔ ∀ x₁ x₂, f x₁ = f x₂ := by + rw [← ENNReal.coe_eq_zero, hf.coe_nnHolderNorm_eq_eHolderNorm, eHolderNorm_eq_zero] + +end MetricSpace + +section SeminormedAddCommGroup + +variable [MetricSpace X] [NormedAddCommGroup Y] +variable {C r : ℝ≥0} {f g : X → Y} + +lemma MemHolder.add (hf : MemHolder r f) (hg : MemHolder r g) : MemHolder r (f + g) := + (hf.holderWith.add hg.holderWith).memHolder + +lemma MemHolder.smul {𝕜} [NormedDivisionRing 𝕜] [Module 𝕜 Y] [BoundedSMul 𝕜 Y] + {c : 𝕜} (hf : MemHolder r f) : MemHolder r (c • f) := + (hf.holderWith.smul c).memHolder + +lemma MemHolder.nsmul [Module ℝ Y] [BoundedSMul ℝ Y] (n : ℕ) (hf : MemHolder r f) : + MemHolder r (n • f) := by + simp [← Nat.cast_smul_eq_nsmul (R := ℝ), hf.smul] + +lemma MemHolder.nnHolderNorm_add_le (hf : MemHolder r f) (hg : MemHolder r g) : + nnHolderNorm r (f + g) ≤ nnHolderNorm r f + nnHolderNorm r g := + (hf.add hg).holderWith.nnholderNorm_le.trans <| + coe_le_coe.2 (hf.holderWith.add hg.holderWith).nnholderNorm_le + +lemma eHolderNorm_add_le : + eHolderNorm r (f + g) ≤ eHolderNorm r f + eHolderNorm r g := by + by_cases hfg : MemHolder r f ∧ MemHolder r g + · obtain ⟨hf, hg⟩ := hfg + rw [← hf.coe_nnHolderNorm_eq_eHolderNorm, ← hg.coe_nnHolderNorm_eq_eHolderNorm, + ← (hf.add hg).coe_nnHolderNorm_eq_eHolderNorm, ← coe_add, ENNReal.coe_le_coe] + exact hf.nnHolderNorm_add_le hg + · rw [Classical.not_and_iff_or_not_not, ← eHolderNorm_eq_top, ← eHolderNorm_eq_top] at hfg + obtain (h | h) := hfg + all_goals simp [h] + +lemma eHolderNorm_smul {α} [NormedDivisionRing α] [Module α Y] [BoundedSMul α Y] (c : α) : + eHolderNorm r (c • f) = ‖c‖₊ * eHolderNorm r f := by + by_cases hc : ‖c‖₊ = 0 + · rw [nnnorm_eq_zero] at hc + simp [hc] + by_cases hf : MemHolder r f + · refine le_antisymm ((hf.holderWith.smul c).eHolderNorm_le.trans ?_) <| mul_le_of_le_div' ?_ + · rw [coe_mul, hf.coe_nnHolderNorm_eq_eHolderNorm, mul_comm] + · rw [← (hf.holderWith.smul c).memHolder.coe_nnHolderNorm_eq_eHolderNorm, ← coe_div hc] + refine HolderWith.eHolderNorm_le fun x₁ x₂ => ?_ + rw [coe_div hc, ← ENNReal.mul_div_right_comm, + ENNReal.le_div_iff_mul_le (Or.inl <| coe_ne_zero.2 hc) <| Or.inl coe_ne_top, + mul_comm, ← smul_eq_mul, ← ENNReal.smul_def, ← edist_smul₀, ← Pi.smul_apply, + ← Pi.smul_apply] + exact hf.smul.holderWith x₁ x₂ + · rw [← eHolderNorm_eq_top] at hf + rw [hf, mul_top <| coe_ne_zero.2 hc, eHolderNorm_eq_top] + rw [nnnorm_eq_zero] at hc + intro h + have := h.smul (c := c⁻¹) + rw [inv_smul_smul₀ hc] at this + exact this.eHolderNorm_lt_top.ne hf + +lemma MemHolder.nnHolderNorm_smul {α} [NormedDivisionRing α] [Module α Y] [BoundedSMul α Y] + (hf : MemHolder r f) (c : α) : + nnHolderNorm r (c • f) = ‖c‖₊ * nnHolderNorm r f := by + rw [← ENNReal.coe_inj, coe_mul, hf.coe_nnHolderNorm_eq_eHolderNorm, + hf.smul.coe_nnHolderNorm_eq_eHolderNorm, eHolderNorm_smul] + +lemma eHolderNorm_nsmul [Module ℝ Y] [BoundedSMul ℝ Y] (n : ℕ) : + eHolderNorm r (n • f) = n • eHolderNorm r f := by + simp [← Nat.cast_smul_eq_nsmul (R := ℝ), eHolderNorm_smul] + +lemma MemHolder.nnHolderNorm_nsmul [Module ℝ Y] [BoundedSMul ℝ Y] (n : ℕ) (hf : MemHolder r f) : + nnHolderNorm r (n • f) = n • nnHolderNorm r f := by + simp [← Nat.cast_smul_eq_nsmul (R := ℝ), hf.nnHolderNorm_smul] + +end SeminormedAddCommGroup From 475211332eda98d23d2aa9658463cf3efb1abc1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Sat, 12 Oct 2024 07:45:41 +0000 Subject: [PATCH 048/425] chore(MeasureTheory/Integral/SetIntegral): fix lemma names (#17658) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename: * `integral_empty` -> `setIntegral_empty` * `integral_union` -> `setIntegral_union` * `integral_univ` -> `setIntegral_univ` * `setIntegral_congr` -> `setIntegral_congr_fun` * `setIntegral_congr₀` -> `setIntegral_congr_fun₀` * `setLIntegral_congr_set_ae` -> `setIntegral_congr_set` From PFR --- .../Calculus/BumpFunction/Normed.lean | 2 +- Mathlib/Analysis/Fourier/AddCircle.lean | 4 +- Mathlib/Analysis/MellinTransform.lean | 6 +- .../SpecialFunctions/Gamma/Basic.lean | 10 +-- .../Analysis/SpecialFunctions/Gamma/Beta.lean | 6 +- .../SpecialFunctions/Gamma/BohrMollerup.lean | 4 +- .../Gaussian/GaussianIntegral.lean | 2 +- .../Analysis/SpecialFunctions/PolarCoord.lean | 6 +- .../Constructions/HaarToSphere.lean | 2 +- .../Decomposition/RadonNikodym.lean | 8 +-- .../Function/AEEqOfIntegral.lean | 2 +- .../ConditionalExpectation/Basic.lean | 2 +- Mathlib/MeasureTheory/Integral/Average.lean | 2 +- .../Integral/DivergenceTheorem.lean | 16 ++--- Mathlib/MeasureTheory/Integral/Gamma.lean | 10 +-- .../Integral/IntegralEqImproper.lean | 8 +-- .../Integral/IntervalIntegral.lean | 12 ++-- .../MeasureTheory/Integral/PeakFunction.lean | 4 +- .../MeasureTheory/Integral/SetIntegral.lean | 70 ++++++++++++------- .../MeasureTheory/Integral/TorusIntegral.lean | 4 +- .../Measure/Lebesgue/Integral.lean | 6 +- .../Measure/Lebesgue/VolumeOfBalls.lean | 8 +-- Mathlib/MeasureTheory/Measure/Tilted.lean | 2 +- .../NumberTheory/LSeries/AbstractFuncEq.lean | 8 +-- .../LSeries/MellinEqDirichlet.lean | 4 +- .../Kernel/Disintegration/CDFToKernel.lean | 2 +- .../Kernel/Disintegration/CondCDF.lean | 2 +- .../Kernel/Disintegration/Density.lean | 4 +- .../Probability/Martingale/BorelCantelli.lean | 2 +- .../Probability/Martingale/Convergence.lean | 4 +- .../Martingale/OptionalStopping.lean | 8 +-- .../Probability/Martingale/Upcrossing.lean | 2 +- 32 files changed, 125 insertions(+), 107 deletions(-) diff --git a/Mathlib/Analysis/Calculus/BumpFunction/Normed.lean b/Mathlib/Analysis/Calculus/BumpFunction/Normed.lean index a61f635da6766c..fd3e53a98f2313 100644 --- a/Mathlib/Analysis/Calculus/BumpFunction/Normed.lean +++ b/Mathlib/Analysis/Calculus/BumpFunction/Normed.lean @@ -97,7 +97,7 @@ variable (μ) theorem measure_closedBall_le_integral : (μ (closedBall c f.rIn)).toReal ≤ ∫ x, f x ∂μ := by calc (μ (closedBall c f.rIn)).toReal = ∫ x in closedBall c f.rIn, 1 ∂μ := by simp - _ = ∫ x in closedBall c f.rIn, f x ∂μ := setIntegral_congr measurableSet_closedBall + _ = ∫ x in closedBall c f.rIn, f x ∂μ := setIntegral_congr_fun measurableSet_closedBall (fun x hx ↦ (one_of_mem_closedBall f hx).symm) _ ≤ ∫ x, f x ∂μ := setIntegral_le_integral f.integrable (Eventually.of_forall (fun x ↦ f.nonneg)) diff --git a/Mathlib/Analysis/Fourier/AddCircle.lean b/Mathlib/Analysis/Fourier/AddCircle.lean index 7ca64c6a78543c..d162af7712aca4 100644 --- a/Mathlib/Analysis/Fourier/AddCircle.lean +++ b/Mathlib/Analysis/Fourier/AddCircle.lean @@ -315,7 +315,7 @@ theorem fourierCoeffOn_eq_integral {a b : ℝ} (f : ℝ → E) (n : ℤ) (hab : rw [fourierCoeffOn, fourierCoeff_eq_intervalIntegral _ _ a, add_sub, add_sub_cancel_left] congr 1 simp_rw [intervalIntegral.integral_of_le hab.le] - refine setIntegral_congr measurableSet_Ioc fun x hx => ?_ + refine setIntegral_congr_fun measurableSet_Ioc fun x hx => ?_ rw [liftIoc_coe_apply] rwa [add_sub, add_sub_cancel_left] @@ -344,7 +344,7 @@ theorem fourierCoeff_liftIco_eq {a : ℝ} (f : ℝ → ℂ) (n : ℤ) : congr 1 simp_rw [intervalIntegral.integral_of_le (lt_add_of_pos_right a hT.out).le] iterate 2 rw [integral_Ioc_eq_integral_Ioo] - refine setIntegral_congr measurableSet_Ioo fun x hx => ?_ + refine setIntegral_congr_fun measurableSet_Ioo fun x hx => ?_ rw [liftIco_coe_apply (Ioo_subset_Ico_self hx)] end fourierCoeff diff --git a/Mathlib/Analysis/MellinTransform.lean b/Mathlib/Analysis/MellinTransform.lean index 6712829f036dc7..2f9f2d152d5db3 100644 --- a/Mathlib/Analysis/MellinTransform.lean +++ b/Mathlib/Analysis/MellinTransform.lean @@ -96,7 +96,7 @@ def mellinInv (σ : ℝ) (f : ℂ → E) (x : ℝ) : E := -- next few lemmas don't require convergence of the Mellin transform (they are just 0 = 0 otherwise) theorem mellin_cpow_smul (f : ℝ → E) (s a : ℂ) : mellin (fun t => (t : ℂ) ^ a • f t) s = mellin f (s + a) := by - refine setIntegral_congr measurableSet_Ioi fun t ht => ?_ + refine setIntegral_congr_fun measurableSet_Ioi fun t ht => ?_ simp_rw [← sub_add_eq_add_sub, cpow_add _ _ (ofReal_ne_zero.2 <| ne_of_gt ht), mul_smul] theorem mellin_const_smul (f : ℝ → E) (s : ℂ) {𝕜 : Type*} [NontriviallyNormedField 𝕜] @@ -116,7 +116,7 @@ theorem mellin_comp_rpow (f : ℝ → E) (s : ℂ) (a : ℝ) : · simp [integral, mellin, hE] simp_rw [mellin] conv_rhs => rw [← integral_comp_rpow_Ioi _ ha, ← integral_smul] - refine setIntegral_congr measurableSet_Ioi fun t ht => ?_ + refine setIntegral_congr_fun measurableSet_Ioi fun t ht => ?_ dsimp only rw [← mul_smul, ← mul_assoc, inv_mul_cancel₀ (mt abs_eq_zero.1 ha), one_mul, ← smul_assoc, real_smul] @@ -135,7 +135,7 @@ theorem mellin_comp_mul_left (f : ℝ → E) (s : ℂ) {a : ℝ} (ha : 0 < a) : (by ring : 1 - s = -(s - 1)), cpow_neg, inv_mul_cancel_left₀] rw [Ne, cpow_eq_zero_iff, ofReal_eq_zero, not_and_or] exact Or.inl ha.ne' - rw [setIntegral_congr measurableSet_Ioi this, integral_smul, + rw [setIntegral_congr_fun measurableSet_Ioi this, integral_smul, integral_comp_mul_left_Ioi (fun u ↦ (u : ℂ) ^ (s - 1) • f u) _ ha, mul_zero, ← Complex.coe_smul, ← mul_smul, sub_eq_add_neg, cpow_add _ _ (ofReal_ne_zero.mpr ha.ne'), cpow_one, ofReal_inv, diff --git a/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean index 86b3f777ce844a..ac24c2337c4907 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean @@ -115,7 +115,7 @@ def GammaIntegral (s : ℂ) : ℂ := theorem GammaIntegral_conj (s : ℂ) : GammaIntegral (conj s) = conj (GammaIntegral s) := by rw [GammaIntegral, GammaIntegral, ← integral_conj] - refine setIntegral_congr measurableSet_Ioi fun x hx => ?_ + refine setIntegral_congr_fun measurableSet_Ioi fun x hx => ?_ dsimp only rw [RingHom.map_mul, conj_ofReal, cpow_def_of_ne_zero (ofReal_ne_zero.mpr (ne_of_gt hx)), cpow_def_of_ne_zero (ofReal_ne_zero.mpr (ne_of_gt hx)), ← exp_conj, RingHom.map_mul, ← @@ -126,7 +126,7 @@ theorem GammaIntegral_ofReal (s : ℝ) : have : ∀ r : ℝ, Complex.ofReal' r = @RCLike.ofReal ℂ _ r := fun r => rfl rw [GammaIntegral] conv_rhs => rw [this, ← _root_.integral_ofReal] - refine setIntegral_congr measurableSet_Ioi ?_ + refine setIntegral_congr_fun measurableSet_Ioi ?_ intro x hx; dsimp only conv_rhs => rw [← this] rw [ofReal_mul, ofReal_cpow (mem_Ioi.mp hx).le] @@ -377,7 +377,7 @@ lemma integral_cpow_mul_exp_neg_mul_Ioi {a : ℂ} {r : ℝ} (ha : 0 < a.re) (hr rw [← cpow_add _ _ (one_div_ne_zero <| ofReal_ne_zero.mpr hr.ne'), add_sub_cancel] calc _ = ∫ (t : ℝ) in Ioi 0, (1 / r) ^ (a - 1) * (r * t) ^ (a - 1) * exp (-(r * t)) := by - refine MeasureTheory.setIntegral_congr measurableSet_Ioi (fun x hx ↦ ?_) + refine MeasureTheory.setIntegral_congr_fun measurableSet_Ioi (fun x hx ↦ ?_) rw [mem_Ioi] at hx rw [mul_cpow_ofReal_nonneg hr.le hx.le, ← mul_assoc, one_div, ← ofReal_inv, ← mul_cpow_ofReal_nonneg (inv_pos.mpr hr).le hr.le, ← ofReal_mul r⁻¹, @@ -487,7 +487,7 @@ theorem Gamma_eq_integral {s : ℝ} (hs : 0 < s) : have cc : ∀ r : ℝ, Complex.ofReal' r = @RCLike.ofReal ℂ _ r := fun r => rfl conv_lhs => rw [this]; enter [1, 2, x]; rw [cc] rw [_root_.integral_ofReal, ← cc, Complex.ofReal_re] - refine setIntegral_congr measurableSet_Ioi fun x hx => ?_ + refine setIntegral_congr_fun measurableSet_Ioi fun x hx => ?_ push_cast rw [Complex.ofReal_cpow (le_of_lt hx)] push_cast; rfl @@ -551,7 +551,7 @@ lemma integral_rpow_mul_exp_neg_mul_Ioi {a r : ℝ} (ha : 0 < a) (hr : 0 < r) : ∫ t : ℝ in Ioi 0, t ^ (a - 1) * exp (-(r * t)) = (1 / r) ^ a * Gamma a := by rw [← ofReal_inj, ofReal_mul, ← Gamma_ofReal, ofReal_cpow (by positivity), ofReal_div] convert integral_cpow_mul_exp_neg_mul_Ioi (by rwa [ofReal_re] : 0 < (a : ℂ).re) hr - refine _root_.integral_ofReal.symm.trans <| setIntegral_congr measurableSet_Ioi (fun t ht ↦ ?_) + refine integral_ofReal.symm.trans <| setIntegral_congr_fun measurableSet_Ioi (fun t ht ↦ ?_) norm_cast simp_rw [← ofReal_cpow ht.le, RCLike.ofReal_mul, coe_algebraMap] diff --git a/Mathlib/Analysis/SpecialFunctions/Gamma/Beta.lean b/Mathlib/Analysis/SpecialFunctions/Gamma/Beta.lean index f449779354eda0..feeba0621e3e6f 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gamma/Beta.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gamma/Beta.lean @@ -114,7 +114,7 @@ theorem betaIntegral_scaled (s t : ℂ) {a : ℝ} (ha : 0 < a) : rw [A, mul_assoc, ← intervalIntegral.integral_const_mul, ← real_smul, ← zero_div a, ← div_self ha.ne', ← intervalIntegral.integral_comp_div _ ha.ne', zero_div] simp_rw [intervalIntegral.integral_of_le ha.le] - refine setIntegral_congr measurableSet_Ioc fun x hx => ?_ + refine setIntegral_congr_fun measurableSet_Ioc fun x hx => ?_ rw [mul_mul_mul_comm] congr 1 · rw [← mul_cpow_ofReal_nonneg ha.le (div_pos hx.1 ha).le, ofReal_div, mul_div_cancel₀ _ ha'] @@ -134,7 +134,7 @@ theorem Gamma_mul_Gamma_eq_betaIntegral {s t : ℂ} (hs : 0 < re s) (ht : 0 < re have hst : 0 < re (s + t) := by rw [add_re]; exact add_pos hs ht rw [Gamma_eq_integral hs, Gamma_eq_integral ht, Gamma_eq_integral hst, GammaIntegral, GammaIntegral, GammaIntegral, ← conv_int, ← integral_mul_right (betaIntegral _ _)] - refine setIntegral_congr measurableSet_Ioi fun x hx => ?_ + refine setIntegral_congr_fun measurableSet_Ioi fun x hx => ?_ rw [mul_assoc, ← betaIntegral_scaled s t hx, ← intervalIntegral.integral_const_mul] congr 1 with y : 1 push_cast @@ -259,7 +259,7 @@ theorem GammaSeq_eq_approx_Gamma_integral {s : ℂ} (hs : 0 < re s) {n : ℕ} (h ← intervalIntegral.integral_const_mul, ← intervalIntegral.integral_const_mul] swap; · exact Nat.cast_ne_zero.mpr hn simp_rw [intervalIntegral.integral_of_le zero_le_one] - refine setIntegral_congr measurableSet_Ioc fun x hx => ?_ + refine setIntegral_congr_fun measurableSet_Ioc fun x hx => ?_ push_cast have hn' : (n : ℂ) ≠ 0 := Nat.cast_ne_zero.mpr hn have A : (n : ℂ) ^ s = (n : ℂ) ^ (s - 1) * n := by diff --git a/Mathlib/Analysis/SpecialFunctions/Gamma/BohrMollerup.lean b/Mathlib/Analysis/SpecialFunctions/Gamma/BohrMollerup.lean index f3bd9a9a2e9a4a..c9f1f89b0bd5a3 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gamma/BohrMollerup.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gamma/BohrMollerup.lean @@ -94,7 +94,7 @@ theorem Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma {s t a b : ℝ} (hs : 0 < MeasureTheory.integral_mul_le_Lp_mul_Lq_of_nonneg e (posf' a s) (posf' b t) (f_mem_Lp ha hs) (f_mem_Lp hb ht) using 1 - · refine setIntegral_congr measurableSet_Ioi fun x hx => ?_ + · refine setIntegral_congr_fun measurableSet_Ioi fun x hx => ?_ dsimp only have A : exp (-x) = exp (-a * x) * exp (-b * x) := by rw [← exp_add, ← add_mul, ← neg_add, hab, neg_one_mul] @@ -103,7 +103,7 @@ theorem Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma {s t a b : ℝ} (hs : 0 < rw [A, B] ring · rw [one_div_one_div, one_div_one_div] - congr 2 <;> exact setIntegral_congr measurableSet_Ioi fun x hx => fpow (by assumption) _ hx + congr 2 <;> exact setIntegral_congr_fun measurableSet_Ioi fun x hx => fpow (by assumption) _ hx theorem convexOn_log_Gamma : ConvexOn ℝ (Ioi 0) (log ∘ Gamma) := by refine convexOn_iff_forall_pos.mpr ⟨convex_Ioi _, fun x hx y hy a b ha hb hab => ?_⟩ diff --git a/Mathlib/Analysis/SpecialFunctions/Gaussian/GaussianIntegral.lean b/Mathlib/Analysis/SpecialFunctions/Gaussian/GaussianIntegral.lean index 163d700eb16bbc..1c044bfc8ba0eb 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gaussian/GaussianIntegral.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gaussian/GaussianIntegral.lean @@ -335,7 +335,7 @@ theorem Real.Gamma_one_half_eq : Real.Gamma (1 / 2) = √π := by rw [Gamma_eq_integral one_half_pos, ← integral_comp_rpow_Ioi_of_pos zero_lt_two] convert congr_arg (fun x : ℝ => 2 * x) (integral_gaussian_Ioi 1) using 1 · rw [← integral_mul_left] - refine setIntegral_congr measurableSet_Ioi fun x hx => ?_ + refine setIntegral_congr_fun measurableSet_Ioi fun x hx => ?_ dsimp only have : (x ^ (2 : ℝ)) ^ (1 / (2 : ℝ) - 1) = x⁻¹ := by rw [← rpow_mul (le_of_lt hx)] diff --git a/Mathlib/Analysis/SpecialFunctions/PolarCoord.lean b/Mathlib/Analysis/SpecialFunctions/PolarCoord.lean index 62dafde2c14333..46513cef6be86b 100644 --- a/Mathlib/Analysis/SpecialFunctions/PolarCoord.lean +++ b/Mathlib/Analysis/SpecialFunctions/PolarCoord.lean @@ -135,13 +135,13 @@ theorem integral_comp_polarCoord_symm {E : Type*} [NormedAddCommGroup E] [Normed symm calc ∫ p, f p = ∫ p in polarCoord.source, f p := by - rw [← integral_univ] - apply setIntegral_congr_set_ae + rw [← setIntegral_univ] + apply setIntegral_congr_set exact polarCoord_source_ae_eq_univ.symm _ = ∫ p in polarCoord.target, abs (B p).det • f (polarCoord.symm p) := by apply integral_target_eq_integral_abs_det_fderiv_smul volume A _ = ∫ p in polarCoord.target, p.1 • f (polarCoord.symm p) := by - apply setIntegral_congr polarCoord.open_target.measurableSet fun x hx => ?_ + apply setIntegral_congr_fun polarCoord.open_target.measurableSet fun x hx => ?_ rw [B_det, abs_of_pos] exact hx.1 diff --git a/Mathlib/MeasureTheory/Constructions/HaarToSphere.lean b/Mathlib/MeasureTheory/Constructions/HaarToSphere.lean index 2b64a512ceb6ea..01b32e29b00eec 100644 --- a/Mathlib/MeasureTheory/Constructions/HaarToSphere.lean +++ b/Mathlib/MeasureTheory/Constructions/HaarToSphere.lean @@ -147,7 +147,7 @@ lemma integral_fun_norm_addHaar (f : ℝ → F) : rw [integral_withDensity_eq_integral_smul, μ.toSphere_apply_univ, ENNReal.toReal_mul, ENNReal.toReal_nat, ← nsmul_eq_mul, smul_assoc, integral_subtype_comap measurableSet_Ioi fun a ↦ Real.toNNReal (a ^ (dim E - 1)) • f a, - setIntegral_congr measurableSet_Ioi fun x hx ↦ ?_] + setIntegral_congr_fun measurableSet_Ioi fun x hx ↦ ?_] · rw [NNReal.smul_def, Real.coe_toNNReal _ (pow_nonneg hx.out.le _)] · exact (measurable_subtype_coe.pow_const _).real_toNNReal diff --git a/Mathlib/MeasureTheory/Decomposition/RadonNikodym.lean b/Mathlib/MeasureTheory/Decomposition/RadonNikodym.lean index 48bb69b5fadb25..f2347396e6fc35 100644 --- a/Mathlib/MeasureTheory/Decomposition/RadonNikodym.lean +++ b/Mathlib/MeasureTheory/Decomposition/RadonNikodym.lean @@ -388,13 +388,13 @@ alias set_integral_toReal_rnDeriv := setIntegral_toReal_rnDeriv lemma integral_toReal_rnDeriv [SigmaFinite μ] [SigmaFinite ν] (hμν : μ ≪ ν) : ∫ x, (μ.rnDeriv ν x).toReal ∂ν = (μ Set.univ).toReal := by - rw [← integral_univ, setIntegral_toReal_rnDeriv hμν Set.univ] + rw [← setIntegral_univ, setIntegral_toReal_rnDeriv hμν Set.univ] lemma integral_toReal_rnDeriv' [IsFiniteMeasure μ] [SigmaFinite ν] : ∫ x, (μ.rnDeriv ν x).toReal ∂ν = (μ Set.univ).toReal - (μ.singularPart ν Set.univ).toReal := by rw [← ENNReal.toReal_sub_of_le (μ.singularPart_le ν Set.univ) (measure_ne_top _ _), ← Measure.sub_apply .univ (Measure.singularPart_le μ ν), Measure.measure_sub_singularPart, - ← Measure.setIntegral_toReal_rnDeriv_eq_withDensity, integral_univ] + ← Measure.setIntegral_toReal_rnDeriv_eq_withDensity, setIntegral_univ] end integral @@ -563,8 +563,8 @@ theorem integral_rnDeriv_smul [HaveLebesgueDecomposition μ ν] (hμν : μ ≪ [SigmaFinite μ] {f : α → E} : ∫ x, (μ.rnDeriv ν x).toReal • f x ∂ν = ∫ x, f x ∂μ := by by_cases hf : Integrable f μ - · rw [← integral_univ, ← withDensityᵥ_apply ((integrable_rnDeriv_smul_iff hμν).mpr hf) .univ, - ← integral_univ, ← withDensityᵥ_apply hf .univ, withDensityᵥ_rnDeriv_smul hμν hf] + · rw [← setIntegral_univ, ← withDensityᵥ_apply ((integrable_rnDeriv_smul_iff hμν).mpr hf) .univ, + ← setIntegral_univ, ← withDensityᵥ_apply hf .univ, withDensityᵥ_rnDeriv_smul hμν hf] · rw [integral_undef hf, integral_undef] contrapose! hf exact (integrable_rnDeriv_smul_iff hμν).mp hf diff --git a/Mathlib/MeasureTheory/Function/AEEqOfIntegral.lean b/Mathlib/MeasureTheory/Function/AEEqOfIntegral.lean index 20685e3ff10ed3..d9303573bf9fd6 100644 --- a/Mathlib/MeasureTheory/Function/AEEqOfIntegral.lean +++ b/Mathlib/MeasureTheory/Function/AEEqOfIntegral.lean @@ -590,7 +590,7 @@ lemma ae_eq_zero_of_forall_setIntegral_isClosed_eq_zero {μ : Measure β} {f : have A : ∀ (t : Set β), MeasurableSet t → ∫ (x : β) in t, f x ∂μ = 0 → ∫ (x : β) in tᶜ, f x ∂μ = 0 := by intro t t_meas ht - have I : ∫ x, f x ∂μ = 0 := by rw [← integral_univ]; exact h'f _ isClosed_univ + have I : ∫ x, f x ∂μ = 0 := by rw [← setIntegral_univ]; exact h'f _ isClosed_univ simpa [ht, I] using integral_add_compl t_meas hf intro s hs refine MeasurableSet.induction_on_open (fun U hU ↦ ?_) A (fun g g_disj g_meas hg ↦ ?_) hs diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Basic.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Basic.lean index daab2ab684f354..8e4660db64bc61 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Basic.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Basic.lean @@ -208,7 +208,7 @@ theorem integral_condexp (hm : m ≤ m0) [hμm : SigmaFinite (μ.trim hm)] : ∫ x, (μ[f|m]) x ∂μ = ∫ x, f x ∂μ := by by_cases hf : Integrable f μ · suffices ∫ x in Set.univ, (μ[f|m]) x ∂μ = ∫ x in Set.univ, f x ∂μ by - simp_rw [integral_univ] at this; exact this + simp_rw [setIntegral_univ] at this; exact this exact setIntegral_condexp hm hf (@MeasurableSet.univ _ m) simp only [condexp_undef hf, Pi.zero_apply, integral_zero, integral_undef hf] diff --git a/Mathlib/MeasureTheory/Integral/Average.lean b/Mathlib/MeasureTheory/Integral/Average.lean index 2b93b827a03390..86ca2d01fcaf8c 100644 --- a/Mathlib/MeasureTheory/Integral/Average.lean +++ b/Mathlib/MeasureTheory/Integral/Average.lean @@ -321,7 +321,7 @@ theorem average_congr {f g : α → E} (h : f =ᵐ[μ] g) : ⨍ x, f x ∂μ = simp only [average_eq, integral_congr_ae h] theorem setAverage_congr (h : s =ᵐ[μ] t) : ⨍ x in s, f x ∂μ = ⨍ x in t, f x ∂μ := by - simp only [setAverage_eq, setIntegral_congr_set_ae h, measure_congr h] + simp only [setAverage_eq, setIntegral_congr_set h, measure_congr h] theorem setAverage_congr_fun (hs : MeasurableSet s) (h : ∀ᵐ x ∂μ, x ∈ s → f x = g x) : ⨍ x in s, f x ∂μ = ⨍ x in s, g x ∂μ := by simp only [average_eq, setIntegral_congr_ae hs h] diff --git a/Mathlib/MeasureTheory/Integral/DivergenceTheorem.lean b/Mathlib/MeasureTheory/Integral/DivergenceTheorem.lean index 2280f163883e01..c42a397ec5d543 100644 --- a/Mathlib/MeasureTheory/Integral/DivergenceTheorem.lean +++ b/Mathlib/MeasureTheory/Integral/DivergenceTheorem.lean @@ -116,7 +116,7 @@ theorem integral_divergence_of_hasFDerivWithinAt_off_countable_aux₁ (I : Box ( ∑ i : Fin (n + 1), ((∫ x in Box.Icc (I.face i), f (i.insertNth (I.upper i) x) i) - ∫ x in Box.Icc (I.face i), f (i.insertNth (I.lower i) x) i) := by - simp only [← setIntegral_congr_set_ae (Box.coe_ae_eq_Icc _)] + simp only [← setIntegral_congr_set (Box.coe_ae_eq_Icc _)] have A := (Hi.mono_set Box.coe_subset_Icc).hasBoxIntegral ⊥ rfl have B := hasIntegral_GP_divergence_of_forall_hasDerivWithinAt I f f' (s ∩ Box.Icc I) @@ -273,10 +273,10 @@ theorem integral_divergence_of_hasFDerivWithinAt_off_countable (hle : a ≤ b) ((∫ x in face i, f (frontFace i x) i) - ∫ x in face i, f (backFace i x) i) := by rcases em (∃ i, a i = b i) with (⟨i, hi⟩ | hne) · -- First we sort out the trivial case `∃ i, a i = b i`. - rw [volume_pi, ← setIntegral_congr_set_ae Measure.univ_pi_Ioc_ae_eq_Icc] + rw [volume_pi, ← setIntegral_congr_set Measure.univ_pi_Ioc_ae_eq_Icc] have hi' : Ioc (a i) (b i) = ∅ := Ioc_eq_empty hi.not_lt have : (pi Set.univ fun j => Ioc (a j) (b j)) = ∅ := univ_pi_eq_empty hi' - rw [this, integral_empty, sum_eq_zero] + rw [this, setIntegral_empty, sum_eq_zero] rintro j - rcases eq_or_ne i j with (rfl | hne) · simp [hi] @@ -284,8 +284,8 @@ theorem integral_divergence_of_hasFDerivWithinAt_off_countable (hle : a ≤ b) have : Icc (a ∘ j.succAbove) (b ∘ j.succAbove) =ᵐ[volume] (∅ : Set ℝⁿ) := by rw [ae_eq_empty, Real.volume_Icc_pi, prod_eq_zero (Finset.mem_univ i)] simp [hi] - rw [setIntegral_congr_set_ae this, setIntegral_congr_set_ae this, integral_empty, - integral_empty, sub_self] + rw [setIntegral_congr_set this, setIntegral_congr_set this, setIntegral_empty, + setIntegral_empty, sub_self] · -- In the non-trivial case `∀ i, a i < b i`, we apply a lemma we proved above. have hlt : ∀ i, a i < b i := fun i => (hle i).lt_of_ne fun hi => hne ⟨i, hi⟩ exact integral_divergence_of_hasFDerivWithinAt_off_countable_aux₂ ⟨a, b, hlt⟩ f f' s hs Hc @@ -382,7 +382,7 @@ theorem integral_eq_of_hasDerivWithinAt_off_countable_of_le (f f' : ℝ → E) { have hF' : ∀ x y, F' x y = y • f' x := fun x y => rfl calc ∫ x in a..b, f' x = ∫ x in Icc a b, f' x := by - rw [intervalIntegral.integral_of_le hle, setIntegral_congr_set_ae Ioc_ae_eq_Icc] + rw [intervalIntegral.integral_of_le hle, setIntegral_congr_set Ioc_ae_eq_Icc] _ = ∑ i : Fin 1, ((∫ x in Icc (e a ∘ i.succAbove) (e b ∘ i.succAbove), f (e.symm <| i.insertNth (e b i) x)) - @@ -467,7 +467,7 @@ theorem integral_divergence_prod_Icc_of_hasFDerivWithinAt_off_countable_of_le (f _ = (((∫ x in a.1..b.1, g (x, b.2)) - ∫ x in a.1..b.1, g (x, a.2)) + ∫ y in a.2..b.2, f (b.1, y)) - ∫ y in a.2..b.2, f (a.1, y) := by simp only [intervalIntegral.integral_of_le hle.1, intervalIntegral.integral_of_le hle.2, - setIntegral_congr_set_ae (Ioc_ae_eq_Icc (α := ℝ) (μ := volume))] + setIntegral_congr_set (Ioc_ae_eq_Icc (α := ℝ) (μ := volume))] abel /-- **Divergence theorem** for functions on the plane. It is formulated in terms of two functions @@ -506,7 +506,7 @@ theorem integral2_divergence_prod_of_hasFDerivWithinAt_off_countable (f g : ℝ (∫ x in a₁..b₁, ∫ y in a₂..b₂, f' (x, y) (1, 0) + g' (x, y) (0, 1)) = ∫ x in Icc a₁ b₁, ∫ y in Icc a₂ b₂, f' (x, y) (1, 0) + g' (x, y) (0, 1) := by simp only [intervalIntegral.integral_of_le, h₁, h₂, - setIntegral_congr_set_ae (Ioc_ae_eq_Icc (α := ℝ) (μ := volume))] + setIntegral_congr_set (Ioc_ae_eq_Icc (α := ℝ) (μ := volume))] _ = ∫ x in Icc a₁ b₁ ×ˢ Icc a₂ b₂, f' x (1, 0) + g' x (0, 1) := (setIntegral_prod _ Hi).symm _ = (((∫ x in a₁..b₁, g (x, b₂)) - ∫ x in a₁..b₁, g (x, a₂)) + ∫ y in a₂..b₂, f (b₁, y)) - ∫ y in a₂..b₂, f (a₁, y) := by diff --git a/Mathlib/MeasureTheory/Integral/Gamma.lean b/Mathlib/MeasureTheory/Integral/Gamma.lean index e45745db0df273..e8364efdee04a0 100644 --- a/Mathlib/MeasureTheory/Integral/Gamma.lean +++ b/Mathlib/MeasureTheory/Integral/Gamma.lean @@ -24,11 +24,11 @@ theorem integral_rpow_mul_exp_neg_rpow {p q : ℝ} (hp : 0 < p) (hq : - 1 < q) : _ = ∫ (x : ℝ) in Ioi 0, (1 / p * x ^ (1 / p - 1)) • ((x ^ (1 / p)) ^ q * exp (-x)) := by rw [← integral_comp_rpow_Ioi _ (one_div_ne_zero (ne_of_gt hp)), abs_eq_self.mpr (le_of_lt (one_div_pos.mpr hp))] - refine setIntegral_congr measurableSet_Ioi (fun _ hx => ?_) + refine setIntegral_congr_fun measurableSet_Ioi (fun _ hx => ?_) rw [← rpow_mul (le_of_lt hx) _ p, one_div_mul_cancel (ne_of_gt hp), rpow_one] _ = ∫ (x : ℝ) in Ioi 0, 1 / p * exp (-x) * x ^ (1 / p - 1 + q / p) := by simp_rw [smul_eq_mul, mul_assoc] - refine setIntegral_congr measurableSet_Ioi (fun _ hx => ?_) + refine setIntegral_congr_fun measurableSet_Ioi (fun _ hx => ?_) rw [← rpow_mul (le_of_lt hx), div_mul_eq_mul_div, one_mul, rpow_add hx] ring_nf _ = (1 / p) * Gamma ((q + 1) / p) := by @@ -41,7 +41,7 @@ theorem integral_rpow_mul_exp_neg_mul_rpow {p q b : ℝ} (hp : 0 < p) (hq : - 1 b ^ (-(q + 1) / p) * (1 / p) * Gamma ((q + 1) / p) := by calc _ = ∫ x in Ioi (0 : ℝ), b ^ (-p⁻¹ * q) * ((b ^ p⁻¹ * x) ^ q * rexp (-(b ^ p⁻¹ * x) ^ p)) := by - refine setIntegral_congr measurableSet_Ioi (fun _ hx => ?_) + refine setIntegral_congr_fun measurableSet_Ioi (fun _ hx => ?_) rw [mul_rpow _ (le_of_lt hx), mul_rpow _ (le_of_lt hx), ← rpow_mul, ← rpow_mul, inv_mul_cancel₀, rpow_one, mul_assoc, ← mul_assoc, ← rpow_add, neg_mul p⁻¹, neg_add_cancel, rpow_zero, one_mul, neg_mul] @@ -88,7 +88,7 @@ theorem Complex.integral_rpow_mul_exp_neg_rpow {p q : ℝ} (hp : 1 ≤ p) (hq : smul_eq_mul, mul_one, mul_comm] _ = 2 * π * ∫ x in Ioi (0 : ℝ), x ^ (q + 1) * rexp (-x ^ p) := by congr 1 - refine setIntegral_congr measurableSet_Ioi (fun x hx => ?_) + refine setIntegral_congr_fun measurableSet_Ioi (fun x hx => ?_) rw [mem_Ioi] at hx rw [abs_eq_self.mpr hx.le, rpow_add hx, rpow_one] ring @@ -115,7 +115,7 @@ theorem Complex.integral_rpow_mul_exp_neg_mul_rpow {p q b : ℝ} (hp : 1 ≤ p) smul_eq_mul, mul_one, mul_comm] _ = 2 * π * ∫ x in Ioi (0 : ℝ), x ^ (q + 1) * rexp (-b * x ^ p) := by congr 1 - refine setIntegral_congr measurableSet_Ioi (fun x hx => ?_) + refine setIntegral_congr_fun measurableSet_Ioi (fun x hx => ?_) rw [mem_Ioi] at hx rw [abs_eq_self.mpr hx.le, rpow_add hx, rpow_one] ring diff --git a/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean b/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean index 737247f5c89182..10441a23710fa5 100644 --- a/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean +++ b/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean @@ -793,7 +793,7 @@ theorem integrableOn_Ioi_deriv_of_nonneg (hcont : ContinuousWithinAt g (Ici a) a (fun y hy => hderiv y hy.1) fun y hy => g'pos y hy.1 _ = ∫ y in a..id x, ‖g' y‖ := by simp_rw [intervalIntegral.integral_of_le h'x] - refine setIntegral_congr measurableSet_Ioc fun y hy => ?_ + refine setIntegral_congr_fun measurableSet_Ioc fun y hy => ?_ dsimp rw [abs_of_nonneg] exact g'pos _ hy.1 @@ -996,8 +996,8 @@ see `tendsto_limUnder_of_hasDerivAt_of_integrableOn_Iic` and theorem integral_of_hasDerivAt_of_tendsto [CompleteSpace E] (hderiv : ∀ x, HasDerivAt f (f' x) x) (hf' : Integrable f') (hbot : Tendsto f atBot (𝓝 m)) (htop : Tendsto f atTop (𝓝 n)) : ∫ x, f' x = n - m := by - rw [← integral_univ, ← Set.Iic_union_Ioi (a := 0), - integral_union (Iic_disjoint_Ioi le_rfl) measurableSet_Ioi hf'.integrableOn hf'.integrableOn, + rw [← setIntegral_univ, ← Set.Iic_union_Ioi (a := 0), + setIntegral_union (Iic_disjoint_Ioi le_rfl) measurableSet_Ioi hf'.integrableOn hf'.integrableOn, integral_Iic_of_hasDerivAt_of_tendsto' (fun x _ ↦ hderiv x) hf'.integrableOn hbot, integral_Ioi_of_hasDerivAt_of_tendsto' (fun x _ ↦ hderiv x) hf'.integrableOn htop] abel @@ -1086,7 +1086,7 @@ theorem integral_comp_rpow_Ioi (g : ℝ → E) {p : ℝ} (hp : p ≠ 0) : 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 measurableSet_Ioi ?_ + refine setIntegral_congr_fun measurableSet_Ioi ?_ intro x hx; dsimp only rw [abs_mul, abs_of_nonneg (rpow_nonneg (le_of_lt hx) _)] diff --git a/Mathlib/MeasureTheory/Integral/IntervalIntegral.lean b/Mathlib/MeasureTheory/Integral/IntervalIntegral.lean index d7473d6e2d8dfb..0c443e0792ad6a 100644 --- a/Mathlib/MeasureTheory/Integral/IntervalIntegral.lean +++ b/Mathlib/MeasureTheory/Integral/IntervalIntegral.lean @@ -786,14 +786,14 @@ theorem integral_congr {a b : ℝ} (h : EqOn f g [[a, b]]) : ∫ x in a..b, f x ∂μ = ∫ x in a..b, g x ∂μ := by rcases le_total a b with hab | hab <;> simpa [hab, integral_of_le, integral_of_ge] using - setIntegral_congr measurableSet_Ioc (h.mono Ioc_subset_Icc_self) + setIntegral_congr_fun measurableSet_Ioc (h.mono Ioc_subset_Icc_self) theorem integral_add_adjacent_intervals_cancel (hab : IntervalIntegrable f μ a b) (hbc : IntervalIntegrable f μ b c) : (((∫ x in a..b, f x ∂μ) + ∫ x in b..c, f x ∂μ) + ∫ x in c..a, f x ∂μ) = 0 := by have hac := hab.trans hbc simp only [intervalIntegral, sub_add_sub_comm, sub_eq_zero] - iterate 4 rw [← integral_union] + iterate 4 rw [← setIntegral_union] · suffices Ioc a b ∪ Ioc b c ∪ Ioc c a = Ioc b a ∪ Ioc c b ∪ Ioc a c by rw [this] rw [Ioc_union_Ioc_union_Ioc_cycle, union_right_comm, Ioc_union_Ioc_union_Ioc_cycle, min_left_comm, max_left_comm] @@ -857,20 +857,20 @@ theorem integral_Iic_sub_Iic (ha : IntegrableOn f (Iic a) μ) (hb : IntegrableOn ((∫ x in Iic b, f x ∂μ) - ∫ x in Iic a, f x ∂μ) = ∫ x in a..b, f x ∂μ := by wlog hab : a ≤ b generalizing a b · rw [integral_symm, ← this hb ha (le_of_not_le hab), neg_sub] - rw [sub_eq_iff_eq_add', integral_of_le hab, ← integral_union (Iic_disjoint_Ioc le_rfl), + rw [sub_eq_iff_eq_add', integral_of_le hab, ← setIntegral_union (Iic_disjoint_Ioc le_rfl), Iic_union_Ioc_eq_Iic hab] exacts [measurableSet_Ioc, ha, hb.mono_set fun _ => And.right] theorem integral_Iic_add_Ioi (h_left : IntegrableOn f (Iic b) μ) (h_right : IntegrableOn f (Ioi b) μ) : (∫ x in Iic b, f x ∂μ) + (∫ x in Ioi b, f x ∂μ) = ∫ (x : ℝ), f x ∂μ := by - convert (integral_union (Iic_disjoint_Ioi <| Eq.le rfl) measurableSet_Ioi h_left h_right).symm + convert (setIntegral_union (Iic_disjoint_Ioi <| Eq.le rfl) measurableSet_Ioi h_left h_right).symm rw [Iic_union_Ioi, Measure.restrict_univ] theorem integral_Iio_add_Ici (h_left : IntegrableOn f (Iio b) μ) (h_right : IntegrableOn f (Ici b) μ) : (∫ x in Iio b, f x ∂μ) + (∫ x in Ici b, f x ∂μ) = ∫ (x : ℝ), f x ∂μ := by - convert (integral_union (Iio_disjoint_Ici <| Eq.le rfl) measurableSet_Ici h_left h_right).symm + convert (setIntegral_union (Iio_disjoint_Ici <| Eq.le rfl) measurableSet_Ici h_left h_right).symm rw [Iio_union_Ici, Measure.restrict_univ] /-- If `μ` is a finite measure then `∫ x in a..b, c ∂μ = (μ (Iic b) - μ (Iic a)) • c`. -/ @@ -1075,7 +1075,7 @@ variable {μ : Measure ℝ} {f : ℝ → E} theorem _root_.MeasureTheory.Integrable.hasSum_intervalIntegral (hfi : Integrable f μ) (y : ℝ) : HasSum (fun n : ℤ => ∫ x in y + n..y + n + 1, f x ∂μ) (∫ x, f x ∂μ) := by simp_rw [integral_of_le (le_add_of_nonneg_right zero_le_one)] - rw [← integral_univ, ← iUnion_Ioc_add_intCast y] + rw [← setIntegral_univ, ← iUnion_Ioc_add_intCast y] exact hasSum_integral_iUnion (fun i => measurableSet_Ioc) (pairwise_disjoint_Ioc_add_intCast y) hfi.integrableOn diff --git a/Mathlib/MeasureTheory/Integral/PeakFunction.lean b/Mathlib/MeasureTheory/Integral/PeakFunction.lean index 845644d23d8fb8..e9adaff6ffe0ad 100644 --- a/Mathlib/MeasureTheory/Integral/PeakFunction.lean +++ b/Mathlib/MeasureTheory/Integral/PeakFunction.lean @@ -147,7 +147,7 @@ theorem tendsto_setIntegral_peak_smul_of_integrableOn_of_tendsto_aux · exact Eventually.of_forall fun x => mul_nonneg (norm_nonneg _) δpos.le · exact Eventually.of_forall ut _ = ∫ x in t, φ i x * δ ∂μ := by - apply setIntegral_congr ht fun x hx => ?_ + apply setIntegral_congr_fun ht fun x hx => ?_ rw [Real.norm_of_nonneg (hφpos _ (hts hx))] _ = (∫ x in t, φ i x ∂μ) * δ := by rw [integral_mul_right] _ ≤ 2 * δ := by gcongr; linarith [(le_abs_self _).trans h'i.le] @@ -171,7 +171,7 @@ theorem tendsto_setIntegral_peak_smul_of_integrableOn_of_tendsto_aux ‖∫ x in s, φ i x • g x ∂μ‖ = ‖(∫ x in s \ u, φ i x • g x ∂μ) + ∫ x in s ∩ u, φ i x • g x ∂μ‖ := by conv_lhs => rw [← diff_union_inter s u] - rw [integral_union disjoint_sdiff_inter (hs.inter u_open.measurableSet) + rw [setIntegral_union disjoint_sdiff_inter (hs.inter u_open.measurableSet) (h''i.mono_set diff_subset) (h''i.mono_set inter_subset_left)] _ ≤ ‖∫ x in s \ u, φ i x • g x ∂μ‖ + ‖∫ x in s ∩ u, φ i x • g x ∂μ‖ := norm_add_le _ _ _ ≤ (δ * ∫ x in s, ‖g x‖ ∂μ) + 2 * δ := add_le_add C B diff --git a/Mathlib/MeasureTheory/Integral/SetIntegral.lean b/Mathlib/MeasureTheory/Integral/SetIntegral.lean index be099131dfc9bd..0174fcb3cd94f0 100644 --- a/Mathlib/MeasureTheory/Integral/SetIntegral.lean +++ b/Mathlib/MeasureTheory/Integral/SetIntegral.lean @@ -21,7 +21,7 @@ and is zero otherwise. Since `∫ x in s, f x ∂μ` is a notation, one can rewrite or apply any theorem about `∫ x, f x ∂μ` directly. In this file we prove some theorems about dependence of `∫ x in s, f x ∂μ` on `s`, e.g. -`integral_union`, `integral_empty`, `integral_univ`. +`setIntegral_union`, `setIntegral_empty`, `setIntegral_univ`. We use the property `IntegrableOn f s μ := Integrable f (μ.restrict s)`, defined in `MeasureTheory.IntegrableOn`. We also defined in that same file a predicate @@ -82,38 +82,50 @@ theorem setIntegral_congr_ae (hs : MeasurableSet s) (h : ∀ᵐ x ∂μ, x ∈ s @[deprecated (since := "2024-04-17")] alias set_integral_congr_ae := setIntegral_congr_ae -theorem setIntegral_congr₀ (hs : NullMeasurableSet s μ) (h : EqOn f g s) : +theorem setIntegral_congr_fun₀ (hs : NullMeasurableSet s μ) (h : EqOn f g s) : ∫ x in s, f x ∂μ = ∫ x in s, g x ∂μ := setIntegral_congr_ae₀ hs <| Eventually.of_forall h +@[deprecated (since := "2024-10-12")] +alias setIntegral_congr₀ := setIntegral_congr_fun₀ + @[deprecated (since := "2024-04-17")] -alias set_integral_congr₀ := setIntegral_congr₀ +alias set_integral_congr₀ := setIntegral_congr_fun₀ -theorem setIntegral_congr (hs : MeasurableSet s) (h : EqOn f g s) : +theorem setIntegral_congr_fun (hs : MeasurableSet s) (h : EqOn f g s) : ∫ x in s, f x ∂μ = ∫ x in s, g x ∂μ := setIntegral_congr_ae hs <| Eventually.of_forall h +@[deprecated (since := "2024-10-12")] +alias setIntegral_congr := setIntegral_congr_fun + @[deprecated (since := "2024-04-17")] -alias set_integral_congr := setIntegral_congr +alias set_integral_congr := setIntegral_congr_fun -theorem setIntegral_congr_set_ae (hst : s =ᵐ[μ] t) : ∫ x in s, f x ∂μ = ∫ x in t, f x ∂μ := by +theorem setIntegral_congr_set (hst : s =ᵐ[μ] t) : ∫ x in s, f x ∂μ = ∫ x in t, f x ∂μ := by rw [Measure.restrict_congr_set hst] +@[deprecated (since := "2024-10-12")] +alias setIntegral_congr_set_ae := setIntegral_congr_set + @[deprecated (since := "2024-04-17")] -alias set_integral_congr_set_ae := setIntegral_congr_set_ae +alias set_integral_congr_set_ae := setIntegral_congr_set theorem integral_union_ae (hst : AEDisjoint μ s t) (ht : NullMeasurableSet t μ) (hfs : IntegrableOn f s μ) (hft : IntegrableOn f t μ) : ∫ x in s ∪ t, f x ∂μ = ∫ x in s, f x ∂μ + ∫ x in t, f x ∂μ := by simp only [IntegrableOn, Measure.restrict_union₀ hst ht, integral_add_measure hfs hft] -theorem integral_union (hst : Disjoint s t) (ht : MeasurableSet t) (hfs : IntegrableOn f s μ) +theorem setIntegral_union (hst : Disjoint s t) (ht : MeasurableSet t) (hfs : IntegrableOn f s μ) (hft : IntegrableOn f t μ) : ∫ x in s ∪ t, f x ∂μ = ∫ x in s, f x ∂μ + ∫ x in t, f x ∂μ := integral_union_ae hst.aedisjoint ht.nullMeasurableSet hfs hft +@[deprecated (since := "2024-10-12")] +alias integral_union := setIntegral_union + theorem integral_diff (ht : MeasurableSet t) (hfs : IntegrableOn f s μ) (hts : t ⊆ s) : ∫ x in s \ t, f x ∂μ = ∫ x in s, f x ∂μ - ∫ x in t, f x ∂μ := by - rw [eq_sub_iff_add_eq, ← integral_union, diff_union_of_subset hts] + rw [eq_sub_iff_add_eq, ← setIntegral_union, diff_union_of_subset hts] exacts [disjoint_sdiff_self_left, ht, hfs.mono_set diff_subset, hfs.mono_set hts] theorem integral_inter_add_diff₀ (ht : NullMeasurableSet t μ) (hfs : IntegrableOn f s μ) : @@ -134,7 +146,7 @@ theorem integral_finset_biUnion {ι : Type*} (t : Finset ι) {s : ι → Set X} · simp · simp only [Finset.coe_insert, Finset.forall_mem_insert, Set.pairwise_insert, Finset.set_biUnion_insert] at hs hf h's ⊢ - rw [integral_union _ _ hf.1 (integrableOn_finset_iUnion.2 hf.2)] + rw [setIntegral_union _ _ hf.1 (integrableOn_finset_iUnion.2 hf.2)] · 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 @@ -147,16 +159,22 @@ theorem integral_fintype_iUnion {ι : Type*} [Fintype ι] {s : ι → Set X} · simp · simp [pairwise_univ, h's] -theorem integral_empty : ∫ x in ∅, f x ∂μ = 0 := by +theorem setIntegral_empty : ∫ x in ∅, f x ∂μ = 0 := by rw [Measure.restrict_empty, integral_zero_measure] -theorem integral_univ : ∫ x in univ, f x ∂μ = ∫ x, f x ∂μ := by rw [Measure.restrict_univ] +@[deprecated (since := "2024-10-12")] +alias integral_empty := setIntegral_empty + +theorem setIntegral_univ : ∫ x in univ, f x ∂μ = ∫ x, f x ∂μ := by rw [Measure.restrict_univ] + +@[deprecated (since := "2024-10-12")] +alias integral_univ := setIntegral_univ theorem integral_add_compl₀ (hs : NullMeasurableSet s μ) (hfi : Integrable f μ) : ∫ x in s, f x ∂μ + ∫ x in sᶜ, f x ∂μ = ∫ x, f x ∂μ := by rw [ ← integral_union_ae disjoint_compl_right.aedisjoint hs.compl hfi.integrableOn hfi.integrableOn, - union_compl_self, integral_univ] + union_compl_self, setIntegral_univ] theorem integral_add_compl (hs : MeasurableSet s) (hfi : Integrable f μ) : ∫ x in s, f x ∂μ + ∫ x in sᶜ, f x ∂μ = ∫ x, f x ∂μ := @@ -328,7 +346,7 @@ theorem integral_union_eq_left_of_ae_aux (ht_eq : ∀ᵐ x ∂μ.restrict t, f x setIntegral_eq_zero_of_forall_eq_zero fun x hx => hx.2 rw [← integral_inter_add_diff hk h's, ← integral_inter_add_diff hk H, A, A, zero_add, zero_add, union_diff_distrib, union_comm] - apply setIntegral_congr_set_ae + apply setIntegral_congr_set rw [union_ae_eq_right] apply measure_mono_null diff_subset rw [measure_zero_iff_ae_nmem] @@ -371,7 +389,7 @@ theorem setIntegral_eq_of_subset_of_ae_diff_eq_zero_aux (hts : s ⊆ t) _ = ∫ x in t \ k, f x ∂μ := by rw [setIntegral_eq_zero_of_forall_eq_zero fun x hx => ?_, zero_add]; exact hx.2 _ = ∫ x in s \ k, f x ∂μ := by - apply setIntegral_congr_set_ae + apply setIntegral_congr_set filter_upwards [h't] with x hx change (x ∈ t \ k) = (x ∈ s \ k) simp only [mem_preimage, mem_singleton_iff, eq_iff_iff, and_congr_left_iff, mem_diff] @@ -430,7 +448,7 @@ coincides with its integral on the whole space. -/ theorem setIntegral_eq_integral_of_ae_compl_eq_zero (h : ∀ᵐ x ∂μ, x ∉ s → f x = 0) : ∫ x in s, f x ∂μ = ∫ x, f x ∂μ := by symm - nth_rw 1 [← integral_univ] + nth_rw 1 [← setIntegral_univ] apply setIntegral_eq_of_subset_of_ae_diff_eq_zero nullMeasurableSet_univ (subset_univ _) filter_upwards [h] with x hx h'x using hx h'x.2 @@ -471,14 +489,14 @@ theorem integral_norm_eq_pos_sub_neg {f : X → ℝ} (hfi : Integrable f μ) : rw [← integral_add_compl₀ h_meas hfi.norm] _ = ∫ x in {x | 0 ≤ f x}, f x ∂μ + ∫ x in {x | 0 ≤ f x}ᶜ, ‖f x‖ ∂μ := by congr 1 - refine setIntegral_congr₀ h_meas fun x hx => ?_ + refine setIntegral_congr_fun₀ h_meas fun x hx => ?_ dsimp only rw [Real.norm_eq_abs, abs_eq_self.mpr _] exact hx _ = ∫ x in {x | 0 ≤ f x}, f x ∂μ - ∫ x in {x | 0 ≤ f x}ᶜ, f x ∂μ := by congr 1 rw [← integral_neg] - refine setIntegral_congr₀ h_meas.compl fun x hx => ?_ + refine setIntegral_congr_fun₀ h_meas.compl fun x hx => ?_ dsimp only rw [Real.norm_eq_abs, abs_eq_neg_self.mpr _] rw [Set.mem_compl_iff, Set.nmem_setOf_iff] at hx @@ -518,7 +536,7 @@ theorem integral_indicatorConstLp [CompleteSpace E] ∫ x, indicatorConstLp p ht hμt e x ∂μ = (μ t).toReal • e := calc ∫ x, indicatorConstLp p ht hμt e x ∂μ = ∫ x in univ, indicatorConstLp p ht hμt e x ∂μ := by - rw [integral_univ] + rw [setIntegral_univ] _ = (μ (t ∩ univ)).toReal • e := setIntegral_indicatorConstLp MeasurableSet.univ ht hμt e _ = (μ t).toReal • e := by rw [inter_univ] @@ -676,31 +694,31 @@ variable [PartialOrder X] {x y : X} theorem integral_Icc_eq_integral_Ioc' (hx : μ {x} = 0) : ∫ t in Icc x y, f t ∂μ = ∫ t in Ioc x y, f t ∂μ := - setIntegral_congr_set_ae (Ioc_ae_eq_Icc' hx).symm + setIntegral_congr_set (Ioc_ae_eq_Icc' hx).symm theorem integral_Icc_eq_integral_Ico' (hy : μ {y} = 0) : ∫ t in Icc x y, f t ∂μ = ∫ t in Ico x y, f t ∂μ := - setIntegral_congr_set_ae (Ico_ae_eq_Icc' hy).symm + setIntegral_congr_set (Ico_ae_eq_Icc' hy).symm theorem integral_Ioc_eq_integral_Ioo' (hy : μ {y} = 0) : ∫ t in Ioc x y, f t ∂μ = ∫ t in Ioo x y, f t ∂μ := - setIntegral_congr_set_ae (Ioo_ae_eq_Ioc' hy).symm + setIntegral_congr_set (Ioo_ae_eq_Ioc' hy).symm theorem integral_Ico_eq_integral_Ioo' (hx : μ {x} = 0) : ∫ t in Ico x y, f t ∂μ = ∫ t in Ioo x y, f t ∂μ := - setIntegral_congr_set_ae (Ioo_ae_eq_Ico' hx).symm + setIntegral_congr_set (Ioo_ae_eq_Ico' hx).symm theorem integral_Icc_eq_integral_Ioo' (hx : μ {x} = 0) (hy : μ {y} = 0) : ∫ t in Icc x y, f t ∂μ = ∫ t in Ioo x y, f t ∂μ := - setIntegral_congr_set_ae (Ioo_ae_eq_Icc' hx hy).symm + setIntegral_congr_set (Ioo_ae_eq_Icc' hx hy).symm theorem integral_Iic_eq_integral_Iio' (hx : μ {x} = 0) : ∫ t in Iic x, f t ∂μ = ∫ t in Iio x, f t ∂μ := - setIntegral_congr_set_ae (Iio_ae_eq_Iic' hx).symm + setIntegral_congr_set (Iio_ae_eq_Iic' hx).symm theorem integral_Ici_eq_integral_Ioi' (hx : μ {x} = 0) : ∫ t in Ici x, f t ∂μ = ∫ t in Ioi x, f t ∂μ := - setIntegral_congr_set_ae (Ioi_ae_eq_Ici' hx).symm + setIntegral_congr_set (Ioi_ae_eq_Ici' hx).symm variable [NoAtoms μ] diff --git a/Mathlib/MeasureTheory/Integral/TorusIntegral.lean b/Mathlib/MeasureTheory/Integral/TorusIntegral.lean index 2ac46ce80a6297..9591233916874a 100644 --- a/Mathlib/MeasureTheory/Integral/TorusIntegral.lean +++ b/Mathlib/MeasureTheory/Integral/TorusIntegral.lean @@ -220,10 +220,10 @@ theorem torusIntegral_succAbove ((Fin.insertNthOrderIso (fun _ => ℝ) i).preimage_Icc _ _).trans (Icc_prod_eq _ _) rw [torusIntegral, ← hem.map_eq, setIntegral_map_equiv, heπ, Measure.volume_eq_prod, setIntegral_prod, circleIntegral_def_Icc] - · refine setIntegral_congr measurableSet_Icc fun θ _ => ?_ + · refine setIntegral_congr_fun measurableSet_Icc fun θ _ => ?_ simp (config := { unfoldPartialApp := true }) only [e, torusIntegral, ← integral_smul, deriv_circleMap, i.prod_univ_succAbove _, smul_smul, torusMap, circleMap_zero] - refine setIntegral_congr measurableSet_Icc fun Θ _ => ?_ + refine setIntegral_congr_fun measurableSet_Icc fun Θ _ => ?_ simp only [MeasurableEquiv.piFinSuccAbove_symm_apply, i.insertNth_apply_same, i.insertNth_apply_succAbove, (· ∘ ·), Fin.insertNthEquiv, Equiv.coe_fn_mk] congr 2 diff --git a/Mathlib/MeasureTheory/Measure/Lebesgue/Integral.lean b/Mathlib/MeasureTheory/Measure/Lebesgue/Integral.lean index 15ee5ceb0977a7..1b31285651c1ca 100644 --- a/Mathlib/MeasureTheory/Measure/Lebesgue/Integral.lean +++ b/Mathlib/MeasureTheory/Measure/Lebesgue/Integral.lean @@ -95,7 +95,7 @@ theorem integral_comp_neg_Ioi {E : Type*} [NormedAddCommGroup E] [NormedSpace theorem integral_comp_abs {f : ℝ → ℝ} : ∫ x, f |x| = 2 * ∫ x in Ioi (0 : ℝ), f x := by have eq : ∫ (x : ℝ) in Ioi 0, f |x| = ∫ (x : ℝ) in Ioi 0, f x := by - refine setIntegral_congr measurableSet_Ioi (fun _ hx => ?_) + refine setIntegral_congr_fun measurableSet_Ioi (fun _ hx => ?_) rw [abs_eq_self.mpr (le_of_lt (by exact hx))] by_cases hf : IntegrableOn (fun x => f |x|) (Ioi 0) · have int_Iic : IntegrableOn (fun x ↦ f |x|) (Iic 0) := by @@ -106,13 +106,13 @@ theorem integral_comp_abs {f : ℝ → ℝ} : exact integrableOn_Ici_iff_integrableOn_Ioi.mpr hf calc _ = (∫ x in Iic 0, f |x|) + ∫ x in Ioi 0, f |x| := by - rw [← integral_union (Iic_disjoint_Ioi le_rfl) measurableSet_Ioi int_Iic hf, + rw [← setIntegral_union (Iic_disjoint_Ioi le_rfl) measurableSet_Ioi int_Iic hf, Iic_union_Ioi, restrict_univ] _ = 2 * ∫ x in Ioi 0, f x := by rw [two_mul, eq] congr! 1 rw [← neg_zero, ← integral_comp_neg_Iic, neg_zero] - refine setIntegral_congr measurableSet_Iic (fun _ hx => ?_) + refine setIntegral_congr_fun measurableSet_Iic (fun _ hx => ?_) rw [abs_eq_neg_self.mpr (by exact hx)] · have : ¬ Integrable (fun x => f |x|) := by contrapose! hf diff --git a/Mathlib/MeasureTheory/Measure/Lebesgue/VolumeOfBalls.lean b/Mathlib/MeasureTheory/Measure/Lebesgue/VolumeOfBalls.lean index 7e7bce6be7fc84..8cde3b70935662 100644 --- a/Mathlib/MeasureTheory/Measure/Lebesgue/VolumeOfBalls.lean +++ b/Mathlib/MeasureTheory/Measure/Lebesgue/VolumeOfBalls.lean @@ -48,10 +48,10 @@ theorem MeasureTheory.measure_unitBall_eq_integral_div_gamma {E : Type*} {p : μ (Metric.ball 0 1) = .ofReal ((∫ (x : E), Real.exp (- ‖x‖ ^ p) ∂μ) / Real.Gamma (finrank ℝ E / p + 1)) := by obtain hE | hE := subsingleton_or_nontrivial E - · rw [(Metric.nonempty_ball.mpr zero_lt_one).eq_zero, ← integral_univ, Set.univ_nonempty.eq_zero, - integral_singleton, finrank_zero_of_subsingleton, Nat.cast_zero, zero_div, zero_add, - Real.Gamma_one, div_one, norm_zero, Real.zero_rpow (ne_of_gt hp), neg_zero, Real.exp_zero, - smul_eq_mul, mul_one, ofReal_toReal (measure_ne_top μ {0})] + · rw [(Metric.nonempty_ball.mpr zero_lt_one).eq_zero, ← setIntegral_univ, + Set.univ_nonempty.eq_zero, integral_singleton, finrank_zero_of_subsingleton, Nat.cast_zero, + zero_div, zero_add, Real.Gamma_one, div_one, norm_zero, Real.zero_rpow hp.ne', neg_zero, + Real.exp_zero, smul_eq_mul, mul_one, ofReal_toReal (measure_ne_top μ {0})] · have : (0 : ℝ) < finrank ℝ E := Nat.cast_pos.mpr finrank_pos have : ((∫ y in Set.Ioi (0 : ℝ), y ^ (finrank ℝ E - 1) • Real.exp (-y ^ p)) / Real.Gamma ((finrank ℝ E) / p + 1)) * (finrank ℝ E) = 1 := by diff --git a/Mathlib/MeasureTheory/Measure/Tilted.lean b/Mathlib/MeasureTheory/Measure/Tilted.lean index 0dcb5897a59371..78793a1d887328 100644 --- a/Mathlib/MeasureTheory/Measure/Tilted.lean +++ b/Mathlib/MeasureTheory/Measure/Tilted.lean @@ -235,7 +235,7 @@ alias set_integral_tilted := setIntegral_tilted lemma integral_tilted (f : α → ℝ) (g : α → E) : ∫ x, g x ∂(μ.tilted f) = ∫ x, (exp (f x) / ∫ x, exp (f x) ∂μ) • (g x) ∂μ := by - rw [← integral_univ, setIntegral_tilted' f g MeasurableSet.univ, integral_univ] + rw [← setIntegral_univ, setIntegral_tilted' f g MeasurableSet.univ, setIntegral_univ] end integral diff --git a/Mathlib/NumberTheory/LSeries/AbstractFuncEq.lean b/Mathlib/NumberTheory/LSeries/AbstractFuncEq.lean index 64d09847b3f9e2..5f25d59164fa6f 100644 --- a/Mathlib/NumberTheory/LSeries/AbstractFuncEq.lean +++ b/Mathlib/NumberTheory/LSeries/AbstractFuncEq.lean @@ -226,8 +226,8 @@ theorem functional_equation (s : ℂ) : have step3 := mellin_const_smul (fun t ↦ (t : ℂ) ^ (-P.k : ℂ) • P.g (1 / t)) (P.k - s) P.ε rw [step2] at step3 rw [← step3] - -- now the integrand matches `P.h_feq'` on `Ioi 0`, so we can apply `setIntegral_congr` - refine setIntegral_congr measurableSet_Ioi (fun t ht ↦ ?_) + -- now the integrand matches `P.h_feq'` on `Ioi 0`, so we can apply `setIntegral_congr_fun` + refine setIntegral_congr_fun measurableSet_Ioi (fun t ht ↦ ?_) simp_rw [P.h_feq' t ht, ← mul_smul] -- some simple `cpow` arithmetic to finish rw [cpow_neg, ofReal_cpow (le_of_lt ht)] @@ -343,7 +343,7 @@ lemma f_modif_aux2 [CompleteSpace E] {s : ℂ} (hs : P.k < re s) : _ = ∫ (x : ℝ) in Ioi 0, (x : ℂ) ^ (s - 1) • ((Ioo 0 1).indicator (fun t : ℝ ↦ P.f₀ - (P.ε * ↑(t ^ (-P.k))) • P.g₀) x + ({1} : Set ℝ).indicator (fun _ ↦ P.f₀ - P.f 1) x) := - setIntegral_congr measurableSet_Ioi (fun x hx ↦ by simp [f_modif_aux1 P hx]) + setIntegral_congr_fun measurableSet_Ioi (fun x hx ↦ by simp [f_modif_aux1 P hx]) _ = ∫ (x : ℝ) in Ioi 0, (x : ℂ) ^ (s - 1) • ((Ioo 0 1).indicator (fun t : ℝ ↦ P.f₀ - (P.ε * ↑(t ^ (-P.k))) • P.g₀) x) := by refine setIntegral_congr_ae measurableSet_Ioi (eventually_of_mem (U := {1}ᶜ) @@ -353,7 +353,7 @@ lemma f_modif_aux2 [CompleteSpace E] {s : ℂ} (hs : P.k < re s) : simp_rw [← indicator_smul, setIntegral_indicator measurableSet_Ioo, inter_eq_right.mpr Ioo_subset_Ioi_self, integral_Ioc_eq_integral_Ioo] _ = ∫ x : ℝ in Ioc 0 1, ((x : ℂ) ^ (s - 1) • P.f₀ - P.ε • (x : ℂ) ^ (s - P.k - 1) • P.g₀) := by - refine setIntegral_congr measurableSet_Ioc (fun x ⟨hx, _⟩ ↦ ?_) + refine setIntegral_congr_fun measurableSet_Ioc (fun x ⟨hx, _⟩ ↦ ?_) rw [ofReal_cpow hx.le, ofReal_neg, smul_sub, ← mul_smul, mul_comm, mul_assoc, mul_smul, mul_comm, ← cpow_add _ _ (ofReal_ne_zero.mpr hx.ne'), ← sub_eq_add_neg, sub_right_comm] _ = (∫ (x : ℝ) in Ioc 0 1, (x : ℂ) ^ (s - 1)) • P.f₀ diff --git a/Mathlib/NumberTheory/LSeries/MellinEqDirichlet.lean b/Mathlib/NumberTheory/LSeries/MellinEqDirichlet.lean index 7f8d7a14ef207f..445256d8910b79 100644 --- a/Mathlib/NumberTheory/LSeries/MellinEqDirichlet.lean +++ b/Mathlib/NumberTheory/LSeries/MellinEqDirichlet.lean @@ -23,7 +23,7 @@ lemma hasSum_mellin {a : ι → ℂ} {p : ι → ℝ} {F : ℝ → ℂ} {s : ℂ (hF : ∀ t ∈ Ioi 0, HasSum (fun i ↦ a i * rexp (-p i * t)) (F t)) (h_sum : Summable fun i ↦ ‖a i‖ / (p i) ^ s.re) : HasSum (fun i ↦ Gamma s * a i / p i ^ s) (mellin F s) := by - simp_rw [mellin, smul_eq_mul, ← setIntegral_congr measurableSet_Ioi + simp_rw [mellin, smul_eq_mul, ← setIntegral_congr_fun measurableSet_Ioi (fun t ht ↦ congr_arg _ (hF t ht).tsum_eq), ← tsum_mul_left] convert hasSum_integral_of_summable_integral_norm (F := fun i t ↦ t ^ (s - 1) * (a i * rexp (-p i * t))) (fun i ↦ ?_) ?_ using 2 with i @@ -56,7 +56,7 @@ lemma hasSum_mellin {a : ι → ℂ} {p : ι → ℝ} {F : ℝ → ℂ} {s : ℂ have := Real.integral_rpow_mul_exp_neg_mul_Ioi hs hpi simp_rw [← neg_mul (p i), one_div, inv_rpow hpi.le, ← div_eq_inv_mul] at this rw [norm_of_nonneg (integral_nonneg (fun _ ↦ norm_nonneg _)), ← this] - refine setIntegral_congr measurableSet_Ioi (fun t ht ↦ ?_) + refine setIntegral_congr_fun measurableSet_Ioi (fun t ht ↦ ?_) rw [norm_mul, norm_real, Real.norm_eq_abs, Real.abs_exp, Complex.norm_eq_abs, abs_cpow_eq_rpow_re_of_pos ht, sub_re, one_re] diff --git a/Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean b/Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean index 5f9e2e892db191..3655fb84066ea2 100644 --- a/Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean +++ b/Mathlib/Probability/Kernel/Disintegration/CDFToKernel.lean @@ -223,7 +223,7 @@ lemma integral_stieltjesOfMeasurableRat [IsFiniteKernel κ] (hf : IsRatCondKerne (a : α) (x : ℝ) : ∫ b, stieltjesOfMeasurableRat f hf.measurable (a, b) x ∂(ν a) = (κ a (univ ×ˢ Iic x)).toReal := by - rw [← integral_univ, setIntegral_stieltjesOfMeasurableRat hf _ _ MeasurableSet.univ] + rw [← setIntegral_univ, setIntegral_stieltjesOfMeasurableRat hf _ _ MeasurableSet.univ] end stieltjesOfMeasurableRat diff --git a/Mathlib/Probability/Kernel/Disintegration/CondCDF.lean b/Mathlib/Probability/Kernel/Disintegration/CondCDF.lean index 22bfd49d0e4107..a5c415461bb5bf 100644 --- a/Mathlib/Probability/Kernel/Disintegration/CondCDF.lean +++ b/Mathlib/Probability/Kernel/Disintegration/CondCDF.lean @@ -192,7 +192,7 @@ alias set_integral_preCDF_fst := setIntegral_preCDF_fst lemma integral_preCDF_fst (ρ : Measure (α × ℝ)) (r : ℚ) [IsFiniteMeasure ρ] : ∫ x, (preCDF ρ r x).toReal ∂ρ.fst = (ρ.IicSnd r univ).toReal := by - rw [← integral_univ, setIntegral_preCDF_fst ρ _ MeasurableSet.univ] + rw [← setIntegral_univ, setIntegral_preCDF_fst ρ _ MeasurableSet.univ] lemma integrable_preCDF (ρ : Measure (α × ℝ)) [IsFiniteMeasure ρ] (x : ℚ) : Integrable (fun a ↦ (preCDF ρ x a).toReal) ρ.fst := by diff --git a/Mathlib/Probability/Kernel/Disintegration/Density.lean b/Mathlib/Probability/Kernel/Disintegration/Density.lean index 1e1d4fe17ac122..61538fa7f84ae9 100644 --- a/Mathlib/Probability/Kernel/Disintegration/Density.lean +++ b/Mathlib/Probability/Kernel/Disintegration/Density.lean @@ -276,7 +276,7 @@ alias set_integral_densityProcess := setIntegral_densityProcess lemma integral_densityProcess (hκν : fst κ ≤ ν) [IsFiniteKernel ν] (n : ℕ) (a : α) {s : Set β} (hs : MeasurableSet s) : ∫ x, densityProcess κ ν n a x s ∂(ν a) = (κ a (univ ×ˢ s)).toReal := by - rw [← integral_univ, setIntegral_densityProcess hκν _ _ hs MeasurableSet.univ] + rw [← setIntegral_univ, setIntegral_densityProcess hκν _ _ hs MeasurableSet.univ] lemma setIntegral_densityProcess_of_le (hκν : fst κ ≤ ν) [IsFiniteKernel ν] {n m : ℕ} (hnm : n ≤ m) (a : α) {s : Set β} (hs : MeasurableSet s) @@ -576,7 +576,7 @@ alias set_integral_density_of_measurableSet := setIntegral_density_of_measurable lemma integral_density (hκν : fst κ ≤ ν) [IsFiniteKernel ν] (a : α) {s : Set β} (hs : MeasurableSet s) : ∫ x, density κ ν a x s ∂(ν a) = (κ a (univ ×ˢ s)).toReal := by - rw [← integral_univ, setIntegral_density_of_measurableSet hκν 0 a hs MeasurableSet.univ] + rw [← setIntegral_univ, setIntegral_density_of_measurableSet hκν 0 a hs MeasurableSet.univ] lemma setIntegral_density (hκν : fst κ ≤ ν) [IsFiniteKernel ν] (a : α) {s : Set β} (hs : MeasurableSet s) {A : Set γ} (hA : MeasurableSet A) : diff --git a/Mathlib/Probability/Martingale/BorelCantelli.lean b/Mathlib/Probability/Martingale/BorelCantelli.lean index fe55abdba94f9a..4897ac3d82a8ea 100644 --- a/Mathlib/Probability/Martingale/BorelCantelli.lean +++ b/Mathlib/Probability/Martingale/BorelCantelli.lean @@ -126,7 +126,7 @@ theorem Submartingale.stoppedValue_leastGE_eLpNorm_le [IsFiniteMeasure μ] (hf : eLpNorm (stoppedValue f (leastGE f r i)) 1 μ ≤ 2 * μ Set.univ * ENNReal.ofReal (r + R) := by refine eLpNorm_one_le_of_le' ((hf.stoppedValue_leastGE r).integrable _) ?_ (norm_stoppedValue_leastGE_le hr hf0 hbdd i) - rw [← integral_univ] + rw [← setIntegral_univ] refine le_trans ?_ ((hf.stoppedValue_leastGE r).setIntegral_le (zero_le _) MeasurableSet.univ) simp_rw [stoppedValue, leastGE, hitting_of_le le_rfl, hf0, integral_zero', le_rfl] diff --git a/Mathlib/Probability/Martingale/Convergence.lean b/Mathlib/Probability/Martingale/Convergence.lean index 9ed222f99b9a37..42764ff3c943d5 100644 --- a/Mathlib/Probability/Martingale/Convergence.lean +++ b/Mathlib/Probability/Martingale/Convergence.lean @@ -399,8 +399,8 @@ theorem Integrable.tendsto_ae_condexp (hg : Integrable g μ) setIntegral_trim hle stronglyMeasurable_limitProcess htmeas.compl, hgeq, hheq, ← setIntegral_trim hle hgmeas htmeas, ← setIntegral_trim hle stronglyMeasurable_limitProcess htmeas, ← integral_trim hle hgmeas, ← - integral_trim hle stronglyMeasurable_limitProcess, ← integral_univ, - this 0 _ MeasurableSet.univ, integral_univ, ht (measure_lt_top _ _)] + integral_trim hle stronglyMeasurable_limitProcess, ← setIntegral_univ, + this 0 _ MeasurableSet.univ, setIntegral_univ, ht (measure_lt_top _ _)] · rintro f hf hfmeas heq - rw [integral_iUnion (fun n => hle _ (hfmeas n)) hf hg.integrableOn, integral_iUnion (fun n => hle _ (hfmeas n)) hf hlimint.integrableOn] diff --git a/Mathlib/Probability/Martingale/OptionalStopping.lean b/Mathlib/Probability/Martingale/OptionalStopping.lean index fee8f4ea1c1a39..c047618b86b018 100644 --- a/Mathlib/Probability/Martingale/OptionalStopping.lean +++ b/Mathlib/Probability/Martingale/OptionalStopping.lean @@ -144,8 +144,8 @@ theorem maximal_ineq [IsFiniteMeasure μ] (hsub : Submartingale f 𝒢 μ) (hnon (∫ ω in {ω | ↑ε ≤ (range (n+1)).sup' nonempty_range_succ fun k => f k ω}, f n ω ∂μ) + ENNReal.ofReal (∫ ω in {ω | ((range (n+1)).sup' nonempty_range_succ fun k => f k ω) < ↑ε}, f n ω ∂μ) := by - rw [← ENNReal.ofReal_add, ← integral_union] - · rw [← integral_univ] + rw [← ENNReal.ofReal_add, ← setIntegral_union] + · rw [← setIntegral_univ] convert rfl ext ω change (ε : ℝ) ≤ _ ∨ _ < (ε : ℝ) ↔ _ @@ -186,8 +186,8 @@ theorem maximal_ineq [IsFiniteMeasure μ] (hsub : Submartingale f 𝒢 μ) (hnon ((not_le.2 hω) ((le_sup'_iff _).2 ⟨m, mem_range.2 (Nat.lt_succ_of_le hm.2), hεm⟩)) simp_rw [stoppedValue, this, le_rfl] _ = ENNReal.ofReal (∫ ω, stoppedValue f (hitting f {y : ℝ | ↑ε ≤ y} 0 n) ω ∂μ) := by - rw [← ENNReal.ofReal_add, ← integral_union] - · rw [← integral_univ (μ := μ)] + rw [← ENNReal.ofReal_add, ← setIntegral_union] + · rw [← setIntegral_univ (μ := μ)] convert rfl ext ω change _ ↔ (ε : ℝ) ≤ _ ∨ _ < (ε : ℝ) diff --git a/Mathlib/Probability/Martingale/Upcrossing.lean b/Mathlib/Probability/Martingale/Upcrossing.lean index 9c8e55e651df7c..3550483556921e 100644 --- a/Mathlib/Probability/Martingale/Upcrossing.lean +++ b/Mathlib/Probability/Martingale/Upcrossing.lean @@ -389,7 +389,7 @@ theorem Submartingale.sum_mul_upcrossingStrat_le [IsFiniteMeasure μ] (hf : Subm have h₁ : (0 : ℝ) ≤ μ[∑ k ∈ Finset.range n, (1 - upcrossingStrat a b f N k) * (f (k + 1) - f k)] := by have := (hf.sum_sub_upcrossingStrat_mul a b N).setIntegral_le (zero_le n) MeasurableSet.univ - rw [integral_univ, integral_univ] at this + rw [setIntegral_univ, setIntegral_univ] at this refine le_trans ?_ this simp only [Finset.range_zero, Finset.sum_empty, integral_zero', le_refl] have h₂ : μ[∑ k ∈ Finset.range n, (1 - upcrossingStrat a b f N k) * (f (k + 1) - f k)] = From 0405d97af3ed0666079ab4ff41eab850d2867a17 Mon Sep 17 00:00:00 2001 From: YnirPaz Date: Sat, 12 Oct 2024 08:01:28 +0000 Subject: [PATCH 049/425] feat(SetTheory/Cardinal/Basic): congruency theorems for cardinalities of sigmas (#16824) Add various congruency lemmas for `Cardinal.mk`. Co-authored-by: Eric Wieser --- Mathlib/SetTheory/Cardinal/Basic.lean | 56 +++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/Mathlib/SetTheory/Cardinal/Basic.lean b/Mathlib/SetTheory/Cardinal/Basic.lean index 2b1f5b5347d2fd..e6a0f29565545d 100644 --- a/Mathlib/SetTheory/Cardinal/Basic.lean +++ b/Mathlib/SetTheory/Cardinal/Basic.lean @@ -852,6 +852,34 @@ theorem iSup_le_sum {ι} (f : ι → Cardinal) : iSup f ≤ sum f := theorem mk_sigma {ι} (f : ι → Type*) : #(Σ i, f i) = sum fun i => #(f i) := mk_congr <| Equiv.sigmaCongrRight fun _ => outMkEquiv.symm +theorem mk_sigma_congr_lift {ι : Type v} {ι' : Type v'} {f : ι → Type w} {g : ι' → Type w'} + (e : ι ≃ ι') (h : ∀ i, lift.{w'} #(f i) = lift.{w} #(g (e i))) : + lift.{max v' w'} #(Σ i, f i) = lift.{max v w} #(Σ i, g i) := + Cardinal.lift_mk_eq'.2 ⟨.sigmaCongr e fun i ↦ Classical.choice <| Cardinal.lift_mk_eq'.1 (h i)⟩ + +theorem mk_sigma_congr {ι ι' : Type u} {f : ι → Type v} {g : ι' → Type v} (e : ι ≃ ι') + (h : ∀ i, #(f i) = #(g (e i))) : #(Σ i, f i) = #(Σ i, g i) := + mk_congr <| Equiv.sigmaCongr e fun i ↦ Classical.choice <| Cardinal.eq.mp (h i) + +/-- Similar to `mk_sigma_congr` with indexing types in different universes. This is not a strict +generalization. -/ +theorem mk_sigma_congr' {ι : Type u} {ι' : Type v} {f : ι → Type max w (max u v)} + {g : ι' → Type max w (max u v)} (e : ι ≃ ι') + (h : ∀ i, #(f i) = #(g (e i))) : #(Σ i, f i) = #(Σ i, g i) := + mk_congr <| Equiv.sigmaCongr e fun i ↦ Classical.choice <| Cardinal.eq.mp (h i) + +theorem mk_sigma_congrRight {ι : Type u} {f g : ι → Type v} (h : ∀ i, #(f i) = #(g i)) : + #(Σ i, f i) = #(Σ i, g i) := + mk_sigma_congr (Equiv.refl ι) h + +theorem mk_psigma_congrRight {ι : Type u} {f g : ι → Type v} (h : ∀ i, #(f i) = #(g i)) : + #(Σ' i, f i) = #(Σ' i, g i) := + mk_congr <| .psigmaCongrRight fun i => Classical.choice <| Cardinal.eq.mp (h i) + +theorem mk_psigma_congrRight_prop {ι : Prop} {f g : ι → Type v} (h : ∀ i, #(f i) = #(g i)) : + #(Σ' i, f i) = #(Σ' i, g i) := + mk_congr <| .psigmaCongrRight fun i => Classical.choice <| Cardinal.eq.mp (h i) + theorem mk_sigma_arrow {ι} (α : Type*) (f : ι → Type*) : #(Sigma f → α) = #(Π i, f i → α) := mk_congr <| Equiv.piCurry fun _ _ ↦ α @@ -1098,6 +1126,34 @@ def prod {ι : Type u} (f : ι → Cardinal) : Cardinal := theorem mk_pi {ι : Type u} (α : ι → Type v) : #(Π i, α i) = prod fun i => #(α i) := mk_congr <| Equiv.piCongrRight fun _ => outMkEquiv.symm +theorem mk_pi_congr_lift {ι : Type v} {ι' : Type v'} {f : ι → Type w} {g : ι' → Type w'} + (e : ι ≃ ι') (h : ∀ i, lift.{w'} #(f i) = lift.{w} #(g (e i))) : + lift.{max v' w'} #(Π i, f i) = lift.{max v w} #(Π i, g i) := + Cardinal.lift_mk_eq'.2 ⟨.piCongr e fun i ↦ Classical.choice <| Cardinal.lift_mk_eq'.1 (h i)⟩ + +theorem mk_pi_congr {ι ι' : Type u} {f : ι → Type v} {g : ι' → Type v} (e : ι ≃ ι') + (h : ∀ i, #(f i) = #(g (e i))) : #(Π i, f i) = #(Π i, g i) := + mk_congr <| Equiv.piCongr e fun i ↦ Classical.choice <| Cardinal.eq.mp (h i) + +theorem mk_pi_congr_prop {ι ι' : Prop} {f : ι → Type v} {g : ι' → Type v} (e : ι ↔ ι') + (h : ∀ i, #(f i) = #(g (e.mp i))) : #(Π i, f i) = #(Π i, g i) := + mk_congr <| Equiv.piCongr (.ofIff e) fun i ↦ Classical.choice <| Cardinal.eq.mp (h i) + +/-- Similar to `mk_pi_congr` with indexing types in different universes. This is not a strict +generalization. -/ +theorem mk_pi_congr' {ι : Type u} {ι' : Type v} {f : ι → Type max w (max u v)} + {g : ι' → Type max w (max u v)} (e : ι ≃ ι') + (h : ∀ i, #(f i) = #(g (e i))) : #(Π i, f i) = #(Π i, g i) := + mk_congr <| Equiv.piCongr e fun i ↦ Classical.choice <| Cardinal.eq.mp (h i) + +theorem mk_pi_congrRight {ι : Type u} {f g : ι → Type v} (h : ∀ i, #(f i) = #(g i)) : + #(Π i, f i) = #(Π i, g i) := + mk_pi_congr (Equiv.refl ι) h + +theorem mk_pi_congrRight_prop {ι : Prop} {f g : ι → Type v} (h : ∀ i, #(f i) = #(g i)) : + #(Π i, f i) = #(Π i, g i) := + mk_pi_congr_prop Iff.rfl h + @[simp] theorem prod_const (ι : Type u) (a : Cardinal.{v}) : (prod fun _ : ι => a) = lift.{u} a ^ lift.{v} #ι := From 9defbc67f123f0828be81330176f2551072158a8 Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Sat, 12 Oct 2024 08:21:56 +0000 Subject: [PATCH 050/425] chore: bump to nightly-2024-10-12 --- lean-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lean-toolchain b/lean-toolchain index 101e9ee14ef77c..f3a11d3ea4e638 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-11 +leanprover/lean4:nightly-2024-10-12 From 90cf978d2237de99eb5a639301b5b0b3f913d744 Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Sat, 12 Oct 2024 08:56:40 +0000 Subject: [PATCH 051/425] chore(Order/Bounds): move defs to a new file (#17676) Also generalize definitions to `LE`. --- Mathlib.lean | 1 + Mathlib/Algebra/CharP/Defs.lean | 1 + Mathlib/Data/Int/GCD.lean | 4 ++- Mathlib/Order/Bounds/Basic.lean | 54 +++----------------------------- Mathlib/Order/Bounds/Defs.lean | 55 +++++++++++++++++++++++++++++++++ Mathlib/Order/WellFounded.lean | 2 +- 6 files changed, 66 insertions(+), 51 deletions(-) create mode 100644 Mathlib/Order/Bounds/Defs.lean diff --git a/Mathlib.lean b/Mathlib.lean index f81b6f5cdb74f3..9c48ed611ec6c0 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3571,6 +3571,7 @@ import Mathlib.Order.Booleanisation import Mathlib.Order.Bounded import Mathlib.Order.BoundedOrder import Mathlib.Order.Bounds.Basic +import Mathlib.Order.Bounds.Defs import Mathlib.Order.Bounds.OrderIso import Mathlib.Order.Category.BddDistLat import Mathlib.Order.Category.BddLat diff --git a/Mathlib/Algebra/CharP/Defs.lean b/Mathlib/Algebra/CharP/Defs.lean index 34b448a97de44b..e597077cdd70eb 100644 --- a/Mathlib/Algebra/CharP/Defs.lean +++ b/Mathlib/Algebra/CharP/Defs.lean @@ -12,6 +12,7 @@ import Mathlib.Data.Nat.Find import Mathlib.Data.Nat.Prime.Defs import Mathlib.Data.ULift import Mathlib.Tactic.NormNum.Basic +import Mathlib.Order.Interval.Set.Basic /-! # Characteristic of semirings diff --git a/Mathlib/Data/Int/GCD.lean b/Mathlib/Data/Int/GCD.lean index 6c4e2b4ad9ed91..eccc02d840c40e 100644 --- a/Mathlib/Data/Int/GCD.lean +++ b/Mathlib/Data/Int/GCD.lean @@ -7,7 +7,9 @@ import Mathlib.Algebra.Group.Int import Mathlib.Algebra.GroupWithZero.Semiconj import Mathlib.Algebra.Group.Commute.Units import Mathlib.Data.Nat.GCD.Basic -import Mathlib.Order.Bounds.Basic +import Mathlib.Order.Lattice +import Mathlib.Data.Set.Operations +import Mathlib.Order.Bounds.Defs /-! # Extended GCD and divisibility over ℤ diff --git a/Mathlib/Order/Bounds/Basic.lean b/Mathlib/Order/Bounds/Basic.lean index 86984514ba3e71..ad3019a2ea838f 100644 --- a/Mathlib/Order/Bounds/Basic.lean +++ b/Mathlib/Order/Bounds/Basic.lean @@ -3,26 +3,19 @@ Copyright (c) 2017 Johannes Hölzl. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Johannes Hölzl, Yury Kudryashov -/ -import Mathlib.Order.Interval.Set.Basic import Mathlib.Data.Set.NAry +import Mathlib.Order.Bounds.Defs import Mathlib.Order.Directed +import Mathlib.Order.Interval.Set.Basic /-! # Upper / lower bounds -In this file we define: -* `upperBounds`, `lowerBounds` : the set of upper bounds (resp., lower bounds) of a set; -* `BddAbove s`, `BddBelow s` : the set `s` is bounded above (resp., below), i.e., the set of upper - (resp., lower) bounds of `s` is nonempty; -* `IsLeast s a`, `IsGreatest s a` : `a` is a least (resp., greatest) element of `s`; - for a partial order, it is unique if exists; -* `IsLUB s a`, `IsGLB s a` : `a` is a least upper bound (resp., a greatest lower bound) - of `s`; for a partial order, it is unique if exists. -We also prove various lemmas about monotonicity, behaviour under `∪`, `∩`, `insert`, and provide -formulas for `∅`, `univ`, and intervals. +In this file we prove various lemmas about upper/lower bounds of a set: +monotonicity, behaviour under `∪`, `∩`, `insert`, +and provide formulas for `∅`, `univ`, and intervals. -/ - open Function Set open OrderDual (toDual ofDual) @@ -35,43 +28,6 @@ section variable [Preorder α] [Preorder β] {s t : Set α} {a b : α} -/-! -### Definitions --/ - - -/-- The set of upper bounds of a set. -/ -def upperBounds (s : Set α) : Set α := - { x | ∀ ⦃a⦄, a ∈ s → a ≤ x } - -/-- The set of lower bounds of a set. -/ -def lowerBounds (s : Set α) : Set α := - { x | ∀ ⦃a⦄, a ∈ s → x ≤ a } - -/-- A set is bounded above if there exists an upper bound. -/ -def BddAbove (s : Set α) := - (upperBounds s).Nonempty - -/-- A set is bounded below if there exists a lower bound. -/ -def BddBelow (s : Set α) := - (lowerBounds s).Nonempty - -/-- `a` is a least element of a set `s`; for a partial order, it is unique if exists. -/ -def IsLeast (s : Set α) (a : α) : Prop := - a ∈ s ∧ a ∈ lowerBounds s - -/-- `a` is a greatest element of a set `s`; for a partial order, it is unique if exists. -/ -def IsGreatest (s : Set α) (a : α) : Prop := - a ∈ s ∧ a ∈ upperBounds s - -/-- `a` is a least upper bound of a set `s`; for a partial order, it is unique if exists. -/ -def IsLUB (s : Set α) : α → Prop := - IsLeast (upperBounds s) - -/-- `a` is a greatest lower bound of a set `s`; for a partial order, it is unique if exists. -/ -def IsGLB (s : Set α) : α → Prop := - IsGreatest (lowerBounds s) - theorem mem_upperBounds : a ∈ upperBounds s ↔ ∀ x ∈ s, x ≤ a := Iff.rfl diff --git a/Mathlib/Order/Bounds/Defs.lean b/Mathlib/Order/Bounds/Defs.lean new file mode 100644 index 00000000000000..3ade7ed08f03da --- /dev/null +++ b/Mathlib/Order/Bounds/Defs.lean @@ -0,0 +1,55 @@ +/- +Copyright (c) 2017 Johannes Hölzl. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Johannes Hölzl, Yury Kudryashov +-/ +import Mathlib.Data.Set.Defs +import Mathlib.Tactic.TypeStar + +/-! +# Definitions about upper/lower bounds + +In this file we define: +* `upperBounds`, `lowerBounds` : the set of upper bounds (resp., lower bounds) of a set; +* `BddAbove s`, `BddBelow s` : the set `s` is bounded above (resp., below), i.e., the set of upper + (resp., lower) bounds of `s` is nonempty; +* `IsLeast s a`, `IsGreatest s a` : `a` is a least (resp., greatest) element of `s`; + for a partial order, it is unique if exists; +* `IsLUB s a`, `IsGLB s a` : `a` is a least upper bound (resp., a greatest lower bound) + of `s`; for a partial order, it is unique if exists. +-/ + +variable {α : Type*} [LE α] + +/-- The set of upper bounds of a set. -/ +def upperBounds (s : Set α) : Set α := + { x | ∀ ⦃a⦄, a ∈ s → a ≤ x } + +/-- The set of lower bounds of a set. -/ +def lowerBounds (s : Set α) : Set α := + { x | ∀ ⦃a⦄, a ∈ s → x ≤ a } + +/-- A set is bounded above if there exists an upper bound. -/ +def BddAbove (s : Set α) := + (upperBounds s).Nonempty + +/-- A set is bounded below if there exists a lower bound. -/ +def BddBelow (s : Set α) := + (lowerBounds s).Nonempty + +/-- `a` is a least element of a set `s`; for a partial order, it is unique if exists. -/ +def IsLeast (s : Set α) (a : α) : Prop := + a ∈ s ∧ a ∈ lowerBounds s + +/-- `a` is a greatest element of a set `s`; for a partial order, it is unique if exists. -/ +def IsGreatest (s : Set α) (a : α) : Prop := + a ∈ s ∧ a ∈ upperBounds s + +/-- `a` is a least upper bound of a set `s`; for a partial order, it is unique if exists. -/ +def IsLUB (s : Set α) : α → Prop := + IsLeast (upperBounds s) + +/-- `a` is a greatest lower bound of a set `s`; for a partial order, it is unique if exists. -/ +def IsGLB (s : Set α) : α → Prop := + IsGreatest (lowerBounds s) + diff --git a/Mathlib/Order/WellFounded.lean b/Mathlib/Order/WellFounded.lean index 613d28890f0783..1c5e905b8da099 100644 --- a/Mathlib/Order/WellFounded.lean +++ b/Mathlib/Order/WellFounded.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Jeremy Avigad, Mario Carneiro -/ import Mathlib.Data.Set.Function -import Mathlib.Order.Bounds.Basic +import Mathlib.Order.Bounds.Defs /-! # Well-founded relations From a02b71d090e5b5df65cda5ffbefb58b3ffb168b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Calle=20S=C3=B6nne?= Date: Sat, 12 Oct 2024 12:46:13 +0000 Subject: [PATCH 052/425] feat(MorphismProperty/Presheaf): add `relative` morphism property (#16143) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Given a morphism property P and a functor F, we define the morphism property `P.relative` of morphisms in the codomain of `F`. This is defined as being relatively representable with respect to `F`, and that any represented pullback of the morphism satisfies P. Co-authored-by: Joël Riou --- .../MorphismProperty/Representable.lean | 104 ++++++++++++++++-- 1 file changed, 95 insertions(+), 9 deletions(-) diff --git a/Mathlib/CategoryTheory/MorphismProperty/Representable.lean b/Mathlib/CategoryTheory/MorphismProperty/Representable.lean index 91bf09c44907ec..e2ff92296f5c95 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Representable.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Representable.lean @@ -12,7 +12,7 @@ import Mathlib.CategoryTheory.MorphismProperty.Limits In this file we define and develop basic results about relatively representable morphisms. -Classically, a morphism `f : X ⟶ Y` of presheaves is said to be representable if for any morphism +Classically, a morphism `f : F ⟶ G` of presheaves is said to be representable if for any morphism `g : yoneda.obj X ⟶ G`, there exists a pullback square of the following form ``` yoneda.obj Y --yoneda.map snd--> yoneda.obj X @@ -25,16 +25,14 @@ Classically, a morphism `f : X ⟶ Y` of presheaves is said to be representable In this file, we define a notion of relative representability which works with respect to any functor, and not just `yoneda`. The fact that a morphism `f : F ⟶ G` between presheaves is -representable in the classical case will then be given by `yoneda.relativelyRepresentable f`. - - - +representable in the classical case will then be given by `F.relativelyRepresentable f`. +` ## Main definitions Throughout this file, `F : C ⥤ D` is a functor between categories `C` and `D`. -* We define `relativelyRepresentable` as a `MorphismProperty`. A morphism `f : X ⟶ Y` in `D` is - said to be relatively representable with respect to `F`, if for any `g : F.obj a ⟶ Y`, there - exists a pullback square of the following form +* `Functor.relativelyRepresentable`: A morphism `f : X ⟶ Y` in `D` is said to be relatively + representable with respect to `F`, if for any `g : F.obj a ⟶ Y`, there exists a pullback square + of the following form ``` F.obj b --F.map snd--> F.obj a | | @@ -44,6 +42,10 @@ Throughout this file, `F : C ⥤ D` is a functor between categories `C` and `D`. X ------- f --------> Y ``` +* `MorphismProperty.relative`: Given a morphism property `P` in `C`, a morphism `f : X ⟶ Y` in `D` + satisfies `P.relative F` if it is relatively representable and for any `g : F.obj a ⟶ Y`, the + property `P` holds for any represented pullback of `f` by `g`. + ## API Given `hf : relativelyRepresentable f`, with `f : X ⟶ Y` and `g : F.obj a ⟶ Y`, we provide: @@ -259,7 +261,8 @@ end /-- When `C` has pullbacks, then `F.map f` is representable with respect to `F` for any `f : a ⟶ b` in `C`. -/ -lemma map [Full F] [PreservesLimitsOfShape WalkingCospan F] [HasPullbacks C] {a b : C} (f : a ⟶ b) : +lemma map [Full F] [HasPullbacks C] {a b : C} (f : a ⟶ b) + [∀ c (g : c ⟶ b), PreservesLimit (cospan f g) F] : F.relativelyRepresentable (F.map f) := fun c g ↦ by obtain ⟨g, rfl⟩ := F.map_surjective g refine ⟨Limits.pullback f g, Limits.pullback.snd f g, F.map (Limits.pullback.fst f g), ?_⟩ @@ -288,4 +291,87 @@ instance respectsIso : RespectsIso F.relativelyRepresentable := end Functor.relativelyRepresentable +namespace MorphismProperty + +open Functor.relativelyRepresentable + +variable {X Y : D} (P : MorphismProperty C) + +/-- Given a morphism property `P` in a category `C`, a functor `F : C ⥤ D` and a morphism +`f : X ⟶ Y` in `D`. Then `f` satisfies the morphism property `P.relative` with respect to `F` iff: +* The morphism is representable with respect to `F` +* For any morphism `g : F.obj a ⟶ Y`, the property `P` holds for any represented pullback of + `f` by `g`. -/ +def relative : MorphismProperty D := + fun X Y f ↦ F.relativelyRepresentable f ∧ + ∀ ⦃a b : C⦄ (g : F.obj a ⟶ Y) (fst : F.obj b ⟶ X) (snd : b ⟶ a) + (_ : IsPullback fst (F.map snd) f g), P snd + +/-- Given a morphism property `P` in a category `C`, a morphism `f : F ⟶ G` of presheaves in the +category `Cᵒᵖ ⥤ Type v` satisfies the morphism property `P.presheaf` iff: +* The morphism is representable. +* For any morphism `g : F.obj a ⟶ G`, the property `P` holds for any represented pullback of + `f` by `g`. + +This is implemented as a special case of the more general notion of `P.relative`, to the case when +the functor `F` is `yoneda`. -/ +abbrev presheaf : MorphismProperty (Cᵒᵖ ⥤ Type v₁) := P.relative yoneda + +variable {P} {F} + +/-- A morphism satisfying `P.relative` is representable. -/ +lemma relative.rep {f : X ⟶ Y} (hf : P.relative F f) : F.relativelyRepresentable f := + hf.1 + +lemma relative.property {f : X ⟶ Y} (hf : P.relative F f) : + ∀ ⦃a b : C⦄ (g : F.obj a ⟶ Y) (fst : F.obj b ⟶ X) (snd : b ⟶ a) + (_ : IsPullback fst (F.map snd) f g), P snd := + hf.2 + +lemma relative.property_snd {f : X ⟶ Y} (hf : P.relative F f) {a : C} (g : F.obj a ⟶ Y) : + P (hf.rep.snd g) := + hf.property g _ _ (hf.rep.isPullback g) + +/-- Given a morphism property `P` which respects isomorphisms, then to show that a morphism +`f : X ⟶ Y` satisfies `P.relative` it suffices to show that: +* The morphism is representable. +* For any morphism `g : F.obj a ⟶ G`, the property `P` holds for *some* represented pullback +of `f` by `g`. -/ +lemma relative.of_exists [F.Faithful] [F.Full] [P.RespectsIso] {f : X ⟶ Y} + (h₀ : ∀ ⦃a : C⦄ (g : F.obj a ⟶ Y), ∃ (b : C) (fst : F.obj b ⟶ X) (snd : b ⟶ a) + (_ : IsPullback fst (F.map snd) f g), P snd) : P.relative F f := by + refine ⟨fun a g ↦ ?_, fun a b g fst snd h ↦ ?_⟩ + all_goals obtain ⟨c, g_fst, g_snd, BC, H⟩ := h₀ g + · refine ⟨c, g_snd, g_fst, BC⟩ + · refine (P.arrow_mk_iso_iff ?_).2 H + exact Arrow.isoMk (F.preimageIso (h.isoIsPullback X (F.obj a) BC)) (Iso.refl _) + (F.map_injective (by simp)) + +lemma relative_of_snd [F.Faithful] [F.Full] [P.RespectsIso] {f : X ⟶ Y} + (hf : F.relativelyRepresentable f) (h : ∀ ⦃a : C⦄ (g : F.obj a ⟶ Y), P (hf.snd g)) : + P.relative F f := + relative.of_exists (fun _ g ↦ ⟨hf.pullback g, hf.fst g, hf.snd g, hf.isPullback g, h g⟩) + +/-- If `P : MorphismProperty C` is stable under base change, `F` is fully faithful and preserves +pullbacks, and `C` has all pullbacks, then for any `f : a ⟶ b` in `C`, `F.map f` satisfies +`P.relative` if `f` satisfies `P`. -/ +lemma relative_map [F.Faithful] [F.Full] [HasPullbacks C] (hP : StableUnderBaseChange P) + {a b : C} {f : a ⟶ b} [∀ c (g : c ⟶ b), PreservesLimit (cospan f g) F] + (hf : P f) : P.relative F (F.map f) := by + have := StableUnderBaseChange.respectsIso hP + apply relative.of_exists + intro Y' g + obtain ⟨g, rfl⟩ := F.map_surjective g + exact ⟨_, _, _, (IsPullback.of_hasPullback f g).map F, hP.snd _ _ hf⟩ + +lemma of_relative_map {a b : C} {f : a ⟶ b} (hf : P.relative F (F.map f)) : P f := + hf.property (𝟙 _) (𝟙 _) f (IsPullback.id_horiz (F.map f)) + +lemma relative_map_iff [F.Faithful] [F.Full] [PreservesLimitsOfShape WalkingCospan F] + [HasPullbacks C] (hP : StableUnderBaseChange P) {X Y : C} {f : X ⟶ Y} : + P.relative F (F.map f) ↔ P f := + ⟨fun hf ↦ of_relative_map hf, fun hf ↦ relative_map hP hf⟩ + +end MorphismProperty + end CategoryTheory From 90f1b4da0ba2f4bdadd5f231030d4faa1295b85a Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Sat, 12 Oct 2024 14:24:48 +0000 Subject: [PATCH 053/425] chore(Order): move more defs to Defs (#17677) --- Mathlib/Data/Fintype/Order.lean | 1 + Mathlib/Order/CompleteLattice/Finset.lean | 2 +- Mathlib/Order/Defs.lean | 26 ++++++++++++++++++++++ Mathlib/Order/Filter/AtTopBot.lean | 1 + Mathlib/Order/Minimal.lean | 27 ++--------------------- 5 files changed, 31 insertions(+), 26 deletions(-) diff --git a/Mathlib/Data/Fintype/Order.lean b/Mathlib/Data/Fintype/Order.lean index 6fa3b6c7e32fd2..127472ab51f1dd 100644 --- a/Mathlib/Data/Fintype/Order.lean +++ b/Mathlib/Data/Fintype/Order.lean @@ -6,6 +6,7 @@ Authors: Peter Nelson, Yaël Dillies import Mathlib.Data.Finset.Order import Mathlib.Order.Atoms import Mathlib.Data.Set.Finite +import Mathlib.Order.Minimal /-! # Order structures on finite types diff --git a/Mathlib/Order/CompleteLattice/Finset.lean b/Mathlib/Order/CompleteLattice/Finset.lean index b96b173756c625..b02e5eb918efa5 100644 --- a/Mathlib/Order/CompleteLattice/Finset.lean +++ b/Mathlib/Order/CompleteLattice/Finset.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Mario Carneiro -/ import Mathlib.Data.Finset.Option -import Mathlib.Order.Minimal +import Mathlib.Data.Set.Lattice /-! # Lattice operations on finsets diff --git a/Mathlib/Order/Defs.lean b/Mathlib/Order/Defs.lean index a6a6ffa250fe68..7a46f0ce76cf70 100644 --- a/Mathlib/Order/Defs.lean +++ b/Mathlib/Order/Defs.lean @@ -184,6 +184,32 @@ end end +/-! ### Minimal and maximal -/ + +section LE + +variable {α : Type*} [LE α] {P : α → Prop} {x y : α} + +/-- `Minimal P x` means that `x` is a minimal element satisfying `P`. -/ +def Minimal (P : α → Prop) (x : α) : Prop := P x ∧ ∀ ⦃y⦄, P y → y ≤ x → x ≤ y + +/-- `Maximal P x` means that `x` is a maximal element satisfying `P`. -/ +def Maximal (P : α → Prop) (x : α) : Prop := P x ∧ ∀ ⦃y⦄, P y → x ≤ y → y ≤ x + +lemma Minimal.prop (h : Minimal P x) : P x := + h.1 + +lemma Maximal.prop (h : Maximal P x) : P x := + h.1 + +lemma Minimal.le_of_le (h : Minimal P x) (hy : P y) (hle : y ≤ x) : x ≤ y := + h.2 hy hle + +lemma Maximal.le_of_ge (h : Maximal P x) (hy : P y) (hge : x ≤ y) : y ≤ x := + h.2 hy hge + +end LE + /-! ### Bundled classes -/ variable {α : Type*} diff --git a/Mathlib/Order/Filter/AtTopBot.lean b/Mathlib/Order/Filter/AtTopBot.lean index f393265bd856c1..18b4a5cf5790c1 100644 --- a/Mathlib/Order/Filter/AtTopBot.lean +++ b/Mathlib/Order/Filter/AtTopBot.lean @@ -8,6 +8,7 @@ import Mathlib.Order.ConditionallyCompleteLattice.Basic import Mathlib.Order.Filter.Bases import Mathlib.Order.Filter.Prod import Mathlib.Order.Interval.Set.Disjoint +import Mathlib.Order.Interval.Set.OrderIso /-! # `Filter.atTop` and `Filter.atBot` filters on preorders, monoids and groups. diff --git a/Mathlib/Order/Minimal.lean b/Mathlib/Order/Minimal.lean index cfc38ab8c1e323..688801c79c4974 100644 --- a/Mathlib/Order/Minimal.lean +++ b/Mathlib/Order/Minimal.lean @@ -10,13 +10,8 @@ import Mathlib.Order.Interval.Set.Basic /-! # Minimality and Maximality -This file defines minimality and maximality of an element with respect to a predicate `P` on -an ordered type `α`. - -## Main declarations - -* `Minimal P x`: `x` is minimal satisfying `P`. -* `Maximal P x`: `x` is maximal satisfying `P`. +This file proves basic facts about minimality and maximality +of an element with respect to a predicate `P` on an ordered type `α`. ## Implementation Details @@ -52,24 +47,6 @@ section LE variable [LE α] -/-- `Minimal P x` means that `x` is a minimal element satisfying `P`. -/ -def Minimal (P : α → Prop) (x : α) : Prop := P x ∧ ∀ ⦃y⦄, P y → y ≤ x → x ≤ y - -/-- `Maximal P x` means that `x` is a maximal element satisfying `P`. -/ -def Maximal (P : α → Prop) (x : α) : Prop := P x ∧ ∀ ⦃y⦄, P y → x ≤ y → y ≤ x - -lemma Minimal.prop (h : Minimal P x) : P x := - h.1 - -lemma Maximal.prop (h : Maximal P x) : P x := - h.1 - -lemma Minimal.le_of_le (h : Minimal P x) (hy : P y) (hle : y ≤ x) : x ≤ y := - h.2 hy hle - -lemma Maximal.le_of_ge (h : Maximal P x) (hy : P y) (hge : x ≤ y) : y ≤ x := - h.2 hy hge - @[simp] theorem minimal_toDual : Minimal (fun x ↦ P (ofDual x)) (toDual x) ↔ Maximal P x := Iff.rfl From 1fb2cbcfda77d978c076acdf586d370b83a7d4fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Sat, 12 Oct 2024 15:26:53 +0000 Subject: [PATCH 054/425] chore(Order/ConditionallyCompleteLattice/Basic): ConditionallyCompleteLinearOrderBot extends OrderBot (#17524) --- Mathlib/Order/ConditionallyCompleteLattice/Basic.lean | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean b/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean index 9f80770bcdc858..7910ab0ffc59a3 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean @@ -219,16 +219,12 @@ complete linear orders, we prefix `sInf` and `sSup` by a `c` everywhere. The sam hold in both worlds, sometimes with additional assumptions of nonemptiness or boundedness. -/ class ConditionallyCompleteLinearOrderBot (α : Type*) extends ConditionallyCompleteLinearOrder α, - Bot α where - /-- `⊥` is the least element -/ - bot_le : ∀ x : α, ⊥ ≤ x - /-- The supremum of the empty set is `⊥` -/ + OrderBot α where + /-- The supremum of the empty set is special-cased to `⊥` -/ csSup_empty : sSup ∅ = ⊥ -- see Note [lower instance priority] -instance (priority := 100) ConditionallyCompleteLinearOrderBot.toOrderBot - [h : ConditionallyCompleteLinearOrderBot α] : OrderBot α := - { h with } +attribute [instance 100] ConditionallyCompleteLinearOrderBot.toOrderBot -- see Note [lower instance priority] /-- A complete lattice is a conditionally complete lattice, as there are no restrictions From e7062ed4631c76a999e1988a0d6a6b04a54684e1 Mon Sep 17 00:00:00 2001 From: leanprover-community-bot-assistant Date: Sun, 13 Oct 2024 00:14:51 +0000 Subject: [PATCH 055/425] chore(scripts): update nolints.json (#17690) I am happy to remove some nolints for you! --- scripts/nolints.json | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/scripts/nolints.json b/scripts/nolints.json index 8ea41fbf362a90..8b556db384b5e2 100644 --- a/scripts/nolints.json +++ b/scripts/nolints.json @@ -84,8 +84,6 @@ ["docBlame", "Combinator.I"], ["docBlame", "Combinator.K"], ["docBlame", "Combinator.S"], - ["docBlame", "CommRingCat.forget_obj_eq_coe"], - ["docBlame", "CommSemiRingCat.forget_obj_eq_coe"], ["docBlame", "CompleteBooleanAlgebra.toCompleteAtomicBooleanAlgebra"], ["docBlame", "Computation.parallelRec"], ["docBlame", "Congr!.elabConfig"], @@ -312,13 +310,11 @@ ["docBlame", "ReaderT.callCC"], ["docBlame", "ReaderT.mk"], ["docBlame", "ReaderT.mkLabel"], - ["docBlame", "RingCat.forget_obj_eq_coe"], ["docBlame", "RingQuot.preLift"], ["docBlame", "RingQuot.preLiftAlgHom"], ["docBlame", "RingQuot.toQuot"], ["docBlame", "RootableBy.root"], ["docBlame", "SchwartzMap.toFun"], - ["docBlame", "SemiRingCat.forget_obj_eq_coe"], ["docBlame", "Semigrp.forget_obj_eq_coe"], ["docBlame", "Shrink.rec"], ["docBlame", "SlashAction.map"], @@ -712,10 +708,6 @@ ["docBlame", "Mathlib.Command.Variable.variable?.maxSteps"], ["docBlame", "Mathlib.Meta.NormNum.evalEq.intArm"], ["docBlame", "Mathlib.Meta.NormNum.evalEq.ratArm"], - ["docBlame", "Mathlib.Meta.NormNum.evalLE.core.intArm"], - ["docBlame", "Mathlib.Meta.NormNum.evalLE.core.ratArm"], - ["docBlame", "Mathlib.Meta.NormNum.evalLT.core.intArm"], - ["docBlame", "Mathlib.Meta.NormNum.evalLT.core.ratArm"], ["docBlame", "Mathlib.Meta.NormNum.evalMinFac.aux"], ["docBlame", "Mathlib.Meta.NormNum.evalMinFac.core"], ["docBlame", "Mathlib.Meta.NormNum.evalNatPrime.core"], @@ -749,6 +741,10 @@ ["docBlame", "Mathlib.Tactic.Says.says.verify"], ["docBlame", "Mathlib.Meta.NormNum.evalAdd.core.intArm"], ["docBlame", "Mathlib.Meta.NormNum.evalAdd.core.ratArm"], + ["docBlame", "Mathlib.Meta.NormNum.evalLE.core.intArm"], + ["docBlame", "Mathlib.Meta.NormNum.evalLE.core.ratArm"], + ["docBlame", "Mathlib.Meta.NormNum.evalLT.core.intArm"], + ["docBlame", "Mathlib.Meta.NormNum.evalLT.core.ratArm"], ["docBlame", "Mathlib.Meta.NormNum.evalMul.core.intArm"], ["docBlame", "Mathlib.Meta.NormNum.evalMul.core.ratArm"], ["unusedArguments", "Combinator.K"]] From 0c3eab0a8dbbb6edf18fc81fb7b6587ad1fb9a93 Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Sun, 13 Oct 2024 08:25:34 +0000 Subject: [PATCH 056/425] chore: bump to nightly-2024-10-13 --- lean-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lean-toolchain b/lean-toolchain index f3a11d3ea4e638..30684366328531 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-12 +leanprover/lean4:nightly-2024-10-13 From 7306a0368f2e648c7a32c91876287186cff1eb8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Degenne?= Date: Sun, 13 Oct 2024 09:56:42 +0000 Subject: [PATCH 057/425] feat(MeasureTheory): two lemmas about `Measure.bind` (#17630) Add two simp lemmas `bind_const` and `bind_dirac_eq_map`. Swap the names of `bind_dirac` and `dirac_bind` for coherence with the other names in the file. --- Mathlib/MeasureTheory/Measure/GiryMonad.lean | 25 ++++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/Mathlib/MeasureTheory/Measure/GiryMonad.lean b/Mathlib/MeasureTheory/Measure/GiryMonad.lean index c84c4f12580017..502d9433a781a6 100644 --- a/Mathlib/MeasureTheory/Measure/GiryMonad.lean +++ b/Mathlib/MeasureTheory/Measure/GiryMonad.lean @@ -154,6 +154,11 @@ theorem bind_apply {m : Measure α} {f : α → Measure β} {s : Set β} (hs : M (hf : Measurable f) : bind m f s = ∫⁻ a, f a s ∂m := by rw [bind, join_apply hs, lintegral_map (measurable_coe hs) hf] +@[simp] +lemma bind_const {m : Measure α} {ν : Measure β} : m.bind (fun _ ↦ ν) = m Set.univ • ν := by + ext s hs + rw [bind_apply hs measurable_const, lintegral_const, smul_apply, smul_eq_mul, mul_comm] + theorem measurable_bind' {g : α → Measure β} (hg : Measurable g) : Measurable fun m => bind m g := measurable_join.comp (measurable_map _ hg) @@ -169,16 +174,27 @@ theorem bind_bind {γ} [MeasurableSpace γ] {m : Measure α} {f : α → Measure conv_rhs => enter [2, a]; erw [bind_apply hs hg] rfl -theorem bind_dirac {f : α → Measure β} (hf : Measurable f) (a : α) : bind (dirac a) f = f a := by +theorem dirac_bind {f : α → Measure β} (hf : Measurable f) (a : α) : bind (dirac a) f = f a := by ext1 s hs erw [bind_apply hs hf, lintegral_dirac' a ((measurable_coe hs).comp hf)] rfl -theorem dirac_bind {m : Measure α} : bind m dirac = m := by +@[simp] +theorem bind_dirac {m : Measure α} : bind m dirac = m := by ext1 s hs simp only [bind_apply hs measurable_dirac, dirac_apply' _ hs, lintegral_indicator 1 hs, Pi.one_apply, lintegral_one, restrict_apply, MeasurableSet.univ, univ_inter] +@[simp] +lemma bind_dirac_eq_map (m : Measure α) {f : α → β} (hf : Measurable f) : + m.bind (fun x ↦ Measure.dirac (f x)) = m.map f := by + ext s hs + rw [bind_apply hs] + swap; · exact measurable_dirac.comp hf + simp_rw [dirac_apply' _ hs] + rw [← lintegral_map _ hf, lintegral_indicator_one hs] + exact measurable_const.indicator hs + theorem join_eq_bind (μ : Measure (Measure α)) : join μ = bind μ id := by rw [bind, map_id] theorem join_map_map {f : α → β} (hf : Measurable f) (μ : Measure (Measure α)) : @@ -195,11 +211,10 @@ theorem join_map_join (μ : Measure (Measure (Measure α))) : join (map join μ) funext ν exact join_eq_bind ν -theorem join_map_dirac (μ : Measure α) : join (map dirac μ) = μ := - dirac_bind +theorem join_map_dirac (μ : Measure α) : join (map dirac μ) = μ := bind_dirac theorem join_dirac (μ : Measure α) : join (dirac μ) = μ := - (join_eq_bind (dirac μ)).trans (bind_dirac measurable_id _) + (join_eq_bind (dirac μ)).trans (dirac_bind measurable_id _) end Measure From 56401289abaec88e30725944b201ccadb6118957 Mon Sep 17 00:00:00 2001 From: sgouezel Date: Sun, 13 Oct 2024 10:51:35 +0000 Subject: [PATCH 058/425] chore: generalize strong law of large numbers from `MeasureSpace` to `MeasurableSpace` (#17692) See discussion at https://leanprover.zulipchat.com/#narrow/stream/116395-maths/topic/.60MeasureSpace.60.20vs.20.60Measure.60.20in.20.60ProbabilityTheory.2F.60/near/476526619 --- Mathlib/Probability/StrongLaw.lean | 114 +++++++++++++++-------------- 1 file changed, 60 insertions(+), 54 deletions(-) diff --git a/Mathlib/Probability/StrongLaw.lean b/Mathlib/Probability/StrongLaw.lean index 34d9233a9272f5..70fe8e747018d7 100644 --- a/Mathlib/Probability/StrongLaw.lean +++ b/Mathlib/Probability/StrongLaw.lean @@ -603,10 +603,12 @@ identically distributed integrable real-valued random variables, then `∑ i ∈ converges almost surely to `𝔼[X 0]`. We give here the strong version, due to Etemadi, that only requires pairwise independence. Superseded by `strong_law_ae`, which works for random variables taking values in any Banach space. -/ -theorem strong_law_ae_real {Ω : Type*} [MeasureSpace Ω] - (X : ℕ → Ω → ℝ) (hint : Integrable (X 0)) - (hindep : Pairwise fun i j => IndepFun (X i) (X j)) (hident : ∀ i, IdentDistrib (X i) (X 0)) : - ∀ᵐ ω, Tendsto (fun n : ℕ => (∑ i ∈ range n, X i ω) / n) atTop (𝓝 𝔼[X 0]) := by +theorem strong_law_ae_real {Ω : Type*} {m : MeasurableSpace Ω} {μ : Measure Ω} + (X : ℕ → Ω → ℝ) (hint : Integrable (X 0) μ) + (hindep : Pairwise fun i j => IndepFun (X i) (X j) μ) + (hident : ∀ i, IdentDistrib (X i) (X 0) μ μ) : + ∀ᵐ ω ∂μ, Tendsto (fun n : ℕ => (∑ i ∈ range n, X i ω) / n) atTop (𝓝 (μ [X 0])) := by + let mΩ : MeasureSpace Ω := ⟨μ⟩ -- first get rid of the trivial case where the space is not a probability space by_cases h : ∀ᵐ ω, X 0 ω = 0 · have I : ∀ᵐ ω, ∀ i, X i ω = 0 := by @@ -615,7 +617,7 @@ theorem strong_law_ae_real {Ω : Type*} [MeasureSpace Ω] exact (hident i).symm.ae_snd (p := fun x ↦ x = 0) measurableSet_eq h filter_upwards [I] with ω hω simpa [hω] using (integral_eq_zero_of_ae h).symm - have : IsProbabilityMeasure (ℙ : Measure Ω) := + have : IsProbabilityMeasure μ := hint.isProbabilityMeasure_of_indepFun (X 0) (X 1) h (hindep zero_ne_one) -- then consider separately the positive and the negative part, and apply the result -- for nonnegative functions to them. @@ -630,17 +632,17 @@ theorem strong_law_ae_real {Ω : Type*} [MeasureSpace Ω] strong_law_aux7 _ hint.neg_part (fun i j hij => (hindep hij).comp negm negm) (fun i => (hident i).comp negm) fun i ω => le_max_right _ _ filter_upwards [A, B] with ω hωpos hωneg - convert hωpos.sub hωneg using 1 + convert hωpos.sub hωneg using 2 · simp only [pos, neg, ← sub_div, ← sum_sub_distrib, max_zero_sub_max_neg_zero_eq_self, Function.comp_apply] · simp only [← integral_sub hint.pos_part hint.neg_part, max_zero_sub_max_neg_zero_eq_self, - Function.comp_apply] + Function.comp_apply, mΩ] end StrongLawAeReal section StrongLawVectorSpace -variable {Ω : Type*} [MeasureSpace Ω] [IsProbabilityMeasure (ℙ : Measure Ω)] +variable {Ω : Type*} {mΩ : MeasurableSpace Ω} {μ : Measure Ω} [IsProbabilityMeasure μ] {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [CompleteSpace E] [MeasurableSpace E] @@ -650,22 +652,23 @@ open Set TopologicalSpace the composition of the random variables with a simple function satisfies the strong law of large numbers. -/ lemma strong_law_ae_simpleFunc_comp (X : ℕ → Ω → E) (h' : Measurable (X 0)) - (hindep : Pairwise (fun i j ↦ IndepFun (X i) (X j))) (hident : ∀ i, IdentDistrib (X i) (X 0)) - (φ : SimpleFunc E E) : ∀ᵐ ω, - Tendsto (fun n : ℕ ↦ (n : ℝ) ⁻¹ • (∑ i ∈ range n, φ (X i ω))) atTop (𝓝 𝔼[φ ∘ (X 0)]) := by + (hindep : Pairwise (fun i j ↦ IndepFun (X i) (X j) μ)) + (hident : ∀ i, IdentDistrib (X i) (X 0) μ μ) (φ : SimpleFunc E E) : + ∀ᵐ ω ∂μ, + 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 (P := fun ψ ↦ ∀ᵐ ω, - Tendsto (fun n : ℕ ↦ (n : ℝ) ⁻¹ • (∑ i ∈ range n, ψ (X i ω))) atTop (𝓝 𝔼[ψ ∘ (X 0)])) ?_ ?_ φ + refine SimpleFunc.induction (P := fun ψ ↦ ∀ᵐ ω ∂μ, + Tendsto (fun n : ℕ ↦ (n : ℝ) ⁻¹ • (∑ i ∈ range n, ψ (X i ω))) atTop (𝓝 (μ [ψ ∘ (X 0)]))) ?_ ?_ φ · intro c s hs simp only [SimpleFunc.const_zero, SimpleFunc.coe_piecewise, SimpleFunc.coe_const, SimpleFunc.coe_zero, piecewise_eq_indicator, Function.comp_apply] let F : E → ℝ := indicator s 1 have F_meas : Measurable F := (measurable_indicator_const_iff 1).2 hs let Y : ℕ → Ω → ℝ := fun n ↦ F ∘ (X n) - have : ∀ᵐ (ω : Ω), Tendsto (fun (n : ℕ) ↦ (n : ℝ)⁻¹ • ∑ i ∈ Finset.range n, Y i ω) - atTop (𝓝 𝔼[Y 0]) := by + have : ∀ᵐ (ω : Ω) ∂μ, Tendsto (fun (n : ℕ) ↦ (n : ℝ)⁻¹ • ∑ i ∈ Finset.range n, Y i ω) + atTop (𝓝 (μ [Y 0])) := by simp only [Function.const_one, smul_eq_mul, ← div_eq_inv_mul] apply strong_law_ae_real · exact SimpleFunc.integrable_of_isFiniteMeasure @@ -699,9 +702,10 @@ variable [BorelSpace E] assuming measurability in addition to integrability. This is weakened to ae measurability in the full version `ProbabilityTheory.strong_law_ae`. -/ lemma strong_law_ae_of_measurable - (X : ℕ → Ω → E) (hint : Integrable (X 0)) (h' : StronglyMeasurable (X 0)) - (hindep : Pairwise (fun i j ↦ IndepFun (X i) (X j))) (hident : ∀ i, IdentDistrib (X i) (X 0)) : - ∀ᵐ ω, Tendsto (fun n : ℕ ↦ (n : ℝ) ⁻¹ • (∑ i ∈ range n, X i ω)) atTop (𝓝 𝔼[X 0]) := by + (X : ℕ → Ω → E) (hint : Integrable (X 0) μ) (h' : StronglyMeasurable (X 0)) + (hindep : Pairwise (fun i j ↦ IndepFun (X i) (X j) μ)) + (hident : ∀ i, IdentDistrib (X i) (X 0) μ μ) : + ∀ᵐ ω ∂μ, Tendsto (fun n : ℕ ↦ (n : ℝ) ⁻¹ • (∑ i ∈ range n, X i ω)) atTop (𝓝 (μ [X 0])) := by /- Choose a simple function `φ` such that `φ (X 0)` approximates well enough `X 0` -- this is possible as `X 0` is strongly measurable. Then `φ (X n)` approximates well `X n`. Then the strong law for `φ (X n)` implies the strong law for `X n`, up to a small @@ -717,12 +721,12 @@ lemma strong_law_ae_of_measurable SimpleFunc.nearestPt (fun k => Nat.casesOn k 0 ((↑) ∘ denseSeq s) : ℕ → E) let Y : ℕ → ℕ → Ω → E := fun k i ↦ (φ k) ∘ (X i) -- strong law for `φ (X n)` - have A : ∀ᵐ ω, ∀ k, - Tendsto (fun n : ℕ ↦ (n : ℝ) ⁻¹ • (∑ i ∈ range n, Y k i ω)) atTop (𝓝 𝔼[Y k 0]) := + have A : ∀ᵐ ω ∂μ, ∀ k, + Tendsto (fun n : ℕ ↦ (n : ℝ) ⁻¹ • (∑ i ∈ range n, Y k i ω)) atTop (𝓝 (μ [Y k 0])) := ae_all_iff.2 (fun k ↦ strong_law_ae_simpleFunc_comp X h'.measurable hindep hident (φ k)) -- strong law for the error `‖X i - φ (X i)‖` - have B : ∀ᵐ ω, ∀ k, Tendsto (fun n : ℕ ↦ (∑ i ∈ range n, ‖(X i - Y k i) ω‖) / n) - atTop (𝓝 𝔼[(fun ω ↦ ‖(X 0 - Y k 0) ω‖)]) := by + have B : ∀ᵐ ω ∂μ, ∀ k, Tendsto (fun n : ℕ ↦ (∑ i ∈ range n, ‖(X i - Y k i) ω‖) / n) + atTop (𝓝 (μ [(fun ω ↦ ‖(X 0 - Y k 0) ω‖)])) := by apply ae_all_iff.2 (fun k ↦ ?_) let G : ℕ → E → ℝ := fun k x ↦ ‖x - φ k x‖ have G_meas : ∀ k, Measurable (G k) := @@ -745,32 +749,32 @@ lemma strong_law_ae_of_measurable obtain ⟨δ, δpos, hδ⟩ : ∃ δ, 0 < δ ∧ δ + δ + δ < ε := ⟨ε/4, by positivity, by linarith⟩ -- choose `k` large enough so that `φₖ (X 0)` approximates well enough `X 0`, up to the -- precision `δ`. - obtain ⟨k, hk⟩ : ∃ k, ∫ ω, ‖(X 0 - Y k 0) ω‖ < δ := by + obtain ⟨k, hk⟩ : ∃ k, ∫ ω, ‖(X 0 - Y k 0) ω‖ ∂μ < δ := by simp_rw [Pi.sub_apply, norm_sub_rev (X 0 _)] exact ((tendsto_order.1 (tendsto_integral_norm_approxOn_sub h'.measurable hint)).2 δ δpos).exists - have : ‖𝔼[Y k 0] - 𝔼[X 0]‖ < δ := by + have : ‖μ [Y k 0] - μ [X 0]‖ < δ := by rw [norm_sub_rev, ← integral_sub hint] · exact (norm_integral_le_integral_norm _).trans_lt hk · exact ((φ k).comp (X 0) h'.measurable).integrable_of_isFiniteMeasure -- consider `n` large enough for which the above convergences have taken place within `δ`. have I : ∀ᶠ n in atTop, (∑ i ∈ range n, ‖(X i - Y k i) ω‖) / n < δ := (tendsto_order.1 (h'ω k)).2 δ hk - have J : ∀ᶠ (n : ℕ) in atTop, ‖(n : ℝ) ⁻¹ • (∑ i ∈ range n, Y k i ω) - 𝔼[Y k 0]‖ < δ := by + have J : ∀ᶠ (n : ℕ) in atTop, ‖(n : ℝ) ⁻¹ • (∑ i ∈ range n, Y k i ω) - μ [Y k 0]‖ < δ := by specialize hω k rw [tendsto_iff_norm_sub_tendsto_zero] at hω exact (tendsto_order.1 hω).2 δ δpos filter_upwards [I, J] with n hn h'n -- at such an `n`, the strong law is realized up to `ε`. calc - ‖(n : ℝ)⁻¹ • ∑ i ∈ Finset.range n, X i ω - 𝔼[X 0]‖ + ‖(n : ℝ)⁻¹ • ∑ i ∈ Finset.range n, X i ω - μ [X 0]‖ = ‖(n : ℝ)⁻¹ • ∑ i ∈ Finset.range n, (X i ω - Y k i ω) + - ((n : ℝ)⁻¹ • ∑ i ∈ Finset.range n, Y k i ω - 𝔼[Y k 0]) + (𝔼[Y k 0] - 𝔼[X 0])‖ := by + ((n : ℝ)⁻¹ • ∑ i ∈ Finset.range n, Y k i ω - μ [Y k 0]) + (μ [Y k 0] - μ [X 0])‖ := by congr simp only [Function.comp_apply, sum_sub_distrib, smul_sub] abel _ ≤ ‖(n : ℝ)⁻¹ • ∑ i ∈ Finset.range n, (X i ω - Y k i ω)‖ + - ‖(n : ℝ)⁻¹ • ∑ i ∈ Finset.range n, Y k i ω - 𝔼[Y k 0]‖ + ‖𝔼[Y k 0] - 𝔼[X 0]‖ := + ‖(n : ℝ)⁻¹ • ∑ i ∈ Finset.range n, Y k i ω - μ [Y k 0]‖ + ‖μ [Y k 0] - μ [X 0]‖ := norm_add₃_le _ _ _ _ ≤ (∑ i ∈ Finset.range n, ‖X i ω - Y k i ω‖) / n + δ + δ := by gcongr @@ -783,37 +787,39 @@ lemma strong_law_ae_of_measurable exact hn.le _ < ε := hδ +omit [IsProbabilityMeasure μ] in /-- **Strong law of large numbers**, almost sure version: if `X n` is a sequence of independent identically distributed integrable random variables taking values in a Banach space, then `n⁻¹ • ∑ i ∈ range n, X i` converges almost surely to `𝔼[X 0]`. We give here the strong version, due to Etemadi, that only requires pairwise independence. -/ -theorem strong_law_ae {Ω : Type*} [MeasureSpace Ω] - (X : ℕ → Ω → E) (hint : Integrable (X 0)) - (hindep : Pairwise (fun i j ↦ IndepFun (X i) (X j))) (hident : ∀ i, IdentDistrib (X i) (X 0)) : - ∀ᵐ ω, Tendsto (fun n : ℕ ↦ (n : ℝ) ⁻¹ • (∑ i ∈ range n, X i ω)) atTop (𝓝 𝔼[X 0]) := by +theorem strong_law_ae (X : ℕ → Ω → E) (hint : Integrable (X 0) μ) + (hindep : Pairwise (fun i j ↦ IndepFun (X i) (X j) μ)) + (hident : ∀ i, IdentDistrib (X i) (X 0) μ μ) : + ∀ᵐ ω ∂μ, Tendsto (fun n : ℕ ↦ (n : ℝ) ⁻¹ • (∑ i ∈ range n, X i ω)) atTop (𝓝 (μ [X 0])) := by -- First exclude the trivial case where the space is not a probability space - by_cases h : ∀ᵐ ω, X 0 ω = 0 - · have I : ∀ᵐ ω, ∀ i, X i ω = 0 := by + by_cases h : ∀ᵐ ω ∂μ, X 0 ω = 0 + · have I : ∀ᵐ ω ∂μ, ∀ i, X i ω = 0 := by rw [ae_all_iff] intro i exact (hident i).symm.ae_snd (p := fun x ↦ x = 0) measurableSet_eq h filter_upwards [I] with ω hω simpa [hω] using (integral_eq_zero_of_ae h).symm - have : IsProbabilityMeasure (ℙ : Measure Ω) := + have : IsProbabilityMeasure μ := hint.isProbabilityMeasure_of_indepFun (X 0) (X 1) h (hindep zero_ne_one) -- we reduce to the case of strongly measurable random variables, by using `Y i` which is strongly -- measurable and ae equal to `X i`. - have A : ∀ i, Integrable (X i) := fun i ↦ (hident i).integrable_iff.2 hint + have A : ∀ i, Integrable (X i) μ := fun i ↦ (hident i).integrable_iff.2 hint let Y : ℕ → Ω → E := fun i ↦ (A i).1.mk (X i) - have B : ∀ᵐ ω, ∀ n, X n ω = Y n ω := + have B : ∀ᵐ ω ∂μ, ∀ n, X n ω = Y n ω := ae_all_iff.2 (fun i ↦ AEStronglyMeasurable.ae_eq_mk (A i).1) - have Yint : Integrable (Y 0) := Integrable.congr hint (AEStronglyMeasurable.ae_eq_mk (A 0).1) - have C : ∀ᵐ ω, Tendsto (fun n : ℕ ↦ (n : ℝ) ⁻¹ • (∑ i ∈ range n, Y i ω)) atTop (𝓝 𝔼[Y 0]) := by + have Yint : Integrable (Y 0) μ := Integrable.congr hint (AEStronglyMeasurable.ae_eq_mk (A 0).1) + have C : ∀ᵐ ω ∂μ, + Tendsto (fun n : ℕ ↦ (n : ℝ) ⁻¹ • (∑ i ∈ range n, Y i ω)) atTop (𝓝 (μ [Y 0])) := by apply strong_law_ae_of_measurable Y Yint ((A 0).1.stronglyMeasurable_mk) (fun i j hij ↦ IndepFun.ae_eq (hindep hij) (A i).1.ae_eq_mk (A j).1.ae_eq_mk) (fun i ↦ ((A i).1.identDistrib_mk.symm.trans (hident i)).trans (A 0).1.identDistrib_mk) filter_upwards [B, C] with ω h₁ h₂ - have : 𝔼[X 0] = 𝔼[Y 0] := integral_congr_ae (AEStronglyMeasurable.ae_eq_mk (A 0).1) + have : μ [X 0] = μ [Y 0] := integral_congr_ae (AEStronglyMeasurable.ae_eq_mk (A 0).1) rw [this] apply Tendsto.congr (fun n ↦ ?_) h₂ congr with i @@ -823,39 +829,39 @@ end StrongLawVectorSpace section StrongLawLp -variable {Ω : Type*} [MeasureSpace Ω] +variable {Ω : Type*} {mΩ : MeasurableSpace Ω} {μ : Measure Ω} {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [CompleteSpace E] [MeasurableSpace E] [BorelSpace E] /-- **Strong law of large numbers**, Lᵖ version: if `X n` is a sequence of independent identically distributed random variables in Lᵖ, then `n⁻¹ • ∑ i ∈ range n, X i` converges in `Lᵖ` to `𝔼[X 0]`. -/ -theorem strong_law_Lp {p : ℝ≥0∞} (hp : 1 ≤ p) (hp' : p ≠ ∞) (X : ℕ → Ω → E) (hℒp : Memℒp (X 0) p) - (hindep : Pairwise fun i j => IndepFun (X i) (X j)) (hident : ∀ i, IdentDistrib (X i) (X 0)) : - Tendsto (fun (n : ℕ) => eLpNorm (fun ω => (n : ℝ) ⁻¹ • (∑ i ∈ range n, X i ω) - 𝔼[X 0]) p) +theorem strong_law_Lp {p : ℝ≥0∞} (hp : 1 ≤ p) (hp' : p ≠ ∞) (X : ℕ → Ω → E) + (hℒp : Memℒp (X 0) p μ) (hindep : Pairwise fun i j => IndepFun (X i) (X j) μ) + (hident : ∀ i, IdentDistrib (X i) (X 0) μ μ) : + Tendsto (fun (n : ℕ) => eLpNorm (fun ω => (n : ℝ) ⁻¹ • (∑ i ∈ range n, X i ω) - μ [X 0]) p μ) atTop (𝓝 0) := by -- First exclude the trivial case where the space is not a probability space - by_cases h : ∀ᵐ ω, X 0 ω = 0 - · have I : ∀ᵐ ω, ∀ i, X i ω = 0 := by + by_cases h : ∀ᵐ ω ∂μ, X 0 ω = 0 + · have I : ∀ᵐ ω ∂μ, ∀ i, X i ω = 0 := by rw [ae_all_iff] intro i exact (hident i).symm.ae_snd (p := fun x ↦ x = 0) measurableSet_eq h - have A (n : ℕ) : eLpNorm (fun ω => (n : ℝ) ⁻¹ • (∑ i ∈ range n, X i ω) - 𝔼[X 0]) p ℙ = 0 := by + have A (n : ℕ) : eLpNorm (fun ω => (n : ℝ) ⁻¹ • (∑ i ∈ range n, X i ω) - μ [X 0]) p μ = 0 := by simp only [integral_eq_zero_of_ae h, sub_zero] apply eLpNorm_eq_zero_of_ae_zero filter_upwards [I] with ω hω simp [hω] simp [A] -- Then use ae convergence and uniform integrability - have : IsProbabilityMeasure (ℙ : Measure Ω) := Memℒp.isProbabilityMeasure_of_indepFun + have : IsProbabilityMeasure μ := Memℒp.isProbabilityMeasure_of_indepFun (X 0) (X 1) (zero_lt_one.trans_le hp).ne' hp' hℒp h (hindep zero_ne_one) - have hmeas : ∀ i, AEStronglyMeasurable (X i) ℙ := fun i => + have hmeas : ∀ i, AEStronglyMeasurable (X i) μ := fun i => (hident i).aestronglyMeasurable_iff.2 hℒp.1 - have hint : Integrable (X 0) ℙ := hℒp.integrable hp - have havg : ∀ (n : ℕ), - AEStronglyMeasurable (fun ω => (n : ℝ) ⁻¹ • (∑ i ∈ range n, X i ω)) ℙ := by - intro n - exact AEStronglyMeasurable.const_smul (aestronglyMeasurable_sum _ fun i _ => hmeas i) _ + have hint : Integrable (X 0) μ := hℒp.integrable hp + have havg (n : ℕ) : + AEStronglyMeasurable (fun ω => (n : ℝ) ⁻¹ • (∑ i ∈ range n, X i ω)) μ := + AEStronglyMeasurable.const_smul (aestronglyMeasurable_sum _ fun i _ => hmeas i) _ refine tendsto_Lp_finite_of_tendstoInMeasure hp hp' havg (memℒp_const _) ?_ (tendstoInMeasure_of_tendsto_ae havg (strong_law_ae _ hint hindep hident)) rw [(_ : (fun (n : ℕ) ω => (n : ℝ)⁻¹ • (∑ i ∈ range n, X i ω)) From 1dd1a104324ab698754a2e288b7c6750f7729c34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Degenne?= Date: Sun, 13 Oct 2024 11:01:00 +0000 Subject: [PATCH 059/425] feat(Probability/Kernel): `IsFiniteKernel` instances (#17681) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `IsFiniteKernel` instances for `withDensity η (rnDeriv κ η)` and `singularPart κ η`. --- .../MeasureTheory/Decomposition/RadonNikodym.lean | 3 +++ Mathlib/Probability/Kernel/RadonNikodym.lean | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/Mathlib/MeasureTheory/Decomposition/RadonNikodym.lean b/Mathlib/MeasureTheory/Decomposition/RadonNikodym.lean index f2347396e6fc35..83a31d388715d6 100644 --- a/Mathlib/MeasureTheory/Decomposition/RadonNikodym.lean +++ b/Mathlib/MeasureTheory/Decomposition/RadonNikodym.lean @@ -305,6 +305,9 @@ lemma setLIntegral_rnDeriv_le (s : Set α) : @[deprecated (since := "2024-06-29")] alias set_lintegral_rnDeriv_le := setLIntegral_rnDeriv_le +lemma lintegral_rnDeriv_le : ∫⁻ x, μ.rnDeriv ν x ∂ν ≤ μ Set.univ := + (setLIntegral_univ _).symm ▸ Measure.setLIntegral_rnDeriv_le Set.univ + lemma setLIntegral_rnDeriv' [HaveLebesgueDecomposition μ ν] (hμν : μ ≪ ν) {s : Set α} (hs : MeasurableSet s) : ∫⁻ x in s, μ.rnDeriv ν x ∂ν = μ s := by diff --git a/Mathlib/Probability/Kernel/RadonNikodym.lean b/Mathlib/Probability/Kernel/RadonNikodym.lean index 9b011fdfed3240..9e0392d8f287bc 100644 --- a/Mathlib/Probability/Kernel/RadonNikodym.lean +++ b/Mathlib/Probability/Kernel/RadonNikodym.lean @@ -534,4 +534,19 @@ lemma eq_singularPart (h : κ = η.withDensity f + ξ) end Unique +instance [hκ : IsFiniteKernel κ] [IsFiniteKernel η] : + IsFiniteKernel (withDensity η (rnDeriv κ η)) := by + refine ⟨hκ.bound, hκ.bound_lt_top, fun a ↦ ?_⟩ + rw [Kernel.withDensity_apply', setLIntegral_univ] + swap; · exact measurable_rnDeriv κ η + rw [lintegral_congr_ae rnDeriv_eq_rnDeriv_measure] + exact Measure.lintegral_rnDeriv_le.trans (measure_le_bound _ _ _) + +instance [hκ : IsFiniteKernel κ] [IsFiniteKernel η] : IsFiniteKernel (singularPart κ η) := by + refine ⟨hκ.bound, hκ.bound_lt_top, fun a ↦ ?_⟩ + have h : withDensity η (rnDeriv κ η) a univ + singularPart κ η a univ = κ a univ := by + conv_rhs => rw [← rnDeriv_add_singularPart κ η] + simp + exact (self_le_add_left _ _).trans (h.le.trans (measure_le_bound _ _ _)) + end ProbabilityTheory.Kernel From 81d66bb893988a10f0e7f3b5baa2f8bc0f35993f Mon Sep 17 00:00:00 2001 From: Kyle Miller Date: Sun, 13 Oct 2024 11:16:27 +0000 Subject: [PATCH 060/425] chore: more adaptations for lean4#5542 (#17688) In [lean4#5542](https://github.com/leanprover/lean4/pull/5542) we are deprecating `inductive ... :=`, `structure ... :=`, and `class ... :=` for their `... where` counterparts. Continuation of #17655. --- test/Simps.lean | 2 +- test/Traversable.lean | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Simps.lean b/test/Simps.lean index af1bc4b6f4a5eb..cb6c499476837b 100644 --- a/test/Simps.lean +++ b/test/Simps.lean @@ -101,7 +101,7 @@ infix:25 (priority := default+1) " ≃ " => Equiv' /- Since `prod` and `PProd` are a special case for `@[simps]`, we define a new structure to test the basic functionality.-/ -structure MyProd (α β : Type _) := (fst : α) (snd : β) +structure MyProd (α β : Type _) where (fst : α) (snd : β) def MyProd.map {α α' β β'} (f : α → α') (g : β → β') (x : MyProd α β) : MyProd α' β' := ⟨f x.1, g x.2⟩ diff --git a/test/Traversable.lean b/test/Traversable.lean index 136433f0ae4ea0..ae7c2e2279e617 100644 --- a/test/Traversable.lean +++ b/test/Traversable.lean @@ -34,7 +34,7 @@ inductive RecData (α : Type u) : Type u #guard_msgs (drop info) in #synth LawfulTraversable RecData -unsafe structure MetaStruct (α : Type u) : Type u := +unsafe structure MetaStruct (α : Type u) : Type u where x : α y : ℤ z : List α From 1a7af1321b0f26658007033f2f7efa27c8642219 Mon Sep 17 00:00:00 2001 From: Johan Commelin Date: Sun, 13 Oct 2024 13:23:28 +0200 Subject: [PATCH 061/425] chore: adaptations for nightly-2024-10-10 (#17657) Co-authored-by: leanprover-community-mathlib4-bot Co-authored-by: adomani Co-authored-by: Kyle Miller --- lake-manifest.json | 10 ++++---- lean-toolchain | 2 +- test/AdmitLinter.lean | 4 ++-- test/DeriveFintype.lean | 4 ++-- test/DualNumber.lean | 3 +++ test/FlexibleLinter.lean | 16 +------------ test/HashCommandLinter.lean | 10 ++++---- test/Lint.lean | 38 +++++------------------------- test/LintStyle.lean | 17 +------------ test/MinImports.lean | 9 +------ test/RefineLinter.lean | 3 +-- test/UnusedTactic.lean | 4 +--- test/dfinsupp_notation.lean | 6 ----- test/finsupp_notation.lean | 3 --- test/globalAttributeIn.lean | 8 ------- test/jacobiSym.lean | 3 +++ test/oldObtain.lean | 4 +--- test/random.lean | 12 +++++++--- test/success_if_fail_with_msg.lean | 3 --- 19 files changed, 41 insertions(+), 118 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index cb03203b6f6211..8dbc5a9f315905 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,17 +5,17 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "daf1ed91789811cf6bbb7bf2f4dad6b3bad8fbf4", + "rev": "b8b985f203e1f2f590e3ce46b50d722cc2ba8692", "name": "batteries", "manifestFile": "lake-manifest.json", - "inputRev": "main", + "inputRev": "nightly-testing", "inherited": false, "configFile": "lakefile.lean"}, {"url": "https://github.com/leanprover-community/quote4", "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "2b2f6d7fbe9d917fc010e9054c1ce11774c9088b", + "rev": "fa3d73a2cf077f4b14c7840352ac7b08aeb6eb41", "name": "Qq", "manifestFile": "lake-manifest.json", "inputRev": "master", @@ -44,7 +44,7 @@ {"url": "https://github.com/leanprover/lean4-cli", "type": "git", "subDir": null, - "scope": "", + "scope": "leanprover", "rev": "2cf1030dc2ae6b3632c84a09350b675ef3e347d0", "name": "Cli", "manifestFile": "lake-manifest.json", @@ -55,7 +55,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "16b29255b0f85e924cd32a6d5b5a275848b47903", + "rev": "9b4088ccf0f44ddd7b1132bb1348aef8cf481e12", "name": "importGraph", "manifestFile": "lake-manifest.json", "inputRev": "main", diff --git a/lean-toolchain b/lean-toolchain index 00aa67ea747271..712a96012abe9b 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-08 +leanprover/lean4:nightly-2024-10-10 diff --git a/test/AdmitLinter.lean b/test/AdmitLinter.lean index 8c7ddf13f19e3d..a751765d5f0adf 100644 --- a/test/AdmitLinter.lean +++ b/test/AdmitLinter.lean @@ -1,5 +1,7 @@ import Mathlib.Tactic.Linter.AdmitLinter +set_option linter.admit true + /-- warning: declaration uses 'sorry' --- @@ -7,7 +9,6 @@ warning: The `admit` tactic is discouraged: please consider using the synonymous note: this linter can be disabled with `set_option linter.admit false` -/ #guard_msgs in -set_option linter.admit true in example : True := by admit /-- @@ -26,7 +27,6 @@ warning: The `admit` tactic is discouraged: please consider using the synonymous note: this linter can be disabled with `set_option linter.admit false` -/ #guard_msgs in -set_option linter.admit true in example : True ∧ True := by have : True := by · admit diff --git a/test/DeriveFintype.lean b/test/DeriveFintype.lean index 423883d50da0e3..8f995c6ce28430 100644 --- a/test/DeriveFintype.lean +++ b/test/DeriveFintype.lean @@ -57,7 +57,7 @@ info: instFintypeC example : (Finset.univ : Finset (C Bool)) = Finset.univ.image .c := rfl -inductive C' (P : Prop) | c (h : P) +inductive C' (P : Prop) : Type | c (h : P) deriving Fintype /-- info: instFintypeC'OfDecidable -/ @@ -81,7 +81,7 @@ info: instFintypeC #synth Fintype (C α) end -inductive D (p : Prop) | d (h : p) +inductive D (p : Prop) : Type | d (h : p) deriving Fintype section diff --git a/test/DualNumber.lean b/test/DualNumber.lean index a98ec3702d0c05..b8a4eb86df2fec 100644 --- a/test/DualNumber.lean +++ b/test/DualNumber.lean @@ -2,6 +2,9 @@ import Mathlib.Algebra.DualNumber open DualNumber +-- TODO(kmill): make a ToExpr instance for DualNumber +set_option eval.pp false + /-- info: 0 + 0*ε -/ #guard_msgs in #eval (0 : ℕ[ε]) diff --git a/test/FlexibleLinter.lean b/test/FlexibleLinter.lean index 75ff835bdc5a3c..d6d26d250e223d 100644 --- a/test/FlexibleLinter.lean +++ b/test/FlexibleLinter.lean @@ -3,7 +3,7 @@ import Mathlib.Tactic.Linter.FlexibleLinter import Mathlib.Tactic.Abel import Mathlib.Tactic.Ring -set_option linter.flexible false +set_option linter.flexible true /-- warning: 'simp at h' is a flexible tactic modifying 'h'… @@ -12,7 +12,6 @@ note: this linter can be disabled with `set_option linter.flexible false` info: … and 'exact h' uses 'h'! -/ #guard_msgs in -set_option linter.flexible true in example (h : 0 + 0 = 0) : True := by simp at h try exact h @@ -45,7 +44,6 @@ note: this linter can be disabled with `set_option linter.flexible false` info: … and 'assumption' uses '⊢'! -/ #guard_msgs in -set_option linter.flexible true in example {a b : Nat} (h : a = b) : a + 0 = b := by simp induction a <;> assumption @@ -58,7 +56,6 @@ note: this linter can be disabled with `set_option linter.flexible false` info: … and 'exact h' uses 'h'! -/ #guard_msgs in -set_option linter.flexible true in example (h : 0 = 0 ∨ 0 = 0) : True := by cases h <;> rename_i h <;> @@ -78,7 +75,6 @@ note: this linter can be disabled with `set_option linter.flexible false` info: … and 'contradiction' uses '⊢'! -/ #guard_msgs in -set_option linter.flexible true in example (h : 0 = 1 ∨ 0 = 1) : 0 = 1 ∧ 0 = 1 := by cases h <;> simp on_goal 2 => · contradiction @@ -100,7 +96,6 @@ note: this linter can be disabled with `set_option linter.flexible false` info: … and 'contradiction' uses '⊢'! -/ #guard_msgs in -set_option linter.flexible true in example (h : 0 = 1 ∨ 0 = 1) : 0 = 1 ∧ 0 = 1 := by cases h <;> simp · contradiction @@ -119,7 +114,6 @@ info: … and 'rw [← Classical.not_not (a := True)] at h' uses 'h'! -/ #guard_msgs in -- `simp at h` stains `h` but not other locations -set_option linter.flexible true in example {h : 0 = 0} {k : 1 = 1} : True := by simp at h k; rw [← Classical.not_not (a := True)] @@ -149,7 +143,6 @@ info: … and 'rw [add_comm]' uses '⊢'! -/ #guard_msgs in -- `norm_num` is allowed after `simp`, but "passes along the stain". -set_option linter.flexible true in example {a : Rat} : a + (0 + 2 + 1 : Rat) = 3 + a := by simp norm_num @@ -163,7 +156,6 @@ info: … and 'exact h.symm' uses '⊢'! -/ #guard_msgs in -- `congr` is allowed after `simp`, but "passes along the stain". -set_option linter.flexible true in example {a b : Nat} (h : a = b) : a + b + 0 = b + a := by simp congr @@ -208,7 +200,6 @@ note: this linter can be disabled with `set_option linter.flexible false` info: … and 'contradiction' uses '⊢'! -/ #guard_msgs in -set_option linter.flexible true in example (h : 0 = 1 ∨ 0 = 1) : 0 = 1 ∧ 0 = 1 := by cases h <;> simp · simp_all @@ -234,7 +225,6 @@ note: this linter can be disabled with `set_option linter.flexible false` info: … and 'rw [← Classical.not_not (a := True)] at h' uses 'h'! -/ #guard_msgs in -set_option linter.flexible true in -- `simp at h` stains `h` but not other locations example {h : 0 = 0} {k : 1 = 1} : ¬ ¬ True := by simp at h @@ -256,7 +246,6 @@ note: this linter can be disabled with `set_option linter.flexible false` info: … and 'rw [← Classical.not_not (a := True)] at h' uses 'h'! -/ #guard_msgs in -set_option linter.flexible true in -- `simp at h` stains `h` but not other locations example {h : 0 = 0} {k : 1 = 1} : True := by simp at h k @@ -274,7 +263,6 @@ info: … and 'rw [← Classical.not_not (a := True)] at h' uses 'h'! -/ #guard_msgs in -- `simp at h` stains `h` but not other locations -set_option linter.flexible true in example {h : 0 = 0} : True := by simp at h rw [← Classical.not_not (a := True)] @@ -289,7 +277,6 @@ note: this linter can be disabled with `set_option linter.flexible false` info: … and 'rwa [← Classical.not_not (a := False)]' uses '⊢'! -/ #guard_msgs in -set_option linter.flexible true in example {h : False} : 0 = 1 := by simp rw [← Classical.not_not (a := False)] at h @@ -303,7 +290,6 @@ note: this linter can be disabled with `set_option linter.flexible false` info: … and 'rwa [← Classical.not_not (a := False)]' uses '⊢'! -/ #guard_msgs in -set_option linter.flexible true in example {h : False} : 0 = 1 ∧ 0 = 1 := by constructor · simpa diff --git a/test/HashCommandLinter.lean b/test/HashCommandLinter.lean index 203db4657db9e0..073acaf21b07ad 100644 --- a/test/HashCommandLinter.lean +++ b/test/HashCommandLinter.lean @@ -6,11 +6,8 @@ set_option linter.hashCommand true section ignored_commands --- `#guard_msgs in` without a doc-string triggers the linter, but with the `doc-string does not -/-- -warning: `#`-commands, such as '#guard_msgs', are not allowed in 'Mathlib' -note: this linter can be disabled with `set_option linter.hashCommand false` --/ +-- As a consequence of lean4#5644, `#guard_msgs in`, even without a doc-string, +-- does not triggers the `#`-command linter. #guard_msgs in #guard_msgs in #adaptation_note /-- testing that the hashCommand linter ignores this. -/ @@ -31,7 +28,8 @@ note: this linter can be disabled with `set_option linter.hashCommand false` #check 0 /-- -info: +warning: `#`-commands, such as '#eval', are not allowed in 'Mathlib' +note: this linter can be disabled with `set_option linter.hashCommand false` -/ #guard_msgs in -- emits an empty message -- the linter allows it diff --git a/test/Lint.lean b/test/Lint.lean index 25bf9c9147d13b..6887d8c4a350ec 100644 --- a/test/Lint.lean +++ b/test/Lint.lean @@ -2,17 +2,11 @@ import Mathlib.Tactic.Linter.Lint import Mathlib.Tactic.ToAdditive import Mathlib.Order.SetNotation --- TODO: the linter also runs on the #guard_msg, so disable it once --- See https://leanprover.zulipchat.com/#narrow/stream/348111-std4/topic/.23guard_msgs.20doesn't.20silence.20warnings/near/423534679 - -set_option linter.dupNamespace false - /-- warning: The namespace 'add' is duplicated in the declaration 'add.add' note: this linter can be disabled with `set_option linter.dupNamespace false` -/ #guard_msgs in -set_option linter.dupNamespace true in def add.add := True namespace Foo @@ -22,7 +16,6 @@ warning: The namespace 'Foo' is duplicated in the declaration 'Foo.Foo.foo' note: this linter can be disabled with `set_option linter.dupNamespace false` -/ #guard_msgs in -set_option linter.dupNamespace true in def Foo.foo := True -- the `dupNamespace` linter does not notice that `to_additive` created `Foo.add.add`. @@ -41,7 +34,6 @@ 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` -/ #guard_msgs in -set_option linter.dupNamespace true in alias Nat.Nats := Nat end Nat @@ -54,14 +46,12 @@ warning: The namespace 'add' is duplicated in the declaration 'add.add' note: this linter can be disabled with `set_option linter.dupNamespace false` -/ #guard_msgs in -set_option linter.dupNamespace true in export Nat (add) end add section cdotLinter - -set_option linter.style.cdot false +set_option linter.style.cdot true set_option linter.globalAttributeIn false in /-- @@ -75,7 +65,6 @@ warning: Please, use '·' (typed as `\.`) instead of '.' as 'cdot'. note: this linter can be disabled with `set_option linter.style.cdot false` -/ #guard_msgs in -set_option linter.style.cdot true in attribute [instance] Int.add in instance : Inhabited Nat where default := by @@ -83,13 +72,11 @@ instance : Inhabited Nat where · have : Nat → Nat → Nat := (· + .) . exact 0 -set_option linter.style.cdot false in /-- warning: Please, use '·' (typed as `\.`) instead of '.' as 'cdot'. note: this linter can be disabled with `set_option linter.style.cdot false` -/ #guard_msgs in -set_option linter.style.cdot true in example : Add Nat where add := (. + ·) /-- @@ -97,7 +84,6 @@ warning: Please, use '·' (typed as `\.`) instead of '.' as 'cdot'. note: this linter can be disabled with `set_option linter.style.cdot false` -/ #guard_msgs in -set_option linter.style.cdot true in example : Add Nat where add := (. + ·) /-- @@ -109,7 +95,6 @@ warning: This central dot `·` is isolated; please merge it with the next line. warning: This central dot `·` is isolated; please merge it with the next line. -/ #guard_msgs in -set_option linter.style.cdot true in example : Nat := by have : Nat := by · @@ -123,7 +108,6 @@ example : Nat := by exact 0 #guard_msgs in -set_option linter.style.cdot true in example : True := by have : Nat := by -- This is how code should look: no error. @@ -132,9 +116,9 @@ example : True := by trivial end cdotLinter +set_option linter.style.dollarSyntax true set_option linter.globalAttributeIn false in -set_option linter.style.dollarSyntax false in /-- warning: Please use '<|' instead of '$' for the pipe operator. note: this linter can be disabled with `set_option linter.style.dollarSyntax false` @@ -143,7 +127,6 @@ warning: Please use '<|' instead of '$' for the pipe operator. note: this linter can be disabled with `set_option linter.style.dollarSyntax false` -/ #guard_msgs in -set_option linter.style.dollarSyntax true in attribute [instance] Int.add in instance (f g : Nat → Nat) : Inhabited Nat where default := by @@ -153,7 +136,7 @@ instance (f g : Nat → Nat) : Inhabited Nat where section lambdaSyntaxLinter -set_option linter.style.lambdaSyntax false +set_option linter.style.lambdaSyntax true /-- warning: Please use 'fun' and not 'λ' to define anonymous functions. @@ -161,7 +144,6 @@ The 'λ' syntax is deprecated in mathlib4. note: this linter can be disabled with `set_option linter.style.lambdaSyntax false` -/ #guard_msgs in -set_option linter.style.lambdaSyntax true in example : ℕ → ℕ := λ _ ↦ 0 /-- @@ -170,7 +152,6 @@ The 'λ' syntax is deprecated in mathlib4. note: this linter can be disabled with `set_option linter.style.lambdaSyntax false` -/ #guard_msgs in -set_option linter.style.lambdaSyntax true in def foo : Bool := by let _f : ℕ → ℕ := λ _ ↦ 0 exact true @@ -183,7 +164,6 @@ The 'λ' syntax is deprecated in mathlib4. note: this linter can be disabled with `set_option linter.style.lambdaSyntax false` -/ #guard_msgs in -set_option linter.style.lambdaSyntax true in example : ℕ → ℕ := by exact λ n ↦ 3 * n + 1 /-- @@ -202,7 +182,6 @@ The 'λ' syntax is deprecated in mathlib4. note: this linter can be disabled with `set_option linter.style.lambdaSyntax false` -/ #guard_msgs in -set_option linter.style.lambdaSyntax true in example : ℕ → ℕ → ℕ → ℕ := by have (n : ℕ) : True := trivial have : (Set.univ : Set ℕ) = ⋃ (i : ℕ), (Set.iUnion λ j ↦ ({0, j} : Set ℕ)) := sorry @@ -223,7 +202,6 @@ The 'λ' syntax is deprecated in mathlib4. note: this linter can be disabled with `set_option linter.style.lambdaSyntax false` -/ #guard_msgs in -set_option linter.style.lambdaSyntax true in example : True := by have : 0 = 0 ∧ 0 = 0 ∧ 1 + 3 = 4 := by refine ⟨by trivial, by @@ -245,27 +223,24 @@ The 'λ' syntax is deprecated in mathlib4. note: this linter can be disabled with `set_option linter.style.lambdaSyntax false` -/ #guard_msgs in -set_option linter.style.lambdaSyntax true in -example : ℕ → ℕ := set_option linter.style.lambdaSyntax false in λ _ ↦ 0 +example : ℕ → ℕ := λ _ ↦ 0 set_option linter.style.lambdaSyntax false #guard_msgs in -example : ℕ → ℕ := set_option linter.style.lambdaSyntax true in λ _ ↦ 0 +example : ℕ → ℕ := λ _ ↦ 0 end lambdaSyntaxLinter -set_option linter.style.longLine false +set_option linter.style.longLine true /-- warning: This line exceeds the 100 character limit, please shorten it! note: this linter can be disabled with `set_option linter.style.longLine false` -/ #guard_msgs in -set_option linter.style.longLine true in /-! -/ #guard_msgs in -- Lines with more than 100 characters containing URLs are allowed. -set_option linter.style.longLine true in /-! http -/ set_option linter.style.longLine true @@ -292,5 +267,4 @@ You can use "string gaps" to format long strings: within a string quotation, usi note: this linter can be disabled with `set_option linter.style.longLine false` -/ #guard_msgs in -set_option linter.style.longLine true in #check " \" " diff --git a/test/LintStyle.lean b/test/LintStyle.lean index 7a58c6c946e9e7..82826979b6f8cc 100644 --- a/test/LintStyle.lean +++ b/test/LintStyle.lean @@ -5,12 +5,7 @@ import Mathlib.Tactic.Common /-! Tests for the `setOption` linter -/ section setOption - --- The warning generated by `linter.style.setOption` is not suppressed by `#guard_msgs`, --- because the linter is run on `#guard_msgs` itself. This is a known issue, see e.g. --- https://leanprover.zulipchat.com/#narrow/stream/348111-batteries/topic/unreachableTactic.20linter.20not.20suppressed.20by.20.60.23guard_msgs.60 --- We jump through an extra hoop here to silence the warning. -set_option linter.style.setOption false +set_option linter.style.setOption true -- All types of options are supported: boolean, numeric and string-valued. -- On the top level, i.e. as commands. @@ -22,7 +17,6 @@ Mathlib project, please remove 'set_option pp.all'. note: this linter can be disabled with `set_option linter.style.setOption false` -/ #guard_msgs in -set_option linter.style.setOption true in set_option pp.all true /-- @@ -32,7 +26,6 @@ Mathlib project, please remove 'set_option profiler'. note: this linter can be disabled with `set_option linter.style.setOption false` -/ #guard_msgs in -set_option linter.style.setOption true in set_option profiler false /-- @@ -42,7 +35,6 @@ Mathlib project, please remove 'set_option pp.all'. note: this linter can be disabled with `set_option linter.style.setOption false` -/ #guard_msgs in -set_option linter.style.setOption true in set_option pp.all false /-- @@ -52,7 +44,6 @@ Mathlib project, please remove 'set_option profiler.threshold'. note: this linter can be disabled with `set_option linter.style.setOption false` -/ #guard_msgs in -set_option linter.style.setOption true in set_option profiler.threshold 50 /-- @@ -62,7 +53,6 @@ Mathlib project, please remove 'set_option trace.profiler.output'. note: this linter can be disabled with `set_option linter.style.setOption false` -/ #guard_msgs in -set_option linter.style.setOption true in set_option trace.profiler.output "foo" /-- @@ -72,7 +62,6 @@ Mathlib project, please remove 'set_option debug.moduleNameAtTimeout'. note: this linter can be disabled with `set_option linter.style.setOption false` -/ #guard_msgs in -set_option linter.style.setOption true in set_option debug.moduleNameAtTimeout false -- The lint does not fire on arbitrary options. @@ -87,7 +76,6 @@ Mathlib project, please remove 'set_option pp.all'. note: this linter can be disabled with `set_option linter.style.setOption false` -/ #guard_msgs in -set_option linter.style.setOption true in lemma tactic : True := by set_option pp.all true in trivial @@ -99,7 +87,6 @@ Mathlib project, please remove 'set_option pp.raw.maxDepth'. note: this linter can be disabled with `set_option linter.style.setOption false` -/ #guard_msgs in -set_option linter.style.setOption true in lemma tactic2 : True := by set_option pp.raw.maxDepth 32 in trivial @@ -111,7 +98,6 @@ Mathlib project, please remove 'set_option pp.all'. note: this linter can be disabled with `set_option linter.style.setOption false` -/ #guard_msgs in -set_option linter.style.setOption true in lemma tactic3 : True := by set_option pp.all false in trivial @@ -123,7 +109,6 @@ Mathlib project, please remove 'set_option trace.profiler.output'. note: this linter can be disabled with `set_option linter.style.setOption false` -/ #guard_msgs in -set_option linter.style.setOption true in lemma tactic4 : True := by set_option trace.profiler.output "foo" in trivial diff --git a/test/MinImports.lean b/test/MinImports.lean index abf1594c8f5650..e14a41012d3c09 100644 --- a/test/MinImports.lean +++ b/test/MinImports.lean @@ -74,18 +74,17 @@ import Mathlib.Data.Nat.Notation #min_imports in lemma hi (n : ℕ) : n = n := by extract_goal; rfl +set_option linter.minImports true /-- warning: Imports increased to [Init.Guard, Mathlib.Data.Int.Notation] note: this linter can be disabled with `set_option linter.minImports false` -/ #guard_msgs in -set_option linter.minImports true in #guard (0 : ℤ) = 0 #guard_msgs in -- no new imports needed here, so no message -set_option linter.minImports true in #guard (0 : ℤ) = 0 set_option linter.minImports false in @@ -98,14 +97,8 @@ note: this linter can be disabled with `set_option linter.minImports false` -/ #guard_msgs in -- again, the imports pick-up, after the reset -set_option linter.minImports true in #guard (0 : ℤ) = 0 --- finally, we leave the linter "on", to give it a chance to parse `eoi` --- and to silence it, we make sure to put in a command for each import - -set_option linter.minImports true - /-- warning: Imports increased to [Mathlib.Tactic.Linter.MinImports] diff --git a/test/RefineLinter.lean b/test/RefineLinter.lean index 241609de243c99..75319bebdc7f86 100644 --- a/test/RefineLinter.lean +++ b/test/RefineLinter.lean @@ -1,6 +1,6 @@ import Mathlib.Tactic.Linter.RefineLinter -set_option linter.refine false +set_option linter.refine true /-- warning: The `refine'` tactic is discouraged: please strongly consider using `refine` or `apply` instead. @@ -11,6 +11,5 @@ The `refine'` tactic is discouraged: please strongly consider using `refine` or note: this linter can be disabled with `set_option linter.refine false` -/ #guard_msgs in -set_option linter.refine true in example : True := by refine' (by refine' .intro) diff --git a/test/UnusedTactic.lean b/test/UnusedTactic.lean index e12d30af91f30a..e81739bb01e4de 100644 --- a/test/UnusedTactic.lean +++ b/test/UnusedTactic.lean @@ -11,7 +11,7 @@ example : True := by example : True ∧ True := by constructor <;> trivial; -set_option linter.unusedTactic false +set_option linter.unusedTactic true /-- warning: 'congr' tactic does nothing note: this linter can be disabled with `set_option linter.unusedTactic false` @@ -20,7 +20,6 @@ warning: 'done' tactic does nothing note: this linter can be disabled with `set_option linter.unusedTactic false` -/ #guard_msgs in -set_option linter.unusedTactic true in -- the linter notices that `congr` is unused example : True := by congr @@ -32,7 +31,6 @@ section allowing_more_unused_tactics #allow_unused_tactic Lean.Parser.Tactic.done Lean.Parser.Tactic.skip #guard_msgs in -set_option linter.unusedTactic true in example : True := by skip constructor diff --git a/test/dfinsupp_notation.lean b/test/dfinsupp_notation.lean index ed6511532b5f91..e4988503d7f41c 100644 --- a/test/dfinsupp_notation.lean +++ b/test/dfinsupp_notation.lean @@ -7,18 +7,12 @@ example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4 : Π₀ i, Fin (i + 10)) 1 = 3 := by example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4 : Π₀ i, Fin (i + 10)) 2 = 3 := by simp example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4 : Π₀ i, Fin (i + 10)) 3 = 4 := by simp -/-- -info: --/ #guard_msgs in #eval show Lean.MetaM Unit from guard <| reprStr (fun₀ | 1 => 3 | 2 => 3 : Π₀ i, Fin (i + 10)) = "fun₀ | 1 => 3 | 2 => 3" -/-- -info: --/ #guard_msgs in #eval show Lean.MetaM Unit from guard <| diff --git a/test/finsupp_notation.lean b/test/finsupp_notation.lean index e042b67a8903f0..89651a952e342a 100644 --- a/test/finsupp_notation.lean +++ b/test/finsupp_notation.lean @@ -12,9 +12,6 @@ example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4) 2 = 3 := by example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4) 3 = 4 := by simp -/-- -info: --/ #guard_msgs in #eval show Lean.MetaM Unit from guard <| diff --git a/test/globalAttributeIn.lean b/test/globalAttributeIn.lean index 13716057e16c33..793a51c174f087 100644 --- a/test/globalAttributeIn.lean +++ b/test/globalAttributeIn.lean @@ -25,7 +25,6 @@ instance : Inhabited Int where -- Global instances with `in`, are linted, as they are a footgun. -set_option linter.globalAttributeIn false in /-- warning: Despite the `in`, the attribute 'instance 1100' is added globally to 'Int.add' please remove the `in` or make this a `local instance 1100` @@ -33,32 +32,27 @@ note: this linter can be disabled with `set_option linter.globalAttributeIn fals -/ #guard_msgs in set_option autoImplicit false in -set_option linter.globalAttributeIn true in attribute [instance 1100] Int.add in set_option autoImplicit false in instance : Inhabited Int where default := 0 -set_option linter.globalAttributeIn false in /-- warning: Despite the `in`, the attribute 'instance' is added globally to 'Int.add' please remove the `in` or make this a `local instance` note: this linter can be disabled with `set_option linter.globalAttributeIn false` -/ #guard_msgs in -set_option linter.globalAttributeIn true in attribute [instance] Int.add in instance : Inhabited Int where default := 0 -set_option linter.globalAttributeIn false in /-- warning: Despite the `in`, the attribute 'simp' is added globally to 'Int.add' please remove the `in` or make this a `local simp` note: this linter can be disabled with `set_option linter.globalAttributeIn false` -/ #guard_msgs in -set_option linter.globalAttributeIn true in attribute [simp] Int.add in instance : Inhabited Int where default := 0 @@ -70,7 +64,6 @@ namespace X #guard_msgs in theorem foo (x y : Nat) : x = y := sorry -set_option linter.globalAttributeIn false in /-- warning: Despite the `in`, the attribute 'simp' is added globally to 'foo' please remove the `in` or make this a `local simp` @@ -81,7 +74,6 @@ please remove the `in` or make this a `local ext` note: this linter can be disabled with `set_option linter.globalAttributeIn false` -/ #guard_msgs in -set_option linter.globalAttributeIn true in attribute [simp, local simp, ext, scoped instance, -simp, -ext] foo in def bar := False diff --git a/test/jacobiSym.lean b/test/jacobiSym.lean index 916deb2aa2d2df..bb555a83210ac7 100644 --- a/test/jacobiSym.lean +++ b/test/jacobiSym.lean @@ -1,6 +1,9 @@ import Mathlib.NumberTheory.LegendreSymbol.JacobiSymbol import Mathlib.Tactic.NormNum.Prime +-- TODO(kmill): remove once the mathlib ToExpr Int instance is removed +set_option eval.pp false + section Csimp /-! diff --git a/test/oldObtain.lean b/test/oldObtain.lean index bdbf53e7e9e948..5a7bb3201701c8 100644 --- a/test/oldObtain.lean +++ b/test/oldObtain.lean @@ -7,7 +7,7 @@ import Mathlib.Tactic.Linter.OldObtain /-! Tests for the `oldObtain` linter. -/ -set_option linter.oldObtain false +set_option linter.oldObtain true -- These cases are fine. theorem foo : True := by @@ -24,7 +24,6 @@ warning: Please remove stream-of-conciousness `obtain` syntax note: this linter can be disabled with `set_option linter.oldObtain false` -/ #guard_msgs in -set_option linter.oldObtain true in theorem foo' : True := by obtain : True · trivial @@ -35,7 +34,6 @@ warning: Please remove stream-of-conciousness `obtain` syntax note: this linter can be disabled with `set_option linter.oldObtain false` -/ #guard_msgs in -set_option linter.oldObtain true in theorem foo'' : True := by obtain h : True · trivial diff --git a/test/random.lean b/test/random.lean index 057e3a275af45a..64c0b767faaf83 100644 --- a/test/random.lean +++ b/test/random.lean @@ -3,6 +3,9 @@ import Mathlib.Tactic.NormNum open Random +-- TODO(kmill): remove once the mathlib ToExpr Int instance is removed +set_option eval.pp false + section Rand /-- @@ -33,7 +36,8 @@ section RandT /-- info: Got 6 Got 27 -33 +--- +info: 33 -/ #guard_msgs in #eval show IO _ from do @@ -47,7 +51,8 @@ Got 27 /-- info: Got 6 Got 27 -33 +--- +info: 33 -/ #guard_msgs in #eval show Lean.Meta.MetaM _ from do @@ -62,7 +67,8 @@ Got 27 /-- info: Got 4 Got 4 -8 +--- +info: 8 -/ #guard_msgs in #eval show Lean.Meta.MetaM _ from do diff --git a/test/success_if_fail_with_msg.lean b/test/success_if_fail_with_msg.lean index 5f9f786e3ea3f9..1e190fde9d2c32 100644 --- a/test/success_if_fail_with_msg.lean +++ b/test/success_if_fail_with_msg.lean @@ -54,8 +54,5 @@ def doesntFail : MetaM Unit := do try successIfFailWithMessage "I failed!" alwaysFails catch _ => throwError "I *really* failed." -/-- -info: --/ #guard_msgs in #eval doesntFail From 626e646a45085713dacac5c222cfe6d768e8dd67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Sun, 13 Oct 2024 13:49:18 +0000 Subject: [PATCH 062/425] feat(PMF): A few more lemmas (#17698) From LeanCamCombi --- .../ProbabilityMassFunction/Constructions.lean | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Mathlib/Probability/ProbabilityMassFunction/Constructions.lean b/Mathlib/Probability/ProbabilityMassFunction/Constructions.lean index 31bbe40f16a4be..503b97db3cdf22 100644 --- a/Mathlib/Probability/ProbabilityMassFunction/Constructions.lean +++ b/Mathlib/Probability/ProbabilityMassFunction/Constructions.lean @@ -32,7 +32,7 @@ noncomputable section variable {α β γ : Type*} open scoped Classical -open NNReal ENNReal +open NNReal ENNReal Finset MeasureTheory section Map @@ -82,13 +82,19 @@ variable (s : Set β) theorem toOuterMeasure_map_apply : (p.map f).toOuterMeasure s = p.toOuterMeasure (f ⁻¹' s) := by simp [map, Set.indicator, toOuterMeasure_apply p (f ⁻¹' s)] +variable {mα : MeasurableSpace α} {mβ : MeasurableSpace β} + @[simp] -theorem toMeasure_map_apply [MeasurableSpace α] [MeasurableSpace β] (hf : Measurable f) +theorem toMeasure_map_apply (hf : Measurable f) (hs : MeasurableSet s) : (p.map f).toMeasure s = p.toMeasure (f ⁻¹' s) := by rw [toMeasure_apply_eq_toOuterMeasure_apply _ s hs, toMeasure_apply_eq_toOuterMeasure_apply _ (f ⁻¹' s) (measurableSet_preimage hf hs)] exact toOuterMeasure_map_apply f p s +@[simp] +lemma toMeasure_map (p : PMF α) (hf : Measurable f) : p.toMeasure.map f = (p.map f).toMeasure := by + ext s hs : 1; rw [PMF.toMeasure_map_apply _ _ _ hf hs, Measure.map_apply hf hs] + end Measure end Map @@ -185,6 +191,14 @@ theorem support_ofFintype : (ofFintype f h).support = Function.support f := rfl theorem mem_support_ofFintype_iff (a : α) : a ∈ (ofFintype f h).support ↔ f a ≠ 0 := Iff.rfl +@[simp] +lemma map_ofFintype [Fintype β] (f : α → ℝ≥0∞) (h : ∑ a, f a = 1) (g : α → β) : + (ofFintype f h).map g = ofFintype (fun b ↦ ∑ a with g a = b, f a) + (by simpa [Finset.sum_fiberwise_eq_sum_filter univ univ g f]) := by + ext b : 1 + simp only [sum_filter, eq_comm, map_apply, ofFintype_apply] + exact tsum_eq_sum fun _ h ↦ (h <| mem_univ _).elim + section Measure variable (s : Set α) From 3d44cf129e2a1defd3f806de73f8f0f3994c4ae2 Mon Sep 17 00:00:00 2001 From: Robin Carlier Date: Sun, 13 Oct 2024 14:07:50 +0000 Subject: [PATCH 063/425] feeat(CategoryTheory/Monoidal/Functor): Constructor for strong monoidal functors from oplax monoidal functors (#17691) Add a constructor `MonoidalFunctor.fromOplaxMonoidalFunctor` that converts an oplax monoidal functor to a monoidal functor, provided the tensorators ans unitors are isomorphims. --- Mathlib/CategoryTheory/Monoidal/Functor.lean | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Mathlib/CategoryTheory/Monoidal/Functor.lean b/Mathlib/CategoryTheory/Monoidal/Functor.lean index 1cd5fbc682a6ca..1581d1d32ba355 100644 --- a/Mathlib/CategoryTheory/Monoidal/Functor.lean +++ b/Mathlib/CategoryTheory/Monoidal/Functor.lean @@ -309,6 +309,27 @@ noncomputable def MonoidalFunctor.toOplaxMonoidalFunctor (F : MonoidalFunctor C rw [← F.map_comp, Iso.hom_inv_id, F.map_id] simp } +/-- Construct a (strong) monoidal functor out of an oplax monoidal functor whose tensorators and +unitors are isomorphisms -/ +@[simps] +noncomputable def MonoidalFunctor.fromOplaxMonoidalFunctor (F : OplaxMonoidalFunctor C D) + [IsIso F.η] [∀ (X Y : C), IsIso (F.δ X Y)] : MonoidalFunctor C D := + { F with + ε := inv F.η + μ := fun X Y => inv (F.δ X Y) + associativity := by + intro X Y Z + rw [← inv_whiskerRight, IsIso.inv_comp_eq, IsIso.inv_comp_eq] + simp + left_unitality := by + intro X + rw [← inv_whiskerRight, ← IsIso.inv_comp_eq] + simp + right_unitality := by + intro X + rw [← inv_whiskerLeft, ← IsIso.inv_comp_eq] + simp } + end open MonoidalCategory From 9d6891a766a51bbb1555a9dc2f503d47e7817f7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Sun, 13 Oct 2024 16:31:57 +0000 Subject: [PATCH 064/425] feat: `MeasurableSpace` instance for `AddChar` (#17275) This is stupid, but it's the only case I care about in APAP. Can be made less stupid later. From LeanAPAP --- Mathlib.lean | 1 + .../MeasureTheory/Constructions/AddChar.lean | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 Mathlib/MeasureTheory/Constructions/AddChar.lean diff --git a/Mathlib.lean b/Mathlib.lean index 9c48ed611ec6c0..3297901061da40 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3200,6 +3200,7 @@ import Mathlib.Logic.Small.Set import Mathlib.Logic.Unique import Mathlib.Logic.UnivLE import Mathlib.MeasureTheory.Category.MeasCat +import Mathlib.MeasureTheory.Constructions.AddChar import Mathlib.MeasureTheory.Constructions.BorelSpace.Basic import Mathlib.MeasureTheory.Constructions.BorelSpace.Complex import Mathlib.MeasureTheory.Constructions.BorelSpace.ContinuousLinearMap diff --git a/Mathlib/MeasureTheory/Constructions/AddChar.lean b/Mathlib/MeasureTheory/Constructions/AddChar.lean new file mode 100644 index 00000000000000..acc12ca8fcb9c7 --- /dev/null +++ b/Mathlib/MeasureTheory/Constructions/AddChar.lean @@ -0,0 +1,27 @@ +/- +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 +-/ +import Mathlib.Algebra.Group.AddChar +import Mathlib.MeasureTheory.MeasurableSpace.Defs + +/-! +# Measurable space instance for additive characters + +This file endows `AddChar A M` with the discrete measurable space structure whenever `A` and `M` +are themselves discrete measurable spaces. + +## TODO + +Give the definition in the correct generality. +-/ + +namespace AddChar +variable {A M : Type*} [AddMonoid A] [Monoid M] + [MeasurableSpace A] [DiscreteMeasurableSpace A] [MeasurableSpace M] [DiscreteMeasurableSpace M] + +instance instMeasurableSpace : MeasurableSpace (AddChar A M) := ⊤ +instance instDiscreteMeasurableSpace : DiscreteMeasurableSpace (AddChar A M) := ⟨fun _ ↦ trivial⟩ + +end AddChar From f0851b74e3121c838551def8cdc1d736bb0af57c Mon Sep 17 00:00:00 2001 From: Tobias Grosser Date: Sun, 13 Oct 2024 14:59:43 +0100 Subject: [PATCH 065/425] feat: add CommRing (BitVec w) --- Mathlib/Data/BitVec.lean | 75 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/Mathlib/Data/BitVec.lean b/Mathlib/Data/BitVec.lean index e3928ba4fb51cf..0de6798b599779 100644 --- a/Mathlib/Data/BitVec.lean +++ b/Mathlib/Data/BitVec.lean @@ -5,6 +5,12 @@ Authors: Simon Hudon, Harun Khan, Alex Keizer -/ import Mathlib.Algebra.Ring.InjSurj import Mathlib.Data.ZMod.Defs +import Mathlib.Tactic.Ring +import Mathlib.Data.Nat.Bitwise +import Mathlib.Algebra.Group.Fin.Basic +import Mathlib.Data.Nat.Bits +import Mathlib.Data.ZMod.Defs + /-! # Basic Theorems About Bitvectors @@ -58,4 +64,73 @@ instance : CommSemiring (BitVec w) := (fun _ => rfl) /- toFin_natCast -/ -- The statement in the new API would be: `n#(k.succ) = ((n / 2)#k).concat (n % 2 != 0)` +theorem ofInt_negSucc (w n : Nat ) : + BitVec.ofInt w (Int.negSucc n) = ~~~.ofNat w n := by + simp [BitVec.ofInt] + rw [BitVec.toNat_eq] + simp only [Int.toNat, toNat_ofNatLt, toNat_not, toNat_ofNat] + split + · rename_i a b c + simp only [Int.ofNat_eq_coe] at c + rw [Int.negSucc_emod] at c + symm + rw [← Int.natCast_inj] + rw [Nat.cast_sub] + rw [Nat.cast_sub] + have _ : 0 < 2 ^ w := by simp + simp_all only [gt_iff_lt, Nat.ofNat_pos, pow_pos, Nat.cast_pow, + Nat.cast_ofNat, Nat.cast_one, Int.ofNat_emod] + have h : 0 < 2 ^ w := by simp + · omega + · omega + · omega + · have nonneg : Int.negSucc n % 2 ^ w ≥ 0 := by + simp only [ge_iff_le, ne_eq, pow_eq_zero_iff', OfNat.ofNat_ne_zero, false_and, + not_false_eq_true, Int.emod_nonneg (Int.negSucc n) _] + simp_all only [Nat.ofNat_pos, gt_iff_lt, pow_pos, ne_eq, pow_eq_zero_iff', + OfNat.ofNat_ne_zero, false_and, not_false_eq_true, ge_iff_le, Int.negSucc_not_nonneg] + +@[simp] lemma ofFin_neg {x : Fin (2 ^ w)} : ofFin (-x) = -(ofFin x) := by + ext; rw [neg_eq_zero_sub]; simp; rfl + +@[simp] lemma ofFin_ofNat (n : ℕ) : + ofFin (no_index (OfNat.ofNat n : Fin (2^w))) = OfNat.ofNat n := by + simp only [OfNat.ofNat, Fin.ofNat', BitVec.ofNat, Nat.and_pow_two_sub_one_eq_mod] + +theorem toFin_inj {x y : BitVec w} : x.toFin = y.toFin ↔ x = y := + toFin_injective.eq_iff + +@[simp] lemma ofFin_natCast (n : ℕ) : ofFin (n : Fin (2^w)) = n := by + simp only [Nat.cast, NatCast.natCast, OfNat.ofNat, BitVec.ofNat, Nat.and_pow_two_sub_one_eq_mod] + rfl + +lemma toFin_natCast (n : ℕ) : toFin (n : BitVec w) = n := by + rw [toFin_inj]; simp only [ofFin_natCast] + +theorem ofFin_intCast (z : ℤ) : ofFin (z : Fin (2^w)) = Int.cast z := by + cases w + case zero => + simp only [eq_nil] + case succ w => + simp only [Int.cast, IntCast.intCast] + unfold Int.castDef + cases' z with z z + · rfl + · rw [ofInt_negSucc] + simp only [Nat.cast_add, Nat.cast_one, neg_add_rev] + rw [← add_ofFin, ofFin_neg, ofFin_ofNat, ofNat_eq_ofNat, ofFin_neg, ofFin_natCast, + natCast_eq_ofNat, negOne_eq_allOnes, ← sub_toAdd, allOnes_sub_eq_not] + +theorem toFin_intCast (z : ℤ) : toFin (z : BitVec w) = z := by + apply toFin_inj.mpr <| (ofFin_intCast z).symm + +lemma toFin_zero : toFin (0 : BitVec w) = 0 := rfl +lemma toFin_one : toFin (1 : BitVec w) = 1 := by + rw [toFin_inj]; simp only [ofNat_eq_ofNat, ofFin_ofNat] + +instance : CommRing (BitVec w) := + toFin_injective.commRing _ + toFin_zero toFin_one toFin_add toFin_mul toFin_neg toFin_sub + toFin_nsmul toFin_zsmul toFin_pow toFin_natCast toFin_intCast + end BitVec From 6d3dd6391932c25a061785f6a5af2a4e169fed6a Mon Sep 17 00:00:00 2001 From: Tobias Grosser Date: Sun, 13 Oct 2024 15:03:46 +0100 Subject: [PATCH 066/425] chore: clean includes and ofInt_negSucc proof --- Mathlib/Data/BitVec.lean | 43 ++++++++++++---------------------------- 1 file changed, 13 insertions(+), 30 deletions(-) diff --git a/Mathlib/Data/BitVec.lean b/Mathlib/Data/BitVec.lean index 0de6798b599779..dd971a84ca1c5c 100644 --- a/Mathlib/Data/BitVec.lean +++ b/Mathlib/Data/BitVec.lean @@ -5,12 +5,7 @@ Authors: Simon Hudon, Harun Khan, Alex Keizer -/ import Mathlib.Algebra.Ring.InjSurj import Mathlib.Data.ZMod.Defs -import Mathlib.Tactic.Ring -import Mathlib.Data.Nat.Bitwise -import Mathlib.Algebra.Group.Fin.Basic -import Mathlib.Data.Nat.Bits -import Mathlib.Data.ZMod.Defs - +import Mathlib.Data.Nat.Cast.Order.Ring /-! # Basic Theorems About Bitvectors @@ -64,31 +59,19 @@ instance : CommSemiring (BitVec w) := (fun _ => rfl) /- toFin_natCast -/ -- The statement in the new API would be: `n#(k.succ) = ((n / 2)#k).concat (n % 2 != 0)` -theorem ofInt_negSucc (w n : Nat ) : +@[simp] theorem ofInt_negSucc {w n : Nat} : BitVec.ofInt w (Int.negSucc n) = ~~~.ofNat w n := by - simp [BitVec.ofInt] - rw [BitVec.toNat_eq] - simp only [Int.toNat, toNat_ofNatLt, toNat_not, toNat_ofNat] - split - · rename_i a b c - simp only [Int.ofNat_eq_coe] at c - rw [Int.negSucc_emod] at c - symm - rw [← Int.natCast_inj] - rw [Nat.cast_sub] - rw [Nat.cast_sub] - have _ : 0 < 2 ^ w := by simp - simp_all only [gt_iff_lt, Nat.ofNat_pos, pow_pos, Nat.cast_pow, - Nat.cast_ofNat, Nat.cast_one, Int.ofNat_emod] - have h : 0 < 2 ^ w := by simp - · omega - · omega - · omega - · have nonneg : Int.negSucc n % 2 ^ w ≥ 0 := by - simp only [ge_iff_le, ne_eq, pow_eq_zero_iff', OfNat.ofNat_ne_zero, false_and, - not_false_eq_true, Int.emod_nonneg (Int.negSucc n) _] - simp_all only [Nat.ofNat_pos, gt_iff_lt, pow_pos, ne_eq, pow_eq_zero_iff', - OfNat.ofNat_ne_zero, false_and, not_false_eq_true, ge_iff_le, Int.negSucc_not_nonneg] + simp only [BitVec.ofInt, Int.toNat, Int.ofNat_eq_coe, toNat_eq, toNat_ofNatLt, toNat_not, + toNat_ofNat] + cases h : Int.negSucc n % ((2 ^ w : Nat) : Int) + case ofNat => + rw [Int.ofNat_eq_coe, Int.negSucc_emod] at h + simp only + all_goals omega + case negSucc a => + have neg := Int.negSucc_lt_zero a + have _ : 0 ≤ Int.negSucc n % ((2 ^ w : Nat) : Int) := Int.emod_nonneg _ (by omega) + omega @[simp] lemma ofFin_neg {x : Fin (2 ^ w)} : ofFin (-x) = -(ofFin x) := by ext; rw [neg_eq_zero_sub]; simp; rfl From 1e0bf9d9afd9b3ab7bb1a46ad8e56d0145afcf3e Mon Sep 17 00:00:00 2001 From: Tobias Grosser Date: Sun, 13 Oct 2024 16:55:24 +0100 Subject: [PATCH 067/425] chore: drop unused include --- Mathlib/Data/BitVec.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/Data/BitVec.lean b/Mathlib/Data/BitVec.lean index dd971a84ca1c5c..8215159095be77 100644 --- a/Mathlib/Data/BitVec.lean +++ b/Mathlib/Data/BitVec.lean @@ -5,7 +5,6 @@ Authors: Simon Hudon, Harun Khan, Alex Keizer -/ import Mathlib.Algebra.Ring.InjSurj import Mathlib.Data.ZMod.Defs -import Mathlib.Data.Nat.Cast.Order.Ring /-! # Basic Theorems About Bitvectors From db823ad2e3410f1ac7398e8e87a0bc122e9e79fa Mon Sep 17 00:00:00 2001 From: Tobias Grosser Date: Sun, 13 Oct 2024 16:55:43 +0100 Subject: [PATCH 068/425] Update Mathlib/Data/BitVec.lean Co-authored-by: Mario Carneiro --- Mathlib/Data/BitVec.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Data/BitVec.lean b/Mathlib/Data/BitVec.lean index 8215159095be77..ba64ca16b6f234 100644 --- a/Mathlib/Data/BitVec.lean +++ b/Mathlib/Data/BitVec.lean @@ -89,7 +89,7 @@ theorem toFin_inj {x y : BitVec w} : x.toFin = y.toFin ↔ x = y := lemma toFin_natCast (n : ℕ) : toFin (n : BitVec w) = n := by rw [toFin_inj]; simp only [ofFin_natCast] -theorem ofFin_intCast (z : ℤ) : ofFin (z : Fin (2^w)) = Int.cast z := by +theorem ofFin_intCast (z : ℤ) : ofFin (z : Fin (2^w)) = ↑z := by cases w case zero => simp only [eq_nil] From 95c9826c87dc38877869388294a8a9876dd328ac Mon Sep 17 00:00:00 2001 From: Tobias Grosser Date: Sun, 13 Oct 2024 17:14:09 +0100 Subject: [PATCH 069/425] clean proof --- Mathlib/Data/BitVec.lean | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Mathlib/Data/BitVec.lean b/Mathlib/Data/BitVec.lean index ba64ca16b6f234..15c3c502cabf71 100644 --- a/Mathlib/Data/BitVec.lean +++ b/Mathlib/Data/BitVec.lean @@ -65,8 +65,9 @@ instance : CommSemiring (BitVec w) := cases h : Int.negSucc n % ((2 ^ w : Nat) : Int) case ofNat => rw [Int.ofNat_eq_coe, Int.negSucc_emod] at h - simp only - all_goals omega + · dsimp only + omega + · omega case negSucc a => have neg := Int.negSucc_lt_zero a have _ : 0 ≤ Int.negSucc n % ((2 ^ w : Nat) : Int) := Int.emod_nonneg _ (by omega) From 8ce376a7f9ad97c52ccf9c5bbb8aedc299344902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20B=C3=B6ving?= Date: Sun, 13 Oct 2024 18:35:54 +0200 Subject: [PATCH 070/425] fix it --- Mathlib/Data/UInt.lean | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Mathlib/Data/UInt.lean b/Mathlib/Data/UInt.lean index ddb06ac8604b83..11a59c1c7f8ffd 100644 --- a/Mathlib/Data/UInt.lean +++ b/Mathlib/Data/UInt.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Mario Carneiro -/ import Mathlib.Data.ZMod.Defs +import Mathlib.Data.BitVec /-! # Adds Mathlib specific instances to the `UIntX` data types. @@ -52,12 +53,15 @@ run_cmd open $typeName (eq_of_val_eq) in lemma val_injective : Function.Injective val := @eq_of_val_eq + open $typeName (eq_of_toBitVec_eq) in + lemma toBitVec_injective : Function.Injective toBitVec := @eq_of_toBitVec_eq + instance instCommMonoid : CommMonoid $typeName := - Function.Injective.commMonoid val val_injective + Function.Injective.commMonoid toBitVec toBitVec_injective rfl (fun _ _ => rfl) (fun _ _ => rfl) instance instNonUnitalCommRing : NonUnitalCommRing $typeName := - Function.Injective.nonUnitalCommRing val val_injective + Function.Injective.nonUnitalCommRing toBitVec toBitVec_injective rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) @@ -72,9 +76,9 @@ run_cmd lemma intCast_def (z : ℤ) : (z : $typeName) = ⟨z⟩ := rfl local instance instCommRing : CommRing $typeName := - Function.Injective.commRing val val_injective + Function.Injective.commRing toBitVec toBitVec_injective rfl rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ => sorry) + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ => rfl) namespace CommRing attribute [scoped instance] instCommRing instNatCast instIntCast From 6a98dbda3b518bc41f99919309f3571fe4f7a637 Mon Sep 17 00:00:00 2001 From: Robin Carlier Date: Sun, 13 Oct 2024 17:05:05 +0000 Subject: [PATCH 071/425] feat(CategoryTheory/ChosenFiniteProducts.lean): `simp` lemmas for left and right unitors in `ChosenFiniteProducts` monoidal structure (#17695) Add 4 `simp` lemmas for left and right unitors in the monoidal structure obtained from instances of `ChosenFiniteProducts`. --- Mathlib/CategoryTheory/ChosenFiniteProducts.lean | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Mathlib/CategoryTheory/ChosenFiniteProducts.lean b/Mathlib/CategoryTheory/ChosenFiniteProducts.lean index 7ae5f97b5511b6..4c342ebe1413b8 100644 --- a/Mathlib/CategoryTheory/ChosenFiniteProducts.lean +++ b/Mathlib/CategoryTheory/ChosenFiniteProducts.lean @@ -178,6 +178,22 @@ lemma associator_inv_fst_snd (X Y Z : C) : lemma associator_inv_snd (X Y Z : C) : (α_ X Y Z).inv ≫ snd _ _ = snd _ _ ≫ snd _ _ := lift_snd _ _ +@[reassoc (attr := simp)] +lemma leftUnitor_inv_fst (X : C) : + (λ_ X).inv ≫ fst _ _ = toUnit _ := toUnit_unique _ _ + +@[reassoc (attr := simp)] +lemma leftUnitor_inv_snd (X : C) : + (λ_ X).inv ≫ snd _ _ = 𝟙 X := lift_snd _ _ + +@[reassoc (attr := simp)] +lemma rightUnitor_inv_fst (X : C) : + (ρ_ X).inv ≫ fst _ _ = 𝟙 X := lift_fst _ _ + +@[reassoc (attr := simp)] +lemma rightUnitor_inv_snd (X : C) : + (ρ_ X).inv ≫ snd _ _ = toUnit _ := toUnit_unique _ _ + /-- Construct an instance of `ChosenFiniteProducts C` given an instance of `HasFiniteProducts C`. -/ From f55bf2cca801bc507674f1dd9e26a1b7b6b89f3b Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Sun, 13 Oct 2024 17:33:25 +0000 Subject: [PATCH 072/425] chore(*): replace `erw` with `rw` where possible (#17703) Go through Mathlib and replace `erw` calls where `rw` would also succeed. This PR is split off from #17638, containing all the changes that the linter suggested. Co-authored-by: Anne Baanen --- Archive/Wiedijk100Theorems/Partition.lean | 2 +- .../Category/ModuleCat/Presheaf/Sheafify.lean | 14 ++++---- Mathlib/Algebra/Homology/ShortComplex/Ab.lean | 6 ++-- .../ShortComplex/ConcreteCategory.lean | 2 +- Mathlib/AlgebraicGeometry/AffineScheme.lean | 4 +-- Mathlib/AlgebraicGeometry/Cover/Open.lean | 2 +- Mathlib/AlgebraicGeometry/Gluing.lean | 12 +++---- .../Analysis/Normed/Group/SemiNormedGrp.lean | 3 +- .../Group/SemiNormedGrp/Completion.lean | 3 +- .../Normed/Group/SemiNormedGrp/Kernels.lean | 6 ++-- .../Geometry/RingedSpace/OpenImmersion.lean | 8 ++--- .../RingedSpace/PresheafedSpace/Gluing.lean | 18 +++++----- .../Category/TopCat/Limits/Products.lean | 2 +- .../Category/TopCat/Limits/Pullbacks.lean | 14 ++++---- Mathlib/Topology/Gluing.lean | 34 +++++-------------- 15 files changed, 53 insertions(+), 77 deletions(-) diff --git a/Archive/Wiedijk100Theorems/Partition.lean b/Archive/Wiedijk100Theorems/Partition.lean index 0ced772d9f68f1..1045104e58395c 100644 --- a/Archive/Wiedijk100Theorems/Partition.lean +++ b/Archive/Wiedijk100Theorems/Partition.lean @@ -329,7 +329,7 @@ theorem partialDistinctGF_prop [CommSemiring α] (n m : ℕ) : -/ theorem distinctGF_prop [CommSemiring α] (n m : ℕ) (h : n < m + 1) : ((Nat.Partition.distincts n).card : α) = coeff α n (partialDistinctGF m) := by - erw [← partialDistinctGF_prop, Nat.Partition.distincts] + rw [← partialDistinctGF_prop, Nat.Partition.distincts] congr with p apply (and_iff_left _).symm intro i hi diff --git a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Sheafify.lean b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Sheafify.lean index fb4312736f67f2..c00b766a8362dc 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Sheafify.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Sheafify.lean @@ -201,7 +201,7 @@ instance : Subsingleton (SMulCandidate α φ r m) where all_goals apply Presheaf.imageSieve_mem apply A.isSeparated _ _ hS intro Y f ⟨⟨r₀, hr₀⟩, ⟨m₀, hm₀⟩⟩ - erw [h₁ f.op r₀ hr₀ m₀ hm₀, h₂ f.op r₀ hr₀ m₀ hm₀] + rw [h₁ f.op r₀ hr₀ m₀ hm₀, h₂ f.op r₀ hr₀ m₀ hm₀] noncomputable instance : Unique (SMulCandidate α φ r m) := uniqueOfSubsingleton (Nonempty.some inferInstance) @@ -225,13 +225,13 @@ protected lemma one_smul : smul α φ 1 m = m := by protected lemma zero_smul : smul α φ 0 m = 0 := by apply A.isSeparated _ _ (Presheaf.imageSieve_mem J φ m) rintro Y f ⟨m₀, hm₀⟩ - erw [map_smul_eq α φ 0 m f.op 0 (by simp) m₀ hm₀, zero_smul, map_zero, + rw [map_smul_eq α φ 0 m f.op 0 (by simp) m₀ hm₀, zero_smul, map_zero, (A.val.map f.op).map_zero] protected lemma smul_zero : smul α φ r 0 = 0 := by apply A.isSeparated _ _ (Presheaf.imageSieve_mem J α r) rintro Y f ⟨r₀, hr₀⟩ - erw [(A.val.map f.op).map_zero, map_smul_eq α φ r 0 f.op r₀ hr₀ 0 (by simp), + rw [(A.val.map f.op).map_zero, map_smul_eq α φ r 0 f.op r₀ hr₀ 0 (by simp), smul_zero, map_zero] protected lemma smul_add : smul α φ r (m + m') = smul α φ r m + smul α φ r m' := by @@ -241,7 +241,7 @@ protected lemma smul_add : smul α φ r (m + m') = smul α φ r m + smul α φ r all_goals apply Presheaf.imageSieve_mem apply A.isSeparated _ _ hS rintro Y f ⟨⟨⟨r₀, hr₀⟩, ⟨m₀ : M₀.obj _, hm₀⟩⟩, ⟨m₀' : M₀.obj _, hm₀'⟩⟩ - erw [(A.val.map f.op).map_add, map_smul_eq α φ r m f.op r₀ hr₀ m₀ hm₀, + rw [(A.val.map f.op).map_add, map_smul_eq α φ r m f.op r₀ hr₀ m₀ hm₀, map_smul_eq α φ r m' f.op r₀ hr₀ m₀' hm₀', map_smul_eq α φ r (m + m') f.op r₀ hr₀ (m₀ + m₀') (by rw [map_add, map_add, hm₀, hm₀']), @@ -254,7 +254,7 @@ protected lemma add_smul : smul α φ (r + r') m = smul α φ r m + smul α φ r all_goals apply Presheaf.imageSieve_mem apply A.isSeparated _ _ hS rintro Y f ⟨⟨⟨r₀ : R₀.obj _, hr₀⟩, ⟨r₀' : R₀.obj _, hr₀'⟩⟩, ⟨m₀, hm₀⟩⟩ - erw [(A.val.map f.op).map_add, map_smul_eq α φ r m f.op r₀ hr₀ m₀ hm₀, + rw [(A.val.map f.op).map_add, map_smul_eq α φ r m f.op r₀ hr₀ m₀ hm₀, map_smul_eq α φ r' m f.op r₀' hr₀' m₀ hm₀, map_smul_eq α φ (r + r') m f.op (r₀ + r₀') (by rw [map_add, map_add, hr₀, hr₀']) m₀ hm₀, add_smul, map_add] @@ -266,7 +266,7 @@ protected lemma mul_smul : smul α φ (r * r') m = smul α φ r (smul α φ r' m all_goals apply Presheaf.imageSieve_mem apply A.isSeparated _ _ hS rintro Y f ⟨⟨⟨r₀ : R₀.obj _, hr₀⟩, ⟨r₀' : R₀.obj _, hr₀'⟩⟩, ⟨m₀ : M₀.obj _, hm₀⟩⟩ - erw [map_smul_eq α φ (r * r') m f.op (r₀ * r₀') + rw [map_smul_eq α φ (r * r') m f.op (r₀ * r₀') (by rw [map_mul, map_mul, hr₀, hr₀']) m₀ hm₀, mul_smul, map_smul_eq α φ r (smul α φ r' m) f.op r₀ hr₀ (r₀' • m₀) (map_smul_eq α φ r' m f.op r₀' hr₀' m₀ hm₀).symm] @@ -292,7 +292,7 @@ lemma map_smul : all_goals apply Presheaf.imageSieve_mem apply A.isSeparated _ _ hS rintro Y f ⟨⟨r₀, hr₀⟩, ⟨m₀, hm₀⟩⟩ - erw [← comp_apply, ← Functor.map_comp, + rw [← comp_apply, ← Functor.map_comp, map_smul_eq α φ r m (π ≫ f.op) r₀ (by rw [hr₀, Functor.map_comp, comp_apply]) m₀ (by rw [hm₀, Functor.map_comp, comp_apply]), map_smul_eq α φ (R.val.map π r) (A.val.map π m) f.op r₀ hr₀ m₀ hm₀] diff --git a/Mathlib/Algebra/Homology/ShortComplex/Ab.lean b/Mathlib/Algebra/Homology/ShortComplex/Ab.lean index 474f801a48272a..393b22f24e512c 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/Ab.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/Ab.lean @@ -37,7 +37,7 @@ variable (S : ShortComplex Ab.{u}) @[simp] lemma ab_zero_apply (x : S.X₁) : S.g (S.f x) = 0 := by - erw [← comp_apply, S.zero] + rw [← comp_apply, S.zero] rfl /-- The canonical additive morphism `S.X₁ →+ AddMonoidHom.ker S.g` induced by `S.f`. -/ @@ -81,7 +81,7 @@ noncomputable def abCyclesIso : S.cycles ≅ AddCommGrp.of (AddMonoidHom.ker S.g lemma abCyclesIso_inv_apply_iCycles (x : AddMonoidHom.ker S.g) : S.iCycles (S.abCyclesIso.inv x) = x := by dsimp only [abCyclesIso] - erw [← comp_apply, S.abLeftHomologyData.cyclesIso_inv_comp_iCycles] + rw [← comp_apply, S.abLeftHomologyData.cyclesIso_inv_comp_iCycles] rfl /-- Given a short complex `S` of abelian groups, this is the isomorphism between @@ -129,7 +129,7 @@ lemma ab_exact_iff_range_eq_ker : S.Exact ↔ S.f.range = S.g.ker := by · intro h refine le_antisymm ?_ h rintro _ ⟨x₁, rfl⟩ - erw [AddMonoidHom.mem_ker, ← comp_apply, S.zero] + rw [AddMonoidHom.mem_ker, ← comp_apply, S.zero] rfl · intro h rw [h] diff --git a/Mathlib/Algebra/Homology/ShortComplex/ConcreteCategory.lean b/Mathlib/Algebra/Homology/ShortComplex/ConcreteCategory.lean index 2c1cd6db62c31b..51fd7a82b87525 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/ConcreteCategory.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/ConcreteCategory.lean @@ -32,7 +32,7 @@ lemma ShortComplex.zero_apply [Limits.HasZeroMorphisms C] [(forget₂ C Ab).PreservesZeroMorphisms] (S : ShortComplex C) (x : (forget₂ C Ab).obj S.X₁) : ((forget₂ C Ab).map S.g) (((forget₂ C Ab).map S.f) x) = 0 := by - erw [← comp_apply, ← Functor.map_comp, S.zero, Functor.map_zero] + rw [← comp_apply, ← Functor.map_comp, S.zero, Functor.map_zero] rfl section preadditive diff --git a/Mathlib/AlgebraicGeometry/AffineScheme.lean b/Mathlib/AlgebraicGeometry/AffineScheme.lean index fbc5e7b02e459d..35d58412138ae3 100644 --- a/Mathlib/AlgebraicGeometry/AffineScheme.lean +++ b/Mathlib/AlgebraicGeometry/AffineScheme.lean @@ -326,7 +326,7 @@ theorem range_fromSpec : delta IsAffineOpen.fromSpec; dsimp [IsAffineOpen.isoSpec_inv] rw [Set.range_comp, Set.range_iff_surjective.mpr, Set.image_univ] · exact Subtype.range_coe - erw [← coe_comp, ← TopCat.epi_iff_surjective] -- now `erw` after #13170 + rw [← coe_comp, ← TopCat.epi_iff_surjective] infer_instance @[simp] @@ -398,7 +398,7 @@ theorem _root_.AlgebraicGeometry.Scheme.Hom.isAffineOpen_iff_of_isOpenImmersion refine ⟨fun hU => @isAffine_of_isIso _ _ (IsOpenImmersion.isoOfRangeEq (X.ofRestrict U.openEmbedding ≫ f) (Y.ofRestrict _) ?_).hom ?_ hU, fun hU => hU.image_of_isOpenImmersion f⟩ - · erw [Scheme.comp_val_base, coe_comp, Set.range_comp] -- now `erw` after #13170 + · rw [Scheme.comp_val_base, coe_comp, Set.range_comp] dsimp [Opens.coe_inclusion', Scheme.restrict] erw [Subtype.range_coe, Subtype.range_coe] -- now `erw` after #13170 rfl diff --git a/Mathlib/AlgebraicGeometry/Cover/Open.lean b/Mathlib/AlgebraicGeometry/Cover/Open.lean index c137272d6c0cea..b49a2ae091e066 100644 --- a/Mathlib/AlgebraicGeometry/Cover/Open.lean +++ b/Mathlib/AlgebraicGeometry/Cover/Open.lean @@ -106,7 +106,7 @@ def OpenCover.bind (f : ∀ x : 𝒰.J, OpenCover (𝒰.obj x)) : OpenCover X wh change x ∈ Set.range ((f (𝒰.f x)).map ((f (𝒰.f x)).f y) ≫ 𝒰.map (𝒰.f x)).1.base use z erw [comp_apply] - erw [hz, hy] -- now `erw` after #13170 + rw [hz, hy] -- Porting note: weirdly, even though no input is needed, `inferInstance` does not work -- `PresheafedSpace.IsOpenImmersion.comp` is marked as `instance` IsOpen x := PresheafedSpace.IsOpenImmersion.comp _ _ diff --git a/Mathlib/AlgebraicGeometry/Gluing.lean b/Mathlib/AlgebraicGeometry/Gluing.lean index a2543e35ee7538..6bd24a246c33d4 100644 --- a/Mathlib/AlgebraicGeometry/Gluing.lean +++ b/Mathlib/AlgebraicGeometry/Gluing.lean @@ -228,15 +228,13 @@ theorem ι_eq_iff (i j : D.J) (x : (D.U i).carrier) (y : (D.U j).carrier) : (TopCat.GlueData.ι_eq_iff_rel D.toLocallyRingedSpaceGlueData.toSheafedSpaceGlueData.toPresheafedSpaceGlueData.toTopGlueData i j x y) - rw [← ((TopCat.mono_iff_injective D.isoCarrier.inv).mp _).eq_iff] - · erw [← comp_apply] -- now `erw` after #13170 - simp_rw [← D.ι_isoCarrier_inv] + rw [← ((TopCat.mono_iff_injective D.isoCarrier.inv).mp _).eq_iff, ← comp_apply] + · simp_rw [← D.ι_isoCarrier_inv] rfl -- `rfl` was not needed before #13170 · infer_instance theorem isOpen_iff (U : Set D.glued.carrier) : IsOpen U ↔ ∀ i, IsOpen ((D.ι i).1.base ⁻¹' U) := by - rw [← (TopCat.homeoOfIso D.isoCarrier.symm).isOpen_preimage] - rw [TopCat.GlueData.isOpen_iff] + rw [← (TopCat.homeoOfIso D.isoCarrier.symm).isOpen_preimage, TopCat.GlueData.isOpen_iff] apply forall_congr' intro i rw [← Set.preimage_comp, ← ι_isoCarrier_inv] @@ -342,7 +340,7 @@ theorem fromGlued_injective : Function.Injective 𝒰.fromGlued.1.base := by intro x y h obtain ⟨i, x, rfl⟩ := 𝒰.gluedCover.ι_jointly_surjective x obtain ⟨j, y, rfl⟩ := 𝒰.gluedCover.ι_jointly_surjective y - erw [← comp_apply, ← comp_apply] at h -- now `erw` after #13170 + rw [← comp_apply, ← comp_apply] at h simp_rw [← SheafedSpace.comp_base, ← LocallyRingedSpace.comp_val] at h erw [ι_fromGlued, ι_fromGlued] at h let e := @@ -390,7 +388,7 @@ instance : Epi 𝒰.fromGlued.val.base := by intro x obtain ⟨y, h⟩ := 𝒰.covers x use (𝒰.gluedCover.ι (𝒰.f x)).1.base y - erw [← comp_apply] -- now `erw` after #13170 + rw [← comp_apply] rw [← 𝒰.ι_fromGlued (𝒰.f x)] at h exact h diff --git a/Mathlib/Analysis/Normed/Group/SemiNormedGrp.lean b/Mathlib/Analysis/Normed/Group/SemiNormedGrp.lean index f63a09356056da..bb705ce63bda8f 100644 --- a/Mathlib/Analysis/Normed/Group/SemiNormedGrp.lean +++ b/Mathlib/Analysis/Normed/Group/SemiNormedGrp.lean @@ -112,8 +112,7 @@ theorem iso_isometry_of_normNoninc {V W : SemiNormedGrp} (i : V ≅ W) (h1 : i.h intro v apply le_antisymm (h1 v) calc - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 - ‖v‖ = ‖i.inv (i.hom v)‖ := by erw [Iso.hom_inv_id_apply] + ‖v‖ = ‖i.inv (i.hom v)‖ := by rw [Iso.hom_inv_id_apply] _ ≤ ‖i.hom v‖ := h2 _ end SemiNormedGrp diff --git a/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Completion.lean b/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Completion.lean index ca858da92cd338..4fe5df1db1b36c 100644 --- a/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Completion.lean +++ b/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Completion.lean @@ -94,8 +94,7 @@ instance : Preadditive SemiNormedGrp.{u} where -- Porting note: failing simps probably due to instance synthesis issues with concrete -- cats; see the gymnastics below for what used to be -- simp only [add_apply, comp_apply. map_add] - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 - rw [NormedAddGroupHom.add_apply]; erw [CategoryTheory.comp_apply, CategoryTheory.comp_apply, + rw [NormedAddGroupHom.add_apply, CategoryTheory.comp_apply, CategoryTheory.comp_apply, CategoryTheory.comp_apply, @NormedAddGroupHom.add_apply _ _ (_) (_)] convert map_add g (f x) (f' x) comp_add _ _ _ _ _ _ := by diff --git a/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Kernels.lean b/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Kernels.lean index e5aff9ade9489f..f70d7104b5b932 100644 --- a/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Kernels.lean +++ b/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Kernels.lean @@ -145,14 +145,12 @@ def cokernelCocone {X Y : SemiNormedGrp.{u}} (f : X ⟶ Y) : Cofork f 0 := ext a simp only [comp_apply, Limits.zero_comp] -- Porting note: `simp` not firing on the below - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 - erw [comp_apply, NormedAddGroupHom.zero_apply] + rw [comp_apply, NormedAddGroupHom.zero_apply] -- Porting note: Lean 3 didn't need this instance letI : SeminormedAddCommGroup ((forget SemiNormedGrp).obj Y) := (inferInstance : SeminormedAddCommGroup Y) -- Porting note: again simp doesn't seem to be firing in the below line - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 - erw [← NormedAddGroupHom.mem_ker, f.range.ker_normedMk, f.mem_range] + rw [← NormedAddGroupHom.mem_ker, f.range.ker_normedMk, f.mem_range] -- This used to be `simp only [exists_apply_eq_apply]` before leanprover/lean4#2644 convert exists_apply_eq_apply f a) diff --git a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean index 408d39010d7d34..a5571115fc47de 100644 --- a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean +++ b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean @@ -1119,17 +1119,15 @@ theorem lift_range (H' : Set.range g.1.base ⊆ Set.range f.1.base) : have : _ = (pullback.fst f g).val.base := PreservesPullback.iso_hom_fst (LocallyRingedSpace.forgetToSheafedSpace ⋙ SheafedSpace.forget _) f g - erw [LocallyRingedSpace.comp_val, SheafedSpace.comp_base, ← this, ← Category.assoc, coe_comp] - -- now `erw` after #13170 - rw [Set.range_comp, Set.range_iff_surjective.mpr, Set.image_univ] + rw [LocallyRingedSpace.comp_val, SheafedSpace.comp_base, ← this, ← Category.assoc, coe_comp, + Set.range_comp, Set.range_iff_surjective.mpr, Set.image_univ] -- Porting note (#11224): change `rw` to `erw` on this lemma · erw [TopCat.pullback_fst_range] ext constructor · rintro ⟨y, eq⟩; exact ⟨y, eq.symm⟩ · rintro ⟨y, eq⟩; exact ⟨y, eq.symm⟩ - · erw [← TopCat.epi_iff_surjective] -- now `erw` after #13170 - rw [show (inv (pullback.snd f g)).val.base = _ from + · rw [← TopCat.epi_iff_surjective, show (inv (pullback.snd f g)).val.base = _ from (LocallyRingedSpace.forgetToSheafedSpace ⋙ SheafedSpace.forget _).map_inv _] infer_instance diff --git a/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean b/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean index 93d358233ae906..19b9450951092e 100644 --- a/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean +++ b/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean @@ -190,20 +190,18 @@ theorem snd_invApp_t_app' (i j k : D.J) (U : Opens (pullback (D.f i j) (D.f i k) replace this := (congr_arg ((PresheafedSpace.Hom.base ·)) this).symm replace this := congr_arg (ContinuousMap.toFun ·) this dsimp at this - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 - erw [coe_comp, coe_comp] at this - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 - erw [this, Set.image_comp, Set.image_comp, Set.preimage_image_eq] + rw [coe_comp, coe_comp] at this + rw [this, Set.image_comp, Set.image_comp, Set.preimage_image_eq] swap · refine Function.HasLeftInverse.injective ⟨(D.t i k).base, fun x => ?_⟩ - erw [← comp_apply, ← comp_base, D.t_inv, id_base, id_apply] -- now `erw` after #13170 + rw [← comp_apply, ← comp_base, D.t_inv, id_base, id_apply] refine congr_arg (_ '' ·) ?_ refine congr_fun ?_ _ refine Set.image_eq_preimage_of_inverse ?_ ?_ · intro x - erw [← comp_apply, ← comp_base, IsIso.inv_hom_id, id_base, id_apply] -- now `erw` after #13170 + rw [← comp_apply, ← comp_base, IsIso.inv_hom_id, id_base, id_apply] · intro x - erw [← comp_apply, ← comp_base, IsIso.hom_inv_id, id_base, id_apply] -- now `erw` after #13170 + rw [← comp_apply, ← comp_base, IsIso.hom_inv_id, id_base, id_apply] · rw [← IsIso.eq_inv_comp, IsOpenImmersion.inv_invApp, Category.assoc, (D.t' k i j).c.naturality_assoc] simp_rw [← Category.assoc] @@ -260,7 +258,7 @@ theorem ι_image_preimage_eq (i j : D.J) (U : Opens (D.U i).carrier) : change (D.t i j ≫ D.t j i).base '' _ = _ rw [𝖣.t_inv] simp - · erw [← coe_comp, ← TopCat.mono_iff_injective] -- now `erw` after #13170 + · rw [← coe_comp, ← TopCat.mono_iff_injective] infer_instance /-- (Implementation). The map `Γ(𝒪_{U_i}, U) ⟶ Γ(𝒪_{U_j}, 𝖣.ι j ⁻¹' (𝖣.ι i '' U))` -/ @@ -412,9 +410,9 @@ theorem ιInvApp_π {i : D.J} (U : Opens (D.U i).carrier) : · exact h2.symm · have := D.ι_gluedIso_inv (PresheafedSpace.forget _) i dsimp at this - erw [← this, coe_comp] -- now `erw` after #13170 + rw [← this, coe_comp] refine Function.Injective.comp ?_ (TopCat.GlueData.ι_injective D.toTopGlueData i) - erw [← TopCat.mono_iff_injective] -- now `erw` after #13170 + rw [← TopCat.mono_iff_injective] infer_instance delta ιInvApp rw [limit.lift_π] diff --git a/Mathlib/Topology/Category/TopCat/Limits/Products.lean b/Mathlib/Topology/Category/TopCat/Limits/Products.lean index 780074ed743fed..bd879c98c4ab4c 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Products.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Products.lean @@ -224,7 +224,7 @@ theorem range_prod_map {W X Y Z : TopCat.{u}} (f : W ⟶ Y) (g : X ⟶ Z) : · rintro ⟨y, rfl⟩ simp_rw [Set.mem_inter_iff, Set.mem_preimage, Set.mem_range] -- sizable changes in this proof after #13170 - erw [← comp_apply, ← comp_apply] + rw [← comp_apply, ← comp_apply] simp_rw [Limits.prod.map_fst, Limits.prod.map_snd, comp_apply] exact ⟨exists_apply_eq_apply _ _, exists_apply_eq_apply _ _⟩ diff --git a/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean b/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean index 3d1a8ae947989e..f60d2f02b49187 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean @@ -71,12 +71,14 @@ def pullbackConeIsLimit (f : X ⟶ Z) (g : Y ⟶ Z) : IsLimit (pullbackCone f g) refine ⟨?_, ?_, ?_⟩ · delta pullbackCone ext a - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 - erw [comp_apply, ContinuousMap.coe_mk] + -- This used to be `rw`, but we need `rw; rfl` after leanprover/lean4#2644 + rw [comp_apply, ContinuousMap.coe_mk] + rfl · delta pullbackCone ext a - -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 - erw [comp_apply, ContinuousMap.coe_mk] + -- This used to be `rw`, but we need `rw; rfl` after leanprover/lean4#2644 + rw [comp_apply, ContinuousMap.coe_mk] + rfl · intro m h₁ h₂ -- Porting note (#11041): used to be `ext x`. apply ContinuousMap.ext; intro x @@ -198,13 +200,13 @@ theorem range_pullback_map {W X Y Z S T : TopCat} (f₁ : W ⟶ S) (f₂ : X ⟶ constructor · rintro ⟨y, rfl⟩ simp only [Set.mem_inter_iff, Set.mem_preimage, Set.mem_range] - erw [← comp_apply, ← comp_apply] -- now `erw` after #13170 + rw [← comp_apply, ← comp_apply] simp only [limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app, comp_apply] exact ⟨exists_apply_eq_apply _ _, exists_apply_eq_apply _ _⟩ rintro ⟨⟨x₁, hx₁⟩, ⟨x₂, hx₂⟩⟩ have : f₁ x₁ = f₂ x₂ := by apply (TopCat.mono_iff_injective _).mp H₃ - erw [← comp_apply, eq₁, ← comp_apply, eq₂, -- now `erw` after #13170 + rw [← comp_apply, eq₁, ← comp_apply, eq₂, comp_apply, comp_apply, hx₁, hx₂, ← comp_apply, pullback.condition] rfl -- `rfl` was not needed before #13170 use (pullbackIsoProdSubtype f₁ f₂).inv ⟨⟨x₁, x₂⟩, this⟩ diff --git a/Mathlib/Topology/Gluing.lean b/Mathlib/Topology/Gluing.lean index c6d7656eb38bc8..d6fd7281d0b0cc 100644 --- a/Mathlib/Topology/Gluing.lean +++ b/Mathlib/Topology/Gluing.lean @@ -121,8 +121,7 @@ def Rel (a b : Σ i, ((D.U i : TopCat) : Type _)) : Prop := theorem rel_equiv : Equivalence D.Rel := ⟨fun x => Or.inl (refl x), by rintro a b (⟨⟨⟩⟩ | ⟨x, e₁, e₂⟩) - exacts [Or.inl rfl, Or.inr ⟨D.t _ _ x, e₂, by erw [← e₁, D.t_inv_apply]⟩], by - -- previous line now `erw` after #13170 + exacts [Or.inl rfl, Or.inr ⟨D.t _ _ x, e₂, by rw [← e₁, D.t_inv_apply]⟩], by rintro ⟨i, a⟩ ⟨j, b⟩ ⟨k, c⟩ (⟨⟨⟩⟩ | ⟨x, e₁, e₂⟩) · exact id rintro (⟨⟨⟩⟩ | ⟨y, e₃, e₄⟩) @@ -237,9 +236,7 @@ theorem image_inter (i j : D.J) : · exact ⟨inv (D.f i i) x₁, by -- porting note (#10745): was `simp [eq₁]` -- See https://github.com/leanprover-community/mathlib4/issues/5026 - rw [TopCat.comp_app] - erw [CategoryTheory.IsIso.inv_hom_id_apply] - rw [eq₁]⟩ + rw [TopCat.comp_app, CategoryTheory.IsIso.inv_hom_id_apply, eq₁]⟩ · -- Porting note: was -- dsimp only at *; substs e₁ eq₁; exact ⟨y, by simp⟩ dsimp only at * @@ -247,7 +244,7 @@ theorem image_inter (i j : D.J) : exact ⟨y, by simp [e₁]⟩ · rintro ⟨x, hx⟩ refine ⟨⟨D.f i j x, hx⟩, ⟨D.f j i (D.t _ _ x), ?_⟩⟩ - erw [D.glue_condition_apply] -- now `erw` after #13170 + rw [D.glue_condition_apply] exact hx theorem preimage_range (i j : D.J) : 𝖣.ι j ⁻¹' Set.range (𝖣.ι i) = Set.range (D.f j i) := by @@ -361,7 +358,7 @@ def mk' (h : MkCore.{u}) : TopCat.GlueData where exact (h.V_id i).symm ▸ (Opens.inclusionTopIso (h.U i)).isIso_hom f_open := fun i j : h.J => (h.V i j).openEmbedding t := h.t - t_id i := by ext; erw [h.t_id]; rfl -- now `erw` after #13170 + t_id i := by ext; rw [h.t_id]; rfl t' := h.t' t_fac i j k := by delta MkCore.t' @@ -376,16 +373,8 @@ def mk' (h : MkCore.{u}) : TopCat.GlueData where simp only [Iso.inv_hom_id_assoc, Category.assoc, Category.id_comp] rw [← Iso.eq_inv_comp, Iso.inv_hom_id] ext1 ⟨⟨⟨x, hx⟩, ⟨x', hx'⟩⟩, rfl : x = x'⟩ - -- The next 6 tactics (up to `convert ...` were a single `rw` before leanprover/lean4#2644 - -- rw [comp_app, ContinuousMap.coe_mk, comp_app, id_app, ContinuousMap.coe_mk, Subtype.mk_eq_mk, - -- Prod.mk.inj_iff, Subtype.mk_eq_mk, Subtype.ext_iff, and_self_iff] - erw [comp_app] --, comp_app, id_app] -- now `erw` after #13170 - -- erw [ContinuousMap.coe_mk] - conv_lhs => erw [ContinuousMap.coe_mk] - erw [id_app] - rw [ContinuousMap.coe_mk] - erw [Subtype.mk_eq_mk] - rw [Prod.mk.inj_iff, Subtype.mk_eq_mk, Subtype.ext_iff, and_self_iff] + rw [comp_app, ContinuousMap.coe_mk, comp_app, id_app, ContinuousMap.coe_mk, Subtype.mk_eq_mk, + Prod.mk.inj_iff, Subtype.mk_eq_mk, Subtype.ext_iff, and_self_iff] convert congr_arg Subtype.val (h.t_inv k i ⟨x, hx'⟩) using 3 refine Subtype.ext ?_ exact h.cocycle i j k ⟨x, hx⟩ hx' @@ -432,9 +421,8 @@ theorem fromOpenSubsetsGlue_injective : Function.Injective (fromOpenSubsetsGlue intro x y e obtain ⟨i, ⟨x, hx⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x obtain ⟨j, ⟨y, hy⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective y - -- Porting note: now it is `erw`, it was `rw` -- see the porting note on `ι_fromOpenSubsetsGlue` - erw [ι_fromOpenSubsetsGlue_apply, ι_fromOpenSubsetsGlue_apply] at e + rw [ι_fromOpenSubsetsGlue_apply, ι_fromOpenSubsetsGlue_apply] at e change x = y at e subst e rw [(ofOpenSubsets U).ι_eq_iff_rel] @@ -458,9 +446,7 @@ theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by apply congr_arg exact Set.preimage_image_eq _ (fromOpenSubsetsGlue_injective U) · refine ⟨Set.mem_image_of_mem _ hx, ?_⟩ - -- Porting note: another `rw ↦ erw` - -- See above. - erw [ι_fromOpenSubsetsGlue_apply] + rw [ι_fromOpenSubsetsGlue_apply] exact Set.mem_range_self _ theorem fromOpenSubsetsGlue_openEmbedding : OpenEmbedding (fromOpenSubsetsGlue U) := @@ -472,9 +458,7 @@ theorem range_fromOpenSubsetsGlue : Set.range (fromOpenSubsetsGlue U) = ⋃ i, ( constructor · rintro ⟨x, rfl⟩ obtain ⟨i, ⟨x, hx'⟩, rfl⟩ := (ofOpenSubsets U).ι_jointly_surjective x - -- Porting note: another `rw ↦ erw` - -- See above - erw [ι_fromOpenSubsetsGlue_apply] + rw [ι_fromOpenSubsetsGlue_apply] exact Set.subset_iUnion _ i hx' · rintro ⟨_, ⟨i, rfl⟩, hx⟩ rename_i x From 67556a01b672c8c92e938601bdabad2d4ef3cc10 Mon Sep 17 00:00:00 2001 From: Dagur Asgeirsson Date: Sun, 13 Oct 2024 17:57:36 +0000 Subject: [PATCH 073/425] fix(Condensed): use `CompHausLike.const` instead of a private def (#17409) --- Mathlib/Condensed/Light/TopCatAdjunction.lean | 15 ++++--------- Mathlib/Condensed/TopCatAdjunction.lean | 22 +++++++------------ 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/Mathlib/Condensed/Light/TopCatAdjunction.lean b/Mathlib/Condensed/Light/TopCatAdjunction.lean index 5b6ffa2fd3fa46..3be36032d682c3 100644 --- a/Mathlib/Condensed/Light/TopCatAdjunction.lean +++ b/Mathlib/Condensed/Light/TopCatAdjunction.lean @@ -28,16 +28,11 @@ namespace LightCondSet variable (X : LightCondSet.{u}) -/-- Auxiliary definition to define the topology on `X(*)` for a light condensed set `X`. -/ -private def _root_.LightProfinite.const (S : LightProfinite.{u}) (s : S) : - LightProfinite.of PUnit.{u+1} ⟶ S := - ContinuousMap.const _ s - /-- Auxiliary definition to define the topology on `X(*)` for a light condensed set `X`. -/ private def coinducingCoprod : (Σ (i : (S : LightProfinite.{u}) × X.val.obj ⟨S⟩), i.fst) → X.val.obj ⟨LightProfinite.of PUnit⟩ := - fun ⟨⟨S, i⟩, s⟩ ↦ X.val.map (S.const s).op i + fun ⟨⟨_, i⟩, s⟩ ↦ X.val.map ((of PUnit.{u+1}).const s).op i /-- Let `X` be a light condensed set. We define a topology on `X(*)` as the quotient topology of all the maps from light profinite sets `S` to `X(*)`, corresponding to elements of `X(S)`. @@ -67,10 +62,8 @@ def toTopCatMap : X.toTopCat ⟶ Y.toTopCat where apply continuous_sigma intro ⟨S, x⟩ simp only [Function.comp_apply, coinducingCoprod] - have : (fun (a : S) ↦ f.val.app ⟨LightProfinite.of PUnit⟩ (X.val.map (S.const a).op x)) = - (fun (a : S) ↦ Y.val.map (S.const a).op (f.val.app ⟨S⟩ x)) := - funext fun a ↦ NatTrans.naturality_apply f.val (S.const a).op x - rw [this] + rw [show (fun (a : S) ↦ f.val.app ⟨of PUnit⟩ (X.val.map ((of PUnit.{u+1}).const a).op x)) = _ + from funext fun a ↦ NatTrans.naturality_apply f.val ((of PUnit.{u+1}).const a).op x] exact continuous_coinducingCoprod _ _ /-- The functor `LightCondSet ⥤ TopCat` -/ @@ -104,7 +97,7 @@ lemma topCatAdjunctionCounit_bijective (X : TopCat.{u}) : def topCatAdjunctionUnit (X : LightCondSet.{u}) : X ⟶ X.toTopCat.toLightCondSet where val := { app := fun S x ↦ { - toFun := fun s ↦ X.val.map (S.unop.const s).op x + toFun := fun s ↦ X.val.map ((of PUnit.{u+1}).const s).op x continuous_toFun := by suffices ∀ (i : (T : LightProfinite.{u}) × X.val.obj ⟨T⟩), Continuous (fun (a : i.fst) ↦ X.coinducingCoprod ⟨i, a⟩) from this ⟨_, _⟩ diff --git a/Mathlib/Condensed/TopCatAdjunction.lean b/Mathlib/Condensed/TopCatAdjunction.lean index 732a1448149d9d..b29f668f984844 100644 --- a/Mathlib/Condensed/TopCatAdjunction.lean +++ b/Mathlib/Condensed/TopCatAdjunction.lean @@ -19,20 +19,16 @@ The counit is an isomorphism for compactly generated spaces, and we conclude tha universe u -open Condensed CondensedSet CategoryTheory +open Condensed CondensedSet CategoryTheory CompHaus attribute [local instance] ConcreteCategory.instFunLike variable (X : CondensedSet.{u}) -/-- Auxiliary definition to define the topology on `X(*)` for a condensed set `X`. -/ -private def _root_.CompHaus.const (S : CompHaus.{u}) (s : S) : CompHaus.of PUnit.{u+1} ⟶ S := - ContinuousMap.const _ s - /-- Auxiliary definition to define the topology on `X(*)` for a condensed set `X`. -/ private def CondensedSet.coinducingCoprod : - (Σ (i : (S : CompHaus.{u}) × X.val.obj ⟨S⟩), i.fst) → X.val.obj ⟨CompHaus.of PUnit⟩ := - fun ⟨⟨S, i⟩, s⟩ ↦ X.val.map (S.const s).op i + (Σ (i : (S : CompHaus.{u}) × X.val.obj ⟨S⟩), i.fst) → X.val.obj ⟨of PUnit⟩ := + fun ⟨⟨_, i⟩, s⟩ ↦ X.val.map ((of PUnit.{u+1}).const s).op i /-- Let `X` be a condensed set. We define a topology on `X(*)` as the quotient topology of all the maps from compact Hausdorff `S` spaces to `X(*)`, corresponding to elements of `X(S)`. @@ -41,7 +37,7 @@ local instance : TopologicalSpace (X.val.obj ⟨CompHaus.of PUnit⟩) := TopologicalSpace.coinduced (coinducingCoprod X) inferInstance /-- The object part of the functor `CondensedSet ⥤ TopCat` -/ -def CondensedSet.toTopCat : TopCat.{u+1} := TopCat.of (X.val.obj ⟨CompHaus.of PUnit⟩) +def CondensedSet.toTopCat : TopCat.{u+1} := TopCat.of (X.val.obj ⟨of PUnit⟩) namespace CondensedSet @@ -57,16 +53,14 @@ variable {X} {Y : CondensedSet} (f : X ⟶ Y) /-- The map part of the functor `CondensedSet ⥤ TopCat` -/ @[simps] def toTopCatMap : X.toTopCat ⟶ Y.toTopCat where - toFun := f.val.app ⟨CompHaus.of PUnit⟩ + toFun := f.val.app ⟨of PUnit⟩ continuous_toFun := by rw [continuous_coinduced_dom] apply continuous_sigma intro ⟨S, x⟩ simp only [Function.comp_apply, coinducingCoprod] - have : (fun (a : S) ↦ f.val.app ⟨CompHaus.of PUnit⟩ (X.val.map (S.const a).op x)) = - (fun (a : S) ↦ Y.val.map (S.const a).op (f.val.app ⟨S⟩ x)) := - funext fun a ↦ NatTrans.naturality_apply f.val (S.const a).op x - rw [this] + rw [show (fun (a : S) ↦ f.val.app ⟨of PUnit⟩ (X.val.map ((of PUnit.{u+1}).const a).op x)) = _ + from funext fun a ↦ NatTrans.naturality_apply f.val ((of PUnit.{u+1}).const a).op x] exact continuous_coinducingCoprod Y _ end CondensedSet @@ -105,7 +99,7 @@ lemma topCatAdjunctionCounit_bijective (X : TopCat.{u+1}) : def topCatAdjunctionUnit (X : CondensedSet.{u}) : X ⟶ X.toTopCat.toCondensedSet where val := { app := fun S x ↦ { - toFun := fun s ↦ X.val.map (S.unop.const s).op x + toFun := fun s ↦ X.val.map ((of PUnit.{u+1}).const s).op x continuous_toFun := by suffices ∀ (i : (T : CompHaus.{u}) × X.val.obj ⟨T⟩), Continuous (fun (a : i.fst) ↦ X.coinducingCoprod ⟨i, a⟩) from this ⟨_, _⟩ From 30a10605aa1d9405ecadc0663af7951f95319314 Mon Sep 17 00:00:00 2001 From: Chris Birkbeck Date: Sun, 13 Oct 2024 19:01:15 +0000 Subject: [PATCH 074/425] feat(Analysis/Calculus/LogDeriv): add division lemma (#16541) Co-authored-by: Chris Birkbeck --- Mathlib/Analysis/Calculus/LogDeriv.lean | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Mathlib/Analysis/Calculus/LogDeriv.lean b/Mathlib/Analysis/Calculus/LogDeriv.lean index 525cbcab01852a..495f3de5c2775b 100644 --- a/Mathlib/Analysis/Calculus/LogDeriv.lean +++ b/Mathlib/Analysis/Calculus/LogDeriv.lean @@ -50,6 +50,13 @@ theorem logDeriv_mul {f g : 𝕜 → 𝕜'} (x : 𝕜) (hf : f x ≠ 0) (hg : g simp only [logDeriv_apply, deriv_mul hdf hdg] field_simp [mul_comm] +theorem logDeriv_div {f g : 𝕜 → 𝕜'} (x : 𝕜) (hf : f x ≠ 0) (hg : g x ≠ 0) + (hdf : DifferentiableAt 𝕜 f x) (hdg : DifferentiableAt 𝕜 g x) : + logDeriv (fun z => f z / g z) x = logDeriv f x - logDeriv g x := by + simp only [logDeriv_apply, deriv_div hdf hdg] + field_simp [mul_comm] + ring + theorem logDeriv_mul_const {f : 𝕜 → 𝕜'} (x : 𝕜) (a : 𝕜') (ha : a ≠ 0): logDeriv (fun z => f z * a) x = logDeriv f x := by simp only [logDeriv_apply, deriv_mul_const_field, mul_div_mul_right _ _ ha] @@ -102,4 +109,3 @@ theorem logDeriv_comp {f : 𝕜' → 𝕜'} {g : 𝕜 → 𝕜'} {x : 𝕜} (hf (hg : DifferentiableAt 𝕜 g x) : logDeriv (f ∘ g) x = logDeriv f (g x) * deriv g x := by simp only [logDeriv, Pi.div_apply, deriv.comp _ hf hg, comp_apply] ring - From 282d392e489013a298925f42995f95183301cce4 Mon Sep 17 00:00:00 2001 From: Yuma Mizuno Date: Sun, 13 Oct 2024 20:13:07 +0000 Subject: [PATCH 075/425] chore(Probability/Variance): generalize assumptions from `MeasureSpace` to `MeasurableSpace` (#17702) https://leanprover.zulipchat.com/#narrow/stream/116395-maths/topic/.60MeasureSpace.60.20vs.20.60Measure.60.20in.20.60ProbabilityTheory.2F.60 --- Mathlib/Probability/Variance.lean | 76 +++++++++++++++---------------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/Mathlib/Probability/Variance.lean b/Mathlib/Probability/Variance.lean index 9b0a9bcb2fe5c3..3510fdd5599013 100644 --- a/Mathlib/Probability/Variance.lean +++ b/Mathlib/Probability/Variance.lean @@ -178,44 +178,42 @@ theorem variance_smul' {A : Type*} [CommSemiring A] [Algebra A ℝ] (c : A) (X : scoped notation "Var[" X "]" => ProbabilityTheory.variance X MeasureTheory.MeasureSpace.volume -variable [MeasureSpace Ω] - -theorem variance_def' [@IsProbabilityMeasure Ω _ ℙ] {X : Ω → ℝ} (hX : Memℒp X 2) : - Var[X] = 𝔼[X ^ 2] - 𝔼[X] ^ 2 := by +theorem variance_def' [IsProbabilityMeasure μ] {X : Ω → ℝ} (hX : Memℒp X 2 μ) : + variance X μ = μ[X ^ 2] - μ[X] ^ 2 := by rw [hX.variance_eq, sub_sq', integral_sub', integral_add']; rotate_left · exact hX.integrable_sq - · convert @integrable_const Ω ℝ (_) ℙ _ _ (𝔼[X] ^ 2) + · apply integrable_const · apply hX.integrable_sq.add - convert @integrable_const Ω ℝ (_) ℙ _ _ (𝔼[X] ^ 2) + apply integrable_const · exact ((hX.integrable one_le_two).const_mul 2).mul_const' _ simp only [Pi.pow_apply, integral_const, measure_univ, ENNReal.one_toReal, smul_eq_mul, one_mul, Pi.mul_apply, Pi.ofNat_apply, Nat.cast_ofNat, integral_mul_right, integral_mul_left] ring -theorem variance_le_expectation_sq [@IsProbabilityMeasure Ω _ ℙ] {X : Ω → ℝ} - (hm : AEStronglyMeasurable X ℙ) : Var[X] ≤ 𝔼[X ^ 2] := by - by_cases hX : Memℒp X 2 +theorem variance_le_expectation_sq [IsProbabilityMeasure μ] {X : Ω → ℝ} + (hm : AEStronglyMeasurable X μ) : variance X μ ≤ μ[X ^ 2] := by + by_cases hX : Memℒp X 2 μ · rw [variance_def' hX] simp only [sq_nonneg, sub_le_self_iff] rw [variance, evariance_eq_lintegral_ofReal, ← integral_eq_lintegral_of_nonneg_ae] - · by_cases hint : Integrable X; swap + · by_cases hint : Integrable X μ; swap · simp only [integral_undef hint, Pi.pow_apply, Pi.sub_apply, sub_zero] exact le_rfl · rw [integral_undef] · exact integral_nonneg fun a => sq_nonneg _ intro h - have A : Memℒp (X - fun ω : Ω => 𝔼[X]) 2 ℙ := + have A : Memℒp (X - fun ω : Ω => μ[X]) 2 μ := (memℒp_two_iff_integrable_sq (hint.aestronglyMeasurable.sub aestronglyMeasurable_const)).2 h - have B : Memℒp (fun _ : Ω => 𝔼[X]) 2 ℙ := memℒp_const _ + have B : Memℒp (fun _ : Ω => μ[X]) 2 μ := memℒp_const _ apply hX convert A.add B simp · exact Eventually.of_forall fun x => sq_nonneg _ · exact (AEMeasurable.pow_const (hm.aemeasurable.sub_const _) _).aestronglyMeasurable -theorem evariance_def' [@IsProbabilityMeasure Ω _ ℙ] {X : Ω → ℝ} (hX : AEStronglyMeasurable X ℙ) : - eVar[X] = (∫⁻ ω, (‖X ω‖₊ ^ 2 :)) - ENNReal.ofReal (𝔼[X] ^ 2) := by - by_cases hℒ : Memℒp X 2 +theorem evariance_def' [IsProbabilityMeasure μ] {X : Ω → ℝ} (hX : AEStronglyMeasurable X μ) : + evariance X μ = (∫⁻ ω, (‖X ω‖₊ ^ 2 :) ∂μ) - ENNReal.ofReal (μ[X] ^ 2) := by + by_cases hℒ : Memℒp X 2 μ · rw [← hℒ.ofReal_variance_eq, variance_def' hℒ, ENNReal.ofReal_sub _ (sq_nonneg _)] congr rw [lintegral_coe_eq_integral] @@ -233,11 +231,11 @@ theorem evariance_def' [@IsProbabilityMeasure Ω _ ℙ] {X : Ω → ℝ} (hX : A exact mod_cast hℒ fun _ => zero_le_two /-- **Chebyshev's inequality** for `ℝ≥0∞`-valued variance. -/ -theorem meas_ge_le_evariance_div_sq {X : Ω → ℝ} (hX : AEStronglyMeasurable X ℙ) {c : ℝ≥0} - (hc : c ≠ 0) : ℙ {ω | ↑c ≤ |X ω - 𝔼[X]|} ≤ eVar[X] / c ^ 2 := by +theorem meas_ge_le_evariance_div_sq {X : Ω → ℝ} (hX : AEStronglyMeasurable X μ) {c : ℝ≥0} + (hc : c ≠ 0) : μ {ω | ↑c ≤ |X ω - μ[X]|} ≤ evariance X μ / c ^ 2 := by have A : (c : ℝ≥0∞) ≠ 0 := by rwa [Ne, ENNReal.coe_eq_zero] - have B : AEStronglyMeasurable (fun _ : Ω => 𝔼[X]) ℙ := aestronglyMeasurable_const - convert meas_ge_le_mul_pow_eLpNorm ℙ two_ne_zero ENNReal.two_ne_top (hX.sub B) A using 1 + have B : AEStronglyMeasurable (fun _ : Ω => μ[X]) μ := aestronglyMeasurable_const + convert meas_ge_le_mul_pow_eLpNorm μ two_ne_zero ENNReal.two_ne_top (hX.sub B) A using 1 · congr simp only [Pi.sub_apply, ENNReal.coe_le_coe, ← Real.norm_eq_abs, ← coe_nnnorm, NNReal.coe_le_coe, ENNReal.ofReal_coe_nnreal] @@ -251,22 +249,22 @@ theorem meas_ge_le_evariance_div_sq {X : Ω → ℝ} (hX : AEStronglyMeasurable /-- **Chebyshev's inequality**: one can control the deviation probability of a real random variable from its expectation in terms of the variance. -/ -theorem meas_ge_le_variance_div_sq [@IsFiniteMeasure Ω _ ℙ] {X : Ω → ℝ} (hX : Memℒp X 2) {c : ℝ} - (hc : 0 < c) : ℙ {ω | c ≤ |X ω - 𝔼[X]|} ≤ ENNReal.ofReal (Var[X] / c ^ 2) := by +theorem meas_ge_le_variance_div_sq [IsFiniteMeasure μ] {X : Ω → ℝ} (hX : Memℒp X 2 μ) {c : ℝ} + (hc : 0 < c) : μ {ω | c ≤ |X ω - μ[X]|} ≤ ENNReal.ofReal (variance X μ / c ^ 2) := by rw [ENNReal.ofReal_div_of_pos (sq_pos_of_ne_zero hc.ne.symm), hX.ofReal_variance_eq] - convert @meas_ge_le_evariance_div_sq _ _ _ hX.1 c.toNNReal (by simp [hc]) using 1 + convert @meas_ge_le_evariance_div_sq _ _ _ _ hX.1 c.toNNReal (by simp [hc]) using 1 · simp only [Real.coe_toNNReal', max_le_iff, abs_nonneg, and_true] · rw [ENNReal.ofReal_pow hc.le] rfl -- Porting note: supplied `MeasurableSpace Ω` argument of `h` by unification /-- The variance of the sum of two independent random variables is the sum of the variances. -/ -theorem IndepFun.variance_add [@IsProbabilityMeasure Ω _ ℙ] {X Y : Ω → ℝ} (hX : Memℒp X 2) - (hY : Memℒp Y 2) (h : @IndepFun _ _ _ (_) _ _ X Y ℙ) : Var[X + Y] = Var[X] + Var[Y] := +theorem IndepFun.variance_add [IsProbabilityMeasure μ] {X Y : Ω → ℝ} (hX : Memℒp X 2 μ) + (hY : Memℒp Y 2 μ) (h : IndepFun X Y μ) : variance (X + Y) μ = variance X μ + variance Y μ := calc - Var[X + Y] = 𝔼[fun a => X a ^ 2 + Y a ^ 2 + 2 * X a * Y a] - 𝔼[X + Y] ^ 2 := by + variance (X + Y) μ = μ[fun a => X a ^ 2 + Y a ^ 2 + 2 * X a * Y a] - μ[X + Y] ^ 2 := by simp [variance_def' (hX.add hY), add_sq'] - _ = 𝔼[X ^ 2] + 𝔼[Y ^ 2] + (2 : ℝ) * 𝔼[X * Y] - (𝔼[X] + 𝔼[Y]) ^ 2 := by + _ = μ[X ^ 2] + μ[Y ^ 2] + (2 : ℝ) * μ[X * Y] - (μ[X] + μ[Y]) ^ 2 := by simp only [Pi.add_apply, Pi.pow_apply, Pi.mul_apply, mul_assoc] rw [integral_add, integral_add, integral_add, integral_mul_left] · exact hX.integrable one_le_two @@ -276,27 +274,27 @@ theorem IndepFun.variance_add [@IsProbabilityMeasure Ω _ ℙ] {X Y : Ω → ℝ · exact hX.integrable_sq.add hY.integrable_sq · apply Integrable.const_mul exact h.integrable_mul (hX.integrable one_le_two) (hY.integrable one_le_two) - _ = 𝔼[X ^ 2] + 𝔼[Y ^ 2] + 2 * (𝔼[X] * 𝔼[Y]) - (𝔼[X] + 𝔼[Y]) ^ 2 := by + _ = μ[X ^ 2] + μ[Y ^ 2] + 2 * (μ[X] * μ[Y]) - (μ[X] + μ[Y]) ^ 2 := by congr exact h.integral_mul_of_integrable (hX.integrable one_le_two) (hY.integrable one_le_two) - _ = Var[X] + Var[Y] := by simp only [variance_def', hX, hY, Pi.pow_apply]; ring + _ = variance X μ + variance Y μ := by simp only [variance_def', hX, hY, Pi.pow_apply]; ring -- Porting note: supplied `MeasurableSpace Ω` argument of `hs`, `h` by unification /-- The variance of a finite sum of pairwise independent random variables is the sum of the variances. -/ -theorem IndepFun.variance_sum [@IsProbabilityMeasure Ω _ ℙ] {ι : Type*} {X : ι → Ω → ℝ} - {s : Finset ι} (hs : ∀ i ∈ s, @Memℒp _ _ _ (_) (X i) 2 ℙ) - (h : Set.Pairwise ↑s fun i j => @IndepFun _ _ _ (_) _ _ (X i) (X j) ℙ) : - Var[∑ i ∈ s, X i] = ∑ i ∈ s, Var[X i] := by +theorem IndepFun.variance_sum [IsProbabilityMeasure μ] {ι : Type*} {X : ι → Ω → ℝ} + {s : Finset ι} (hs : ∀ i ∈ s, Memℒp (X i) 2 μ) + (h : Set.Pairwise ↑s fun i j => IndepFun (X i) (X j) μ) : + variance (∑ i ∈ s, X i) μ = ∑ i ∈ s, variance (X i) μ := by classical induction' s using Finset.induction_on with k s ks IH · simp only [Finset.sum_empty, variance_zero] rw [variance_def' (memℒp_finset_sum' _ hs), sum_insert ks, sum_insert ks] simp only [add_sq'] calc - 𝔼[X k ^ 2 + (∑ i ∈ s, X i) ^ 2 + 2 * X k * ∑ i ∈ s, X i] - 𝔼[X k + ∑ i ∈ s, X i] ^ 2 = - 𝔼[X k ^ 2] + 𝔼[(∑ i ∈ s, X i) ^ 2] + 𝔼[2 * X k * ∑ i ∈ s, X i] - - (𝔼[X k] + 𝔼[∑ i ∈ s, X i]) ^ 2 := by + μ[(X k ^ 2 + (∑ i ∈ s, X i) ^ 2 + 2 * X k * ∑ i ∈ s, X i : Ω → ℝ)] - μ[X k + ∑ i ∈ s, X i] ^ 2 = + μ[X k ^ 2] + μ[(∑ i ∈ s, X i) ^ 2] + μ[2 * X k * ∑ i ∈ s, X i] - + (μ[X k] + μ[∑ i ∈ s, X i]) ^ 2 := by rw [integral_add', integral_add', integral_add'] · exact Memℒp.integrable one_le_two (hs _ (mem_insert_self _ _)) · apply integrable_finset_sum' _ fun i hi => ?_ @@ -316,12 +314,12 @@ theorem IndepFun.variance_sum [@IsProbabilityMeasure Ω _ ℙ] {ι : Type*} {X : (Memℒp.integrable one_le_two (hs _ (mem_insert_of_mem hi))) apply h (mem_insert_self _ _) (mem_insert_of_mem hi) exact fun hki => ks (hki.symm ▸ hi) - _ = Var[X k] + Var[∑ i ∈ s, X i] + - (𝔼[2 * X k * ∑ i ∈ s, X i] - 2 * 𝔼[X k] * 𝔼[∑ i ∈ s, X i]) := by + _ = variance (X k) μ + variance (∑ i ∈ s, X i) μ + + (μ[2 * X k * ∑ i ∈ s, X i] - 2 * μ[X k] * μ[∑ i ∈ s, X i]) := by rw [variance_def' (hs _ (mem_insert_self _ _)), variance_def' (memℒp_finset_sum' _ fun i hi => hs _ (mem_insert_of_mem hi))] ring - _ = Var[X k] + Var[∑ i ∈ s, X i] := by + _ = variance (X k) μ + variance (∑ i ∈ s, X i) μ := by simp_rw [Pi.mul_apply, Pi.ofNat_apply, Nat.cast_ofNat, sum_apply, mul_sum, mul_assoc, add_right_eq_self] rw [integral_finset_sum s fun i hi => ?_]; swap @@ -339,7 +337,7 @@ theorem IndepFun.variance_sum [@IsProbabilityMeasure Ω _ ℙ] {ι : Type*} {X : exact fun hki => ks (hki.symm ▸ hi) · exact Memℒp.aestronglyMeasurable (hs _ (mem_insert_self _ _)) · exact Memℒp.aestronglyMeasurable (hs _ (mem_insert_of_mem hi)) - _ = Var[X k] + ∑ i ∈ s, Var[X i] := by + _ = variance (X k) μ + ∑ i ∈ s, variance (X i) μ := by rw [IH (fun i hi => hs i (mem_insert_of_mem hi)) (h.mono (by simp only [coe_insert, Set.subset_insert]))] From 808cf46e3d230a7e7f659426ee064052588917ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Sun, 13 Oct 2024 20:22:57 +0000 Subject: [PATCH 076/425] feat: a countable discrete measurable space is standard Borel (#17652) From PFR --- Mathlib/MeasureTheory/Constructions/Polish/Basic.lean | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean index 89db09097d3cbe..052b874d84c6a9 100644 --- a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean @@ -109,6 +109,12 @@ variable [MeasurableSpace α] instance standardBorel_of_polish [τ : TopologicalSpace α] [BorelSpace α] [PolishSpace α] : StandardBorelSpace α := by exists τ +instance standardBorelSpace_of_discreteMeasurableSpace [DiscreteMeasurableSpace α] [Countable α] : + StandardBorelSpace α := + let _ : TopologicalSpace α := ⊥ + have : DiscreteTopology α := ⟨rfl⟩ + inferInstance + instance countablyGenerated_of_standardBorel [StandardBorelSpace α] : MeasurableSpace.CountablyGenerated α := letI := upgradeStandardBorel α From 1e919af2379a4ac592e6962ea4985b717544759a Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Sun, 13 Oct 2024 20:38:30 +0000 Subject: [PATCH 077/425] feat(Measure/Typeclasses): rename `sFiniteSeq` (#17423) Moves: - MeasureTheory.*sFiniteSeq* -> MeasureTheory.*sfiniteSeq* --- .../Constructions/Prod/Basic.lean | 38 +++++++------- .../MeasureTheory/Decomposition/Lebesgue.lean | 2 +- Mathlib/MeasureTheory/Integral/Lebesgue.lean | 4 +- .../MeasureTheory/Measure/AEMeasurable.lean | 2 +- .../MeasureTheory/Measure/Typeclasses.lean | 52 ++++++++++++------- .../MeasureTheory/Measure/WithDensity.lean | 4 +- .../Measure/WithDensityFinite.lean | 9 ++-- Mathlib/Probability/Kernel/Basic.lean | 2 +- 8 files changed, 64 insertions(+), 49 deletions(-) diff --git a/Mathlib/MeasureTheory/Constructions/Prod/Basic.lean b/Mathlib/MeasureTheory/Constructions/Prod/Basic.lean index a8e405fc234e17..a3700ee3a34cfb 100644 --- a/Mathlib/MeasureTheory/Constructions/Prod/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/Prod/Basic.lean @@ -163,7 +163,7 @@ theorem measurable_measure_prod_mk_left_finite [IsFiniteMeasure ν] {s : Set (α is a measurable function. -/ theorem measurable_measure_prod_mk_left [SFinite ν] {s : Set (α × β)} (hs : MeasurableSet s) : Measurable fun x => ν (Prod.mk x ⁻¹' s) := by - rw [← sum_sFiniteSeq ν] + rw [← sum_sfiniteSeq ν] simp_rw [Measure.sum_apply_of_countable] exact Measurable.ennreal_tsum (fun i ↦ measurable_measure_prod_mk_left_finite hs) @@ -573,8 +573,8 @@ instance prod.instSFinite {α β : Type*} {_ : MeasurableSpace α} {μ : Measure [SFinite μ] {_ : MeasurableSpace β} {ν : Measure β} [SFinite ν] : SFinite (μ.prod ν) := by have : μ.prod ν = - Measure.sum (fun (p : ℕ × ℕ) ↦ (sFiniteSeq μ p.1).prod (sFiniteSeq ν p.2)) := by - conv_lhs => rw [← sum_sFiniteSeq μ, ← sum_sFiniteSeq ν] + Measure.sum (fun (p : ℕ × ℕ) ↦ (sfiniteSeq μ p.1).prod (sfiniteSeq ν p.2)) := by + conv_lhs => rw [← sum_sfiniteSeq μ, ← sum_sfiniteSeq ν] apply prod_sum rw [this] infer_instance @@ -620,12 +620,12 @@ theorem prod_eq {μ : Measure α} [SigmaFinite μ] {ν : Measure β} [SigmaFinit variable [SFinite μ] theorem prod_swap : map Prod.swap (μ.prod ν) = ν.prod μ := by - have : sum (fun (i : ℕ × ℕ) ↦ map Prod.swap ((sFiniteSeq μ i.1).prod (sFiniteSeq ν i.2))) - = sum (fun (i : ℕ × ℕ) ↦ map Prod.swap ((sFiniteSeq μ i.2).prod (sFiniteSeq ν i.1))) := by + have : sum (fun (i : ℕ × ℕ) ↦ map Prod.swap ((sfiniteSeq μ i.1).prod (sfiniteSeq ν i.2))) + = sum (fun (i : ℕ × ℕ) ↦ map Prod.swap ((sfiniteSeq μ i.2).prod (sfiniteSeq ν i.1))) := by ext s hs rw [sum_apply _ hs, sum_apply _ hs] exact ((Equiv.prodComm ℕ ℕ).tsum_eq _).symm - rw [← sum_sFiniteSeq μ, ← sum_sFiniteSeq ν, prod_sum, prod_sum, + rw [← sum_sfiniteSeq μ, ← sum_sfiniteSeq ν, prod_sum, prod_sum, map_sum measurable_swap.aemeasurable, this] congr 1 ext1 i @@ -687,19 +687,19 @@ lemma nullMeasurableSet_prod {s : Set α} {t : Set β} : theorem prodAssoc_prod [SFinite τ] : map MeasurableEquiv.prodAssoc ((μ.prod ν).prod τ) = μ.prod (ν.prod τ) := by have : sum (fun (p : ℕ × ℕ × ℕ) ↦ - (sFiniteSeq μ p.1).prod ((sFiniteSeq ν p.2.1).prod (sFiniteSeq τ p.2.2))) + (sfiniteSeq μ p.1).prod ((sfiniteSeq ν p.2.1).prod (sfiniteSeq τ p.2.2))) = sum (fun (p : (ℕ × ℕ) × ℕ) ↦ - (sFiniteSeq μ p.1.1).prod ((sFiniteSeq ν p.1.2).prod (sFiniteSeq τ p.2))) := by + (sfiniteSeq μ p.1.1).prod ((sfiniteSeq ν p.1.2).prod (sfiniteSeq τ p.2))) := by ext s hs rw [sum_apply _ hs, sum_apply _ hs, ← (Equiv.prodAssoc _ _ _).tsum_eq] simp only [Equiv.prodAssoc_apply] - rw [← sum_sFiniteSeq μ, ← sum_sFiniteSeq ν, ← sum_sFiniteSeq τ, prod_sum, prod_sum, + rw [← sum_sfiniteSeq μ, ← sum_sfiniteSeq ν, ← sum_sfiniteSeq τ, prod_sum, prod_sum, map_sum MeasurableEquiv.prodAssoc.measurable.aemeasurable, prod_sum, prod_sum, this] congr ext1 i refine (prod_eq_generateFrom generateFrom_measurableSet generateFrom_prod - isPiSystem_measurableSet isPiSystem_prod ((sFiniteSeq μ i.1.1)).toFiniteSpanningSetsIn - ((sFiniteSeq ν i.1.2).toFiniteSpanningSetsIn.prod (sFiniteSeq τ i.2).toFiniteSpanningSetsIn) + 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 simp_rw [map_apply (MeasurableEquiv.measurable _) (hs.prod (ht.prod hu)), @@ -710,7 +710,7 @@ theorem prodAssoc_prod [SFinite τ] : theorem prod_restrict (s : Set α) (t : Set β) : (μ.restrict s).prod (ν.restrict t) = (μ.prod ν).restrict (s ×ˢ t) := by - rw [← sum_sFiniteSeq μ, ← sum_sFiniteSeq ν, restrict_sum_of_countable, restrict_sum_of_countable, + rw [← sum_sfiniteSeq μ, ← sum_sfiniteSeq ν, restrict_sum_of_countable, restrict_sum_of_countable, prod_sum, prod_sum, restrict_sum_of_countable] congr 1 ext1 i @@ -725,27 +725,27 @@ theorem restrict_prod_eq_prod_univ (s : Set α) : theorem prod_dirac (y : β) : μ.prod (dirac y) = map (fun x => (x, y)) μ := by classical - rw [← sum_sFiniteSeq μ, prod_sum_left, map_sum measurable_prod_mk_right.aemeasurable] + rw [← sum_sfiniteSeq μ, prod_sum_left, map_sum measurable_prod_mk_right.aemeasurable] congr ext1 i refine prod_eq fun s t hs ht => ?_ simp_rw [map_apply measurable_prod_mk_right (hs.prod ht), mk_preimage_prod_left_eq_if, measure_if, - dirac_apply' _ ht, ← indicator_mul_right _ fun _ => sFiniteSeq μ i s, Pi.one_apply, mul_one] + dirac_apply' _ ht, ← indicator_mul_right _ fun _ => sfiniteSeq μ i s, Pi.one_apply, mul_one] theorem dirac_prod (x : α) : (dirac x).prod ν = map (Prod.mk x) ν := by classical - rw [← sum_sFiniteSeq ν, prod_sum_right, map_sum measurable_prod_mk_left.aemeasurable] + rw [← sum_sfiniteSeq ν, prod_sum_right, map_sum measurable_prod_mk_left.aemeasurable] congr ext1 i refine prod_eq fun s t hs ht => ?_ simp_rw [map_apply measurable_prod_mk_left (hs.prod ht), mk_preimage_prod_right_eq_if, measure_if, - dirac_apply' _ hs, ← indicator_mul_left _ _ fun _ => sFiniteSeq ν i t, Pi.one_apply, one_mul] + dirac_apply' _ hs, ← indicator_mul_left _ _ fun _ => sfiniteSeq ν i t, Pi.one_apply, one_mul] theorem dirac_prod_dirac {x : α} {y : β} : (dirac x).prod (dirac y) = dirac (x, y) := by rw [prod_dirac, map_dirac measurable_prod_mk_right] theorem prod_add (ν' : Measure β) [SFinite ν'] : μ.prod (ν + ν') = μ.prod ν + μ.prod ν' := by - simp_rw [← sum_sFiniteSeq ν, ← sum_sFiniteSeq ν', sum_add_sum, ← sum_sFiniteSeq μ, prod_sum, + simp_rw [← sum_sfiniteSeq ν, ← sum_sfiniteSeq ν', sum_add_sum, ← sum_sfiniteSeq μ, prod_sum, sum_add_sum] congr ext1 i @@ -753,7 +753,7 @@ theorem prod_add (ν' : Measure β) [SFinite ν'] : μ.prod (ν + ν') = μ.prod simp_rw [add_apply, prod_prod, left_distrib] theorem add_prod (μ' : Measure α) [SFinite μ'] : (μ + μ').prod ν = μ.prod ν + μ'.prod ν := by - simp_rw [← sum_sFiniteSeq μ, ← sum_sFiniteSeq μ', sum_add_sum, ← sum_sFiniteSeq ν, prod_sum, + simp_rw [← sum_sfiniteSeq μ, ← sum_sfiniteSeq μ', sum_add_sum, ← sum_sfiniteSeq ν, prod_sum, sum_add_sum] congr ext1 i @@ -771,7 +771,7 @@ theorem prod_zero (μ : Measure α) : μ.prod (0 : Measure β) = 0 := by simp [M theorem map_prod_map {δ} [MeasurableSpace δ] {f : α → β} {g : γ → δ} (μa : Measure α) (μc : Measure γ) [SFinite μa] [SFinite μc] (hf : Measurable f) (hg : Measurable g) : (map f μa).prod (map g μc) = map (Prod.map f g) (μa.prod μc) := by - simp_rw [← sum_sFiniteSeq μa, ← sum_sFiniteSeq μc, map_sum hf.aemeasurable, + simp_rw [← sum_sfiniteSeq μa, ← sum_sfiniteSeq μc, map_sum hf.aemeasurable, map_sum hg.aemeasurable, prod_sum, map_sum (hf.prod_map hg).aemeasurable] congr ext1 i diff --git a/Mathlib/MeasureTheory/Decomposition/Lebesgue.lean b/Mathlib/MeasureTheory/Decomposition/Lebesgue.lean index 243efac2011bc0..b82573cc25bc5e 100644 --- a/Mathlib/MeasureTheory/Decomposition/Lebesgue.lean +++ b/Mathlib/MeasureTheory/Decomposition/Lebesgue.lean @@ -922,7 +922,7 @@ then the same is true for any s-finite measure. -/ theorem HaveLebesgueDecomposition.sfinite_of_isFiniteMeasure [SFinite μ] (_h : ∀ (μ : Measure α) [IsFiniteMeasure μ], HaveLebesgueDecomposition μ ν) : HaveLebesgueDecomposition μ ν := - sum_sFiniteSeq μ ▸ sum_left _ + sum_sfiniteSeq μ ▸ sum_left _ attribute [local instance] haveLebesgueDecomposition_of_finiteMeasure diff --git a/Mathlib/MeasureTheory/Integral/Lebesgue.lean b/Mathlib/MeasureTheory/Integral/Lebesgue.lean index 184a66e158c303..e00c2da2c5ee91 100644 --- a/Mathlib/MeasureTheory/Integral/Lebesgue.lean +++ b/Mathlib/MeasureTheory/Integral/Lebesgue.lean @@ -1836,9 +1836,9 @@ theorem exists_measurable_le_forall_setLIntegral_eq [SFinite μ] (f : α → ℝ · exact ⟨g, hgm, hgle, fun s ↦ (hleg s).antisymm (lintegral_mono hgle)⟩ -- Without loss of generality, `μ` is a finite measure. wlog h : IsFiniteMeasure μ generalizing μ - · choose g hgm hgle hgint using fun n ↦ @this (sFiniteSeq μ n) _ inferInstance + · choose g hgm hgle hgint using fun n ↦ @this (sfiniteSeq μ n) _ inferInstance refine ⟨fun x ↦ ⨆ n, g n x, measurable_iSup hgm, fun x ↦ iSup_le (hgle · x), fun s ↦ ?_⟩ - rw [← sum_sFiniteSeq μ, Measure.restrict_sum_of_countable, + rw [← sum_sfiniteSeq μ, Measure.restrict_sum_of_countable, lintegral_sum_measure, lintegral_sum_measure] exact ENNReal.tsum_le_tsum fun n ↦ (hgint n s).trans (lintegral_mono fun x ↦ le_iSup (g · x) _) -- According to `exists_measurable_le_lintegral_eq`, for any natural `n` diff --git a/Mathlib/MeasureTheory/Measure/AEMeasurable.lean b/Mathlib/MeasureTheory/Measure/AEMeasurable.lean index 7ea4ac9be4b941..e1a65cd8f49a19 100644 --- a/Mathlib/MeasureTheory/Measure/AEMeasurable.lean +++ b/Mathlib/MeasureTheory/Measure/AEMeasurable.lean @@ -413,7 +413,7 @@ lemma map_sum {ι : Type*} {m : ι → Measure α} {f : α → β} (hf : AEMeasu instance (μ : Measure α) (f : α → β) [SFinite μ] : SFinite (μ.map f) := by by_cases H : AEMeasurable f μ - · rw [← sum_sFiniteSeq μ] at H ⊢ + · rw [← sum_sfiniteSeq μ] at H ⊢ rw [map_sum H] infer_instance · rw [map_of_not_aemeasurable H] diff --git a/Mathlib/MeasureTheory/Measure/Typeclasses.lean b/Mathlib/MeasureTheory/Measure/Typeclasses.lean index 9268fb84188248..df7f1022fa796c 100644 --- a/Mathlib/MeasureTheory/Measure/Typeclasses.lean +++ b/Mathlib/MeasureTheory/Measure/Typeclasses.lean @@ -548,24 +548,36 @@ section SFinite class SFinite (μ : Measure α) : Prop where out' : ∃ m : ℕ → Measure α, (∀ n, IsFiniteMeasure (m n)) ∧ μ = Measure.sum m -/-- A sequence of finite measures such that `μ = sum (sFiniteSeq μ)` (see `sum_sFiniteSeq`). -/ -noncomputable -def sFiniteSeq (μ : Measure α) [h : SFinite μ] : ℕ → Measure α := h.1.choose +/-- A sequence of finite measures such that `μ = sum (sfiniteSeq μ)` (see `sum_sfiniteSeq`). -/ +noncomputable def sfiniteSeq (μ : Measure α) [h : SFinite μ] : ℕ → Measure α := h.1.choose -instance isFiniteMeasure_sFiniteSeq [h : SFinite μ] (n : ℕ) : IsFiniteMeasure (sFiniteSeq μ n) := +@[deprecated (since := "2024-10-11")] alias sFiniteSeq := sfiniteSeq + +instance isFiniteMeasure_sfiniteSeq [h : SFinite μ] (n : ℕ) : IsFiniteMeasure (sfiniteSeq μ n) := h.1.choose_spec.1 n -lemma sum_sFiniteSeq (μ : Measure α) [h : SFinite μ] : sum (sFiniteSeq μ) = μ := +set_option linter.deprecated false in +@[deprecated (since := "2024-10-11")] +instance isFiniteMeasure_sFiniteSeq [SFinite μ] (n : ℕ) : IsFiniteMeasure (sFiniteSeq μ n) := + isFiniteMeasure_sfiniteSeq n + +lemma sum_sfiniteSeq (μ : Measure α) [h : SFinite μ] : sum (sfiniteSeq μ) = μ := h.1.choose_spec.2.symm -lemma sFiniteSeq_le (μ : Measure α) [SFinite μ] (n : ℕ) : sFiniteSeq μ n ≤ μ := - (le_sum _ n).trans (sum_sFiniteSeq μ).le +@[deprecated (since := "2024-10-11")] alias sum_sFiniteSeq := sum_sfiniteSeq + +lemma sfiniteSeq_le (μ : Measure α) [SFinite μ] (n : ℕ) : sfiniteSeq μ n ≤ μ := + (le_sum _ n).trans (sum_sfiniteSeq μ).le + +@[deprecated (since := "2024-10-11")] alias sFiniteSeq_le := sfiniteSeq_le instance : SFinite (0 : Measure α) := ⟨fun _ ↦ 0, inferInstance, by rw [Measure.sum_zero]⟩ @[simp] -lemma sFiniteSeq_zero (n : ℕ) : sFiniteSeq (0 : Measure α) n = 0 := - bot_unique <| sFiniteSeq_le _ _ +lemma sfiniteSeq_zero (n : ℕ) : sfiniteSeq (0 : Measure α) n = 0 := + bot_unique <| sfiniteSeq_le _ _ + +@[deprecated (since := "2024-10-11")] alias sFiniteSeq_zero := sfiniteSeq_zero /-- A countable sum of finite measures is s-finite. This lemma is superseded by the instance below. -/ @@ -582,7 +594,7 @@ lemma sfinite_sum_of_countable [Countable ι] instance [Countable ι] (m : ι → Measure α) [∀ n, SFinite (m n)] : SFinite (Measure.sum m) := by change SFinite (Measure.sum (fun i ↦ m i)) - simp_rw [← sum_sFiniteSeq (m _), Measure.sum_sum] + simp_rw [← sum_sfiniteSeq (m _), Measure.sum_sum] apply sfinite_sum_of_countable instance [SFinite μ] [SFinite ν] : SFinite (μ + ν) := by @@ -590,8 +602,8 @@ instance [SFinite μ] [SFinite ν] : SFinite (μ + ν) := by simpa using inferInstanceAs (SFinite (.sum (cond · μ ν))) instance [SFinite μ] (s : Set α) : SFinite (μ.restrict s) := - ⟨fun n ↦ (sFiniteSeq μ n).restrict s, fun n ↦ inferInstance, - by rw [← restrict_sum_of_countable, sum_sFiniteSeq]⟩ + ⟨fun n ↦ (sfiniteSeq μ n).restrict s, fun n ↦ inferInstance, + by rw [← restrict_sum_of_countable, sum_sfiniteSeq]⟩ variable (μ) in /-- For an s-finite measure `μ`, there exists a finite measure `ν` @@ -599,12 +611,12 @@ such that each of `μ` and `ν` is absolutely continuous with respect to the oth -/ theorem exists_isFiniteMeasure_absolutelyContinuous [SFinite μ] : ∃ ν : Measure α, IsFiniteMeasure ν ∧ μ ≪ ν ∧ ν ≪ μ := by - rcases ENNReal.exists_pos_tsum_mul_lt_of_countable top_ne_zero (sFiniteSeq μ · univ) + rcases ENNReal.exists_pos_tsum_mul_lt_of_countable top_ne_zero (sfiniteSeq μ · univ) fun _ ↦ measure_ne_top _ _ with ⟨c, hc₀, hc⟩ - have {s : Set α} : sum (fun n ↦ c n • sFiniteSeq μ n) s = 0 ↔ μ s = 0 := by - conv_rhs => rw [← sum_sFiniteSeq μ, sum_apply_of_countable] + have {s : Set α} : sum (fun n ↦ c n • sfiniteSeq μ n) s = 0 ↔ μ s = 0 := by + conv_rhs => rw [← sum_sfiniteSeq μ, sum_apply_of_countable] simp [(hc₀ _).ne'] - refine ⟨.sum fun n ↦ c n • sFiniteSeq μ n, ⟨?_⟩, fun _ ↦ this.1, fun _ ↦ this.2⟩ + refine ⟨.sum fun n ↦ c n • sfiniteSeq μ n, ⟨?_⟩, fun _ ↦ this.1, fun _ ↦ this.2⟩ simpa [mul_comm] using hc variable (μ) in @@ -791,9 +803,9 @@ theorem countable_meas_pos_of_disjoint_iUnion₀ {ι : Type*} {_ : MeasurableSpa [SFinite μ] {As : ι → Set α} (As_mble : ∀ i : ι, NullMeasurableSet (As i) μ) (As_disj : Pairwise (AEDisjoint μ on As)) : Set.Countable { i : ι | 0 < μ (As i) } := by - rw [← sum_sFiniteSeq μ] at As_disj As_mble ⊢ - have obs : { i : ι | 0 < sum (sFiniteSeq μ) (As i) } - ⊆ ⋃ n, { i : ι | 0 < sFiniteSeq μ n (As i) } := by + rw [← sum_sfiniteSeq μ] at As_disj As_mble ⊢ + have obs : { i : ι | 0 < sum (sfiniteSeq μ) (As i) } + ⊆ ⋃ 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 * @@ -939,7 +951,7 @@ This only holds when `μ` is s-finite -- for example for σ-finite measures. For this assumption (but requiring that `t` has finite measure), see `measure_toMeasurable_inter`. -/ theorem measure_toMeasurable_inter_of_sFinite [SFinite μ] {s : Set α} (hs : MeasurableSet s) (t : Set α) : μ (toMeasurable μ t ∩ s) = μ (t ∩ s) := - measure_toMeasurable_inter_of_sum hs (fun _ ↦ measure_ne_top _ t) (sum_sFiniteSeq μ).symm + measure_toMeasurable_inter_of_sum hs (fun _ ↦ measure_ne_top _ t) (sum_sfiniteSeq μ).symm @[simp] theorem restrict_toMeasurable_of_sFinite [SFinite μ] (s : Set α) : diff --git a/Mathlib/MeasureTheory/Measure/WithDensity.lean b/Mathlib/MeasureTheory/Measure/WithDensity.lean index 4af7da3eaff237..c6f8473cff0f9c 100644 --- a/Mathlib/MeasureTheory/Measure/WithDensity.lean +++ b/Mathlib/MeasureTheory/Measure/WithDensity.lean @@ -615,8 +615,8 @@ instance Measure.withDensity.instSFinite [SFinite μ] {f : α → ℝ≥0∞} : · rcases exists_measurable_le_withDensity_eq μ f with ⟨g, hgm, -, h⟩ exact h ▸ this hgm wlog hμ : IsFiniteMeasure μ generalizing μ - · rw [← sum_sFiniteSeq μ, withDensity_sum] - have (n : ℕ) : SFinite ((sFiniteSeq μ n).withDensity f) := this inferInstance + · rw [← sum_sfiniteSeq μ, withDensity_sum] + have (n : ℕ) : SFinite ((sfiniteSeq μ n).withDensity f) := this inferInstance infer_instance set s := {x | f x = ∞} have hs : MeasurableSet s := hfm (measurableSet_singleton _) diff --git a/Mathlib/MeasureTheory/Measure/WithDensityFinite.lean b/Mathlib/MeasureTheory/Measure/WithDensityFinite.lean index 5b496cf711c4d7..21abd06cd6ceea 100644 --- a/Mathlib/MeasureTheory/Measure/WithDensityFinite.lean +++ b/Mathlib/MeasureTheory/Measure/WithDensityFinite.lean @@ -100,9 +100,12 @@ instance [SFinite μ] [NeZero μ] : IsProbabilityMeasure μ.toFinite := by lemma absolutelyContinuous_toFinite (μ : Measure α) [SFinite μ] : μ ≪ μ.toFinite := Measure.ae_le_iff_absolutelyContinuous.mp ae_toFinite.ge -lemma sFiniteSeq_absolutelyContinuous_toFinite (μ : Measure α) [SFinite μ] (n : ℕ) : - sFiniteSeq μ n ≪ μ.toFinite := - (sFiniteSeq_le μ n).absolutelyContinuous.trans (absolutelyContinuous_toFinite μ) +lemma sfiniteSeq_absolutelyContinuous_toFinite (μ : Measure α) [SFinite μ] (n : ℕ) : + sfiniteSeq μ n ≪ μ.toFinite := + (sfiniteSeq_le μ n).absolutelyContinuous.trans (absolutelyContinuous_toFinite μ) + +@[deprecated (since := "2024-10-11")] +alias sFiniteSeq_absolutelyContinuous_toFinite := sfiniteSeq_absolutelyContinuous_toFinite lemma toFinite_absolutelyContinuous (μ : Measure α) [SFinite μ] : μ.toFinite ≪ μ := Measure.ae_le_iff_absolutelyContinuous.mp ae_toFinite.le diff --git a/Mathlib/Probability/Kernel/Basic.lean b/Mathlib/Probability/Kernel/Basic.lean index 3fc42e7dc57d22..b4ac72bc2f8105 100644 --- a/Mathlib/Probability/Kernel/Basic.lean +++ b/Mathlib/Probability/Kernel/Basic.lean @@ -124,7 +124,7 @@ instance const.instIsFiniteKernel {μβ : Measure β} [IsFiniteMeasure μβ] : instance const.instIsSFiniteKernel {μβ : Measure β} [SFinite μβ] : IsSFiniteKernel (const α μβ) := - ⟨fun n ↦ const α (sFiniteSeq μβ n), fun n ↦ inferInstance, by rw [sum_const, sum_sFiniteSeq]⟩ + ⟨fun n ↦ const α (sfiniteSeq μβ n), fun n ↦ inferInstance, by rw [sum_const, sum_sfiniteSeq]⟩ instance const.instIsMarkovKernel {μβ : Measure β} [hμβ : IsProbabilityMeasure μβ] : IsMarkovKernel (const α μβ) := From d1ea328b98d11798d80b789820f5317a02f0f8a6 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Sun, 13 Oct 2024 23:44:15 +0000 Subject: [PATCH 078/425] chore: adaptations for nightly-2024-10-13 (#17711) Co-authored-by: leanprover-community-mathlib4-bot Co-authored-by: Johan Commelin Co-authored-by: adomani Co-authored-by: Kyle Miller --- lake-manifest.json | 4 ++-- lean-toolchain | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index 8dbc5a9f315905..140811af6321f0 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,10 +5,10 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "b8b985f203e1f2f590e3ce46b50d722cc2ba8692", + "rev": "daf1ed91789811cf6bbb7bf2f4dad6b3bad8fbf4", "name": "batteries", "manifestFile": "lake-manifest.json", - "inputRev": "nightly-testing", + "inputRev": "main", "inherited": false, "configFile": "lakefile.lean"}, {"url": "https://github.com/leanprover-community/quote4", diff --git a/lean-toolchain b/lean-toolchain index 712a96012abe9b..30684366328531 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-10 +leanprover/lean4:nightly-2024-10-13 From cd125921730e9f4817a698255455d3d10e2ce971 Mon Sep 17 00:00:00 2001 From: Christopher Hoskin Date: Sun, 13 Oct 2024 23:54:00 +0000 Subject: [PATCH 079/425] refactor(Topology/Order/ScottTopology): Unify concepts of Scott Topology (#16523) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unify Scott Topologies, following on from #13201 and #16826. Originally Mathlib had a notion of ω-Scott Continuity and ω-Scott Topology based on Chains for ω-complete partial orders. Previously we introduced a notion of Scott Continuity and Scott Topology based on directed sets for arbitrary pre-orders (#2508). In #13201, we generalised our definition of Scott Continuity to include ω-Scott Continuity as a special case. This PR continues that work by generalising our notion of Scott Topology to include ω-Scott Topology as a special case. `Topology.IsScott.scottContinuous_iff_continuous` and `Topology.IsScott.ωscottContinuous_iff_continuous` have almost identical proofs and are presumably special cases of a more general result that I have not yet formulated. However I think this PR covers enough ground to be worth considering at this stage. Co-authored-by: Christopher Hoskin Co-authored-by: Christopher Hoskin --- .../Topology/OmegaCompletePartialOrder.lean | 20 ++ Mathlib/Topology/Order/LawsonTopology.lean | 23 ++- Mathlib/Topology/Order/ScottTopology.lean | 192 ++++++++++-------- 3 files changed, 139 insertions(+), 96 deletions(-) diff --git a/Mathlib/Topology/OmegaCompletePartialOrder.lean b/Mathlib/Topology/OmegaCompletePartialOrder.lean index 89f1e3ee2fa588..c7890d3939837b 100644 --- a/Mathlib/Topology/OmegaCompletePartialOrder.lean +++ b/Mathlib/Topology/OmegaCompletePartialOrder.lean @@ -6,6 +6,7 @@ Authors: Simon Hudon import Mathlib.Topology.Basic import Mathlib.Order.UpperLower.Basic import Mathlib.Order.OmegaCompletePartialOrder +import Mathlib.Topology.Order.ScottTopology /-! # Scott Topological Spaces @@ -23,6 +24,14 @@ open Set OmegaCompletePartialOrder universe u +open Topology.IsScott in +@[simp] lemma Topology.IsScott.ωscottContinuous_iff_continuous {α : Type*} + [OmegaCompletePartialOrder α] [TopologicalSpace α] + [Topology.IsScott α (Set.range fun c : Chain α => Set.range c)] {f : α → Prop} : + ωScottContinuous f ↔ Continuous f := by + rw [ωScottContinuous, scottContinuous_iff_continuous (fun a b hab => by + use Chain.pair a b hab; exact OmegaCompletePartialOrder.Chain.range_pair a b hab)] + -- "Scott", "ωSup" namespace Scott @@ -67,6 +76,17 @@ instance Scott.topologicalSpace (α : Type u) [OmegaCompletePartialOrder α] : isOpen_inter := Scott.IsOpen.inter α isOpen_sUnion := Scott.isOpen_sUnion α +lemma isOpen_iff_ωScottContinuous_mem {α} [OmegaCompletePartialOrder α] {s : Set (Scott α)} : + IsOpen s ↔ ωScottContinuous fun x ↦ x ∈ s := by rfl + +lemma scott_eq_Scott {α} [OmegaCompletePartialOrder α] : + Topology.scott α (Set.range fun c : Chain α => Set.range c) = Scott.topologicalSpace α := by + ext U + letI := Topology.scott α (Set.range fun c : Chain α => Set.range c) + rw [isOpen_iff_ωScottContinuous_mem, @isOpen_iff_continuous_mem, + @Topology.IsScott.ωscottContinuous_iff_continuous _ _ + (Topology.scott α (Set.range fun c : Chain α => Set.range c)) ({ topology_eq_scott := rfl })] + section notBelow variable {α : Type*} [OmegaCompletePartialOrder α] (y : Scott α) diff --git a/Mathlib/Topology/Order/LawsonTopology.lean b/Mathlib/Topology/Order/LawsonTopology.lean index 945cc85292c34c..442697dd2d18a6 100644 --- a/Mathlib/Topology/Order/LawsonTopology.lean +++ b/Mathlib/Topology/Order/LawsonTopology.lean @@ -61,7 +61,7 @@ section Preorder /-- The Lawson topology is defined as the meet of `Topology.lower` and the `Topology.scott`. -/ -def lawson (α : Type*) [Preorder α] : TopologicalSpace α := lower α ⊓ scott α +def lawson (α : Type*) [Preorder α] : TopologicalSpace α := lower α ⊓ scott α univ variable (α) [Preorder α] [TopologicalSpace α] @@ -80,13 +80,13 @@ variable (α) [Preorder α] [TopologicalSpace α] [IsLawson α] /-- The complements of the upper closures of finite sets intersected with Scott open sets form a basis for the lawson topology. -/ -def lawsonBasis := { s : Set α | ∃ t : Set α, t.Finite ∧ ∃ u : Set α, IsOpen[scott α] u ∧ +def lawsonBasis := { s : Set α | ∃ t : Set α, t.Finite ∧ ∃ u : Set α, IsOpen[scott α univ] u ∧ u \ upperClosure t = s } protected theorem isTopologicalBasis : TopologicalSpace.IsTopologicalBasis (lawsonBasis α) := by have lawsonBasis_image2 : lawsonBasis α = (image2 (fun x x_1 ↦ ⇑WithLower.toLower ⁻¹' x ∩ ⇑WithScott.toScott ⁻¹' x_1) - (IsLower.lowerBasis (WithLower α)) {U | IsOpen[scott α] U}) := by + (IsLower.lowerBasis (WithLower α)) {U | IsOpen[scott α univ] U}) := by rw [lawsonBasis, image2, IsLower.lowerBasis] simp_rw [diff_eq_compl_inter] aesop @@ -97,7 +97,8 @@ protected theorem isTopologicalBasis : TopologicalSpace.IsTopologicalBasis (laws rw [@topology_eq_lawson α _ _ _, lawson] apply (congrArg₂ Inf.inf _) _ · letI _ := lower α; exact @IsLower.withLowerHomeomorph α ‹_› (lower α) ⟨rfl⟩ |>.inducing.induced - letI _ := scott α; exact @IsScott.withScottHomeomorph α _ (scott α) ⟨rfl⟩ |>.inducing.induced + letI _ := scott α univ + exact @IsScott.withScottHomeomorph α _ (scott α univ) ⟨rfl⟩ |>.inducing.induced end Preorder end IsLawson @@ -161,11 +162,11 @@ section Preorder variable [Preorder α] -lemma lawson_le_scott : lawson α ≤ scott α := inf_le_right +lemma lawson_le_scott : lawson α ≤ scott α univ := inf_le_right lemma lawson_le_lower : lawson α ≤ lower α := inf_le_left -lemma scottHausdorff_le_lawson : scottHausdorff α ≤ lawson α := +lemma scottHausdorff_le_lawson : scottHausdorff α univ ≤ lawson α := le_inf scottHausdorff_le_lower scottHausdorff_le_scott lemma lawsonClosed_of_scottClosed (s : Set α) (h : IsClosed (WithScott.ofScott ⁻¹' s)) : @@ -177,24 +178,24 @@ lemma lawsonClosed_of_lowerClosed (s : Set α) (h : IsClosed (WithLower.ofLower /-- An upper set is Lawson open if and only if it is Scott open -/ lemma lawsonOpen_iff_scottOpen_of_isUpperSet {s : Set α} (h : IsUpperSet s) : IsOpen (WithLawson.ofLawson ⁻¹' s) ↔ IsOpen (WithScott.ofScott ⁻¹' s) := - ⟨fun hs => IsScott.isOpen_iff_isUpperSet_and_scottHausdorff_open.mpr + ⟨fun hs => IsScott.isOpen_iff_isUpperSet_and_scottHausdorff_open (D := univ).mpr ⟨h, (scottHausdorff_le_lawson s) hs⟩, lawson_le_scott _⟩ variable (L : TopologicalSpace α) (S : TopologicalSpace α) -variable [@IsLawson α _ L] [@IsScott α _ S] +variable [@IsLawson α _ L] [@IsScott α univ _ S] lemma isLawson_le_isScott : L ≤ S := by - rw [@IsScott.topology_eq α _ S _, @IsLawson.topology_eq_lawson α _ L _] + rw [@IsScott.topology_eq α univ _ S _, @IsLawson.topology_eq_lawson α _ L _] exact inf_le_right -lemma scottHausdorff_le_isLawson : scottHausdorff α ≤ L := by +lemma scottHausdorff_le_isLawson : scottHausdorff α univ ≤ L := by rw [@IsLawson.topology_eq_lawson α _ L _] exact scottHausdorff_le_lawson /-- An upper set is Lawson open if and only if it is Scott open -/ lemma lawsonOpen_iff_scottOpen_of_isUpperSet' (s : Set α) (h : IsUpperSet s) : IsOpen[L] s ↔ IsOpen[S] s := by - rw [@IsLawson.topology_eq_lawson α _ L _, @IsScott.topology_eq α _ S _] + rw [@IsLawson.topology_eq_lawson α _ L _, @IsScott.topology_eq α univ _ S _] exact lawsonOpen_iff_scottOpen_of_isUpperSet h lemma lawsonClosed_iff_scottClosed_of_isLowerSet (s : Set α) (h : IsLowerSet s) : diff --git a/Mathlib/Topology/Order/ScottTopology.lean b/Mathlib/Topology/Order/ScottTopology.lean index 747074b163cfb1..0a203e27ad7898 100644 --- a/Mathlib/Topology/Order/ScottTopology.lean +++ b/Mathlib/Topology/Order/ScottTopology.lean @@ -68,11 +68,25 @@ variable {α β : Type*} section Preorder variable [Preorder α] {s t : Set α} +/-- A set `s` is said to be inaccessible by directed joins on `D` if, when the least upper bound of +a directed set `d` in `D` lies in `s` then `d` has non-empty intersection with `s`. -/ +def DirSupInaccOn (D : Set (Set α)) (s : Set α) : Prop := + ∀ ⦃d⦄, d ∈ D → d.Nonempty → DirectedOn (· ≤ ·) d → ∀ ⦃a⦄, IsLUB d a → a ∈ s → (d ∩ s).Nonempty + /-- A set `s` is said to be inaccessible by directed joins if, when the least upper bound of a directed set `d` lies in `s` then `d` has non-empty intersection with `s`. -/ def DirSupInacc (s : Set α) : Prop := ∀ ⦃d⦄, d.Nonempty → DirectedOn (· ≤ ·) d → ∀ ⦃a⦄, IsLUB d a → a ∈ s → (d ∩ s).Nonempty +@[simp] lemma dirSupInaccOn_univ : DirSupInaccOn univ s ↔ DirSupInacc s := by + simp [DirSupInaccOn, DirSupInacc] + +@[simp] lemma DirSupInacc.dirSupInaccOn {D : Set (Set α)} : + DirSupInacc s → DirSupInaccOn D s := fun h _ _ d₂ d₃ _ hda => h d₂ d₃ hda + +lemma DirSupInaccOn.mono {D₁ D₂ : Set (Set α)} (hD : D₁ ⊆ D₂) (hf : DirSupInaccOn D₂ s) : + DirSupInaccOn D₁ s := fun ⦃_⦄ a ↦ hf (hD a) + /-- A set `s` is said to be closed under directed joins if, whenever a directed set `d` has a least upper bound `a` and is a subset of `s` then `a` also lies in `s`. @@ -124,54 +138,55 @@ namespace Topology /-! ### Scott-Hausdorff topology -/ section ScottHausdorff -variable [Preorder α] /-- The Scott-Hausdorff topology. A set `u` is open in the Scott-Hausdorff topology iff when the least upper bound of a directed set `d` lies in `u` then there is a tail of `d` which is a subset of `u`. -/ -def scottHausdorff (α : Type*) [Preorder α] : TopologicalSpace α where - IsOpen u := ∀ ⦃d : Set α⦄, d.Nonempty → DirectedOn (· ≤ ·) d → ∀ ⦃a : α⦄, IsLUB d a → +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 - isOpen_univ := fun d ⟨b, hb⟩ _ _ _ _ ↦ ⟨b, hb, (Ici b ∩ d).subset_univ⟩ - isOpen_inter s t hs ht d hd₁ hd₂ a hd₃ ha := by - obtain ⟨b₁, hb₁d, hb₁ds⟩ := hs hd₁ hd₂ hd₃ ha.1 - obtain ⟨b₂, hb₂d, hb₂dt⟩ := ht hd₁ hd₂ hd₃ ha.2 + isOpen_univ := fun d _ ⟨b, hb⟩ _ _ _ _ ↦ ⟨b, hb, (Ici b ∩ d).subset_univ⟩ + isOpen_inter s t hs ht d hd₀ hd₁ hd₂ a hd₃ ha := by + obtain ⟨b₁, hb₁d, hb₁ds⟩ := hs hd₀ hd₁ hd₂ hd₃ ha.1 + obtain ⟨b₂, hb₂d, hb₂dt⟩ := ht hd₀ hd₁ hd₂ hd₃ ha.2 obtain ⟨c, hcd, hc⟩ := hd₂ b₁ hb₁d b₂ hb₂d exact ⟨c, hcd, fun e ⟨hce, hed⟩ ↦ ⟨hb₁ds ⟨hc.1.trans hce, hed⟩, hb₂dt ⟨hc.2.trans hce, hed⟩⟩⟩ - isOpen_sUnion := fun s h d hd₁ hd₂ a hd₃ ⟨s₀, hs₀s, has₀⟩ ↦ by - obtain ⟨b, hbd, hbds₀⟩ := h s₀ hs₀s hd₁ hd₂ hd₃ has₀ + isOpen_sUnion := fun s h d hd₀ hd₁ hd₂ a hd₃ ⟨s₀, hs₀s, has₀⟩ ↦ by + obtain ⟨b, hbd, hbds₀⟩ := h s₀ hs₀s hd₀ hd₁ hd₂ hd₃ has₀ exact ⟨b, hbd, Set.subset_sUnion_of_subset s s₀ hbds₀ hs₀s⟩ -variable (α) [TopologicalSpace α] +variable (α) (D : Set (Set α)) [Preorder α] [TopologicalSpace α] /-- Predicate for an ordered topological space to be equipped with its Scott-Hausdorff topology. A set `u` is open in the Scott-Hausdorff topology iff when the least upper bound of a directed set `d` lies in `u` then there is a tail of `d` which is a subset of `u`. -/ class IsScottHausdorff : Prop where - topology_eq_scottHausdorff : ‹TopologicalSpace α› = scottHausdorff α + topology_eq_scottHausdorff : ‹TopologicalSpace α› = scottHausdorff α D -instance : @IsScottHausdorff α _ (scottHausdorff α) := - @IsScottHausdorff.mk _ _ (scottHausdorff α) rfl +instance : @IsScottHausdorff α D _ (scottHausdorff α D) := + @IsScottHausdorff.mk _ _ _ (scottHausdorff α D) rfl namespace IsScottHausdorff -variable [IsScottHausdorff α] {s : Set α} +variable {s : Set α} -lemma topology_eq : ‹_› = scottHausdorff α := topology_eq_scottHausdorff +lemma topology_eq [IsScottHausdorff α D] : ‹_› = scottHausdorff α D := topology_eq_scottHausdorff -variable {α} +variable {α D} -lemma isOpen_iff : - IsOpen s ↔ ∀ ⦃d : Set α⦄, d.Nonempty → DirectedOn (· ≤ ·) d → ∀ ⦃a : α⦄, IsLUB d a → - a ∈ s → ∃ b ∈ d, Ici b ∩ d ⊆ s := by rw [topology_eq_scottHausdorff (α := α)]; rfl +lemma isOpen_iff [IsScottHausdorff α D] : + IsOpen s ↔ ∀ ⦃d : Set α⦄, d ∈ D → d.Nonempty → DirectedOn (· ≤ ·) d → ∀ ⦃a : α⦄, IsLUB d a → + a ∈ s → ∃ b ∈ d, Ici b ∩ d ⊆ s := by erw [topology_eq_scottHausdorff (α := α) (D := D)]; rfl -lemma dirSupInacc_of_isOpen (h : IsOpen s) : DirSupInacc s := - fun d hd₁ hd₂ a hda hd₃ ↦ by - obtain ⟨b, hbd, hb⟩ := isOpen_iff.1 h hd₁ hd₂ hda hd₃; exact ⟨b, hbd, hb ⟨le_rfl, hbd⟩⟩ +lemma dirSupInaccOn_of_isOpen [IsScottHausdorff α D] (h : IsOpen s) : DirSupInaccOn D s := + fun d hd₀ hd₁ hd₂ a hda hd₃ ↦ by + obtain ⟨b, hbd, hb⟩ := isOpen_iff.mp h hd₀ hd₁ hd₂ hda hd₃; exact ⟨b, hbd, hb ⟨le_rfl, hbd⟩⟩ -lemma dirSupClosed_of_isClosed (h : IsClosed s) : DirSupClosed s := - (dirSupInacc_of_isOpen h.isOpen_compl).of_compl +lemma dirSupClosed_of_isClosed [IsScottHausdorff α univ] (h : IsClosed s) : DirSupClosed s := by + apply DirSupInacc.of_compl + rw [← dirSupInaccOn_univ] + exact (dirSupInaccOn_of_isOpen h.isOpen_compl) end IsScottHausdorff end ScottHausdorff @@ -179,10 +194,11 @@ end ScottHausdorff section ScottHausdorff namespace IsScottHausdorff -variable {s : Set α} [Preorder α] {t : TopologicalSpace α} [IsScottHausdorff α] +variable {s : Set α} [Preorder α] {t : TopologicalSpace α} [IsScottHausdorff α univ] lemma isOpen_of_isLowerSet (h : IsLowerSet s) : IsOpen s := - isOpen_iff.2 fun _d ⟨b, hb⟩ _ _ hda ha ↦ ⟨b, hb, fun _ hc ↦ h (mem_upperBounds.1 hda.1 _ hc.2) ha⟩ + (isOpen_iff (D := univ)).2 fun _d _ ⟨b, hb⟩ _ _ hda ha ↦ + ⟨b, hb, fun _ hc ↦ h (mem_upperBounds.1 hda.1 _ hc.2) ha⟩ lemma isClosed_of_isUpperSet (h : IsUpperSet s) : IsClosed s := isOpen_compl_iff.1 <| isOpen_of_isLowerSet h.compl @@ -194,105 +210,110 @@ end ScottHausdorff section Scott section Preorder -variable [Preorder α] /-- The Scott topology. It is defined as the join of the topology of upper sets and the Scott-Hausdorff topology. -/ -def scott (α : Type*) [Preorder α] : TopologicalSpace α := upperSet α ⊔ scottHausdorff α +def scott (α : Type*) (D : Set (Set α)) [Preorder α] : TopologicalSpace α := + upperSet α ⊔ scottHausdorff α D -lemma upperSet_le_scott : upperSet α ≤ scott α := le_sup_left +lemma upperSet_le_scott [Preorder α] : upperSet α ≤ scott α univ := le_sup_left -lemma scottHausdorff_le_scott : scottHausdorff α ≤ scott α := le_sup_right +lemma scottHausdorff_le_scott [Preorder α] : scottHausdorff α univ ≤ scott α univ:= le_sup_right -variable (α) [TopologicalSpace α] +variable (α) (D) [Preorder α] [TopologicalSpace α] /-- Predicate for an ordered topological space to be equipped with its Scott topology. The Scott topology is defined as the join of the topology of upper sets and the Scott Hausdorff topology. -/ class IsScott : Prop where - topology_eq_scott : ‹TopologicalSpace α› = scott α + topology_eq_scott : ‹TopologicalSpace α› = scott α D end Preorder namespace IsScott section Preorder -variable (α) [Preorder α] [TopologicalSpace α] [IsScott α] +variable (α) (D) [Preorder α] [TopologicalSpace α] -lemma topology_eq : ‹_› = scott α := topology_eq_scott +lemma topology_eq [IsScott α D] : ‹_› = scott α D := topology_eq_scott -variable {α} {s : Set α} {a : α} +variable {α} {D} {s : Set α} {a : α} -lemma isOpen_iff_isUpperSet_and_scottHausdorff_open : - IsOpen s ↔ IsUpperSet s ∧ IsOpen[scottHausdorff α] s := by rw [topology_eq α]; rfl +lemma isOpen_iff_isUpperSet_and_scottHausdorff_open [IsScott α D] : + IsOpen s ↔ IsUpperSet s ∧ IsOpen[scottHausdorff α D] s := by erw [topology_eq α D]; rfl -lemma isOpen_iff_isUpperSet_and_dirSupInacc : IsOpen s ↔ IsUpperSet s ∧ DirSupInacc s := by - rw [isOpen_iff_isUpperSet_and_scottHausdorff_open] +lemma isOpen_iff_isUpperSet_and_dirSupInaccOn [IsScott α D] : + IsOpen s ↔ IsUpperSet s ∧ DirSupInaccOn D s := by + rw [isOpen_iff_isUpperSet_and_scottHausdorff_open (D := D)] refine and_congr_right fun h ↦ - ⟨@IsScottHausdorff.dirSupInacc_of_isOpen _ _ (scottHausdorff α) _ _, - fun h' d d₁ d₂ _ d₃ ha ↦ ?_⟩ - obtain ⟨b, hbd, hbu⟩ := h' d₁ d₂ d₃ ha + ⟨@IsScottHausdorff.dirSupInaccOn_of_isOpen _ _ _ (scottHausdorff α D) _ _, + fun h' d d₀ d₁ d₂ _ d₃ ha ↦ ?_⟩ + obtain ⟨b, hbd, hbu⟩ := h' d₀ d₁ d₂ d₃ ha exact ⟨b, hbd, Subset.trans inter_subset_left (h.Ici_subset hbu)⟩ -lemma isClosed_iff_isLowerSet_and_dirSupClosed : IsClosed s ↔ IsLowerSet s ∧ DirSupClosed s := by - rw [← isOpen_compl_iff, isOpen_iff_isUpperSet_and_dirSupInacc, isUpperSet_compl, - dirSupInacc_compl] +lemma isClosed_iff_isLowerSet_and_dirSupClosed [IsScott α univ] : + IsClosed s ↔ IsLowerSet s ∧ DirSupClosed s := by + rw [← isOpen_compl_iff, isOpen_iff_isUpperSet_and_dirSupInaccOn (D := univ), isUpperSet_compl, + dirSupInaccOn_univ, dirSupInacc_compl] -lemma isUpperSet_of_isOpen : IsOpen s → IsUpperSet s := fun h ↦ - (isOpen_iff_isUpperSet_and_scottHausdorff_open.mp h).left +lemma isUpperSet_of_isOpen [IsScott α D] : IsOpen s → IsUpperSet s := fun h ↦ + (isOpen_iff_isUpperSet_and_scottHausdorff_open (D := D).mp h).left -lemma isLowerSet_of_isClosed : IsClosed s → IsLowerSet s := fun h ↦ +lemma isLowerSet_of_isClosed [IsScott α univ] : IsClosed s → IsLowerSet s := fun h ↦ (isClosed_iff_isLowerSet_and_dirSupClosed.mp h).left -lemma dirSupClosed_of_isClosed : IsClosed s → DirSupClosed s := fun h ↦ +lemma dirSupClosed_of_isClosed [IsScott α univ] : IsClosed s → DirSupClosed s := fun h ↦ (isClosed_iff_isLowerSet_and_dirSupClosed.mp h).right -lemma lowerClosure_subset_closure : ↑(lowerClosure s) ⊆ closure s := by +lemma lowerClosure_subset_closure [IsScott α univ] : ↑(lowerClosure s) ⊆ closure s := by convert closure.mono (@upperSet_le_scott α _) · rw [@IsUpperSet.closure_eq_lowerClosure α _ (upperSet α) ?_ s] infer_instance - · exact topology_eq α + · exact topology_eq α univ -lemma isClosed_Iic : IsClosed (Iic a) := +lemma isClosed_Iic [IsScott α univ] : IsClosed (Iic a) := isClosed_iff_isLowerSet_and_dirSupClosed.2 ⟨isLowerSet_Iic _, dirSupClosed_Iic _⟩ /-- The closure of a singleton `{a}` in the Scott topology is the right-closed left-infinite interval `(-∞,a]`. -/ -@[simp] lemma closure_singleton : closure {a} = Iic a := le_antisymm +@[simp] lemma closure_singleton [IsScott α univ] : closure {a} = Iic a := le_antisymm (closure_minimal (by rw [singleton_subset_iff, mem_Iic]) isClosed_Iic) <| by rw [← LowerSet.coe_Iic, ← lowerClosure_singleton] apply lowerClosure_subset_closure -variable [Preorder β] [TopologicalSpace β] [IsScott β] {f : α → β} +variable [Preorder β] [TopologicalSpace β] [IsScott β univ] {f : α → β} -lemma monotone_of_continuous (hf : Continuous f) : Monotone f := fun _ b hab ↦ by +lemma monotone_of_continuous [IsScott α D] (hf : Continuous f) : Monotone f := fun _ b hab ↦ by by_contra h simpa only [mem_compl_iff, mem_preimage, mem_Iic, le_refl, not_true] - using isUpperSet_of_isOpen ((isOpen_compl_iff.2 isClosed_Iic).preimage hf) hab h + using isUpperSet_of_isOpen (D := D) ((isOpen_compl_iff.2 isClosed_Iic).preimage hf) hab h -@[simp] lemma scottContinuous_iff_continuous : ScottContinuous f ↔ Continuous f := by +@[simp] lemma scottContinuous_iff_continuous {D : Set (Set α)} [Topology.IsScott α D] + (hD : ∀ a b : α, a ≤ b → {a, b} ∈ D) : ScottContinuousOn D f ↔ Continuous f := by refine ⟨fun h ↦ continuous_def.2 fun u hu ↦ ?_, ?_⟩ - · rw [isOpen_iff_isUpperSet_and_dirSupInacc] - exact ⟨(isUpperSet_of_isOpen hu).preimage h.monotone, fun _ hd₁ hd₂ _ hd₃ ha ↦ - image_inter_nonempty_iff.mp <| (isOpen_iff_isUpperSet_and_dirSupInacc.mp hu).2 (hd₁.image f) - (directedOn_image.mpr (hd₂.mono @(h.monotone))) (h hd₁ hd₂ hd₃) ha⟩ - · refine fun hf _ d₁ d₂ _ d₃ ↦ ⟨(monotone_of_continuous hf).mem_upperBounds_image d₃.1, + · rw [isOpen_iff_isUpperSet_and_dirSupInaccOn (D := D)] + exact ⟨(isUpperSet_of_isOpen (D := univ) hu).preimage (h.monotone D hD), + fun t h₀ hd₁ hd₂ a hd₃ ha ↦ image_inter_nonempty_iff.mp <| + (isOpen_iff_isUpperSet_and_dirSupInaccOn (D := univ).mp hu).2 trivial (Nonempty.image f hd₁) + (directedOn_image.mpr (hd₂.mono @(h.monotone D hD))) (h h₀ hd₁ hd₂ hd₃) ha⟩ + · refine fun hf t h₀ d₁ d₂ a d₃ ↦ + ⟨(monotone_of_continuous (D := D) hf).mem_upperBounds_image d₃.1, fun b hb ↦ ?_⟩ by_contra h let u := (Iic b)ᶜ - have hu : IsOpen (f ⁻¹' u) := (isOpen_compl_iff.2 isClosed_Iic).preimage hf - rw [isOpen_iff_isUpperSet_and_dirSupInacc] at hu - obtain ⟨c, hcd, hfcb⟩ := hu.2 d₁ d₂ d₃ h + have hu : IsOpen (f ⁻¹' u) := (isOpen_compl_iff.2 Topology.IsScott.isClosed_Iic).preimage hf + rw [isOpen_iff_isUpperSet_and_dirSupInaccOn (D := D)] at hu + obtain ⟨c, hcd, hfcb⟩ := hu.2 h₀ d₁ d₂ d₃ h simp [upperBounds] at hb exact hfcb <| hb _ hcd end Preorder section PartialOrder -variable [PartialOrder α] [TopologicalSpace α] [IsScott α] +variable [PartialOrder α] [TopologicalSpace α] [IsScott α univ] /-- The Scott topology on a partial order is T₀. @@ -308,7 +329,7 @@ section CompleteLinearOrder variable [CompleteLinearOrder α] -lemma isOpen_iff_Iic_compl_or_univ [TopologicalSpace α] [Topology.IsScott α] (U : Set α) : +lemma isOpen_iff_Iic_compl_or_univ [TopologicalSpace α] [Topology.IsScott α univ] (U : Set α) : IsOpen U ↔ U = univ ∨ ∃ a, (Iic a)ᶜ = U := by constructor · intro hU @@ -326,25 +347,25 @@ lemma isOpen_iff_Iic_compl_or_univ [TopologicalSpace α] [Topology.IsScott α] ( -- 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 α = upper α := by +lemma scott_eq_upper_of_completeLinearOrder : scott α univ = upper α := by letI := upper α ext U rw [@Topology.IsUpper.isTopologicalSpace_basis _ _ (upper α) ({ topology_eq_upperTopology := rfl }) U] - letI := scott α - rw [@isOpen_iff_Iic_compl_or_univ _ _ (scott α) ({ topology_eq_scott := rfl }) U] + letI := 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 -/ -instance [TopologicalSpace α] [IsUpper α] : IsScott α where +instance [TopologicalSpace α] [IsUpper α] : IsScott α univ where topology_eq_scott := by rw [scott_eq_upper_of_completeLinearOrder] exact IsUpper.topology_eq α end CompleteLinearOrder -lemma isOpen_iff_scottContinuous_mem [Preorder α] {s : Set α} [TopologicalSpace α] [IsScott α] : - IsOpen s ↔ ScottContinuous fun x ↦ x ∈ s := by - rw [scottContinuous_iff_continuous] +lemma isOpen_iff_scottContinuous_mem [Preorder α] {s : Set α} [TopologicalSpace α] + [IsScott α univ] : IsOpen s ↔ ScottContinuous fun x ↦ x ∈ s := by + rw [← scottContinuousOn_univ, scottContinuous_iff_continuous (fun _ _ _ ↦ by trivial)] exact isOpen_iff_continuous_mem end IsScott @@ -384,34 +405,35 @@ instance [Inhabited α] : Inhabited (WithScott α) := ‹Inhabited α› variable [Preorder α] instance : Preorder (WithScott α) := ‹Preorder α› -instance : TopologicalSpace (WithScott α) := scott α -instance : IsScott (WithScott α) := ⟨rfl⟩ +instance : TopologicalSpace (WithScott α) := scott α univ +instance : IsScott (WithScott α) univ := ⟨rfl⟩ lemma isOpen_iff_isUpperSet_and_scottHausdorff_open' {u : Set α} : - IsOpen (WithScott.ofScott ⁻¹' u) ↔ IsUpperSet u ∧ (scottHausdorff α).IsOpen u := Iff.rfl + IsOpen (WithScott.ofScott ⁻¹' u) ↔ IsUpperSet u ∧ (scottHausdorff α univ).IsOpen u := Iff.rfl end WithScott end Scott variable [Preorder α] -lemma scottHausdorff_le_lower : scottHausdorff α ≤ lower α := - fun s h => IsScottHausdorff.isOpen_of_isLowerSet (t := scottHausdorff α) +lemma scottHausdorff_le_lower : scottHausdorff α univ ≤ lower α := + fun s h => IsScottHausdorff.isOpen_of_isLowerSet (t := scottHausdorff α univ) <| (@IsLower.isLowerSet_of_isOpen (Topology.WithLower α) _ _ _ s h) variable [TopologicalSpace α] /-- If `α` is equipped with the Scott topology, then it is homeomorphic to `WithScott α`. -/ -def IsScott.withScottHomeomorph [IsScott α] : WithScott α ≃ₜ α := - WithScott.ofScott.toHomeomorphOfInducing ⟨by erw [IsScott.topology_eq α, induced_id]; rfl⟩ +def IsScott.withScottHomeomorph [IsScott α univ] : WithScott α ≃ₜ α := + WithScott.ofScott.toHomeomorphOfInducing ⟨by erw [IsScott.topology_eq α univ, induced_id]; rfl⟩ -lemma IsScott.scottHausdorff_le [IsScott α] : scottHausdorff α ≤ ‹TopologicalSpace α› := by - rw [IsScott.topology_eq α, scott]; exact le_sup_right +lemma IsScott.scottHausdorff_le [IsScott α univ] : + scottHausdorff α univ ≤ ‹TopologicalSpace α› := by + rw [IsScott.topology_eq α univ, scott]; exact le_sup_right -lemma IsLower.scottHausdorff_le [IsLower α] : scottHausdorff α ≤ ‹TopologicalSpace α› := +lemma IsLower.scottHausdorff_le [IsLower α] : scottHausdorff α univ ≤ ‹TopologicalSpace α› := fun _ h ↦ - IsScottHausdorff.isOpen_of_isLowerSet (t := scottHausdorff α) + IsScottHausdorff.isOpen_of_isLowerSet (t := scottHausdorff α univ) <| IsLower.isLowerSet_of_isOpen h end Topology From 9a1b545e7b7a28f511f76e81c42a737a45948ec1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Sun, 13 Oct 2024 23:54:01 +0000 Subject: [PATCH 080/425] feat(SetTheory/Game/Nim): make `grundyValue` a nimber (#17645) We redefine the grundy value of an impartial game as a nimber. That way, we can prove a more general form of `grundyValue_add`. --- Mathlib/SetTheory/Game/Nim.lean | 100 ++++++++++++-------------- Mathlib/SetTheory/Ordinal/Nimber.lean | 4 ++ 2 files changed, 48 insertions(+), 56 deletions(-) diff --git a/Mathlib/SetTheory/Game/Nim.lean b/Mathlib/SetTheory/Game/Nim.lean index f563fafa77d4b7..7bf6c35a662b1e 100644 --- a/Mathlib/SetTheory/Game/Nim.lean +++ b/Mathlib/SetTheory/Game/Nim.lean @@ -3,9 +3,9 @@ Copyright (c) 2020 Fox Thomson. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Fox Thomson, Markus Himmel -/ -import Mathlib.Data.Nat.Bitwise import Mathlib.SetTheory.Game.Birthday import Mathlib.SetTheory.Game.Impartial +import Mathlib.SetTheory.Ordinal.Nimber /-! # Nim and the Sprague-Grundy theorem @@ -14,8 +14,8 @@ This file contains the definition for nim for any ordinal `o`. In the game of `n may move to `nim o₂` for any `o₂ < o₁`. We also define a Grundy value for an impartial game `G` and prove the Sprague-Grundy theorem, that `G` is equivalent to `nim (grundyValue G)`. -Finally, we compute the sum of finite Grundy numbers: if `G` and `H` have Grundy values `n` and `m`, -where `n` and `m` are natural numbers, then `G + H` has the Grundy value `n xor m`. +Finally, we prove that the grundy value of a sum `G + H` corresponds to the nimber sum of the +individual grundy values. ## Implementation details @@ -37,7 +37,7 @@ universe u namespace SetTheory open scoped PGame -open Ordinal +open Ordinal Nimber namespace PGame @@ -209,8 +209,12 @@ theorem nim_equiv_iff_eq {o₁ o₂ : Ordinal} : (nim o₁ ≈ nim o₂) ↔ o /-- The Grundy value of an impartial game is recursively defined as the minimum excluded value (the infimum of the complement) of the Grundy values of either its left or right options. -This is the ordinal which corresponds to the game of nim that the game is equivalent to. -/ -noncomputable def grundyValue (G : PGame.{u}) : Ordinal.{u} := +This is the ordinal which corresponds to the game of nim that the game is equivalent to. + +This function takes a value in `Nimber`. This is a type synonym for the ordinals which has the same +ordering, but addition in `Nimber` is such that it corresponds to the grundy value of the addition +of games. See that file for more information on nimbers and their arithmetic. -/ +noncomputable def grundyValue (G : PGame.{u}) : Nimber.{u} := sInf (Set.range fun i => grundyValue (G.moveLeft i))ᶜ termination_by G @@ -232,26 +236,27 @@ theorem grundyValue_ne_moveLeft {G : PGame} (i : G.LeftMoves) : rw [Set.mem_compl_iff, Set.mem_range, not_exists] at this exact this _ -theorem le_grundyValue_of_Iio_subset_moveLeft {G : PGame} {o : Ordinal} +theorem le_grundyValue_of_Iio_subset_moveLeft {G : PGame} {o : Nimber} (h : Set.Iio o ⊆ Set.range (grundyValue ∘ G.moveLeft)) : o ≤ grundyValue G := by by_contra! ho obtain ⟨i, hi⟩ := h ho exact grundyValue_ne_moveLeft i hi -theorem exists_grundyValue_moveLeft_of_lt {G : PGame} {o : Ordinal} (h : o < grundyValue G) : +theorem exists_grundyValue_moveLeft_of_lt {G : PGame} {o : Nimber} (h : o < grundyValue G) : ∃ i, grundyValue (G.moveLeft i) = o := by rw [grundyValue_eq_sInf_moveLeft] at h by_contra ha exact h.not_le (csInf_le' ha) -theorem grundyValue_le_of_forall_moveLeft {G : PGame} {o : Ordinal} +theorem grundyValue_le_of_forall_moveLeft {G : PGame} {o : Nimber} (h : ∀ i, grundyValue (G.moveLeft i) ≠ o) : G.grundyValue ≤ o := by contrapose! h exact exists_grundyValue_moveLeft_of_lt h /-- The **Sprague-Grundy theorem** states that every impartial game is equivalent to a game of nim, namely the game of nim corresponding to the game's Grundy value. -/ -theorem equiv_nim_grundyValue (G : PGame.{u}) [G.Impartial] : G ≈ nim (grundyValue G) := by +theorem equiv_nim_grundyValue (G : PGame.{u}) [G.Impartial] : + G ≈ nim (toOrdinal (grundyValue G)) := by rw [Impartial.equiv_iff_add_equiv_zero, ← Impartial.forall_leftMoves_fuzzy_iff_equiv_zero] intro x apply leftMoves_add_cases x <;> @@ -267,13 +272,13 @@ theorem equiv_nim_grundyValue (G : PGame.{u}) [G.Impartial] : G ≈ nim (grundyV exact Equiv.trans (add_congr_left (equiv_nim_grundyValue _)) (hj ▸ Impartial.add_self _) termination_by G -theorem grundyValue_eq_iff_equiv_nim {G : PGame} [G.Impartial] {o : Ordinal} : - grundyValue G = o ↔ G ≈ nim o := +theorem grundyValue_eq_iff_equiv_nim {G : PGame} [G.Impartial] {o : Nimber} : + grundyValue G = o ↔ G ≈ nim (toOrdinal o) := ⟨by rintro rfl; exact equiv_nim_grundyValue G, by intro h; rw [← nim_equiv_iff_eq]; exact Equiv.trans (Equiv.symm (equiv_nim_grundyValue G)) h⟩ @[simp] -theorem nim_grundyValue (o : Ordinal.{u}) : grundyValue (nim o) = o := +theorem nim_grundyValue (o : Ordinal.{u}) : grundyValue (nim o) = ∗o := grundyValue_eq_iff_equiv_nim.2 PGame.equiv_rfl theorem grundyValue_eq_iff_equiv (G H : PGame) [G.Impartial] [H.Impartial] : @@ -284,7 +289,7 @@ theorem grundyValue_eq_iff_equiv (G H : PGame) [G.Impartial] [H.Impartial] : theorem grundyValue_zero : grundyValue 0 = 0 := grundyValue_eq_iff_equiv_nim.2 (Equiv.symm nim_zero_equiv) -theorem grundyValue_iff_equiv_zero (G : PGame) [G.Impartial] : grundyValue G = 0 ↔ (G ≈ 0) := by +theorem grundyValue_iff_equiv_zero (G : PGame) [G.Impartial] : grundyValue G = 0 ↔ G ≈ 0 := by rw [← grundyValue_eq_iff_equiv, grundyValue_zero] @[simp] @@ -313,68 +318,51 @@ theorem grundyValue_ne_moveRight {G : PGame} [G.Impartial] (i : G.RightMoves) : grundyValue (G.moveRight i) ≠ grundyValue G := by convert grundyValue_ne_moveLeft (toLeftMovesNeg i) using 1 <;> simp -theorem le_grundyValue_of_Iio_subset_moveRight {G : PGame} [G.Impartial] {o : Ordinal} +theorem le_grundyValue_of_Iio_subset_moveRight {G : PGame} [G.Impartial] {o : Nimber} (h : Set.Iio o ⊆ Set.range (grundyValue ∘ G.moveRight)) : o ≤ grundyValue G := by by_contra! ho obtain ⟨i, hi⟩ := h ho exact grundyValue_ne_moveRight i hi -theorem exists_grundyValue_moveRight_of_lt {G : PGame} [G.Impartial] {o : Ordinal} +theorem exists_grundyValue_moveRight_of_lt {G : PGame} [G.Impartial] {o : Nimber} (h : o < grundyValue G) : ∃ i, grundyValue (G.moveRight i) = o := by rw [← grundyValue_neg] at h obtain ⟨i, hi⟩ := exists_grundyValue_moveLeft_of_lt h use toLeftMovesNeg.symm i rwa [← grundyValue_neg, ← moveLeft_neg'] -theorem grundyValue_le_of_forall_moveRight {G : PGame} [G.Impartial] {o : Ordinal} +theorem grundyValue_le_of_forall_moveRight {G : PGame} [G.Impartial] {o : Nimber} (h : ∀ i, grundyValue (G.moveRight i) ≠ o) : G.grundyValue ≤ o := by contrapose! h exact exists_grundyValue_moveRight_of_lt h --- Todo: redefine `grundyValue` as a nimber, and prove `grundyValue (nim a + nim b) = a + b` for all --- nimbers. - -/-- The Grundy value of the sum of two nim games with natural numbers of piles equals their bitwise -xor. -/ -@[simp] -theorem grundyValue_nim_add_nim (n m : ℕ) : grundyValue (nim.{u} n + nim.{u} m) = n ^^^ m := by +/-- The Grundy value of the sum of two nim games equals their nimber addition. -/ +theorem grundyValue_nim_add_nim (x y : Ordinal) : grundyValue (nim x + nim y) = ∗x + ∗y := by apply (grundyValue_le_of_forall_moveLeft _).antisymm (le_grundyValue_of_Iio_subset_moveLeft _) - -- Since XOR is injective, no left moves of `nim n + nim m` will have `n ^^^ m` as a Grundy value. · intro i - apply leftMoves_add_cases i - all_goals - intro j - have hj := toLeftMovesNim_symm_lt j - obtain ⟨k, hk⟩ := lt_omega0.1 (hj.trans (nat_lt_omega0 _)) - rw [hk, Nat.cast_lt] at hj - have := hj.ne - have := hj -- The termination checker doesn't work without this. - · rwa [add_moveLeft_inl, moveLeft_nim', ne_eq, hk, grundyValue_nim_add_nim, Nat.cast_inj, - Nat.xor_left_inj] - · rwa [add_moveLeft_inr, moveLeft_nim', ne_eq, hk, grundyValue_nim_add_nim, Nat.cast_inj, - Nat.xor_right_inj] - -- For any `k < n ^^^ m`, either `nim (k ^^^ m) + nim m` or `nim n + nim (k ^^^ n)` is a left - -- option with Grundy value `k`. + apply leftMoves_add_cases i <;> intro j <;> have := (toLeftMovesNim_symm_lt j).ne + · simpa [grundyValue_nim_add_nim (toLeftMovesNim.symm j) y] + · simpa [grundyValue_nim_add_nim x (toLeftMovesNim.symm j)] · intro k hk - obtain ⟨k, rfl⟩ := Ordinal.lt_omega0.1 (hk.trans (Ordinal.nat_lt_omega0 _)) - rw [Set.mem_Iio, Nat.cast_lt] at hk - obtain hk | hk := Nat.lt_xor_cases hk <;> rw [← natCast_lt] at hk - · use toLeftMovesAdd (Sum.inl (toLeftMovesNim ⟨_, hk⟩)) - rw [Function.comp_apply, add_moveLeft_inl, moveLeft_nim', Equiv.symm_apply_apply, - grundyValue_nim_add_nim, Nat.xor_cancel_right] - · use toLeftMovesAdd (Sum.inr (toLeftMovesNim ⟨_, hk⟩)) - rw [Function.comp_apply, add_moveLeft_inr, moveLeft_nim', Equiv.symm_apply_apply, - grundyValue_nim_add_nim, Nat.xor_comm, Nat.xor_cancel_right] -termination_by (n, m) - -theorem nim_add_nim_equiv {n m : ℕ} : nim n + nim m ≈ nim (n ^^^ m) := by + obtain h | h := Nimber.lt_add_cases hk + · let a := toOrdinal (k + ∗y) + use toLeftMovesAdd (Sum.inl (toLeftMovesNim ⟨a, h⟩)) + simp [a, grundyValue_nim_add_nim a y] + · let a := toOrdinal (k + ∗x) + use toLeftMovesAdd (Sum.inr (toLeftMovesNim ⟨a, h⟩)) + simp [a, grundyValue_nim_add_nim x a, add_comm (∗x)] +termination_by (x, y) + +theorem nim_add_nim_equiv (x y : Ordinal) : + nim x + nim y ≈ nim (toOrdinal (∗x + ∗y)) := by rw [← grundyValue_eq_iff_equiv_nim, grundyValue_nim_add_nim] -theorem grundyValue_add (G H : PGame) [G.Impartial] [H.Impartial] {n m : ℕ} (hG : grundyValue G = n) - (hH : grundyValue H = m) : grundyValue (G + H) = n ^^^ m := by - rw [← nim_grundyValue (n ^^^ m), grundyValue_eq_iff_equiv] - refine Equiv.trans ?_ nim_add_nim_equiv - convert add_congr (equiv_nim_grundyValue G) (equiv_nim_grundyValue H) <;> simp only [hG, hH] +@[simp] +theorem grundyValue_add (G H : PGame) [G.Impartial] [H.Impartial] : + grundyValue (G + H) = grundyValue G + grundyValue H := by + rw [← (grundyValue G).toOrdinal_toNimber, ← (grundyValue H).toOrdinal_toNimber, + ← grundyValue_nim_add_nim, grundyValue_eq_iff_equiv] + exact add_congr (equiv_nim_grundyValue G) (equiv_nim_grundyValue H) end PGame diff --git a/Mathlib/SetTheory/Ordinal/Nimber.lean b/Mathlib/SetTheory/Ordinal/Nimber.lean index 8a3f05befdbaab..b38f2ccbca68ff 100644 --- a/Mathlib/SetTheory/Ordinal/Nimber.lean +++ b/Mathlib/SetTheory/Ordinal/Nimber.lean @@ -369,6 +369,10 @@ theorem add_trichotomy {a b c : Nimber} (h : a + b + c ≠ 0) : · rw [← hx'] at hx exact Or.inr <| Or.inr hx +theorem lt_add_cases {a b c : Nimber} (h : a < b + c) : a + c < b ∨ a + b < c := by + obtain ha | hb | hc := add_trichotomy <| add_assoc a b c ▸ add_ne_zero_iff.2 h.ne + exacts [(h.asymm ha).elim, Or.inl <| add_comm c a ▸ hb, Or.inr hc] + /-- Nimber addition of naturals corresponds to the bitwise XOR operation. -/ theorem add_nat (a b : ℕ) : ∗a + ∗b = ∗(a ^^^ b) := by apply le_antisymm From d990505b65cea8a25936e0e803ce41f66bd24922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Sun, 13 Oct 2024 23:54:02 +0000 Subject: [PATCH 081/425] chore: rename `Complex.ofReal'` to `Complex.ofReal` (#17650) That's already how it was called in lemma names. Rename the existing `Complex.ofReal` to `Complex.ofRealHom` --- Mathlib/Analysis/CStarAlgebra/Spectrum.lean | 2 +- Mathlib/Analysis/Complex/AbelLimit.lean | 8 +- Mathlib/Analysis/Complex/Basic.lean | 2 +- .../SpecialFunctions/Gamma/Basic.lean | 4 +- Mathlib/Data/Complex/Abs.lean | 6 +- Mathlib/Data/Complex/Basic.lean | 106 +++++++++--------- Mathlib/Data/Complex/BigOperators.lean | 6 +- Mathlib/Data/Complex/Module.lean | 2 +- Mathlib/Data/Complex/Order.lean | 14 +-- Mathlib/NumberTheory/LSeries/Dirichlet.lean | 2 +- .../NumberTheory/LSeries/HurwitzZetaEven.lean | 8 +- .../NumberTheory/LSeries/HurwitzZetaOdd.lean | 4 +- .../LSeries/HurwitzZetaValues.lean | 12 +- .../LSeries/MellinEqDirichlet.lean | 2 +- .../NumberField/Discriminant.lean | 6 +- Mathlib/Topology/Instances/Complex.lean | 12 +- 16 files changed, 97 insertions(+), 99 deletions(-) diff --git a/Mathlib/Analysis/CStarAlgebra/Spectrum.lean b/Mathlib/Analysis/CStarAlgebra/Spectrum.lean index 6d91e465acfeb4..65c73492f78900 100644 --- a/Mathlib/Analysis/CStarAlgebra/Spectrum.lean +++ b/Mathlib/Analysis/CStarAlgebra/Spectrum.lean @@ -178,7 +178,7 @@ lemma IsSelfAdjoint.isConnected_spectrum_compl {a : A} (ha : IsSelfAdjoint a) : case nonempty => have := Filter.NeBot.nonempty_of_mem inferInstance <| Filter.mem_map.mp <| Complex.isometry_ofReal.antilipschitz.tendsto_cobounded (spectrum.isBounded a |>.compl) - exact this.image Complex.ofReal' |>.mono <| by simp + exact this.image Complex.ofReal |>.mono <| by simp case' upper => apply Complex.isConnected_of_upperHalfPlane ?_ <| Set.inter_subset_right case' lower => apply Complex.isConnected_of_lowerHalfPlane ?_ <| Set.inter_subset_right all_goals diff --git a/Mathlib/Analysis/Complex/AbelLimit.lean b/Mathlib/Analysis/Complex/AbelLimit.lean index 167aa0434d8061..20c8a9420d6f31 100644 --- a/Mathlib/Analysis/Complex/AbelLimit.lean +++ b/Mathlib/Analysis/Complex/AbelLimit.lean @@ -55,9 +55,9 @@ theorem stolzSet_empty {M : ℝ} (hM : M ≤ 1) : stolzSet M = ∅ := by _ ≤ _ := norm_sub_norm_le _ _ theorem nhdsWithin_lt_le_nhdsWithin_stolzSet {M : ℝ} (hM : 1 < M) : - (𝓝[<] 1).map ofReal' ≤ 𝓝[stolzSet M] 1 := by + (𝓝[<] 1).map ofReal ≤ 𝓝[stolzSet M] 1 := by rw [← tendsto_id'] - refine tendsto_map' <| tendsto_nhdsWithin_of_tendsto_nhds_of_eventually_within ofReal' + refine tendsto_map' <| tendsto_nhdsWithin_of_tendsto_nhds_of_eventually_within ofReal (tendsto_nhdsWithin_of_tendsto_nhds <| ofRealCLM.continuous.tendsto' 1 1 rfl) ?_ simp only [eventually_iff, norm_eq_abs, abs_ofReal, abs_lt, mem_nhdsWithin] refine ⟨Set.Ioo 0 2, isOpen_Ioo, by norm_num, fun x hx ↦ ?_⟩ @@ -241,7 +241,7 @@ theorem tendsto_tsum_powerSeries_nhdsWithin_stolzCone theorem tendsto_tsum_powerSeries_nhdsWithin_lt (h : Tendsto (fun n ↦ ∑ i ∈ range n, f i) atTop (𝓝 l)) : - Tendsto (fun z ↦ ∑' n, f n * z ^ n) ((𝓝[<] 1).map ofReal') (𝓝 l) := + Tendsto (fun z ↦ ∑' n, f n * z ^ n) ((𝓝[<] 1).map ofReal) (𝓝 l) := (tendsto_tsum_powerSeries_nhdsWithin_stolzSet (M := 2) h).mono_left (nhdsWithin_lt_le_nhdsWithin_stolzSet one_lt_two) @@ -258,7 +258,7 @@ is continuous at 1 when approaching 1 from the left. -/ theorem tendsto_tsum_powerSeries_nhdsWithin_lt (h : Tendsto (fun n ↦ ∑ i ∈ range n, f i) atTop (𝓝 l)) : Tendsto (fun x ↦ ∑' n, f n * x ^ n) (𝓝[<] 1) (𝓝 l) := by - have m : (𝓝 l).map ofReal' ≤ 𝓝 ↑l := ofRealCLM.continuous.tendsto l + have m : (𝓝 l).map ofReal ≤ 𝓝 ↑l := ofRealCLM.continuous.tendsto l replace h := (tendsto_map.comp h).mono_right m rw [Function.comp_def] at h push_cast at h diff --git a/Mathlib/Analysis/Complex/Basic.lean b/Mathlib/Analysis/Complex/Basic.lean index b2b77580329f55..e4257988bc45bf 100644 --- a/Mathlib/Analysis/Complex/Basic.lean +++ b/Mathlib/Analysis/Complex/Basic.lean @@ -363,7 +363,7 @@ lemma _root_.Filter.Tendsto.ofReal {α : Type*} {l : Filter α} {f : α → ℝ} (continuous_ofReal.tendsto _).comp hf /-- The only continuous ring homomorphism from `ℝ` to `ℂ` is the identity. -/ -theorem ringHom_eq_ofReal_of_continuous {f : ℝ →+* ℂ} (h : Continuous f) : f = Complex.ofReal := by +theorem ringHom_eq_ofReal_of_continuous {f : ℝ →+* ℂ} (h : Continuous f) : f = ofRealHom := by convert congr_arg AlgHom.toRingHom <| Subsingleton.elim (AlgHom.mk' f <| map_real_smul f h) (Algebra.ofId ℝ ℂ) diff --git a/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean index ac24c2337c4907..685bc7386b0d04 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean @@ -123,7 +123,7 @@ theorem GammaIntegral_conj (s : ℂ) : GammaIntegral (conj s) = conj (GammaInteg theorem GammaIntegral_ofReal (s : ℝ) : GammaIntegral ↑s = ↑(∫ x : ℝ in Ioi 0, Real.exp (-x) * x ^ (s - 1)) := by - have : ∀ r : ℝ, Complex.ofReal' r = @RCLike.ofReal ℂ _ r := fun r => rfl + have : ∀ r : ℝ, Complex.ofReal r = @RCLike.ofReal ℂ _ r := fun r => rfl rw [GammaIntegral] conv_rhs => rw [this, ← _root_.integral_ofReal] refine setIntegral_congr_fun measurableSet_Ioi ?_ @@ -484,7 +484,7 @@ theorem Gamma_eq_integral {s : ℝ} (hs : 0 < s) : simp_rw [← Complex.ofReal_one, ← Complex.ofReal_sub] suffices ∫ x : ℝ in Ioi 0, ↑(exp (-x)) * (x : ℂ) ^ ((s - 1 : ℝ) : ℂ) = ∫ x : ℝ in Ioi 0, ((exp (-x) * x ^ (s - 1) : ℝ) : ℂ) by - have cc : ∀ r : ℝ, Complex.ofReal' r = @RCLike.ofReal ℂ _ r := fun r => rfl + have cc : ∀ r : ℝ, Complex.ofReal r = @RCLike.ofReal ℂ _ r := fun r => rfl conv_lhs => rw [this]; enter [1, 2, x]; rw [cc] rw [_root_.integral_ofReal, ← cc, Complex.ofReal_re] refine setIntegral_congr_fun measurableSet_Ioi fun x hx => ?_ diff --git a/Mathlib/Data/Complex/Abs.lean b/Mathlib/Data/Complex/Abs.lean index 8ca8f1fbe0ea60..a43a2daaf814f2 100644 --- a/Mathlib/Data/Complex/Abs.lean +++ b/Mathlib/Data/Complex/Abs.lean @@ -276,13 +276,13 @@ theorem lim_eq_lim_im_add_lim_re (f : CauSeq ℂ Complex.abs) : f ≈ _ := equiv_limAux f _ = CauSeq.const Complex.abs (↑(lim (cauSeqRe f)) + ↑(lim (cauSeqIm f)) * I) := CauSeq.ext fun _ => - Complex.ext (by simp [limAux, cauSeqRe, ofReal']) (by simp [limAux, cauSeqIm, ofReal']) + Complex.ext (by simp [limAux, cauSeqRe, ofReal]) (by simp [limAux, cauSeqIm, ofReal]) theorem lim_re (f : CauSeq ℂ Complex.abs) : lim (cauSeqRe f) = (lim f).re := by - rw [lim_eq_lim_im_add_lim_re]; simp [ofReal'] + rw [lim_eq_lim_im_add_lim_re]; simp [ofReal] theorem lim_im (f : CauSeq ℂ Complex.abs) : lim (cauSeqIm f) = (lim f).im := by - rw [lim_eq_lim_im_add_lim_re]; simp [ofReal'] + rw [lim_eq_lim_im_add_lim_re]; simp [ofReal] theorem isCauSeq_conj (f : CauSeq ℂ Complex.abs) : IsCauSeq Complex.abs fun n => conj (f n) := fun ε ε0 => diff --git a/Mathlib/Data/Complex/Basic.lean b/Mathlib/Data/Complex/Basic.lean index bb39cc9638ee70..57f5d7f916a1bb 100644 --- a/Mathlib/Data/Complex/Basic.lean +++ b/Mathlib/Data/Complex/Basic.lean @@ -73,13 +73,14 @@ theorem range_im : range im = univ := im_surjective.range_eq -- Porting note: refactored instance to allow `norm_cast` to work -/-- The natural inclusion of the real numbers into the complex numbers. -The name `Complex.ofReal` is reserved for the bundled homomorphism. -/ +/-- The natural inclusion of the real numbers into the complex numbers. -/ @[coe] -def ofReal' (r : ℝ) : ℂ := +def ofReal (r : ℝ) : ℂ := ⟨r, 0⟩ instance : Coe ℝ ℂ := - ⟨ofReal'⟩ + ⟨ofReal⟩ + +@[deprecated (since := "2024-10-12")] alias ofReal' := ofReal @[simp, norm_cast] theorem ofReal_re (r : ℝ) : Complex.re (r : ℂ) = r := @@ -177,7 +178,7 @@ theorem add_im (z w : ℂ) : (z + w).im = z.im + w.im := @[simp, norm_cast] theorem ofReal_add (r s : ℝ) : ((r + s : ℝ) : ℂ) = r + s := - Complex.ext_iff.2 <| by simp [ofReal'] + Complex.ext_iff.2 <| by simp [ofReal] -- replaced by `Complex.ofReal_ofNat` @@ -194,7 +195,7 @@ theorem neg_im (z : ℂ) : (-z).im = -z.im := @[simp, norm_cast] theorem ofReal_neg (r : ℝ) : ((-r : ℝ) : ℂ) = -r := - Complex.ext_iff.2 <| by simp [ofReal'] + Complex.ext_iff.2 <| by simp [ofReal] instance : Sub ℂ := ⟨fun z w => ⟨z.re - w.re, z.im - w.im⟩⟩ @@ -212,14 +213,14 @@ theorem mul_im (z w : ℂ) : (z * w).im = z.re * w.im + z.im * w.re := @[simp, norm_cast] theorem ofReal_mul (r s : ℝ) : ((r * s : ℝ) : ℂ) = r * s := - Complex.ext_iff.2 <| by simp [ofReal'] + Complex.ext_iff.2 <| by simp [ofReal] -theorem re_ofReal_mul (r : ℝ) (z : ℂ) : (r * z).re = r * z.re := by simp [ofReal'] +theorem re_ofReal_mul (r : ℝ) (z : ℂ) : (r * z).re = r * z.re := by simp [ofReal] -theorem im_ofReal_mul (r : ℝ) (z : ℂ) : (r * z).im = r * z.im := by simp [ofReal'] +theorem im_ofReal_mul (r : ℝ) (z : ℂ) : (r * z).im = r * z.im := by simp [ofReal] -lemma re_mul_ofReal (z : ℂ) (r : ℝ) : (z * r).re = z.re * r := by simp [ofReal'] -lemma im_mul_ofReal (z : ℂ) (r : ℝ) : (z * r).im = z.im * r := by simp [ofReal'] +lemma re_mul_ofReal (z : ℂ) (r : ℝ) : (z * r).re = z.re * r := by simp [ofReal] +lemma im_mul_ofReal (z : ℂ) (r : ℝ) : (z * r).im = z.im * r := by simp [ofReal] theorem ofReal_mul' (r : ℝ) (z : ℂ) : ↑r * z = ⟨r * z.re, r * z.im⟩ := ext (re_ofReal_mul _ _) (im_ofReal_mul _ _) @@ -249,11 +250,11 @@ theorem I_mul (z : ℂ) : I * z = ⟨-z.im, z.re⟩ := @[simp] lemma I_ne_zero : (I : ℂ) ≠ 0 := mt (congr_arg im) zero_ne_one.symm theorem mk_eq_add_mul_I (a b : ℝ) : Complex.mk a b = a + b * I := - Complex.ext_iff.2 <| by simp [ofReal'] + Complex.ext_iff.2 <| by simp [ofReal] @[simp] theorem re_add_im (z : ℂ) : (z.re : ℂ) + z.im * I = z := - Complex.ext_iff.2 <| by simp [ofReal'] + Complex.ext_iff.2 <| by simp [ofReal] theorem mul_I_re (z : ℂ) : (z * I).re = -z.im := by simp @@ -265,7 +266,7 @@ theorem I_mul_im (z : ℂ) : (I * z).im = z.re := by simp @[simp] theorem equivRealProd_symm_apply (p : ℝ × ℝ) : equivRealProd.symm p = p.1 + p.2 * I := by - ext <;> simp [Complex.equivRealProd, ofReal'] + ext <;> simp [Complex.equivRealProd, ofReal] /-- The natural `AddEquiv` from `ℂ` to `ℝ × ℝ`. -/ @[simps! (config := { simpRhs := true }) apply symm_apply_re symm_apply_im] @@ -414,16 +415,16 @@ end /-! ### Cast lemmas -/ -noncomputable instance instNNRatCast : NNRatCast ℂ where nnratCast q := ofReal' q -noncomputable instance instRatCast : RatCast ℂ where ratCast q := ofReal' q +noncomputable instance instNNRatCast : NNRatCast ℂ where nnratCast q := ofReal q +noncomputable instance instRatCast : RatCast ℂ where ratCast q := ofReal q -- See note [no_index around OfNat.ofNat] @[simp, norm_cast] lemma ofReal_ofNat (n : ℕ) [n.AtLeastTwo] : - ofReal' (no_index (OfNat.ofNat n)) = OfNat.ofNat n := rfl -@[simp, norm_cast] lemma ofReal_natCast (n : ℕ) : ofReal' n = n := rfl -@[simp, norm_cast] lemma ofReal_intCast (n : ℤ) : ofReal' n = n := rfl -@[simp, norm_cast] lemma ofReal_nnratCast (q : ℚ≥0) : ofReal' q = q := rfl -@[simp, norm_cast] lemma ofReal_ratCast (q : ℚ) : ofReal' q = q := rfl + ofReal (no_index (OfNat.ofNat n)) = OfNat.ofNat n := rfl +@[simp, norm_cast] lemma ofReal_natCast (n : ℕ) : ofReal n = n := rfl +@[simp, norm_cast] lemma ofReal_intCast (n : ℤ) : ofReal n = n := rfl +@[simp, norm_cast] lemma ofReal_nnratCast (q : ℚ≥0) : ofReal q = q := rfl +@[simp, norm_cast] lemma ofReal_ratCast (q : ℚ) : ofReal q = q := rfl @[deprecated (since := "2024-04-17")] alias ofReal_rat_cast := ofReal_ratCast @@ -505,7 +506,7 @@ theorem conj_eq_iff_real {z : ℂ} : conj z = z ↔ ∃ r : ℝ, z = r := rw [e, conj_ofReal]⟩ theorem conj_eq_iff_re {z : ℂ} : conj z = z ↔ (z.re : ℂ) = z := - conj_eq_iff_real.trans ⟨by rintro ⟨r, rfl⟩; simp [ofReal'], fun h => ⟨_, h.symm⟩⟩ + conj_eq_iff_real.trans ⟨by rintro ⟨r, rfl⟩; simp [ofReal], fun h => ⟨_, h.symm⟩⟩ theorem conj_eq_iff_im {z : ℂ} : conj z = z ↔ z.im = 0 := ⟨fun h => add_self_eq_zero.mp (neg_eq_iff_add_eq_zero.mp (congr_arg im h)), fun h => @@ -536,7 +537,7 @@ theorem normSq_apply (z : ℂ) : normSq z = z.re * z.re + z.im * z.im := @[simp] theorem normSq_ofReal (r : ℝ) : normSq r = r * r := by - simp [normSq, ofReal'] + simp [normSq, ofReal] @[simp] theorem normSq_natCast (n : ℕ) : normSq n = n * n := normSq_ofReal _ @@ -570,7 +571,7 @@ theorem normSq_add_mul_I (x y : ℝ) : normSq (x + y * I) = x ^ 2 + y ^ 2 := by rw [← mk_eq_add_mul_I, normSq_mk, sq, sq] theorem normSq_eq_conj_mul_self {z : ℂ} : (normSq z : ℂ) = conj z * z := by - ext <;> simp [normSq, mul_comm, ofReal'] + ext <;> simp [normSq, mul_comm, ofReal] -- @[simp] /- Porting note (#11119): `simp` attribute removed as linter reports this can be proved @@ -619,44 +620,43 @@ theorem im_sq_le_normSq (z : ℂ) : z.im * z.im ≤ normSq z := le_add_of_nonneg_left (mul_self_nonneg _) theorem mul_conj (z : ℂ) : z * conj z = normSq z := - Complex.ext_iff.2 <| by simp [normSq, mul_comm, sub_eq_neg_add, add_comm, ofReal'] + Complex.ext_iff.2 <| by simp [normSq, mul_comm, sub_eq_neg_add, add_comm, ofReal] theorem add_conj (z : ℂ) : z + conj z = (2 * z.re : ℝ) := - Complex.ext_iff.2 <| by simp [two_mul, ofReal'] + Complex.ext_iff.2 <| by simp [two_mul, ofReal] /-- The coercion `ℝ → ℂ` as a `RingHom`. -/ -def ofReal : ℝ →+* ℂ where +def ofRealHom : ℝ →+* ℂ where toFun x := (x : ℂ) map_one' := ofReal_one map_zero' := ofReal_zero map_mul' := ofReal_mul map_add' := ofReal_add -@[simp] -theorem ofReal_eq_coe (r : ℝ) : ofReal r = r := - rfl +@[simp] lemma ofRealHom_eq_coe (r : ℝ) : ofRealHom r = r := rfl variable {α : Type*} -@[simp] lemma ofReal_comp_add (f g : α → ℝ) : ofReal' ∘ (f + g) = ofReal' ∘ f + ofReal' ∘ g := - map_comp_add ofReal .. +@[simp] lemma ofReal_comp_add (f g : α → ℝ) : ofReal ∘ (f + g) = ofReal ∘ f + ofReal ∘ g := + map_comp_add ofRealHom .. -@[simp] lemma ofReal_comp_sub (f g : α → ℝ) : ofReal' ∘ (f - g) = ofReal' ∘ f - ofReal' ∘ g := - map_comp_sub ofReal .. +@[simp] lemma ofReal_comp_sub (f g : α → ℝ) : ofReal ∘ (f - g) = ofReal ∘ f - ofReal ∘ g := + map_comp_sub ofRealHom .. -@[simp] lemma ofReal_comp_neg (f : α → ℝ) : ofReal' ∘ (-f) = -(ofReal' ∘ f) := map_comp_neg ofReal _ +@[simp] lemma ofReal_comp_neg (f : α → ℝ) : ofReal ∘ (-f) = -(ofReal ∘ f) := + map_comp_neg ofRealHom _ -lemma ofReal_comp_nsmul (n : ℕ) (f : α → ℝ) : ofReal' ∘ (n • f) = n • (ofReal' ∘ f) := - map_comp_nsmul ofReal .. +lemma ofReal_comp_nsmul (n : ℕ) (f : α → ℝ) : ofReal ∘ (n • f) = n • (ofReal ∘ f) := + map_comp_nsmul ofRealHom .. -lemma ofReal_comp_zsmul (n : ℤ) (f : α → ℝ) : ofReal' ∘ (n • f) = n • (ofReal' ∘ f) := - map_comp_zsmul ofReal .. +lemma ofReal_comp_zsmul (n : ℤ) (f : α → ℝ) : ofReal ∘ (n • f) = n • (ofReal ∘ f) := + map_comp_zsmul ofRealHom .. -@[simp] lemma ofReal_comp_mul (f g : α → ℝ) : ofReal' ∘ (f * g) = ofReal' ∘ f * ofReal' ∘ g := - map_comp_mul ofReal .. +@[simp] lemma ofReal_comp_mul (f g : α → ℝ) : ofReal ∘ (f * g) = ofReal ∘ f * ofReal ∘ g := + map_comp_mul ofRealHom .. -@[simp] lemma ofReal_comp_pow (f : α → ℝ) (n : ℕ) : ofReal' ∘ (f ^ n) = (ofReal' ∘ f) ^ n := - map_comp_pow ofReal .. +@[simp] lemma ofReal_comp_pow (f : α → ℝ) (n : ℕ) : ofReal ∘ (f ^ n) = (ofReal ∘ f) ^ n := + map_comp_pow ofRealHom .. @[simp] theorem I_sq : I ^ 2 = -1 := by rw [sq, I_mul_I] @@ -674,14 +674,14 @@ theorem sub_im (z w : ℂ) : (z - w).im = z.im - w.im := @[simp, norm_cast] theorem ofReal_sub (r s : ℝ) : ((r - s : ℝ) : ℂ) = r - s := - Complex.ext_iff.2 <| by simp [ofReal'] + Complex.ext_iff.2 <| by simp [ofReal] @[simp, norm_cast] theorem ofReal_pow (r : ℝ) (n : ℕ) : ((r ^ n : ℝ) : ℂ) = (r : ℂ) ^ n := by induction n <;> simp [*, ofReal_mul, pow_succ] theorem sub_conj (z : ℂ) : z - conj z = (2 * z.im : ℝ) * I := - Complex.ext_iff.2 <| by simp [two_mul, sub_eq_add_neg, ofReal'] + Complex.ext_iff.2 <| by simp [two_mul, sub_eq_add_neg, ofReal] theorem normSq_sub (z w : ℂ) : normSq (z - w) = normSq z + normSq w - 2 * (z * conj w).re := by rw [sub_eq_add_neg, normSq_add] @@ -698,14 +698,14 @@ theorem inv_def (z : ℂ) : z⁻¹ = conj z * ((normSq z)⁻¹ : ℝ) := rfl @[simp] -theorem inv_re (z : ℂ) : z⁻¹.re = z.re / normSq z := by simp [inv_def, division_def, ofReal'] +theorem inv_re (z : ℂ) : z⁻¹.re = z.re / normSq z := by simp [inv_def, division_def, ofReal] @[simp] -theorem inv_im (z : ℂ) : z⁻¹.im = -z.im / normSq z := by simp [inv_def, division_def, ofReal'] +theorem inv_im (z : ℂ) : z⁻¹.im = -z.im / normSq z := by simp [inv_def, division_def, ofReal] @[simp, norm_cast] theorem ofReal_inv (r : ℝ) : ((r⁻¹ : ℝ) : ℂ) = (r : ℂ)⁻¹ := - Complex.ext_iff.2 <| by simp [ofReal'] + Complex.ext_iff.2 <| by simp [ofReal] protected theorem inv_zero : (0⁻¹ : ℂ) = 0 := by rw [← ofReal_zero, ← ofReal_inv, inv_zero] @@ -735,21 +735,19 @@ noncomputable instance instField : Field ℂ where qsmul_def n z := Complex.ext_iff.2 <| by simp [Rat.smul_def, smul_re, smul_im] @[simp, norm_cast] -lemma ofReal_nnqsmul (q : ℚ≥0) (r : ℝ) : ofReal' (q • r) = q • r := by simp [NNRat.smul_def] +lemma ofReal_nnqsmul (q : ℚ≥0) (r : ℝ) : ofReal (q • r) = q • r := by simp [NNRat.smul_def] @[simp, norm_cast] -lemma ofReal_qsmul (q : ℚ) (r : ℝ) : ofReal' (q • r) = q • r := by simp [Rat.smul_def] +lemma ofReal_qsmul (q : ℚ) (r : ℝ) : ofReal (q • r) = q • r := by simp [Rat.smul_def] theorem conj_inv (x : ℂ) : conj x⁻¹ = (conj x)⁻¹ := star_inv' _ @[simp, norm_cast] -theorem ofReal_div (r s : ℝ) : ((r / s : ℝ) : ℂ) = r / s := - map_div₀ ofReal r s +theorem ofReal_div (r s : ℝ) : ((r / s : ℝ) : ℂ) = r / s := map_div₀ ofRealHom r s @[simp, norm_cast] -theorem ofReal_zpow (r : ℝ) (n : ℤ) : ((r ^ n : ℝ) : ℂ) = (r : ℂ) ^ n := - map_zpow₀ ofReal r n +theorem ofReal_zpow (r : ℝ) (n : ℤ) : ((r ^ n : ℝ) : ℂ) = (r : ℂ) ^ n := map_zpow₀ ofRealHom r n @[simp] theorem div_I (z : ℂ) : z / I = -(z * I) := diff --git a/Mathlib/Data/Complex/BigOperators.lean b/Mathlib/Data/Complex/BigOperators.lean index df65eec1fe3108..02af83a94a767a 100644 --- a/Mathlib/Data/Complex/BigOperators.lean +++ b/Mathlib/Data/Complex/BigOperators.lean @@ -19,15 +19,15 @@ variable {α : Type*} (s : Finset α) @[simp, norm_cast] theorem ofReal_prod (f : α → ℝ) : ((∏ i ∈ s, f i : ℝ) : ℂ) = ∏ i ∈ s, (f i : ℂ) := - map_prod ofReal _ _ + map_prod ofRealHom _ _ @[simp, norm_cast] theorem ofReal_sum (f : α → ℝ) : ((∑ i ∈ s, f i : ℝ) : ℂ) = ∑ i ∈ s, (f i : ℂ) := - map_sum ofReal _ _ + map_sum ofRealHom _ _ @[simp, norm_cast] lemma ofReal_expect (f : α → ℝ) : (𝔼 i ∈ s, f i : ℝ) = 𝔼 i ∈ s, (f i : ℂ) := - map_expect ofReal .. + map_expect ofRealHom .. @[simp, norm_cast] lemma ofReal_balance [Fintype α] (f : α → ℝ) (a : α) : diff --git a/Mathlib/Data/Complex/Module.lean b/Mathlib/Data/Complex/Module.lean index e8fc5c5c392dc9..880e0c28ab5d89 100644 --- a/Mathlib/Data/Complex/Module.lean +++ b/Mathlib/Data/Complex/Module.lean @@ -93,7 +93,7 @@ instance (priority := 100) instModule [Semiring R] [Module R ℝ] : Module R ℂ -- priority manually adjusted in #11980 instance (priority := 95) instAlgebraOfReal [CommSemiring R] [Algebra R ℝ] : Algebra R ℂ := - { Complex.ofReal.comp (algebraMap R ℝ) with + { Complex.ofRealHom.comp (algebraMap R ℝ) with smul := (· • ·) smul_def' := fun r x => by ext <;> simp [smul_re, smul_im, Algebra.smul_def] commutes' := fun r ⟨xr, xi⟩ => by ext <;> simp [smul_re, smul_im, Algebra.commutes] } diff --git a/Mathlib/Data/Complex/Order.lean b/Mathlib/Data/Complex/Order.lean index a9bc019f2b0bfa..1b8327a6d9187d 100644 --- a/Mathlib/Data/Complex/Order.lean +++ b/Mathlib/Data/Complex/Order.lean @@ -64,10 +64,10 @@ theorem pos_iff {z : ℂ} : 0 < z ↔ 0 < z.re ∧ 0 = z.im := lt_def @[simp, norm_cast] -theorem real_le_real {x y : ℝ} : (x : ℂ) ≤ (y : ℂ) ↔ x ≤ y := by simp [le_def, ofReal'] +theorem real_le_real {x y : ℝ} : (x : ℂ) ≤ (y : ℂ) ↔ x ≤ y := by simp [le_def, ofReal] @[simp, norm_cast] -theorem real_lt_real {x y : ℝ} : (x : ℂ) < (y : ℂ) ↔ x < y := by simp [lt_def, ofReal'] +theorem real_lt_real {x y : ℝ} : (x : ℂ) < (y : ℂ) ↔ x < y := by simp [lt_def, ofReal] @[simp, norm_cast] theorem zero_le_real {x : ℝ} : (0 : ℂ) ≤ (x : ℂ) ↔ 0 ≤ x := @@ -106,9 +106,9 @@ lemma neg_re_eq_abs {z : ℂ} : -z.re = abs z ↔ z ≤ 0 := by @[simp] lemma re_eq_neg_abs {z : ℂ} : z.re = -abs z ↔ z ≤ 0 := by rw [← neg_eq_iff_eq_neg, neg_re_eq_abs] -lemma monotone_ofReal : Monotone ofReal' := by +lemma monotone_ofReal : Monotone ofReal := by intro x y hxy - simp only [ofReal_eq_coe, real_le_real, hxy] + simp only [ofRealHom_eq_coe, real_le_real, hxy] end Complex @@ -122,11 +122,11 @@ private 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 _] +@[positivity Complex.ofReal _, Complex.ofReal _] def evalComplexOfReal : PositivityExt where eval {u α} _ _ e := do -- TODO: Can we avoid duplicating the code? match u, α, e with - | 0, ~q(ℂ), ~q(Complex.ofReal' $a) => + | 0, ~q(ℂ), ~q(Complex.ofReal $a) => assumeInstancesCommute match ← core q(inferInstance) q(inferInstance) a with | .positive pa => return .positive q(ofReal_pos $pa) @@ -140,7 +140,7 @@ def evalComplexOfReal : PositivityExt where eval {u α} _ _ e := do | .nonnegative pa => return .nonnegative q(ofReal_nonneg $pa) | .nonzero pa => return .nonzero q(ofReal_ne_zero_of_ne_zero $pa) | _ => return .none - | _, _ => throwError "not Complex.ofReal'" + | _, _ => throwError "not Complex.ofReal" example (x : ℝ) (hx : 0 < x) : 0 < (x : ℂ) := by positivity example (x : ℝ) (hx : 0 ≤ x) : 0 ≤ (x : ℂ) := by positivity diff --git a/Mathlib/NumberTheory/LSeries/Dirichlet.lean b/Mathlib/NumberTheory/LSeries/Dirichlet.lean index 6e6fed2c20936c..f82517ccefe5d7 100644 --- a/Mathlib/NumberTheory/LSeries/Dirichlet.lean +++ b/Mathlib/NumberTheory/LSeries/Dirichlet.lean @@ -329,7 +329,7 @@ lemma convolution_vonMangoldt_zeta : ↗Λ ⍟ ↗ζ = ↗Complex.log := by ext n simpa only [zeta_apply, apply_ite, cast_zero, cast_one, LSeries.convolution_def, mul_zero, mul_one, mul_apply, natCoe_apply, ofReal_sum, ofReal_zero, log_apply, ofReal_log n.cast_nonneg] - using congr_arg (ofReal' <| · n) vonMangoldt_mul_zeta + using congr_arg (ofReal <| · n) vonMangoldt_mul_zeta lemma convolution_vonMangoldt_const_one : ↗Λ ⍟ 1 = ↗Complex.log := (convolution_one_eq_convolution_zeta _).trans convolution_vonMangoldt_zeta diff --git a/Mathlib/NumberTheory/LSeries/HurwitzZetaEven.lean b/Mathlib/NumberTheory/LSeries/HurwitzZetaEven.lean index ac307e2324e770..f7685d232a68b9 100644 --- a/Mathlib/NumberTheory/LSeries/HurwitzZetaEven.lean +++ b/Mathlib/NumberTheory/LSeries/HurwitzZetaEven.lean @@ -269,8 +269,8 @@ section FEPair /-- A `WeakFEPair` structure with `f = evenKernel a` and `g = cosKernel a`. -/ def hurwitzEvenFEPair (a : UnitAddCircle) : WeakFEPair ℂ where - f := ofReal' ∘ evenKernel a - g := ofReal' ∘ cosKernel a + f := ofReal ∘ evenKernel a + g := ofReal ∘ cosKernel a hf_int := (continuous_ofReal.comp_continuousOn (continuousOn_evenKernel a)).locallyIntegrableOn measurableSet_Ioi hg_int := (continuous_ofReal.comp_continuousOn (continuousOn_cosKernel a)).locallyIntegrableOn @@ -288,7 +288,7 @@ def hurwitzEvenFEPair (a : UnitAddCircle) : WeakFEPair ℂ where hg_top r := by obtain ⟨p, hp, hp'⟩ := isBigO_atTop_cosKernel_sub a rw [← isBigO_norm_left] at hp' ⊢ - have (x : ℝ) : ‖(ofReal' ∘ cosKernel a) x - 1‖ = ‖cosKernel a x - 1‖ := by + have (x : ℝ) : ‖(ofReal ∘ cosKernel a) x - 1‖ = ‖cosKernel a x - 1‖ := by rw [← norm_real, ofReal_sub, ofReal_one, Function.comp_apply] simp only [this] exact hp'.trans (isLittleO_exp_neg_mul_rpow_atTop hp _).isBigO @@ -555,7 +555,7 @@ lemma hasSum_int_completedHurwitzZetaEven (a : ℝ) {s : ℂ} (hs : 1 < re s) : · rw [mul_comm, mul_one_div] rw [show completedHurwitzZetaEven a s = mellin (fun t ↦ ((evenKernel (↑a) t : ℂ) - ↑(if (a : UnitAddCircle) = 0 then 1 else 0 : ℝ)) / 2) (s / 2) by - simp_rw [mellin_div_const, apply_ite ofReal', ofReal_one, ofReal_zero] + simp_rw [mellin_div_const, apply_ite ofReal, ofReal_one, ofReal_zero] refine congr_arg (· / 2) ((hurwitzEvenFEPair a).hasMellin (?_ : 1 / 2 < (s / 2).re)).2.symm rwa [div_ofNat_re, div_lt_div_right two_pos]] refine (hasSum_mellin_pi_mul_sq (zero_lt_one.trans hs) hF ?_).congr_fun fun n ↦ ?_ diff --git a/Mathlib/NumberTheory/LSeries/HurwitzZetaOdd.lean b/Mathlib/NumberTheory/LSeries/HurwitzZetaOdd.lean index cf70f0a830ee77..4869bf6967314b 100644 --- a/Mathlib/NumberTheory/LSeries/HurwitzZetaOdd.lean +++ b/Mathlib/NumberTheory/LSeries/HurwitzZetaOdd.lean @@ -302,8 +302,8 @@ section FEPair /-- A `StrongFEPair` structure with `f = oddKernel a` and `g = sinKernel a`. -/ @[simps] def hurwitzOddFEPair (a : UnitAddCircle) : StrongFEPair ℂ where - f := ofReal' ∘ oddKernel a - g := ofReal' ∘ sinKernel a + f := ofReal ∘ oddKernel a + g := ofReal ∘ sinKernel a hf_int := (continuous_ofReal.comp_continuousOn (continuousOn_oddKernel a)).locallyIntegrableOn measurableSet_Ioi hg_int := (continuous_ofReal.comp_continuousOn (continuousOn_sinKernel a)).locallyIntegrableOn diff --git a/Mathlib/NumberTheory/LSeries/HurwitzZetaValues.lean b/Mathlib/NumberTheory/LSeries/HurwitzZetaValues.lean index 7f86bf40031573..a4fa533e22e111 100644 --- a/Mathlib/NumberTheory/LSeries/HurwitzZetaValues.lean +++ b/Mathlib/NumberTheory/LSeries/HurwitzZetaValues.lean @@ -51,7 +51,7 @@ theorem cosZeta_two_mul_nat (hk : k ≠ 0) (hx : x ∈ Icc 0 1) : ((Polynomial.bernoulli (2 * k)).map (algebraMap ℚ ℂ)).eval (x : ℂ) := by rw [← (hasSum_nat_cosZeta x (?_ : 1 < re (2 * k))).tsum_eq] · refine Eq.trans ?_ <| - (congr_arg ofReal' (hasSum_one_div_nat_pow_mul_cos hk hx).tsum_eq).trans ?_ + (congr_arg ofReal (hasSum_one_div_nat_pow_mul_cos hk hx).tsum_eq).trans ?_ · rw [ofReal_tsum] refine tsum_congr fun n ↦ ?_ rw [mul_comm (1 / _), mul_one_div, ofReal_div, mul_assoc (2 * π), mul_comm x n, ← mul_assoc, @@ -60,8 +60,8 @@ theorem cosZeta_two_mul_nat (hk : k ≠ 0) (hx : x ∈ Icc 0 1) : ofReal_neg, ofReal_one] congr 1 have : (Polynomial.bernoulli (2 * k)).map (algebraMap ℚ ℂ) = _ := - (Polynomial.map_map (algebraMap ℚ ℝ) ofReal _).symm - rw [this, ← ofReal_eq_coe, ← ofReal_eq_coe] + (Polynomial.map_map (algebraMap ℚ ℝ) ofRealHom _).symm + rw [this, ← ofRealHom_eq_coe, ← ofRealHom_eq_coe] apply Polynomial.map_aeval_eq_aeval_map simp only [Algebra.id.map_eq_id, RingHomCompTriple.comp_eq] · rw [← Nat.cast_ofNat, ← Nat.cast_one, ← Nat.cast_mul, natCast_re, Nat.cast_lt] @@ -79,7 +79,7 @@ theorem sinZeta_two_mul_nat_add_one (hk : k ≠ 0) (hx : x ∈ Icc 0 1) : ((Polynomial.bernoulli (2 * k + 1)).map (algebraMap ℚ ℂ)).eval (x : ℂ) := by rw [← (hasSum_nat_sinZeta x (?_ : 1 < re (2 * k + 1))).tsum_eq] · refine Eq.trans ?_ <| - (congr_arg ofReal' (hasSum_one_div_nat_pow_mul_sin hk hx).tsum_eq).trans ?_ + (congr_arg ofReal (hasSum_one_div_nat_pow_mul_sin hk hx).tsum_eq).trans ?_ · rw [ofReal_tsum] refine tsum_congr fun n ↦ ?_ rw [mul_comm (1 / _), mul_one_div, ofReal_div, mul_assoc (2 * π), mul_comm x n, ← mul_assoc] @@ -90,8 +90,8 @@ theorem sinZeta_two_mul_nat_add_one (hk : k ≠ 0) (hx : x ∈ Icc 0 1) : ofReal_neg, ofReal_one] congr 1 have : (Polynomial.bernoulli (2 * k + 1)).map (algebraMap ℚ ℂ) = _ := - (Polynomial.map_map (algebraMap ℚ ℝ) ofReal _).symm - rw [this, ← ofReal_eq_coe, ← ofReal_eq_coe] + (Polynomial.map_map (algebraMap ℚ ℝ) ofRealHom _).symm + rw [this, ← ofRealHom_eq_coe, ← ofRealHom_eq_coe] apply Polynomial.map_aeval_eq_aeval_map simp only [Algebra.id.map_eq_id, RingHomCompTriple.comp_eq] · rw [← Nat.cast_ofNat, ← Nat.cast_one, ← Nat.cast_mul, ← Nat.cast_add_one, natCast_re, diff --git a/Mathlib/NumberTheory/LSeries/MellinEqDirichlet.lean b/Mathlib/NumberTheory/LSeries/MellinEqDirichlet.lean index 445256d8910b79..b7ea5c807bd4db 100644 --- a/Mathlib/NumberTheory/LSeries/MellinEqDirichlet.lean +++ b/Mathlib/NumberTheory/LSeries/MellinEqDirichlet.lean @@ -142,7 +142,7 @@ lemma hasSum_mellin_pi_mul_sq' {a : ι → ℂ} {r : ι → ℝ} {F : ℝ → · rcases eq_or_ne (r i) 0 with h | h · rw [h, abs_zero, ofReal_zero, zero_cpow hs₁, zero_cpow hs₃, div_zero, div_zero] · rw [cpow_add _ _ (ofReal_ne_zero.mpr <| abs_ne_zero.mpr h), cpow_one] - conv_rhs => enter [1]; rw [← sign_mul_abs (r i), ofReal_mul, ← ofReal_eq_coe, + conv_rhs => enter [1]; rw [← sign_mul_abs (r i), ofReal_mul, ← ofRealHom_eq_coe, SignType.map_cast] field_simp [h] ring_nf diff --git a/Mathlib/NumberTheory/NumberField/Discriminant.lean b/Mathlib/NumberTheory/NumberField/Discriminant.lean index 52a08d5551c4af..758d8a99b48ed0 100644 --- a/Mathlib/NumberTheory/NumberField/Discriminant.lean +++ b/Mathlib/NumberTheory/NumberField/Discriminant.lean @@ -78,7 +78,7 @@ theorem _root_.NumberField.mixedEmbedding.volume_fundamentalDomain_latticeBasis let M := (mixedEmbedding.stdBasis K).toMatrix ((latticeBasis K).reindex e.symm) let N := Algebra.embeddingsMatrixReindex ℚ ℂ (integralBasis K ∘ f.symm) RingHom.equivRatAlgHom - suffices M.map Complex.ofReal = (matrixToStdBasis K) * + suffices M.map ofRealHom = matrixToStdBasis K * (Matrix.reindex (indexEquiv K).symm (indexEquiv K).symm N).transpose by calc volume (fundamentalDomain (latticeBasis K)) _ = ‖((mixedEmbedding.stdBasis K).toMatrix ((latticeBasis K).reindex e.symm)).det‖₊ := by @@ -86,7 +86,7 @@ theorem _root_.NumberField.mixedEmbedding.volume_fundamentalDomain_latticeBasis ((latticeBasis K).reindex e.symm), volume_fundamentalDomain_stdBasis, mul_one] rfl _ = ‖(matrixToStdBasis K).det * N.det‖₊ := by - rw [← nnnorm_real, ← ofReal_eq_coe, RingHom.map_det, RingHom.mapMatrix_apply, this, + rw [← nnnorm_real, ← ofRealHom_eq_coe, RingHom.map_det, RingHom.mapMatrix_apply, this, det_mul, det_transpose, det_reindex_self] _ = (2 : ℝ≥0∞)⁻¹ ^ Fintype.card {w : InfinitePlace K // IsComplex w} * sqrt ‖N.det ^ 2‖₊ := by have : ‖Complex.I‖₊ = 1 := by rw [← norm_toNNReal, norm_eq_abs, abs_I, Real.toNNReal_one] @@ -99,7 +99,7 @@ theorem _root_.NumberField.mixedEmbedding.volume_fundamentalDomain_latticeBasis ext : 2 dsimp only [M] rw [Matrix.map_apply, Basis.toMatrix_apply, Basis.coe_reindex, Function.comp_apply, - Equiv.symm_symm, latticeBasis_apply, ← commMap_canonical_eq_mixed, Complex.ofReal_eq_coe, + Equiv.symm_symm, latticeBasis_apply, ← commMap_canonical_eq_mixed, Complex.ofRealHom_eq_coe, stdBasis_repr_eq_matrixToStdBasis_mul K _ (fun _ => rfl)] rfl diff --git a/Mathlib/Topology/Instances/Complex.lean b/Mathlib/Topology/Instances/Complex.lean index 717f60129dd838..f48381256f1154 100644 --- a/Mathlib/Topology/Instances/Complex.lean +++ b/Mathlib/Topology/Instances/Complex.lean @@ -23,15 +23,15 @@ open ComplexConjugate /-- The only closed subfields of `ℂ` are `ℝ` and `ℂ`. -/ theorem Complex.subfield_eq_of_closed {K : Subfield ℂ} (hc : IsClosed (K : Set ℂ)) : - K = ofReal.fieldRange ∨ K = ⊤ := by - suffices range (ofReal' : ℝ → ℂ) ⊆ K by + K = ofRealHom.fieldRange ∨ K = ⊤ := by + suffices range (ofReal : ℝ → ℂ) ⊆ K by rw [range_subset_iff, ← coe_algebraMap] at this have := (Subalgebra.isSimpleOrder_of_finrank finrank_real_complex).eq_bot_or_eq_top (Subfield.toIntermediateField K this).toSubalgebra simp_rw [← SetLike.coe_set_eq, IntermediateField.coe_toSubalgebra] at this ⊢ exact this - suffices range (ofReal' : ℝ → ℂ) ⊆ closure (Set.range ((ofReal' : ℝ → ℂ) ∘ ((↑) : ℚ → ℝ))) by + suffices range (ofReal : ℝ → ℂ) ⊆ closure (Set.range ((ofReal : ℝ → ℂ) ∘ ((↑) : ℚ → ℝ))) by refine subset_trans this ?_ rw [← IsClosed.closure_eq hc] apply closure_mono @@ -65,19 +65,19 @@ 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 ofReal.rangeRestrict) + let ψ₁ := RingHom.comp extψ (RingHom.comp j.symm.toRingHom ofRealHom.rangeRestrict) -- 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 : ℝ, ofReal.rangeRestrict r = j (ι x) + rsuffices ⟨r, hr⟩ : ∃ r : ℝ, ofRealHom.rangeRestrict r = j (ι x) · have := RingHom.congr_fun (ringHom_eq_ofReal_of_continuous hψ₁) r -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 erw [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 [← ofReal.coe_rangeRestrict, hr] + · rw [← ofRealHom.coe_rangeRestrict, hr] rfl obtain ⟨r, hr⟩ := SetLike.coe_mem (j (ι x)) exact ⟨r, Subtype.ext hr⟩ From f05050b115197e8ba830798a4daa47d562d159cd Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Mon, 14 Oct 2024 00:37:39 +0000 Subject: [PATCH 082/425] chore: bump ProofWidgets (#17710) This will resolve the current ``` warning: ././.lake/packages/proofwidgets/lakefile.lean:83:2: warning: `Lake.Package.afterReleaseAsync` has been deprecated, use `Lake.Package.afterBuildCacheAsync` instead ``` appearing in the output of `lake build`. --- lake-manifest.json | 8 ++++---- lakefile.lean | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index 4a49ec817f12a3..140811af6321f0 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -15,7 +15,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "2b2f6d7fbe9d917fc010e9054c1ce11774c9088b", + "rev": "fa3d73a2cf077f4b14c7840352ac7b08aeb6eb41", "name": "Qq", "manifestFile": "lake-manifest.json", "inputRev": "master", @@ -35,10 +35,10 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "eb08eee94098fe530ccd6d8751a86fe405473d4c", + "rev": "cd20dae87c48495f0220663014dff11671597fcf", "name": "proofwidgets", "manifestFile": "lake-manifest.json", - "inputRev": "v0.0.42", + "inputRev": "v0.0.43-pre", "inherited": false, "configFile": "lakefile.lean"}, {"url": "https://github.com/leanprover/lean4-cli", @@ -55,7 +55,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "7376ac07aa2b0492372c056b7a2c3163b3026d1e", + "rev": "9b4088ccf0f44ddd7b1132bb1348aef8cf481e12", "name": "importGraph", "manifestFile": "lake-manifest.json", "inputRev": "main", diff --git a/lakefile.lean b/lakefile.lean index 212047a97ac351..a4a09667f6c2b7 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -10,7 +10,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 "v0.0.42" +require "leanprover-community" / "proofwidgets" @ git "v0.0.43-pre" require "leanprover-community" / "importGraph" @ git "main" require "leanprover-community" / "LeanSearchClient" @ git "main" from git "https://github.com/leanprover-community/LeanSearchClient" @ "main" From 369e6fb7f19248b711058b501a33216271d8b21f Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Mon, 14 Oct 2024 01:03:17 +0000 Subject: [PATCH 083/425] chore: simplify lean4checker reporting (#17712) Previously, we were doing some mysterious `awk` parsing of the workflow result page, apparently in order to save clicking on link. This just links directly, and cuts out the unnecessarily `curl` + `awk` munging. Let's keep things simple? --- .github/workflows/lean4checker.yml | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/.github/workflows/lean4checker.yml b/.github/workflows/lean4checker.yml index 8976cc19badb69..49ad37ef600629 100644 --- a/.github/workflows/lean4checker.yml +++ b/.github/workflows/lean4checker.yml @@ -79,13 +79,6 @@ jobs: cd .. lake env lean4checker/.lake/build/bin/lean4checker - - id: ci_url - run: | - url=https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - curl -s "${url}" | - # extract the CI run number from the unique line that matches ` href=".../job/[job number]"` - awk -v url="${url}" -F'/' '/^ *href/ {gsub(/"/, "", $NF); printf("summary<> "$GITHUB_OUTPUT" - - name: Post success message on Zulip if: success() uses: zulip/github-actions-zulip/send-message@v1 @@ -97,7 +90,7 @@ jobs: type: 'stream' topic: 'lean4checker' content: | - ✅ lean4checker [succeeded](${{ steps.ci_url.outputs.summary }}) on ${{ github.sha }} + ✅ lean4checker [succeeded](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) on ${{ github.sha }} - name: Post failure message on Zulip if: failure() @@ -110,7 +103,7 @@ jobs: type: 'stream' topic: 'lean4checker failure' content: | - ❌ lean4checker [failed](${{ steps.ci_url.outputs.summary }}) on ${{ github.sha }} + ❌ lean4checker [failed](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) on ${{ github.sha }} continue-on-error: true - name: Post failure message on Zulip main topic @@ -124,5 +117,5 @@ jobs: type: 'stream' topic: 'lean4checker' content: | - ❌ lean4checker failed on ${{ github.sha }} + ❌ lean4checker [failed](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) on ${{ github.sha }} continue-on-error: true From cfdf6e790c2f52c3f68bdd0e162e0e69427f4e0d Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Mon, 14 Oct 2024 01:54:47 +0000 Subject: [PATCH 084/425] chore: use latest lean4checker (#17713) This updates to a version of lean4checker that by default only checks the current project, not upstream dependencies. This makes it possible for downstream projects to check themselves, without rechecking all of Mathlib. --- .github/workflows/lean4checker.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lean4checker.yml b/.github/workflows/lean4checker.yml index 49ad37ef600629..ab862ac1b44f4b 100644 --- a/.github/workflows/lean4checker.yml +++ b/.github/workflows/lean4checker.yml @@ -70,14 +70,19 @@ jobs: run: | git clone https://github.com/leanprover/lean4checker cd lean4checker - git checkout v4.13.0-rc3 + # This should be changed back to a version tag when + # anything subsequent to `v4.13.0-rc3` is released. + git checkout master # Now that the git hash is embedded in each olean, # we need to compile lean4checker on the same toolchain cp ../lean-toolchain . lake build ./test.sh cd .. - lake env lean4checker/.lake/build/bin/lean4checker + # After https://github.com/leanprover/lean4checker/pull/26 + # lean4checker by default only runs on the current project + # so we explicitly check Batteries as well here. + lake env lean4checker/.lake/build/bin/lean4checker Batteries Mathlib - name: Post success message on Zulip if: success() From 21742f934471116ce625b97eb63d62492ec7903d Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Mon, 14 Oct 2024 13:20:54 +1100 Subject: [PATCH 085/425] bump Qq --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 7345819129da2a..734282c7ab05fa 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -15,7 +15,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "6e87b74d74c99137adcfc6f7d47d77b65b1eb927", + "rev": "2b14204c09d6c01c42c157adf9cc95ffac85ed06", "name": "Qq", "manifestFile": "lake-manifest.json", "inputRev": "lean-pr-testing-5323", From 06079d2779d291a4b9e906e377f102c115338b68 Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Mon, 14 Oct 2024 02:36:11 +0000 Subject: [PATCH 086/425] Update lean-toolchain for testing https://github.com/leanprover/lean4/pull/5694 --- lake-manifest.json | 4 ++-- lakefile.lean | 2 +- lean-toolchain | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index 140811af6321f0..6dc97077d66899 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,10 +5,10 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "daf1ed91789811cf6bbb7bf2f4dad6b3bad8fbf4", + "rev": "5742b12a435f2a3074de2620bc839905a5b7ae6a", "name": "batteries", "manifestFile": "lake-manifest.json", - "inputRev": "main", + "inputRev": "lean-pr-testing-5694", "inherited": false, "configFile": "lakefile.lean"}, {"url": "https://github.com/leanprover-community/quote4", diff --git a/lakefile.lean b/lakefile.lean index a4a09667f6c2b7..aa903569e6195f 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -7,7 +7,7 @@ open Lake DSL ## Mathlib dependencies on upstream projects -/ -require "leanprover-community" / "batteries" @ git "main" +require "leanprover-community" / "batteries" @ git "lean-pr-testing-5694" require "leanprover-community" / "Qq" @ git "master" require "leanprover-community" / "aesop" @ git "master" require "leanprover-community" / "proofwidgets" @ git "v0.0.43-pre" diff --git a/lean-toolchain b/lean-toolchain index 30684366328531..d81a3e4cc26444 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-13 +leanprover/lean4-pr-releases:pr-release-5694 From da6abacefb686c5ddf6e404cc12f869085b0ea77 Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Mon, 14 Oct 2024 05:08:49 +0000 Subject: [PATCH 087/425] chore(*): add `@[gcongr]` to some n-ary monotonicity lemmas (#17704) --- Mathlib/Data/Finset/NAry.lean | 3 +++ Mathlib/Data/Set/NAry.lean | 3 +++ Mathlib/Order/Filter/NAry.lean | 3 +++ 3 files changed, 9 insertions(+) diff --git a/Mathlib/Data/Finset/NAry.lean b/Mathlib/Data/Finset/NAry.lean index 4db70840b348d5..97c9c4284cbd7d 100644 --- a/Mathlib/Data/Finset/NAry.lean +++ b/Mathlib/Data/Finset/NAry.lean @@ -64,13 +64,16 @@ theorem mem_image₂_of_mem (ha : a ∈ s) (hb : b ∈ t) : f a b ∈ image₂ f theorem mem_image₂_iff (hf : Injective2 f) : f a b ∈ image₂ f s t ↔ a ∈ s ∧ b ∈ t := by rw [← mem_coe, coe_image₂, mem_image2_iff hf, mem_coe, mem_coe] +@[gcongr] theorem image₂_subset (hs : s ⊆ s') (ht : t ⊆ t') : image₂ f s t ⊆ image₂ f s' t' := by rw [← coe_subset, coe_image₂, coe_image₂] exact image2_subset hs ht +@[gcongr] theorem image₂_subset_left (ht : t ⊆ t') : image₂ f s t ⊆ image₂ f s t' := image₂_subset Subset.rfl ht +@[gcongr] theorem image₂_subset_right (hs : s ⊆ s') : image₂ f s t ⊆ image₂ f s' t := image₂_subset hs Subset.rfl diff --git a/Mathlib/Data/Set/NAry.lean b/Mathlib/Data/Set/NAry.lean index 9f1f7eb9541232..cc3eaa655b1f2b 100644 --- a/Mathlib/Data/Set/NAry.lean +++ b/Mathlib/Data/Set/NAry.lean @@ -31,13 +31,16 @@ theorem mem_image2_iff (hf : Injective2 f) : f a b ∈ image2 f s t ↔ a ∈ s exact ⟨ha', hb'⟩, fun ⟨ha, hb⟩ => mem_image2_of_mem ha hb⟩ /-- image2 is monotone with respect to `⊆`. -/ +@[gcongr] theorem image2_subset (hs : s ⊆ s') (ht : t ⊆ t') : image2 f s t ⊆ image2 f s' t' := by rintro _ ⟨a, ha, b, hb, rfl⟩ exact mem_image2_of_mem (hs ha) (ht hb) +@[gcongr] theorem image2_subset_left (ht : t ⊆ t') : image2 f s t ⊆ image2 f s t' := image2_subset Subset.rfl ht +@[gcongr] theorem image2_subset_right (hs : s ⊆ s') : image2 f s t ⊆ image2 f s' t := image2_subset hs Subset.rfl diff --git a/Mathlib/Order/Filter/NAry.lean b/Mathlib/Order/Filter/NAry.lean index 747639ad50753a..933e6da7c66463 100644 --- a/Mathlib/Order/Filter/NAry.lean +++ b/Mathlib/Order/Filter/NAry.lean @@ -60,12 +60,15 @@ theorem map₂_mk_eq_prod (f : Filter α) (g : Filter β) : map₂ Prod.mk f g = -- lemma image2_mem_map₂_iff (hm : injective2 m) : image2 m s t ∈ map₂ m f g ↔ s ∈ f ∧ t ∈ g := -- ⟨by { rintro ⟨u, v, hu, hv, h⟩, rw image2_subset_image2_iff hm at h, -- exact ⟨mem_of_superset hu h.1, mem_of_superset hv h.2⟩ }, fun h ↦ image2_mem_map₂ h.1 h.2⟩ +@[gcongr] theorem map₂_mono (hf : f₁ ≤ f₂) (hg : g₁ ≤ g₂) : map₂ m f₁ g₁ ≤ map₂ m f₂ g₂ := fun _ ⟨s, hs, t, ht, hst⟩ => ⟨s, hf hs, t, hg ht, hst⟩ +@[gcongr] theorem map₂_mono_left (h : g₁ ≤ g₂) : map₂ m f g₁ ≤ map₂ m f g₂ := map₂_mono Subset.rfl h +@[gcongr] theorem map₂_mono_right (h : f₁ ≤ f₂) : map₂ m f₁ g ≤ map₂ m f₂ g := map₂_mono h Subset.rfl From 8ffb37e8cda9237c18dfa5e199e884e73b894127 Mon Sep 17 00:00:00 2001 From: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com> Date: Mon, 14 Oct 2024 06:05:07 +0000 Subject: [PATCH 088/425] chore: rename IsAlgClosure fields (#16392) to match the naming convention (rule 4). --- .../IsAlgClosed/AlgebraicClosure.lean | 2 +- Mathlib/FieldTheory/IsAlgClosed/Basic.lean | 31 ++++++++++--------- .../IsAlgClosed/Classification.lean | 4 +-- Mathlib/FieldTheory/IsSepClosed.lean | 4 +-- Mathlib/FieldTheory/PurelyInseparable.lean | 6 ++-- 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean b/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean index 787429c5e3827f..a00d2cba8705ef 100644 --- a/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean +++ b/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean @@ -404,7 +404,7 @@ instance : IsAlgClosure k (AlgebraicClosure k) := by exact ⟨inferInstance, (algEquivAlgebraicClosureAux k).symm.isAlgebraic⟩ instance isAlgebraic : Algebra.IsAlgebraic k (AlgebraicClosure k) := - IsAlgClosure.algebraic + IsAlgClosure.isAlgebraic instance [CharZero k] : CharZero (AlgebraicClosure k) := charZero_of_injective_algebraMap (RingHom.injective (algebraMap k (AlgebraicClosure k))) diff --git a/Mathlib/FieldTheory/IsAlgClosed/Basic.lean b/Mathlib/FieldTheory/IsAlgClosed/Basic.lean index f50d91d7f2c113..f8ad1b02ce4a16 100644 --- a/Mathlib/FieldTheory/IsAlgClosed/Basic.lean +++ b/Mathlib/FieldTheory/IsAlgClosed/Basic.lean @@ -202,10 +202,13 @@ lemma Polynomial.isCoprime_iff_aeval_ne_zero_of_isAlgClosed (K : Type v) [Field /-- Typeclass for an extension being an algebraic closure. -/ class IsAlgClosure (R : Type u) (K : Type v) [CommRing R] [Field K] [Algebra R K] [NoZeroSMulDivisors R K] : Prop where - alg_closed : IsAlgClosed K - algebraic : Algebra.IsAlgebraic R K + isAlgClosed : IsAlgClosed K + isAlgebraic : Algebra.IsAlgebraic R K -attribute [instance] IsAlgClosure.algebraic +@[deprecated (since := "2024-08-31")] alias IsAlgClosure.alg_closed := IsAlgClosure.isAlgClosed +@[deprecated (since := "2024-08-31")] alias IsAlgClosure.algebraic := IsAlgClosure.isAlgebraic + +attribute [instance] IsAlgClosure.isAlgebraic theorem isAlgClosure_iff (K : Type v) [Field K] [Algebra k K] : IsAlgClosure k K ↔ IsAlgClosed K ∧ Algebra.IsAlgebraic k K := @@ -213,8 +216,8 @@ theorem isAlgClosure_iff (K : Type v) [Field K] [Algebra k K] : instance (priority := 100) IsAlgClosure.normal (R K : Type*) [Field R] [Field K] [Algebra R K] [IsAlgClosure R K] : Normal R K where - toIsAlgebraic := IsAlgClosure.algebraic - splits' _ := @IsAlgClosed.splits_codomain _ _ _ (IsAlgClosure.alg_closed R) _ _ _ + toIsAlgebraic := IsAlgClosure.isAlgebraic + splits' _ := @IsAlgClosed.splits_codomain _ _ _ (IsAlgClosure.isAlgClosed R) _ _ _ instance (priority := 100) IsAlgClosure.separable (R K : Type*) [Field R] [Field K] [Algebra R K] [IsAlgClosure R K] [CharZero R] : Algebra.IsSeparable R K := @@ -298,9 +301,9 @@ end IsAlgClosed namespace IsAlgClosure -- Porting note: errors with --- > cannot find synthesization order for instance alg_closed with type +-- > cannot find synthesization order for instance isAlgClosed with type -- > all remaining arguments have metavariables --- attribute [local instance] IsAlgClosure.alg_closed +-- attribute [local instance] IsAlgClosure.isAlgClosed section @@ -311,9 +314,9 @@ variable [Algebra R L] [NoZeroSMulDivisors R L] [IsAlgClosure R L] /-- A (random) isomorphism between two algebraic closures of `R`. -/ noncomputable def equiv : L ≃ₐ[R] M := -- Porting note (#10754): added to replace local instance above - haveI : IsAlgClosed L := IsAlgClosure.alg_closed R - haveI : IsAlgClosed M := IsAlgClosure.alg_closed R - AlgEquiv.ofBijective _ (IsAlgClosure.algebraic.algHom_bijective₂ + haveI : IsAlgClosed L := IsAlgClosure.isAlgClosed R + haveI : IsAlgClosed M := IsAlgClosure.isAlgClosed R + AlgEquiv.ofBijective _ (IsAlgClosure.isAlgebraic.algHom_bijective₂ (IsAlgClosed.lift : L →ₐ[R] M) (IsAlgClosed.lift : M →ₐ[R] L)).1 @@ -332,7 +335,7 @@ variable [Algebra K J] [Algebra J L] [IsAlgClosure J L] [Algebra K L] [IsScalarT /-- If `J` is an algebraic extension of `K` and `L` is an algebraic closure of `J`, then it is also an algebraic closure of `K`. -/ theorem ofAlgebraic [hKJ : Algebra.IsAlgebraic K J] : IsAlgClosure K L := - ⟨IsAlgClosure.alg_closed J, hKJ.trans⟩ + ⟨IsAlgClosure.isAlgClosed J, hKJ.trans⟩ /-- A (random) isomorphism between an algebraic closure of `R` and an algebraic closure of an algebraic extension of `R` -/ @@ -343,8 +346,8 @@ noncomputable def equivOfAlgebraic' [Nontrivial S] [NoZeroSMulDivisors R S] exact (Function.Injective.comp (NoZeroSMulDivisors.algebraMap_injective S L) (NoZeroSMulDivisors.algebraMap_injective R S) : _) letI : IsAlgClosure R L := - { alg_closed := IsAlgClosure.alg_closed S - algebraic := ‹_› } + { isAlgClosed := IsAlgClosure.isAlgClosed S + isAlgebraic := ‹_› } exact IsAlgClosure.equiv _ _ _ /-- A (random) isomorphism between an algebraic closure of `K` and an algebraic closure @@ -371,7 +374,7 @@ noncomputable def equivOfEquivAux (hSR : S ≃+* R) : haveI : IsScalarTower S R L := IsScalarTower.of_algebraMap_eq (by simp [RingHom.algebraMap_toAlgebra]) haveI : NoZeroSMulDivisors R S := NoZeroSMulDivisors.of_algebraMap_injective hSR.symm.injective - have : Algebra.IsAlgebraic R L := (IsAlgClosure.algebraic.tower_top_of_injective + have : Algebra.IsAlgebraic R L := (IsAlgClosure.isAlgebraic.tower_top_of_injective (show Function.Injective (algebraMap S R) from hSR.injective)) refine ⟨equivOfAlgebraic' R S L M, ?_⟩ diff --git a/Mathlib/FieldTheory/IsAlgClosed/Classification.lean b/Mathlib/FieldTheory/IsAlgClosed/Classification.lean index e0fb0cd9df5942..f617fc7a73aec1 100644 --- a/Mathlib/FieldTheory/IsAlgClosed/Classification.lean +++ b/Mathlib/FieldTheory/IsAlgClosed/Classification.lean @@ -92,8 +92,8 @@ variable (hv : AlgebraicIndependent R v) theorem isAlgClosure_of_transcendence_basis [IsAlgClosed K] (hv : IsTranscendenceBasis R v) : IsAlgClosure (Algebra.adjoin R (Set.range v)) K := letI := RingHom.domain_nontrivial (algebraMap R K) - { alg_closed := by infer_instance - algebraic := hv.isAlgebraic } + { isAlgClosed := by infer_instance + isAlgebraic := hv.isAlgebraic } variable (hw : AlgebraicIndependent R w) diff --git a/Mathlib/FieldTheory/IsSepClosed.lean b/Mathlib/FieldTheory/IsSepClosed.lean index 1a11e8d38dff72..8e15662dae680e 100644 --- a/Mathlib/FieldTheory/IsSepClosed.lean +++ b/Mathlib/FieldTheory/IsSepClosed.lean @@ -214,8 +214,8 @@ instance (priority := 100) IsSepClosure.isAlgClosure_of_perfectField then it is also a separable closure of `k`. -/ instance (priority := 100) IsSepClosure.of_isAlgClosure_of_perfectField [Algebra k K] [IsAlgClosure k K] [PerfectField k] : IsSepClosure k K := - ⟨haveI := IsAlgClosure.alg_closed (R := k) (K := K); inferInstance, - (IsAlgClosure.algebraic (R := k) (K := K)).isSeparable_of_perfectField⟩ + ⟨haveI := IsAlgClosure.isAlgClosed (R := k) (K := K); inferInstance, + (IsAlgClosure.isAlgebraic (R := k) (K := K)).isSeparable_of_perfectField⟩ variable {k} {K} diff --git a/Mathlib/FieldTheory/PurelyInseparable.lean b/Mathlib/FieldTheory/PurelyInseparable.lean index 93c3226de53d77..2a1a024969a2d5 100644 --- a/Mathlib/FieldTheory/PurelyInseparable.lean +++ b/Mathlib/FieldTheory/PurelyInseparable.lean @@ -811,8 +811,8 @@ end purely inseparable. -/ theorem isSepClosed_iff_isPurelyInseparable_algebraicClosure [IsAlgClosure F E] : IsSepClosed F ↔ IsPurelyInseparable F E := - ⟨fun _ ↦ IsAlgClosure.algebraic.isPurelyInseparable_of_isSepClosed, fun H ↦ by - haveI := IsAlgClosure.alg_closed F (K := E) + ⟨fun _ ↦ IsAlgClosure.isAlgebraic.isPurelyInseparable_of_isSepClosed, fun H ↦ by + haveI := IsAlgClosure.isAlgClosed F (K := E) rwa [← separableClosure.eq_bot_iff, IsSepClosed.separableClosure_eq_bot_iff] at H⟩ variable {F E} in @@ -845,7 +845,7 @@ theorem perfectField_of_isSeparable_of_perfectField_top [Algebra.IsSeparable F E separable. -/ theorem perfectField_iff_isSeparable_algebraicClosure [IsAlgClosure F E] : PerfectField F ↔ Algebra.IsSeparable F E := - ⟨fun _ ↦ IsSepClosure.separable, fun _ ↦ haveI : IsAlgClosed E := IsAlgClosure.alg_closed F + ⟨fun _ ↦ IsSepClosure.separable, fun _ ↦ haveI : IsAlgClosed E := IsAlgClosure.isAlgClosed F perfectField_of_isSeparable_of_perfectField_top F E⟩ namespace Field From 5d2ccbb3e5b5df402d3b88f4c9aa0cd2ac986130 Mon Sep 17 00:00:00 2001 From: grunweg Date: Mon, 14 Oct 2024 06:05:08 +0000 Subject: [PATCH 089/425] =?UTF-8?q?chore:=20weaken=20typeclass=20assumptio?= =?UTF-8?q?ns=20`MetricSpace`=20=E2=86=92=20`PseudoMetricSpace`=20(#17520)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Discovered through the linter in #17519 (but in fact not related to it). Co-authored-by: Eric Wieser Co-authored-by: Michael Rothgang --- Mathlib/MeasureTheory/Covering/DensityTheorem.lean | 2 +- Mathlib/MeasureTheory/Covering/Differentiation.lean | 3 ++- Mathlib/MeasureTheory/Covering/LiminfLimsup.lean | 3 ++- Mathlib/MeasureTheory/Covering/Vitali.lean | 8 +++++--- Mathlib/MeasureTheory/Covering/VitaliFamily.lean | 2 +- Mathlib/MeasureTheory/Measure/Doubling.lean | 4 ++-- 6 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Mathlib/MeasureTheory/Covering/DensityTheorem.lean b/Mathlib/MeasureTheory/Covering/DensityTheorem.lean index 62c58768b78a65..146d0ba6eff075 100644 --- a/Mathlib/MeasureTheory/Covering/DensityTheorem.lean +++ b/Mathlib/MeasureTheory/Covering/DensityTheorem.lean @@ -35,7 +35,7 @@ open scoped NNReal Topology namespace IsUnifLocDoublingMeasure -variable {α : Type*} [MetricSpace α] [MeasurableSpace α] (μ : Measure α) +variable {α : Type*} [PseudoMetricSpace α] [MeasurableSpace α] (μ : Measure α) [IsUnifLocDoublingMeasure μ] section diff --git a/Mathlib/MeasureTheory/Covering/Differentiation.lean b/Mathlib/MeasureTheory/Covering/Differentiation.lean index 803d605ca1b7fd..f2de314db2a9e5 100644 --- a/Mathlib/MeasureTheory/Covering/Differentiation.lean +++ b/Mathlib/MeasureTheory/Covering/Differentiation.lean @@ -78,7 +78,8 @@ open MeasureTheory Metric Set Filter TopologicalSpace MeasureTheory.Measure open scoped Filter ENNReal MeasureTheory NNReal Topology -variable {α : Type*} [MetricSpace α] {m0 : MeasurableSpace α} {μ : Measure α} (v : VitaliFamily μ) +variable {α : Type*} [PseudoMetricSpace α] {m0 : MeasurableSpace α} {μ : Measure α} + (v : VitaliFamily μ) {E : Type*} [NormedAddCommGroup E] namespace VitaliFamily diff --git a/Mathlib/MeasureTheory/Covering/LiminfLimsup.lean b/Mathlib/MeasureTheory/Covering/LiminfLimsup.lean index 539f24411b7c9e..564f7b35210b90 100644 --- a/Mathlib/MeasureTheory/Covering/LiminfLimsup.lean +++ b/Mathlib/MeasureTheory/Covering/LiminfLimsup.lean @@ -28,7 +28,8 @@ open Set Filter Metric MeasureTheory TopologicalSpace open scoped NNReal ENNReal Topology -variable {α : Type*} [MetricSpace α] [SecondCountableTopology α] [MeasurableSpace α] [BorelSpace α] +variable {α : Type*} +variable [PseudoMetricSpace α] [SecondCountableTopology α] [MeasurableSpace α] [BorelSpace α] variable (μ : Measure α) [IsLocallyFiniteMeasure μ] [IsUnifLocDoublingMeasure μ] /-- This is really an auxiliary result en route to `blimsup_cthickening_ae_le_of_eventually_mul_le` diff --git a/Mathlib/MeasureTheory/Covering/Vitali.lean b/Mathlib/MeasureTheory/Covering/Vitali.lean index 364031a842a496..fb944ea1501163 100644 --- a/Mathlib/MeasureTheory/Covering/Vitali.lean +++ b/Mathlib/MeasureTheory/Covering/Vitali.lean @@ -155,7 +155,8 @@ theorem exists_disjoint_subfamily_covering_enlargment (B : ι → Set α) (t : S /-- Vitali covering theorem, closed balls version: given a family `t` of closed balls, one can extract a disjoint subfamily `u ⊆ t` so that all balls in `t` are covered by the τ-times dilations of balls in `u`, for some `τ > 3`. -/ -theorem exists_disjoint_subfamily_covering_enlargment_closedBall [MetricSpace α] (t : Set ι) +theorem exists_disjoint_subfamily_covering_enlargment_closedBall + [PseudoMetricSpace α] (t : Set ι) (x : ι → α) (r : ι → ℝ) (R : ℝ) (hr : ∀ a ∈ t, r a ≤ R) (τ : ℝ) (hτ : 3 < τ) : ∃ u ⊆ t, (u.PairwiseDisjoint fun a => closedBall (x a) (r a)) ∧ @@ -200,7 +201,8 @@ Then one can extract from `t` a disjoint subfamily that covers almost all `s`. For more flexibility, we give a statement with a parameterized family of sets. -/ -theorem exists_disjoint_covering_ae [MetricSpace α] [MeasurableSpace α] [OpensMeasurableSpace α] +theorem exists_disjoint_covering_ae + [PseudoMetricSpace α] [MeasurableSpace α] [OpensMeasurableSpace α] [SecondCountableTopology α] (μ : Measure α) [IsLocallyFiniteMeasure μ] (s : Set α) (t : Set ι) (C : ℝ≥0) (r : ι → ℝ) (c : ι → α) (B : ι → Set α) (hB : ∀ a ∈ t, B a ⊆ closedBall (c a) (r a)) (μB : ∀ a ∈ t, μ (closedBall (c a) (3 * r a)) ≤ C * μ (B a)) @@ -390,7 +392,7 @@ theorem exists_disjoint_covering_ae [MetricSpace α] [MeasurableSpace α] [Opens doubling. Then the set of closed sets `a` with nonempty interior contained in `closedBall x r` and covering a fixed proportion `1/C` of the ball `closedBall x (3 * r)` forms a Vitali family. This is essentially a restatement of the measurable Vitali theorem. -/ -protected def vitaliFamily [MetricSpace α] [MeasurableSpace α] [OpensMeasurableSpace α] +protected def vitaliFamily [PseudoMetricSpace α] [MeasurableSpace α] [OpensMeasurableSpace α] [SecondCountableTopology α] (μ : Measure α) [IsLocallyFiniteMeasure μ] (C : ℝ≥0) (h : ∀ x, ∃ᶠ r in 𝓝[>] 0, μ (closedBall x (3 * r)) ≤ C * μ (closedBall x r)) : VitaliFamily μ where diff --git a/Mathlib/MeasureTheory/Covering/VitaliFamily.lean b/Mathlib/MeasureTheory/Covering/VitaliFamily.lean index a584639b9f6e92..ec5f09391c9ae4 100644 --- a/Mathlib/MeasureTheory/Covering/VitaliFamily.lean +++ b/Mathlib/MeasureTheory/Covering/VitaliFamily.lean @@ -49,7 +49,7 @@ Vitali relations there) open MeasureTheory Metric Set Filter TopologicalSpace MeasureTheory.Measure open scoped Topology -variable {X : Type*} [MetricSpace X] +variable {X : Type*} [PseudoMetricSpace X] /-- On a metric space `X` with a measure `μ`, consider for each `x : X` a family of measurable sets with nonempty interiors, called `setsAt x`. This family is a Vitali family if it satisfies the diff --git a/Mathlib/MeasureTheory/Measure/Doubling.lean b/Mathlib/MeasureTheory/Measure/Doubling.lean index 0aabc6cf60a991..d8195c77470d65 100644 --- a/Mathlib/MeasureTheory/Measure/Doubling.lean +++ b/Mathlib/MeasureTheory/Measure/Doubling.lean @@ -36,14 +36,14 @@ example we want hyperbolic space to carry the instance `IsUnifLocDoublingMeasure volumes grow exponentially in hyperbolic space. To be really explicit, consider the hyperbolic plane of curvature -1, the area of a disc of radius `ε` is `A(ε) = 2π(cosh(ε) - 1)` so `A(2ε)/A(ε) ~ exp(ε)`. -/ -class IsUnifLocDoublingMeasure {α : Type*} [MetricSpace α] [MeasurableSpace α] +class IsUnifLocDoublingMeasure {α : Type*} [PseudoMetricSpace α] [MeasurableSpace α] (μ : Measure α) : Prop where exists_measure_closedBall_le_mul'' : ∃ C : ℝ≥0, ∀ᶠ ε in 𝓝[>] 0, ∀ x, μ (closedBall x (2 * ε)) ≤ C * μ (closedBall x ε) namespace IsUnifLocDoublingMeasure -variable {α : Type*} [MetricSpace α] [MeasurableSpace α] (μ : Measure α) +variable {α : Type*} [PseudoMetricSpace α] [MeasurableSpace α] (μ : Measure α) [IsUnifLocDoublingMeasure μ] -- Porting note: added for missing infer kinds From 81429386f17c2ba789c13a64ae10df4883ba1932 Mon Sep 17 00:00:00 2001 From: Bulhwi Cha Date: Mon, 14 Oct 2024 07:22:36 +0000 Subject: [PATCH 090/425] refactor: move theorem about lists to batteries (#12540) `List.modifyHead_modifyHead` is from `Mathlib.Data.List.Basic`. I need it to prove `String.splitOn_of_valid`. See https://github.com/leanprover-community/batteries/pull/743. Corresponding Batteries PR: https://github.com/leanprover-community/batteries/pull/756 Co-authored-by: Kim Morrison --- Mathlib/Data/List/Basic.lean | 7 ------- Mathlib/Data/List/Perm.lean | 6 ------ lake-manifest.json | 2 +- 3 files changed, 1 insertion(+), 14 deletions(-) diff --git a/Mathlib/Data/List/Basic.lean b/Mathlib/Data/List/Basic.lean index 267f3bbefd34ef..daea69185dee8a 100644 --- a/Mathlib/Data/List/Basic.lean +++ b/Mathlib/Data/List/Basic.lean @@ -287,10 +287,6 @@ theorem map_reverseAux (f : α → β) (l₁ l₂ : List α) : map f (reverseAux l₁ l₂) = reverseAux (map f l₁) (map f l₂) := by simp only [reverseAux_eq, map_append, map_reverse] -/-! ### empty -/ - -@[deprecated (since := "2024-08-15")] alias isEmpty_iff_eq_nil := isEmpty_iff - /-! ### getLast -/ attribute [simp] getLast_cons @@ -509,9 +505,6 @@ theorem get_cons {l : List α} {a : α} {n} (hl) : l.get ⟨n - 1, by contrapose! hl; rw [length_cons]; omega⟩ := getElem_cons hl -theorem modifyHead_modifyHead (l : List α) (f g : α → α) : - (l.modifyHead f).modifyHead g = l.modifyHead (g ∘ f) := by cases l <;> simp - /-! ### Induction from the right -/ /-- Induction principle from the right for lists: if a property holds for the empty list, and diff --git a/Mathlib/Data/List/Perm.lean b/Mathlib/Data/List/Perm.lean index 52ea464bb68046..6c00caa35fe6e0 100644 --- a/Mathlib/Data/List/Perm.lean +++ b/Mathlib/Data/List/Perm.lean @@ -131,12 +131,6 @@ lemma subperm_iff : l₁ <+~ l₂ ↔ ∃ l, l ~ l₂ ∧ l₁ <+ l := by · rintro (rfl | rfl) exacts [nil_subperm, Subperm.refl _] -attribute [simp] nil_subperm - -@[simp] -theorem subperm_nil : List.Subperm l [] ↔ l = [] := - ⟨fun h ↦ length_eq_zero.1 <| Nat.le_zero.1 h.length_le, by rintro rfl; rfl⟩ - lemma subperm_cons_self : l <+~ a :: l := ⟨l, Perm.refl _, sublist_cons_self _ _⟩ lemma count_eq_count_filter_add [DecidableEq α] (P : α → Prop) [DecidablePred P] diff --git a/lake-manifest.json b/lake-manifest.json index 140811af6321f0..0fb978e09f267a 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "daf1ed91789811cf6bbb7bf2f4dad6b3bad8fbf4", + "rev": "9efd9c267ad7a71c5e3a83e8fbbd446fe61ef119", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 7fe7e109014be7b69a513af14c44df3d3ab680c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Mon, 14 Oct 2024 07:22:37 +0000 Subject: [PATCH 091/425] chore(Polish): fix instance priority (#17696) These instances should have lower priority as they always apply. --- .../MeasureTheory/Constructions/Polish/Basic.lean | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean index 052b874d84c6a9..721c0f2411c57a 100644 --- a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean @@ -106,21 +106,26 @@ section variable [MeasurableSpace α] -instance standardBorel_of_polish [τ : TopologicalSpace α] +-- See note [lower instance priority] +instance (priority := 100) standardBorel_of_polish [τ : TopologicalSpace α] [BorelSpace α] [PolishSpace α] : StandardBorelSpace α := by exists τ -instance standardBorelSpace_of_discreteMeasurableSpace [DiscreteMeasurableSpace α] [Countable α] : - StandardBorelSpace α := +-- See note [lower instance priority] +instance (priority := 100) standardBorelSpace_of_discreteMeasurableSpace [DiscreteMeasurableSpace α] + [Countable α] : StandardBorelSpace α := let _ : TopologicalSpace α := ⊥ have : DiscreteTopology α := ⟨rfl⟩ inferInstance -instance countablyGenerated_of_standardBorel [StandardBorelSpace α] : +-- See note [lower instance priority] +instance (priority := 100) countablyGenerated_of_standardBorel [StandardBorelSpace α] : MeasurableSpace.CountablyGenerated α := letI := upgradeStandardBorel α inferInstance -instance measurableSingleton_of_standardBorel [StandardBorelSpace α] : MeasurableSingletonClass α := +-- See note [lower instance priority] +instance (priority := 100) measurableSingleton_of_standardBorel [StandardBorelSpace α] : + MeasurableSingletonClass α := letI := upgradeStandardBorel α inferInstance From 98aa9626d08ecf2f51e60596fc6206cb14d265ab Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Mon, 14 Oct 2024 18:40:43 +1100 Subject: [PATCH 092/425] fixes for leanprover/lean4#5694 --- Mathlib/Data/Nat/Factorization/Defs.lean | 3 --- Mathlib/Data/Nat/Factors.lean | 2 -- 2 files changed, 5 deletions(-) diff --git a/Mathlib/Data/Nat/Factorization/Defs.lean b/Mathlib/Data/Nat/Factorization/Defs.lean index fb64f3dd9d2d66..d87a08e80720e6 100644 --- a/Mathlib/Data/Nat/Factorization/Defs.lean +++ b/Mathlib/Data/Nat/Factorization/Defs.lean @@ -35,9 +35,6 @@ with a normalization function, and then deduplicated. The basics of this have b -/ --- Workaround for lean4#2038 -attribute [-instance] instBEqNat - open Nat Finset List Finsupp namespace Nat diff --git a/Mathlib/Data/Nat/Factors.lean b/Mathlib/Data/Nat/Factors.lean index df65aa467ceea3..132785107afc0e 100644 --- a/Mathlib/Data/Nat/Factors.lean +++ b/Mathlib/Data/Nat/Factors.lean @@ -29,8 +29,6 @@ open Nat namespace Nat -attribute [instance 0] instBEqNat - /-- `primeFactorsList n` is the prime factorization of `n`, listed in increasing order. -/ def primeFactorsList : ℕ → List ℕ | 0 => [] From 5ab87a979ed4fbe6219ecaf7ca251345ab04ec8f Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Mon, 14 Oct 2024 08:17:17 +0000 Subject: [PATCH 093/425] chore: use foldr in List.prod (#17223) Makes `List.prod_cons` a `rfl` lemma, without any axioms. Closes https://github.com/leanprover-community/mathlib3/issues/161 Simplifies some hypotheses, and makes this compatible with `Nat.sum` in core (which I will subsequently remove). --- Mathlib/Algebra/BigOperators/Group/List.lean | 84 ++++++++++--------- .../Algebra/BigOperators/Group/Multiset.lean | 3 +- Mathlib/Algebra/FreeMonoid/Basic.lean | 2 +- Mathlib/Data/Finsupp/BigOperators.lean | 7 +- Mathlib/Data/PNat/Factors.lean | 1 - 5 files changed, 50 insertions(+), 47 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Group/List.lean b/Mathlib/Algebra/BigOperators/Group/List.lean index 6a1a5fb8af68e6..f7ed6fb0165259 100644 --- a/Mathlib/Algebra/BigOperators/Group/List.lean +++ b/Mathlib/Algebra/BigOperators/Group/List.lean @@ -31,10 +31,10 @@ section Defs /-- Product of a list. -`List.prod [a, b, c] = ((1 * a) * b) * c` -/ -@[to_additive "Sum of a list.\n\n`List.sum [a, b, c] = ((0 + a) + b) + c`"] +`List.prod [a, b, c] = a * (b * (c * 1))` -/ +@[to_additive "Sum of a list.\n\n`List.sum [a, b, c] = a + (b + (c + 0))`"] def prod {α} [Mul α] [One α] : List α → α := - foldl (· * ·) 1 + foldr (· * ·) 1 /-- The alternating sum of a list. -/ def alternatingSum {G : Type*} [Zero G] [Add G] [Neg G] : List G → G @@ -51,21 +51,41 @@ def alternatingProd {G : Type*} [One G] [Mul G] [Inv G] : List G → G end Defs -section MulOneClass +section Mul -variable [MulOneClass M] {l : List M} {a : M} +variable [Mul M] [One M] {l : List M} {a : M} @[to_additive (attr := simp)] theorem prod_nil : ([] : List M).prod = 1 := rfl +@[to_additive (attr := simp)] +theorem prod_cons : (a :: l).prod = a * l.prod := rfl + +@[to_additive] +lemma prod_induction + (p : M → Prop) (hom : ∀ a b, p a → p b → p (a * b)) (unit : p 1) (base : ∀ x ∈ l, p x) : + p l.prod := by + induction l with + | nil => simpa + | cons a l ih => + rw [List.prod_cons] + simp only [mem_cons, forall_eq_or_imp] at base + exact hom _ _ (base.1) (ih base.2) + +end Mul + +section MulOneClass + +variable [MulOneClass M] {l : List M} {a : M} + @[to_additive] theorem prod_singleton : [a].prod = a := - one_mul a + mul_one a -@[to_additive (attr := simp)] +@[to_additive] theorem prod_one_cons : (1 :: l).prod = l.prod := by - rw [prod, foldl, mul_one] + rw [prod, foldr, one_mul] @[to_additive] theorem prod_map_one {l : List ι} : @@ -80,29 +100,18 @@ section Monoid variable [Monoid M] [Monoid N] [Monoid P] {l l₁ l₂ : List M} {a : M} -@[to_additive (attr := simp)] -theorem prod_cons : (a :: l).prod = a * l.prod := - calc - (a :: l).prod = foldl (· * ·) (a * 1) l := by - simp only [List.prod, foldl_cons, one_mul, mul_one] - _ = _ := foldl_assoc - @[to_additive] -lemma prod_induction - (p : M → Prop) (hom : ∀ a b, p a → p b → p (a * b)) (unit : p 1) (base : ∀ x ∈ l, p x) : - p l.prod := by - induction l with - | nil => simpa - | cons a l ih => - rw [List.prod_cons] - simp only [Bool.not_eq_true, List.mem_cons, forall_eq_or_imp] at base - exact hom _ _ (base.1) (ih base.2) +theorem prod_eq_foldl : ∀ {l : List M}, l.prod = foldl (· * ·) 1 l + | [] => rfl + | cons a l => by + rw [prod_cons, prod_eq_foldl, ← foldl_assoc (α := M) (op := (· * ·))] + simp @[to_additive (attr := simp)] theorem prod_append : (l₁ ++ l₂).prod = l₁.prod * l₂.prod := calc - (l₁ ++ l₂).prod = foldl (· * ·) (foldl (· * ·) 1 l₁ * 1) l₂ := by simp [List.prod] - _ = l₁.prod * l₂.prod := foldl_assoc + (l₁ ++ l₂).prod = foldr (· * ·) (1 * foldr (· * ·) 1 l₂) l₁ := by simp [List.prod] + _ = l₁.prod * l₂.prod := foldr_assoc @[to_additive] theorem prod_concat : (l.concat a).prod = l.prod * a := by @@ -113,9 +122,7 @@ theorem prod_join {l : List (List M)} : l.join.prod = (l.map List.prod).prod := induction l <;> [rfl; simp only [*, List.join, map, prod_append, prod_cons]] @[to_additive] -theorem prod_eq_foldr : ∀ {l : List M}, l.prod = foldr (· * ·) 1 l - | [] => rfl - | cons a l => by rw [prod_cons, foldr_cons, prod_eq_foldr] +theorem prod_eq_foldr {l : List M} : l.prod = foldr (· * ·) 1 l := rfl @[to_additive (attr := simp)] theorem prod_replicate (n : ℕ) (a : M) : (replicate n a).prod = a ^ n := by @@ -135,7 +142,7 @@ theorem prod_hom_rel (l : List ι) {r : M → N → Prop} {f : ι → M} {g : ι @[to_additive] theorem rel_prod {R : M → N → Prop} (h : R 1 1) (hf : (R ⇒ R ⇒ R) (· * ·) (· * ·)) : (Forall₂ R ⇒ R) prod prod := - rel_foldl hf h + rel_foldr hf h @[to_additive] theorem prod_hom_nonempty {l : List M} {F : Type*} [FunLike F M N] [MulHomClass F M N] (f : F) @@ -145,8 +152,8 @@ theorem prod_hom_nonempty {l : List M} {F : Type*} [FunLike F M N] [MulHomClass @[to_additive] theorem prod_hom (l : List M) {F : Type*} [FunLike F M N] [MonoidHomClass F M N] (f : F) : (l.map f).prod = f l.prod := by - simp only [prod, foldl_map, ← map_one f] - exact l.foldl_hom f (· * ·) (· * f ·) 1 (fun x y => (map_mul f x y).symm) + simp only [prod, foldr_map, ← map_one f] + exact l.foldr_hom f (· * ·) (f · * ·) 1 (fun x y => (map_mul f x y).symm) @[to_additive] theorem prod_hom₂_nonempty {l : List ι} (f : M → N → P) @@ -158,8 +165,8 @@ theorem prod_hom₂_nonempty {l : List ι} (f : M → N → P) theorem prod_hom₂ (l : List ι) (f : M → N → P) (hf : ∀ a b c d, f (a * b) (c * d) = f a c * f b d) (hf' : f 1 1 = 1) (f₁ : ι → M) (f₂ : ι → N) : (l.map fun i => f (f₁ i) (f₂ i)).prod = f (l.map f₁).prod (l.map f₂).prod := by - rw [prod, prod, prod, foldl_map, foldl_map, foldl_map, - ← l.foldl_hom₂ f _ _ (fun x y => x * f (f₁ y) (f₂ y)) _ _ (by simp [hf]), hf'] + rw [prod, prod, prod, foldr_map, foldr_map, foldr_map, + ← l.foldr_hom₂ f _ _ (fun x y => f (f₁ x) (f₂ x) * y) _ _ (by simp [hf]), hf'] @[to_additive (attr := simp)] theorem prod_map_mul {α : Type*} [CommMonoid α] {l : List ι} {f g : ι → α} : @@ -315,14 +322,14 @@ depend on the order of elements. -/ @[to_additive "If elements of a list additively commute with each other, then their sum does not depend on the order of elements."] lemma Perm.prod_eq' (h : l₁ ~ l₂) (hc : l₁.Pairwise Commute) : l₁.prod = l₂.prod := by - refine h.foldl_eq' ?_ _ + refine h.foldr_eq' ?_ _ apply Pairwise.forall_of_forall · intro x y h z exact (h z).symm · intros; rfl · apply hc.imp intro a b h z - rw [mul_assoc z, mul_assoc z, h] + rw [← mul_assoc, ← mul_assoc, h] end Monoid @@ -342,7 +349,7 @@ lemma prod_map_erase [DecidableEq α] (f : α → M) {a} : · simp only [map, erase_cons_tail (not_beq_of_ne ne.symm), prod_cons, prod_map_erase _ h, mul_left_comm (f a) (f b)] -@[to_additive] lemma Perm.prod_eq (h : Perm l₁ l₂) : prod l₁ = prod l₂ := h.foldl_op_eq +@[to_additive] lemma Perm.prod_eq (h : Perm l₁ l₂) : prod l₁ = prod l₂ := h.foldr_op_eq @[to_additive] lemma prod_reverse (l : List M) : prod l.reverse = prod l := (reverse_perm l).prod_eq @@ -625,8 +632,7 @@ end MonoidHom end MonoidHom -@[simp] lemma Nat.sum_eq_listSum (l : List ℕ) : Nat.sum l = l.sum := - (List.foldl_eq_foldr _ _).symm +@[simp] lemma Nat.sum_eq_listSum (l : List ℕ) : Nat.sum l = l.sum := rfl namespace List diff --git a/Mathlib/Algebra/BigOperators/Group/Multiset.lean b/Mathlib/Algebra/BigOperators/Group/Multiset.lean index b3ab0b0f8c1247..a0bb921c056e3a 100644 --- a/Mathlib/Algebra/BigOperators/Group/Multiset.lean +++ b/Mathlib/Algebra/BigOperators/Group/Multiset.lean @@ -49,8 +49,7 @@ theorem prod_eq_foldl (s : Multiset α) : (foldr_swap _ _ _).trans (by simp [mul_comm]) @[to_additive (attr := simp, norm_cast)] -theorem prod_coe (l : List α) : prod ↑l = l.prod := - prod_eq_foldl _ +theorem prod_coe (l : List α) : prod ↑l = l.prod := rfl @[to_additive (attr := simp)] theorem prod_toList (s : Multiset α) : s.toList.prod = s.prod := by diff --git a/Mathlib/Algebra/FreeMonoid/Basic.lean b/Mathlib/Algebra/FreeMonoid/Basic.lean index 9f12ab8a836868..6137d36c3f5ed0 100644 --- a/Mathlib/Algebra/FreeMonoid/Basic.lean +++ b/Mathlib/Algebra/FreeMonoid/Basic.lean @@ -155,7 +155,7 @@ def prodAux {M} [Monoid M] : List M → M @[to_additive] lemma prodAux_eq : ∀ l : List M, FreeMonoid.prodAux l = l.prod | [] => rfl - | (_ :: xs) => congr_arg (fun x => List.foldl (· * ·) x xs) (one_mul _).symm + | (_ :: xs) => by simp [prodAux, List.prod_eq_foldl] /-- Equivalence between maps `α → M` and monoid homomorphisms `FreeMonoid α →* M`. -/ @[to_additive "Equivalence between maps `α → A` and additive monoid homomorphisms diff --git a/Mathlib/Data/Finsupp/BigOperators.lean b/Mathlib/Data/Finsupp/BigOperators.lean index 49c8433784071d..170585fa66d4ba 100644 --- a/Mathlib/Data/Finsupp/BigOperators.lean +++ b/Mathlib/Data/Finsupp/BigOperators.lean @@ -94,10 +94,9 @@ theorem Multiset.support_sum_eq [AddCommMonoid M] (s : Multiset (ι →₀ M)) obtain ⟨l, hl, hd⟩ := hs suffices a.Pairwise (_root_.Disjoint on Finsupp.support) by convert List.support_sum_eq a this - · simp only [Multiset.quot_mk_to_coe'', Multiset.sum_coe] - · dsimp only [Function.comp_def] - simp only [quot_mk_to_coe'', map_coe, sup_coe, Finset.le_eq_subset, - Finset.sup_eq_union, Finset.bot_eq_empty, List.foldr_map] + dsimp only [Function.comp_def] + simp only [quot_mk_to_coe'', map_coe, sup_coe, Finset.le_eq_subset, + Finset.sup_eq_union, Finset.bot_eq_empty, List.foldr_map] simp only [Multiset.quot_mk_to_coe'', Multiset.map_coe, Multiset.coe_eq_coe] at hl exact hl.symm.pairwise hd fun h ↦ _root_.Disjoint.symm h diff --git a/Mathlib/Data/PNat/Factors.lean b/Mathlib/Data/PNat/Factors.lean index 103a0f6a9d2799..2a2367c5bbc13e 100644 --- a/Mathlib/Data/PNat/Factors.lean +++ b/Mathlib/Data/PNat/Factors.lean @@ -224,7 +224,6 @@ theorem factorMultiset_prod (v : PrimeMultiset) : v.prod.factorMultiset = v := b rcases v with ⟨l⟩ --unfold_coes dsimp [PrimeMultiset.toNatMultiset] - rw [Multiset.prod_coe] let l' := l.map (Coe.coe : Nat.Primes → ℕ) have : ∀ p : ℕ, p ∈ l' → p.Prime := fun p hp => by rcases List.mem_map.mp hp with ⟨⟨_, hp'⟩, ⟨_, h_eq⟩⟩ From 9bd02e1b13989d9a7e33c85e741260f933361dbd Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Mon, 14 Oct 2024 08:24:25 +0000 Subject: [PATCH 094/425] chore: bump to nightly-2024-10-14 --- lean-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lean-toolchain b/lean-toolchain index 30684366328531..a7eff1cf43d14e 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-13 +leanprover/lean4:nightly-2024-10-14 From 67ce9277b33cf5b6b2ae8fd793039e9b911ee2c7 Mon Sep 17 00:00:00 2001 From: Robin Carlier <57142648+robin-carlier@users.noreply.github.com> Date: Mon, 14 Oct 2024 09:10:35 +0000 Subject: [PATCH 095/425] feat(CategoryTheory/ChosenFiniteProducts/FunctorCategory): Tensoring on the left preserves colimits if it does so on the base category (#17719) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Show that if `C` has chosen finite products and is such that tensoring on the left preserves `K`-shaped colimits, then the tensor product on `J ⥤ C` has the same property. --- .../ChosenFiniteProducts/FunctorCategory.lean | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Mathlib/CategoryTheory/ChosenFiniteProducts/FunctorCategory.lean b/Mathlib/CategoryTheory/ChosenFiniteProducts/FunctorCategory.lean index c95c9da1f310e9..265a1793d3a1dc 100644 --- a/Mathlib/CategoryTheory/ChosenFiniteProducts/FunctorCategory.lean +++ b/Mathlib/CategoryTheory/ChosenFiniteProducts/FunctorCategory.lean @@ -151,6 +151,15 @@ lemma associator_inv_app (F₁ F₂ F₃ : J ⥤ C) (j : J) : (α_ F₁ F₂ F₃).inv.app j = (α_ _ _ _).inv := by rw [← cancel_mono ((α_ _ _ _).hom), Iso.inv_hom_id, ← associator_hom_app, Iso.inv_hom_id_app] +noncomputable instance {K : Type*} [Category K] [HasColimitsOfShape K C] + [∀ X : C, PreservesColimitsOfShape K (tensorLeft X)] {F : J ⥤ C} : + PreservesColimitsOfShape K (tensorLeft F) := by + apply preservesColimitsOfShapeOfEvaluation + intro k + haveI : tensorLeft F ⋙ (evaluation J C).obj k ≅ (evaluation J C).obj k ⋙ tensorLeft (F.obj k) := + NatIso.ofComponents (fun _ ↦ Iso.refl _) + exact preservesColimitsOfShapeOfNatIso this.symm + end Monoidal end Functor From 3f919e0d20d51cf1876d2c2b751446c822bc4f37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Mon, 14 Oct 2024 09:30:01 +0000 Subject: [PATCH 096/425] =?UTF-8?q?chore(SetTheory/Ordinal/Arithmetic):=20?= =?UTF-8?q?`sub=5FisNormal`=20=E2=86=92=20`isNormal=5Fsub`,=20etc.=20(#176?= =?UTF-8?q?73)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We fix various misnamed lemmas involving `IsNormal` and `IsLimit`. --- Mathlib/SetTheory/Cardinal/Aleph.lean | 14 +++-- Mathlib/SetTheory/Cardinal/Cofinality.lean | 2 +- Mathlib/SetTheory/Ordinal/Arithmetic.lean | 60 ++++++++++++++-------- Mathlib/SetTheory/Ordinal/Exponential.lean | 41 +++++++++------ Mathlib/SetTheory/Ordinal/FixedPoint.lean | 57 +++++++++++--------- Mathlib/SetTheory/Ordinal/NaturalOps.lean | 4 +- Mathlib/SetTheory/Ordinal/Notation.lean | 12 ++--- Mathlib/SetTheory/Ordinal/Principal.lean | 19 +++---- 8 files changed, 125 insertions(+), 84 deletions(-) diff --git a/Mathlib/SetTheory/Cardinal/Aleph.lean b/Mathlib/SetTheory/Cardinal/Aleph.lean index a2d762c20d204d..cfb20ec7268ad7 100644 --- a/Mathlib/SetTheory/Cardinal/Aleph.lean +++ b/Mathlib/SetTheory/Cardinal/Aleph.lean @@ -281,7 +281,7 @@ theorem aleph'_isNormal : IsNormal (ord ∘ aleph') := simp [ord_le, aleph'_le_of_limit l]⟩ theorem aleph_isNormal : IsNormal (ord ∘ aleph) := - aleph'_isNormal.trans <| add_isNormal ω + aleph'_isNormal.trans <| isNormal_add_right ω theorem succ_aleph0 : succ ℵ₀ = aleph 1 := by rw [← aleph_zero, ← aleph_succ, Ordinal.succ_zero] @@ -396,11 +396,15 @@ theorem beth_pos (o : Ordinal) : 0 < beth o := theorem beth_ne_zero (o : Ordinal) : beth o ≠ 0 := (beth_pos o).ne' +theorem isNormal_beth : IsNormal (ord ∘ beth) := by + refine (isNormal_iff_strictMono_limit _).2 + ⟨ord_strictMono.comp beth_strictMono, fun o ho a ha ↦ ?_⟩ + rw [comp_apply, beth_limit ho, ord_le] + exact ciSup_le' fun b => ord_le.1 (ha _ b.2) + +@[deprecated isNormal_beth (since := "2024-10-11")] theorem beth_normal : IsNormal.{u} fun o => (beth o).ord := - (isNormal_iff_strictMono_limit _).2 - ⟨ord_strictMono.comp beth_strictMono, fun o ho a ha => by - rw [beth_limit ho, ord_le] - exact ciSup_le' fun b => ord_le.1 (ha _ b.2)⟩ + isNormal_beth end Cardinal diff --git a/Mathlib/SetTheory/Cardinal/Cofinality.lean b/Mathlib/SetTheory/Cardinal/Cofinality.lean index 55b3d56e3120c5..ded9fbf59464d1 100644 --- a/Mathlib/SetTheory/Cardinal/Cofinality.lean +++ b/Mathlib/SetTheory/Cardinal/Cofinality.lean @@ -652,7 +652,7 @@ theorem cof_add (a b : Ordinal) : b ≠ 0 → cof (a + b) = cof b := fun h => by rcases zero_or_succ_or_limit b with (rfl | ⟨c, rfl⟩ | hb) · contradiction · rw [add_succ, cof_succ, cof_succ] - · exact (add_isNormal a).cof_eq hb + · exact (isNormal_add_right a).cof_eq hb theorem aleph0_le_cof {o} : ℵ₀ ≤ cof o ↔ IsLimit o := by rcases zero_or_succ_or_limit o with (rfl | ⟨o, rfl⟩ | l) diff --git a/Mathlib/SetTheory/Ordinal/Arithmetic.lean b/Mathlib/SetTheory/Ordinal/Arithmetic.lean index c98fcecd35665c..967798e7995f7d 100644 --- a/Mathlib/SetTheory/Ordinal/Arithmetic.lean +++ b/Mathlib/SetTheory/Ordinal/Arithmetic.lean @@ -479,11 +479,17 @@ theorem add_le_of_limit {a b c : Ordinal} (h : IsLimit b) : a + b ≤ c ↔ ∀ · rcases a with ⟨a | a, h₁⟩ <;> rcases b with ⟨b | b, h₂⟩ <;> cases h₁ <;> cases h₂ <;> rintro ⟨⟩ <;> constructor <;> assumption⟩ -theorem add_isNormal (a : Ordinal) : IsNormal (a + ·) := +theorem isNormal_add_right (a : Ordinal) : IsNormal (a + ·) := ⟨fun b => (add_lt_add_iff_left a).2 (lt_succ b), fun _b l _c => add_le_of_limit l⟩ -theorem add_isLimit (a) {b} : IsLimit b → IsLimit (a + b) := - (add_isNormal a).isLimit +@[deprecated isNormal_add_right (since := "2024-10-11")] +alias add_isNormal := isNormal_add_right + +theorem isLimit_add (a) {b} : IsLimit b → IsLimit (a + b) := + (isNormal_add_right a).isLimit + +@[deprecated isLimit_add (since := "2024-10-11")] +alias add_isLimit := isLimit_add alias IsLimit.add := add_isLimit @@ -554,10 +560,13 @@ theorem sub_sub (a b c : Ordinal) : a - b - c = a - (b + c) := theorem add_sub_add_cancel (a b c : Ordinal) : a + b - (a + c) = b - c := by rw [← sub_sub, add_sub_cancel] -theorem sub_isLimit {a b} (l : IsLimit a) (h : b < a) : IsLimit (a - b) := +theorem isLimit_sub {a b} (l : IsLimit a) (h : b < a) : IsLimit (a - b) := ⟨ne_of_gt <| lt_sub.2 <| by rwa [add_zero], fun c h => by rw [lt_sub, add_succ]; exact l.2 _ (lt_sub.1 h)⟩ +@[deprecated isLimit_sub (since := "2024-10-11")] +alias sub_isLimit := isLimit_sub + -- @[simp] -- Porting note (#10618): simp can prove this theorem one_add_omega0 : 1 + ω = ω := by refine le_antisymm ?_ (le_add_left _ _) @@ -739,7 +748,7 @@ theorem mul_le_of_limit {a b c : Ordinal} (h : IsLimit b) : a * b ≤ c ↔ ∀ | H β s => exact mul_le_of_limit_aux h H⟩ -theorem mul_isNormal {a : Ordinal} (h : 0 < a) : IsNormal (a * ·) := +theorem isNormal_mul_right {a : Ordinal} (h : 0 < a) : IsNormal (a * ·) := -- Porting note(#12129): additional beta reduction needed ⟨fun b => by beta_reduce @@ -747,15 +756,18 @@ theorem mul_isNormal {a : Ordinal} (h : 0 < a) : IsNormal (a * ·) := simpa only [add_zero] using (add_lt_add_iff_left (a * b)).2 h, fun b l c => mul_le_of_limit l⟩ +@[deprecated isNormal_mul_right (since := "2024-10-11")] +alias mul_isNormal := isNormal_mul_right + theorem lt_mul_of_limit {a b c : Ordinal} (h : IsLimit c) : a < b * c ↔ ∃ c' < c, a < b * c' := by -- Porting note: `bex_def` is required. simpa only [not_forall₂, not_le, bex_def] using not_congr (@mul_le_of_limit b c a h) theorem mul_lt_mul_iff_left {a b c : Ordinal} (a0 : 0 < a) : a * b < a * c ↔ b < c := - (mul_isNormal a0).lt_iff + (isNormal_mul_right a0).lt_iff theorem mul_le_mul_iff_left {a b c : Ordinal} (a0 : 0 < a) : a * b ≤ a * c ↔ b ≤ c := - (mul_isNormal a0).le_iff + (isNormal_mul_right a0).le_iff theorem mul_lt_mul_of_pos_left {a b c : Ordinal} (h : a < b) (c0 : 0 < c) : c * a < c * b := (mul_lt_mul_iff_left c0).2 h @@ -770,17 +782,23 @@ theorem le_of_mul_le_mul_left {a b c : Ordinal} (h : c * a ≤ c * b) (h0 : 0 < le_imp_le_of_lt_imp_lt (fun h' => mul_lt_mul_of_pos_left h' h0) h theorem mul_right_inj {a b c : Ordinal} (a0 : 0 < a) : a * b = a * c ↔ b = c := - (mul_isNormal a0).inj + (isNormal_mul_right a0).inj -theorem mul_isLimit {a b : Ordinal} (a0 : 0 < a) : IsLimit b → IsLimit (a * b) := - (mul_isNormal a0).isLimit +theorem isLimit_mul {a b : Ordinal} (a0 : 0 < a) : IsLimit b → IsLimit (a * b) := + (isNormal_mul_right a0).isLimit -theorem mul_isLimit_left {a b : Ordinal} (l : IsLimit a) (b0 : 0 < b) : IsLimit (a * b) := by +@[deprecated isLimit_mul (since := "2024-10-11")] +alias mul_isLimit := isLimit_mul + +theorem isLimit_mul_left {a b : Ordinal} (l : IsLimit a) (b0 : 0 < b) : IsLimit (a * b) := by rcases zero_or_succ_or_limit b with (rfl | ⟨b, rfl⟩ | lb) · exact b0.false.elim · rw [mul_succ] - exact add_isLimit _ l - · exact mul_isLimit l.pos lb + exact isLimit_add _ l + · exact isLimit_mul l.pos lb + +@[deprecated isLimit_mul_left (since := "2024-10-11")] +alias mul_isLimit_left := isLimit_mul_left theorem smul_eq_mul : ∀ (n : ℕ) (a : Ordinal), n • a = a * n | 0, a => by rw [zero_nsmul, Nat.cast_zero, mul_zero] @@ -904,11 +922,11 @@ theorem isLimit_add_iff {a b} : IsLimit (a + b) ↔ IsLimit b ∨ b = 0 ∧ IsLi exact ⟨h', h⟩ left rw [← add_sub_cancel a b] - apply sub_isLimit h + apply isLimit_sub h suffices a + 0 < a + b by simpa only [add_zero] using this rwa [add_lt_add_iff_left, Ordinal.pos_iff_ne_zero] rcases h with (h | ⟨rfl, h⟩) - · exact add_isLimit a h + · exact isLimit_add a h · simpa only [add_zero] theorem dvd_add_iff : ∀ {a b c : Ordinal}, a ∣ b → (a ∣ b + c ↔ a ∣ c) @@ -2216,7 +2234,7 @@ namespace Ordinal theorem lt_add_of_limit {a b c : Ordinal.{u}} (h : IsLimit c) : a < b + c ↔ ∃ c' < c, a < b + c' := by -- Porting note: `bex_def` is required. - rw [← IsNormal.bsup_eq.{u, u} (add_isNormal b) h, lt_bsup, bex_def] + rw [← IsNormal.bsup_eq.{u, u} (isNormal_add_right b) h, lt_bsup, bex_def] theorem lt_omega0 {o : Ordinal} : o < ω ↔ ∃ n : ℕ, o = n := by simp_rw [← Cardinal.ord_aleph0, Cardinal.lt_ord, lt_aleph0, card_eq_nat] @@ -2296,9 +2314,9 @@ theorem isLimit_iff_omega0_dvd {a : Ordinal} : IsLimit a ↔ a ≠ 0 ∧ ω ∣ rcases lt_omega0.1 hb with ⟨n, rfl⟩ exact (add_le_add_right (mul_div_le _ _) _).trans - (lt_sub.1 <| nat_lt_limit (sub_isLimit l hx) _).le + (lt_sub.1 <| nat_lt_limit (isLimit_sub l hx) _).le · rcases h with ⟨a0, b, rfl⟩ - refine mul_isLimit_left omega0_isLimit (Ordinal.pos_iff_ne_zero.2 <| mt ?_ a0) + refine isLimit_mul_left omega0_isLimit (Ordinal.pos_iff_ne_zero.2 <| mt ?_ a0) intro e simp only [e, mul_zero] @@ -2351,19 +2369,19 @@ alias IsNormal.apply_omega := IsNormal.apply_omega0 @[simp] theorem iSup_add_nat (o : Ordinal) : ⨆ n : ℕ, o + n = o + ω := - (add_isNormal o).apply_omega0 + (isNormal_add_right o).apply_omega0 set_option linter.deprecated false in @[deprecated iSup_add_nat (since := "2024-08-27")] theorem sup_add_nat (o : Ordinal) : (sup fun n : ℕ => o + n) = o + ω := - (add_isNormal o).apply_omega0 + (isNormal_add_right o).apply_omega0 @[simp] theorem iSup_mul_nat (o : Ordinal) : ⨆ n : ℕ, o * n = o * ω := by rcases eq_zero_or_pos o with (rfl | ho) · rw [zero_mul] exact iSup_eq_zero_iff.2 fun n => zero_mul (n : Ordinal) - · exact (mul_isNormal ho).apply_omega0 + · exact (isNormal_mul_right ho).apply_omega0 set_option linter.deprecated false in @[deprecated iSup_add_nat (since := "2024-08-27")] diff --git a/Mathlib/SetTheory/Ordinal/Exponential.lean b/Mathlib/SetTheory/Ordinal/Exponential.lean index b00223b311dabe..6fb276eb864d63 100644 --- a/Mathlib/SetTheory/Ordinal/Exponential.lean +++ b/Mathlib/SetTheory/Ordinal/Exponential.lean @@ -100,29 +100,38 @@ theorem opow_natCast (a : Ordinal) (n : ℕ) : a ^ (n : Ordinal) = a ^ n := by | zero => rw [Nat.cast_zero, opow_zero, pow_zero] | succ n IH => rw [Nat.cast_succ, add_one_eq_succ, opow_succ, pow_succ, IH] -theorem opow_isNormal {a : Ordinal} (h : 1 < a) : IsNormal (a ^ ·) := +theorem isNormal_opow {a : Ordinal} (h : 1 < a) : IsNormal (a ^ ·) := have a0 : 0 < a := zero_lt_one.trans h ⟨fun b => by simpa only [mul_one, opow_succ] using (mul_lt_mul_iff_left (opow_pos b a0)).2 h, fun b l c => opow_le_of_limit (ne_of_gt a0) l⟩ +@[deprecated isNormal_opow (since := "2024-10-11")] +alias opow_isNormal := isNormal_opow + theorem opow_lt_opow_iff_right {a b c : Ordinal} (a1 : 1 < a) : a ^ b < a ^ c ↔ b < c := - (opow_isNormal a1).lt_iff + (isNormal_opow a1).lt_iff theorem opow_le_opow_iff_right {a b c : Ordinal} (a1 : 1 < a) : a ^ b ≤ a ^ c ↔ b ≤ c := - (opow_isNormal a1).le_iff + (isNormal_opow a1).le_iff theorem opow_right_inj {a b c : Ordinal} (a1 : 1 < a) : a ^ b = a ^ c ↔ b = c := - (opow_isNormal a1).inj + (isNormal_opow a1).inj + +theorem isLimit_opow {a b : Ordinal} (a1 : 1 < a) : IsLimit b → IsLimit (a ^ b) := + (isNormal_opow a1).isLimit -theorem opow_isLimit {a b : Ordinal} (a1 : 1 < a) : IsLimit b → IsLimit (a ^ b) := - (opow_isNormal a1).isLimit +@[deprecated isLimit_opow (since := "2024-10-11")] +alias opow_isLimit := isLimit_opow -theorem opow_isLimit_left {a b : Ordinal} (l : IsLimit a) (hb : b ≠ 0) : IsLimit (a ^ b) := by +theorem isLimit_opow_left {a b : Ordinal} (l : IsLimit a) (hb : b ≠ 0) : IsLimit (a ^ b) := by rcases zero_or_succ_or_limit b with (e | ⟨b, rfl⟩ | l') · exact absurd e hb · rw [opow_succ] - exact mul_isLimit (opow_pos _ l.pos) l - · exact opow_isLimit l.one_lt l' + exact isLimit_mul (opow_pos _ l.pos) l + · exact isLimit_opow l.one_lt l' + +@[deprecated isLimit_opow_left (since := "2024-10-11")] +alias opow_isLimit_left := isLimit_opow_left theorem opow_le_opow_right {a b c : Ordinal} (h₁ : 0 < a) (h₂ : b ≤ c) : a ^ b ≤ a ^ c := by rcases lt_or_eq_of_le (one_le_iff_pos.2 h₁) with h₁ | h₁ @@ -159,7 +168,7 @@ theorem left_le_opow (a : Ordinal) {b : Ordinal} (b1 : 0 < b) : a ≤ a ^ b := b rwa [opow_le_opow_iff_right a1, one_le_iff_pos] theorem right_le_opow {a : Ordinal} (b : Ordinal) (a1 : 1 < a) : b ≤ a ^ b := - (opow_isNormal a1).id_le _ + (isNormal_opow a1).id_le _ theorem opow_lt_opow_left_of_succ {a b c : Ordinal} (ab : a < b) : a ^ succ c < b ^ succ c := by rw [opow_succ, opow_succ] @@ -182,12 +191,12 @@ theorem opow_add (a b c : Ordinal) : a ^ (b + c) = a ^ b * a ^ c := by | H₃ c l IH => refine eq_of_forall_ge_iff fun d => - (((opow_isNormal a1).trans (add_isNormal b)).limit_le l).trans ?_ + (((isNormal_opow a1).trans (isNormal_add_right b)).limit_le l).trans ?_ dsimp only [Function.comp_def] simp (config := { contextual := true }) only [IH] exact - (((mul_isNormal <| opow_pos b (Ordinal.pos_iff_ne_zero.2 a0)).trans - (opow_isNormal a1)).limit_le + (((isNormal_mul_right <| opow_pos b (Ordinal.pos_iff_ne_zero.2 a0)).trans + (isNormal_opow a1)).limit_le l).symm theorem opow_one_add (a b : Ordinal) : a ^ (1 + b) = a * a ^ b := by rw [opow_add, opow_one] @@ -219,7 +228,7 @@ theorem opow_mul (a b c : Ordinal) : a ^ (b * c) = (a ^ b) ^ c := by | H₃ c l IH => refine eq_of_forall_ge_iff fun d => - (((opow_isNormal a1).trans (mul_isNormal (Ordinal.pos_iff_ne_zero.2 b0))).limit_le + (((isNormal_opow a1).trans (isNormal_mul_right (Ordinal.pos_iff_ne_zero.2 b0))).limit_le l).trans ?_ dsimp only [Function.comp_def] @@ -481,7 +490,7 @@ theorem natCast_opow (m : ℕ) : ∀ n : ℕ, ↑(m ^ n : ℕ) = (m : Ordinal) ^ theorem iSup_pow {o : Ordinal} (ho : 0 < o) : ⨆ n : ℕ, o ^ n = o ^ ω := by simp_rw [← opow_natCast] rcases (one_le_iff_pos.2 ho).lt_or_eq with ho₁ | rfl - · exact (opow_isNormal ho₁).apply_omega0 + · exact (isNormal_opow ho₁).apply_omega0 · rw [one_opow] refine le_antisymm (Ordinal.iSup_le fun n => by rw [one_opow]) ?_ convert Ordinal.le_iSup _ 0 @@ -492,7 +501,7 @@ set_option linter.deprecated false in theorem sup_opow_nat {o : Ordinal} (ho : 0 < o) : (sup fun n : ℕ => o ^ n) = o ^ ω := by simp_rw [← opow_natCast] rcases (one_le_iff_pos.2 ho).lt_or_eq with ho₁ | rfl - · exact (opow_isNormal ho₁).apply_omega0 + · exact (isNormal_opow ho₁).apply_omega0 · rw [one_opow] refine le_antisymm (sup_le fun n => by rw [one_opow]) ?_ convert le_sup (fun n : ℕ => 1 ^ (n : Ordinal)) 0 diff --git a/Mathlib/SetTheory/Ordinal/FixedPoint.lean b/Mathlib/SetTheory/Ordinal/FixedPoint.lean index 0ec30e305b66c7..40cae6c0b82996 100644 --- a/Mathlib/SetTheory/Ordinal/FixedPoint.lean +++ b/Mathlib/SetTheory/Ordinal/FixedPoint.lean @@ -165,10 +165,13 @@ theorem derivFamily_limit (f : ι → Ordinal → Ordinal) {o} : IsLimit o → derivFamily.{u, v} f o = bsup.{max u v, u} o fun a _ => derivFamily.{u, v} f a := limitRecOn_limit _ _ _ _ -theorem derivFamily_isNormal (f : ι → Ordinal → Ordinal) : IsNormal (derivFamily f) := +theorem isNormal_derivFamily (f : ι → Ordinal → Ordinal) : IsNormal (derivFamily f) := ⟨fun o => by rw [derivFamily_succ, ← succ_le_iff]; apply le_nfpFamily, fun o l a => by rw [derivFamily_limit _ l, bsup_le_iff]⟩ +@[deprecated isNormal_derivFamily (since := "2024-10-11")] +alias derivFamily_isNormal := isNormal_derivFamily + theorem derivFamily_fp {i} (H : IsNormal (f i)) (o : Ordinal.{max u v}) : f i (derivFamily.{u, v} f o) = derivFamily.{u, v} f o := by induction' o using limitRecOn with o _ o l IH @@ -185,7 +188,7 @@ theorem le_iff_derivFamily (H : ∀ i, IsNormal (f i)) {a} : (∀ i, f i a ≤ a) ↔ ∃ o, derivFamily.{u, v} f o = a := ⟨fun ha => by suffices ∀ (o) (_ : a ≤ derivFamily.{u, v} f o), ∃ o, derivFamily.{u, v} f o = a from - this a (derivFamily_isNormal _).le_apply + this a (isNormal_derivFamily _).le_apply intro o induction' o using limitRecOn with o IH o l IH · intro h₁ @@ -215,7 +218,7 @@ theorem fp_iff_derivFamily (H : ∀ i, IsNormal (f i)) {a} : theorem derivFamily_eq_enumOrd (H : ∀ i, IsNormal (f i)) : derivFamily.{u, v} f = enumOrd (⋂ i, Function.fixedPoints (f i)) := by rw [eq_comm, eq_enumOrd _ (not_bddAbove_fp_family H)] - use (derivFamily_isNormal f).strictMono + use (isNormal_derivFamily f).strictMono rw [Set.range_eq_iff] refine ⟨?_, fun a ha => ?_⟩ · rintro a S ⟨i, hi⟩ @@ -335,9 +338,12 @@ theorem derivBFamily_eq_derivFamily {o : Ordinal} (f : ∀ b < o, Ordinal → Or derivBFamily.{u, v} o f = derivFamily.{u, v} (familyOfBFamily o f) := rfl -theorem derivBFamily_isNormal {o : Ordinal} (f : ∀ b < o, Ordinal → Ordinal) : +theorem isNormal_derivBFamily {o : Ordinal} (f : ∀ b < o, Ordinal → Ordinal) : IsNormal (derivBFamily o f) := - derivFamily_isNormal _ + isNormal_derivFamily _ + +@[deprecated isNormal_derivBFamily (since := "2024-10-11")] +alias derivBFamily_isNormal := isNormal_derivBFamily theorem derivBFamily_fp {i hi} (H : IsNormal (f i hi)) (a : Ordinal) : f i hi (derivBFamily.{u, v} o f a) = derivBFamily.{u, v} o f a := by @@ -366,7 +372,7 @@ theorem fp_iff_derivBFamily (H : ∀ i hi, IsNormal (f i hi)) {a} : theorem derivBFamily_eq_enumOrd (H : ∀ i hi, IsNormal (f i hi)) : derivBFamily.{u, v} o f = enumOrd (⋂ (i) (hi), Function.fixedPoints (f i hi)) := by rw [eq_comm, eq_enumOrd _ (not_bddAbove_fp_bfamily H)] - use (derivBFamily_isNormal f).strictMono + use (isNormal_derivBFamily f).strictMono rw [Set.range_eq_iff] refine ⟨fun a => Set.mem_iInter₂.2 fun i hi => derivBFamily_fp (H i hi) a, fun a ha => ?_⟩ rw [Set.mem_iInter₂] at ha @@ -495,11 +501,14 @@ theorem deriv_succ (f o) : deriv f (succ o) = nfp f (succ (deriv f o)) := theorem deriv_limit (f) {o} : IsLimit o → deriv f o = bsup.{u, 0} o fun a _ => deriv f a := derivFamily_limit _ -theorem deriv_isNormal (f) : IsNormal (deriv f) := - derivFamily_isNormal _ +theorem isNormal_deriv (f) : IsNormal (deriv f) := + isNormal_derivFamily _ + +@[deprecated isNormal_deriv (since := "2024-10-11")] +alias deriv_isNormal := isNormal_deriv theorem deriv_id_of_nfp_id {f : Ordinal → Ordinal} (h : nfp f = id) : deriv f = id := - ((deriv_isNormal _).eq_iff_zero_and_succ IsNormal.refl).2 (by simp [h]) + ((isNormal_deriv _).eq_iff_zero_and_succ IsNormal.refl).2 (by simp [h]) theorem IsNormal.deriv_fp {f} (H : IsNormal f) : ∀ o, f (deriv f o) = deriv f o := @derivFamily_fp Unit (fun _ => f) Unit.unit H @@ -518,7 +527,7 @@ theorem deriv_eq_enumOrd (H : IsNormal f) : deriv f = enumOrd (Function.fixedPoi exact (Set.iInter_const _).symm theorem deriv_eq_id_of_nfp_eq_id {f : Ordinal → Ordinal} (h : nfp f = id) : deriv f = id := - (IsNormal.eq_iff_zero_and_succ (deriv_isNormal _) IsNormal.refl).2 <| by simp [h] + (IsNormal.eq_iff_zero_and_succ (isNormal_deriv _) IsNormal.refl).2 <| by simp [h] theorem nfp_zero_left (a) : nfp 0 a = a := by rw [← iSup_iterate_eq_nfp] @@ -555,9 +564,9 @@ theorem nfp_add_zero (a) : nfp (a + ·) 0 = a * ω := by · rw [iterate_succ_apply', Nat.add_comm, Nat.cast_add, Nat.cast_one, mul_one_add, hn] theorem nfp_add_eq_mul_omega0 {a b} (hba : b ≤ a * ω) : nfp (a + ·) b = a * ω := by - apply le_antisymm (nfp_le_fp (add_isNormal a).monotone hba _) + apply le_antisymm (nfp_le_fp (isNormal_add_right a).monotone hba _) · rw [← nfp_add_zero] - exact nfp_monotone (add_isNormal a).monotone (Ordinal.zero_le b) + exact nfp_monotone (isNormal_add_right a).monotone (Ordinal.zero_le b) · dsimp; rw [← mul_one_add, one_add_omega0] @[deprecated (since := "2024-09-30")] @@ -566,9 +575,9 @@ alias nfp_add_eq_mul_omega := nfp_add_eq_mul_omega0 theorem add_eq_right_iff_mul_omega0_le {a b : Ordinal} : a + b = b ↔ a * ω ≤ b := by refine ⟨fun h => ?_, fun h => ?_⟩ · rw [← nfp_add_zero a, ← deriv_zero_right] - cases' (add_isNormal a).fp_iff_deriv.1 h with c hc + cases' (isNormal_add_right a).fp_iff_deriv.1 h with c hc rw [← hc] - exact (deriv_isNormal _).monotone (Ordinal.zero_le _) + exact (isNormal_deriv _).monotone (Ordinal.zero_le _) · have := Ordinal.add_sub_cancel_of_le h nth_rw 1 [← this] rwa [← add_assoc, ← mul_one_add, one_add_omega0] @@ -578,14 +587,14 @@ alias add_eq_right_iff_mul_omega_le := add_eq_right_iff_mul_omega0_le theorem add_le_right_iff_mul_omega0_le {a b : Ordinal} : a + b ≤ b ↔ a * ω ≤ b := by rw [← add_eq_right_iff_mul_omega0_le] - exact (add_isNormal a).le_iff_eq + exact (isNormal_add_right a).le_iff_eq @[deprecated (since := "2024-09-30")] alias add_le_right_iff_mul_omega_le := add_le_right_iff_mul_omega0_le theorem deriv_add_eq_mul_omega0_add (a b : Ordinal.{u}) : deriv (a + ·) b = a * ω + b := by revert b - rw [← funext_iff, IsNormal.eq_iff_zero_and_succ (deriv_isNormal _) (add_isNormal _)] + rw [← funext_iff, IsNormal.eq_iff_zero_and_succ (isNormal_deriv _) (isNormal_add_right _)] refine ⟨?_, fun a h => ?_⟩ · rw [deriv_zero_right, add_zero] exact nfp_add_zero a @@ -620,10 +629,10 @@ theorem nfp_mul_eq_opow_omega0 {a b : Ordinal} (hb : 0 < b) (hba : b ≤ (a ^ ω simp_rw [Ordinal.le_zero.1 hba, zero_mul] exact nfp_zero_left 0 apply le_antisymm - · apply nfp_le_fp (mul_isNormal ha).monotone hba + · apply nfp_le_fp (isNormal_mul_right ha).monotone hba rw [← opow_one_add, one_add_omega0] rw [← nfp_mul_one ha] - exact nfp_monotone (mul_isNormal ha).monotone (one_le_iff_pos.2 hb) + exact nfp_monotone (isNormal_mul_right ha).monotone (one_le_iff_pos.2 hb) @[deprecated (since := "2024-09-30")] alias nfp_mul_eq_opow_omega := nfp_mul_eq_opow_omega0 @@ -637,7 +646,7 @@ theorem eq_zero_or_opow_omega0_le_of_mul_eq_right {a b : Ordinal} (hab : a * b = intro hb rw [← nfp_mul_one ha] rw [← Ne, ← one_le_iff_ne_zero] at hb - exact nfp_le_fp (mul_isNormal ha).monotone hb (le_of_eq hab) + exact nfp_le_fp (isNormal_mul_right ha).monotone hb (le_of_eq hab) @[deprecated (since := "2024-09-30")] alias eq_zero_or_opow_omega_le_of_mul_eq_right := eq_zero_or_opow_omega0_le_of_mul_eq_right @@ -663,7 +672,7 @@ alias mul_eq_right_iff_opow_omega_dvd := mul_eq_right_iff_opow_omega0_dvd theorem mul_le_right_iff_opow_omega0_dvd {a b : Ordinal} (ha : 0 < a) : a * b ≤ b ↔ (a ^ ω) ∣ b := by rw [← mul_eq_right_iff_opow_omega0_dvd] - exact (mul_isNormal ha).le_iff_eq + exact (isNormal_mul_right ha).le_iff_eq @[deprecated (since := "2024-09-30")] alias mul_le_right_iff_opow_omega_dvd := mul_le_right_iff_opow_omega0_dvd @@ -671,12 +680,12 @@ alias mul_le_right_iff_opow_omega_dvd := mul_le_right_iff_opow_omega0_dvd theorem nfp_mul_opow_omega0_add {a c : Ordinal} (b) (ha : 0 < a) (hc : 0 < c) (hca : c ≤ a ^ ω) : nfp (a * ·) (a ^ ω * b + c) = (a ^ (ω : Ordinal.{u})) * succ b := by apply le_antisymm - · apply nfp_le_fp (mul_isNormal ha).monotone + · apply nfp_le_fp (isNormal_mul_right ha).monotone · rw [mul_succ] apply add_le_add_left hca · dsimp only; rw [← mul_assoc, ← opow_one_add, one_add_omega0] - · cases' mul_eq_right_iff_opow_omega0_dvd.1 ((mul_isNormal ha).nfp_fp ((a ^ ω) * b + c)) with - d hd + · obtain ⟨d, hd⟩ := + mul_eq_right_iff_opow_omega0_dvd.1 ((isNormal_mul_right ha).nfp_fp ((a ^ ω) * b + c)) rw [hd] apply mul_le_mul_left' have := le_nfp (a * ·) (a ^ ω * b + c) @@ -692,7 +701,7 @@ theorem deriv_mul_eq_opow_omega0_mul {a : Ordinal.{u}} (ha : 0 < a) (b) : deriv (a * ·) b = (a ^ ω) * b := by revert b rw [← funext_iff, - IsNormal.eq_iff_zero_and_succ (deriv_isNormal _) (mul_isNormal (opow_pos ω ha))] + IsNormal.eq_iff_zero_and_succ (isNormal_deriv _) (isNormal_mul_right (opow_pos ω ha))] refine ⟨?_, fun c h => ?_⟩ · dsimp only; rw [deriv_zero_right, nfp_mul_zero, mul_zero] · rw [deriv_succ, h] diff --git a/Mathlib/SetTheory/Ordinal/NaturalOps.lean b/Mathlib/SetTheory/Ordinal/NaturalOps.lean index b901e17cfa6085..3c72aeb23d13a9 100644 --- a/Mathlib/SetTheory/Ordinal/NaturalOps.lean +++ b/Mathlib/SetTheory/Ordinal/NaturalOps.lean @@ -307,7 +307,7 @@ theorem add_le_nadd : a + b ≤ a ♯ b := by | H₂ c h => rwa [add_succ, nadd_succ, succ_le_succ_iff] | H₃ c hc H => - simp_rw [← IsNormal.blsub_eq.{u, u} (add_isNormal a) hc, blsub_le_iff] + simp_rw [← IsNormal.blsub_eq.{u, u} (isNormal_add_right a) hc, blsub_le_iff] exact fun i hi => (H i hi).trans_lt (nadd_lt_nadd_left hi a) end Ordinal @@ -721,7 +721,7 @@ theorem mul_le_nmul (a b : Ordinal.{u}) : a * b ≤ a ⨳ b := by · intro c hc H rcases eq_zero_or_pos a with (rfl | ha) · simp - · rw [← IsNormal.blsub_eq.{u, u} (mul_isNormal ha) hc, blsub_le_iff] + · rw [← IsNormal.blsub_eq.{u, u} (isNormal_mul_right ha) hc, blsub_le_iff] exact fun i hi => (H i hi).trans_lt (nmul_lt_nmul_of_pos_left hi ha) @[deprecated mul_le_nmul (since := "2024-08-20")] diff --git a/Mathlib/SetTheory/Ordinal/Notation.lean b/Mathlib/SetTheory/Ordinal/Notation.lean index fd54a141e21311..0d443138f41f48 100644 --- a/Mathlib/SetTheory/Ordinal/Notation.lean +++ b/Mathlib/SetTheory/Ordinal/Notation.lean @@ -579,7 +579,7 @@ theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = rep rw [← mul_assoc] congr 2 have := mt repr_inj.1 e0 - rw [add_mul_limit ao (opow_isLimit_left omega0_isLimit this), mul_assoc, + rw [add_mul_limit ao (isLimit_opow_left omega0_isLimit this), mul_assoc, mul_omega0_dvd (natCast_pos.2 n₁.pos) (nat_lt_omega0 _)] simpa using opow_dvd_opow ω (one_le_iff_ne_zero.2 this) @@ -1031,13 +1031,13 @@ theorem fundamentalSequence_has_prop (o) : FundamentalSequenceProp o (fundamenta · exact ⟨rfl, inferInstance⟩ · have := opow_pos (repr a') omega0_pos refine - ⟨mul_isLimit this omega0_isLimit, fun i => + ⟨isLimit_mul this omega0_isLimit, fun i => ⟨this, ?_, fun H => @NF.oadd_zero _ _ (iha.2 H.fst)⟩, exists_lt_mul_omega0'⟩ rw [← mul_succ, ← natCast_succ, Ordinal.mul_lt_mul_iff_left this] apply nat_lt_omega0 · have := opow_pos (repr a') omega0_pos refine - ⟨add_isLimit _ (mul_isLimit this omega0_isLimit), fun i => ⟨this, ?_, ?_⟩, + ⟨isLimit_add _ (isLimit_mul this omega0_isLimit), fun i => ⟨this, ?_, ?_⟩, exists_lt_add exists_lt_mul_omega0'⟩ · rw [← mul_succ, ← natCast_succ, Ordinal.mul_lt_mul_iff_left this] apply nat_lt_omega0 @@ -1045,13 +1045,13 @@ theorem fundamentalSequence_has_prop (o) : FundamentalSequenceProp o (fundamenta rw [repr, ← zero_def, repr, add_zero, iha.1, opow_succ, Ordinal.mul_lt_mul_iff_left this] apply nat_lt_omega0 · rcases iha with ⟨h1, h2, h3⟩ - refine ⟨opow_isLimit one_lt_omega0 h1, fun i => ?_, + refine ⟨isLimit_opow one_lt_omega0 h1, fun i => ?_, exists_lt_omega0_opow' one_lt_omega0 h1 h3⟩ obtain ⟨h4, h5, h6⟩ := h2 i exact ⟨h4, h5, fun H => @NF.oadd_zero _ _ (h6 H.fst)⟩ · rcases iha with ⟨h1, h2, h3⟩ refine - ⟨add_isLimit _ (opow_isLimit one_lt_omega0 h1), fun i => ?_, + ⟨isLimit_add _ (isLimit_opow one_lt_omega0 h1), fun i => ?_, exists_lt_add (exists_lt_omega0_opow' one_lt_omega0 h1 h3)⟩ obtain ⟨h4, h5, h6⟩ := h2 i refine ⟨h4, h5, fun H => H.fst.oadd _ (NF.below_of_lt' ?_ (@NF.oadd_zero _ _ (h6 H.fst)))⟩ @@ -1065,7 +1065,7 @@ theorem fundamentalSequence_has_prop (o) : FundamentalSequenceProp o (fundamenta · rcases ihb with ⟨h1, h2, h3⟩ simp only [repr] exact - ⟨Ordinal.add_isLimit _ h1, fun i => + ⟨Ordinal.isLimit_add _ h1, fun i => ⟨oadd_lt_oadd_3 (h2 i).1, oadd_lt_oadd_3 (h2 i).2.1, fun H => H.fst.oadd _ (NF.below_of_lt' (lt_trans (h2 i).2.1 H.snd'.repr_lt) ((h2 i).2.2 H.snd))⟩, exists_lt_add h3⟩ diff --git a/Mathlib/SetTheory/Ordinal/Principal.lean b/Mathlib/SetTheory/Ordinal/Principal.lean index 2835fd286b3f39..1f7d12231c7428 100644 --- a/Mathlib/SetTheory/Ordinal/Principal.lean +++ b/Mathlib/SetTheory/Ordinal/Principal.lean @@ -139,13 +139,13 @@ theorem principal_add_iff_add_left_eq_self {o : Ordinal} : Principal (· + ·) o ↔ ∀ a < o, a + o = o := by refine ⟨fun ho a hao => ?_, fun h a b hao hbo => ?_⟩ · cases' lt_or_le 1 o with ho₁ ho₁ - · exact op_eq_self_of_principal hao (add_isNormal a) ho (principal_add_isLimit ho₁ ho) + · exact op_eq_self_of_principal hao (isNormal_add_right a) ho (principal_add_isLimit ho₁ ho) · rcases le_one_iff.1 ho₁ with (rfl | rfl) · exact (Ordinal.not_lt_zero a hao).elim · rw [lt_one_iff_zero] at hao rw [hao, zero_add] · rw [← h a hao] - exact (add_isNormal a).strictMono hbo + exact (isNormal_add_right a).strictMono hbo theorem exists_lt_add_of_not_principal_add {a} (ha : ¬Principal (· + ·) a) : ∃ b < a, ∃ c < a, b + c = a := by @@ -188,7 +188,7 @@ theorem add_omega0_opow {a b : Ordinal} (h : a < ω ^ b) : a + ω ^ b = ω ^ b : apply (add_le_add_right ax.le _).trans rw [opow_succ, ← mul_add, add_omega0 xo] · rcases (lt_opow_of_limit omega0_ne_zero l).1 h with ⟨x, xb, ax⟩ - apply (((add_isNormal a).trans <| opow_isNormal one_lt_omega0).limit_le l).2 + apply (((isNormal_add_right a).trans <| isNormal_opow one_lt_omega0).limit_le l).2 intro y yb calc a + ω ^ y ≤ a + ω ^ max x y := add_le_add_left (opow_le_opow_right omega0_pos (le_max_right x y)) _ @@ -310,12 +310,12 @@ theorem principal_mul_iff_mul_left_eq {o : Ordinal} : · have : a < succ 1 := hao.trans_le (by simpa using ho) rwa [lt_succ_iff] at this · rwa [← succ_le_iff, succ_zero] at ha₀ - · exact op_eq_self_of_principal hao (mul_isNormal ha₀) h (principal_mul_isLimit ho h) + · exact op_eq_self_of_principal hao (isNormal_mul_right ha₀) h (principal_mul_isLimit ho h) · rcases eq_or_ne a 0 with (rfl | ha) · dsimp only; rwa [zero_mul] rw [← Ordinal.pos_iff_ne_zero] at ha rw [← h a ha hao] - exact (mul_isNormal ha).strictMono hbo + exact (isNormal_mul_right ha).strictMono hbo theorem principal_mul_omega0 : Principal (· * ·) ω := fun a b ha hb => match a, b, lt_omega0.1 ha, lt_omega0.1 hb with @@ -337,11 +337,12 @@ theorem mul_lt_omega0_opow {a b c : Ordinal} (c0 : 0 < c) (ha : a < ω ^ c) (hb rcases zero_or_succ_or_limit c with (rfl | ⟨c, rfl⟩ | l) · exact (lt_irrefl _).elim c0 · rw [opow_succ] at ha - rcases ((mul_isNormal <| opow_pos _ omega0_pos).limit_lt omega0_isLimit).1 ha with ⟨n, hn, an⟩ + obtain ⟨n, hn, an⟩ := + ((isNormal_mul_right <| opow_pos _ omega0_pos).limit_lt omega0_isLimit).1 ha apply (mul_le_mul_right' (le_of_lt an) _).trans_lt rw [opow_succ, mul_assoc, mul_lt_mul_iff_left (opow_pos _ omega0_pos)] exact principal_mul_omega0 hn hb - · rcases ((opow_isNormal one_lt_omega0).limit_lt l).1 ha with ⟨x, hx, ax⟩ + · rcases ((isNormal_opow one_lt_omega0).limit_lt l).1 ha with ⟨x, hx, ax⟩ refine (mul_le_mul' (le_of_lt ax) (le_of_lt hb)).trans_lt ?_ rw [← opow_succ, opow_lt_opow_iff_right one_lt_omega0] exact l.2 _ hx @@ -356,7 +357,7 @@ theorem mul_omega0_opow_opow {a b : Ordinal} (a0 : 0 < a) (h : a < ω ^ ω ^ b) exact mul_omega0 a0 h · apply le_antisymm · obtain ⟨x, xb, ax⟩ := - (lt_opow_of_limit omega0_ne_zero (opow_isLimit_left omega0_isLimit b0)).1 h + (lt_opow_of_limit omega0_ne_zero (isLimit_opow_left omega0_isLimit b0)).1 h apply (mul_le_mul_right' (le_of_lt ax) _).trans rw [← opow_add, add_omega0_opow xb] · conv_lhs => rw [← one_mul (ω ^ _)] @@ -408,7 +409,7 @@ theorem mul_eq_opow_log_succ {a b : Ordinal.{u}} (ha : a ≠ 0) (hb : Principal (hb₂ : 2 < b) : a * b = b ^ succ (log b a) := by apply le_antisymm · have hbl := principal_mul_isLimit hb₂ hb - rw [← IsNormal.bsup_eq.{u, u} (mul_isNormal (Ordinal.pos_iff_ne_zero.2 ha)) hbl, bsup_le_iff] + rw [← (isNormal_mul_right (Ordinal.pos_iff_ne_zero.2 ha)).bsup_eq hbl, bsup_le_iff] intro c hcb have hb₁ : 1 < b := (lt_succ 1).trans (by rwa [succ_one]) have hbo₀ : b ^ log b a ≠ 0 := Ordinal.pos_iff_ne_zero.1 (opow_pos _ (zero_lt_one.trans hb₁)) From 6694638ec7db7087c21403c7d61e84b306f91298 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Mon, 14 Oct 2024 21:00:09 +1100 Subject: [PATCH 097/425] fix test for leanprover/lean4#5694 --- test/DefEqTransformations.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/DefEqTransformations.lean b/test/DefEqTransformations.lean index 496e641a680f8f..095b6a8bf70920 100644 --- a/test/DefEqTransformations.lean +++ b/test/DefEqTransformations.lean @@ -119,7 +119,7 @@ example : 1 + 2 = 2 + 1 := by example (m n : Nat) : (m == n) = true := by unfold_projs - guard_target =ₛ Nat.beq m n = true + guard_target =ₛ decide (m = n) = true exact test_sorry example {α : Type u} (f : α → α) (a : α) : From a7672918e6047be4231ba32048dc5a4a1f2c237c Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Mon, 14 Oct 2024 10:01:51 +0000 Subject: [PATCH 098/425] feat(CompleteLattice): add `iSup_image2` (#17705) --- Mathlib/Order/CompleteLattice.lean | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Mathlib/Order/CompleteLattice.lean b/Mathlib/Order/CompleteLattice.lean index 9e2df5ddb29f1f..87517a17d75440 100644 --- a/Mathlib/Order/CompleteLattice.lean +++ b/Mathlib/Order/CompleteLattice.lean @@ -1227,7 +1227,8 @@ theorem iInf_pair {f : β → α} {a b : β} : ⨅ x ∈ ({a, b} : Set β), f x rw [iInf_insert, iInf_singleton] theorem iSup_image {γ} {f : β → γ} {g : γ → α} {t : Set β} : - ⨆ c ∈ f '' t, g c = ⨆ b ∈ t, g (f b) := by rw [← sSup_image, ← sSup_image, ← image_comp]; rfl + ⨆ c ∈ f '' t, g c = ⨆ b ∈ t, g (f b) := by + rw [← sSup_image, ← sSup_image, ← image_comp, comp_def] theorem iInf_image : ∀ {γ} {f : β → γ} {g : γ → α} {t : Set β}, ⨅ c ∈ f '' t, g c = ⨅ b ∈ t, g (f b) := @@ -1326,6 +1327,14 @@ theorem biInf_prod {f : β × γ → α} {s : Set β} {t : Set γ} : ⨅ x ∈ s ×ˢ t, f x = ⨅ (a ∈ s) (b ∈ t), f (a, b) := @biSup_prod αᵒᵈ _ _ _ _ _ _ +theorem iSup_image2 {γ δ} (f : β → γ → δ) (s : Set β) (t : Set γ) (g : δ → α) : + ⨆ d ∈ image2 f s t, g d = ⨆ b ∈ s, ⨆ c ∈ t, g (f b c) := by + rw [← image_prod, iSup_image, biSup_prod] + +theorem iInf_image2 {γ δ} (f : β → γ → δ) (s : Set β) (t : Set γ) (g : δ → α) : + ⨅ d ∈ image2 f s t, g d = ⨅ b ∈ s, ⨅ c ∈ t, g (f b c) := + iSup_image2 f s t (toDual ∘ g) + theorem iSup_sum {f : β ⊕ γ → α} : ⨆ x, f x = (⨆ i, f (Sum.inl i)) ⊔ ⨆ j, f (Sum.inr j) := eq_of_forall_ge_iff fun c => by simp only [sup_le_iff, iSup_le_iff, Sum.forall] From 6f6340442790cd33e43fe67eb4c97f3adc27d202 Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Mon, 14 Oct 2024 10:32:40 +0000 Subject: [PATCH 099/425] Update lean-toolchain for testing https://github.com/leanprover/lean4/pull/5703 --- lake-manifest.json | 4 ++-- lakefile.lean | 2 +- lean-toolchain | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index 140811af6321f0..d2dbd724a5f1cd 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,10 +5,10 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "daf1ed91789811cf6bbb7bf2f4dad6b3bad8fbf4", + "rev": "f54b701214b344f80234823ec8216e6a89f335b3", "name": "batteries", "manifestFile": "lake-manifest.json", - "inputRev": "main", + "inputRev": "lean-pr-testing-5703", "inherited": false, "configFile": "lakefile.lean"}, {"url": "https://github.com/leanprover-community/quote4", diff --git a/lakefile.lean b/lakefile.lean index a4a09667f6c2b7..bed7b948d3ca39 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -7,7 +7,7 @@ open Lake DSL ## Mathlib dependencies on upstream projects -/ -require "leanprover-community" / "batteries" @ git "main" +require "leanprover-community" / "batteries" @ git "lean-pr-testing-5703" require "leanprover-community" / "Qq" @ git "master" require "leanprover-community" / "aesop" @ git "master" require "leanprover-community" / "proofwidgets" @ git "v0.0.43-pre" diff --git a/lean-toolchain b/lean-toolchain index 30684366328531..ddc5d58408618f 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-13 +leanprover/lean4-pr-releases:pr-release-5703 From c6981000727fad47176ffe74ede4355b1804ceda Mon Sep 17 00:00:00 2001 From: grhkm21 Date: Mon, 14 Oct 2024 10:52:08 +0000 Subject: [PATCH 100/425] refactor(CharP): make variables explicit + refactor (#14416) Follows up on Yael's comment in #8612 by making `n` (in `x ^ (p ^ n)`) explicit. Co-authored-by: Jeremy Tan Jie Rui --- Mathlib/Algebra/CharP/Basic.lean | 61 +++++++++++----------- Mathlib/Algebra/CharP/ExpChar.lean | 10 ++-- Mathlib/Data/Nat/Choose/Lucas.lean | 2 +- Mathlib/RingTheory/Polynomial/Dickson.lean | 5 +- 4 files changed, 39 insertions(+), 39 deletions(-) diff --git a/Mathlib/Algebra/CharP/Basic.lean b/Mathlib/Algebra/CharP/Basic.lean index af8e256be0815f..6440a87f6d3247 100644 --- a/Mathlib/Algebra/CharP/Basic.lean +++ b/Mathlib/Algebra/CharP/Basic.lean @@ -21,9 +21,10 @@ variable {R : Type*} namespace Commute -variable [Semiring R] {p : ℕ} {x y : R} +variable [Semiring R] {p : ℕ} (hp : p.Prime) {x y : R} +include hp -protected theorem add_pow_prime_pow_eq (hp : p.Prime) (h : Commute x y) (n : ℕ) : +protected theorem add_pow_prime_pow_eq (h : Commute x y) (n : ℕ) : (x + y) ^ p ^ n = x ^ p ^ n + y ^ p ^ n + p * ∑ k ∈ Ioo 0 (p ^ n), x ^ k * y ^ (p ^ n - k) * ↑((p ^ n).choose k / p) := by @@ -37,16 +38,16 @@ protected theorem add_pow_prime_pow_eq (hp : p.Prime) (h : Commute x y) (n : ℕ rw [mem_Ioo] at hi rw [Nat.div_mul_cancel (hp.dvd_choose_pow hi.1.ne' hi.2.ne)] -protected theorem add_pow_prime_eq (hp : p.Prime) (h : Commute x y) : +protected theorem add_pow_prime_eq (h : Commute x y) : (x + y) ^ p = x ^ p + y ^ p + p * ∑ k ∈ Finset.Ioo 0 p, x ^ k * y ^ (p - k) * ↑(p.choose k / p) := by simpa using h.add_pow_prime_pow_eq hp 1 -protected theorem exists_add_pow_prime_pow_eq (hp : p.Prime) (h : Commute x y) (n : ℕ) : +protected theorem exists_add_pow_prime_pow_eq (h : Commute x y) (n : ℕ) : ∃ r, (x + y) ^ p ^ n = x ^ p ^ n + y ^ p ^ n + p * r := ⟨_, h.add_pow_prime_pow_eq hp n⟩ -protected theorem exists_add_pow_prime_eq (hp : p.Prime) (h : Commute x y) : +protected theorem exists_add_pow_prime_eq (h : Commute x y) : ∃ r, (x + y) ^ p = x ^ p + y ^ p + p * r := ⟨_, h.add_pow_prime_eq hp⟩ @@ -54,92 +55,92 @@ end Commute section CommSemiring -variable [CommSemiring R] {p : ℕ} {x y : R} +variable [CommSemiring R] {p : ℕ} (hp : p.Prime) (x y : R) (n : ℕ) +include hp -theorem add_pow_prime_pow_eq (hp : p.Prime) (x y : R) (n : ℕ) : +theorem add_pow_prime_pow_eq : (x + y) ^ p ^ n = x ^ p ^ n + y ^ p ^ n + p * ∑ k ∈ Finset.Ioo 0 (p ^ n), x ^ k * y ^ (p ^ n - k) * ↑((p ^ n).choose k / p) := (Commute.all x y).add_pow_prime_pow_eq hp n -theorem add_pow_prime_eq (hp : p.Prime) (x y : R) : +theorem add_pow_prime_eq : (x + y) ^ p = x ^ p + y ^ p + p * ∑ k ∈ Finset.Ioo 0 p, x ^ k * y ^ (p - k) * ↑(p.choose k / p) := (Commute.all x y).add_pow_prime_eq hp -theorem exists_add_pow_prime_pow_eq (hp : p.Prime) (x y : R) (n : ℕ) : +theorem exists_add_pow_prime_pow_eq : ∃ r, (x + y) ^ p ^ n = x ^ p ^ n + y ^ p ^ n + p * r := (Commute.all x y).exists_add_pow_prime_pow_eq hp n -theorem exists_add_pow_prime_eq (hp : p.Prime) (x y : R) : +theorem exists_add_pow_prime_eq : ∃ r, (x + y) ^ p = x ^ p + y ^ p + p * r := (Commute.all x y).exists_add_pow_prime_eq hp end CommSemiring -variable (R) +variable (R) (x y : R) (n : ℕ) -theorem add_pow_char_of_commute [Semiring R] {p : ℕ} [hp : Fact p.Prime] [CharP R p] (x y : R) +theorem add_pow_char_of_commute [Semiring R] {p : ℕ} [hp : Fact p.Prime] [CharP R p] (h : Commute x y) : (x + y) ^ p = x ^ p + y ^ p := by let ⟨r, hr⟩ := h.exists_add_pow_prime_eq hp.out simp [hr] -theorem add_pow_char_pow_of_commute [Semiring R] {p n : ℕ} [hp : Fact p.Prime] [CharP R p] - (x y : R) (h : Commute x y) : (x + y) ^ p ^ n = x ^ p ^ n + y ^ p ^ n := by +theorem add_pow_char_pow_of_commute [Semiring R] {p : ℕ} [hp : Fact p.Prime] [CharP R p] + (h : Commute x y) : (x + y) ^ p ^ n = x ^ p ^ n + y ^ p ^ n := by let ⟨r, hr⟩ := h.exists_add_pow_prime_pow_eq hp.out n simp [hr] -theorem sub_pow_char_of_commute [Ring R] {p : ℕ} [Fact p.Prime] [CharP R p] (x y : R) - (h : Commute x y) : (x - y) ^ p = x ^ p - y ^ p := by +theorem sub_pow_char_of_commute [Ring R] {p : ℕ} [Fact p.Prime] [CharP R p] (h : Commute x y) : + (x - y) ^ p = x ^ p - y ^ p := by rw [eq_sub_iff_add_eq, ← add_pow_char_of_commute _ _ _ (Commute.sub_left h rfl)] simp -theorem sub_pow_char_pow_of_commute [Ring R] {p : ℕ} [Fact p.Prime] [CharP R p] {n : ℕ} (x y : R) - (h : Commute x y) : (x - y) ^ p ^ n = x ^ p ^ n - y ^ p ^ n := by +theorem sub_pow_char_pow_of_commute [Ring R] {p : ℕ} [Fact p.Prime] [CharP R p] (h : Commute x y) : + (x - y) ^ p ^ n = x ^ p ^ n - y ^ p ^ n := by induction n with | zero => simp | succ n n_ih => rw [pow_succ, pow_mul, pow_mul, pow_mul, n_ih] apply sub_pow_char_of_commute; apply Commute.pow_pow h -theorem add_pow_char [CommSemiring R] {p : ℕ} [Fact p.Prime] [CharP R p] (x y : R) : +theorem add_pow_char [CommSemiring R] {p : ℕ} [Fact p.Prime] [CharP R p] : (x + y) ^ p = x ^ p + y ^ p := add_pow_char_of_commute _ _ _ (Commute.all _ _) -theorem add_pow_char_pow [CommSemiring R] {p : ℕ} [Fact p.Prime] [CharP R p] {n : ℕ} (x y : R) : +theorem add_pow_char_pow [CommSemiring R] {p : ℕ} [Fact p.Prime] [CharP R p] : (x + y) ^ p ^ n = x ^ p ^ n + y ^ p ^ n := - add_pow_char_pow_of_commute _ _ _ (Commute.all _ _) + add_pow_char_pow_of_commute _ _ _ _ (Commute.all _ _) theorem add_pow_eq_add_pow_mod_mul_pow_add_pow_div - [CommSemiring R] {p : ℕ} [Fact p.Prime] [CharP R p] {n : ℕ} (x y : R) : + [CommSemiring R] {p : ℕ} [Fact p.Prime] [CharP R p] (x y : R) : (x + y) ^ n = (x + y) ^ (n % p) * (x ^ p + y ^ p) ^ (n / p) := by rw [← add_pow_char, ← pow_mul, ← pow_add, Nat.mod_add_div] -theorem sub_pow_char [CommRing R] {p : ℕ} [Fact p.Prime] [CharP R p] (x y : R) : +theorem sub_pow_char [CommRing R] {p : ℕ} [Fact p.Prime] [CharP R p] : (x - y) ^ p = x ^ p - y ^ p := sub_pow_char_of_commute _ _ _ (Commute.all _ _) -theorem sub_pow_char_pow [CommRing R] {p : ℕ} [Fact p.Prime] [CharP R p] {n : ℕ} (x y : R) : +theorem sub_pow_char_pow [CommRing R] {p : ℕ} [Fact p.Prime] [CharP R p] : (x - y) ^ p ^ n = x ^ p ^ n - y ^ p ^ n := - sub_pow_char_pow_of_commute _ _ _ (Commute.all _ _) + sub_pow_char_pow_of_commute _ _ _ _ (Commute.all _ _) -theorem sub_pow_eq_sub_pow_mod_mul_pow_sub_pow_div - [CommRing R] {p : ℕ} [Fact p.Prime] [CharP R p] {n : ℕ} (x y : R) : +theorem sub_pow_eq_sub_pow_mod_mul_pow_sub_pow_div [CommRing R] {p : ℕ} [Fact p.Prime] [CharP R p] : (x - y) ^ n = (x - y) ^ (n % p) * (x ^ p - y ^ p) ^ (n / p) := by rw [← sub_pow_char, ← pow_mul, ← pow_add, Nat.mod_add_div] -theorem CharP.neg_one_pow_char [Ring R] (p : ℕ) [CharP R p] [Fact p.Prime] : +theorem CharP.neg_one_pow_char [Ring R] (p : ℕ) [Fact p.Prime] [CharP R p] : (-1 : R) ^ p = -1 := by rw [eq_neg_iff_add_eq_zero] nth_rw 2 [← one_pow p] rw [← add_pow_char_of_commute R _ _ (Commute.one_right _), neg_add_cancel, zero_pow (Fact.out (p := Nat.Prime p)).ne_zero] -theorem CharP.neg_one_pow_char_pow [Ring R] (p n : ℕ) [CharP R p] [Fact p.Prime] : +theorem CharP.neg_one_pow_char_pow [Ring R] (p : ℕ) [CharP R p] [Fact p.Prime] : (-1 : R) ^ p ^ n = -1 := by rw [eq_neg_iff_add_eq_zero] nth_rw 2 [← one_pow (p ^ n)] - rw [← add_pow_char_pow_of_commute R _ _ (Commute.one_right _), neg_add_cancel, + rw [← add_pow_char_pow_of_commute R _ _ _ (Commute.one_right _), neg_add_cancel, zero_pow (pow_ne_zero _ (Fact.out (p := Nat.Prime p)).ne_zero)] namespace CharP diff --git a/Mathlib/Algebra/CharP/ExpChar.lean b/Mathlib/Algebra/CharP/ExpChar.lean index 3c3955406e021e..24ac40fe6a5e29 100644 --- a/Mathlib/Algebra/CharP/ExpChar.lean +++ b/Mathlib/Algebra/CharP/ExpChar.lean @@ -207,7 +207,7 @@ theorem add_pow_expChar_pow_of_commute [Semiring R] {q : ℕ} [hR : ExpChar R q] {n : ℕ} (x y : R) (h : Commute x y) : (x + y) ^ q ^ n = x ^ q ^ n + y ^ q ^ n := by rcases hR with _ | hprime · simp only [one_pow, pow_one] - haveI := Fact.mk hprime; exact add_pow_char_pow_of_commute R x y h + haveI := Fact.mk hprime; exact add_pow_char_pow_of_commute R x y n h theorem sub_pow_expChar_of_commute [Ring R] {q : ℕ} [hR : ExpChar R q] (x y : R) (h : Commute x y) : (x - y) ^ q = x ^ q - y ^ q := by @@ -219,7 +219,7 @@ theorem sub_pow_expChar_pow_of_commute [Ring R] {q : ℕ} [hR : ExpChar R q] {n : ℕ} (x y : R) (h : Commute x y) : (x - y) ^ q ^ n = x ^ q ^ n - y ^ q ^ n := by rcases hR with _ | hprime · simp only [one_pow, pow_one] - haveI := Fact.mk hprime; exact sub_pow_char_pow_of_commute R x y h + haveI := Fact.mk hprime; exact sub_pow_char_pow_of_commute R x y n h theorem add_pow_expChar [CommSemiring R] {q : ℕ} [hR : ExpChar R q] (x y : R) : (x + y) ^ q = x ^ q + y ^ q := by @@ -231,7 +231,7 @@ theorem add_pow_expChar_pow [CommSemiring R] {q : ℕ} [hR : ExpChar R q] {n : ℕ} (x y : R) : (x + y) ^ q ^ n = x ^ q ^ n + y ^ q ^ n := by rcases hR with _ | hprime · simp only [one_pow, pow_one] - haveI := Fact.mk hprime; exact add_pow_char_pow R x y + haveI := Fact.mk hprime; exact add_pow_char_pow R x y n theorem sub_pow_expChar [CommRing R] {q : ℕ} [hR : ExpChar R q] (x y : R) : (x - y) ^ q = x ^ q - y ^ q := by @@ -243,7 +243,7 @@ theorem sub_pow_expChar_pow [CommRing R] {q : ℕ} [hR : ExpChar R q] {n : ℕ} (x y : R) : (x - y) ^ q ^ n = x ^ q ^ n - y ^ q ^ n := by rcases hR with _ | hprime · simp only [one_pow, pow_one] - haveI := Fact.mk hprime; exact sub_pow_char_pow R x y + haveI := Fact.mk hprime; exact sub_pow_char_pow R x y n theorem ExpChar.neg_one_pow_expChar [Ring R] (q : ℕ) [hR : ExpChar R q] : (-1 : R) ^ q = -1 := by @@ -255,7 +255,7 @@ theorem ExpChar.neg_one_pow_expChar_pow [Ring R] (q n : ℕ) [hR : ExpChar R q] (-1 : R) ^ q ^ n = -1 := by rcases hR with _ | hprime · simp only [one_pow, pow_one] - haveI := Fact.mk hprime; exact CharP.neg_one_pow_char_pow R q n + haveI := Fact.mk hprime; exact CharP.neg_one_pow_char_pow R n q section frobenius diff --git a/Mathlib/Data/Nat/Choose/Lucas.lean b/Mathlib/Data/Nat/Choose/Lucas.lean index ed558834148908..94e97c1f452af2 100644 --- a/Mathlib/Data/Nat/Choose/Lucas.lean +++ b/Mathlib/Data/Nat/Choose/Lucas.lean @@ -33,7 +33,7 @@ modulo `p`. Also see `choose_modEq_choose_mod_mul_choose_div_nat` for the versio theorem choose_modEq_choose_mod_mul_choose_div : choose n k ≡ choose (n % p) (k % p) * choose (n / p) (k / p) [ZMOD p] := by have decompose : ((X : (ZMod p)[X]) + 1) ^ n = (X + 1) ^ (n % p) * (X ^ p + 1) ^ (n / p) := by - simpa using add_pow_eq_add_pow_mod_mul_pow_add_pow_div _ (X : (ZMod p)[X]) 1 + simpa using add_pow_eq_add_pow_mod_mul_pow_add_pow_div _ n (X : (ZMod p)[X]) 1 simp only [← ZMod.intCast_eq_intCast_iff, Int.cast_mul, Int.cast_ofNat, ← coeff_X_add_one_pow _ n k, ← eq_intCast (Int.castRingHom (ZMod p)), ← coeff_map, Polynomial.map_pow, Polynomial.map_add, Polynomial.map_one, map_X, decompose] diff --git a/Mathlib/RingTheory/Polynomial/Dickson.lean b/Mathlib/RingTheory/Polynomial/Dickson.lean index fdb6b3b533b34a..73b4540c4c50bc 100644 --- a/Mathlib/RingTheory/Polynomial/Dickson.lean +++ b/Mathlib/RingTheory/Polynomial/Dickson.lean @@ -200,9 +200,8 @@ 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, @add_pow_char K _ p, - dickson_one_one_eval_add_inv _ _ (mul_inv_cancel₀ hx), inv_pow, ZMod.castHom_apply, - ZMod.cast_one'] + simp only [eval_X, eval_pow, Set.mem_setOf_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. · intro h From cb3a2f9abefa51c42fe965d53a78974abc2fbc6c Mon Sep 17 00:00:00 2001 From: Jujian Zhang Date: Mon, 14 Oct 2024 11:21:01 +0000 Subject: [PATCH 101/425] feat(Algebra/Central): definition of central simple algebra (#16856) Co-authored-by: zjj --- Mathlib.lean | 2 + Mathlib/Algebra/Central/Basic.lean | 56 +++++++++++++++++++++++++ Mathlib/Algebra/Central/Defs.lean | 66 ++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 Mathlib/Algebra/Central/Basic.lean create mode 100644 Mathlib/Algebra/Central/Defs.lean diff --git a/Mathlib.lean b/Mathlib.lean index 3297901061da40..fca4baff8f9b43 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -145,6 +145,8 @@ import Mathlib.Algebra.Category.Ring.FilteredColimits import Mathlib.Algebra.Category.Ring.Instances import Mathlib.Algebra.Category.Ring.Limits import Mathlib.Algebra.Category.Semigrp.Basic +import Mathlib.Algebra.Central.Basic +import Mathlib.Algebra.Central.Defs import Mathlib.Algebra.CharP.Algebra import Mathlib.Algebra.CharP.Basic import Mathlib.Algebra.CharP.CharAndCard diff --git a/Mathlib/Algebra/Central/Basic.lean b/Mathlib/Algebra/Central/Basic.lean new file mode 100644 index 00000000000000..b2aedab38df075 --- /dev/null +++ b/Mathlib/Algebra/Central/Basic.lean @@ -0,0 +1,56 @@ +/- +Copyright (c) 2024 Jujian Zhang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jujian Zhang +-/ + +import Mathlib.Algebra.Central.Defs + +/-! +# Central Algebras + +In this file, we prove some basic results about central algebras over a commutative ring. + +## Main results + +- `Algebra.IsCentral.center_eq_bot`: the center of a central algebra over `K` is equal to `K`. +- `Algebra.IsCentral.self`: a commutative ring is a central algebra over itself. +- `Algebra.IsCentral.baseField_essentially_unique`: Let `D/K/k` is a tower of scalars where + `K` and `k` are fields. If `D` is a nontrivial central algebra over `k`, `K` is isomorphic to `k`. +-/ + +universe u v + +namespace Algebra.IsCentral + +variable (K : Type u) [CommSemiring K] (D : Type v) [Semiring D] [Algebra K D] [IsCentral K D] + +@[simp] +lemma center_eq_bot : Subalgebra.center K D = ⊥ := eq_bot_iff.2 IsCentral.out + +variable {D} in +lemma mem_center_iff {x : D} : x ∈ Subalgebra.center K D ↔ ∃ (a : K), x = algebraMap K D a := by + rw [center_eq_bot, Algebra.mem_bot] + simp [eq_comm] + +instance self : IsCentral K K where + out x := by simp [Algebra.mem_bot] + +lemma baseField_essentially_unique + (k K D : Type*) [Field k] [Field K] [Ring D] [Nontrivial D] + [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 := + { 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 + exact ⟨algebraMap k K x, by simp [algebraMap_eq_smul_one, smul_assoc]⟩ } + refine ⟨NoZeroSMulDivisors.algebraMap_injective k K, fun x => ?_⟩ + have H : algebraMap K D x ∈ (Subalgebra.center K D : Set D) := Subalgebra.algebraMap_mem _ _ + rw [show (Subalgebra.center K D : Set D) = Subalgebra.center k D by rfl] at H + simp only [center_eq_bot, coe_bot, Set.mem_range] at H + obtain ⟨x', H⟩ := H + exact ⟨x', (algebraMap K D).injective <| by simp [← H, algebraMap_eq_smul_one]⟩ + +end Algebra.IsCentral diff --git a/Mathlib/Algebra/Central/Defs.lean b/Mathlib/Algebra/Central/Defs.lean new file mode 100644 index 00000000000000..c88a10b8b3abaf --- /dev/null +++ b/Mathlib/Algebra/Central/Defs.lean @@ -0,0 +1,66 @@ +/- +Copyright (c) 2024 Jujian Zhang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jujian Zhang +-/ + +import Mathlib.Algebra.Algebra.Subalgebra.Basic + +/-! +# Central Algebras + +In this file we define the predicate `Algebra.IsCentral K D` where `K` is a commutative ring and `D` +is a (not necessarily commutative) `K`-algebra. + +## Main definitions + +- `Algebra.IsCentral K D` : `D` is a central algebra over `K` iff the center of `D` is exactly `K`. + +## Implementation notes + +We require the `K`-center of `D` to be smaller than or equal to the smallest subalgebra so that when +we prove something is central, there we don't need to prove `⊥ ≤ center K D` even though this +direction is trivial. + +### Central Simple Algebras + +To define central simple algebras, we could do the following: +```lean +class Algebra.IsCentralSimple (K : Type u) [Field K] (D : Type v) [Ring D] [Algebra K D] where + [is_central : IsCentral K D] + [is_simple : IsSimpleRing D] +``` +but an instance of `[Algebra.IsCentralSimple K D]` would not imply `[IsSimpleRing D]` because of +synthesization orders (`K` cannot be inferred). Thus, to obtain a central simple `K`-algebra `D`, +one should use `Algebra.IsCentral K D` and `IsSimpleRing D` separately. + +Note that the predicate `Albgera.IsCentral K D` and `IsSimpleRing D` makes sense just for `K` a +`CommRing` but it doesn't give the right definition for central simple algebra; for a commutative +ring base, one should use the theory of Azumaya algebras. In fact ideals of `K` immediately give +rise to nontrivial quotients of `D` so there are no central simple algebras in this case according +to our definition, if K is not a field. +The theory of central simple algebras really is a theory over fields. + +Thus to declare a central simple algebra, one should use the following: +```lean +variable (k D : Type*) [Field k] [Ring D] [Algebra k D] +variable [Algebra.IsCentral k D] [IsSimpleRing D] +variable [FiniteDimensional k D] +``` +where `FiniteDimensional k D` is almost always assumed in most references, but some results does not +need this assumption. + +## Tags +central algebra, center, simple ring, central simple algebra + +-/ + +universe u v + +/-- +For a commutative ring `K` and a `K`-algebra `D`, we say that `D` is a central algebra over `K` if +the center of `D` is the image of `K` in `D`. +-/ +class Algebra.IsCentral + (K : Type u) [CommSemiring K] (D : Type v) [Semiring D] [Algebra K D] : Prop where + out : Subalgebra.center K D ≤ ⊥ From 46734ac514fecfeb6a423c3065baecee4eb8acdd Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Mon, 14 Oct 2024 22:44:31 +1100 Subject: [PATCH 102/425] bump batteries for leanprover/lean4#5703 --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index d2dbd724a5f1cd..7eaaf938079bda 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "f54b701214b344f80234823ec8216e6a89f335b3", + "rev": "97dd02816cbdc4c0152a4d2e863b6297cbcc36c4", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "lean-pr-testing-5703", From e1266368eec600c9a80782e9e8d31dbbba1ca49b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Calle=20S=C3=B6nne?= Date: Mon, 14 Oct 2024 11:53:14 +0000 Subject: [PATCH 103/425] feat(CategoryTheory/Limits): Add basic pullback lemmas (#17685) This PR adds some basic lemmas about pullbacks of a monos/epi by itself. This is used in #14208. --- Mathlib/CategoryTheory/CommSq.lean | 13 ++++ Mathlib/CategoryTheory/Galois/Basic.lean | 2 +- .../Limits/Shapes/Pullback/CommSq.lean | 35 ++++++++-- .../Limits/Shapes/Pullback/Mono.lean | 69 +++++++++++++------ 4 files changed, 89 insertions(+), 30 deletions(-) diff --git a/Mathlib/CategoryTheory/CommSq.lean b/Mathlib/CategoryTheory/CommSq.lean index f40df65859a4d9..fedadf5d160910 100644 --- a/Mathlib/CategoryTheory/CommSq.lean +++ b/Mathlib/CategoryTheory/CommSq.lean @@ -109,6 +109,19 @@ lemma vert_comp {W X Y Y' Z Z' : C} {f : W ⟶ X} {g : W ⟶ Y} {g' : Y ⟶ Y'} CommSq f (g ≫ g') (h ≫ h') i' := flip (horiz_comp (flip hsq₁) (flip hsq₂)) + +section + +variable {W X Y : C} + +theorem eq_of_mono {f : W ⟶ X} {g : W ⟶ X} {i : X ⟶ Y} [Mono i] (sq : CommSq f g i i) : f = g := + (cancel_mono i).1 sq.w + +theorem eq_of_epi {f : W ⟶ X} {h : X ⟶ Y} {i : X ⟶ Y} [Epi f] (sq : CommSq f f h i) : h = i := + (cancel_epi f).1 sq.w + +end + end CommSq namespace Functor diff --git a/Mathlib/CategoryTheory/Galois/Basic.lean b/Mathlib/CategoryTheory/Galois/Basic.lean index a0cd79ac0d2fe2..77db617102e028 100644 --- a/Mathlib/CategoryTheory/Galois/Basic.lean +++ b/Mathlib/CategoryTheory/Galois/Basic.lean @@ -149,7 +149,7 @@ noncomputable instance {G : Type*} [Group G] [Finite G] : instance : ReflectsMonomorphisms F := ReflectsMonomorphisms.mk <| by intro X Y f _ haveI : IsIso (pullback.fst (F.map f) (F.map f)) := - fst_iso_of_mono_eq (F.map f) + isIso_fst_of_mono (F.map f) haveI : IsIso (F.map (pullback.fst f f)) := by rw [← PreservesPullback.iso_hom_fst] exact IsIso.comp_isIso diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/CommSq.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/CommSq.lean index 423fed53f4080e..978cc03484cb2c 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/CommSq.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/CommSq.lean @@ -3,12 +3,9 @@ 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 -/ -import Mathlib.CategoryTheory.CommSq -import Mathlib.CategoryTheory.Limits.Opposites -import Mathlib.CategoryTheory.Limits.Shapes.Biproducts -import Mathlib.CategoryTheory.Limits.Shapes.ZeroMorphisms -import Mathlib.CategoryTheory.Limits.Constructions.BinaryProducts + import Mathlib.CategoryTheory.Limits.Constructions.ZeroObjects +import Mathlib.CategoryTheory.Limits.Shapes.Biproducts import Mathlib.CategoryTheory.Limits.Shapes.Pullback.Pasting /-! @@ -23,7 +20,7 @@ We provide another API for pullbacks and pushouts. snd f | | v v - Y ---g---> Zfst + Y ---g---> Z ``` is a pullback square. @@ -270,7 +267,7 @@ theorem of_hasBinaryProduct [HasBinaryProduct X Y] [HasZeroObject C] [HasZeroMor section -variable {P': C} {fst' : P' ⟶ X} {snd' : P' ⟶ Y} +variable {P' : C} {fst' : P' ⟶ X} {snd' : P' ⟶ Y} /-- Any object at the top left of a pullback square is isomorphic to the object at the top left of any other pullback square with the same cospan. -/ @@ -362,6 +359,18 @@ lemma of_iso (h : IsPullback fst snd f g) rw [← reassoc_of% commfst, e₂.hom_inv_id, Category.comp_id] · change snd = e₁.hom ≫ snd' ≫ e₃.inv rw [← reassoc_of% commsnd, e₃.hom_inv_id, Category.comp_id]))⟩ +section + +variable {P X Y : C} {fst : P ⟶ X} {snd : P ⟶ X} {f : X ⟶ Y} [Mono f] + +lemma isIso_fst_of_mono (h : IsPullback fst snd f f) : IsIso fst := + h.cone.isIso_fst_of_mono_of_isLimit h.isLimit + +lemma isIso_snd_iso_of_mono {P X Y : C} {fst : P ⟶ X} {snd : P ⟶ X} {f : X ⟶ Y} [Mono f] + (h : IsPullback fst snd f f) : IsIso snd := + h.cone.isIso_snd_of_mono_of_isLimit h.isLimit + +end end IsPullback @@ -540,6 +549,18 @@ lemma of_iso (h : IsPushout f g inl inr) (IsColimit.ofIsoColimit h.isColimit (PushoutCocone.ext e₄ comminl comminr))⟩ +section + +variable {P X Y : C} {inl : X ⟶ P} {inr : X ⟶ P} {f : Y ⟶ X} [Epi f] + +lemma isIso_inl_iso_of_epi (h : IsPushout f f inl inr) : IsIso inl := + h.cocone.isIso_inl_of_epi_of_isColimit h.isColimit + +lemma isIso_inr_iso_of_epi (h : IsPushout f f inl inr) : IsIso inr := + h.cocone.isIso_inr_of_epi_of_isColimit h.isColimit + +end + end IsPushout namespace IsPullback diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean index 5393b03bb61a3d..e71c318301bbd6 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean @@ -191,30 +191,42 @@ section open WalkingCospan -variable (f : X ⟶ Y) +variable (f : X ⟶ Y) [Mono f] -instance has_kernel_pair_of_mono [Mono f] : HasPullback f f := +instance has_kernel_pair_of_mono : HasPullback f f := ⟨⟨⟨_, PullbackCone.isLimitMkIdId f⟩⟩⟩ -theorem fst_eq_snd_of_mono_eq [Mono f] : pullback.fst f f = pullback.snd f f := - ((PullbackCone.isLimitMkIdId f).fac (getLimitCone (cospan f f)).cone left).symm.trans - ((PullbackCone.isLimitMkIdId f).fac (getLimitCone (cospan f f)).cone right : _) +theorem PullbackCone.fst_eq_snd_of_mono_eq {f : X ⟶ Y} [Mono f] (t : PullbackCone f f) : + t.fst = t.snd := + (cancel_mono f).1 t.condition + +theorem fst_eq_snd_of_mono_eq : pullback.fst f f = pullback.snd f f := + PullbackCone.fst_eq_snd_of_mono_eq (getLimitCone (cospan f f)).cone @[simp] -theorem pullbackSymmetry_hom_of_mono_eq [Mono f] : (pullbackSymmetry f f).hom = 𝟙 _ := by +theorem pullbackSymmetry_hom_of_mono_eq : (pullbackSymmetry f f).hom = 𝟙 _ := by ext · simp [fst_eq_snd_of_mono_eq] · simp [fst_eq_snd_of_mono_eq] -instance fst_iso_of_mono_eq [Mono f] : IsIso (pullback.fst f f) := by - refine ⟨⟨pullback.lift (𝟙 _) (𝟙 _) (by simp), ?_, by simp⟩⟩ - ext +variable {f} in +lemma PullbackCone.isIso_fst_of_mono_of_isLimit {t : PullbackCone f f} (ht : IsLimit t) : + IsIso t.fst := by + refine ⟨⟨PullbackCone.IsLimit.lift ht (𝟙 _) (𝟙 _) (by simp), ?_, by simp⟩⟩ + apply PullbackCone.IsLimit.hom_ext ht · simp · simp [fst_eq_snd_of_mono_eq] -instance snd_iso_of_mono_eq [Mono f] : IsIso (pullback.snd f f) := - fst_eq_snd_of_mono_eq f ▸ fst_iso_of_mono_eq f +variable {f} in +lemma PullbackCone.isIso_snd_of_mono_of_isLimit {t : PullbackCone f f} (ht : IsLimit t) : + IsIso t.snd := + t.fst_eq_snd_of_mono_eq ▸ t.isIso_fst_of_mono_of_isLimit ht + +instance isIso_fst_of_mono : IsIso (pullback.fst f f) := + PullbackCone.isIso_fst_of_mono_of_isLimit (getLimitCone (cospan f f)).isLimit +instance isIso_snd_of_mono : IsIso (pullback.snd f f) := + PullbackCone.isIso_snd_of_mono_of_isLimit (getLimitCone (cospan f f)).isLimit end namespace PushoutCocone @@ -357,27 +369,40 @@ section open WalkingSpan -variable (f : X ⟶ Y) +variable (f : X ⟶ Y) [Epi f] -instance has_cokernel_pair_of_epi [Epi f] : HasPushout f f := +instance has_cokernel_pair_of_epi : HasPushout f f := ⟨⟨⟨_, PushoutCocone.isColimitMkIdId f⟩⟩⟩ -theorem inl_eq_inr_of_epi_eq [Epi f] : (pushout.inl _ _ : _ ⟶ pushout f f) = pushout.inr _ _ := - ((PushoutCocone.isColimitMkIdId f).fac (getColimitCocone (span f f)).cocone left).symm.trans - ((PushoutCocone.isColimitMkIdId f).fac (getColimitCocone (span f f)).cocone right : _) +theorem PushoutCocone.inl_eq_inr_of_epi_eq {f : X ⟶ Y} [Epi f] (t : PushoutCocone f f) : + t.inl = t.inr := + (cancel_epi f).1 t.condition + +theorem inl_eq_inr_of_epi_eq : pushout.inl f f = pushout.inr f f := + PushoutCocone.inl_eq_inr_of_epi_eq (getColimitCocone (span f f)).cocone @[simp] -theorem pullback_symmetry_hom_of_epi_eq [Epi f] : (pushoutSymmetry f f).hom = 𝟙 _ := by +theorem pullback_symmetry_hom_of_epi_eq : (pushoutSymmetry f f).hom = 𝟙 _ := by ext <;> simp [inl_eq_inr_of_epi_eq] -instance inl_iso_of_epi_eq [Epi f] : IsIso (pushout.inl _ _ : _ ⟶ pushout f f) := by - refine ⟨⟨pushout.desc (𝟙 _) (𝟙 _) (by simp), by simp, ?_⟩⟩ - apply pushout.hom_ext +variable {f} in +lemma PushoutCocone.isIso_inl_of_epi_of_isColimit {t : PushoutCocone f f} (ht : IsColimit t) : + IsIso t.inl := by + refine ⟨⟨PushoutCocone.IsColimit.desc ht (𝟙 _) (𝟙 _) (by simp), by simp, ?_⟩⟩ + apply PushoutCocone.IsColimit.hom_ext ht · simp · simp [inl_eq_inr_of_epi_eq] -instance inr_iso_of_epi_eq [Epi f] : IsIso (pushout.inr f f) := - inl_eq_inr_of_epi_eq f ▸ inl_iso_of_epi_eq f +variable {f} in +lemma PushoutCocone.isIso_inr_of_epi_of_isColimit {t : PushoutCocone f f} (ht : IsColimit t) : + IsIso t.inr := + t.inl_eq_inr_of_epi_eq ▸ t.isIso_inl_of_epi_of_isColimit ht + +instance isIso_inl_of_epi : IsIso (pushout.inl f f) := + PushoutCocone.isIso_inl_of_epi_of_isColimit (getColimitCocone (span f f)).isColimit + +instance isIso_inr_of_epi : IsIso (pushout.inr f f) := + PushoutCocone.isIso_inr_of_epi_of_isColimit (getColimitCocone (span f f)).isColimit end From 134f2f109f0ac326add237c68eee4d87539f0926 Mon Sep 17 00:00:00 2001 From: Riccardo Brasca Date: Mon, 14 Oct 2024 12:17:36 +0000 Subject: [PATCH 104/425] feat: add `RingTheory.Trace.Quotient`: relations between trace maps and quotients (#14798) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We add a file `RingTheory.Trace.Quotient` gathering results about the relations between the trace map on `B → A` and the trace map on quotients and localizations. Co-authored-by: Andrew Yang <36414270+erdOne@users.noreply.github.com> --- Mathlib.lean | 2 + .../Dimension/Constructions.lean | 6 + Mathlib/LinearAlgebra/Matrix/Trace.lean | 5 +- .../IntegralClosure/IntegrallyClosed.lean | 22 ++ Mathlib/RingTheory/LocalRing/Quotient.lean | 103 ++++++++ Mathlib/RingTheory/Trace/Quotient.lean | 233 ++++++++++++++++++ 6 files changed, 369 insertions(+), 2 deletions(-) create mode 100644 Mathlib/RingTheory/LocalRing/Quotient.lean create mode 100644 Mathlib/RingTheory/Trace/Quotient.lean diff --git a/Mathlib.lean b/Mathlib.lean index fca4baff8f9b43..078370ea49dfab 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3977,6 +3977,7 @@ import Mathlib.RingTheory.LocalRing.Defs import Mathlib.RingTheory.LocalRing.MaximalIdeal.Basic import Mathlib.RingTheory.LocalRing.MaximalIdeal.Defs import Mathlib.RingTheory.LocalRing.Module +import Mathlib.RingTheory.LocalRing.Quotient import Mathlib.RingTheory.LocalRing.ResidueField.Basic import Mathlib.RingTheory.LocalRing.ResidueField.Defs import Mathlib.RingTheory.LocalRing.RingHom.Basic @@ -4104,6 +4105,7 @@ import Mathlib.RingTheory.TensorProduct.Basic import Mathlib.RingTheory.TensorProduct.MvPolynomial import Mathlib.RingTheory.Trace.Basic import Mathlib.RingTheory.Trace.Defs +import Mathlib.RingTheory.Trace.Quotient import Mathlib.RingTheory.TwoSidedIdeal.Basic import Mathlib.RingTheory.TwoSidedIdeal.BigOperators import Mathlib.RingTheory.TwoSidedIdeal.Instances diff --git a/Mathlib/LinearAlgebra/Dimension/Constructions.lean b/Mathlib/LinearAlgebra/Dimension/Constructions.lean index 9a7b9976449732..3c58916c9b5e97 100644 --- a/Mathlib/LinearAlgebra/Dimension/Constructions.lean +++ b/Mathlib/LinearAlgebra/Dimension/Constructions.lean @@ -469,6 +469,12 @@ theorem span_lt_top_of_card_lt_finrank {s : Set M} [Fintype s] (card_lt : s.toFinset.card < finrank R M) : span R s < ⊤ := lt_top_of_finrank_lt_finrank (lt_of_le_of_lt (finrank_span_le_card _) card_lt) +lemma finrank_le_of_span_eq_top {ι : Type*} [Fintype ι] {v : ι → M} + (hv : Submodule.span R (Set.range v) = ⊤) : finrank R M ≤ Fintype.card ι := by + classical + rw [← finrank_top, ← hv] + exact (finrank_span_le_card _).trans (by convert Fintype.card_range_le v; rw [Set.toFinset_card]) + end Span section SubalgebraRank diff --git a/Mathlib/LinearAlgebra/Matrix/Trace.lean b/Mathlib/LinearAlgebra/Matrix/Trace.lean index 40da0be3f44c02..86b9568b2b0d92 100644 --- a/Mathlib/LinearAlgebra/Matrix/Trace.lean +++ b/Mathlib/LinearAlgebra/Matrix/Trace.lean @@ -103,8 +103,9 @@ theorem trace_sum (s : Finset ι) (f : ι → Matrix n n R) : trace (∑ i ∈ s, f i) = ∑ i ∈ s, trace (f i) := map_sum (traceAddMonoidHom n R) f s -theorem _root_.AddMonoidHom.map_trace [AddCommMonoid S] (f : R →+ S) (A : Matrix n n R) : - f (trace A) = trace (f.mapMatrix A) := +theorem _root_.AddMonoidHom.map_trace [AddCommMonoid S] {F : Type*} [FunLike F R S] + [AddMonoidHomClass F R S] (f : F) (A : Matrix n n R) : + f (trace A) = trace ((f : R →+ S).mapMatrix A) := map_sum f (fun i => diag A i) Finset.univ lemma trace_blockDiagonal [DecidableEq p] (M : p → Matrix n n R) : diff --git a/Mathlib/RingTheory/IntegralClosure/IntegrallyClosed.lean b/Mathlib/RingTheory/IntegralClosure/IntegrallyClosed.lean index c987ccc2c77c57..e4a5c700b65efc 100644 --- a/Mathlib/RingTheory/IntegralClosure/IntegrallyClosed.lean +++ b/Mathlib/RingTheory/IntegralClosure/IntegrallyClosed.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Anne Baanen -/ import Mathlib.RingTheory.Localization.Integral +import Mathlib.RingTheory.Localization.LocalizationLocalization /-! # Integrally closed rings @@ -275,6 +276,27 @@ theorem isIntegrallyClosedOfFiniteExtension [IsDomain R] [FiniteDimensional K L] end integralClosure +section localization + +variable {R : Type*} (S : Type*) [CommRing R] [CommRing S] [Algebra R S] + +lemma isIntegrallyClosed_of_isLocalization [IsIntegrallyClosed R] [IsDomain R] (M : Submonoid 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 + 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 + refine (isIntegrallyClosed_iff_isIntegralClosure (K := K)).mpr + ⟨IsFractionRing.injective _ _, fun {x} ↦ ⟨?_, fun e ↦ e.choose_spec ▸ isIntegral_algebraMap⟩⟩ + intro hx + obtain ⟨⟨y, y_mem⟩, hy⟩ := hx.exists_multiple_integral_of_isLocalization M _ + obtain ⟨z, hz⟩ := (isIntegrallyClosed_iff _).mp ‹_› hy + refine ⟨IsLocalization.mk' S z ⟨y, y_mem⟩, (IsLocalization.lift_mk'_spec _ _ _ _).mpr ?_⟩ + rw [RingHom.comp_id, hz, ← Algebra.smul_def, Submonoid.mk_smul] + +end localization /-- Any field is integral closed. -/ /- Although `infer_instance` can find this if you import Mathlib, in this file they have not been proven yet. However, it is used to prove a fundamental property of `IsIntegrallyClosed`, diff --git a/Mathlib/RingTheory/LocalRing/Quotient.lean b/Mathlib/RingTheory/LocalRing/Quotient.lean new file mode 100644 index 00000000000000..e4ef8ab01d8e7f --- /dev/null +++ b/Mathlib/RingTheory/LocalRing/Quotient.lean @@ -0,0 +1,103 @@ +/- +Copyright (c) 2024 Riccardo Brasca. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Andrew Yang, Riccardo Brasca +-/ + +import Mathlib.LinearAlgebra.Dimension.DivisionRing +import Mathlib.LinearAlgebra.FreeModule.PID +import Mathlib.LinearAlgebra.FreeModule.StrongRankCondition +import Mathlib.RingTheory.DiscreteValuationRing.TFAE + +/-! + +We gather results about the quotients of local rings. + +-/ + +open Submodule FiniteDimensional Module + +variable {R S : Type*} [CommRing R] [CommRing S] [Algebra R S] [LocalRing R] [Module.Finite R S] + +namespace LocalRing + +local notation "p" => maximalIdeal R +local notation "pS" => Ideal.map (algebraMap R S) p + +theorem quotient_span_eq_top_iff_span_eq_top (s : Set S) : + span (R ⧸ p) ((Ideal.Quotient.mk (I := pS)) '' s) = ⊤ ↔ span R s = ⊤ := by + have H : (span (R ⧸ p) ((Ideal.Quotient.mk (I := pS)) '' s)).restrictScalars R = + (span R s).map (IsScalarTower.toAlgHom R S (S ⧸ pS)) := by + rw [map_span, ← restrictScalars_span R (R ⧸ p) Ideal.Quotient.mk_surjective, + IsScalarTower.coe_toAlgHom', Ideal.Quotient.algebraMap_eq] + constructor + · intro hs + rw [← top_le_iff] + apply le_of_le_smul_of_le_jacobson_bot + · exact Module.finite_def.mp ‹_› + · exact (jacobson_eq_maximalIdeal ⊥ bot_ne_top).ge + · rw [Ideal.smul_top_eq_map] + rintro x - + have : LinearMap.ker (IsScalarTower.toAlgHom R S (S ⧸ pS)) = + restrictScalars R pS := by + ext; simp [Ideal.Quotient.eq_zero_iff_mem] + rw [← this, ← comap_map_eq, mem_comap, ← H, hs, restrictScalars_top] + exact mem_top + · intro hs + rwa [hs, Submodule.map_top, LinearMap.range_eq_top.mpr, restrictScalars_eq_top_iff] at H + rw [IsScalarTower.coe_toAlgHom', Ideal.Quotient.algebraMap_eq] + exact Ideal.Quotient.mk_surjective + +attribute [local instance] Ideal.Quotient.field + +variable [Module.Free R S] {ι : Type*} + +theorem finrank_quotient_map : + finrank (R ⧸ p) (S ⧸ pS) = finrank R S := by + classical + have : Module.Finite R (S ⧸ pS) := Module.Finite.of_surjective + (IsScalarTower.toAlgHom R S (S ⧸ pS)).toLinearMap (Ideal.Quotient.mk_surjective (I := pS)) + have : Module.Finite (R ⧸ p) (S ⧸ pS) := Module.Finite.of_restrictScalars_finite R _ _ + apply le_antisymm + · let b := Module.Free.chooseBasis R S + conv_rhs => rw [finrank_eq_card_chooseBasisIndex] + apply finrank_le_of_span_eq_top + rw [Set.range_comp] + apply (quotient_span_eq_top_iff_span_eq_top _).mpr b.span_eq + · let b := Module.Free.chooseBasis (R ⧸ p) (S ⧸ pS) + choose b' hb' using fun i ↦ Ideal.Quotient.mk_surjective (b i) + conv_rhs => rw [finrank_eq_card_chooseBasisIndex] + apply finrank_le_of_span_eq_top + apply (quotient_span_eq_top_iff_span_eq_top _).mp + rw [← Set.range_comp, show Ideal.Quotient.mk pS ∘ b' = ⇑b from funext hb'] + exact b.span_eq + +/-- Given a basis of `S`, the induced basis of `S / Ideal.map (algebraMap R S) p`. -/ +noncomputable +def basisQuotient [Fintype ι] (b : Basis ι R S) : Basis ι (R ⧸ p) (S ⧸ pS) := + basisOfTopLeSpanOfCardEqFinrank (Ideal.Quotient.mk pS ∘ b) + (by + rw [Set.range_comp] + exact ((quotient_span_eq_top_iff_span_eq_top _).mpr b.span_eq).ge) + (by rw [finrank_quotient_map, finrank_eq_card_basis b]) + +lemma basisQuotient_apply [Fintype ι] (b : Basis ι R S) (i) : + (basisQuotient b) i = Ideal.Quotient.mk pS (b i) := by + delta basisQuotient + rw [coe_basisOfTopLeSpanOfCardEqFinrank, Function.comp_apply] + +lemma basisQuotient_repr {ι} [Fintype ι] (b : Basis ι R S) (x) (i) : + (basisQuotient b).repr (Ideal.Quotient.mk pS x) i = + Ideal.Quotient.mk p (b.repr x i) := by + refine congr_fun (g := Ideal.Quotient.mk p ∘ b.repr x) ?_ i + apply (Finsupp.linearEquivFunOnFinite (R ⧸ p) _ _).symm.injective + apply (basisQuotient b).repr.symm.injective + simp only [Finsupp.linearEquivFunOnFinite_symm_coe, LinearEquiv.symm_apply_apply, + Basis.repr_symm_apply] + rw [Finsupp.linearCombination_eq_fintype_linearCombination_apply _ (R ⧸ p), + Fintype.linearCombination_apply] + simp only [Function.comp_apply, basisQuotient_apply, + Ideal.Quotient.mk_smul_mk_quotient_map_quotient, ← Algebra.smul_def] + rw [← map_sum, Basis.sum_repr b x] + +end LocalRing diff --git a/Mathlib/RingTheory/Trace/Quotient.lean b/Mathlib/RingTheory/Trace/Quotient.lean new file mode 100644 index 00000000000000..4986caa0081a55 --- /dev/null +++ b/Mathlib/RingTheory/Trace/Quotient.lean @@ -0,0 +1,233 @@ +/- +Copyright (c) 2024 Riccardo Brasca. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Andrew Yang, Riccardo Brasca +-/ + +import Mathlib.RingTheory.DedekindDomain.Dvr +import Mathlib.RingTheory.IntegralClosure.IntegralRestrict +import Mathlib.RingTheory.LocalRing.Quotient + +/-! + +We gather results about the relations between the trace map on `B → A` and the trace map on +quotients and localizations. + +## Main Results + +* `Algebra.trace_quotient_eq_of_isDedekindDomain` : The trace map on `B → A` coincides with the + trace map on `B⧸pB → A⧸p`. + +-/ + +variable {R S : Type*} [CommRing R] [CommRing S] [Algebra R S] + +open LocalRing FiniteDimensional Submodule + +section LocalRing + +local notation "p" => maximalIdeal R +local notation "pS" => Ideal.map (algebraMap R S) p + +variable [Module.Free R S] [Module.Finite R S] + +attribute [local instance] Ideal.Quotient.field + +lemma Algebra.trace_quotient_mk [LocalRing 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 : Basis ι R S := Module.Free.chooseBasis R S + rw [trace_eq_matrix_trace b, trace_eq_matrix_trace (basisQuotient b), AddMonoidHom.map_trace] + congr 1 + ext i j + simp only [leftMulMatrix_apply, coe_lmul_eq_mul, LinearMap.toMatrix_apply, + basisQuotient_apply, LinearMap.mul_apply', RingHom.toAddMonoidHom_eq_coe, + AddMonoidHom.mapMatrix_apply, AddMonoidHom.coe_coe, Matrix.map_apply, ← map_mul, + basisQuotient_repr] + +end LocalRing + +section IsDedekindDomain + +variable (p : Ideal R) [p.IsMaximal] +variable {Rₚ Sₚ : Type*} [CommRing Rₚ] [CommRing Sₚ] [Algebra R Rₚ] [IsLocalization.AtPrime Rₚ p] +variable [LocalRing Rₚ] [Algebra S Sₚ] [Algebra R Sₚ] [Algebra Rₚ Sₚ] +variable [IsLocalization (Algebra.algebraMapSubmonoid S p.primeCompl) Sₚ] +variable [IsScalarTower R S Sₚ] [IsScalarTower R Rₚ Sₚ] + +variable (Rₚ) + +attribute [local instance] Ideal.Quotient.field + +/-- The isomorphism `R ⧸ p ≃+* Rₚ ⧸ maximalIdeal Rₚ`, where `Rₚ` satisfies +`IsLocalization.AtPrime Rₚ p`. In particular, localization preserves the residue field. -/ +noncomputable +def equivQuotMaximalIdealOfIsLocalization : R ⧸ p ≃+* Rₚ ⧸ maximalIdeal Rₚ := by + refine (Ideal.quotEquivOfEq ?_).trans + (RingHom.quotientKerEquivOfSurjective (f := algebraMap R (Rₚ ⧸ maximalIdeal Rₚ)) ?_) + · rw [IsScalarTower.algebraMap_eq R Rₚ, ← RingHom.comap_ker, + Ideal.Quotient.algebraMap_eq, Ideal.mk_ker, IsLocalization.AtPrime.comap_maximalIdeal Rₚ p] + · intro x + obtain ⟨x, rfl⟩ := Ideal.Quotient.mk_surjective x + obtain ⟨x, s, rfl⟩ := IsLocalization.mk'_surjective p.primeCompl x + obtain ⟨s', hs⟩ := Ideal.Quotient.mk_surjective (I := p) (Ideal.Quotient.mk p s)⁻¹ + simp only [IsScalarTower.algebraMap_eq R Rₚ (Rₚ ⧸ _), + Ideal.Quotient.algebraMap_eq, RingHom.comp_apply] + use x * s' + rw [← sub_eq_zero, ← map_sub, Ideal.Quotient.eq_zero_iff_mem] + have : algebraMap R Rₚ s ∉ maximalIdeal Rₚ := by + rw [← Ideal.mem_comap, IsLocalization.AtPrime.comap_maximalIdeal Rₚ p] + exact s.prop + refine ((inferInstanceAs <| (maximalIdeal Rₚ).IsPrime).mem_or_mem ?_).resolve_left this + rw [mul_sub, IsLocalization.mul_mk'_eq_mk'_of_mul, IsLocalization.mk'_mul_cancel_left, + ← map_mul, ← map_sub, ← Ideal.mem_comap, IsLocalization.AtPrime.comap_maximalIdeal Rₚ p, + mul_left_comm, ← Ideal.Quotient.eq_zero_iff_mem, map_sub, map_mul, map_mul, hs, + mul_inv_cancel₀, mul_one, sub_self] + rw [Ne, Ideal.Quotient.eq_zero_iff_mem] + exact s.prop + +lemma IsLocalization.AtPrime.map_eq_maximalIdeal : + p.map (algebraMap R Rₚ) = maximalIdeal Rₚ := by + convert congr_arg (Ideal.map (algebraMap R Rₚ)) + (IsLocalization.AtPrime.comap_maximalIdeal Rₚ p).symm + rw [map_comap p.primeCompl] + +local notation "pS" => Ideal.map (algebraMap R S) p +local notation "pSₚ" => Ideal.map (algebraMap Rₚ Sₚ) (maximalIdeal Rₚ) + +lemma comap_map_eq_map_of_isLocalization_algebraMapSubmonoid : + (Ideal.map (algebraMap R Sₚ) p).comap (algebraMap S Sₚ) = pS := by + rw [IsScalarTower.algebraMap_eq R S Sₚ, ← Ideal.map_map, eq_comm] + apply Ideal.le_comap_map.antisymm + intro x hx + obtain ⟨α, hα, hαx⟩ : ∃ α ∉ p, α • x ∈ pS := by + have ⟨⟨y, s⟩, hy⟩ := (IsLocalization.mem_map_algebraMap_iff + (Algebra.algebraMapSubmonoid S p.primeCompl) Sₚ).mp hx + rw [← map_mul, + IsLocalization.eq_iff_exists (Algebra.algebraMapSubmonoid S p.primeCompl)] at hy + obtain ⟨c, hc⟩ := hy + obtain ⟨α, hα, e⟩ := (c * s).prop + refine ⟨α, hα, ?_⟩ + rw [Algebra.smul_def, e, Submonoid.coe_mul, mul_assoc, mul_comm _ x, hc] + exact Ideal.mul_mem_left _ _ y.prop + obtain ⟨β, γ, hγ, hβ⟩ : ∃ β γ, γ ∈ p ∧ β * α = 1 + γ := by + obtain ⟨β, hβ⟩ := Ideal.Quotient.mk_surjective (I := p) (Ideal.Quotient.mk p α)⁻¹ + refine ⟨β, β * α - 1, ?_, ?_⟩ + · rw [← Ideal.Quotient.eq_zero_iff_mem, map_sub, map_one, + map_mul, hβ, inv_mul_cancel₀, sub_self] + rwa [Ne, Ideal.Quotient.eq_zero_iff_mem] + · rw [add_sub_cancel] + have := Ideal.mul_mem_left _ (algebraMap _ _ β) hαx + rw [← Algebra.smul_def, smul_smul, hβ, add_smul, one_smul] at this + refine (Submodule.add_mem_iff_left _ ?_).mp this + rw [Algebra.smul_def] + apply Ideal.mul_mem_right + exact Ideal.mem_map_of_mem _ hγ + +variable (S Sₚ) + +/-- The isomorphism `S ⧸ pS ≃+* Sₚ ⧸ pSₚ`. -/ +noncomputable +def quotMapEquivQuotMapMaximalIdealOfIsLocalization : S ⧸ pS ≃+* Sₚ ⧸ pSₚ := by + haveI h : pSₚ = Ideal.map (algebraMap S Sₚ) pS := by + rw [← IsLocalization.AtPrime.map_eq_maximalIdeal p Rₚ, Ideal.map_map, + ← IsScalarTower.algebraMap_eq, Ideal.map_map, ← IsScalarTower.algebraMap_eq] + refine (Ideal.quotEquivOfEq ?_).trans + (RingHom.quotientKerEquivOfSurjective (f := algebraMap S (Sₚ ⧸ pSₚ)) ?_) + · rw [IsScalarTower.algebraMap_eq S Sₚ, Ideal.Quotient.algebraMap_eq, ← RingHom.comap_ker, + Ideal.mk_ker, h, Ideal.map_map, ← IsScalarTower.algebraMap_eq, + comap_map_eq_map_of_isLocalization_algebraMapSubmonoid] + · intro x + obtain ⟨x, rfl⟩ := Ideal.Quotient.mk_surjective x + obtain ⟨x, s, rfl⟩ := IsLocalization.mk'_surjective + (Algebra.algebraMapSubmonoid S p.primeCompl) x + obtain ⟨α, hα : α ∉ p, e⟩ := s.prop + obtain ⟨β, γ, hγ, hβ⟩ : ∃ β γ, γ ∈ p ∧ α * β = 1 + γ := by + obtain ⟨β, hβ⟩ := Ideal.Quotient.mk_surjective (I := p) (Ideal.Quotient.mk p α)⁻¹ + refine ⟨β, α * β - 1, ?_, ?_⟩ + · rw [← Ideal.Quotient.eq_zero_iff_mem, map_sub, map_one, + map_mul, hβ, mul_inv_cancel₀, sub_self] + rwa [Ne, Ideal.Quotient.eq_zero_iff_mem] + · rw [add_sub_cancel] + use β • x + rw [IsScalarTower.algebraMap_eq S Sₚ (Sₚ ⧸ pSₚ), Ideal.Quotient.algebraMap_eq, + RingHom.comp_apply, ← sub_eq_zero, ← map_sub, Ideal.Quotient.eq_zero_iff_mem] + rw [h, IsLocalization.mem_map_algebraMap_iff + (Algebra.algebraMapSubmonoid S p.primeCompl) Sₚ] + refine ⟨⟨⟨γ • x, ?_⟩, s⟩, ?_⟩ + · rw [Algebra.smul_def] + apply Ideal.mul_mem_right + exact Ideal.mem_map_of_mem _ hγ + simp only + rw [mul_comm, mul_sub, IsLocalization.mul_mk'_eq_mk'_of_mul, + IsLocalization.mk'_mul_cancel_left, ← map_mul, ← e, ← Algebra.smul_def, smul_smul, + hβ, ← map_sub, add_smul, one_smul, add_comm x, add_sub_cancel_right] + +lemma trace_quotient_eq_trace_localization_quotient (x) : + Algebra.trace (R ⧸ p) (S ⧸ pS) (Ideal.Quotient.mk pS x) = + (equivQuotMaximalIdealOfIsLocalization p Rₚ).symm + (Algebra.trace (Rₚ ⧸ maximalIdeal Rₚ) (Sₚ ⧸ pSₚ) (algebraMap S _ x)) := by + have : IsScalarTower R (Rₚ ⧸ maximalIdeal Rₚ) (Sₚ ⧸ pSₚ) := by + apply IsScalarTower.of_algebraMap_eq' + rw [IsScalarTower.algebraMap_eq R Rₚ (Rₚ ⧸ _), IsScalarTower.algebraMap_eq R Rₚ (Sₚ ⧸ _), + ← RingHom.comp_assoc, ← IsScalarTower.algebraMap_eq Rₚ] + rw [Algebra.trace_eq_of_equiv_equiv (equivQuotMaximalIdealOfIsLocalization p Rₚ) + (quotMapEquivQuotMapMaximalIdealOfIsLocalization S p Rₚ Sₚ)] + · congr + · ext x + simp only [equivQuotMaximalIdealOfIsLocalization, RingHom.quotientKerEquivOfSurjective, + RingEquiv.coe_ringHom_trans, RingHom.coe_comp, RingHom.coe_coe, Function.comp_apply, + Ideal.quotEquivOfEq_mk, RingHom.quotientKerEquivOfRightInverse.apply, RingHom.kerLift_mk, + quotMapEquivQuotMapMaximalIdealOfIsLocalization, + Ideal.Quotient.algebraMap_quotient_map_quotient] + rw [← IsScalarTower.algebraMap_apply, ← IsScalarTower.algebraMap_apply] + +open nonZeroDivisors in +/-- The trace map on `B → A` coincides with the trace map on `B⧸pB → A⧸p`. -/ +lemma Algebra.trace_quotient_eq_of_isDedekindDomain (x) [IsDedekindDomain R] [IsDomain S] + [NoZeroSMulDivisors R S] [Module.Finite R S] [IsIntegrallyClosed S] : + Algebra.trace (R ⧸ p) (S ⧸ pS) (Ideal.Quotient.mk pS x) = + 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' + (by rw [RingHom.algebraMap_toAlgebra, IsLocalization.map_comp, ← IsScalarTower.algebraMap_eq]) + haveI : 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 _ + (NoZeroSMulDivisors.algebraMap_injective _ _)) + haveI : IsDomain Sₚ := IsLocalization.isDomain_of_le_nonZeroDivisors S e + haveI : NoZeroSMulDivisors Rₚ Sₚ := by + rw [NoZeroSMulDivisors.iff_algebraMap_injective, RingHom.injective_iff_ker_eq_bot, + RingHom.ker_eq_bot_iff_eq_zero] + intro x hx + obtain ⟨x, s, rfl⟩ := IsLocalization.mk'_surjective p.primeCompl x + simp only [RingHom.algebraMap_toAlgebra, IsLocalization.map_mk', IsLocalization.mk'_eq_zero_iff, + mul_eq_zero, Subtype.exists, exists_prop] at hx ⊢ + obtain ⟨_, ⟨a, ha, rfl⟩, H⟩ := hx + simp only [(injective_iff_map_eq_zero' _).mp (NoZeroSMulDivisors.algebraMap_injective R S)] at H + refine ⟨a, ha, H⟩ + haveI : Module.Finite Rₚ Sₚ := Module.Finite_of_isLocalization R S _ _ p.primeCompl + haveI : 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' + apply (equivQuotMaximalIdealOfIsLocalization 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 [equivQuotMaximalIdealOfIsLocalization, RingHom.quotientKerEquivOfSurjective, + RingEquiv.coe_trans, Function.comp_apply, Ideal.quotEquivOfEq_mk, + RingHom.quotientKerEquivOfRightInverse.apply, RingHom.kerLift_mk] + +end IsDedekindDomain From 8cb678e92effe8f3913416b9b78327d177e5c3de Mon Sep 17 00:00:00 2001 From: Etienne Date: Mon, 14 Oct 2024 12:17:37 +0000 Subject: [PATCH 105/425] feat: compactly generated spaces for proper maps and preimages of compact sets / proper and properly discontinuous actions (#15239) Prove that a continuous function whose codomain is T2 and compactly generated is proper if and only if the preimages of compact sets are compact. This result already existed but was stated without the typeclass CompactlyGeneratedSpace. It is moved to its own file. When `X \times X` is T2 and compactly generated, a group action is proper if and only if it is properly discontinuous. This was stated without a type class instance for the compactly generated hypothesis. Now it is. --- Mathlib.lean | 4 +- .../Basic.lean} | 109 ------------------ .../ProperAction/ProperlyDiscontinuous.lean | 106 +++++++++++++++++ .../Compactness/CompactlyGeneratedSpace.lean | 15 ++- Mathlib/Topology/Maps/Proper/Basic.lean | 106 +---------------- .../Maps/Proper/CompactlyGenerated.lean | 48 ++++++++ 6 files changed, 169 insertions(+), 219 deletions(-) rename Mathlib/Topology/Algebra/{ProperAction.lean => ProperAction/Basic.lean} (56%) create mode 100644 Mathlib/Topology/Algebra/ProperAction/ProperlyDiscontinuous.lean create mode 100644 Mathlib/Topology/Maps/Proper/CompactlyGenerated.lean diff --git a/Mathlib.lean b/Mathlib.lean index 078370ea49dfab..9a96bd0fcb9476 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4526,7 +4526,8 @@ import Mathlib.Topology.Algebra.Order.Rolle import Mathlib.Topology.Algebra.Order.UpperLower import Mathlib.Topology.Algebra.Polynomial import Mathlib.Topology.Algebra.PontryaginDual -import Mathlib.Topology.Algebra.ProperAction +import Mathlib.Topology.Algebra.ProperAction.Basic +import Mathlib.Topology.Algebra.ProperAction.ProperlyDiscontinuous import Mathlib.Topology.Algebra.ProperConstSMul import Mathlib.Topology.Algebra.Ring.Basic import Mathlib.Topology.Algebra.Ring.Ideal @@ -4716,6 +4717,7 @@ import Mathlib.Topology.LocallyFinite import Mathlib.Topology.Maps.Basic import Mathlib.Topology.Maps.OpenQuotient import Mathlib.Topology.Maps.Proper.Basic +import Mathlib.Topology.Maps.Proper.CompactlyGenerated import Mathlib.Topology.Maps.Proper.UniversallyClosed import Mathlib.Topology.MetricSpace.Algebra import Mathlib.Topology.MetricSpace.Antilipschitz diff --git a/Mathlib/Topology/Algebra/ProperAction.lean b/Mathlib/Topology/Algebra/ProperAction/Basic.lean similarity index 56% rename from Mathlib/Topology/Algebra/ProperAction.lean rename to Mathlib/Topology/Algebra/ProperAction/Basic.lean index 4a337be7878ae3..55f73de488d07f 100644 --- a/Mathlib/Topology/Algebra/ProperAction.lean +++ b/Mathlib/Topology/Algebra/ProperAction/Basic.lean @@ -3,10 +3,8 @@ Copyright (c) 2024 Anatole Dedeker. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Anatole Dedeker, Etienne Marion, Florestan Martin-Baillon, Vincent Guirardel -/ -import Mathlib.Topology.Algebra.Group.Basic import Mathlib.Topology.Algebra.MulAction import Mathlib.Topology.Maps.Proper.Basic -import Mathlib.Topology.Sequences /-! # Proper group action @@ -14,9 +12,6 @@ import Mathlib.Topology.Sequences In this file we define proper action of a group on a topological space, and we prove that in this case the quotient space is T2. We also give equivalent definitions of proper action using ultrafilters and show the transfer of proper action to a closed subgroup. -We give sufficient conditions on the topological space such that the action is properly -discontinuous (see `ProperlyDiscontinuousSMul`) if and only if it is continuous in -the first variable (see `ContinuousConstSMul`) and proper in the sense defined here. ## Main definitions @@ -29,19 +24,6 @@ the first variable (see `ContinuousConstSMul`) and proper in the sense defined h on a topological space `X`, then the quotient space is Hausdorff (T2). * `t2Space_of_properSMul_of_t2Group`: If a T2 group acts properly on a topological space, then this topological space is T2. -* `properlyDiscontinuousSMul_iff_properSMul`: If a discrete group acts on a T2 space `X` such that - `X × X` is compactly generated, then the action is properly discontinuous if and only if it is - continuous in the second variable and proper. This in particular true if `X` is locally compact - or first-countable. - -## Implementation notes - -Concerning `properlyDiscontinuousSMul_iff_properSMul`, this result should be the only one needed -to link properly discontinuous and proper actions. - -TODO: Replace the compactly generated hypothesis by a typeclass instance such that -`WeaklyLocallyCompactSpace.isProperMap_iff_isCompact_preimage` and -`SequentialSpace.isProperMap_iff_isCompact_preimage` are inferred by typeclass inference. ## References @@ -182,94 +164,3 @@ theorem properSMul_of_closedEmbedding {H : Type*} [Group H] [MulAction H X] [Top @[to_additive "If `H` is a closed subgroup of `G` and `G` acts properly on X then so does `H`."] instance {H : Subgroup G} [ProperSMul G X] [H_closed : IsClosed (H : Set G)] : ProperSMul H X := properSMul_of_closedEmbedding H.subtype H_closed.closedEmbedding_subtype_val fun _ _ ↦ rfl - -/-- If a discrete group acts on a T2 space `X` such that `X × X` is compactly generated, -then the action is properly discontinuous if and only if it is continuous in the second variable -and proper. -/ -theorem properlyDiscontinuousSMul_iff_properSMul [T2Space X] [DiscreteTopology G] - [ContinuousConstSMul G X] - (compactlyGenerated : ∀ s : Set (X × X), IsClosed s ↔ ∀ ⦃K⦄, IsCompact K → IsClosed (s ∩ K)) : - ProperlyDiscontinuousSMul G X ↔ ProperSMul G X := by - constructor - · intro h - rw [properSMul_iff] - -- We have to show that `f : (g, x) ↦ (g • x, x)` is proper. - -- Continuity follows from continuity of `g • ·` and the fact that `G` has the - -- discrete topology, thanks to `continuous_of_partial_of_discrete`. - -- Because `X × X` is compactly generated, to show that f is proper - -- it is enough to show that the preimage of a compact set `K` is compact. - refine (isProperMap_iff_isCompact_preimage compactlyGenerated).2 - ⟨(continuous_prod_mk.2 - ⟨continuous_prod_of_discrete_left.2 continuous_const_smul, by fun_prop⟩), - fun K hK ↦ ?_⟩ - -- We set `K' := pr₁(K) ∪ pr₂(K)`, which is compact because `K` is compact and `pr₁` and - -- `pr₂` are continuous. We halso have that `K ⊆ K' × K'`, and `K` is closed because `X` is T2. - -- Therefore `f ⁻¹ (K)` is also closed and `f ⁻¹ (K) ⊆ f ⁻¹ (K' × K')`, thus it suffices to - -- show that `f ⁻¹ (K' × K')` is compact. - let K' := fst '' K ∪ snd '' K - have hK' : IsCompact K' := (hK.image continuous_fst).union (hK.image continuous_snd) - let E := {g : G | Set.Nonempty ((g • ·) '' K' ∩ K')} - -- The set `E` is finite because the action is properly discontinuous. - have fin : Set.Finite E := by - simp_rw [E, nonempty_iff_ne_empty] - exact h.finite_disjoint_inter_image hK' hK' - -- Therefore we can rewrite `f ⁻¹ (K' × K')` as a finite union of compact sets. - have : (fun gx : G × X ↦ (gx.1 • gx.2, gx.2)) ⁻¹' (K' ×ˢ K') = - ⋃ g ∈ E, {g} ×ˢ ((g⁻¹ • ·) '' K' ∩ K') := by - ext gx - simp only [mem_preimage, mem_prod, nonempty_def, mem_inter_iff, mem_image, - exists_exists_and_eq_and, mem_setOf_eq, singleton_prod, iUnion_exists, biUnion_and', - mem_iUnion, exists_prop, E] - constructor - · exact fun ⟨gx_mem, x_mem⟩ ↦ ⟨gx.2, x_mem, gx.1, gx_mem, - ⟨gx.2, ⟨⟨gx.1 • gx.2, gx_mem, by simp⟩, x_mem⟩, rfl⟩⟩ - · rintro ⟨x, -, g, -, ⟨-, ⟨⟨x', x'_mem, rfl⟩, ginvx'_mem⟩, rfl⟩⟩ - exact ⟨by simpa, by simpa⟩ - -- Indeed each set in this finite union is the product of a singleton and - -- the intersection of the compact `K'` with its image by some element `g`, and this image is - -- compact because `g • ·` is continuous. - have : IsCompact ((fun gx : G × X ↦ (gx.1 • gx.2, gx.2)) ⁻¹' (K' ×ˢ K')) := - this ▸ fin.isCompact_biUnion fun g hg ↦ - isCompact_singleton.prod <| (hK'.image <| continuous_const_smul _).inter hK' - -- We conclude as explained above. - exact this.of_isClosed_subset (hK.isClosed.preimage <| - continuous_prod_mk.2 - ⟨continuous_prod_of_discrete_left.2 continuous_const_smul, by fun_prop⟩) <| - preimage_mono fun x hx ↦ ⟨Or.inl ⟨x, hx, rfl⟩, Or.inr ⟨x, hx, rfl⟩⟩ - · intro h; constructor - intro K L hK hL - simp_rw [← nonempty_iff_ne_empty] - -- We want to show that a subset of `G` is finite, but as `G` has the discrete topology it - -- is enough to show that this subset is compact. - apply IsCompact.finite_of_discrete - -- Now set `h : (g, x) ↦ (g⁻¹ • x, x)`, because `f` is proper by hypothesis, so is `h`. - have : IsProperMap (fun gx : G × X ↦ (gx.1⁻¹ • gx.2, gx.2)) := - (IsProperMap.prodMap (Homeomorph.isProperMap (Homeomorph.inv G)) isProperMap_id).comp <| - ProperSMul.isProperMap_smul_pair - --But we also have that `{g | Set.Nonempty ((g • ·) '' K ∩ L)} = h ⁻¹ (K × L)`, which - -- concludes the proof. - have eq : {g | Set.Nonempty ((g • ·) '' K ∩ L)} = - fst '' ((fun gx : G × X ↦ (gx.1⁻¹ • gx.2, gx.2)) ⁻¹' (K ×ˢ L)) := by - simp_rw [nonempty_def] - ext g; constructor - · exact fun ⟨_, ⟨x, x_mem, rfl⟩, hx⟩ ↦ ⟨(g, g • x), ⟨by simpa, hx⟩, rfl⟩ - · rintro ⟨gx, hgx, rfl⟩ - exact ⟨gx.2, ⟨gx.1⁻¹ • gx.2, hgx.1, by simp⟩, hgx.2⟩ - exact eq ▸ IsCompact.image (this.isCompact_preimage <| hK.prod hL) continuous_fst - -/-- If a discrete group acts on a T2 and locally compact space `X`, -then the action is properly discontinuous if and only if it is continuous in the second variable -and proper. -/ -theorem WeaklyLocallyCompactSpace.properlyDiscontinuousSMul_iff_properSMul [T2Space X] - [WeaklyLocallyCompactSpace X] [DiscreteTopology G] [ContinuousConstSMul G X] : - ProperlyDiscontinuousSMul G X ↔ ProperSMul G X := - _root_.properlyDiscontinuousSMul_iff_properSMul - (fun _ ↦ compactlyGenerated_of_weaklyLocallyCompactSpace) - -/-- If a discrete group acts on a T2 and first-countable space `X`, -then the action is properly discontinuous if and only if it is continuous in the second variable -and proper. -/ -theorem FirstCountableTopology.properlyDiscontinuousSMul_iff_properSMul [T2Space X] - [FirstCountableTopology X] [DiscreteTopology G] [ContinuousConstSMul G X] : - ProperlyDiscontinuousSMul G X ↔ ProperSMul G X := - _root_.properlyDiscontinuousSMul_iff_properSMul (fun _ ↦ compactlyGenerated_of_sequentialSpace) diff --git a/Mathlib/Topology/Algebra/ProperAction/ProperlyDiscontinuous.lean b/Mathlib/Topology/Algebra/ProperAction/ProperlyDiscontinuous.lean new file mode 100644 index 00000000000000..72185f7fb509ae --- /dev/null +++ b/Mathlib/Topology/Algebra/ProperAction/ProperlyDiscontinuous.lean @@ -0,0 +1,106 @@ +/- +Copyright (c) 2024 Anatole Dedeker. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Etienne Marion +-/ +import Mathlib.Topology.Algebra.ProperAction.Basic +import Mathlib.Topology.Maps.Proper.CompactlyGenerated + +/-! +# When a proper action is properly discontinuous + +This file proves that 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 +weakly locally compact. + +## Main statement +* `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. + +## Tags + +grouup action, proper action, properly discontinuous, compactly generated +-/ + +variable {G X : Type*} [Group G] [MulAction G X] [TopologicalSpace G] [TopologicalSpace X] + +open Prod Set + +/-- 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 +weakly locally compact. + +There was an older version of this theorem which was changed to this one to make use +of the `CompactlyGeneratedSpace` typeclass. (since 2024-11-10) -/ +theorem properlyDiscontinuousSMul_iff_properSMul [T2Space X] [DiscreteTopology G] + [ContinuousConstSMul G X] [CompactlyGeneratedSpace (X × X)] : + ProperlyDiscontinuousSMul G X ↔ ProperSMul G X := by + constructor + · intro h + rw [properSMul_iff] + -- We have to show that `f : (g, x) ↦ (g • x, x)` is proper. + -- Continuity follows from continuity of `g • ·` and the fact that `G` has the + -- discrete topology, thanks to `continuous_of_partial_of_discrete`. + -- Because `X × X` is compactly generated, to show that f is proper + -- it is enough to show that the preimage of a compact set `K` is compact. + refine isProperMap_iff_isCompact_preimage.2 + ⟨(continuous_prod_mk.2 + ⟨continuous_prod_of_discrete_left.2 continuous_const_smul, by fun_prop⟩), + fun K hK ↦ ?_⟩ + -- We set `K' := pr₁(K) ∪ pr₂(K)`, which is compact because `K` is compact and `pr₁` and + -- `pr₂` are continuous. We halso have that `K ⊆ K' × K'`, and `K` is closed because `X` is T2. + -- Therefore `f ⁻¹ (K)` is also closed and `f ⁻¹ (K) ⊆ f ⁻¹ (K' × K')`, thus it suffices to + -- show that `f ⁻¹ (K' × K')` is compact. + let K' := fst '' K ∪ snd '' K + have hK' : IsCompact K' := (hK.image continuous_fst).union (hK.image continuous_snd) + let E := {g : G | Set.Nonempty ((g • ·) '' K' ∩ K')} + -- The set `E` is finite because the action is properly discontinuous. + have fin : Set.Finite E := by + simp_rw [E, nonempty_iff_ne_empty] + exact h.finite_disjoint_inter_image hK' hK' + -- Therefore we can rewrite `f ⁻¹ (K' × K')` as a finite union of compact sets. + have : (fun gx : G × X ↦ (gx.1 • gx.2, gx.2)) ⁻¹' (K' ×ˢ K') = + ⋃ g ∈ E, {g} ×ˢ ((g⁻¹ • ·) '' K' ∩ K') := by + ext gx + simp only [mem_preimage, mem_prod, nonempty_def, mem_inter_iff, mem_image, + exists_exists_and_eq_and, mem_setOf_eq, singleton_prod, iUnion_exists, biUnion_and', + mem_iUnion, exists_prop, E] + constructor + · exact fun ⟨gx_mem, x_mem⟩ ↦ ⟨gx.2, x_mem, gx.1, gx_mem, + ⟨gx.2, ⟨⟨gx.1 • gx.2, gx_mem, by simp⟩, x_mem⟩, rfl⟩⟩ + · rintro ⟨x, -, g, -, ⟨-, ⟨⟨x', x'_mem, rfl⟩, ginvx'_mem⟩, rfl⟩⟩ + exact ⟨by simpa, by simpa⟩ + -- Indeed each set in this finite union is the product of a singleton and + -- the intersection of the compact `K'` with its image by some element `g`, and this image is + -- compact because `g • ·` is continuous. + have : IsCompact ((fun gx : G × X ↦ (gx.1 • gx.2, gx.2)) ⁻¹' (K' ×ˢ K')) := + this ▸ fin.isCompact_biUnion fun g hg ↦ + isCompact_singleton.prod <| (hK'.image <| continuous_const_smul _).inter hK' + -- We conclude as explained above. + exact this.of_isClosed_subset (hK.isClosed.preimage <| + continuous_prod_mk.2 + ⟨continuous_prod_of_discrete_left.2 continuous_const_smul, by fun_prop⟩) <| + preimage_mono fun x hx ↦ ⟨Or.inl ⟨x, hx, rfl⟩, Or.inr ⟨x, hx, rfl⟩⟩ + · intro h; constructor + intro K L hK hL + simp_rw [← nonempty_iff_ne_empty] + -- We want to show that a subset of `G` is finite, but as `G` has the discrete topology it + -- is enough to show that this subset is compact. + apply IsCompact.finite_of_discrete + -- Now set `h : (g, x) ↦ (g⁻¹ • x, x)`, because `f` is proper by hypothesis, so is `h`. + have : IsProperMap (fun gx : G × X ↦ (gx.1⁻¹ • gx.2, gx.2)) := + (IsProperMap.prodMap (Homeomorph.isProperMap (Homeomorph.inv G)) isProperMap_id).comp <| + ProperSMul.isProperMap_smul_pair + --But we also have that `{g | Set.Nonempty ((g • ·) '' K ∩ L)} = h ⁻¹ (K × L)`, which + -- concludes the proof. + have eq : {g | Set.Nonempty ((g • ·) '' K ∩ L)} = + fst '' ((fun gx : G × X ↦ (gx.1⁻¹ • gx.2, gx.2)) ⁻¹' (K ×ˢ L)) := by + simp_rw [nonempty_def] + ext g; constructor + · exact fun ⟨_, ⟨x, x_mem, rfl⟩, hx⟩ ↦ ⟨(g, g • x), ⟨by simpa, hx⟩, rfl⟩ + · rintro ⟨gx, hgx, rfl⟩ + exact ⟨gx.2, ⟨gx.1⁻¹ • gx.2, hgx.1, by simp⟩, hgx.2⟩ + exact eq ▸ IsCompact.image (this.isCompact_preimage <| hK.prod hL) continuous_fst diff --git a/Mathlib/Topology/Compactness/CompactlyGeneratedSpace.lean b/Mathlib/Topology/Compactness/CompactlyGeneratedSpace.lean index fbcd4585a405af..b80b8869deeaba 100644 --- a/Mathlib/Topology/Compactness/CompactlyGeneratedSpace.lean +++ b/Mathlib/Topology/Compactness/CompactlyGeneratedSpace.lean @@ -307,10 +307,17 @@ instance {ι : Type u} {X : ι → Type v} have hg : Continuous g := continuous_sigmaMk.comp <| hf.comp continuous_uLift_down exact (h _ g hg).preimage continuous_uLift_up +variable [T2Space X] + +theorem CompactlyGeneratedSpace.isClosed_iff_of_t2 [CompactlyGeneratedSpace X] (s : Set X) : + IsClosed s ↔ ∀ ⦃K⦄, IsCompact K → IsClosed (s ∩ K) where + mp hs _ hK := hs.inter hK.isClosed + mpr := CompactlyGeneratedSpace.isClosed + /-- Let `s ⊆ X`. Suppose that `X` is Hausdorff, and that to prove that `s` is closed, it suffices to show that for every compact set `K ⊆ X`, `s ∩ K` is closed. Then `X` is compactly generated. -/ -theorem compactlyGeneratedSpace_of_isClosed_of_t2 [T2Space X] +theorem compactlyGeneratedSpace_of_isClosed_of_t2 (h : ∀ s, (∀ (K : Set X), IsCompact K → IsClosed (s ∩ K)) → IsClosed s) : CompactlyGeneratedSpace X := by refine compactlyGeneratedSpace_of_isClosed fun s hs ↦ h s fun K hK ↦ ?_ @@ -323,15 +330,15 @@ open scoped Set.Notation in /-- Let `s ⊆ X`. Suppose that `X` is Hausdorff, and that to prove that `s` is open, it suffices to show that for every compact set `K ⊆ X`, `s ∩ K` is open in `K`. Then `X` is compactly generated. -/ -theorem compactlyGeneratedSpace_of_isOpen_of_t2 [T2Space X] +theorem compactlyGeneratedSpace_of_isOpen_of_t2 (h : ∀ s, (∀ (K : Set X), IsCompact K → IsOpen (K ↓∩ s)) → IsOpen s) : CompactlyGeneratedSpace X := by refine compactlyGeneratedSpace_of_isOpen fun s hs ↦ h s fun K hK ↦ ?_ have : CompactSpace ↑K := isCompact_iff_compactSpace.1 hK exact hs _ Subtype.val continuous_subtype_val -/-- A Hausdorff and weakly locally compact space and compactly generated. -/ -instance (priority := 100) [WeaklyLocallyCompactSpace X] [T2Space X] : +/-- A Hausdorff and weakly locally compact space is compactly generated. -/ +instance (priority := 100) [WeaklyLocallyCompactSpace X] : CompactlyGeneratedSpace X := by refine compactlyGeneratedSpace_of_isClosed_of_t2 fun s h ↦ ?_ rw [isClosed_iff_forall_filter] diff --git a/Mathlib/Topology/Maps/Proper/Basic.lean b/Mathlib/Topology/Maps/Proper/Basic.lean index 00bd0a3bd86772..aadee505b3cacf 100644 --- a/Mathlib/Topology/Maps/Proper/Basic.lean +++ b/Mathlib/Topology/Maps/Proper/Basic.lean @@ -5,7 +5,6 @@ Authors: Anatole Dedecker, Etienne Marion -/ import Mathlib.Topology.Homeomorph import Mathlib.Topology.Filter -import Mathlib.Topology.Defs.Sequences /-! # Proper maps between topological spaces @@ -20,8 +19,7 @@ the following equivalent conditions: of `ℱ`. We take 3 as the definition in `IsProperMap`, and we show the equivalence with 1, 2, and some -other variations. We also show the usual characterization of proper maps to a locally compact -Hausdorff space as continuous maps such that preimages of compact sets are compact. +other variations. ## Main statements @@ -30,11 +28,6 @@ Hausdorff space as continuous maps such that preimages of compact sets are compa * `IsProperMap.pi_map`: any product of proper maps is proper. * `isProperMap_iff_isClosedMap_and_compact_fibers`: a map is proper if and only if it is continuous, closed, and has compact fibers -* `isProperMap_iff_isCompact_preimage`: a map to a Hausdorff compactly generated space is proper if - and only if it is continuous and preimages of compact sets are compact. This is in particular - true if the space is locally compact or sequential. -* `isProperMap_iff_universally_closed`: a map is proper if and only if it is continuous and - universally closed, in the sense of condition 2. above. ## Implementation notes @@ -45,14 +38,6 @@ particular for the theory of proper group actions. That means that our terminolo align with that of [Stacks: Characterizing proper maps](https://stacks.math.columbia.edu/tag/005M), instead our definition of `IsProperMap` coincides with what they call "Bourbaki-proper". -Concerning `isProperMap_iff_isCompact_preimage`, this result should be the only one needed to link -the definition of a proper map and the criteria "preimage of compact sets are compact", however -the notion of compactly generated space is not yet in Mathlib (TODO) -so it is used as an intermediate result to prove -`WeaklyLocallyCompactSpace.isProperMap_iff_isCompact_preimage` and -`SequentialSpace.isProperMap_iff_isCompact_preimage`. In the future those should be inferred -by typeclass inference. - Regarding the proofs, we don't really follow Bourbaki and go for more filter-heavy proofs, as usual. In particular, their arguments rely heavily on restriction of closed maps (see `IsClosedMap.restrictPreimage`), which makes them somehow annoying to formalize in type theory. @@ -322,95 +307,6 @@ lemma isProperMap_iff_isClosedMap_and_tendsto_cofinite [T1Space Y] : theorem Continuous.isProperMap [CompactSpace X] [T2Space Y] (hf : Continuous f) : IsProperMap f := isProperMap_iff_isClosedMap_and_tendsto_cofinite.2 ⟨hf, hf.isClosedMap, by simp⟩ -/-- If `Y` is Hausdorff and compactly generated, then proper maps `X → Y` are exactly -continuous maps such that the preimage of any compact set is compact. - -This result should be the only one needed to link the definition of a proper map and -the criteria "preimage of compact sets are compact", but the notion of compactly generated space -is not yet in Mathlib (TODO) so we use it as an intermediate result to prove -`WeaklyLocallyCompactSpace.isProperMap_iff_isCompact_preimage` and -`SequentialSpace.isProperMap_iff_isCompact_preimage`. In the future those should be inferred -by typeclass inference. -/ -theorem isProperMap_iff_isCompact_preimage [T2Space Y] - (compactlyGenerated : ∀ s : Set Y, IsClosed s ↔ ∀ ⦃K⦄, IsCompact K → IsClosed (s ∩ K)) : - IsProperMap f ↔ Continuous f ∧ ∀ ⦃K⦄, IsCompact K → IsCompact (f ⁻¹' K) where - mp hf := ⟨hf.continuous, fun _ ↦ hf.isCompact_preimage⟩ - mpr := fun ⟨hf, h⟩ ↦ isProperMap_iff_isClosedMap_and_compact_fibers.2 - ⟨hf, fun _ hs ↦ (compactlyGenerated _).2 - fun _ hK ↦ image_inter_preimage .. ▸ (((h hK).inter_left hs).image hf).isClosed, - fun _ ↦ h isCompact_singleton⟩ - -/-- A locally compact space is compactly generated. -/ -theorem compactlyGenerated_of_weaklyLocallyCompactSpace [T2Space X] [WeaklyLocallyCompactSpace X] - {s : Set X} : IsClosed s ↔ ∀ ⦃K⦄, IsCompact K → IsClosed (s ∩ K) := by - refine ⟨fun hs K hK ↦ hs.inter hK.isClosed, fun h ↦ ?_⟩ - rw [isClosed_iff_forall_filter] - intro x ℱ hℱ₁ hℱ₂ hℱ₃ - rcases exists_compact_mem_nhds x with ⟨K, hK, K_mem⟩ - exact mem_of_mem_inter_left <| isClosed_iff_forall_filter.1 (h hK) x ℱ hℱ₁ - (inf_principal ▸ le_inf hℱ₂ (le_trans hℱ₃ <| le_principal_iff.2 K_mem)) hℱ₃ - -/-- If `Y` is locally compact and Hausdorff, then proper maps `X → Y` are exactly continuous maps -such that the preimage of any compact set is compact. - -This result is a direct consequence of `isProperMap_iff_isCompact_preimage`, because any -Hausdorff and weakly locally compact space is compactly generated. -In the future it should be inferred by typeclass inference, however compactly generated spaces -are not yet in Mathlib (TODO), therefore we also add this theorem. -/ -theorem WeaklyLocallyCompactSpace.isProperMap_iff_isCompact_preimage [T2Space Y] - [WeaklyLocallyCompactSpace Y] : - IsProperMap f ↔ Continuous f ∧ ∀ ⦃K⦄, IsCompact K → IsCompact (f ⁻¹' K) := - _root_.isProperMap_iff_isCompact_preimage - (fun _ ↦ compactlyGenerated_of_weaklyLocallyCompactSpace) - -/-- A sequential space is compactly generated. -/ -theorem compactlyGenerated_of_sequentialSpace [T2Space X] [SequentialSpace X] {s : Set X} : - IsClosed s ↔ ∀ ⦃K⦄, IsCompact K → IsClosed (s ∩ K) := by - refine ⟨fun hs K hK ↦ hs.inter hK.isClosed, - fun h ↦ SequentialSpace.isClosed_of_seq _ fun u p hu hup ↦ - mem_of_mem_inter_left ((h hup.isCompact_insert_range).mem_of_tendsto hup ?_)⟩ - simp only [mem_inter_iff, mem_insert_iff, mem_range, exists_apply_eq_apply, or_true, and_true, - eventually_atTop, ge_iff_le] - exact ⟨0, fun n _ ↦ hu n⟩ - -/-- If `Y` is sequential and Hausdorff, then proper maps `X → Y` are exactly continuous maps -such that the preimage of any compact set is compact. - -This result is a direct consequence of `isProperMap_iff_isCompact_preimage`, because any -Hausdorff and sequential space is compactly generated. In the future it should be inferred -by typeclass inference, however compactly generated spaces are not yet in Mathlib (TODO), -therefore we also add this theorem. -/ -theorem SequentialSpace.isProperMap_iff_isCompact_preimage [T2Space Y] [SequentialSpace Y] : - IsProperMap f ↔ Continuous f ∧ ∀ ⦃K⦄, IsCompact K → IsCompact (f ⁻¹' K) := - _root_.isProperMap_iff_isCompact_preimage - (fun _ ↦ compactlyGenerated_of_sequentialSpace) - -/-- Version of `isProperMap_iff_isCompact_preimage` in terms of `cocompact`. -/ -lemma isProperMap_iff_tendsto_cocompact [T2Space Y] - (compactlyGenerated : ∀ s : Set Y, IsClosed s ↔ ∀ ⦃K⦄, IsCompact K → IsClosed (s ∩ K)) : - IsProperMap f ↔ Continuous f ∧ Tendsto f (cocompact X) (cocompact Y) := by - simp_rw [isProperMap_iff_isCompact_preimage compactlyGenerated, - hasBasis_cocompact.tendsto_right_iff, ← mem_preimage, eventually_mem_set, preimage_compl] - refine and_congr_right fun f_cont ↦ - ⟨fun H K hK ↦ (H hK).compl_mem_cocompact, fun H K hK ↦ ?_⟩ - rcases mem_cocompact.mp (H K hK) with ⟨K', hK', hK'y⟩ - exact hK'.of_isClosed_subset (hK.isClosed.preimage f_cont) - (compl_le_compl_iff_le.mp hK'y) - -/-- Version of `WeaklyLocallyCompactSpace.isProperMap_iff_isCompact_preimage` -in terms of `cocompact`. -/ -lemma WeaklyLocallyCompactSpace.isProperMap_iff_tendsto_cocompact [T2Space Y] - [WeaklyLocallyCompactSpace Y] : - IsProperMap f ↔ Continuous f ∧ Tendsto f (cocompact X) (cocompact Y) := - _root_.isProperMap_iff_tendsto_cocompact - (fun _ ↦ compactlyGenerated_of_weaklyLocallyCompactSpace) - -/-- Version of `SequentialSpace.isProperMap_iff_isCompact_preimage` in terms of `cocompact`. -/ -lemma SequentialSpace.isProperMap_iff_tendsto_cocompact [T2Space Y] [SequentialSpace Y] : - IsProperMap f ↔ Continuous f ∧ Tendsto f (cocompact X) (cocompact Y) := - _root_.isProperMap_iff_tendsto_cocompact - (fun _ ↦ compactlyGenerated_of_sequentialSpace) - /-- A proper map `f : X → Y` is **universally closed**: for any topological space `Z`, the map `Prod.map f id : X × Z → Y × Z` is closed. We will prove in `isProperMap_iff_universally_closed` that proper maps are exactly continuous maps which have this property, but this result should be diff --git a/Mathlib/Topology/Maps/Proper/CompactlyGenerated.lean b/Mathlib/Topology/Maps/Proper/CompactlyGenerated.lean new file mode 100644 index 00000000000000..6213ed0602433d --- /dev/null +++ b/Mathlib/Topology/Maps/Proper/CompactlyGenerated.lean @@ -0,0 +1,48 @@ +/- +Copyright (c) 2024 Anatole Dedecker. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Anatole Dedecker, Etienne Marion +-/ +import Mathlib.Topology.Compactness.CompactlyGeneratedSpace +import Mathlib.Topology.Maps.Proper.Basic + +/-! +# A map is proper iff preimage of compact sets are compact + +This file proves that if `Y` is a Hausdorff and compactly generated space, a continuous map +`f : X → Y` is proper if and only if preimage of compact sets are compact. +-/ + +open Set Filter + +variable {X Y : Type*} [TopologicalSpace X] [TopologicalSpace Y] +variable [T2Space Y] [CompactlyGeneratedSpace Y] +variable {f : X → Y} + +/-- If `Y` is Hausdorff and compactly generated, then proper maps `X → Y` are exactly +continuous maps such that the preimage of any compact set is compact. This is in particular true +if `Y` is Hausdorff and sequential or locally compact. + +There was an older version of this theorem which was changed to this one to make use +of the `CompactlyGeneratedSpace` typeclass. (since 2024-11-10) -/ +theorem isProperMap_iff_isCompact_preimage : + IsProperMap f ↔ Continuous f ∧ ∀ ⦃K⦄, IsCompact K → IsCompact (f ⁻¹' K) where + mp hf := ⟨hf.continuous, fun _ ↦ hf.isCompact_preimage⟩ + mpr := fun ⟨hf, h⟩ ↦ isProperMap_iff_isClosedMap_and_compact_fibers.2 + ⟨hf, fun _ hs ↦ CompactlyGeneratedSpace.isClosed + fun _ hK ↦ image_inter_preimage .. ▸ (((h hK).inter_left hs).image hf).isClosed, + fun _ ↦ h isCompact_singleton⟩ + +/-- Version of `isProperMap_iff_isCompact_preimage` in terms of `cocompact`. + +There was an older version of this theorem which was changed to this one to make use +of the `CompactlyGeneratedSpace` typeclass. (since 2024-11-10) -/ +lemma isProperMap_iff_tendsto_cocompact : + IsProperMap f ↔ Continuous f ∧ Tendsto f (cocompact X) (cocompact Y) := by + simp_rw [isProperMap_iff_isCompact_preimage, + hasBasis_cocompact.tendsto_right_iff, ← mem_preimage, eventually_mem_set, preimage_compl] + refine and_congr_right fun f_cont ↦ + ⟨fun H K hK ↦ (H hK).compl_mem_cocompact, fun H K hK ↦ ?_⟩ + rcases mem_cocompact.mp (H K hK) with ⟨K', hK', hK'y⟩ + exact hK'.of_isClosed_subset (hK.isClosed.preimage f_cont) + (compl_le_compl_iff_le.mp hK'y) From c8c6a5f1a3ba9144952373e10841e7bd3211f17e Mon Sep 17 00:00:00 2001 From: Daniel Weber Date: Mon, 14 Oct 2024 12:17:39 +0000 Subject: [PATCH 106/425] feat(Order/SuccPred): add instances for OrdConnected subtypes (#16766) Co-authored-by: Daniel Weber <55664973+Command-Master@users.noreply.github.com> --- Mathlib/Order/SuccPred/Archimedean.lean | 98 +++++++++++++++++++++++++ Mathlib/Order/SuccPred/Basic.lean | 75 +++++++++++++++++++ 2 files changed, 173 insertions(+) diff --git a/Mathlib/Order/SuccPred/Archimedean.lean b/Mathlib/Order/SuccPred/Archimedean.lean index 0db5ba2b123202..1518b8b1fdbcaa 100644 --- a/Mathlib/Order/SuccPred/Archimedean.lean +++ b/Mathlib/Order/SuccPred/Archimedean.lean @@ -68,6 +68,19 @@ theorem Succ.rec_iff {p : α → Prop} (hsucc : ∀ a, p a ↔ p (succ a)) {a b obtain ⟨n, rfl⟩ := h.exists_succ_iterate exact Iterate.rec (fun b => p a ↔ p b) (fun c hc => hc.trans (hsucc _)) Iff.rfl n +lemma le_total_of_codirected {r v₁ v₂ : α} (h₁ : r ≤ v₁) (h₂ : r ≤ v₂) : v₁ ≤ v₂ ∨ v₂ ≤ v₁ := by + obtain ⟨n, rfl⟩ := h₁.exists_succ_iterate + obtain ⟨m, rfl⟩ := h₂.exists_succ_iterate + clear h₁ h₂ + wlog h : n ≤ m + · rw [Or.comm] + apply this + exact Nat.le_of_not_ge h + left + obtain ⟨k, rfl⟩ := Nat.exists_eq_add_of_le h + rw [Nat.add_comm, Function.iterate_add, Function.comp_apply] + apply Order.le_succ_iterate + end SuccOrder section PredOrder @@ -93,10 +106,59 @@ theorem Pred.rec_iff {p : α → Prop} (hsucc : ∀ a, p a ↔ p (pred a)) {a b p a ↔ p b := (Succ.rec_iff (α := αᵒᵈ) hsucc h).symm +lemma le_total_of_directed {r v₁ v₂ : α} (h₁ : v₁ ≤ r) (h₂ : v₂ ≤ r) : v₁ ≤ v₂ ∨ v₂ ≤ v₁ := + Or.symm (le_total_of_codirected (α := αᵒᵈ) h₁ h₂) + end PredOrder end Preorder +section PartialOrder + +variable [PartialOrder α] + +lemma lt_or_le_of_codirected [SuccOrder α] [IsSuccArchimedean α] {r v₁ v₂ : α} (h₁ : r ≤ v₁) + (h₂ : r ≤ v₂) : v₁ < v₂ ∨ v₂ ≤ v₁ := by + rw [Classical.or_iff_not_imp_right] + intro nh + rcases le_total_of_codirected h₁ h₂ with h | h + · apply lt_of_le_of_ne h (ne_of_not_le nh).symm + · contradiction + +/-- +This isn't an instance due to a loop with `LinearOrder`. +-/ +-- See note [reducible non instances] +abbrev IsSuccArchimedean.linearOrder [SuccOrder α] [IsSuccArchimedean α] + [DecidableEq α] [@DecidableRel α (· ≤ ·)] [@DecidableRel α (· < ·)] [IsDirected α (· ≥ ·)] : + LinearOrder α where + le_total a b := + have ⟨c, ha, hb⟩ := directed_of (· ≥ ·) a b + le_total_of_codirected ha hb + decidableEq := inferInstance + decidableLE := inferInstance + decidableLT := inferInstance + +lemma lt_or_le_of_directed [PredOrder α] [IsPredArchimedean α] {r v₁ v₂ : α} (h₁ : v₁ ≤ r) + (h₂ : v₂ ≤ r) : v₁ < v₂ ∨ v₂ ≤ v₁ := by + rw [Classical.or_iff_not_imp_right] + intro nh + rcases le_total_of_directed h₁ h₂ with h | h + · apply lt_of_le_of_ne h (ne_of_not_le nh).symm + · contradiction + +/-- +This isn't an instance due to a loop with `LinearOrder`. +-/ +-- See note [reducible non instances] +abbrev IsPredArchimedean.linearOrder [PredOrder α] [IsPredArchimedean α] + [DecidableEq α] [@DecidableRel α (· ≤ ·)] [@DecidableRel α (· < ·)] [IsDirected α (· ≤ ·)] : + LinearOrder α := + letI : LinearOrder αᵒᵈ := IsSuccArchimedean.linearOrder + inferInstanceAs (LinearOrder αᵒᵈᵒᵈ) + +end PartialOrder + section LinearOrder variable [LinearOrder α] @@ -298,3 +360,39 @@ protected lemma IsPredArchimedean.of_orderIso [PredOrder X] [IsPredArchimedean X | succ n IH => simp only [Function.iterate_succ', Function.comp_apply, IH, f.map_pred] end OrderIso + +section OrdConnected + +variable [PartialOrder α] + +instance Set.OrdConnected.isPredArchimedean [PredOrder α] [IsPredArchimedean α] + (s : Set α) [s.OrdConnected] : IsPredArchimedean s where + exists_pred_iterate_of_le := @fun ⟨b, hb⟩ ⟨c, hc⟩ hbc ↦ by classical + simp only [Subtype.mk_le_mk] at hbc + obtain ⟨n, hn⟩ := hbc.exists_pred_iterate + use n + induction n generalizing c with + | zero => simp_all + | succ n hi => + simp_all only [Function.iterate_succ, Function.comp_apply] + change Order.pred^[n] (dite ..) = _ + split_ifs with h + · dsimp only at h ⊢ + apply hi _ _ _ hn + · rw [← hn] + apply Order.pred_iterate_le + · have : Order.pred (⟨c, hc⟩ : s) = ⟨c, hc⟩ := by + change dite .. = _ + simp [h] + rw [Function.iterate_fixed] + · simp only [Order.pred_eq_iff_isMin] at this + apply (this.eq_of_le _).symm + exact hbc + · exact this + +instance Set.OrdConnected.isSuccArchimedean [SuccOrder α] [IsSuccArchimedean α] + (s : Set α) [s.OrdConnected] : IsSuccArchimedean s := + letI : IsPredArchimedean sᵒᵈ := inferInstanceAs (IsPredArchimedean (OrderDual.ofDual ⁻¹' s)) + inferInstanceAs (IsSuccArchimedean sᵒᵈᵒᵈ) + +end OrdConnected diff --git a/Mathlib/Order/SuccPred/Basic.lean b/Mathlib/Order/SuccPred/Basic.lean index 43142cc9da3866..5620dbe15bbf18 100644 --- a/Mathlib/Order/SuccPred/Basic.lean +++ b/Mathlib/Order/SuccPred/Basic.lean @@ -1237,3 +1237,78 @@ protected abbrev PredOrder.ofOrderIso [PredOrder X] (f : X ≃o Y) : le_pred_of_lt h := by rw [← map_inv_le_iff]; exact le_pred_of_lt (by simp [h]) end OrderIso + +section OrdConnected + +variable {α : Type*} [PartialOrder α] {s : Set α} [s.OrdConnected] + +open scoped Classical in +noncomputable instance Set.OrdConnected.predOrder [PredOrder α] : + PredOrder s where + pred x := if h : Order.pred x.1 ∈ s then ⟨Order.pred x.1, h⟩ else x + pred_le := fun ⟨x, hx⟩ ↦ by dsimp; split <;> simp_all [Order.pred_le] + min_of_le_pred := @fun ⟨x, hx⟩ h ↦ by + dsimp at h + split_ifs at h with h' + · simp only [Subtype.mk_le_mk, Order.le_pred_iff_isMin] at h + rintro ⟨y, _⟩ hy + simp [h hy] + · rintro ⟨y, hy⟩ h + rcases h.lt_or_eq with h | h + · simp only [Subtype.mk_lt_mk] at h + have := h.le_pred + absurd h' + apply out' hy hx + simp [this, Order.pred_le] + · simp [h] + le_pred_of_lt := @fun ⟨b, hb⟩ ⟨c, hc⟩ h ↦ by + rw [Subtype.mk_lt_mk] at h + dsimp only + split + · exact h.le_pred + · exact h.le + +@[simp, norm_cast] +lemma coe_pred_of_mem [PredOrder α] {a : s} (h : pred a.1 ∈ s) : + (pred a).1 = pred ↑a := by classical + change Subtype.val (dite ..) = _ + simp [h] + +lemma isMin_of_not_pred_mem [PredOrder α] {a : s} (h : pred ↑a ∉ s) : IsMin a := by classical + rw [← pred_eq_iff_isMin] + change dite .. = _ + simp [h] + +lemma not_pred_mem_iff_isMin [PredOrder α] [NoMinOrder α] {a : s} : + pred ↑a ∉ s ↔ IsMin a where + mp := isMin_of_not_pred_mem + mpr h nh := by + replace h := congr($h.pred_eq.1) + rw [coe_pred_of_mem nh] at h + simp at h + +noncomputable instance Set.OrdConnected.succOrder [SuccOrder α] : + SuccOrder s := + letI : PredOrder sᵒᵈ := inferInstanceAs (PredOrder (OrderDual.ofDual ⁻¹' s)) + inferInstanceAs (SuccOrder sᵒᵈᵒᵈ) + +@[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 + +lemma isMax_of_not_succ_mem [SuccOrder α] {a : s} (h : succ ↑a ∉ s) : IsMax a := by classical + rw [← succ_eq_iff_isMax] + change dite .. = _ + split_ifs <;> trivial + +lemma not_succ_mem_iff_isMax [SuccOrder α] [NoMaxOrder α] {a : s} : + succ ↑a ∉ s ↔ IsMax a where + mp := isMax_of_not_succ_mem + mpr h nh := by + replace h := congr($h.succ_eq.1) + rw [coe_succ_of_mem nh] at h + simp at h + +end OrdConnected From 2ed7908c53ea500b6846c6a9782474148b221a79 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Mon, 14 Oct 2024 12:17:40 +0000 Subject: [PATCH 107/425] chore: unused arguments (#17348) --- Mathlib/Algebra/Algebra/Basic.lean | 4 +- Mathlib/Algebra/Algebra/Equiv.lean | 6 +- Mathlib/Algebra/Algebra/Hom.lean | 6 +- Mathlib/Algebra/Algebra/Operations.lean | 8 +- Mathlib/Algebra/Algebra/Opposite.lean | 2 +- Mathlib/Algebra/Algebra/Subalgebra/Basic.lean | 4 +- Mathlib/Algebra/Algebra/Tower.lean | 4 +- Mathlib/Algebra/Algebra/ZMod.lean | 2 +- Mathlib/Algebra/Associated/Basic.lean | 2 +- Mathlib/Algebra/BigOperators/Associated.lean | 2 +- Mathlib/Algebra/BigOperators/Finsupp.lean | 2 +- .../Algebra/BigOperators/Group/Finset.lean | 4 +- Mathlib/Algebra/BigOperators/Group/List.lean | 2 +- Mathlib/Algebra/BigOperators/Intervals.lean | 4 +- .../Algebra/Category/AlgebraCat/Basic.lean | 2 +- .../Algebra/Category/AlgebraCat/Monoidal.lean | 8 +- .../Algebra/Category/BialgebraCat/Basic.lean | 4 +- Mathlib/Algebra/Category/BoolRing.lean | 8 +- .../Algebra/Category/CoalgebraCat/Basic.lean | 2 +- .../Category/CoalgebraCat/Monoidal.lean | 2 +- Mathlib/Algebra/Category/Grp/Adjunctions.lean | 22 ++--- Mathlib/Algebra/Category/Grp/Basic.lean | 4 +- Mathlib/Algebra/Category/Grp/Biproducts.lean | 2 +- .../Category/Grp/EnoughInjectives.lean | 2 +- .../Grp/EquivalenceGroupAddGroup.lean | 8 +- Mathlib/Algebra/Category/Grp/Limits.lean | 2 +- .../Category/HopfAlgebraCat/Basic.lean | 4 +- .../Category/ModuleCat/Adjunctions.lean | 20 ++--- .../Algebra/Category/ModuleCat/Algebra.lean | 2 +- Mathlib/Algebra/Category/ModuleCat/Basic.lean | 2 +- .../Category/ModuleCat/Biproducts.lean | 2 +- .../Category/ModuleCat/ChangeOfRings.lean | 14 ++-- .../Algebra/Category/ModuleCat/Colimits.lean | 2 +- .../Algebra/Category/ModuleCat/EpiMono.lean | 2 +- .../Algebra/Category/ModuleCat/Kernels.lean | 2 +- .../Category/ModuleCat/Monoidal/Closed.lean | 2 +- .../Category/ModuleCat/Presheaf/Colimits.lean | 2 +- .../Category/ModuleCat/Presheaf/Limits.lean | 2 +- .../Algebra/Category/MonCat/Adjunctions.lean | 4 +- Mathlib/Algebra/Category/MonCat/Basic.lean | 6 +- Mathlib/Algebra/Category/MonCat/Colimits.lean | 2 +- Mathlib/Algebra/Category/MonCat/Limits.lean | 2 +- .../Algebra/Category/Ring/Adjunctions.lean | 2 +- Mathlib/Algebra/Category/Ring/Basic.lean | 6 +- Mathlib/Algebra/Category/Ring/Colimits.lean | 22 ++--- .../Algebra/Category/Ring/Constructions.lean | 2 +- Mathlib/Algebra/Category/Ring/Limits.lean | 2 +- Mathlib/Algebra/CharP/Defs.lean | 2 +- Mathlib/Algebra/CharZero/Lemmas.lean | 2 +- Mathlib/Algebra/DirectLimit.lean | 14 ++-- Mathlib/Algebra/DirectSum/Basic.lean | 2 +- Mathlib/Algebra/DirectSum/Module.lean | 2 +- Mathlib/Algebra/DirectSum/Ring.lean | 2 +- Mathlib/Algebra/Divisibility/Units.lean | 2 +- Mathlib/Algebra/DualNumber.lean | 21 +++++ Mathlib/Algebra/DualQuaternion.lean | 12 ++- Mathlib/Algebra/EuclideanDomain/Field.lean | 6 +- Mathlib/Algebra/Field/Basic.lean | 4 +- Mathlib/Algebra/Field/IsField.lean | 4 +- Mathlib/Algebra/Field/MinimalAxioms.lean | 4 +- Mathlib/Algebra/Field/Opposite.lean | 8 +- Mathlib/Algebra/Field/Rat.lean | 6 +- Mathlib/Algebra/Free.lean | 28 +++---- Mathlib/Algebra/FreeMonoid/Basic.lean | 4 +- Mathlib/Algebra/GCDMonoid/Basic.lean | 26 +++--- Mathlib/Algebra/GCDMonoid/Nat.lean | 8 +- Mathlib/Algebra/GeomSum.lean | 6 +- Mathlib/Algebra/Group/Action/Defs.lean | 8 +- Mathlib/Algebra/Group/Action/Units.lean | 4 +- Mathlib/Algebra/Group/Basic.lean | 2 +- Mathlib/Algebra/Group/Conj.lean | 4 +- Mathlib/Algebra/Group/Hom/Basic.lean | 2 +- Mathlib/Algebra/Group/Hom/Defs.lean | 4 +- Mathlib/Algebra/Group/Indicator.lean | 2 +- Mathlib/Algebra/Group/Opposite.lean | 2 +- Mathlib/Algebra/Group/Pi/Lemmas.lean | 2 +- .../Algebra/Group/Pointwise/Finset/Basic.lean | 2 +- Mathlib/Algebra/Group/Prod.lean | 8 +- Mathlib/Algebra/Group/Subgroup/Basic.lean | 16 ++-- Mathlib/Algebra/Group/Subgroup/Pointwise.lean | 6 +- Mathlib/Algebra/Group/Submonoid/Basic.lean | 6 +- .../Algebra/Group/Submonoid/Membership.lean | 2 +- .../Algebra/Group/Submonoid/Operations.lean | 2 +- .../Algebra/Group/Submonoid/Pointwise.lean | 4 +- Mathlib/Algebra/Group/UniqueProds/Basic.lean | 2 +- Mathlib/Algebra/Group/WithOne/Basic.lean | 4 +- .../Algebra/GroupWithZero/Action/Defs.lean | 2 +- Mathlib/Algebra/GroupWithZero/Basic.lean | 2 +- Mathlib/Algebra/GroupWithZero/Hom.lean | 7 ++ Mathlib/Algebra/GroupWithZero/WithZero.lean | 20 ++--- Mathlib/Algebra/Homology/Additive.lean | 6 +- Mathlib/Algebra/Homology/Augment.lean | 18 ++--- Mathlib/Algebra/Homology/BifunctorShift.lean | 4 +- Mathlib/Algebra/Homology/Functor.lean | 2 +- .../Homology/HomologicalBicomplex.lean | 6 +- .../Algebra/Homology/HomologicalComplex.lean | 6 +- .../Homology/HomologicalComplexLimits.lean | 2 +- Mathlib/Algebra/Homology/Homotopy.lean | 4 +- .../Homology/HomotopyCategory/Shift.lean | 6 +- Mathlib/Algebra/Homology/HomotopyCofiber.lean | 2 +- Mathlib/Algebra/Homology/Localization.lean | 4 +- Mathlib/Algebra/Homology/Opposite.lean | 8 +- Mathlib/Algebra/Homology/Single.lean | 2 +- Mathlib/Algebra/IsPrimePow.lean | 2 +- Mathlib/Algebra/Lie/BaseChange.lean | 2 +- Mathlib/Algebra/Lie/Derivation/Basic.lean | 2 +- Mathlib/Algebra/Lie/DirectSum.lean | 4 +- Mathlib/Algebra/Lie/Subalgebra.lean | 4 +- Mathlib/Algebra/Lie/Submodule.lean | 4 +- Mathlib/Algebra/Lie/TensorProduct.lean | 4 +- Mathlib/Algebra/Module/BigOperators.lean | 2 +- Mathlib/Algebra/Module/CharacterModule.lean | 4 +- Mathlib/Algebra/Module/Equiv/Basic.lean | 6 +- Mathlib/Algebra/Module/Injective.lean | 2 +- Mathlib/Algebra/Module/LinearMap/Defs.lean | 2 +- Mathlib/Algebra/Module/LinearMap/End.lean | 2 +- Mathlib/Algebra/Module/LocalizedModule.lean | 4 +- .../Algebra/Module/Submodule/Bilinear.lean | 2 +- Mathlib/Algebra/Module/Submodule/Equiv.lean | 2 +- Mathlib/Algebra/Module/Submodule/Map.lean | 4 +- Mathlib/Algebra/Module/Submodule/Range.lean | 2 +- Mathlib/Algebra/MonoidAlgebra/Grading.lean | 2 +- Mathlib/Algebra/MvPolynomial/Basic.lean | 2 +- Mathlib/Algebra/MvPolynomial/CommRing.lean | 2 +- Mathlib/Algebra/MvPolynomial/PDeriv.lean | 2 +- Mathlib/Algebra/Order/Antidiag/Finsupp.lean | 2 +- Mathlib/Algebra/Order/Antidiag/Pi.lean | 4 +- Mathlib/Algebra/Order/Antidiag/Prod.lean | 2 +- Mathlib/Algebra/Order/CauSeq/Basic.lean | 12 +-- Mathlib/Algebra/Order/CauSeq/Completion.lean | 6 +- Mathlib/Algebra/Order/CompleteField.lean | 2 +- .../Algebra/Order/Field/Canonical/Defs.lean | 2 +- Mathlib/Algebra/Order/Floor.lean | 2 +- Mathlib/Algebra/Order/Group/Cone.lean | 2 +- Mathlib/Algebra/Order/Group/Defs.lean | 2 +- .../Order/GroupWithZero/Unbundled.lean | 2 +- .../Algebra/Order/GroupWithZero/WithZero.lean | 4 +- Mathlib/Algebra/Order/Hom/Basic.lean | 2 +- Mathlib/Algebra/Order/Monoid/Defs.lean | 2 +- .../Algebra/Order/Monoid/Unbundled/Basic.lean | 4 +- Mathlib/Algebra/Order/Ring/Basic.lean | 2 +- Mathlib/Algebra/Order/Ring/Canonical.lean | 4 +- Mathlib/Algebra/Order/Ring/Cone.lean | 2 +- Mathlib/Algebra/Order/Ring/Rat.lean | 4 +- Mathlib/Algebra/Polynomial/EraseLead.lean | 12 +-- Mathlib/Algebra/Polynomial/FieldDivision.lean | 4 +- .../Algebra/Polynomial/GroupRingAction.lean | 4 +- Mathlib/Algebra/Polynomial/Laurent.lean | 4 +- Mathlib/Algebra/Polynomial/Mirror.lean | 2 +- Mathlib/Algebra/Polynomial/Module/Basic.lean | 2 +- Mathlib/Algebra/Polynomial/RingDivision.lean | 6 ++ Mathlib/Algebra/Polynomial/Roots.lean | 2 +- Mathlib/Algebra/Polynomial/Splits.lean | 2 +- Mathlib/Algebra/Polynomial/Taylor.lean | 2 +- Mathlib/Algebra/Quandle.lean | 12 +-- Mathlib/Algebra/Ring/BooleanRing.lean | 2 +- Mathlib/Algebra/Ring/Hom/Defs.lean | 6 +- Mathlib/Algebra/Ring/Prod.lean | 4 +- Mathlib/Algebra/Ring/Subring/Basic.lean | 24 +++--- Mathlib/Algebra/RingQuot.lean | 6 +- Mathlib/Algebra/Star/CentroidHom.lean | 2 +- Mathlib/Algebra/Star/NonUnitalSubalgebra.lean | 4 +- Mathlib/Algebra/Star/Subalgebra.lean | 4 +- Mathlib/AlgebraicGeometry/Cover/Open.lean | 12 +-- Mathlib/AlgebraicGeometry/Gluing.lean | 8 +- .../GluingOneHypercover.lean | 2 +- Mathlib/AlgebraicGeometry/Limits.lean | 2 +- Mathlib/AlgebraicGeometry/Modules/Tilde.lean | 2 +- .../AlgebraicGeometry/Morphisms/Basic.lean | 6 +- .../Morphisms/Constructors.lean | 2 +- .../Morphisms/FiniteType.lean | 2 +- .../AlgebraicGeometry/Morphisms/IsIso.lean | 2 +- .../ProjectiveSpectrum/Scheme.lean | 2 +- .../ProjectiveSpectrum/StructureSheaf.lean | 6 +- Mathlib/AlgebraicGeometry/Pullbacks.lean | 4 +- .../AlgebraicGeometry/Sites/BigZariski.lean | 2 +- Mathlib/AlgebraicGeometry/Spec.lean | 2 +- Mathlib/AlgebraicGeometry/StructureSheaf.lean | 30 +++---- Mathlib/AlgebraicTopology/CechNerve.lean | 8 +- .../AlgebraicTopology/DoldKan/GammaCompN.lean | 2 +- .../AlgebraicTopology/DoldKan/Homotopies.lean | 2 +- .../DoldKan/Projections.lean | 4 +- .../AlgebraicTopology/ExtraDegeneracy.lean | 2 +- .../FundamentalGroupoid/Basic.lean | 14 ++-- .../FundamentalGroupoid/Product.lean | 4 +- .../AlgebraicTopology/SimplexCategory.lean | 2 +- .../SimplicialCategory/SimplicialObject.lean | 2 +- .../AlgebraicTopology/SimplicialObject.lean | 4 +- .../SimplicialSet/Basic.lean | 16 +++- .../SimplicialSet/Nerve.lean | 2 +- .../SplitSimplicialObject.lean | 2 +- Mathlib/Analysis/Analytic/Basic.lean | 2 +- Mathlib/Analysis/Analytic/CPolynomial.lean | 2 +- Mathlib/Analysis/Analytic/Composition.lean | 2 +- Mathlib/Analysis/Analytic/Constructions.lean | 2 +- Mathlib/Analysis/Asymptotics/Asymptotics.lean | 8 +- Mathlib/Analysis/BoxIntegral/Basic.lean | 4 +- .../Analysis/BoxIntegral/Partition/Basic.lean | 12 +-- .../Analysis/BoxIntegral/Partition/Split.lean | 4 +- .../ContinuousFunctionalCalculus/Unique.lean | 2 +- .../Analysis/CStarAlgebra/Module/Defs.lean | 2 +- Mathlib/Analysis/CStarAlgebra/Multiplier.lean | 2 +- .../Calculus/BumpFunction/InnerProduct.lean | 2 +- Mathlib/Analysis/Calculus/ContDiff/Basic.lean | 2 +- .../Analysis/Calculus/LineDeriv/Basic.lean | 4 +- .../Calculus/LocalExtr/Polynomial.lean | 4 +- Mathlib/Analysis/Calculus/MeanValue.lean | 8 +- .../Complex/UpperHalfPlane/Basic.lean | 2 +- Mathlib/Analysis/Convex/Basic.lean | 4 +- Mathlib/Analysis/Convex/Body.lean | 2 +- Mathlib/Analysis/Convex/Caratheodory.lean | 2 +- Mathlib/Analysis/Convex/Combination.lean | 2 +- Mathlib/Analysis/Convex/Gauge.lean | 2 +- Mathlib/Analysis/Convex/Normed.lean | 2 +- Mathlib/Analysis/Convex/Segment.lean | 4 +- .../Analysis/InnerProductSpace/Adjoint.lean | 4 +- Mathlib/Analysis/InnerProductSpace/Basic.lean | 6 +- Mathlib/Analysis/LocallyConvex/Bounded.lean | 2 +- .../Analysis/LocallyConvex/WithSeminorms.lean | 4 +- .../Normed/Affine/ContinuousAffineMap.lean | 2 +- .../Analysis/Normed/Algebra/Exponential.lean | 2 +- .../Normed/Algebra/MatrixExponential.lean | 2 +- Mathlib/Analysis/Normed/Algebra/Spectrum.lean | 4 +- Mathlib/Analysis/Normed/Group/Basic.lean | 2 +- Mathlib/Analysis/Normed/Group/Hom.lean | 2 +- .../Analysis/Normed/Group/SemiNormedGrp.lean | 2 +- .../Normed/Group/SemiNormedGrp/Kernels.lean | 6 +- Mathlib/Analysis/Normed/Group/Seminorm.lean | 16 ++-- Mathlib/Analysis/Normed/Lp/LpEquiv.lean | 2 +- Mathlib/Analysis/Normed/Lp/PiLp.lean | 2 +- Mathlib/Analysis/Normed/Lp/lpSpace.lean | 2 +- .../Normed/Operator/BoundedLinearMaps.lean | 2 +- Mathlib/Analysis/NormedSpace/BallAction.lean | 12 +-- Mathlib/Analysis/NormedSpace/ENorm.lean | 16 ++-- .../NormedSpace/Multilinear/Basic.lean | 8 +- .../NormedSpace/Multilinear/Curry.lean | 8 +- Mathlib/Analysis/ODE/PicardLindelof.lean | 4 +- Mathlib/Analysis/Quaternion.lean | 4 +- Mathlib/Analysis/RCLike/Basic.lean | 10 +-- Mathlib/Analysis/Seminorm.lean | 8 +- .../SpecialFunctions/Complex/LogBounds.lean | 2 +- .../SpecialFunctions/Complex/LogDeriv.lean | 4 +- Mathlib/Analysis/SpecialFunctions/Exp.lean | 2 +- .../SpecialFunctions/Pow/Asymptotics.lean | 6 +- .../Analysis/SpecialFunctions/Pow/Real.lean | 8 ++ .../SpecialFunctions/Trigonometric/Basic.lean | 4 +- .../Abelian/Pseudoelements.lean | 2 +- .../CategoryTheory/Adjunction/Evaluation.lean | 8 +- .../Adjunction/FullyFaithful.lean | 2 +- .../Adjunction/Lifting/Left.lean | 7 ++ .../CategoryTheory/Bicategory/Coherence.lean | 4 +- Mathlib/CategoryTheory/Bicategory/End.lean | 4 +- Mathlib/CategoryTheory/Bicategory/Free.lean | 26 +++--- .../Bicategory/FunctorBicategory.lean | 10 +-- .../Bicategory/LocallyDiscrete.lean | 10 +-- .../NaturalTransformation/Oplax.lean | 2 +- .../NaturalTransformation/Strong.lean | 2 +- .../CategoryTheory/Bicategory/SingleObj.lean | 4 +- .../CategoryTheory/Category/Bipointed.lean | 4 +- Mathlib/CategoryTheory/Category/Cat.lean | 14 ++-- .../CategoryTheory/Category/Cat/Limit.lean | 4 +- .../CategoryTheory/Category/PartialFun.lean | 8 +- Mathlib/CategoryTheory/Category/Pointed.lean | 2 +- Mathlib/CategoryTheory/Category/RelCat.lean | 6 +- Mathlib/CategoryTheory/Category/TwoP.lean | 4 +- Mathlib/CategoryTheory/Category/ULift.lean | 16 ++-- .../ChosenFiniteProducts/FunctorCategory.lean | 2 +- Mathlib/CategoryTheory/Closed/Types.lean | 2 +- Mathlib/CategoryTheory/Closed/Zero.lean | 2 +- Mathlib/CategoryTheory/CofilteredSystem.lean | 2 +- Mathlib/CategoryTheory/Comma/Presheaf.lean | 8 +- Mathlib/CategoryTheory/ComposableArrows.lean | 4 +- .../ConcreteCategory/BundledHom.lean | 10 +-- Mathlib/CategoryTheory/Core.lean | 2 +- Mathlib/CategoryTheory/Dialectica/Basic.lean | 2 +- Mathlib/CategoryTheory/DiscreteCategory.lean | 10 +-- .../CategoryTheory/EffectiveEpi/Basic.lean | 4 +- Mathlib/CategoryTheory/EffectiveEpi/Comp.lean | 2 +- Mathlib/CategoryTheory/Endomorphism.lean | 4 +- Mathlib/CategoryTheory/Enriched/Basic.lean | 8 +- .../FiberedCategory/BasedCategory.lean | 10 +-- .../FiberedCategory/HomLift.lean | 8 +- Mathlib/CategoryTheory/Filtered/Basic.lean | 2 +- .../CategoryTheory/FinCategory/AsType.lean | 6 +- Mathlib/CategoryTheory/Functor/Const.lean | 10 +-- Mathlib/CategoryTheory/Functor/Currying.lean | 4 +- Mathlib/CategoryTheory/Functor/EpiMono.lean | 8 +- Mathlib/CategoryTheory/Functor/Flat.lean | 4 +- .../CategoryTheory/Functor/FunctorHom.lean | 2 +- .../CategoryTheory/Functor/OfSequence.lean | 2 +- .../CategoryTheory/Functor/Trifunctor.lean | 4 +- Mathlib/CategoryTheory/Galois/Basic.lean | 2 +- Mathlib/CategoryTheory/Galois/Examples.lean | 6 +- .../Galois/IsFundamentalgroup.lean | 2 +- Mathlib/CategoryTheory/Generator.lean | 8 +- Mathlib/CategoryTheory/GlueData.lean | 8 +- .../GradedObject/Trifunctor.lean | 6 +- Mathlib/CategoryTheory/Grothendieck.lean | 6 +- Mathlib/CategoryTheory/Groupoid.lean | 6 +- .../CategoryTheory/Groupoid/Subgroupoid.lean | 10 +-- .../CategoryTheory/GuitartExact/Basic.lean | 4 +- Mathlib/CategoryTheory/IsConnected.lean | 6 +- .../CategoryTheory/IsomorphismClasses.lean | 2 +- .../CategoryTheory/Limits/ConeCategory.lean | 8 +- Mathlib/CategoryTheory/Limits/Cones.lean | 4 +- Mathlib/CategoryTheory/Limits/Connected.lean | 4 +- .../Limits/Constructions/BinaryProducts.lean | 4 +- .../Limits/Constructions/Filtered.lean | 2 +- .../LimitsOfProductsAndEqualizers.lean | 4 +- .../Limits/FunctorCategory/Basic.lean | 2 +- Mathlib/CategoryTheory/Limits/HasLimits.lean | 6 +- .../Limits/Indization/IndObject.lean | 4 +- .../CategoryTheory/Limits/IsConnected.lean | 2 +- Mathlib/CategoryTheory/Limits/IsLimit.lean | 2 +- Mathlib/CategoryTheory/Limits/Lattice.lean | 8 +- Mathlib/CategoryTheory/Limits/Opposites.lean | 8 +- .../Limits/Preserves/Basic.lean | 12 +-- .../Limits/Preserves/Shapes/Zero.lean | 4 +- Mathlib/CategoryTheory/Limits/Presheaf.lean | 2 +- .../Limits/Shapes/BinaryProducts.lean | 8 +- .../Limits/Shapes/Biproducts.lean | 8 +- .../Limits/Shapes/ConcreteCategory.lean | 4 +- .../Limits/Shapes/Equalizers.lean | 12 +-- .../CategoryTheory/Limits/Shapes/Kernels.lean | 20 ++--- .../Limits/Shapes/Multiequalizer.lean | 8 +- .../Limits/Shapes/Pullback/CommSq.lean | 4 +- .../Limits/Shapes/Pullback/Mono.lean | 4 +- .../Limits/Shapes/StrongEpi.lean | 4 +- .../Limits/Shapes/Terminal.lean | 24 +++--- .../CategoryTheory/Limits/Shapes/Types.lean | 10 +-- .../Limits/Shapes/WideEqualizers.lean | 8 +- .../Limits/Shapes/WidePullbacks.lean | 8 +- .../Limits/Shapes/ZeroMorphisms.lean | 10 +-- Mathlib/CategoryTheory/Limits/Yoneda.lean | 4 +- .../Localization/CalculusOfFractions.lean | 6 +- .../Localization/Composition.lean | 2 +- .../Localization/Construction.lean | 4 +- .../Localization/Predicate.lean | 2 +- Mathlib/CategoryTheory/Monad/Adjunction.lean | 12 +-- Mathlib/CategoryTheory/Monad/Kleisli.lean | 12 +-- Mathlib/CategoryTheory/Monad/Monadicity.lean | 7 ++ Mathlib/CategoryTheory/Monad/Products.lean | 8 +- Mathlib/CategoryTheory/Monad/Types.lean | 6 +- .../Monoidal/Cartesian/Comon_.lean | 2 +- Mathlib/CategoryTheory/Monoidal/Comon_.lean | 2 +- Mathlib/CategoryTheory/Monoidal/Discrete.lean | 6 +- .../CategoryTheory/Monoidal/Free/Basic.lean | 8 +- .../Monoidal/Free/Coherence.lean | 4 +- Mathlib/CategoryTheory/Monoidal/Functor.lean | 8 +- .../Monoidal/FunctorCategory.lean | 2 +- .../CategoryTheory/Monoidal/Functorial.lean | 2 +- .../Monoidal/Internal/FunctorCategory.lean | 4 +- .../Monoidal/Internal/Module.lean | 26 +++--- .../Monoidal/Internal/Types.lean | 12 +-- Mathlib/CategoryTheory/Monoidal/Limits.lean | 4 +- Mathlib/CategoryTheory/Monoidal/Mon_.lean | 2 +- .../Monoidal/OfHasFiniteProducts.lean | 8 +- Mathlib/CategoryTheory/Monoidal/Opposite.lean | 4 +- .../CategoryTheory/Monoidal/Preadditive.lean | 6 +- .../Monoidal/Rigid/FunctorCategory.lean | 8 +- .../CategoryTheory/Monoidal/Subcategory.lean | 10 +-- .../CategoryTheory/Monoidal/Transport.lean | 2 +- .../Monoidal/Types/Coyoneda.lean | 2 +- .../MorphismProperty/Concrete.lean | 2 +- Mathlib/CategoryTheory/Opposites.lean | 14 ++-- Mathlib/CategoryTheory/PUnit.lean | 2 +- Mathlib/CategoryTheory/PathCategory.lean | 6 +- Mathlib/CategoryTheory/Pi/Basic.lean | 6 +- .../Preadditive/FunctorCategory.lean | 2 +- Mathlib/CategoryTheory/Preadditive/Mat.lean | 4 +- .../Preadditive/Projective.lean | 4 +- Mathlib/CategoryTheory/Preadditive/Schur.lean | 4 +- .../Preadditive/Yoneda/Basic.lean | 22 ++--- Mathlib/CategoryTheory/Products/Basic.lean | 10 +-- Mathlib/CategoryTheory/Quotient.lean | 2 +- Mathlib/CategoryTheory/Shift/CommShift.lean | 2 +- .../CategoryTheory/Shift/SingleFunctors.lean | 6 +- Mathlib/CategoryTheory/Sigma/Basic.lean | 4 +- Mathlib/CategoryTheory/Sites/Closed.lean | 2 +- .../Sites/ConcreteSheafification.lean | 4 +- Mathlib/CategoryTheory/Sites/Coverage.lean | 8 +- .../Sites/EffectiveEpimorphic.lean | 8 +- .../Sites/EqualizerSheafCondition.lean | 2 +- .../CategoryTheory/Sites/Grothendieck.lean | 26 +++--- .../CategoryTheory/Sites/InducedTopology.lean | 2 +- Mathlib/CategoryTheory/Sites/IsSheafFor.lean | 4 +- Mathlib/CategoryTheory/Sites/Limits.lean | 2 +- .../Sites/LocallyFullyFaithful.lean | 4 +- .../Sites/NonabelianCohomology/H1.lean | 4 +- Mathlib/CategoryTheory/Sites/Over.lean | 4 +- Mathlib/CategoryTheory/Sites/Plus.lean | 4 +- Mathlib/CategoryTheory/Sites/Pretopology.lean | 12 +-- Mathlib/CategoryTheory/Sites/Sheaf.lean | 14 ++-- Mathlib/CategoryTheory/Sites/SheafHom.lean | 4 +- Mathlib/CategoryTheory/Sites/Sieves.lean | 34 ++++---- Mathlib/CategoryTheory/Sites/Spaces.lean | 4 +- Mathlib/CategoryTheory/Sites/Subsheaf.lean | 8 +- Mathlib/CategoryTheory/Sites/Types.lean | 4 +- Mathlib/CategoryTheory/Sites/Whiskering.lean | 6 +- Mathlib/CategoryTheory/Skeletal.lean | 12 +-- Mathlib/CategoryTheory/Subobject/Comma.lean | 4 +- Mathlib/CategoryTheory/Subobject/Limits.lean | 4 +- .../CategoryTheory/Subobject/MonoOver.lean | 2 +- Mathlib/CategoryTheory/Subobject/Types.lean | 2 +- Mathlib/CategoryTheory/Subterminal.lean | 8 +- Mathlib/CategoryTheory/Sums/Basic.lean | 20 ++--- Mathlib/CategoryTheory/Types.lean | 6 +- Mathlib/CategoryTheory/Widesubcategory.lean | 4 +- Mathlib/CategoryTheory/WithTerminal.lean | 28 +++---- Mathlib/CategoryTheory/Yoneda.lean | 30 +++---- .../Combinatorics/Additive/FreimanHom.lean | 10 +-- Mathlib/Combinatorics/Colex.lean | 4 +- Mathlib/Combinatorics/Digraph/Basic.lean | 14 ++-- .../Enumerative/DoubleCounting.lean | 4 +- .../Combinatorics/Enumerative/DyckWord.lean | 4 +- Mathlib/Combinatorics/Hall/Basic.lean | 2 +- Mathlib/Combinatorics/SimpleGraph/Basic.lean | 18 ++--- .../Connectivity/WalkCounting.lean | 2 +- Mathlib/Combinatorics/SimpleGraph/Maps.lean | 2 +- .../SimpleGraph/Regularity/Bound.lean | 2 +- .../SimpleGraph/Regularity/Energy.lean | 2 +- .../SimpleGraph/StronglyRegular.lean | 2 +- .../Combinatorics/SimpleGraph/Subgraph.lean | 16 ++-- Mathlib/Computability/Ackermann.lean | 2 +- Mathlib/Computability/Halting.lean | 2 +- Mathlib/Computability/Language.lean | 2 +- Mathlib/Computability/Partrec.lean | 10 +-- Mathlib/Computability/PartrecCode.lean | 2 +- Mathlib/Computability/Primrec.lean | 8 +- Mathlib/Computability/Reduce.lean | 2 +- Mathlib/Computability/RegularExpressions.lean | 4 +- Mathlib/Computability/TuringMachine.lean | 12 +-- .../Condensed/Discrete/LocallyConstant.lean | 6 +- Mathlib/Control/EquivFunctor.lean | 2 +- Mathlib/Control/EquivFunctor/Instances.lean | 2 +- Mathlib/Control/Functor/Multivariate.lean | 8 +- Mathlib/Control/Traversable/Basic.lean | 4 +- Mathlib/Control/Traversable/Lemmas.lean | 2 +- Mathlib/Data/Analysis/Filter.lean | 4 +- Mathlib/Data/Bool/Count.lean | 2 +- Mathlib/Data/Complex/Abs.lean | 4 +- Mathlib/Data/Complex/Module.lean | 4 +- Mathlib/Data/Complex/Order.lean | 6 +- Mathlib/Data/DFinsupp/Basic.lean | 8 +- Mathlib/Data/DFinsupp/Order.lean | 4 +- Mathlib/Data/ENNReal/Basic.lean | 2 +- Mathlib/Data/ENNReal/Inv.lean | 2 +- Mathlib/Data/ENNReal/Real.lean | 2 +- Mathlib/Data/Fin/Tuple/Basic.lean | 10 +-- Mathlib/Data/Fin/Tuple/Reflection.lean | 4 +- Mathlib/Data/FinEnum.lean | 2 +- Mathlib/Data/Finite/Card.lean | 2 +- Mathlib/Data/Finmap.lean | 2 +- Mathlib/Data/Finset/Basic.lean | 10 +-- Mathlib/Data/Finset/Card.lean | 6 +- Mathlib/Data/Finset/Functor.lean | 14 ++-- Mathlib/Data/Finset/Grade.lean | 2 +- Mathlib/Data/Finset/Image.lean | 4 +- Mathlib/Data/Finset/Lattice.lean | 2 +- Mathlib/Data/Finset/NatAntidiagonal.lean | 4 +- Mathlib/Data/Finset/NoncommProd.lean | 10 +-- Mathlib/Data/Finset/Order.lean | 4 +- Mathlib/Data/Finset/Preimage.lean | 6 +- Mathlib/Data/Finset/Union.lean | 2 +- Mathlib/Data/Finsupp/Basic.lean | 4 +- Mathlib/Data/Finsupp/Multiset.lean | 2 +- Mathlib/Data/Finsupp/Order.lean | 4 +- Mathlib/Data/Fintype/Card.lean | 4 +- Mathlib/Data/Fintype/Order.lean | 4 +- Mathlib/Data/Fintype/Quotient.lean | 6 +- Mathlib/Data/Fintype/Sum.lean | 2 +- Mathlib/Data/Int/Bitwise.lean | 2 +- Mathlib/Data/Int/LeastGreatest.lean | 2 +- Mathlib/Data/Int/Lemmas.lean | 2 +- Mathlib/Data/List/Basic.lean | 40 +++++----- Mathlib/Data/List/Chain.lean | 8 +- Mathlib/Data/List/Destutter.lean | 2 +- Mathlib/Data/List/InsertNth.lean | 6 +- Mathlib/Data/List/Lattice.lean | 2 +- Mathlib/Data/List/Lemmas.lean | 8 +- Mathlib/Data/List/Lex.lean | 16 ++-- Mathlib/Data/List/MinMax.lean | 2 +- Mathlib/Data/List/Perm.lean | 2 +- Mathlib/Data/List/Permutation.lean | 2 +- Mathlib/Data/List/Rotate.lean | 2 +- Mathlib/Data/List/Sigma.lean | 2 +- Mathlib/Data/List/Sort.lean | 4 +- Mathlib/Data/List/Sublists.lean | 2 +- Mathlib/Data/List/TFAE.lean | 2 +- Mathlib/Data/List/Zip.lean | 2 +- Mathlib/Data/Matrix/Basic.lean | 4 +- Mathlib/Data/Matrix/DMatrix.lean | 2 +- Mathlib/Data/Matrix/DualNumber.lean | 6 +- Mathlib/Data/Matrix/Reflection.lean | 6 +- Mathlib/Data/Matroid/Basic.lean | 4 +- Mathlib/Data/Matroid/Closure.lean | 4 +- Mathlib/Data/Matroid/Dual.lean | 2 +- Mathlib/Data/Matroid/IndepAxioms.lean | 4 +- Mathlib/Data/Matroid/Map.lean | 4 +- Mathlib/Data/Matroid/Restrict.lean | 4 +- Mathlib/Data/Multiset/Basic.lean | 18 ++--- Mathlib/Data/Multiset/Bind.lean | 4 +- Mathlib/Data/Multiset/FinsetOps.lean | 2 +- Mathlib/Data/Multiset/Nodup.lean | 2 +- Mathlib/Data/NNReal/Basic.lean | 4 +- Mathlib/Data/Nat/Bits.lean | 2 +- Mathlib/Data/Nat/Cast/Order/Basic.lean | 2 +- Mathlib/Data/Nat/Choose/Basic.lean | 4 +- Mathlib/Data/Nat/Choose/Multinomial.lean | 2 +- Mathlib/Data/Nat/Choose/Sum.lean | 2 +- Mathlib/Data/Nat/Defs.lean | 12 +-- Mathlib/Data/Nat/Fib/Zeckendorf.lean | 2 +- Mathlib/Data/Nat/Find.lean | 6 +- Mathlib/Data/Nat/Lattice.lean | 2 +- Mathlib/Data/Nat/Log.lean | 8 ++ Mathlib/Data/Nat/Pairing.lean | 2 +- Mathlib/Data/Nat/PartENat.lean | 12 +-- Mathlib/Data/Nat/Prime/Basic.lean | 2 +- Mathlib/Data/Nat/Prime/Defs.lean | 2 +- Mathlib/Data/Num/Lemmas.lean | 64 +++++++-------- Mathlib/Data/Option/Basic.lean | 8 +- Mathlib/Data/Option/Defs.lean | 2 +- Mathlib/Data/Ordmap/Ordset.lean | 20 ++--- Mathlib/Data/PEquiv.lean | 2 +- Mathlib/Data/PFun.lean | 10 +-- Mathlib/Data/PNat/Basic.lean | 4 +- Mathlib/Data/PSigma/Order.lean | 2 +- Mathlib/Data/Part.lean | 6 +- .../QPF/Multivariate/Constructions/Comp.lean | 2 +- Mathlib/Data/QPF/Univariate/Basic.lean | 4 +- Mathlib/Data/Quot.lean | 2 +- Mathlib/Data/Rat/Floor.lean | 6 +- Mathlib/Data/Rat/Lemmas.lean | 2 +- Mathlib/Data/Real/Basic.lean | 4 +- Mathlib/Data/Real/EReal.lean | 2 +- Mathlib/Data/Rel.lean | 2 +- Mathlib/Data/Semiquot.lean | 6 +- Mathlib/Data/Seq/Computation.lean | 4 +- Mathlib/Data/Seq/Seq.lean | 2 +- Mathlib/Data/Seq/WSeq.lean | 2 +- Mathlib/Data/Set/Enumerate.lean | 2 +- Mathlib/Data/Set/Finite.lean | 4 +- Mathlib/Data/Set/Function.lean | 6 +- Mathlib/Data/Set/Image.lean | 6 +- Mathlib/Data/Set/Lattice.lean | 8 +- Mathlib/Data/Set/Prod.lean | 4 +- Mathlib/Data/Setoid/Basic.lean | 16 ++-- Mathlib/Data/Setoid/Partition.lean | 4 +- Mathlib/Data/Sigma/Order.lean | 2 +- Mathlib/Data/Stream/Init.lean | 12 +-- Mathlib/Data/String/Basic.lean | 2 +- Mathlib/Data/Sum/Order.lean | 2 +- Mathlib/Data/Sym/Basic.lean | 2 +- Mathlib/Data/Sym/Sym2.lean | 18 ++--- Mathlib/Data/Tree/Basic.lean | 2 +- Mathlib/Data/Vector/Basic.lean | 2 +- Mathlib/Data/Vector/Defs.lean | 2 +- Mathlib/Data/Vector3.lean | 6 +- Mathlib/Data/W/Basic.lean | 6 +- Mathlib/Data/W/Cardinal.lean | 2 +- Mathlib/Data/ZMod/Basic.lean | 8 +- Mathlib/Data/ZMod/Defs.lean | 4 +- Mathlib/Data/ZMod/IntUnitsPower.lean | 6 +- Mathlib/Deprecated/Subgroup.lean | 4 +- Mathlib/Deprecated/Submonoid.lean | 2 +- .../RotationNumber/TranslationNumber.lean | 20 ++--- Mathlib/Dynamics/PeriodicPts.lean | 2 +- Mathlib/FieldTheory/Adjoin.lean | 2 +- Mathlib/FieldTheory/Finite/Polynomial.lean | 2 +- .../FieldTheory/IntermediateField/Basic.lean | 10 +-- .../IsAlgClosed/Classification.lean | 2 +- Mathlib/FieldTheory/KummerExtension.lean | 2 +- Mathlib/FieldTheory/PerfectClosure.lean | 6 +- Mathlib/FieldTheory/RatFunc/Basic.lean | 10 +-- Mathlib/FieldTheory/RatFunc/Defs.lean | 4 +- Mathlib/FieldTheory/Separable.lean | 2 +- .../SplittingField/Construction.lean | 4 +- Mathlib/Geometry/Euclidean/Sphere/Basic.lean | 2 +- Mathlib/Geometry/Manifold/ChartedSpace.lean | 4 +- .../Geometry/Manifold/DerivationBundle.lean | 4 +- Mathlib/Geometry/Manifold/Instances/Real.lean | 4 +- .../RingedSpace/LocallyRingedSpace.lean | 4 +- .../LocallyRingedSpace/HasColimits.lean | 2 +- .../Geometry/RingedSpace/SheafedSpace.lean | 2 +- Mathlib/GroupTheory/Abelianization.lean | 2 +- Mathlib/GroupTheory/Archimedean.lean | 2 +- Mathlib/GroupTheory/CommutingProbability.lean | 4 +- Mathlib/GroupTheory/Congruence/Basic.lean | 8 +- Mathlib/GroupTheory/CoprodI.lean | 2 +- Mathlib/GroupTheory/Coset/Basic.lean | 10 +-- Mathlib/GroupTheory/Divisible.lean | 2 +- Mathlib/GroupTheory/FreeAbelianGroup.lean | 2 +- Mathlib/GroupTheory/FreeGroup/Basic.lean | 12 +-- .../FreeGroup/NielsenSchreier.lean | 9 ++- Mathlib/GroupTheory/GroupAction/Blocks.lean | 4 +- Mathlib/GroupTheory/GroupAction/ConjAct.lean | 2 +- Mathlib/GroupTheory/GroupAction/Quotient.lean | 2 +- Mathlib/GroupTheory/HNNExtension.lean | 2 +- .../GroupTheory/MonoidLocalization/Order.lean | 4 +- Mathlib/GroupTheory/NoncommPiCoprod.lean | 4 +- Mathlib/GroupTheory/PGroup.lean | 4 +- Mathlib/GroupTheory/Perm/Basic.lean | 8 +- Mathlib/GroupTheory/Perm/Cycle/Basic.lean | 8 +- Mathlib/GroupTheory/Perm/Cycle/Type.lean | 2 +- Mathlib/GroupTheory/Perm/DomMulAct.lean | 4 +- Mathlib/GroupTheory/Perm/List.lean | 2 +- Mathlib/GroupTheory/Perm/Sign.lean | 6 +- Mathlib/GroupTheory/Perm/Support.lean | 2 +- Mathlib/GroupTheory/PushoutI.lean | 2 +- Mathlib/GroupTheory/QuotientGroup/Basic.lean | 2 +- Mathlib/GroupTheory/SchurZassenhaus.lean | 2 +- .../SpecificGroups/Alternating.lean | 2 +- .../GroupTheory/SpecificGroups/Dihedral.lean | 10 +-- Mathlib/GroupTheory/Sylow.lean | 10 +-- .../AffineSpace/AffineEquiv.lean | 2 +- .../LinearAlgebra/AffineSpace/AffineMap.lean | 4 +- .../AffineSpace/AffineSubspace.lean | 8 +- Mathlib/LinearAlgebra/Alternating/Basic.lean | 8 +- Mathlib/LinearAlgebra/BilinearForm/Hom.lean | 4 +- Mathlib/LinearAlgebra/BilinearMap.lean | 4 +- .../LinearAlgebra/CliffordAlgebra/Equivs.lean | 2 +- .../LinearAlgebra/CliffordAlgebra/Even.lean | 4 +- Mathlib/LinearAlgebra/DFinsupp.lean | 2 +- .../DirectSum/TensorProduct.lean | 4 +- .../ExteriorAlgebra/OfAlternating.lean | 2 +- .../LinearAlgebra/FiniteDimensional/Defs.lean | 4 +- Mathlib/LinearAlgebra/Finsupp.lean | 4 +- Mathlib/LinearAlgebra/Lagrange.lean | 2 +- Mathlib/LinearAlgebra/LinearIndependent.lean | 4 +- Mathlib/LinearAlgebra/LinearPMap.lean | 16 ++-- .../Matrix/Charpoly/LinearMap.lean | 2 +- Mathlib/LinearAlgebra/Matrix/Circulant.lean | 12 +-- Mathlib/LinearAlgebra/Matrix/DotProduct.lean | 4 +- .../Matrix/GeneralLinearGroup/Card.lean | 2 +- .../Matrix/GeneralLinearGroup/Defs.lean | 2 +- .../Matrix/SpecialLinearGroup.lean | 2 +- Mathlib/LinearAlgebra/Multilinear/Basic.lean | 16 ++-- Mathlib/LinearAlgebra/Pi.lean | 2 +- Mathlib/LinearAlgebra/PiTensorProduct.lean | 4 +- Mathlib/LinearAlgebra/Prod.lean | 4 +- .../Projectivization/Subspace.lean | 4 +- .../QuadraticForm/QuadraticModuleCat.lean | 2 +- .../QuadraticModuleCat/Monoidal.lean | 2 +- Mathlib/LinearAlgebra/Quotient.lean | 4 +- Mathlib/LinearAlgebra/Ray.lean | 2 +- Mathlib/LinearAlgebra/Span.lean | 4 +- .../LinearAlgebra/TensorAlgebra/Basis.lean | 2 +- Mathlib/LinearAlgebra/TensorPower.lean | 14 ++-- .../TensorProduct/DirectLimit.lean | 2 +- Mathlib/LinearAlgebra/TensorProduct/Pi.lean | 2 +- Mathlib/Logic/Equiv/Basic.lean | 22 ++--- Mathlib/Logic/Equiv/Defs.lean | 6 +- Mathlib/Logic/Equiv/Fin.lean | 6 +- Mathlib/Logic/Equiv/List.lean | 8 +- Mathlib/Logic/Equiv/PartialEquiv.lean | 16 ++-- Mathlib/Logic/Equiv/Set.lean | 12 +-- Mathlib/Logic/Equiv/TransferInstance.lean | 12 +-- Mathlib/Logic/Function/Basic.lean | 6 +- Mathlib/Logic/Relation.lean | 2 +- Mathlib/MeasureTheory/Category/MeasCat.lean | 2 +- .../Constructions/BorelSpace/Basic.lean | 2 +- .../Constructions/BorelSpace/Metric.lean | 4 +- .../Constructions/BorelSpace/Order.lean | 6 +- .../Constructions/BorelSpace/Real.lean | 2 +- .../Constructions/EventuallyMeasurable.lean | 2 +- .../Constructions/HaarToSphere.lean | 2 +- Mathlib/MeasureTheory/Constructions/Pi.lean | 2 +- .../MeasureTheory/Covering/Besicovitch.lean | 2 +- .../Covering/DensityTheorem.lean | 12 +-- Mathlib/MeasureTheory/Covering/Vitali.lean | 4 +- .../ConditionalExpectation/CondexpL2.lean | 2 +- Mathlib/MeasureTheory/Function/LpOrder.lean | 2 +- .../Function/LpSeminorm/Basic.lean | 2 +- Mathlib/MeasureTheory/Function/LpSpace.lean | 6 +- .../MeasureTheory/Function/SimpleFunc.lean | 8 +- .../Function/UniformIntegrable.lean | 8 +- .../Integral/IntegralEqImproper.lean | 4 +- Mathlib/MeasureTheory/Integral/Lebesgue.lean | 22 ++--- Mathlib/MeasureTheory/Integral/SetToL1.lean | 8 +- .../MeasureTheory/MeasurableSpace/Basic.lean | 4 +- .../MeasureTheory/MeasurableSpace/Defs.lean | 4 +- .../MeasurableSpace/Embedding.lean | 2 +- Mathlib/MeasureTheory/Measure/Complex.lean | 2 +- Mathlib/MeasureTheory/Measure/Count.lean | 6 +- Mathlib/MeasureTheory/Measure/Hausdorff.lean | 2 +- .../Measure/LevyProkhorovMetric.lean | 12 +-- .../MeasureTheory/Measure/MeasureSpace.lean | 16 ++-- .../MeasureTheory/Measure/NullMeasurable.lean | 2 +- Mathlib/MeasureTheory/Measure/Stieltjes.lean | 2 +- .../MeasureTheory/Measure/Typeclasses.lean | 6 +- .../MeasureTheory/Measure/VectorMeasure.lean | 18 ++--- .../MeasureTheory/Measure/WithDensity.lean | 2 +- .../Measure/WithDensityVectorMeasure.lean | 2 +- .../OuterMeasure/OfFunction.lean | 2 +- .../OuterMeasure/Operations.lean | 32 ++++---- Mathlib/MeasureTheory/PiSystem.lean | 10 +-- Mathlib/MeasureTheory/SetSemiring.lean | 2 +- Mathlib/ModelTheory/DirectLimit.lean | 6 +- Mathlib/ModelTheory/Order.lean | 4 +- Mathlib/ModelTheory/Semantics.lean | 2 +- Mathlib/ModelTheory/Substructures.lean | 14 ++-- Mathlib/ModelTheory/Syntax.lean | 4 +- Mathlib/ModelTheory/Ultraproducts.lean | 4 +- .../Cyclotomic/PrimitiveRoots.lean | 4 +- Mathlib/NumberTheory/Cyclotomic/Rat.lean | 7 ++ Mathlib/NumberTheory/Divisors.lean | 4 +- .../EllipticDivisibilitySequence.lean | 4 +- .../LegendreSymbol/JacobiSymbol.lean | 2 +- .../Liouville/LiouvilleNumber.lean | 2 +- Mathlib/NumberTheory/Liouville/Measure.lean | 2 +- Mathlib/NumberTheory/Liouville/Residual.lean | 2 +- Mathlib/NumberTheory/LucasLehmer.lean | 2 +- Mathlib/NumberTheory/ModularForms/Basic.lean | 24 +++--- .../NumberField/Units/DirichletTheorem.lean | 2 +- Mathlib/NumberTheory/Ostrowski.lean | 2 +- Mathlib/NumberTheory/Padics/Hensel.lean | 2 +- Mathlib/NumberTheory/PellMatiyasevic.lean | 14 ++-- Mathlib/NumberTheory/Primorial.lean | 2 +- Mathlib/NumberTheory/Zsqrtd/Basic.lean | 18 ++--- Mathlib/NumberTheory/Zsqrtd/GaussianInt.lean | 2 +- .../Zsqrtd/QuadraticReciprocity.lean | 2 +- Mathlib/Order/Antichain.lean | 4 +- Mathlib/Order/Antisymmetrization.lean | 2 +- Mathlib/Order/Atoms.lean | 4 +- Mathlib/Order/Basic.lean | 4 +- Mathlib/Order/Birkhoff.lean | 4 +- Mathlib/Order/BooleanAlgebra.lean | 8 +- Mathlib/Order/Booleanisation.lean | 16 ++-- Mathlib/Order/Bounds/Basic.lean | 2 +- Mathlib/Order/Category/BddDistLat.lean | 4 +- Mathlib/Order/Category/BddLat.lean | 22 ++--- Mathlib/Order/Category/BddOrd.lean | 4 +- Mathlib/Order/Category/BoolAlg.lean | 2 +- Mathlib/Order/Category/CompleteLat.lean | 4 +- Mathlib/Order/Category/FinBddDistLat.lean | 2 +- Mathlib/Order/Category/FinBoolAlg.lean | 2 +- Mathlib/Order/Category/FinPartOrd.lean | 2 +- Mathlib/Order/Category/Frm.lean | 4 +- Mathlib/Order/Category/NonemptyFinLinOrd.lean | 2 +- .../Category/OmegaCompletePartialOrder.lean | 6 +- Mathlib/Order/Category/Semilat.lean | 4 +- Mathlib/Order/Circular.lean | 2 +- Mathlib/Order/Closure.lean | 6 +- Mathlib/Order/CompactlyGenerated/Basic.lean | 4 +- Mathlib/Order/Compare.lean | 10 +-- Mathlib/Order/CompleteBooleanAlgebra.lean | 4 +- Mathlib/Order/CompleteLattice.lean | 36 ++++----- Mathlib/Order/CompleteLatticeIntervals.lean | 8 +- Mathlib/Order/Concept.lean | 4 +- .../ConditionallyCompleteLattice/Basic.lean | 20 ++--- Mathlib/Order/Filter/AtTopBot.lean | 10 +-- Mathlib/Order/Filter/Basic.lean | 4 +- Mathlib/Order/Filter/EventuallyConst.lean | 2 +- Mathlib/Order/Filter/FilterProduct.lean | 6 +- Mathlib/Order/Filter/Germ/Basic.lean | 2 +- Mathlib/Order/Filter/Pi.lean | 2 +- Mathlib/Order/Filter/Pointwise.lean | 6 +- Mathlib/Order/Filter/SmallSets.lean | 2 +- Mathlib/Order/Filter/Ultrafilter.lean | 2 +- Mathlib/Order/GaloisConnection.lean | 6 +- Mathlib/Order/Heyting/Basic.lean | 8 +- Mathlib/Order/Heyting/Regular.lean | 8 +- Mathlib/Order/Hom/Order.lean | 6 +- Mathlib/Order/Ideal.lean | 2 +- Mathlib/Order/InitialSeg.lean | 4 +- Mathlib/Order/Interval/Basic.lean | 6 +- Mathlib/Order/Interval/Finset/Defs.lean | 10 +-- Mathlib/Order/Interval/Set/Basic.lean | 2 +- Mathlib/Order/Interval/Set/OrderIso.lean | 4 +- Mathlib/Order/Interval/Set/Pi.lean | 2 +- Mathlib/Order/OmegaCompletePartialOrder.lean | 10 +-- Mathlib/Order/Partition/Finpartition.lean | 6 +- Mathlib/Order/PiLex.lean | 4 +- Mathlib/Order/Rel/GaloisConnection.lean | 2 +- Mathlib/Order/RelClasses.lean | 4 +- Mathlib/Order/RelIso/Group.lean | 6 +- Mathlib/Order/SuccPred/Basic.lean | 2 +- Mathlib/Order/SupClosed.lean | 4 +- Mathlib/Order/WellFoundedSet.lean | 2 +- Mathlib/Order/WithBot.lean | 8 +- Mathlib/Order/Zorn.lean | 2 +- .../Probability/Distributions/Uniform.lean | 2 +- Mathlib/Probability/Independence/Kernel.lean | 2 +- Mathlib/Probability/Kernel/Defs.lean | 2 +- .../Kernel/Disintegration/StandardBorel.lean | 8 +- .../Probability/Martingale/Convergence.lean | 2 +- Mathlib/Probability/Moments.lean | 6 +- .../Constructions.lean | 2 +- .../ProbabilityMassFunction/Monad.lean | 2 +- Mathlib/Probability/Process/Filtration.lean | 24 +++--- .../RepresentationTheory/Action/Basic.lean | 4 +- .../RepresentationTheory/Action/Concrete.lean | 6 +- .../RepresentationTheory/Action/Monoidal.lean | 2 +- .../GroupCohomology/LowDegree.lean | 4 +- .../GroupCohomology/Resolution.lean | 2 +- Mathlib/RepresentationTheory/Rep.lean | 6 +- Mathlib/RingTheory/Adjoin/FG.lean | 2 +- Mathlib/RingTheory/Bialgebra/Hom.lean | 6 +- Mathlib/RingTheory/Binomial.lean | 4 +- Mathlib/RingTheory/Coalgebra/Hom.lean | 6 +- .../DedekindDomain/FiniteAdeleRing.lean | 2 +- Mathlib/RingTheory/DedekindDomain/Ideal.lean | 4 +- .../DedekindDomain/SelmerGroup.lean | 2 +- Mathlib/RingTheory/Derivation/Basic.lean | 2 +- Mathlib/RingTheory/Filtration.lean | 2 +- Mathlib/RingTheory/Finiteness.lean | 2 +- .../FractionalIdeal/Operations.lean | 6 +- Mathlib/RingTheory/FreeCommRing.lean | 2 +- Mathlib/RingTheory/FreeRing.lean | 2 +- .../HomogeneousLocalization.lean | 8 +- Mathlib/RingTheory/HahnSeries/Summable.lean | 4 +- Mathlib/RingTheory/HahnSeries/Valuation.lean | 2 +- Mathlib/RingTheory/Ideal/Maps.lean | 4 +- Mathlib/RingTheory/Ideal/Operations.lean | 16 ++-- Mathlib/RingTheory/Ideal/Pointwise.lean | 6 +- Mathlib/RingTheory/Ideal/Quotient.lean | 8 +- Mathlib/RingTheory/IntegralDomain.lean | 4 +- Mathlib/RingTheory/JacobsonIdeal.lean | 2 +- Mathlib/RingTheory/Kaehler/Basic.lean | 4 +- Mathlib/RingTheory/LocalProperties/Basic.lean | 8 +- .../RingTheory/LocalProperties/Reduced.lean | 4 +- Mathlib/RingTheory/Localization/AtPrime.lean | 6 +- Mathlib/RingTheory/Localization/Basic.lean | 2 +- .../RingTheory/Localization/FractionRing.lean | 4 +- Mathlib/RingTheory/Multiplicity.lean | 2 +- .../RingTheory/MvPolynomial/Homogeneous.lean | 2 +- .../Symmetric/FundamentalTheorem.lean | 2 +- .../MvPolynomial/WeightedHomogeneous.lean | 2 +- .../RingTheory/NonUnitalSubring/Basic.lean | 14 ++-- Mathlib/RingTheory/Nullstellensatz.lean | 10 +-- Mathlib/RingTheory/OreLocalization/Ring.lean | 4 +- Mathlib/RingTheory/Perfection.lean | 20 ++--- Mathlib/RingTheory/Polynomial/Basic.lean | 4 +- .../Polynomial/Cyclotomic/Eval.lean | 4 +- Mathlib/RingTheory/Polynomial/Quotient.lean | 8 +- Mathlib/RingTheory/PowerBasis.lean | 2 +- Mathlib/RingTheory/ReesAlgebra.lean | 2 +- .../RingTheory/Regular/RegularSequence.lean | 2 +- Mathlib/RingTheory/SimpleModule.lean | 4 +- Mathlib/RingTheory/TensorProduct/Basic.lean | 8 +- .../RingTheory/UniqueFactorizationDomain.lean | 10 +-- .../Valuation/ValuationSubring.lean | 6 +- Mathlib/RingTheory/WittVector/IsPoly.lean | 6 +- Mathlib/RingTheory/WittVector/MulP.lean | 2 +- Mathlib/RingTheory/WittVector/Truncated.lean | 2 +- Mathlib/SetTheory/Cardinal/Basic.lean | 14 ++-- Mathlib/SetTheory/Cardinal/Cofinality.lean | 14 ++-- Mathlib/SetTheory/Game/Basic.lean | 4 +- Mathlib/SetTheory/Game/PGame.lean | 2 +- Mathlib/SetTheory/Game/State.lean | 2 +- Mathlib/SetTheory/Lists.lean | 4 +- Mathlib/SetTheory/Ordinal/Arithmetic.lean | 15 ++-- Mathlib/SetTheory/Ordinal/Basic.lean | 16 ++-- Mathlib/SetTheory/Ordinal/Exponential.lean | 2 +- Mathlib/SetTheory/Ordinal/FixedPoint.lean | 2 +- Mathlib/SetTheory/Ordinal/NaturalOps.lean | 8 +- Mathlib/SetTheory/Ordinal/Notation.lean | 12 +-- Mathlib/SetTheory/Ordinal/Principal.lean | 2 +- Mathlib/SetTheory/ZFC/Basic.lean | 2 +- Mathlib/SetTheory/ZFC/Ordinal.lean | 2 +- Mathlib/Tactic/NormNum/Basic.lean | 8 ++ Mathlib/Tactic/NormNum/DivMod.lean | 8 ++ Mathlib/Tactic/NormNum/Eq.lean | 8 ++ Mathlib/Tactic/NormNum/GCD.lean | 8 ++ Mathlib/Tactic/NormNum/Ineq.lean | 8 ++ Mathlib/Tactic/NormNum/Inv.lean | 8 ++ Mathlib/Tactic/NormNum/IsCoprime.lean | 2 +- Mathlib/Tactic/NormNum/LegendreSymbol.lean | 8 ++ Mathlib/Tactic/NormNum/NatFib.lean | 2 +- Mathlib/Tactic/NormNum/NatSqrt.lean | 2 +- Mathlib/Tactic/NormNum/Pow.lean | 8 ++ Mathlib/Tactic/NormNum/Prime.lean | 4 +- Mathlib/Testing/SlimCheck/Functions.lean | 2 +- Mathlib/Topology/Algebra/Group/Basic.lean | 2 +- .../Topology/Algebra/InfiniteSum/Basic.lean | 2 +- .../Algebra/Module/Alternating/Basic.lean | 4 +- .../Algebra/Nonarchimedean/Basic.lean | 2 +- .../Topology/Algebra/Order/LiminfLimsup.lean | 2 +- Mathlib/Topology/Algebra/UniformField.lean | 4 +- Mathlib/Topology/Bases.lean | 2 +- Mathlib/Topology/Basic.lean | 6 +- Mathlib/Topology/Category/Compactum.lean | 2 +- .../Category/LightProfinite/Basic.lean | 4 +- .../Topology/Category/Profinite/Basic.lean | 2 +- .../Topology/Category/TopCat/Adjunctions.lean | 8 +- .../Category/TopCat/Limits/Basic.lean | 2 +- .../Category/TopCat/Limits/Products.lean | 2 +- .../Category/TopCat/Limits/Pullbacks.lean | 2 +- .../Topology/Category/TopCat/OpenNhds.lean | 4 +- Mathlib/Topology/Category/TopCat/Opens.lean | 8 +- Mathlib/Topology/Category/TopCat/Yoneda.lean | 2 +- Mathlib/Topology/Category/TopCommRingCat.lean | 2 +- Mathlib/Topology/CompactOpen.lean | 2 +- .../Topology/Compactification/OnePoint.lean | 2 +- Mathlib/Topology/Compactness/Compact.lean | 8 +- .../Compactness/CompactlyGeneratedSpace.lean | 7 ++ Mathlib/Topology/Compactness/Lindelof.lean | 2 +- .../Topology/Compactness/SigmaCompact.lean | 2 +- Mathlib/Topology/Connected/Basic.lean | 4 +- Mathlib/Topology/Constructions.lean | 6 +- Mathlib/Topology/ContinuousMap/Bounded.lean | 8 +- Mathlib/Topology/ContinuousMap/Compact.lean | 2 +- Mathlib/Topology/ContinuousMap/Ideals.lean | 6 +- Mathlib/Topology/ContinuousMap/Units.lean | 4 +- Mathlib/Topology/ContinuousOn.lean | 2 +- Mathlib/Topology/Defs/Induced.lean | 2 +- Mathlib/Topology/EMetricSpace/Defs.lean | 2 +- Mathlib/Topology/EMetricSpace/Pi.lean | 2 +- .../Topology/FiberBundle/Constructions.lean | 12 +-- Mathlib/Topology/Filter.lean | 2 +- Mathlib/Topology/Gluing.lean | 10 +-- Mathlib/Topology/Homeomorph.lean | 2 +- Mathlib/Topology/Homotopy/HSpaces.lean | 2 +- Mathlib/Topology/Instances/ENNReal.lean | 2 +- Mathlib/Topology/Instances/EReal.lean | 4 +- Mathlib/Topology/Instances/Real.lean | 8 +- Mathlib/Topology/List.lean | 2 +- Mathlib/Topology/MetricSpace/Algebra.lean | 8 +- Mathlib/Topology/MetricSpace/Closeds.lean | 12 +-- Mathlib/Topology/MetricSpace/Dilation.lean | 2 +- Mathlib/Topology/MetricSpace/Gluing.lean | 6 +- .../MetricSpace/GromovHausdorffRealized.lean | 6 +- .../MetricSpace/HausdorffDistance.lean | 2 +- Mathlib/Topology/MetricSpace/Isometry.lean | 6 +- .../MetricSpace/Pseudo/Constructions.lean | 10 +-- Mathlib/Topology/MetricSpace/Pseudo/Defs.lean | 6 +- Mathlib/Topology/Metrizable/Uniformity.lean | 2 +- Mathlib/Topology/Order.lean | 2 +- Mathlib/Topology/Order/Basic.lean | 4 +- Mathlib/Topology/Order/Bornology.lean | 4 +- .../Order/Category/FrameAdjunction.lean | 2 +- .../Topology/Order/MonotoneContinuity.lean | 2 +- Mathlib/Topology/Partial.lean | 2 +- Mathlib/Topology/PartialHomeomorph.lean | 2 +- Mathlib/Topology/PartitionOfUnity.lean | 4 +- Mathlib/Topology/SeparatedMap.lean | 14 ++++ Mathlib/Topology/Separation.lean | 4 +- Mathlib/Topology/Sequences.lean | 2 +- Mathlib/Topology/Sets/Opens.lean | 6 +- Mathlib/Topology/Sheaves/LocalPredicate.lean | 4 +- Mathlib/Topology/Sheaves/Operations.lean | 2 +- .../Topology/Sheaves/PresheafOfFunctions.lean | 18 ++--- .../SheafCondition/PairwiseIntersections.lean | 2 +- Mathlib/Topology/Sheaves/Skyscraper.lean | 4 +- Mathlib/Topology/ShrinkingLemma.lean | 4 +- .../Topology/UniformSpace/AbsoluteValue.lean | 2 +- Mathlib/Topology/UniformSpace/Basic.lean | 6 +- Mathlib/Topology/UniformSpace/Compact.lean | 2 +- Mathlib/Topology/UniformSpace/Completion.lean | 6 +- .../UniformSpace/UniformConvergence.lean | 4 +- .../UniformSpace/UniformEmbedding.lean | 22 ++--- Mathlib/Topology/VectorBundle/Hom.lean | 4 +- scripts/fix_unused.py | 80 +++++++++++++++++++ 953 files changed, 2726 insertions(+), 2472 deletions(-) create mode 100755 scripts/fix_unused.py diff --git a/Mathlib/Algebra/Algebra/Basic.lean b/Mathlib/Algebra/Algebra/Basic.lean index f4a24f5977006e..66932daf4008da 100644 --- a/Mathlib/Algebra/Algebra/Basic.lean +++ b/Mathlib/Algebra/Algebra/Basic.lean @@ -479,8 +479,8 @@ def LinearMap.extendScalarsOfSurjectiveEquiv (h : Function.Surjective (algebraMa map_add' _ _ := rfl map_smul' _ _ := rfl invFun f := f.restrictScalars S - left_inv f := rfl - right_inv f := rfl + left_inv _ := rfl + right_inv _ := rfl /-- If `R →+* S` is surjective, then `R`-linear maps are also `S`-linear. -/ abbrev LinearMap.extendScalarsOfSurjective (h : Function.Surjective (algebraMap R S)) diff --git a/Mathlib/Algebra/Algebra/Equiv.lean b/Mathlib/Algebra/Algebra/Equiv.lean index d19412446121d5..fa867ba948dfbf 100644 --- a/Mathlib/Algebra/Algebra/Equiv.lean +++ b/Mathlib/Algebra/Algebra/Equiv.lean @@ -625,10 +625,10 @@ end OfRingEquiv -- @[simps (config := .lemmasOnly) one] instance aut : Group (A₁ ≃ₐ[R] A₁) where mul ϕ ψ := ψ.trans ϕ - mul_assoc ϕ ψ χ := rfl + mul_assoc _ _ _ := rfl one := refl - one_mul ϕ := ext fun x => rfl - mul_one ϕ := ext fun x => rfl + one_mul _ := ext fun _ => rfl + mul_one _ := ext fun _ => rfl inv := symm inv_mul_cancel ϕ := ext <| symm_apply_apply ϕ diff --git a/Mathlib/Algebra/Algebra/Hom.lean b/Mathlib/Algebra/Algebra/Hom.lean index 0942b526635de9..55dcdc81a91cb8 100644 --- a/Mathlib/Algebra/Algebra/Hom.lean +++ b/Mathlib/Algebra/Algebra/Hom.lean @@ -354,10 +354,10 @@ protected theorem map_list_prod (s : List A) : φ s.prod = (s.map φ).prod := @[simps (config := .lemmasOnly) toSemigroup_toMul_mul toOne_one] instance End : Monoid (A →ₐ[R] A) where mul := comp - mul_assoc ϕ ψ χ := rfl + mul_assoc _ _ _ := rfl one := AlgHom.id R A - one_mul ϕ := rfl - mul_one ϕ := rfl + one_mul _ := rfl + mul_one _ := rfl @[simp] theorem one_apply (x : A) : (1 : A →ₐ[R] A) x = x := diff --git a/Mathlib/Algebra/Algebra/Operations.lean b/Mathlib/Algebra/Algebra/Operations.lean index 15f0ec29f05ab0..ed2b456a4db5b4 100644 --- a/Mathlib/Algebra/Algebra/Operations.lean +++ b/Mathlib/Algebra/Algebra/Operations.lean @@ -490,10 +490,10 @@ submodules. -/ def equivOpposite : Submodule R Aᵐᵒᵖ ≃+* (Submodule R A)ᵐᵒᵖ where toFun p := op <| p.comap (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) invFun p := p.unop.comap (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ).symm : Aᵐᵒᵖ →ₗ[R] A) - left_inv p := SetLike.coe_injective <| rfl - right_inv p := unop_injective <| SetLike.coe_injective rfl + left_inv _ := SetLike.coe_injective <| rfl + right_inv _ := unop_injective <| SetLike.coe_injective rfl map_add' p q := by simp [comap_equiv_eq_map_symm, ← op_add] - map_mul' p q := congr_arg op <| comap_op_mul _ _ + map_mul' _ _ := congr_arg op <| comap_op_mul _ _ protected theorem map_pow {A'} [Semiring A'] [Algebra R A'] (f : A →ₐ[R] A') (n : ℕ) : map f.toLinearMap (M ^ n) = map f.toLinearMap M ^ n := @@ -647,7 +647,7 @@ theorem mem_div_iff_smul_subset {x : A} {I J : Submodule R A} : x ∈ I / J ↔ ⟨fun h y ⟨y', hy', xy'_eq_y⟩ => by rw [← xy'_eq_y] apply h - assumption, fun h y hy => h (Set.smul_mem_smul_set hy)⟩ + assumption, fun h _ hy => h (Set.smul_mem_smul_set hy)⟩ theorem le_div_iff {I J K : Submodule R A} : I ≤ J / K ↔ ∀ x ∈ I, ∀ z ∈ K, x * z ∈ J := Iff.refl _ diff --git a/Mathlib/Algebra/Algebra/Opposite.lean b/Mathlib/Algebra/Algebra/Opposite.lean index 65999d70a14c33..11e27a60fe78fc 100644 --- a/Mathlib/Algebra/Algebra/Opposite.lean +++ b/Mathlib/Algebra/Algebra/Opposite.lean @@ -38,7 +38,7 @@ variable [IsScalarTower R S A] namespace MulOpposite instance instAlgebra : Algebra R Aᵐᵒᵖ where - toRingHom := (algebraMap R A).toOpposite fun x y => Algebra.commutes _ _ + toRingHom := (algebraMap R A).toOpposite fun _ _ => Algebra.commutes _ _ smul_def' c x := unop_injective <| by simp only [unop_smul, RingHom.toOpposite_apply, Function.comp_apply, unop_mul, op_mul, Algebra.smul_def, Algebra.commutes, op_unop, unop_op] diff --git a/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean b/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean index 311a49067acade..9f3d2d832688e6 100644 --- a/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean +++ b/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean @@ -280,8 +280,8 @@ instance (priority := 500) algebra' [CommSemiring R'] [SMul R' R] [Algebra R' A] Algebra.algebraMap_eq_smul_one] exact algebraMap_mem S _ with - commutes' := fun c x => Subtype.eq <| Algebra.commutes _ _ - smul_def' := fun c x => Subtype.eq <| Algebra.smul_def _ _ } + commutes' := fun _ _ => Subtype.eq <| Algebra.commutes _ _ + smul_def' := fun _ _ => Subtype.eq <| Algebra.smul_def _ _ } instance algebra : Algebra R S := S.algebra' diff --git a/Mathlib/Algebra/Algebra/Tower.lean b/Mathlib/Algebra/Algebra/Tower.lean index 3ad6359102d47b..ab29e6a7c911bd 100644 --- a/Mathlib/Algebra/Algebra/Tower.lean +++ b/Mathlib/Algebra/Algebra/Tower.lean @@ -265,7 +265,7 @@ open IsScalarTower theorem smul_mem_span_smul_of_mem {s : Set S} {t : Set A} {k : S} (hks : k ∈ span R s) {x : A} (hx : x ∈ t) : k • x ∈ span R (s • t) := - span_induction hks (fun c hc => subset_span <| Set.smul_mem_smul hc hx) + span_induction hks (fun _ hc => subset_span <| Set.smul_mem_smul hc hx) (by rw [zero_smul]; exact zero_mem _) (fun c₁ c₂ ih₁ ih₂ => by rw [add_smul]; exact add_mem ih₁ ih₂) fun b c hc => by rw [IsScalarTower.smul_assoc]; exact smul_mem _ _ hc @@ -274,7 +274,7 @@ theorem span_smul_of_span_eq_top {s : Set S} (hs : span R s = ⊤) (t : Set A) : span R (s • t) = (span S t).restrictScalars R := le_antisymm (span_le.2 fun _x ⟨p, _hps, _q, hqt, hpqx⟩ ↦ hpqx ▸ (span S t).smul_mem p (subset_span hqt)) - fun p hp ↦ closure_induction hp (zero_mem _) (fun _ _ ↦ add_mem) fun s0 y hy ↦ by + fun _ hp ↦ closure_induction hp (zero_mem _) (fun _ _ ↦ add_mem) fun s0 y hy ↦ by refine span_induction (hs ▸ mem_top : s0 ∈ span R s) (fun x hx ↦ subset_span ⟨x, hx, y, hy, rfl⟩) ?_ ?_ ?_ · rw [zero_smul]; apply zero_mem diff --git a/Mathlib/Algebra/Algebra/ZMod.lean b/Mathlib/Algebra/Algebra/ZMod.lean index a04244c46ce31a..0d26ab239fe689 100644 --- a/Mathlib/Algebra/Algebra/ZMod.lean +++ b/Mathlib/Algebra/Algebra/ZMod.lean @@ -32,7 +32,7 @@ abbrev algebra' (h : m ∣ n) : Algebra (ZMod n) R := rcases ZMod.intCast_surjective a with ⟨k, rfl⟩ show ZMod.castHom h R k * r = r * ZMod.castHom h R k rw [map_intCast, Int.cast_comm] - smul_def' := fun a r => rfl } + smul_def' := fun _ _ => rfl } end diff --git a/Mathlib/Algebra/Associated/Basic.lean b/Mathlib/Algebra/Associated/Basic.lean index 47308730de6b66..a5cad90ce7c77e 100644 --- a/Mathlib/Algebra/Associated/Basic.lean +++ b/Mathlib/Algebra/Associated/Basic.lean @@ -831,7 +831,7 @@ instance instCommMonoid : CommMonoid (Associates M) where instance instPreorder : Preorder (Associates M) where le := Dvd.dvd le_refl := dvd_refl - le_trans a b c := dvd_trans + le_trans _ _ _ := dvd_trans /-- `Associates.mk` as a `MonoidHom`. -/ protected def mkMonoidHom : M →* Associates M where diff --git a/Mathlib/Algebra/BigOperators/Associated.lean b/Mathlib/Algebra/BigOperators/Associated.lean index ebe6b44cb59839..1c4e80f7431fab 100644 --- a/Mathlib/Algebra/BigOperators/Associated.lean +++ b/Mathlib/Algebra/BigOperators/Associated.lean @@ -187,7 +187,7 @@ variable [CancelCommMonoidWithZero α] theorem exists_mem_multiset_le_of_prime {s : Multiset (Associates α)} {p : Associates α} (hp : Prime p) : p ≤ s.prod → ∃ a ∈ s, p ≤ a := - Multiset.induction_on s (fun ⟨d, Eq⟩ => (hp.ne_one (mul_eq_one.1 Eq.symm).1).elim) + Multiset.induction_on s (fun ⟨_, Eq⟩ => (hp.ne_one (mul_eq_one.1 Eq.symm).1).elim) fun a s ih h => have : p ≤ a * s.prod := by simpa using h match Prime.le_or_le hp this with diff --git a/Mathlib/Algebra/BigOperators/Finsupp.lean b/Mathlib/Algebra/BigOperators/Finsupp.lean index 10fdcfb6979ea2..7d830fdf78f5a5 100644 --- a/Mathlib/Algebra/BigOperators/Finsupp.lean +++ b/Mathlib/Algebra/BigOperators/Finsupp.lean @@ -61,7 +61,7 @@ theorem prod_single_index {a : α} {b : M} {h : α → M → N} (h_zero : h a 0 (single a b).prod h = h a b := calc (single a b).prod h = ∏ x ∈ {a}, h x (single a b x) := - prod_of_support_subset _ support_single_subset h fun x hx => + prod_of_support_subset _ support_single_subset h fun _ hx => (mem_singleton.1 hx).symm ▸ h_zero _ = h a b := by simp diff --git a/Mathlib/Algebra/BigOperators/Group/Finset.lean b/Mathlib/Algebra/BigOperators/Group/Finset.lean index ee1faae6ee2a2f..cda549919c99cb 100644 --- a/Mathlib/Algebra/BigOperators/Group/Finset.lean +++ b/Mathlib/Algebra/BigOperators/Group/Finset.lean @@ -1781,7 +1781,7 @@ lemma prod_sdiff_ne_prod_sdiff_iff : end CancelCommMonoid -theorem card_eq_sum_ones (s : Finset α) : s.card = ∑ x ∈ s, 1 := by simp +theorem card_eq_sum_ones (s : Finset α) : s.card = ∑ _ ∈ s, 1 := by simp theorem sum_const_nat {m : ℕ} {f : α → ℕ} (h₁ : ∀ x ∈ s, f x = m) : ∑ x ∈ s, f x = card s * m := by @@ -1865,7 +1865,7 @@ theorem card_biUnion [DecidableEq β] {s : Finset α} {t : α → Finset β} (h : ∀ x ∈ s, ∀ y ∈ s, x ≠ y → Disjoint (t x) (t y)) : (s.biUnion t).card = ∑ u ∈ s, card (t u) := calc - (s.biUnion t).card = ∑ i ∈ s.biUnion t, 1 := card_eq_sum_ones _ + (s.biUnion t).card = ∑ _ ∈ s.biUnion t, 1 := card_eq_sum_ones _ _ = ∑ a ∈ s, ∑ _i ∈ t a, 1 := Finset.sum_biUnion h _ = ∑ u ∈ s, card (t u) := by simp_rw [card_eq_sum_ones] diff --git a/Mathlib/Algebra/BigOperators/Group/List.lean b/Mathlib/Algebra/BigOperators/Group/List.lean index f7ed6fb0165259..4bfe960292e47f 100644 --- a/Mathlib/Algebra/BigOperators/Group/List.lean +++ b/Mathlib/Algebra/BigOperators/Group/List.lean @@ -426,7 +426,7 @@ theorem prod_reverse_noncomm : ∀ L : List G, L.reverse.prod = (L.map fun x => "Counterpart to `List.sum_take_succ` when we have a negation operation"] theorem prod_drop_succ : ∀ (L : List G) (i : ℕ) (p : i < L.length), (L.drop (i + 1)).prod = L[i]⁻¹ * (L.drop i).prod - | [], i, p => False.elim (Nat.not_lt_zero _ p) + | [], _, p => False.elim (Nat.not_lt_zero _ p) | _ :: _, 0, _ => by simp | _ :: xs, i + 1, p => prod_drop_succ xs i (Nat.lt_of_succ_lt_succ p) diff --git a/Mathlib/Algebra/BigOperators/Intervals.lean b/Mathlib/Algebra/BigOperators/Intervals.lean index 3193db4f355efd..00cf03b53b607e 100644 --- a/Mathlib/Algebra/BigOperators/Intervals.lean +++ b/Mathlib/Algebra/BigOperators/Intervals.lean @@ -252,8 +252,8 @@ theorem sum_range_id_mul_two (n : ℕ) : (∑ i ∈ range n, i) * 2 = n * (n - 1 (∑ i ∈ range n, i) * 2 = (∑ i ∈ range n, i) + ∑ i ∈ range n, (n - 1 - i) := by rw [sum_range_reflect (fun i => i) n, mul_two] _ = ∑ i ∈ range n, (i + (n - 1 - i)) := sum_add_distrib.symm - _ = ∑ i ∈ range n, (n - 1) := - sum_congr rfl fun i hi => add_tsub_cancel_of_le <| Nat.le_sub_one_of_lt <| mem_range.1 hi + _ = ∑ _ ∈ range n, (n - 1) := + sum_congr rfl fun _ hi => add_tsub_cancel_of_le <| Nat.le_sub_one_of_lt <| mem_range.1 hi _ = n * (n - 1) := by rw [sum_const, card_range, Nat.nsmul_eq_mul] /-- Gauss' summation formula -/ diff --git a/Mathlib/Algebra/Category/AlgebraCat/Basic.lean b/Mathlib/Algebra/Category/AlgebraCat/Basic.lean index 36546a9af06232..bafe58b5b5db82 100644 --- a/Mathlib/Algebra/Category/AlgebraCat/Basic.lean +++ b/Mathlib/Algebra/Category/AlgebraCat/Basic.lean @@ -154,7 +154,7 @@ def free : Type u ⥤ AlgebraCat.{u} R where /-- The free/forget adjunction for `R`-algebras. -/ def adj : free.{u} R ⊣ forget (AlgebraCat.{u} R) := Adjunction.mkOfHomEquiv - { homEquiv := fun X A => (FreeAlgebra.lift _).symm + { homEquiv := fun _ _ => (FreeAlgebra.lift _).symm -- Relying on `obviously` to fill out these proofs is very slow :( homEquiv_naturality_left_symm := by -- Porting note (#11041): `apply FreeAlgebra.hom_ext` was `ext1`. diff --git a/Mathlib/Algebra/Category/AlgebraCat/Monoidal.lean b/Mathlib/Algebra/Category/AlgebraCat/Monoidal.lean index 9dbed63a629b2d..2275dee4758585 100644 --- a/Mathlib/Algebra/Category/AlgebraCat/Monoidal.lean +++ b/Mathlib/Algebra/Category/AlgebraCat/Monoidal.lean @@ -58,11 +58,11 @@ instance : MonoidalCategoryStruct (AlgebraCat.{u} R) where noncomputable instance instMonoidalCategory : MonoidalCategory (AlgebraCat.{u} R) := Monoidal.induced (forget₂ (AlgebraCat R) (ModuleCat R)) - { μIso := fun X Y => Iso.refl _ + { μIso := fun _ _ => Iso.refl _ εIso := Iso.refl _ - associator_eq := fun X Y Z => TensorProduct.ext₃ (fun x y z => rfl) - leftUnitor_eq := fun X => TensorProduct.ext' (fun x y => rfl) - rightUnitor_eq := fun X => TensorProduct.ext' (fun x y => rfl) } + associator_eq := fun _ _ _ => TensorProduct.ext₃ (fun _ _ _ => rfl) + leftUnitor_eq := fun _ => TensorProduct.ext' (fun _ _ => rfl) + rightUnitor_eq := fun _ => TensorProduct.ext' (fun _ _ => rfl) } variable (R) in /-- `forget₂ (AlgebraCat R) (ModuleCat R)` as a monoidal functor. -/ diff --git a/Mathlib/Algebra/Category/BialgebraCat/Basic.lean b/Mathlib/Algebra/Category/BialgebraCat/Basic.lean index 0d3b3d8260dadc..b4d9a43bf7236e 100644 --- a/Mathlib/Algebra/Category/BialgebraCat/Basic.lean +++ b/Mathlib/Algebra/Category/BialgebraCat/Basic.lean @@ -97,7 +97,7 @@ instance concreteCategory : ConcreteCategory.{v} (BialgebraCat.{v} R) where { obj := fun M => M map := fun f => f.toBialgHom } forget_faithful := - { map_injective := fun {M N} => DFunLike.coe_injective.comp <| Hom.toBialgHom_injective _ _ } + { map_injective := fun {_ _} => DFunLike.coe_injective.comp <| Hom.toBialgHom_injective _ _ } instance hasForgetToAlgebra : HasForget₂ (BialgebraCat R) (AlgebraCat R) where forget₂ := @@ -117,7 +117,7 @@ theorem forget₂_algebra_map (X Y : BialgebraCat R) (f : X ⟶ Y) : instance hasForgetToCoalgebra : HasForget₂ (BialgebraCat R) (CoalgebraCat R) where forget₂ := { obj := fun X => CoalgebraCat.of R X - map := fun {X Y} f => CoalgebraCat.ofHom f.toBialgHom } + map := fun {_ _} f => CoalgebraCat.ofHom f.toBialgHom } @[simp] theorem forget₂_coalgebra_obj (X : BialgebraCat R) : diff --git a/Mathlib/Algebra/Category/BoolRing.lean b/Mathlib/Algebra/Category/BoolRing.lean index 0967458354f179..396dd1283f25fd 100644 --- a/Mathlib/Algebra/Category/BoolRing.lean +++ b/Mathlib/Algebra/Category/BoolRing.lean @@ -80,7 +80,7 @@ end BoolRing instance BoolRing.hasForgetToBoolAlg : HasForget₂ BoolRing BoolAlg where forget₂ := { obj := fun X => BoolAlg.of (AsBoolAlg X) - map := fun {X Y} => RingHom.asBoolAlg } + map := fun {_ _} => RingHom.asBoolAlg } -- Porting note: Added. somehow it does not find this instance. instance {X : BoolAlg} : @@ -91,7 +91,7 @@ instance {X : BoolAlg} : instance BoolAlg.hasForgetToBoolRing : HasForget₂ BoolAlg BoolRing where forget₂ := { obj := fun X => BoolRing.of (AsBoolRing X) - map := fun {X Y} => BoundedLatticeHom.asBoolRing } + map := fun {_ _} => BoundedLatticeHom.asBoolRing } /-- The equivalence between Boolean rings and Boolean algebras. This is actually an isomorphism. -/ @[simps functor inverse] @@ -99,6 +99,6 @@ def boolRingCatEquivBoolAlg : BoolRing ≌ BoolAlg where functor := forget₂ BoolRing BoolAlg inverse := forget₂ BoolAlg BoolRing unitIso := NatIso.ofComponents (fun X => BoolRing.Iso.mk <| - (RingEquiv.asBoolRingAsBoolAlg X).symm) fun {X Y} f => rfl + (RingEquiv.asBoolRingAsBoolAlg X).symm) fun {_ _} _ => rfl counitIso := NatIso.ofComponents (fun X => BoolAlg.Iso.mk <| - OrderIso.asBoolAlgAsBoolRing X) fun {X Y} f => rfl + OrderIso.asBoolAlgAsBoolRing X) fun {_ _} _ => rfl diff --git a/Mathlib/Algebra/Category/CoalgebraCat/Basic.lean b/Mathlib/Algebra/Category/CoalgebraCat/Basic.lean index cbf7f0ebab7435..3d24b8db74884e 100644 --- a/Mathlib/Algebra/Category/CoalgebraCat/Basic.lean +++ b/Mathlib/Algebra/Category/CoalgebraCat/Basic.lean @@ -100,7 +100,7 @@ instance concreteCategory : ConcreteCategory.{v} (CoalgebraCat.{v} R) where { obj := fun M => M map := fun f => f.toCoalgHom } forget_faithful := - { map_injective := fun {M N} => DFunLike.coe_injective.comp <| Hom.toCoalgHom_injective _ _ } + { map_injective := fun {_ _} => DFunLike.coe_injective.comp <| Hom.toCoalgHom_injective _ _ } instance hasForgetToModule : HasForget₂ (CoalgebraCat R) (ModuleCat R) where forget₂ := diff --git a/Mathlib/Algebra/Category/CoalgebraCat/Monoidal.lean b/Mathlib/Algebra/Category/CoalgebraCat/Monoidal.lean index 6eb6644109de47..dbd37c50e0b591 100644 --- a/Mathlib/Algebra/Category/CoalgebraCat/Monoidal.lean +++ b/Mathlib/Algebra/Category/CoalgebraCat/Monoidal.lean @@ -45,7 +45,7 @@ noncomputable instance instMonoidalCategoryStruct : @[simps] noncomputable def MonoidalCategory.inducingFunctorData : Monoidal.InducingFunctorData (forget₂ (CoalgebraCat R) (ModuleCat R)) where - μIso X Y := Iso.refl _ + μIso _ _ := Iso.refl _ whiskerLeft_eq X Y Z f := by ext; rfl whiskerRight_eq X f := by ext; rfl tensorHom_eq f g := by ext; rfl diff --git a/Mathlib/Algebra/Category/Grp/Adjunctions.lean b/Mathlib/Algebra/Category/Grp/Adjunctions.lean index d3443fcb9cfc51..65064b1835e0bf 100644 --- a/Mathlib/Algebra/Category/Grp/Adjunctions.lean +++ b/Mathlib/Algebra/Category/Grp/Adjunctions.lean @@ -64,7 +64,7 @@ theorem free_map_coe {α β : Type u} {f : α → β} (x : FreeAbelianGroup α) -/ def adj : free ⊣ forget AddCommGrp.{u} := Adjunction.mkOfHomEquiv - { homEquiv := fun X G => FreeAbelianGroup.lift.symm + { homEquiv := fun _ _ => FreeAbelianGroup.lift.symm -- Porting note (#11041): used to be just `by intros; ext; rfl`. homEquiv_naturality_left_symm := by intros @@ -122,7 +122,7 @@ def free : Type u ⥤ Grp where -/ def adj : free ⊣ forget Grp.{u} := Adjunction.mkOfHomEquiv - { homEquiv := fun X G => FreeGroup.lift.symm + { homEquiv := fun _ _ => FreeGroup.lift.symm -- Porting note (#11041): used to be just `by intros; ext1; rfl`. homEquiv_naturality_left_symm := by intros @@ -153,7 +153,7 @@ def abelianize : Grp.{u} ⥤ CommGrp.{u} where /-- The abelianization-forgetful adjuction from `Group` to `CommGroup`. -/ def abelianizeAdj : abelianize ⊣ forget₂ CommGrp.{u} Grp.{u} := Adjunction.mkOfHomEquiv - { homEquiv := fun G A => Abelianization.lift.symm + { homEquiv := fun _ _ => Abelianization.lift.symm -- Porting note (#11041): used to be just `by intros; ext1; rfl`. homEquiv_naturality_left_symm := by intros @@ -178,14 +178,14 @@ def MonCat.units : MonCat.{u} ⥤ Grp.{u} where /-- The forgetful-units adjunction between `Grp` and `MonCat`. -/ def Grp.forget₂MonAdj : forget₂ Grp MonCat ⊣ MonCat.units.{u} := Adjunction.mk' { - homEquiv := fun X Y ↦ + homEquiv := fun _ Y ↦ { toFun := fun f => MonoidHom.toHomUnits f invFun := fun f => (Units.coeHom Y).comp f - left_inv := fun f => MonoidHom.ext fun _ => rfl - right_inv := fun f => MonoidHom.ext fun _ => Units.ext rfl } + left_inv := fun _ => MonoidHom.ext fun _ => rfl + right_inv := fun _ => MonoidHom.ext fun _ => Units.ext rfl } unit := { app := fun X => { (@toUnits X _).toMonoidHom with } - naturality := fun X Y f => MonoidHom.ext fun x => Units.ext rfl } + naturality := fun _ _ _ => MonoidHom.ext fun _ => Units.ext rfl } counit := { app := fun X => Units.coeHom X naturality := by intros; exact MonoidHom.ext fun x => rfl } } @@ -204,14 +204,14 @@ def CommMonCat.units : CommMonCat.{u} ⥤ CommGrp.{u} where /-- The forgetful-units adjunction between `CommGrp` and `CommMonCat`. -/ def CommGrp.forget₂CommMonAdj : forget₂ CommGrp CommMonCat ⊣ CommMonCat.units.{u} := Adjunction.mk' { - homEquiv := fun X Y ↦ + homEquiv := fun _ Y ↦ { toFun := fun f => MonoidHom.toHomUnits f invFun := fun f => (Units.coeHom Y).comp f - left_inv := fun f => MonoidHom.ext fun _ => rfl - right_inv := fun f => MonoidHom.ext fun _ => Units.ext rfl } + left_inv := fun _ => MonoidHom.ext fun _ => rfl + right_inv := fun _ => MonoidHom.ext fun _ => Units.ext rfl } unit := { app := fun X => { (@toUnits X _).toMonoidHom with } - naturality := fun X Y f => MonoidHom.ext fun x => Units.ext rfl } + naturality := fun _ _ _ => MonoidHom.ext fun _ => Units.ext rfl } counit := { app := fun X => Units.coeHom X naturality := by intros; exact MonoidHom.ext fun x => rfl } } diff --git a/Mathlib/Algebra/Category/Grp/Basic.lean b/Mathlib/Algebra/Category/Grp/Basic.lean index 0a0eecfaec00ea..67d5908ffff48e 100644 --- a/Mathlib/Algebra/Category/Grp/Basic.lean +++ b/Mathlib/Algebra/Category/Grp/Basic.lean @@ -145,7 +145,7 @@ example {R S : Grp} (i : R ⟶ S) (r : R) (h : r = 1) : i r = 1 := by simp [h] "Universe lift functor for additive groups."] def uliftFunctor : Grp.{u} ⥤ Grp.{max u v} where obj X := Grp.of (ULift.{v, u} X) - map {X Y} f := Grp.ofHom <| + map {_ _} f := Grp.ofHom <| MulEquiv.ulift.symm.toMonoidHom.comp <| f.comp MulEquiv.ulift.toMonoidHom map_id X := by rfl map_comp {X Y Z} f g := by rfl @@ -287,7 +287,7 @@ example {R S : CommGrp} (i : R ⟶ S) (r : R) (h : r = 1) : i r = 1 := by simp [ "Universe lift functor for additive commutative groups."] def uliftFunctor : CommGrp.{u} ⥤ CommGrp.{max u v} where obj X := CommGrp.of (ULift.{v, u} X) - map {X Y} f := CommGrp.ofHom <| + map {_ _} f := CommGrp.ofHom <| MulEquiv.ulift.symm.toMonoidHom.comp <| f.comp MulEquiv.ulift.toMonoidHom map_id X := by rfl map_comp {X Y Z} f g := by rfl diff --git a/Mathlib/Algebra/Category/Grp/Biproducts.lean b/Mathlib/Algebra/Category/Grp/Biproducts.lean index a45ba714db4a04..cd3163c30ea9fe 100644 --- a/Mathlib/Algebra/Category/Grp/Biproducts.lean +++ b/Mathlib/Algebra/Category/Grp/Biproducts.lean @@ -112,7 +112,7 @@ def productLimitCone : Limits.LimitCone (Discrete.functor f) where π := Discrete.natTrans fun j => Pi.evalAddMonoidHom (fun j => f j) j.as } isLimit := { lift := lift.{_, u} f - fac := fun s j => rfl + fac := fun _ _ => rfl uniq := fun s m w => by ext x funext j diff --git a/Mathlib/Algebra/Category/Grp/EnoughInjectives.lean b/Mathlib/Algebra/Category/Grp/EnoughInjectives.lean index 781920a5448fc0..a64a093313fe71 100644 --- a/Mathlib/Algebra/Category/Grp/EnoughInjectives.lean +++ b/Mathlib/Algebra/Category/Grp/EnoughInjectives.lean @@ -35,7 +35,7 @@ instance enoughInjectives : EnoughInjectives AddCommGrp.{u} where injective := injective_of_divisible _ f := ⟨⟨fun a i ↦ ULift.up (i a), by aesop⟩, by aesop⟩ mono := (AddCommGrp.mono_iff_injective _).mpr <| (injective_iff_map_eq_zero _).mpr - fun a h0 ↦ eq_zero_of_character_apply (congr_arg ULift.down <| congr_fun h0 ·) } + fun _ h0 ↦ eq_zero_of_character_apply (congr_arg ULift.down <| congr_fun h0 ·) } end AddCommGrp diff --git a/Mathlib/Algebra/Category/Grp/EquivalenceGroupAddGroup.lean b/Mathlib/Algebra/Category/Grp/EquivalenceGroupAddGroup.lean index ba62f49de2a29d..1a42f237630565 100644 --- a/Mathlib/Algebra/Category/Grp/EquivalenceGroupAddGroup.lean +++ b/Mathlib/Algebra/Category/Grp/EquivalenceGroupAddGroup.lean @@ -31,7 +31,7 @@ private instance (X : AddCommGrp) : AddZeroClass X.α := X.str.toAddZeroClass @[simps] def toAddGrp : Grp ⥤ AddGrp where obj X := AddGrp.of (Additive X) - map {X} {Y} := MonoidHom.toAdditive + map {_} {_} := MonoidHom.toAdditive end Grp @@ -42,7 +42,7 @@ namespace CommGrp @[simps] def toAddCommGrp : CommGrp ⥤ AddCommGrp where obj X := AddCommGrp.of (Additive X) - map {X} {Y} := MonoidHom.toAdditive + map {_} {_} := MonoidHom.toAdditive end CommGrp @@ -53,7 +53,7 @@ namespace AddGrp @[simps] def toGrp : AddGrp ⥤ Grp where obj X := Grp.of (Multiplicative X) - map {X} {Y} := AddMonoidHom.toMultiplicative + map {_} {_} := AddMonoidHom.toMultiplicative end AddGrp @@ -64,7 +64,7 @@ namespace AddCommGrp @[simps] def toCommGrp : AddCommGrp ⥤ CommGrp where obj X := CommGrp.of (Multiplicative X) - map {X} {Y} := AddMonoidHom.toMultiplicative + map {_} {_} := AddMonoidHom.toMultiplicative end AddCommGrp diff --git a/Mathlib/Algebra/Category/Grp/Limits.lean b/Mathlib/Algebra/Category/Grp/Limits.lean index 0763ecc4606e97..d9ca3a039ecbad 100644 --- a/Mathlib/Algebra/Category/Grp/Limits.lean +++ b/Mathlib/Algebra/Category/Grp/Limits.lean @@ -97,7 +97,7 @@ noncomputable instance Forget₂.createsLimit : validLift := by apply IsLimit.uniqueUpToIso (MonCat.HasLimits.limitConeIsLimit.{v, u} _) t makesLimit := IsLimit.ofFaithful (forget₂ Grp MonCat.{u}) (MonCat.HasLimits.limitConeIsLimit _) - (fun s => _) fun s => rfl } + (fun _ => _) fun _ => rfl } /-- A choice of limit cone for a functor into `Grp`. (Generally, you'll just want to use `limit F`.) diff --git a/Mathlib/Algebra/Category/HopfAlgebraCat/Basic.lean b/Mathlib/Algebra/Category/HopfAlgebraCat/Basic.lean index 413f5f5b36abaf..851259eabc1015 100644 --- a/Mathlib/Algebra/Category/HopfAlgebraCat/Basic.lean +++ b/Mathlib/Algebra/Category/HopfAlgebraCat/Basic.lean @@ -96,12 +96,12 @@ instance concreteCategory : ConcreteCategory.{v} (HopfAlgebraCat.{v} R) where { obj := fun M => M map := fun f => f.toBialgHom } forget_faithful := - { map_injective := fun {M N} => DFunLike.coe_injective.comp <| Hom.toBialgHom_injective _ _ } + { map_injective := fun {_ _} => DFunLike.coe_injective.comp <| Hom.toBialgHom_injective _ _ } instance hasForgetToBialgebra : HasForget₂ (HopfAlgebraCat R) (BialgebraCat R) where forget₂ := { obj := fun X => BialgebraCat.of R X - map := fun {X Y} f => BialgebraCat.ofHom f.toBialgHom } + map := fun {_ _} f => BialgebraCat.ofHom f.toBialgHom } @[simp] theorem forget₂_bialgebra_obj (X : HopfAlgebraCat R) : diff --git a/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean b/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean index 5fbd14b8fb7c0f..c45921b738acdc 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean @@ -36,7 +36,7 @@ free `R`-module with generators `x : X`, implemented as the type `X →₀ R`. @[simps] def free : Type u ⥤ ModuleCat R where obj X := ModuleCat.of R (X →₀ R) - map {X Y} f := Finsupp.lmapDomain _ _ f + map {_ _} f := Finsupp.lmapDomain _ _ f map_id := by intros; exact Finsupp.lmapDomain_id _ _ map_comp := by intros; exact Finsupp.lmapDomain_comp _ _ _ _ @@ -45,8 +45,8 @@ def free : Type u ⥤ ModuleCat R where def adj : free R ⊣ forget (ModuleCat.{u} R) := Adjunction.mkOfHomEquiv { homEquiv := fun X M => (Finsupp.lift M R X).toEquiv.symm - homEquiv_naturality_left_symm := fun {_ _} M f g => - Finsupp.lhom_ext' fun x => + homEquiv_naturality_left_symm := fun {_ _} M _ g => + Finsupp.lhom_ext' fun _ => LinearMap.ext_ring (Finsupp.sum_mapDomain_index_addMonoidHom fun y => (smulAddHom R M).flip (g y)).symm } @@ -246,7 +246,7 @@ open Finsupp instance categoryFree : Category (Free R C) where Hom := fun X Y : C => (X ⟶ Y) →₀ R id := fun X : C => Finsupp.single (𝟙 X) 1 - comp {X Y Z : C} f g := + comp {X _ Z : C} f g := (f.sum (fun f' s => g.sum (fun g' t => Finsupp.single (f' ≫ g') (s * t))) : (X ⟶ Z) →₀ R) assoc {W X Y Z} f g h := by dsimp @@ -263,7 +263,7 @@ section -- accordingly instance : Preadditive (Free R C) where - homGroup X Y := Finsupp.instAddCommGroup + homGroup _ _ := Finsupp.instAddCommGroup add_comp X Y Z f f' g := by dsimp [CategoryTheory.categoryFree] rw [Finsupp.sum_add_index'] <;> · simp [add_mul] @@ -274,7 +274,7 @@ instance : Preadditive (Free R C) where rw [Finsupp.sum_add_index'] <;> · simp [mul_add] instance : Linear R (Free R C) where - homModule X Y := Finsupp.module _ R + homModule _ _ := Finsupp.module _ R smul_comp X Y Z r f g := by dsimp [CategoryTheory.categoryFree] rw [Finsupp.sum_smul_index] <;> simp [Finsupp.smul_sum, mul_assoc] @@ -297,8 +297,8 @@ attribute [local simp] single_comp_single @[simps] def embedding : C ⥤ Free R C where obj X := X - map {X Y} f := Finsupp.single f 1 - map_id X := rfl + map {_ _} f := Finsupp.single f 1 + map_id _ := rfl map_comp {X Y Z} f g := by -- Porting note (#10959): simp used to be able to close this goal dsimp only [] @@ -313,7 +313,7 @@ open Preadditive Linear @[simps] def lift (F : C ⥤ D) : Free R C ⥤ D where obj X := F.obj X - map {X Y} f := f.sum fun f' r => r • F.map f' + map {_ _} f := f.sum fun f' r => r • F.map f' map_id := by dsimp [CategoryTheory.categoryFree]; simp map_comp {X Y Z} f g := by apply Finsupp.induction_linear f @@ -364,7 +364,7 @@ instance lift_linear (F : C ⥤ D) : (lift R F).Linear R where is isomorphic to the original functor. -/ def embeddingLiftIso (F : C ⥤ D) : embedding R C ⋙ lift R F ≅ F := - NatIso.ofComponents fun X => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ /-- Two `R`-linear functors out of the `R`-linear completion are isomorphic iff their compositions with the embedding functor are isomorphic. diff --git a/Mathlib/Algebra/Category/ModuleCat/Algebra.lean b/Mathlib/Algebra/Category/ModuleCat/Algebra.lean index 96c3070180a88b..d2d388822bfff9 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Algebra.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Algebra.lean @@ -56,7 +56,7 @@ example (M N : ModuleCat.{v} A) : Module k (M ⟶ N) := LinearMap.module instance linearOverField : Linear k (ModuleCat.{v} A) where -- Porting note: used to be `by infer_instance` instead of `LinearMap.module` - homModule M N := LinearMap.module + homModule _ _ := LinearMap.module smul_comp := by -- Porting note: this was automatic by `aesop_cat` intros diff --git a/Mathlib/Algebra/Category/ModuleCat/Basic.lean b/Mathlib/Algebra/Category/ModuleCat/Basic.lean index ec69a10b56fc39..4a1b72b744e824 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Basic.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Basic.lean @@ -303,7 +303,7 @@ section variable {S : Type u} [CommRing S] instance : Linear S (ModuleCat.{v} S) where - homModule X Y := LinearMap.module + homModule _ _ := LinearMap.module smul_comp := by intros ext diff --git a/Mathlib/Algebra/Category/ModuleCat/Biproducts.lean b/Mathlib/Algebra/Category/ModuleCat/Biproducts.lean index 4bb37bb584fd66..02972a04dba1a1 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Biproducts.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Biproducts.lean @@ -107,7 +107,7 @@ def productLimitCone : Limits.LimitCone (Discrete.functor f) where π := Discrete.natTrans fun j => (LinearMap.proj j.as : (∀ j, f j) →ₗ[R] f j.as) } isLimit := { lift := lift.{_, v} f - fac := fun s j => rfl + fac := fun _ _ => rfl uniq := fun s m w => by ext x funext j diff --git a/Mathlib/Algebra/Category/ModuleCat/ChangeOfRings.lean b/Mathlib/Algebra/Category/ModuleCat/ChangeOfRings.lean index 25c3bca193dcb2..9d1934b7c1d113 100644 --- a/Mathlib/Algebra/Category/ModuleCat/ChangeOfRings.lean +++ b/Mathlib/Algebra/Category/ModuleCat/ChangeOfRings.lean @@ -137,9 +137,9 @@ def semilinearMapAddEquiv {R : Type u₁} {S : Type u₂} [Ring R] [Ring S] (f : { toFun := g map_add' := by simp map_smul' := g.map_smul } - left_inv g := rfl - right_inv g := rfl - map_add' g₁ g₂ := rfl + left_inv _ := rfl + right_inv _ := rfl + map_add' _ _ := rfl section @@ -248,7 +248,7 @@ def restrictScalarsEquivalenceOfRingEquiv {R S} [Ring R] [Ring S] (e : R ≃+* S map_smul' := fun s m ↦ congr_arg (· • m) (e.right_inv s).symm }) (by intros; rfl) counitIso := NatIso.ofComponents (fun M ↦ LinearEquiv.toModuleIso' { __ := AddEquiv.refl M - map_smul' := fun r m ↦ congr_arg (· • (_ : M)) (e.left_inv r)}) (by intros; rfl) + map_smul' := fun r _ ↦ congr_arg (· • (_ : M)) (e.left_inv r)}) (by intros; rfl) functor_unitIso_comp := by intros; rfl instance restrictScalars_isEquivalence_of_ringEquiv {R S} [Ring R] [Ring S] (e : R ≃+* S) : @@ -375,7 +375,7 @@ instance mulAction : MulAction S <| (restrictScalars f).obj ⟨S⟩ →ₗ[R] M instance distribMulAction : DistribMulAction S <| (restrictScalars f).obj ⟨S⟩ →ₗ[R] M := { CoextendScalars.mulAction f _ with smul_add := fun s g h => LinearMap.ext fun _ : S => by simp - smul_zero := fun s => LinearMap.ext fun _ : S => by simp } + smul_zero := fun _ => LinearMap.ext fun _ : S => by simp } /-- `S` acts on Hom(S, M) by `s • g = x ↦ g (x • s)`, this action defines an `S`-module structure on Hom(S, M). @@ -496,7 +496,7 @@ def HomEquiv.toRestriction {X Y} (g : Y ⟶ (coextendScalars f).obj X) : def app' (Y : ModuleCat S) : Y →ₗ[S] (restrictScalars f ⋙ coextendScalars f).obj Y := { toFun := fun y : Y => { toFun := fun s : S => (s • y : Y) - map_add' := fun s s' => add_smul _ _ _ + map_add' := fun _ _ => add_smul _ _ _ map_smul' := fun r (s : S) => by dsimp only [AddHom.toFun_eq_coe, AddHom.coe_mk, RingHom.id_apply] erw [smul_eq_mul, mul_smul] @@ -582,7 +582,7 @@ def restrictCoextendScalarsAdj {R : Type u₁} {S : Type u₂} [Ring R] [Ring S] CoextendScalars.smul_apply', one_mul] } unit := RestrictionCoextensionAdj.unit'.{u₁,u₂,v} f counit := RestrictionCoextensionAdj.counit'.{u₁,u₂,v} f - homEquiv_unit := LinearMap.ext fun y => rfl + homEquiv_unit := LinearMap.ext fun _ => rfl homEquiv_counit := fun {X Y g} => LinearMap.ext <| by -- Porting note (#10745): previously simp [RestrictionCoextensionAdj.counit'] intro x; dsimp diff --git a/Mathlib/Algebra/Category/ModuleCat/Colimits.lean b/Mathlib/Algebra/Category/ModuleCat/Colimits.lean index dd77562189b3e4..d3858a83537a4b 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Colimits.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Colimits.lean @@ -42,7 +42,7 @@ noncomputable def coconePointSMul : R →+* End (colimit (F ⋙ forget₂ _ AddCommGrp)) where toFun r := colimMap { app := fun j => (F.obj j).smul r - naturality := fun X Y f => smul_naturality _ _ } + naturality := fun _ _ _ => smul_naturality _ _ } map_zero' := colimit.hom_ext (by simp) map_one' := colimit.hom_ext (by simp) map_add' r s := colimit.hom_ext (fun j => by diff --git a/Mathlib/Algebra/Category/ModuleCat/EpiMono.lean b/Mathlib/Algebra/Category/ModuleCat/EpiMono.lean index ce1d6cca433f84..0a359d162c781e 100644 --- a/Mathlib/Algebra/Category/ModuleCat/EpiMono.lean +++ b/Mathlib/Algebra/Category/ModuleCat/EpiMono.lean @@ -31,7 +31,7 @@ theorem range_eq_top_of_epi [Epi f] : LinearMap.range f = ⊤ := LinearMap.range_eq_top_of_cancel fun u v => (@cancel_epi _ _ _ _ _ f _ (↟u) (↟v)).1 theorem mono_iff_ker_eq_bot : Mono f ↔ LinearMap.ker f = ⊥ := - ⟨fun hf => ker_eq_bot_of_mono _, fun hf => + ⟨fun _ => ker_eq_bot_of_mono _, fun hf => ConcreteCategory.mono_of_injective _ <| by convert LinearMap.ker_eq_bot.1 hf⟩ theorem mono_iff_injective : Mono f ↔ Function.Injective f := by diff --git a/Mathlib/Algebra/Category/ModuleCat/Kernels.lean b/Mathlib/Algebra/Category/ModuleCat/Kernels.lean index b93458aaf03436..22f0ec32458353 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Kernels.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Kernels.lean @@ -39,7 +39,7 @@ def kernelIsLimit : IsLimit (kernelCone f) := erw [← @Function.comp_apply _ _ _ f (Fork.ι s) c, ← coe_comp] rw [Fork.condition, HasZeroMorphisms.comp_zero (Fork.ι s) N] rfl) - (fun s => LinearMap.subtype_comp_codRestrict _ _ _) fun s m h => + (fun _ => LinearMap.subtype_comp_codRestrict _ _ _) fun s m h => LinearMap.ext fun x => Subtype.ext_iff_val.2 (by simp [← h]; rfl) /-- The cokernel cocone induced by the projection onto the quotient. -/ diff --git a/Mathlib/Algebra/Category/ModuleCat/Monoidal/Closed.lean b/Mathlib/Algebra/Category/ModuleCat/Monoidal/Closed.lean index 55bbfb7b8390cd..979e0ee459b68c 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Monoidal/Closed.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Monoidal/Closed.lean @@ -38,7 +38,7 @@ def monoidalClosedHomEquiv (M N P : ModuleCat.{u} R) : rw [Function.comp_apply] -- This used to be `rw` and was longer (?), but we need `erw` after leanprover/lean4#2644 erw [MonoidalCategory.braiding_hom_apply, TensorProduct.lift.tmul] - right_inv f := rfl + right_inv _ := rfl instance : MonoidalClosed (ModuleCat.{u} R) where closed M := diff --git a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Colimits.lean b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Colimits.lean index 26b9df8025f49b..ea25e5d1bf2f77 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Colimits.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Colimits.lean @@ -63,7 +63,7 @@ taking a colimit in the category of modules over `R.obj X` for all `X`. -/ @[simps] noncomputable def colimitPresheafOfModules : PresheafOfModules R where obj X := colimit (F ⋙ evaluation R X) - map {X Y} f := colimMap (whiskerLeft F (restriction R f)) ≫ + map {_ Y} f := colimMap (whiskerLeft F (restriction R f)) ≫ (preservesColimitIso (ModuleCat.restrictScalars (R.map f)) (F ⋙ evaluation R Y)).inv map_id X := colimit.hom_ext (fun j => by dsimp diff --git a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Limits.lean b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Limits.lean index a8c8858cd5bfeb..52757e35c210f6 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Presheaf/Limits.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Presheaf/Limits.lean @@ -63,7 +63,7 @@ taking a limit in the category of modules over `R.obj X` for all `X`. -/ @[simps] noncomputable def limitPresheafOfModules : PresheafOfModules R where obj X := limit (F ⋙ evaluation R X) - map {X Y} f := limMap (whiskerLeft F (restriction R f)) ≫ + map {_ Y} f := limMap (whiskerLeft F (restriction R f)) ≫ (preservesLimitIso (ModuleCat.restrictScalars (R.map f)) (F ⋙ evaluation R Y)).inv map_id X := by dsimp diff --git a/Mathlib/Algebra/Category/MonCat/Adjunctions.lean b/Mathlib/Algebra/Category/MonCat/Adjunctions.lean index 6b618ac579624b..256b8f3478523e 100644 --- a/Mathlib/Algebra/Category/MonCat/Adjunctions.lean +++ b/Mathlib/Algebra/Category/MonCat/Adjunctions.lean @@ -46,7 +46,7 @@ instance hasForgetToSemigroup : HasForget₂ MonCat Semigrp where @[to_additive "The `adjoinZero`-forgetful adjunction from `AddSemigrp` to `AddMonCat`"] def adjoinOneAdj : adjoinOne ⊣ forget₂ MonCat.{u} Semigrp.{u} := Adjunction.mkOfHomEquiv - { homEquiv := fun S M => WithOne.lift.symm + { homEquiv := fun _ _ => WithOne.lift.symm homEquiv_naturality_left_symm := by intro S T M f g ext x @@ -67,7 +67,7 @@ def free : Type u ⥤ MonCat.{u} where /-- The free-forgetful adjunction for monoids. -/ def adj : free ⊣ forget MonCat.{u} := Adjunction.mkOfHomEquiv - { homEquiv := fun X G => FreeMonoid.lift.symm + { homEquiv := fun _ _ => FreeMonoid.lift.symm homEquiv_naturality_left_symm := fun _ _ => FreeMonoid.hom_eq (fun _ => rfl) } instance : (forget MonCat.{u}).IsRightAdjoint := diff --git a/Mathlib/Algebra/Category/MonCat/Basic.lean b/Mathlib/Algebra/Category/MonCat/Basic.lean index 22bdae92084985..4dbb96dfa65aa0 100644 --- a/Mathlib/Algebra/Category/MonCat/Basic.lean +++ b/Mathlib/Algebra/Category/MonCat/Basic.lean @@ -46,7 +46,7 @@ add_decl_doc AddMonCat.AssocAddMonoidHom @[to_additive] instance bundledHom : BundledHom AssocMonoidHom where - toFun {X Y} _ _ f := ⇑f + toFun {_ _} _ _ f := ⇑f id _ := MonoidHom.id _ comp _ _ _ := MonoidHom.comp @@ -145,7 +145,7 @@ instance {G : Type*} [Group G] : Group (MonCat.of G) := by assumption "Universe lift functor for additive monoids."] def uliftFunctor : MonCat.{u} ⥤ MonCat.{max u v} where obj X := MonCat.of (ULift.{v, u} X) - map {X Y} f := MonCat.ofHom <| + map {_ _} f := MonCat.ofHom <| MulEquiv.ulift.symm.toMonoidHom.comp <| f.comp MulEquiv.ulift.toMonoidHom map_id X := by rfl map_comp {X Y Z} f g := by rfl @@ -249,7 +249,7 @@ lemma ofHom_apply {X Y : Type u} [CommMonoid X] [CommMonoid Y] (f : X →* Y) (x "Universe lift functor for additive commutative monoids."] def uliftFunctor : CommMonCat.{u} ⥤ CommMonCat.{max u v} where obj X := CommMonCat.of (ULift.{v, u} X) - map {X Y} f := CommMonCat.ofHom <| + map {_ _} f := CommMonCat.ofHom <| MulEquiv.ulift.symm.toMonoidHom.comp <| f.comp MulEquiv.ulift.toMonoidHom map_id X := by rfl map_comp {X Y Z} f g := by rfl diff --git a/Mathlib/Algebra/Category/MonCat/Colimits.lean b/Mathlib/Algebra/Category/MonCat/Colimits.lean index bfb19dcc5a1bc1..ac67635fefbbe9 100644 --- a/Mathlib/Algebra/Category/MonCat/Colimits.lean +++ b/Mathlib/Algebra/Category/MonCat/Colimits.lean @@ -122,7 +122,7 @@ instance : Inhabited (ColimitType F) := by instance monoidColimitType : Monoid (ColimitType F) where one := Quotient.mk _ one - mul := Quotient.map₂ mul fun x x' rx y y' ry => + mul := Quotient.map₂ mul fun _ x' rx y _ ry => Setoid.trans (Relation.mul_1 _ _ y rx) (Relation.mul_2 x' _ _ ry) one_mul := Quotient.ind fun _ => Quotient.sound <| Relation.one_mul _ mul_one := Quotient.ind fun _ => Quotient.sound <| Relation.mul_one _ diff --git a/Mathlib/Algebra/Category/MonCat/Limits.lean b/Mathlib/Algebra/Category/MonCat/Limits.lean index 77a05ad7f091f5..123dc3372c9c13 100644 --- a/Mathlib/Algebra/Category/MonCat/Limits.lean +++ b/Mathlib/Algebra/Category/MonCat/Limits.lean @@ -207,7 +207,7 @@ noncomputable instance forget₂CreatesLimit : CreatesLimit F (forget₂ CommMon validLift := by apply IsLimit.uniqueUpToIso (MonCat.HasLimits.limitConeIsLimit _) t makesLimit := IsLimit.ofFaithful (forget₂ CommMonCat MonCat.{u}) - (MonCat.HasLimits.limitConeIsLimit _) (fun s => _) fun s => rfl } + (MonCat.HasLimits.limitConeIsLimit _) (fun _ => _) fun _ => rfl } /-- A choice of limit cone for a functor into `CommMonCat`. (Generally, you'll just want to use `limit F`.) diff --git a/Mathlib/Algebra/Category/Ring/Adjunctions.lean b/Mathlib/Algebra/Category/Ring/Adjunctions.lean index 7e9619ecea87ca..968ee34718fb1b 100644 --- a/Mathlib/Algebra/Category/Ring/Adjunctions.lean +++ b/Mathlib/Algebra/Category/Ring/Adjunctions.lean @@ -47,7 +47,7 @@ theorem free_map_coe {α β : Type u} {f : α → β} : ⇑(free.map f) = ⇑(re -/ def adj : free ⊣ forget CommRingCat.{u} := Adjunction.mkOfHomEquiv - { homEquiv := fun X R => homEquiv + { homEquiv := fun _ _ => homEquiv homEquiv_naturality_left_symm := fun {_ _ Y} f g => RingHom.ext fun x => eval₂_cast_comp f (Int.castRingHom Y) g x } diff --git a/Mathlib/Algebra/Category/Ring/Basic.lean b/Mathlib/Algebra/Category/Ring/Basic.lean index 4e1a2a7998aaeb..718c2490097f56 100644 --- a/Mathlib/Algebra/Category/Ring/Basic.lean +++ b/Mathlib/Algebra/Category/Ring/Basic.lean @@ -377,7 +377,7 @@ instance hasForgetToSemiRingCat : HasForget₂ CommSemiRingCat SemiRingCat := /-- The forgetful functor from commutative rings to (multiplicative) commutative monoids. -/ instance hasForgetToCommMonCat : HasForget₂ CommSemiRingCat CommMonCat := - HasForget₂.mk' (fun R : CommSemiRingCat => CommMonCat.of R) (fun R => rfl) + HasForget₂.mk' (fun R : CommSemiRingCat => CommMonCat.of R) (fun _ => rfl) -- Porting note: `(_ := _)` trick (fun {R₁ R₂} f => RingHom.toMonoidHom (α := R₁) (β := R₂) f) (by rfl) @@ -531,8 +531,8 @@ instance hasForgetToRingCat : HasForget₂ CommRingCat RingCat := /-- The forgetful functor from commutative rings to (multiplicative) commutative monoids. -/ instance hasForgetToCommSemiRingCat : HasForget₂ CommRingCat CommSemiRingCat := - HasForget₂.mk' (fun R : CommRingCat => CommSemiRingCat.of R) (fun R => rfl) - (fun {R₁ R₂} f => f) (by rfl) + HasForget₂.mk' (fun R : CommRingCat => CommSemiRingCat.of R) (fun _ => rfl) + (fun {_ _} f => f) (by rfl) instance : (forget₂ CommRingCat CommSemiRingCat).Full where map_surjective f := ⟨f, rfl⟩ diff --git a/Mathlib/Algebra/Category/Ring/Colimits.lean b/Mathlib/Algebra/Category/Ring/Colimits.lean index b2c1204a2af626..8e8ac95f716511 100644 --- a/Mathlib/Algebra/Category/Ring/Colimits.lean +++ b/Mathlib/Algebra/Category/Ring/Colimits.lean @@ -135,14 +135,14 @@ instance ColimitType.AddGroupWithOne : AddGroupWithOne (ColimitType F) := instance : Ring (ColimitType.{v} F) := { ColimitType.AddGroupWithOne F with mul := Quot.map₂ Prequotient.mul Relation.mul_2 Relation.mul_1 - one_mul := fun x => Quot.inductionOn x fun x => Quot.sound <| Relation.one_mul _ - mul_one := fun x => Quot.inductionOn x fun x => Quot.sound <| Relation.mul_one _ - add_comm := fun x y => Quot.induction_on₂ x y fun x y => Quot.sound <| Relation.add_comm _ _ + one_mul := fun x => Quot.inductionOn x fun _ => Quot.sound <| Relation.one_mul _ + mul_one := fun x => Quot.inductionOn x fun _ => Quot.sound <| Relation.mul_one _ + add_comm := fun x y => Quot.induction_on₂ x y fun _ _ => Quot.sound <| Relation.add_comm _ _ mul_assoc := fun x y z => Quot.induction_on₃ x y z fun x y z => by simp only [(· * ·)] exact Quot.sound (Relation.mul_assoc _ _ _) - mul_zero := fun x => Quot.inductionOn x fun x => Quot.sound <| Relation.mul_zero _ - zero_mul := fun x => Quot.inductionOn x fun x => Quot.sound <| Relation.zero_mul _ + mul_zero := fun x => Quot.inductionOn x fun _ => Quot.sound <| Relation.mul_zero _ + zero_mul := fun x => Quot.inductionOn x fun _ => Quot.sound <| Relation.zero_mul _ left_distrib := fun x y z => Quot.induction_on₃ x y z fun x y z => by simp only [(· + ·), (· * ·), Add.add] exact Quot.sound (Relation.left_distrib _ _ _) @@ -442,15 +442,15 @@ instance ColimitType.AddGroupWithOne : AddGroupWithOne (ColimitType F) := instance : CommRing (ColimitType.{v} F) := { ColimitType.AddGroupWithOne F with mul := Quot.map₂ Prequotient.mul Relation.mul_2 Relation.mul_1 - one_mul := fun x => Quot.inductionOn x fun x => Quot.sound <| Relation.one_mul _ - mul_one := fun x => Quot.inductionOn x fun x => Quot.sound <| Relation.mul_one _ - add_comm := fun x y => Quot.induction_on₂ x y fun x y => Quot.sound <| Relation.add_comm _ _ - mul_comm := fun x y => Quot.induction_on₂ x y fun x y => Quot.sound <| Relation.mul_comm _ _ + one_mul := fun x => Quot.inductionOn x fun _ => Quot.sound <| Relation.one_mul _ + mul_one := fun x => Quot.inductionOn x fun _ => Quot.sound <| Relation.mul_one _ + add_comm := fun x y => Quot.induction_on₂ x y fun _ _ => Quot.sound <| Relation.add_comm _ _ + mul_comm := fun x y => Quot.induction_on₂ x y fun _ _ => Quot.sound <| Relation.mul_comm _ _ mul_assoc := fun x y z => Quot.induction_on₃ x y z fun x y z => by simp only [(· * ·)] exact Quot.sound (Relation.mul_assoc _ _ _) - mul_zero := fun x => Quot.inductionOn x fun x => Quot.sound <| Relation.mul_zero _ - zero_mul := fun x => Quot.inductionOn x fun x => Quot.sound <| Relation.zero_mul _ + mul_zero := fun x => Quot.inductionOn x fun _ => Quot.sound <| Relation.mul_zero _ + zero_mul := fun x => Quot.inductionOn x fun _ => Quot.sound <| Relation.zero_mul _ left_distrib := fun x y z => Quot.induction_on₃ x y z fun x y z => by simp only [(· + ·), (· * ·), Add.add] exact Quot.sound (Relation.left_distrib _ _ _) diff --git a/Mathlib/Algebra/Category/Ring/Constructions.lean b/Mathlib/Algebra/Category/Ring/Constructions.lean index 0736d93d4951f7..c2cc69f71a187a 100644 --- a/Mathlib/Algebra/Category/Ring/Constructions.lean +++ b/Mathlib/Algebra/Category/Ring/Constructions.lean @@ -183,7 +183,7 @@ The categorical product of rings is the cartesian product of rings. def piFanIsLimit : IsLimit (piFan R) where lift s := Pi.ringHom fun i ↦ s.π.1 ⟨i⟩ fac s i := by rfl - uniq s g h := DFunLike.ext _ _ fun x ↦ funext fun i ↦ DFunLike.congr_fun (h ⟨i⟩) x + uniq _ _ h := DFunLike.ext _ _ fun x ↦ funext fun i ↦ DFunLike.congr_fun (h ⟨i⟩) x /-- The categorical product and the usual product agrees diff --git a/Mathlib/Algebra/Category/Ring/Limits.lean b/Mathlib/Algebra/Category/Ring/Limits.lean index a0c514581878e8..bc7c9f6b9f8532 100644 --- a/Mathlib/Algebra/Category/Ring/Limits.lean +++ b/Mathlib/Algebra/Category/Ring/Limits.lean @@ -340,7 +340,7 @@ instance : CreatesLimit F (forget₂ RingCat.{u} SemiRingCat.{u}) := validLift := by apply IsLimit.uniqueUpToIso (SemiRingCat.HasLimits.limitConeIsLimit _) t makesLimit := IsLimit.ofFaithful (forget₂ RingCat SemiRingCat.{u}) - (by apply SemiRingCat.HasLimits.limitConeIsLimit _) (fun s => _) fun s => rfl } + (by apply SemiRingCat.HasLimits.limitConeIsLimit _) (fun _ => _) fun _ => rfl } /-- A choice of limit cone for a functor into `RingCat`. (Generally, you'll just want to use `limit F`.) diff --git a/Mathlib/Algebra/CharP/Defs.lean b/Mathlib/Algebra/CharP/Defs.lean index e597077cdd70eb..4a4cc50bbda1f9 100644 --- a/Mathlib/Algebra/CharP/Defs.lean +++ b/Mathlib/Algebra/CharP/Defs.lean @@ -244,7 +244,7 @@ section NoZeroDivisors variable [NoZeroDivisors R] -lemma char_is_prime_of_two_le (p : ℕ) [hc : CharP R p] (hp : 2 ≤ p) : Nat.Prime p := +lemma char_is_prime_of_two_le (p : ℕ) [CharP R p] (hp : 2 ≤ p) : Nat.Prime p := suffices ∀ (d) (_ : d ∣ p), d = 1 ∨ d = p from Nat.prime_def_lt''.mpr ⟨hp, this⟩ fun (d : ℕ) (hdvd : ∃ e, p = d * e) => let ⟨e, hmul⟩ := hdvd diff --git a/Mathlib/Algebra/CharZero/Lemmas.lean b/Mathlib/Algebra/CharZero/Lemmas.lean index 15bdc16d9f97e6..5c3ac417809dde 100644 --- a/Mathlib/Algebra/CharZero/Lemmas.lean +++ b/Mathlib/Algebra/CharZero/Lemmas.lean @@ -154,7 +154,7 @@ theorem RingHom.charZero (ϕ : R →+* S) [CharZero S] : CharZero R := theorem RingHom.charZero_iff {ϕ : R →+* S} (hϕ : Function.Injective ϕ) : CharZero R ↔ CharZero S := ⟨fun hR => ⟨by intro a b h; rwa [← @Nat.cast_inj R, ← hϕ.eq_iff, map_natCast ϕ, map_natCast ϕ]⟩, - fun hS => ϕ.charZero⟩ + fun _ => ϕ.charZero⟩ theorem RingHom.injective_nat (f : ℕ →+* R) [CharZero R] : Function.Injective f := Subsingleton.elim (Nat.castRingHom _) f ▸ Nat.cast_injective diff --git a/Mathlib/Algebra/DirectLimit.lean b/Mathlib/Algebra/DirectLimit.lean index bcbcb659f05d8a..06bfd7e4deaaf4 100644 --- a/Mathlib/Algebra/DirectLimit.lean +++ b/Mathlib/Algebra/DirectLimit.lean @@ -203,7 +203,7 @@ def map (g : (i : ι) → G i →ₗ[R] G' i) (hg : ∀ i j h, g j ∘ₗ f i j lift_of _ _ _ @[simp] lemma map_id [IsDirected ι (· ≤ ·)] : - map (fun i ↦ LinearMap.id) (fun _ _ _ ↦ rfl) = LinearMap.id (R := R) (M := DirectLimit G f) := + map (fun _ ↦ LinearMap.id) (fun _ _ _ ↦ rfl) = LinearMap.id (R := R) (M := DirectLimit G f) := DFunLike.ext _ _ fun x ↦ (isEmpty_or_nonempty ι).elim (by subsingleton) fun _ ↦ x.induction_on fun i g ↦ by simp @@ -313,7 +313,7 @@ theorem of.zero_exact_aux [∀ i (k : G i), Decidable (k ≠ 0)] [Nonempty ι] [ ⟨ind, fun _ h => (Finset.not_mem_empty _ h).elim, LinearMap.map_zero _⟩ (fun x y ⟨i, hi, hxi⟩ ⟨j, hj, hyj⟩ => let ⟨k, hik, hjk⟩ := exists_ge_ge i j - ⟨k, fun l hl => + ⟨k, fun _ hl => (Finset.mem_union.1 (DFinsupp.support_add hl)).elim (fun hl => le_trans (hi _ hl) hik) fun hl => le_trans (hj _ hl) hjk, by simp [LinearMap.map_add, hxi, hyj, toModule_totalize_of_le hik hi, @@ -458,7 +458,7 @@ def map (g : (i : ι) → G i →+ G' i) lift_of _ _ _ _ _ @[simp] lemma map_id [IsDirected ι (· ≤ ·)] : - map (fun i ↦ AddMonoidHom.id _) (fun _ _ _ ↦ rfl) = AddMonoidHom.id (DirectLimit G f) := + map (fun _ ↦ AddMonoidHom.id _) (fun _ _ _ ↦ rfl) = AddMonoidHom.id (DirectLimit G f) := DFunLike.ext _ _ fun x ↦ (isEmpty_or_nonempty ι).elim (by subsingleton) fun _ ↦ x.induction_on fun i g ↦ by simp @@ -861,7 +861,7 @@ def map (g : (i : ι) → G i →+* G' i) variable [Nonempty ι] @[simp] lemma map_id [IsDirected ι (· ≤ ·)] : - map (fun i ↦ RingHom.id _) (fun _ _ _ ↦ rfl) = + map (fun _ ↦ RingHom.id _) (fun _ _ _ ↦ rfl) = RingHom.id (DirectLimit G fun _ _ h ↦ f _ _ h) := DFunLike.ext _ _ fun x ↦ x.induction_on fun i g ↦ by simp @@ -963,12 +963,12 @@ protected noncomputable abbrev field [DirectedSystem G fun i j h => f' i j h] : -- This used to include the parent CommRing and Nontrivial instances, -- but leaving them implicit avoids a very expensive (2-3 minutes!) eta expansion. inv := inv G fun i j h => f' i j h - mul_inv_cancel := fun p => DirectLimit.mul_inv_cancel G fun i j h => f' i j h + mul_inv_cancel := fun _ => DirectLimit.mul_inv_cancel G fun i j h => f' i j h inv_zero := dif_pos rfl nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl qsmul := _ - qsmul_def := fun q a => rfl + qsmul_def := fun _ _ => rfl end diff --git a/Mathlib/Algebra/DirectSum/Basic.lean b/Mathlib/Algebra/DirectSum/Basic.lean index be12e9e5145fbd..f4f49ac0545981 100644 --- a/Mathlib/Algebra/DirectSum/Basic.lean +++ b/Mathlib/Algebra/DirectSum/Basic.lean @@ -272,7 +272,7 @@ protected def id (M : Type v) (ι : Type* := PUnit) [AddCommMonoid M] [Unique ι DirectSum.induction_on x (by rw [AddMonoidHom.map_zero, AddMonoidHom.map_zero]) (fun p x => by rw [Unique.default_eq p, toAddMonoid_of]; rfl) fun x y ihx ihy => by rw [AddMonoidHom.map_add, AddMonoidHom.map_add, ihx, ihy] - right_inv := fun x => toAddMonoid_of _ _ _ } + right_inv := fun _ => toAddMonoid_of _ _ _ } section CongrLeft diff --git a/Mathlib/Algebra/DirectSum/Module.lean b/Mathlib/Algebra/DirectSum/Module.lean index 291bd79759b1b2..4ed1b6c1db1b8f 100644 --- a/Mathlib/Algebra/DirectSum/Module.lean +++ b/Mathlib/Algebra/DirectSum/Module.lean @@ -223,7 +223,7 @@ variable {α : ι → Type*} {δ : ∀ i, α i → Type w} variable [DecidableEq ι] [∀ i j, AddCommMonoid (δ i j)] [∀ i j, Module R (δ i j)] /-- `curry` as a linear map. -/ -def sigmaLcurry : (⨁ i : Σi, _, δ i.1 i.2) →ₗ[R] ⨁ (i) (j), δ i j := +def sigmaLcurry : (⨁ i : Σ_, _, δ i.1 i.2) →ₗ[R] ⨁ (i) (j), δ i j := { sigmaCurry with map_smul' := fun r ↦ by convert DFinsupp.sigmaCurry_smul (δ := δ) r } @[simp] diff --git a/Mathlib/Algebra/DirectSum/Ring.lean b/Mathlib/Algebra/DirectSum/Ring.lean index adc80f5bfe07a8..39d62eca17f6e7 100644 --- a/Mathlib/Algebra/DirectSum/Ring.lean +++ b/Mathlib/Algebra/DirectSum/Ring.lean @@ -287,7 +287,7 @@ theorem list_prod_ofFn_of_eq_dProd (n : ℕ) (fι : Fin n → ι) (fA : ∀ a, A theorem mul_eq_dfinsupp_sum [∀ (i : ι) (x : A i), Decidable (x ≠ 0)] (a a' : ⨁ i, A i) : a * a' - = a.sum fun i ai => a'.sum fun j aj => DirectSum.of _ _ <| GradedMonoid.GMul.mul ai aj := by + = a.sum fun _ ai => a'.sum fun _ aj => DirectSum.of _ _ <| GradedMonoid.GMul.mul ai aj := by change mulHom _ a a' = _ -- Porting note: I have no idea how the proof from ml3 worked it used to be -- simpa only [mul_hom, to_add_monoid, dfinsupp.lift_add_hom_apply, dfinsupp.sum_add_hom_apply, diff --git a/Mathlib/Algebra/Divisibility/Units.lean b/Mathlib/Algebra/Divisibility/Units.lean index aee46556f879c1..5f8d41a57b2450 100644 --- a/Mathlib/Algebra/Divisibility/Units.lean +++ b/Mathlib/Algebra/Divisibility/Units.lean @@ -34,7 +34,7 @@ theorem coe_dvd : ↑u ∣ a := associates of `b`. -/ theorem dvd_mul_right : a ∣ b * u ↔ a ∣ b := Iff.intro (fun ⟨c, Eq⟩ ↦ ⟨c * ↑u⁻¹, by rw [← mul_assoc, ← Eq, Units.mul_inv_cancel_right]⟩) - fun ⟨c, Eq⟩ ↦ Eq.symm ▸ (_root_.dvd_mul_right _ _).mul_right _ + fun ⟨_, Eq⟩ ↦ Eq.symm ▸ (_root_.dvd_mul_right _ _).mul_right _ /-- In a monoid, an element `a` divides an element `b` iff all associates of `a` divide `b`. -/ theorem mul_right_dvd : a * u ∣ b ↔ a ∣ b := diff --git a/Mathlib/Algebra/DualNumber.lean b/Mathlib/Algebra/DualNumber.lean index eb913a5ad941fb..6e2ef4a79c866f 100644 --- a/Mathlib/Algebra/DualNumber.lean +++ b/Mathlib/Algebra/DualNumber.lean @@ -149,16 +149,37 @@ theorem lift_apply_apply (fe : {_fe : (A →ₐ[R] B) × B // _}) (a : A[ε]) : @[simp] theorem coe_lift_symm_apply (F : A[ε] →ₐ[R] B) : (lift.symm F).val = (F.comp (inlAlgHom _ _ _), F ε) := rfl +#adaptation_note +/-- +The new unused variable linter in +https://github.com/leanprover/lean4/pull/5338 +flags `{fe : (A →ₐ[R] B) × B // _}`. +-/ +set_option linter.unusedVariables false in /-- When applied to `inl`, `DualNumber.lift` applies the map `f : A →ₐ[R] B`. -/ @[simp] theorem lift_apply_inl (fe : {fe : (A →ₐ[R] B) × B // _}) (a : A) : lift fe (inl a : A[ε]) = fe.val.1 a := by rw [lift_apply_apply, fst_inl, snd_inl, map_zero, zero_mul, add_zero] +#adaptation_note +/-- +The new unused variable linter in +https://github.com/leanprover/lean4/pull/5338 +flags `{fe : (A →ₐ[R] B) × B // _}`. +-/ +set_option linter.unusedVariables false in /-- Scaling on the left is sent by `DualNumber.lift` to multiplication on the left -/ @[simp] theorem lift_smul (fe : {fe : (A →ₐ[R] B) × B // _}) (a : A) (ad : A[ε]) : lift fe (a • ad) = fe.val.1 a * lift fe ad := by rw [← inl_mul_eq_smul, map_mul, lift_apply_inl] +#adaptation_note +/-- +The new unused variable linter in +https://github.com/leanprover/lean4/pull/5338 +flags `{fe : (A →ₐ[R] B) × B // _}`. +-/ +set_option linter.unusedVariables false in /-- Scaling on the right is sent by `DualNumber.lift` to multiplication on the right -/ @[simp] theorem lift_op_smul (fe : {fe : (A →ₐ[R] B) × B // _}) (a : A) (ad : A[ε]) : lift fe (MulOpposite.op a • ad) = lift fe ad * fe.val.1 a := by diff --git a/Mathlib/Algebra/DualQuaternion.lean b/Mathlib/Algebra/DualQuaternion.lean index 70ed1572d86ace..c1178645b683e5 100644 --- a/Mathlib/Algebra/DualQuaternion.lean +++ b/Mathlib/Algebra/DualQuaternion.lean @@ -36,20 +36,18 @@ def dualNumberEquiv : Quaternion (DualNumber R) ≃ₐ[R] DualNumber (Quaternion (⟨q.re.fst, q.imI.fst, q.imJ.fst, q.imK.fst⟩, ⟨q.re.snd, q.imI.snd, q.imJ.snd, q.imK.snd⟩) invFun d := ⟨(d.fst.re, d.snd.re), (d.fst.imI, d.snd.imI), (d.fst.imJ, d.snd.imJ), (d.fst.imK, d.snd.imK)⟩ - left_inv := fun ⟨⟨r, rε⟩, ⟨i, iε⟩, ⟨j, jε⟩, ⟨k, kε⟩⟩ => rfl - right_inv := fun ⟨⟨r, i, j, k⟩, ⟨rε, iε, jε, kε⟩⟩ => rfl + left_inv := fun _ => rfl + right_inv := fun _ => rfl map_mul' := by - rintro ⟨⟨xr, xrε⟩, ⟨xi, xiε⟩, ⟨xj, xjε⟩, ⟨xk, xkε⟩⟩ - rintro ⟨⟨yr, yrε⟩, ⟨yi, yiε⟩, ⟨yj, yjε⟩, ⟨yk, ykε⟩⟩ + intros ext : 1 · rfl · dsimp congr 1 <;> simp <;> ring map_add' := by - rintro ⟨⟨xr, xrε⟩, ⟨xi, xiε⟩, ⟨xj, xjε⟩, ⟨xk, xkε⟩⟩ - rintro ⟨⟨yr, yrε⟩, ⟨yi, yiε⟩, ⟨yj, yjε⟩, ⟨yk, ykε⟩⟩ + intros rfl - commutes' r := rfl + commutes' _ := rfl /-! Lemmas characterizing `Quaternion.dualNumberEquiv`. -/ diff --git a/Mathlib/Algebra/EuclideanDomain/Field.lean b/Mathlib/Algebra/EuclideanDomain/Field.lean index 63d2c16a2f5245..10ee495e3d968c 100644 --- a/Mathlib/Algebra/EuclideanDomain/Field.lean +++ b/Mathlib/Algebra/EuclideanDomain/Field.lean @@ -20,7 +20,7 @@ instance (priority := 100) Field.toEuclideanDomain {K : Type*} [Field K] : Eucli by_cases h : b = 0 <;> simp [h, mul_div_cancel₀] r := fun a b => a = 0 ∧ b ≠ 0, r_wellFounded := - WellFounded.intro fun a => - (Acc.intro _) fun b ⟨hb, _⟩ => (Acc.intro _) fun c ⟨_, hnb⟩ => False.elim <| hnb hb, + WellFounded.intro fun _ => + (Acc.intro _) fun _ ⟨hb, _⟩ => (Acc.intro _) fun _ ⟨_, hnb⟩ => False.elim <| hnb hb, remainder_lt := fun a b hnb => by simp [hnb], - mul_left_not_lt := fun a b hnb ⟨hab, hna⟩ => Or.casesOn (mul_eq_zero.1 hab) hna hnb } + mul_left_not_lt := fun _ _ hnb ⟨hab, hna⟩ => Or.casesOn (mul_eq_zero.1 hab) hna hnb } diff --git a/Mathlib/Algebra/Field/Basic.lean b/Mathlib/Algebra/Field/Basic.lean index 420cf3c602577c..989ee8b232df3c 100644 --- a/Mathlib/Algebra/Field/Basic.lean +++ b/Mathlib/Algebra/Field/Basic.lean @@ -228,9 +228,9 @@ noncomputable abbrev DivisionRing.ofIsUnitOrEqZero [Ring R] (h : ∀ a : R, IsUn toRing := ‹Ring R› __ := groupWithZeroOfIsUnitOrEqZero h nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl qsmul := _ - qsmul_def := fun q a => rfl + qsmul_def := fun _ _ => rfl /-- Constructs a `Field` structure on a `CommRing` consisting only of units and 0. -/ -- See note [reducible non-instances] diff --git a/Mathlib/Algebra/Field/IsField.lean b/Mathlib/Algebra/Field/IsField.lean index a3d3847cbc41fc..e9b67d20db2484 100644 --- a/Mathlib/Algebra/Field/IsField.lean +++ b/Mathlib/Algebra/Field/IsField.lean @@ -62,13 +62,13 @@ noncomputable def IsField.toSemifield {R : Type u} [Semiring R] (h : IsField R) inv_zero := dif_pos rfl mul_inv_cancel a ha := by convert Classical.choose_spec (h.mul_inv_cancel ha); exact dif_neg ha nnqsmul := _ - nnqsmul_def q a := rfl + nnqsmul_def _ _ := rfl /-- Transferring from `IsField` to `Field`. -/ noncomputable def IsField.toField {R : Type u} [Ring R] (h : IsField R) : Field R := { ‹Ring R›, IsField.toSemifield h with qsmul := _ - qsmul_def := fun q a => rfl } + qsmul_def := fun _ _ => rfl } /-- For each field, and for each nonzero element of said field, there is a unique inverse. Since `IsField` doesn't remember the data of an `inv` function and as such, diff --git a/Mathlib/Algebra/Field/MinimalAxioms.lean b/Mathlib/Algebra/Field/MinimalAxioms.lean index b80f40d16d8014..17bc0cba5c2989 100644 --- a/Mathlib/Algebra/Field/MinimalAxioms.lean +++ b/Mathlib/Algebra/Field/MinimalAxioms.lean @@ -42,6 +42,6 @@ abbrev Field.ofMinimalAxioms (K : Type u) mul_inv_cancel := mul_inv_cancel inv_zero := inv_zero nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl qsmul := _ - qsmul_def := fun q a => rfl } + qsmul_def := fun _ _ => rfl } diff --git a/Mathlib/Algebra/Field/Opposite.lean b/Mathlib/Algebra/Field/Opposite.lean index 99f0c22d733881..b5e42f500972cb 100644 --- a/Mathlib/Algebra/Field/Opposite.lean +++ b/Mathlib/Algebra/Field/Opposite.lean @@ -34,7 +34,7 @@ instance instDivisionSemiring [DivisionSemiring α] : DivisionSemiring αᵐᵒ __ := instSemiring __ := instGroupWithZero nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl nnratCast_def q := unop_injective <| by rw [unop_nnratCast, unop_div, unop_natCast, unop_natCast, NNRat.cast_def, div_eq_mul_inv, Nat.cast_comm] @@ -42,7 +42,7 @@ instance instDivisionRing [DivisionRing α] : DivisionRing αᵐᵒᵖ where __ := instRing __ := instDivisionSemiring qsmul := _ - qsmul_def := fun q a => rfl + qsmul_def := fun _ _ => rfl ratCast_def q := unop_injective <| by rw [unop_ratCast, Rat.cast_def, unop_div, unop_natCast, unop_intCast, Int.commute_cast, div_eq_mul_inv] @@ -62,7 +62,7 @@ instance instDivisionSemiring [DivisionSemiring α] : DivisionSemiring αᵃᵒ __ := instSemiring __ := instGroupWithZero nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl nnratCast_def q := unop_injective <| by rw [unop_nnratCast, unop_div, unop_natCast, unop_natCast, NNRat.cast_def, div_eq_mul_inv] @@ -70,7 +70,7 @@ instance instDivisionRing [DivisionRing α] : DivisionRing αᵃᵒᵖ where __ := instRing __ := instDivisionSemiring qsmul := _ - qsmul_def := fun q a => rfl + qsmul_def := fun _ _ => rfl ratCast_def q := unop_injective <| by rw [unop_ratCast, Rat.cast_def, unop_div, unop_natCast, unop_intCast, div_eq_mul_inv] diff --git a/Mathlib/Algebra/Field/Rat.lean b/Mathlib/Algebra/Field/Rat.lean index fa3f4d1154ec5d..ee2d2e48680d13 100644 --- a/Mathlib/Algebra/Field/Rat.lean +++ b/Mathlib/Algebra/Field/Rat.lean @@ -29,12 +29,12 @@ instance instField : Field ℚ where __ := commRing __ := commGroupWithZero nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl qsmul := _ - qsmul_def := fun q a => rfl + qsmul_def := fun _ _ => rfl nnratCast_def q := by rw [← NNRat.den_coe, ← Int.cast_natCast q.num, ← NNRat.num_coe]; exact(num_div_den _).symm - ratCast_def q := (num_div_den _).symm + ratCast_def _ := (num_div_den _).symm /-! ### Extra instances to short-circuit type class resolution diff --git a/Mathlib/Algebra/Free.lean b/Mathlib/Algebra/Free.lean index 134a4e81ed9ff9..d7c8967bbf9a0f 100644 --- a/Mathlib/Algebra/Free.lean +++ b/Mathlib/Algebra/Free.lean @@ -105,9 +105,9 @@ variable {α : Type u} {β : Type v} [Mul β] (f : α → β) def lift : (α → β) ≃ (FreeMagma α →ₙ* β) where toFun f := { toFun := liftAux f - map_mul' := fun x y ↦ rfl } + map_mul' := fun _ _ ↦ rfl } invFun F := F ∘ of - left_inv f := rfl + left_inv _ := rfl right_inv F := by ext; rfl @[to_additive (attr := simp)] @@ -173,8 +173,8 @@ theorem mul_seq {α β : Type u} {f g : FreeMagma (α → β)} {x : FreeMagma α @[to_additive] instance instLawfulMonad : LawfulMonad FreeMagma.{u} := LawfulMonad.mk' - (pure_bind := fun f x ↦ rfl) - (bind_assoc := fun x f g ↦ FreeMagma.recOnPure x (fun x ↦ rfl) fun x y ih1 ih2 ↦ by + (pure_bind := fun _ _ ↦ rfl) + (bind_assoc := fun x f g ↦ FreeMagma.recOnPure x (fun _ ↦ rfl) fun x y ih1 ih2 ↦ by rw [mul_bind, mul_bind, mul_bind, ih1, ih2]) (id_map := fun x ↦ FreeMagma.recOnPure x (fun _ ↦ rfl) fun x y ih1 ih2 ↦ by rw [map_mul', ih1, ih2]) @@ -239,7 +239,7 @@ theorem mul_map_seq (x y : FreeMagma α) : instance : LawfulTraversable FreeMagma.{u} := { instLawfulMonad with id_traverse := fun x ↦ - FreeMagma.recOnPure x (fun x ↦ rfl) fun x y ih1 ih2 ↦ by + FreeMagma.recOnPure x (fun _ ↦ rfl) fun x y ih1 ih2 ↦ by rw [traverse_mul, ih1, ih2, mul_map_seq] comp_traverse := fun f g x ↦ FreeMagma.recOnPure x @@ -373,8 +373,8 @@ def lift : (α →ₙ* β) ≃ (AssocQuotient α →ₙ* β) where Quot.liftOn x f <| by rintro a b (⟨c, d, e⟩ | ⟨c, d, e, f⟩) <;> simp only [map_mul, mul_assoc] map_mul' := fun x y ↦ Quot.induction_on₂ x y (map_mul f) } invFun f := f.comp of - left_inv f := (DFunLike.ext _ _) fun x ↦ rfl - right_inv f := hom_ext <| (DFunLike.ext _ _) fun x ↦ rfl + left_inv _ := (DFunLike.ext _ _) fun _ ↦ rfl + right_inv _ := hom_ext <| (DFunLike.ext _ _) fun _ ↦ rfl @[to_additive (attr := simp)] theorem lift_of (x : α) : lift f (of x) = f x := rfl @@ -483,8 +483,8 @@ def lift : (α → β) ≃ (FreeSemigroup α →ₙ* β) where simp [head_mul, tail_mul, ← List.foldl_map, List.foldl_append, List.foldl_cons, List.foldl_assoc] } invFun f := f ∘ of - left_inv f := rfl - right_inv f := hom_ext rfl + left_inv _ := rfl + right_inv _ := hom_ext rfl @[to_additive (attr := simp)] theorem lift_of (x : α) : lift f (of x) = f x := rfl @@ -514,7 +514,7 @@ theorem map_of (x) : map f (of x) = of (f x) := rfl @[to_additive (attr := simp)] theorem length_map (x) : (map f x).length = x.length := - FreeSemigroup.recOnMul x (fun x ↦ rfl) (fun x y hx hy ↦ by simp only [map_mul, length_mul, *]) + FreeSemigroup.recOnMul x (fun _ ↦ rfl) (fun x y hx hy ↦ by simp only [map_mul, length_mul, *]) end Map @@ -558,7 +558,7 @@ theorem mul_seq {f g : FreeSemigroup (α → β)} {x : FreeSemigroup α} : instance instLawfulMonad : LawfulMonad FreeSemigroup.{u} := LawfulMonad.mk' (pure_bind := fun _ _ ↦ rfl) (bind_assoc := fun x g f ↦ - recOnPure x (fun x ↦ rfl) fun x y ih1 ih2 ↦ by rw [mul_bind, mul_bind, mul_bind, ih1, ih2]) + recOnPure x (fun _ ↦ rfl) fun x y ih1 ih2 ↦ by rw [mul_bind, mul_bind, mul_bind, ih1, ih2]) (id_map := fun x ↦ recOnPure x (fun _ ↦ rfl) fun x y ih1 ih2 ↦ by rw [map_mul', ih1, ih2]) /-- `FreeSemigroup` is traversable. -/ @@ -587,7 +587,7 @@ theorem traverse_mul (x y : FreeSemigroup α) : traverse F (x * y) = (· * ·) <$> traverse F x <*> traverse F y := let ⟨x, L1⟩ := x let ⟨y, L2⟩ := y - List.recOn L1 (fun x ↦ rfl) + List.recOn L1 (fun _ ↦ rfl) (fun hd tl ih x ↦ show (· * ·) <$> pure <$> F x <*> traverse F (mk hd tl * mk y L2) = (· * ·) <$> ((· * ·) <$> pure <$> F x <*> traverse F (mk hd tl)) <*> traverse F (mk y L2) @@ -614,7 +614,7 @@ theorem mul_map_seq (x y : FreeSemigroup α) : instance : LawfulTraversable FreeSemigroup.{u} := { instLawfulMonad with id_traverse := fun x ↦ - FreeSemigroup.recOnMul x (fun x ↦ rfl) fun x y ih1 ih2 ↦ by + FreeSemigroup.recOnMul x (fun _ ↦ rfl) fun x y ih1 ih2 ↦ by rw [traverse_mul, ih1, ih2, mul_map_seq] comp_traverse := fun f g x ↦ recOnPure x (fun x ↦ by simp only [traverse_pure, functor_norm, Function.comp_def]) @@ -661,7 +661,7 @@ theorem toFreeSemigroup_map (f : α → β) (x : FreeMagma α) : @[to_additive (attr := simp)] theorem length_toFreeSemigroup (x : FreeMagma α) : (toFreeSemigroup x).length = x.length := - FreeMagma.recOnMul x (fun x ↦ rfl) fun x y hx hy ↦ by + FreeMagma.recOnMul x (fun _ ↦ rfl) fun x y hx hy ↦ by rw [map_mul, FreeSemigroup.length_mul, hx, hy]; rfl end FreeMagma diff --git a/Mathlib/Algebra/FreeMonoid/Basic.lean b/Mathlib/Algebra/FreeMonoid/Basic.lean index 6137d36c3f5ed0..f3a0b039e5ff23 100644 --- a/Mathlib/Algebra/FreeMonoid/Basic.lean +++ b/Mathlib/Algebra/FreeMonoid/Basic.lean @@ -166,8 +166,8 @@ def lift : (α → M) ≃ (FreeMonoid α →* M) where map_one' := rfl map_mul' := fun _ _ ↦ by simp only [prodAux_eq, toList_mul, List.map_append, List.prod_append] } invFun f x := f (of x) - left_inv f := rfl - right_inv f := hom_eq fun x ↦ rfl + left_inv _ := rfl + right_inv _ := hom_eq fun _ ↦ rfl @[to_additive (attr := simp)] theorem lift_ofList (f : α → M) (l : List α) : lift f (ofList l) = (l.map f).prod := diff --git a/Mathlib/Algebra/GCDMonoid/Basic.lean b/Mathlib/Algebra/GCDMonoid/Basic.lean index fee781f192238f..e0744b9bcc73a4 100644 --- a/Mathlib/Algebra/GCDMonoid/Basic.lean +++ b/Mathlib/Algebra/GCDMonoid/Basic.lean @@ -769,7 +769,7 @@ theorem lcm_mul_left [NormalizedGCDMonoid α] (a b c : α) : fun ha : a ≠ 0 => suffices lcm (a * b) (a * c) = normalize (a * lcm b c) by simpa [- normalize_apply] have : a ∣ lcm (a * b) (a * c) := (dvd_mul_right _ _).trans (dvd_lcm_left _ _) - let ⟨d, eq⟩ := this + let ⟨_, eq⟩ := this lcm_eq_normalize (lcm_dvd (mul_dvd_mul_left a (dvd_lcm_left _ _)) (mul_dvd_mul_left a (dvd_lcm_right _ _))) (eq.symm ▸ @@ -953,7 +953,7 @@ noncomputable def gcdMonoidOfGCD [DecidableEq α] (gcd : α → α → α) { gcd gcd_dvd_left gcd_dvd_right - dvd_gcd := fun {a b c} => dvd_gcd + dvd_gcd := fun {_ _ _} => dvd_gcd lcm := fun a b => if a = 0 then 0 else Classical.choose ((gcd_dvd_left a b).trans (Dvd.intro b rfl)) gcd_mul_lcm := fun a b => by @@ -962,7 +962,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 a => if_pos rfl + lcm_zero_left := fun _ => if_pos rfl lcm_zero_right := fun a => by -- Porting note(#12129): additional beta reduction needed beta_reduce @@ -985,7 +985,7 @@ noncomputable def normalizedGCDMonoidOfGCD [NormalizationMonoid α] [DecidableEq gcd gcd_dvd_left gcd_dvd_right - dvd_gcd := fun {a b c} => dvd_gcd + dvd_gcd := fun {_ _ _} => dvd_gcd normalize_gcd lcm := fun a b => if a = 0 then 0 @@ -1023,7 +1023,7 @@ noncomputable def normalizedGCDMonoidOfGCD [NormalizationMonoid α] [DecidableEq · rw [← Classical.choose_spec (dvd_normalize_iff.2 ((gcd_dvd_left a b).trans (Dvd.intro b rfl)))] exact normalize_associated (a * b) - lcm_zero_left := fun a => if_pos rfl + lcm_zero_left := fun _ => if_pos rfl lcm_zero_right := fun a => by -- Porting note(#12129): additional beta reduction needed beta_reduce @@ -1054,8 +1054,8 @@ noncomputable def gcdMonoidOfLCM [DecidableEq α] (lcm : α → α → α) · 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 _ _)] rw [mul_comm, ← Classical.choose_spec (exists_gcd a b)] - lcm_zero_left := fun a => eq_zero_of_zero_dvd (dvd_lcm_left _ _) - lcm_zero_right := fun a => eq_zero_of_zero_dvd (dvd_lcm_right _ _) + 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 -- Porting note(#12129): additional beta reduction needed beta_reduce @@ -1150,8 +1150,8 @@ noncomputable def normalizedGCDMonoidOfLCM [NormalizationMonoid α] [DecidableEq congr rw [← normalize_lcm a b] erw [← normalize.map_mul, ← Classical.choose_spec (exists_gcd a b), normalize_idem] - lcm_zero_left := fun a => eq_zero_of_zero_dvd (dvd_lcm_left _ _) - lcm_zero_right := fun a => eq_zero_of_zero_dvd (dvd_lcm_right _ _) + 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 beta_reduce split_ifs with h h_1 @@ -1308,8 +1308,8 @@ instance (priority := 100) : NormalizedGCDMonoid G₀ where · beta_reduce rw [if_neg (not_and_of_not_left _ ha), one_mul, if_neg (not_or_intro ha hb)] exact (associated_one_iff_isUnit.mpr ((IsUnit.mk0 _ ha).mul (IsUnit.mk0 _ hb))).symm - lcm_zero_left b := if_pos (Or.inl rfl) - lcm_zero_right a := if_pos (Or.inr rfl) + lcm_zero_left _ := if_pos (Or.inl rfl) + lcm_zero_right _ := if_pos (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] @@ -1326,8 +1326,8 @@ namespace Associates variable [CancelCommMonoidWithZero α] [GCDMonoid α] instance instGCDMonoid : GCDMonoid (Associates α) where - gcd := Quotient.map₂' gcd fun a₁ a₂ (ha : Associated _ _) b₁ b₂ (hb : Associated _ _) => ha.gcd hb - lcm := Quotient.map₂' lcm fun a₁ a₂ (ha : Associated _ _) b₁ b₂ (hb : Associated _ _) => ha.lcm hb + gcd := Quotient.map₂' gcd fun _ _ (ha : Associated _ _) _ _ (hb : Associated _ _) => ha.gcd hb + lcm := Quotient.map₂' lcm fun _ _ (ha : Associated _ _) _ _ (hb : Associated _ _) => ha.lcm hb gcd_dvd_left := by rintro ⟨a⟩ ⟨b⟩; exact mk_le_mk_of_dvd (gcd_dvd_left _ _) gcd_dvd_right := by rintro ⟨a⟩ ⟨b⟩; exact mk_le_mk_of_dvd (gcd_dvd_right _ _) dvd_gcd := by diff --git a/Mathlib/Algebra/GCDMonoid/Nat.lean b/Mathlib/Algebra/GCDMonoid/Nat.lean index 11c7bd9c63679f..2824c117566c02 100644 --- a/Mathlib/Algebra/GCDMonoid/Nat.lean +++ b/Mathlib/Algebra/GCDMonoid/Nat.lean @@ -101,14 +101,14 @@ section GCDMonoid instance : GCDMonoid ℤ where gcd a b := Int.gcd a b lcm a b := Int.lcm a b - gcd_dvd_left a b := Int.gcd_dvd_left - gcd_dvd_right a b := Int.gcd_dvd_right + gcd_dvd_left _ _ := Int.gcd_dvd_left + gcd_dvd_right _ _ := Int.gcd_dvd_right dvd_gcd := dvd_gcd gcd_mul_lcm a b := by rw [← Int.ofNat_mul, gcd_mul_lcm, natCast_natAbs, abs_eq_normalize] exact normalize_associated (a * b) - lcm_zero_left a := natCast_eq_zero.2 <| Nat.lcm_zero_left _ - lcm_zero_right a := natCast_eq_zero.2 <| Nat.lcm_zero_right _ + 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, diff --git a/Mathlib/Algebra/GeomSum.lean b/Mathlib/Algebra/GeomSum.lean index 70a08526df06eb..1e81b5455510c3 100644 --- a/Mathlib/Algebra/GeomSum.lean +++ b/Mathlib/Algebra/GeomSum.lean @@ -132,7 +132,7 @@ theorem geom_sum₂_self {α : Type*} [CommRing α] (x : α) (n : ℕ) : ∑ i ∈ Finset.range n, x ^ (i + (n - 1 - i)) := by simp_rw [← pow_add] _ = ∑ _i ∈ Finset.range n, x ^ (n - 1) := - Finset.sum_congr rfl fun i hi => + Finset.sum_congr rfl fun _ hi => congr_arg _ <| add_tsub_cancel_of_le <| Nat.le_sub_one_of_lt <| Finset.mem_range.1 hi _ = (Finset.range n).card • x ^ (n - 1) := Finset.sum_const _ _ = n * x ^ (n - 1) := by rw [Finset.card_range, nsmul_eq_mul] @@ -422,7 +422,7 @@ variable {n : ℕ} {x : α} theorem geom_sum_pos [StrictOrderedSemiring α] (hx : 0 ≤ x) (hn : n ≠ 0) : 0 < ∑ i ∈ range n, x ^ i := - sum_pos' (fun k _ => pow_nonneg hx _) ⟨0, mem_range.2 hn.bot_lt, by simp⟩ + sum_pos' (fun _ _ => pow_nonneg hx _) ⟨0, mem_range.2 hn.bot_lt, by simp⟩ theorem geom_sum_pos_and_lt_one [StrictOrderedRing α] (hx : x < 0) (hx' : 0 < x + 1) (hn : 1 < n) : (0 < ∑ i ∈ range n, x ^ i) ∧ ∑ i ∈ range n, x ^ i < 1 := by @@ -547,7 +547,7 @@ lemma Nat.geomSum_eq (hm : 2 ≤ m) (n : ℕ) : `m ≥ 2` is less than `m ^ n`. -/ lemma Nat.geomSum_lt (hm : 2 ≤ m) (hs : ∀ k ∈ s, k < n) : ∑ k ∈ s, m ^ k < m ^ n := calc - ∑ k ∈ s, m ^ k ≤ ∑ k ∈ range n, m ^ k := sum_le_sum_of_subset fun k hk ↦ + ∑ k ∈ s, m ^ k ≤ ∑ k ∈ range n, m ^ k := sum_le_sum_of_subset fun _ hk ↦ mem_range.2 <| hs _ hk _ = (m ^ n - 1) / (m - 1) := Nat.geomSum_eq hm _ _ ≤ m ^ n - 1 := Nat.div_le_self _ _ diff --git a/Mathlib/Algebra/Group/Action/Defs.lean b/Mathlib/Algebra/Group/Action/Defs.lean index 733f6bd366afc5..ea9c58c15f971d 100644 --- a/Mathlib/Algebra/Group/Action/Defs.lean +++ b/Mathlib/Algebra/Group/Action/Defs.lean @@ -645,11 +645,11 @@ protected def Function.End := α → α instance : Monoid (Function.End α) where one := id mul := (· ∘ ·) - mul_assoc f g h := rfl - mul_one f := rfl - one_mul f := rfl + mul_assoc _ _ _ := rfl + mul_one _ := rfl + one_mul _ := rfl npow n f := f^[n] - npow_succ n f := Function.iterate_succ _ _ + npow_succ _ _ := Function.iterate_succ _ _ instance : Inhabited (Function.End α) := ⟨1⟩ diff --git a/Mathlib/Algebra/Group/Action/Units.lean b/Mathlib/Algebra/Group/Action/Units.lean index b1b817a1fb9205..3894d2568e51a5 100644 --- a/Mathlib/Algebra/Group/Action/Units.lean +++ b/Mathlib/Algebra/Group/Action/Units.lean @@ -71,8 +71,8 @@ instance mulAction' [Group G] [Monoid M] [MulAction G M] [SMulCommClass G M M] ⟨g • (m : M), (g⁻¹ • ((m⁻¹ : Mˣ) : M)), by rw [smul_mul_smul_comm, Units.mul_inv, mul_inv_cancel, one_smul], by rw [smul_mul_smul_comm, Units.inv_mul, inv_mul_cancel, one_smul]⟩ - one_smul m := Units.ext <| one_smul _ _ - mul_smul g₁ g₂ m := Units.ext <| mul_smul _ _ _ + one_smul _ := Units.ext <| one_smul _ _ + mul_smul _ _ _ := Units.ext <| mul_smul _ _ _ @[to_additive (attr := simp)] lemma val_smul [Group G] [Monoid M] [MulAction G M] [SMulCommClass G M M] [IsScalarTower G M M] diff --git a/Mathlib/Algebra/Group/Basic.lean b/Mathlib/Algebra/Group/Basic.lean index 244c63da588ada..e00263356fbaf4 100644 --- a/Mathlib/Algebra/Group/Basic.lean +++ b/Mathlib/Algebra/Group/Basic.lean @@ -426,7 +426,7 @@ lemma one_zpow : ∀ n : ℤ, (1 : α) ^ n = 1 @[to_additive (attr := simp) neg_zsmul] lemma zpow_neg (a : α) : ∀ n : ℤ, a ^ (-n) = (a ^ n)⁻¹ - | (n + 1 : ℕ) => DivInvMonoid.zpow_neg' _ _ + | (_ + 1 : ℕ) => DivInvMonoid.zpow_neg' _ _ | 0 => by change a ^ (0 : ℤ) = (a ^ (0 : ℤ))⁻¹ simp diff --git a/Mathlib/Algebra/Group/Conj.lean b/Mathlib/Algebra/Group/Conj.lean index 3dbb4606b75410..1c2dafc677b31b 100644 --- a/Mathlib/Algebra/Group/Conj.lean +++ b/Mathlib/Algebra/Group/Conj.lean @@ -62,7 +62,7 @@ variable [CancelMonoid α] -- not generalised. @[simp] theorem isConj_one_right {a : α} : IsConj 1 a ↔ a = 1 := - ⟨fun ⟨c, hc⟩ => mul_right_cancel (hc.symm.trans ((mul_one _).trans (one_mul _).symm)), fun h => by + ⟨fun ⟨_, hc⟩ => mul_right_cancel (hc.symm.trans ((mul_one _).trans (one_mul _).symm)), fun h => by rw [h]⟩ @[simp] @@ -222,7 +222,7 @@ theorem mk_bijective : Function.Bijective (@ConjClasses.mk α _) := /-- The bijection between a `CommGroup` and its `ConjClasses`. -/ def mkEquiv : α ≃ ConjClasses α := - ⟨ConjClasses.mk, Quotient.lift id fun (a : α) b => isConj_iff_eq.1, Quotient.lift_mk _ _, by + ⟨ConjClasses.mk, Quotient.lift id fun (_ : α) _ => isConj_iff_eq.1, Quotient.lift_mk _ _, by rw [Function.RightInverse, Function.LeftInverse, forall_isConj] intro x rw [← quotient_mk_eq_mk, ← quotient_mk_eq_mk, Quotient.lift_mk, id]⟩ diff --git a/Mathlib/Algebra/Group/Hom/Basic.lean b/Mathlib/Algebra/Group/Hom/Basic.lean index 9eb317e8d7b71d..114dff59a75baa 100644 --- a/Mathlib/Algebra/Group/Hom/Basic.lean +++ b/Mathlib/Algebra/Group/Hom/Basic.lean @@ -109,7 +109,7 @@ For the iff statement on the triviality of the kernel, see `injective_iff_map_eq theorem _root_.injective_iff_map_eq_one {G H} [Group G] [MulOneClass H] [FunLike F G H] [MonoidHomClass F G H] (f : F) : Function.Injective f ↔ ∀ a, f a = 1 → a = 1 := - ⟨fun h x => (map_eq_one_iff f h).mp, fun h x y hxy => + ⟨fun h _ => (map_eq_one_iff f h).mp, fun h x y hxy => mul_inv_eq_one.1 <| h _ <| by rw [map_mul, hxy, ← map_mul, mul_inv_cancel, map_one]⟩ /-- A homomorphism from a group to a monoid is injective iff its kernel is trivial, diff --git a/Mathlib/Algebra/Group/Hom/Defs.lean b/Mathlib/Algebra/Group/Hom/Defs.lean index 1a3bf932f98fdb..14f51627f6d9d2 100644 --- a/Mathlib/Algebra/Group/Hom/Defs.lean +++ b/Mathlib/Algebra/Group/Hom/Defs.lean @@ -867,7 +867,7 @@ instance : Monoid (Monoid.End M) where mul_one := MonoidHom.comp_id one_mul := MonoidHom.id_comp npow n f := (npowRec n f).copy f^[n] <| by induction n <;> simp [npowRec, *] <;> rfl - npow_succ n f := DFunLike.coe_injective <| Function.iterate_succ _ _ + npow_succ _ _ := DFunLike.coe_injective <| Function.iterate_succ _ _ instance : Inhabited (Monoid.End M) := ⟨1⟩ @@ -908,7 +908,7 @@ instance monoid : Monoid (AddMonoid.End A) where mul_one := AddMonoidHom.comp_id one_mul := AddMonoidHom.id_comp npow n f := (npowRec n f).copy (Nat.iterate f n) <| by induction n <;> simp [npowRec, *] <;> rfl - npow_succ n f := DFunLike.coe_injective <| Function.iterate_succ _ _ + npow_succ _ _ := DFunLike.coe_injective <| Function.iterate_succ _ _ @[simp, norm_cast] lemma coe_pow (f : AddMonoid.End A) (n : ℕ) : (↑(f ^ n) : A → A) = f^[n] := rfl diff --git a/Mathlib/Algebra/Group/Indicator.lean b/Mathlib/Algebra/Group/Indicator.lean index ccb3633809bcab..fc2d14cdfb1400 100644 --- a/Mathlib/Algebra/Group/Indicator.lean +++ b/Mathlib/Algebra/Group/Indicator.lean @@ -94,7 +94,7 @@ theorem mulIndicator_apply_eq_one : mulIndicator s f a = 1 ↔ a ∈ s → f a = ite_eq_right_iff @[to_additive (attr := simp)] -theorem mulIndicator_eq_one : (mulIndicator s f = fun x => 1) ↔ Disjoint (mulSupport f) s := by +theorem mulIndicator_eq_one : (mulIndicator s f = fun _ => 1) ↔ Disjoint (mulSupport f) s := by simp only [funext_iff, mulIndicator_apply_eq_one, Set.disjoint_left, mem_mulSupport, not_imp_not] diff --git a/Mathlib/Algebra/Group/Opposite.lean b/Mathlib/Algebra/Group/Opposite.lean index a66f4838ff8fde..63a5dce25bc2f2 100644 --- a/Mathlib/Algebra/Group/Opposite.lean +++ b/Mathlib/Algebra/Group/Opposite.lean @@ -423,7 +423,7 @@ def MonoidHom.fromOpposite {M N : Type*} [MulOneClass M] [MulOneClass N] (f : M def Units.opEquiv {M} [Monoid M] : Mᵐᵒᵖˣ ≃* Mˣᵐᵒᵖ where toFun u := op ⟨unop u, unop ↑u⁻¹, op_injective u.4, op_injective u.3⟩ invFun := MulOpposite.rec' fun u => ⟨op ↑u, op ↑u⁻¹, unop_injective <| u.4, unop_injective u.3⟩ - map_mul' x y := unop_injective <| Units.ext <| rfl + map_mul' _ _ := unop_injective <| Units.ext <| rfl left_inv x := Units.ext <| by simp right_inv x := unop_injective <| Units.ext <| by rfl diff --git a/Mathlib/Algebra/Group/Pi/Lemmas.lean b/Mathlib/Algebra/Group/Pi/Lemmas.lean index 672442bbd487d2..a344930fb34fa6 100644 --- a/Mathlib/Algebra/Group/Pi/Lemmas.lean +++ b/Mathlib/Algebra/Group/Pi/Lemmas.lean @@ -68,7 +68,7 @@ def Pi.mulHom {γ : Type w} [∀ i, Mul (f i)] [Mul γ] (g : ∀ i, γ →ₙ* f @[to_additive] theorem Pi.mulHom_injective {γ : Type w} [Nonempty I] [∀ i, Mul (f i)] [Mul γ] (g : ∀ i, γ →ₙ* f i) - (hg : ∀ i, Function.Injective (g i)) : Function.Injective (Pi.mulHom g) := fun x y h => + (hg : ∀ i, Function.Injective (g i)) : Function.Injective (Pi.mulHom g) := fun _ _ h => let ⟨i⟩ := ‹Nonempty I› hg i ((Function.funext_iff.mp h : _) i) diff --git a/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean b/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean index 5e5ebeefca3c25..7338d907b43604 100644 --- a/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean +++ b/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean @@ -866,7 +866,7 @@ variable [DivisionMonoid α] {s t : Finset α} @[to_additive (attr := simp)] theorem coe_zpow (s : Finset α) : ∀ n : ℤ, ↑(s ^ n) = (s : Set α) ^ n - | Int.ofNat n => coe_pow _ _ + | Int.ofNat _ => coe_pow _ _ | Int.negSucc n => by refine (coe_inv _).trans ?_ exact congr_arg Inv.inv (coe_pow _ _) diff --git a/Mathlib/Algebra/Group/Prod.lean b/Mathlib/Algebra/Group/Prod.lean index d7cb9b0f80a16c..24f6bc4ccca86b 100644 --- a/Mathlib/Algebra/Group/Prod.lean +++ b/Mathlib/Algebra/Group/Prod.lean @@ -165,8 +165,8 @@ 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_zero := fun z => Prod.ext (Monoid.npow_zero _) (Monoid.npow_zero _), - npow_succ := fun z a => Prod.ext (Monoid.npow_succ _ _) (Monoid.npow_succ _ _), + 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, mul_one := by simp } @@ -180,8 +180,8 @@ instance [DivInvMonoid G] [DivInvMonoid H] : DivInvMonoid (G × H) := @[to_additive] instance [DivisionMonoid G] [DivisionMonoid H] : DivisionMonoid (G × H) := - { mul_inv_rev := fun a b => Prod.ext (mul_inv_rev _ _) (mul_inv_rev _ _), - inv_eq_of_mul := fun a b h => + { mul_inv_rev := fun _ _ => Prod.ext (mul_inv_rev _ _) (mul_inv_rev _ _), + inv_eq_of_mul := fun _ _ h => Prod.ext (inv_eq_of_mul_eq_one_right <| congr_arg fst h) (inv_eq_of_mul_eq_one_right <| congr_arg snd h), inv_inv := by simp } diff --git a/Mathlib/Algebra/Group/Subgroup/Basic.lean b/Mathlib/Algebra/Group/Subgroup/Basic.lean index 556df038ddca9b..4fd2fb66654a41 100644 --- a/Mathlib/Algebra/Group/Subgroup/Basic.lean +++ b/Mathlib/Algebra/Group/Subgroup/Basic.lean @@ -818,12 +818,12 @@ theorem mem_sSup_of_mem {S : Set (Subgroup G)} {s : Subgroup G} (hs : s ∈ S) : @[to_additive (attr := simp)] theorem subsingleton_iff : Subsingleton (Subgroup G) ↔ Subsingleton G := - ⟨fun h => + ⟨fun _ => ⟨fun x y => have : ∀ i : G, i = 1 := fun i => mem_bot.mp <| Subsingleton.elim (⊤ : Subgroup G) ⊥ ▸ mem_top i (this x).trans (this y).symm⟩, - fun h => ⟨fun x y => Subgroup.ext fun i => Subsingleton.elim 1 i ▸ by simp [Subgroup.one_mem]⟩⟩ + fun _ => ⟨fun x y => Subgroup.ext fun i => Subsingleton.elim 1 i ▸ by simp [Subgroup.one_mem]⟩⟩ @[to_additive (attr := simp)] theorem nontrivial_iff : Nontrivial (Subgroup G) ↔ Nontrivial G := @@ -1909,7 +1909,7 @@ theorem normalClosure_mono {s t : Set G} (h : s ⊆ t) : normalClosure s ≤ nor theorem normalClosure_eq_iInf : normalClosure s = ⨅ (N : Subgroup G) (_ : Normal N) (_ : s ⊆ N), N := - le_antisymm (le_iInf fun N => le_iInf fun hN => le_iInf normalClosure_le_normal) + le_antisymm (le_iInf fun _ => le_iInf fun _ => le_iInf normalClosure_le_normal) (iInf_le_of_le (normalClosure s) (iInf_le_of_le (by infer_instance) (iInf_le_of_le subset_normalClosure le_rfl))) @@ -1934,8 +1934,8 @@ as shown by `Subgroup.normalCore_eq_iSup`. -/ def normalCore (H : Subgroup G) : Subgroup G where carrier := { a : G | ∀ b : G, b * a * b⁻¹ ∈ H } one_mem' a := by rw [mul_one, mul_inv_cancel]; exact H.one_mem - inv_mem' {a} h b := (congr_arg (· ∈ H) conj_inv).mp (H.inv_mem (h b)) - mul_mem' {a b} ha hb c := (congr_arg (· ∈ H) conj_mul).mp (H.mul_mem (ha c) (hb c)) + inv_mem' {_} h b := (congr_arg (· ∈ H) conj_inv).mp (H.inv_mem (h b)) + mul_mem' {_ _} ha hb c := (congr_arg (· ∈ H) conj_mul).mp (H.mul_mem (ha c) (hb c)) theorem normalCore_le (H : Subgroup G) : H.normalCore ≤ H := fun a h => by rw [← mul_one a, ← inv_one, ← one_mul a] @@ -2104,7 +2104,7 @@ theorem ofLeftInverse_symm_apply {f : G →* N} {g : N →* G} (h : Function.Lef domain."] noncomputable def ofInjective {f : G →* N} (hf : Function.Injective f) : G ≃* f.range := MulEquiv.ofBijective (f.codRestrict f.range fun x => ⟨x, rfl⟩) - ⟨fun x y h => hf (Subtype.ext_iff.mp h), by + ⟨fun _ _ h => hf (Subtype.ext_iff.mp h), by rintro ⟨x, y, rfl⟩ exact ⟨y, rfl⟩⟩ @@ -2193,7 +2193,7 @@ theorem ker_id : (MonoidHom.id G).ker = ⊥ := @[to_additive] theorem ker_eq_bot_iff (f : G →* M) : f.ker = ⊥ ↔ Function.Injective f := ⟨fun h x y hxy => by rwa [eq_iff, h, mem_bot, inv_mul_eq_one, eq_comm] at hxy, fun h => - bot_unique fun x hx => h (hx.trans f.map_one.symm)⟩ + bot_unique fun _ hx => h (hx.trans f.map_one.symm)⟩ @[to_additive (attr := simp)] theorem _root_.Subgroup.ker_subtype (H : Subgroup G) : H.subtype.ker = ⊥ := @@ -2879,7 +2879,7 @@ theorem disjoint_iff_mul_eq_one {H₁ H₂ : Subgroup G} : ⟨fun h x y hx hy hxy => let hx1 : x = 1 := h hx (H₂.inv_mem hy) (eq_inv_iff_mul_eq_one.mpr hxy) ⟨hx1, by simpa [hx1] using hxy⟩, - fun h x y hx hy hxy => (h hx (H₂.inv_mem hy) (mul_inv_eq_one.mpr hxy)).1⟩ + fun h _ _ hx hy hxy => (h hx (H₂.inv_mem hy) (mul_inv_eq_one.mpr hxy)).1⟩ @[to_additive] theorem mul_injective_of_disjoint {H₁ H₂ : Subgroup G} (h : Disjoint H₁ H₂) : diff --git a/Mathlib/Algebra/Group/Subgroup/Pointwise.lean b/Mathlib/Algebra/Group/Subgroup/Pointwise.lean index 99bb82ddad9cc3..48ad4a5c50a1d8 100644 --- a/Mathlib/Algebra/Group/Subgroup/Pointwise.lean +++ b/Mathlib/Algebra/Group/Subgroup/Pointwise.lean @@ -105,8 +105,8 @@ theorem closure_induction_right {p : (x : G) → x ∈ closure s → Prop} (one closure_induction_left (s := MulOpposite.unop ⁻¹' s) (p := fun m hm => p m.unop <| by rwa [← op_closure] at hm) one - (fun _x hx _y hy => mul_right _ _ _ hx) - (fun _x hx _y hy => mul_inv_cancel _ _ _ hx) + (fun _x hx _y _ => mul_right _ _ _ hx) + (fun _x hx _y _ => mul_inv_cancel _ _ _ hx) (by rwa [← op_closure]) @[to_additive (attr := simp)] @@ -282,7 +282,7 @@ protected def pointwiseMulAction : MulAction α (Subgroup G) where one_smul S := by change S.map _ = S simpa only [map_one] using S.map_id - mul_smul a₁ a₂ S := + mul_smul _ _ S := (congr_arg (fun f : Monoid.End G => S.map f) (MonoidHom.map_mul _ _ _)).trans (S.map_map _ _).symm diff --git a/Mathlib/Algebra/Group/Submonoid/Basic.lean b/Mathlib/Algebra/Group/Submonoid/Basic.lean index 623c641fbcfa67..9cc78b55ddff2d 100644 --- a/Mathlib/Algebra/Group/Submonoid/Basic.lean +++ b/Mathlib/Algebra/Group/Submonoid/Basic.lean @@ -302,12 +302,12 @@ instance : CompleteLattice (Submonoid M) := @[to_additive (attr := simp)] theorem subsingleton_iff : Subsingleton (Submonoid M) ↔ Subsingleton M := - ⟨fun h => + ⟨fun _ => ⟨fun x y => have : ∀ i : M, i = 1 := fun i => mem_bot.mp <| Subsingleton.elim (⊤ : Submonoid M) ⊥ ▸ mem_top i (this x).trans (this y).symm⟩, - fun h => + fun _ => ⟨fun x y => Submonoid.ext fun i => Subsingleton.elim 1 i ▸ by simp [Submonoid.one_mem]⟩⟩ @[to_additive (attr := simp)] @@ -594,7 +594,7 @@ def ofClosureMEqTopRight {M N} [Monoid M] [Monoid N] {s : Set M} (f : M → N) ( map_one' := h1 map_mul' x y := dense_induction y hs (fun y hy x => hmul x y hy) (by simp [h1]) - (fun y₁ y₂ (h₁ : ∀ x, f _ = f _ * f _) (h₂ : ∀ x, f _ = f _ * f _) x => by + (fun y₁ y₂ (h₁ : ∀ _, f _ = f _ * f _) (h₂ : ∀ _, f _ = f _ * f _) x => by simp [← mul_assoc, h₁, h₂]) x @[to_additive (attr := simp, norm_cast)] diff --git a/Mathlib/Algebra/Group/Submonoid/Membership.lean b/Mathlib/Algebra/Group/Submonoid/Membership.lean index 3f5261db6d4226..b36aad9d57cb63 100644 --- a/Mathlib/Algebra/Group/Submonoid/Membership.lean +++ b/Mathlib/Algebra/Group/Submonoid/Membership.lean @@ -379,7 +379,7 @@ theorem closure_induction_right {s : Set M} {p : (m : M) → m ∈ closure s → closure_induction_left (s := MulOpposite.unop ⁻¹' s) (p := fun m hm => p m.unop <| by rwa [← op_closure] at hm) one - (fun _x hx _y hy => mul_right _ _ _ hx) + (fun _x hx _y _ => mul_right _ _ _ hx) (by rwa [← op_closure]) @[to_additive (attr := elab_as_elim)] diff --git a/Mathlib/Algebra/Group/Submonoid/Operations.lean b/Mathlib/Algebra/Group/Submonoid/Operations.lean index f84160423a5b5c..a08c3cc0ece0c7 100644 --- a/Mathlib/Algebra/Group/Submonoid/Operations.lean +++ b/Mathlib/Algebra/Group/Submonoid/Operations.lean @@ -1182,7 +1182,7 @@ elements of `M`. -/ noncomputable def unitsTypeEquivIsUnitSubmonoid [Monoid M] : Mˣ ≃* IsUnit.submonoid M where toFun x := ⟨x, Units.isUnit x⟩ invFun x := x.prop.unit - left_inv x := IsUnit.unit_of_val_units _ + left_inv _ := IsUnit.unit_of_val_units _ right_inv x := by simp_rw [IsUnit.unit_spec] map_mul' x y := by simp_rw [Units.val_mul]; rfl diff --git a/Mathlib/Algebra/Group/Submonoid/Pointwise.lean b/Mathlib/Algebra/Group/Submonoid/Pointwise.lean index c2123399f60374..9434237fea0f10 100644 --- a/Mathlib/Algebra/Group/Submonoid/Pointwise.lean +++ b/Mathlib/Algebra/Group/Submonoid/Pointwise.lean @@ -184,7 +184,7 @@ protected def pointwiseMulAction : MulAction α (Submonoid M) where one_smul S := by change S.map _ = S simpa only [map_one] using S.map_id - mul_smul a₁ a₂ S := + mul_smul _ _ S := (congr_arg (fun f : Monoid.End M => S.map f) (MonoidHom.map_mul _ _ _)).trans (S.map_map _ _).symm @@ -484,7 +484,7 @@ theorem mul_bot (S : AddSubmonoid R) : S * ⊥ = ⊥ := @[simp] theorem bot_mul (S : AddSubmonoid R) : ⊥ * S = ⊥ := - eq_bot_iff.2 <| mul_le.2 fun m hm n hn => by + eq_bot_iff.2 <| mul_le.2 fun m hm n _ => by rw [AddSubmonoid.mem_bot] at hm ⊢; rw [hm, zero_mul] @[mono] diff --git a/Mathlib/Algebra/Group/UniqueProds/Basic.lean b/Mathlib/Algebra/Group/UniqueProds/Basic.lean index 99d252eee83641..bc6e50b4765f82 100644 --- a/Mathlib/Algebra/Group/UniqueProds/Basic.lean +++ b/Mathlib/Algebra/Group/UniqueProds/Basic.lean @@ -136,7 +136,7 @@ alias _root_.UniqueAdd.iff_card_nonpos := UniqueAdd.iff_card_le_one theorem exists_iff_exists_existsUnique : (∃ a0 b0 : G, a0 ∈ A ∧ b0 ∈ B ∧ UniqueMul A B a0 b0) ↔ ∃ g : G, ∃! ab, ab ∈ A ×ˢ B ∧ ab.1 * ab.2 = g := - ⟨fun ⟨a0, b0, hA, hB, h⟩ ↦ ⟨_, (iff_existsUnique hA hB).mp h⟩, fun ⟨g, h⟩ ↦ by + ⟨fun ⟨_, _, hA, hB, h⟩ ↦ ⟨_, (iff_existsUnique hA hB).mp h⟩, fun ⟨g, h⟩ ↦ by have h' := h rcases h' with ⟨⟨a, b⟩, ⟨hab, rfl, -⟩, -⟩ cases' Finset.mem_product.mp hab with ha hb diff --git a/Mathlib/Algebra/Group/WithOne/Basic.lean b/Mathlib/Algebra/Group/WithOne/Basic.lean index 7687d4bd15dca0..3dca5ba0dab777 100644 --- a/Mathlib/Algebra/Group/WithOne/Basic.lean +++ b/Mathlib/Algebra/Group/WithOne/Basic.lean @@ -63,8 +63,8 @@ def lift : (α →ₙ* β) ≃ (WithOne α →* β) where (fun x => WithOne.cases_on y (by rw [mul_one]; exact (mul_one _).symm) (fun y => f.map_mul x y)) } invFun F := F.toMulHom.comp coeMulHom - left_inv f := MulHom.ext fun x => rfl - right_inv F := MonoidHom.ext fun x => WithOne.cases_on x F.map_one.symm (fun x => rfl) + left_inv _ := MulHom.ext fun _ => rfl + right_inv F := MonoidHom.ext fun x => WithOne.cases_on x F.map_one.symm (fun _ => rfl) -- Porting note: the above proofs were broken because they were parenthesized wrong by mathport? variable (f : α →ₙ* β) diff --git a/Mathlib/Algebra/GroupWithZero/Action/Defs.lean b/Mathlib/Algebra/GroupWithZero/Action/Defs.lean index d30f29f25d6f4b..0d5f09f7f565a7 100644 --- a/Mathlib/Algebra/GroupWithZero/Action/Defs.lean +++ b/Mathlib/Algebra/GroupWithZero/Action/Defs.lean @@ -172,7 +172,7 @@ instance AddMonoidHom.smulZeroClass [AddZeroClass B] : SMulZeroClass M (B →+ A { toFun := fun a => r • (f a) map_zero' := by simp only [map_zero, smul_zero] map_add' := fun x y => by simp only [map_add, smul_add] } - smul_zero r := ext fun _ => smul_zero _ + smul_zero _ := ext fun _ => smul_zero _ /-- Pullback a distributive scalar multiplication along an injective additive monoid homomorphism. diff --git a/Mathlib/Algebra/GroupWithZero/Basic.lean b/Mathlib/Algebra/GroupWithZero/Basic.lean index b6f9678b599f4e..da8ba43a46d397 100644 --- a/Mathlib/Algebra/GroupWithZero/Basic.lean +++ b/Mathlib/Algebra/GroupWithZero/Basic.lean @@ -146,7 +146,7 @@ lemma zero_pow_eq (n : ℕ) : (0 : M₀) ^ n = if n = 0 then 1 else 0 := by · rw [h, pow_zero] · rw [zero_pow h] -lemma pow_eq_zero_of_le : ∀ {m n} (hmn : m ≤ n) (ha : a ^ m = 0), a ^ n = 0 +lemma pow_eq_zero_of_le : ∀ {m n} (_ : m ≤ n) (_ : a ^ m = 0), a ^ n = 0 | _, _, Nat.le.refl, ha => ha | _, _, Nat.le.step hmn, ha => by rw [pow_succ, pow_eq_zero_of_le hmn ha, zero_mul] diff --git a/Mathlib/Algebra/GroupWithZero/Hom.lean b/Mathlib/Algebra/GroupWithZero/Hom.lean index 75d6481cf412fd..e4d19ee977799b 100644 --- a/Mathlib/Algebra/GroupWithZero/Hom.lean +++ b/Mathlib/Algebra/GroupWithZero/Hom.lean @@ -39,6 +39,13 @@ open Function namespace NeZero variable {F α β : Type*} [Zero α] [Zero β] [FunLike F α β] [ZeroHomClass F α β] {a : α} +#adaptation_note +/-- +We name `neZero` so it can be used as a named argument, +but since https://github.com/leanprover/lean4/pull/5338, this is considered unused, +so we need to disable the linter. +-/ +set_option linter.unusedVariables false in lemma of_map (f : F) [neZero : NeZero (f a)] : NeZero a := ⟨fun h ↦ ne (f a) <| by rw [h]; exact ZeroHomClass.map_zero f⟩ diff --git a/Mathlib/Algebra/GroupWithZero/WithZero.lean b/Mathlib/Algebra/GroupWithZero/WithZero.lean index 9790623ef1ff9e..66c0edd8d8c172 100644 --- a/Mathlib/Algebra/GroupWithZero/WithZero.lean +++ b/Mathlib/Algebra/GroupWithZero/WithZero.lean @@ -157,10 +157,10 @@ instance monoidWithZero [Monoid α] : MonoidWithZero (WithZero α) where npow n a := a ^ n npow_zero a := match a with | none => rfl - | some a => congr_arg some (pow_zero _) + | some _ => congr_arg some (pow_zero _) npow_succ n a := match a with | none => by change 0 ^ (n + 1) = 0 ^ n * 0; simp only [mul_zero]; rfl - | some a => congr_arg some <| pow_succ _ _ + | some _ => congr_arg some <| pow_succ _ _ instance commMonoidWithZero [CommMonoid α] : CommMonoidWithZero (WithZero α) := { WithZero.monoidWithZero, WithZero.commSemigroup with } @@ -212,13 +212,13 @@ instance divInvMonoid [DivInvMonoid α] : DivInvMonoid (WithZero α) where zpow n a := a ^ n zpow_zero' a := match a with | none => rfl - | some a => congr_arg some (zpow_zero _) + | some _ => congr_arg some (zpow_zero _) zpow_succ' n a := match a with | none => by change 0 ^ _ = 0 ^ _ * 0; simp only [mul_zero]; rfl - | some a => congr_arg some (DivInvMonoid.zpow_succ' _ _) - zpow_neg' n a := match a with + | some _ => congr_arg some (DivInvMonoid.zpow_succ' _ _) + zpow_neg' _ a := match a with | none => rfl - | some a => congr_arg some (DivInvMonoid.zpow_neg' _ _) + | some _ => congr_arg some (DivInvMonoid.zpow_neg' _ _) instance divInvOneMonoid [DivInvOneMonoid α] : DivInvOneMonoid (WithZero α) where __ := divInvMonoid @@ -232,14 +232,14 @@ instance divisionMonoid [DivisionMonoid α] : DivisionMonoid (WithZero α) where __ := involutiveInv mul_inv_rev a b := match a, b with | none, none => rfl - | none, some b => rfl - | some a, none => rfl - | some a, some b => congr_arg some (mul_inv_rev _ _) + | none, some _ => rfl + | some _, none => rfl + | some _, some _ => congr_arg some (mul_inv_rev _ _) inv_eq_of_mul a b := match a, b with | none, none => fun _ ↦ rfl | none, some b => fun _ ↦ by contradiction | some a, none => fun _ ↦ by contradiction - | some a, some b => fun h ↦ + | some _, some _ => fun h ↦ congr_arg some <| inv_eq_of_mul_eq_one_right <| Option.some_injective _ h instance divisionCommMonoid [DivisionCommMonoid α] : DivisionCommMonoid (WithZero α) where diff --git a/Mathlib/Algebra/Homology/Additive.lean b/Mathlib/Algebra/Homology/Additive.lean index 85979eabec6276..5fbebb2c8beb91 100644 --- a/Mathlib/Algebra/Homology/Additive.lean +++ b/Mathlib/Algebra/Homology/Additive.lean @@ -29,7 +29,7 @@ variable (f g : C ⟶ D) (h k : D ⟶ E) (i : ι) namespace HomologicalComplex instance : Zero (C ⟶ D) := - ⟨{ f := fun i => 0 }⟩ + ⟨{ f := fun _ => 0 }⟩ instance : Add (C ⟶ D) := ⟨fun f g => { f := fun i => f.f i + g.f i }⟩ @@ -133,7 +133,7 @@ isomorphic to the identity functor. -/ @[simps!] def Functor.mapHomologicalComplexIdIso (c : ComplexShape ι) : (𝟭 W₁).mapHomologicalComplex c ≅ 𝟭 _ := - NatIso.ofComponents fun K => Hom.isoOfComponents fun i => Iso.refl _ + NatIso.ofComponents fun K => Hom.isoOfComponents fun _ => Iso.refl _ instance Functor.mapHomologicalComplex_reflects_iso (F : W₁ ⥤ W₂) [F.PreservesZeroMorphisms] [ReflectsIsomorphisms F] (c : ComplexShape ι) : @@ -155,7 +155,7 @@ between those functors applied to homological complexes. def NatTrans.mapHomologicalComplex {F G : W₁ ⥤ W₂} [F.PreservesZeroMorphisms] [G.PreservesZeroMorphisms] (α : F ⟶ G) (c : ComplexShape ι) : F.mapHomologicalComplex c ⟶ G.mapHomologicalComplex c where - app C := { f := fun i => α.app _ } + app C := { f := fun _ => α.app _ } @[simp] theorem NatTrans.mapHomologicalComplex_id diff --git a/Mathlib/Algebra/Homology/Augment.lean b/Mathlib/Algebra/Homology/Augment.lean index c72e003fc75571..e9554f54c2961a 100644 --- a/Mathlib/Algebra/Homology/Augment.lean +++ b/Mathlib/Algebra/Homology/Augment.lean @@ -55,7 +55,7 @@ def augment (C : ChainComplex V ℕ) {X : V} (f : C.X 0 ⟶ X) (w : C.d 1 0 ≫ | _, _ => 0 shape | 1, 0, h => absurd rfl h - | i + 2, 0, _ => rfl + | _ + 2, 0, _ => rfl | 0, _, _ => rfl | i + 1, j + 1, h => by simp only; exact C.shape i j (Nat.succ_ne_succ.1 h) @@ -88,9 +88,9 @@ to the original complex. -/ def truncateAugment (C : ChainComplex V ℕ) {X : V} (f : C.X 0 ⟶ X) (w : C.d 1 0 ≫ f = 0) : truncate.obj (augment C f w) ≅ C where - hom := { f := fun i => 𝟙 _ } + hom := { f := fun _ => 𝟙 _ } inv := - { f := fun i => 𝟙 _ + { f := fun _ => 𝟙 _ comm' := fun i j => by cases j <;> · dsimp @@ -125,7 +125,7 @@ theorem chainComplex_d_succ_succ_zero (C : ChainComplex V ℕ) (i : ℕ) : C.d ( def augmentTruncate (C : ChainComplex V ℕ) : augment (truncate.obj C) (C.d 1 0) (C.d_comp_d _ _ _) ≅ C where hom := - { f := fun | 0 => 𝟙 _ | n+1 => 𝟙 _ + { f := fun | 0 => 𝟙 _ | _+1 => 𝟙 _ comm' := fun i j => by -- Porting note: was an rcases n with (_|_|n) but that was causing issues match i with @@ -133,7 +133,7 @@ def augmentTruncate (C : ChainComplex V ℕ) : cases' j with j <;> dsimp [augment, truncate] <;> simp } inv := - { f := fun | 0 => 𝟙 _ | n+1 => 𝟙 _ + { f := fun | 0 => 𝟙 _ | _+1 => 𝟙 _ comm' := fun i j => by -- Porting note: was an rcases n with (_|_|n) but that was causing issues match i with @@ -259,9 +259,9 @@ to the original complex. -/ def truncateAugment (C : CochainComplex V ℕ) {X : V} (f : X ⟶ C.X 0) (w : f ≫ C.d 0 1 = 0) : truncate.obj (augment C f w) ≅ C where - hom := { f := fun i => 𝟙 _ } + hom := { f := fun _ => 𝟙 _ } inv := - { f := fun i => 𝟙 _ + { f := fun _ => 𝟙 _ comm' := fun i j => by cases j <;> · dsimp @@ -300,14 +300,14 @@ theorem cochainComplex_d_succ_succ_zero (C : CochainComplex V ℕ) (i : ℕ) : C def augmentTruncate (C : CochainComplex V ℕ) : augment (truncate.obj C) (C.d 0 1) (C.d_comp_d _ _ _) ≅ C where hom := - { f := fun | 0 => 𝟙 _ | n+1 => 𝟙 _ + { f := fun | 0 => 𝟙 _ | _+1 => 𝟙 _ comm' := fun i j => by rcases j with (_ | _ | j) <;> cases i <;> · dsimp -- Porting note (#10959): simp can't handle this now but aesop does aesop } inv := - { f := fun | 0 => 𝟙 _ | n+1 => 𝟙 _ + { f := fun | 0 => 𝟙 _ | _+1 => 𝟙 _ comm' := fun i j => by rcases j with (_ | _ | j) <;> cases' i with i <;> · dsimp diff --git a/Mathlib/Algebra/Homology/BifunctorShift.lean b/Mathlib/Algebra/Homology/BifunctorShift.lean index 4f6b9ee6aabb4c..b5493653d24f8d 100644 --- a/Mathlib/Algebra/Homology/BifunctorShift.lean +++ b/Mathlib/Algebra/Homology/BifunctorShift.lean @@ -67,7 +67,7 @@ def mapBifunctorHomologicalComplexShift₁Iso : ((F.mapBifunctorHomologicalComplex _ _).obj (K₁⟦x⟧)).obj K₂ ≅ (HomologicalComplex₂.shiftFunctor₁ D x).obj (((F.mapBifunctorHomologicalComplex _ _).obj K₁).obj K₂) := - HomologicalComplex.Hom.isoOfComponents (fun i₁ => Iso.refl _) + HomologicalComplex.Hom.isoOfComponents (fun _ => Iso.refl _) instance : HasMapBifunctor (K₁⟦x⟧) K₂ F := HomologicalComplex₂.hasTotal_of_iso (mapBifunctorHomologicalComplexShift₁Iso K₁ K₂ F x).symm _ @@ -95,7 +95,7 @@ def mapBifunctorHomologicalComplexShift₂Iso : (HomologicalComplex₂.shiftFunctor₂ D y).obj (((F.mapBifunctorHomologicalComplex _ _).obj K₁).obj K₂) := HomologicalComplex.Hom.isoOfComponents - (fun i₁ => HomologicalComplex.Hom.isoOfComponents (fun i₂ => Iso.refl _)) + (fun i₁ => HomologicalComplex.Hom.isoOfComponents (fun _ => Iso.refl _)) instance : HasMapBifunctor K₁ (K₂⟦y⟧) F := HomologicalComplex₂.hasTotal_of_iso (mapBifunctorHomologicalComplexShift₂Iso K₁ K₂ F y).symm _ diff --git a/Mathlib/Algebra/Homology/Functor.lean b/Mathlib/Algebra/Homology/Functor.lean index 81f80b27fe33b8..59cf2538f199cf 100644 --- a/Mathlib/Algebra/Homology/Functor.lean +++ b/Mathlib/Algebra/Homology/Functor.lean @@ -45,7 +45,7 @@ def asFunctor {T : Type*} [Category T] (C : HomologicalComplex (T ⥤ V) c) : exact this t } map h := { f := fun i => (C.X i).map h - comm' := fun i j _ => NatTrans.naturality _ _ } + comm' := fun _ _ _ => NatTrans.naturality _ _ } map_id t := by ext i dsimp diff --git a/Mathlib/Algebra/Homology/HomologicalBicomplex.lean b/Mathlib/Algebra/Homology/HomologicalBicomplex.lean index dbd85f9d8e7100..634f2df3056f23 100644 --- a/Mathlib/Algebra/Homology/HomologicalBicomplex.lean +++ b/Mathlib/Algebra/Homology/HomologicalBicomplex.lean @@ -149,7 +149,7 @@ def flip (K : HomologicalComplex₂ C c₁ c₂) : HomologicalComplex₂ C c₂ X i := { X := fun j => (K.X j).X i d := fun j j' => (K.d j j').f i - shape := fun j j' w => K.shape_f _ _ w i } + shape := fun _ _ w => K.shape_f _ _ w i } d i i' := { f := fun j => (K.X j).d i i' } shape i i' w := by ext j @@ -176,7 +176,7 @@ def flipFunctor : def flipEquivalenceUnitIso : 𝟭 (HomologicalComplex₂ C c₁ c₂) ≅ flipFunctor C c₁ c₂ ⋙ flipFunctor C c₂ c₁ := NatIso.ofComponents (fun K => HomologicalComplex.Hom.isoOfComponents (fun i₁ => - HomologicalComplex.Hom.isoOfComponents (fun i₂ => Iso.refl _) + HomologicalComplex.Hom.isoOfComponents (fun _ => Iso.refl _) (by aesop_cat)) (by aesop_cat)) (by aesop_cat) /-- Auxiliary definition for `HomologicalComplex₂.flipEquivalence`. -/ @@ -184,7 +184,7 @@ def flipEquivalenceUnitIso : def flipEquivalenceCounitIso : flipFunctor C c₂ c₁ ⋙ flipFunctor C c₁ c₂ ≅ 𝟭 (HomologicalComplex₂ C c₂ c₁) := NatIso.ofComponents (fun K => HomologicalComplex.Hom.isoOfComponents (fun i₂ => - HomologicalComplex.Hom.isoOfComponents (fun i₁ => Iso.refl _) + HomologicalComplex.Hom.isoOfComponents (fun _ => Iso.refl _) (by aesop_cat)) (by aesop_cat)) (by aesop_cat) /-- Flipping a complex of complexes over the diagonal, as an equivalence of categories. -/ diff --git a/Mathlib/Algebra/Homology/HomologicalComplex.lean b/Mathlib/Algebra/Homology/HomologicalComplex.lean index 2494b21c2eb586..0b0c05b2019edb 100644 --- a/Mathlib/Algebra/Homology/HomologicalComplex.lean +++ b/Mathlib/Algebra/Homology/HomologicalComplex.lean @@ -224,7 +224,7 @@ theorem Hom.comm {A B : HomologicalComplex V c} (f : A.Hom B) (i j : ι) : · rw [A.shape i j hij, B.shape i j hij, comp_zero, zero_comp] instance (A B : HomologicalComplex V c) : Inhabited (Hom A B) := - ⟨{ f := fun i => 0 }⟩ + ⟨{ f := fun _ => 0 }⟩ /-- Identity chain map. -/ def id (A : HomologicalComplex V c) : Hom A A where f _ := 𝟙 _ @@ -273,7 +273,7 @@ theorem hom_f_injective {C₁ C₂ : HomologicalComplex V c} : Function.Injective fun f : Hom C₁ C₂ => f.f := by aesop_cat instance (X Y : HomologicalComplex V c) : Zero (X ⟶ Y) := - ⟨{ f := fun i => 0}⟩ + ⟨{ f := fun _ => 0}⟩ @[simp] theorem zero_f (C D : HomologicalComplex V c) (i : ι) : (0 : C ⟶ D).f i = 0 := @@ -346,7 +346,7 @@ instance : (forget V c).Faithful where just picking out the `i`-th object. -/ @[simps!] def forgetEval (i : ι) : forget V c ⋙ GradedObject.eval i ≅ eval V c i := - NatIso.ofComponents fun X => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ end diff --git a/Mathlib/Algebra/Homology/HomologicalComplexLimits.lean b/Mathlib/Algebra/Homology/HomologicalComplexLimits.lean index 2589bf52e1e50b..0e2a446e272645 100644 --- a/Mathlib/Algebra/Homology/HomologicalComplexLimits.lean +++ b/Mathlib/Algebra/Homology/HomologicalComplexLimits.lean @@ -66,7 +66,7 @@ noncomputable def coneOfHasLimitEval : Cone F where dsimp rw [(F.obj j).shape _ _ h, comp_zero, zero_comp] } π := - { app := fun j => { f := fun n => limit.π _ j } + { app := fun j => { f := fun _ => limit.π _ j } naturality := fun i j φ => by ext n dsimp diff --git a/Mathlib/Algebra/Homology/Homotopy.lean b/Mathlib/Algebra/Homology/Homotopy.lean index f8c43c0d2b8445..82243da05a6b34 100644 --- a/Mathlib/Algebra/Homology/Homotopy.lean +++ b/Mathlib/Algebra/Homology/Homotopy.lean @@ -131,11 +131,11 @@ namespace Homotopy def equivSubZero : Homotopy f g ≃ Homotopy (f - g) 0 where toFun h := { hom := fun i j => h.hom i j - zero := fun i j w => h.zero _ _ w + zero := fun _ _ w => h.zero _ _ w comm := fun i => by simp [h.comm] } invFun h := { hom := fun i j => h.hom i j - zero := fun i j w => h.zero _ _ w + zero := fun _ _ w => h.zero _ _ w comm := fun i => by simpa [sub_eq_iff_eq_add] using h.comm i } left_inv := by aesop_cat right_inv := by aesop_cat diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/Shift.lean b/Mathlib/Algebra/Homology/HomotopyCategory/Shift.lean index 01810e1dc41e49..ccbab125d8ff98 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/Shift.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/Shift.lean @@ -40,7 +40,7 @@ multiplies the differentials by `(-1)^n`. -/ def shiftFunctor (n : ℤ) : CochainComplex C ℤ ⥤ CochainComplex C ℤ where obj K := { X := fun i => K.X (i + n) - d := fun i j => n.negOnePow • K.d _ _ + d := fun _ _ => n.negOnePow • K.d _ _ d_comp_d' := by intros simp only [Linear.comp_units_smul, Linear.units_smul_comp, d_comp_d, smul_zero] @@ -52,7 +52,7 @@ def shiftFunctor (n : ℤ) : CochainComplex C ℤ ⥤ CochainComplex C ℤ where dsimp at hij' ⊢ omega } map φ := - { f := fun i => φ.f _ + { f := fun _ => φ.f _ comm' := by intros dsimp @@ -273,7 +273,7 @@ variable {C} between `φ₁⟦n⟧'` and `φ₂⟦n⟧'`. -/ def shift {K L : CochainComplex C ℤ} {φ₁ φ₂ : K ⟶ L} (h : Homotopy φ₁ φ₂) (n : ℤ) : Homotopy (φ₁⟦n⟧') (φ₂⟦n⟧') where - hom i j := n.negOnePow • h.hom _ _ + hom _ _ := n.negOnePow • h.hom _ _ zero i j hij := by dsimp rw [h.zero, smul_zero] diff --git a/Mathlib/Algebra/Homology/HomotopyCofiber.lean b/Mathlib/Algebra/Homology/HomotopyCofiber.lean index dfbe3a72907cae..c09675a4982fcb 100644 --- a/Mathlib/Algebra/Homology/HomotopyCofiber.lean +++ b/Mathlib/Algebra/Homology/HomotopyCofiber.lean @@ -245,7 +245,7 @@ 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 i j hij := dif_neg hij + zero _ _ hij := dif_neg hij comm j := by obtain ⟨i, hij⟩ := hc j rw [prevD_eq _ hij, dif_pos hij] diff --git a/Mathlib/Algebra/Homology/Localization.lean b/Mathlib/Algebra/Homology/Localization.lean index 197ad242ab355c..9401e727157608 100644 --- a/Mathlib/Algebra/Homology/Localization.lean +++ b/Mathlib/Algebra/Homology/Localization.lean @@ -223,8 +223,8 @@ def ComplexShape.strictUniversalPropertyFixedTargetQuotient (E : Type*) [Categor intro K L f g ⟨h⟩ have : DecidableRel c.Rel := by classical infer_instance exact h.map_eq_of_inverts_homotopyEquivalences hc F hF) - fac F hF := rfl - uniq F₁ F₂ h := Quotient.lift_unique' _ _ _ h + fac _ _ := rfl + uniq _ _ h := Quotient.lift_unique' _ _ _ h lemma ComplexShape.quotient_isLocalization : (HomotopyCategory.quotient C c).IsLocalization diff --git a/Mathlib/Algebra/Homology/Opposite.lean b/Mathlib/Algebra/Homology/Opposite.lean index ae00fdfe5a5f17..ba39dfe50ab4e2 100644 --- a/Mathlib/Algebra/Homology/Opposite.lean +++ b/Mathlib/Algebra/Homology/Opposite.lean @@ -123,7 +123,7 @@ def opInverse : HomologicalComplex Vᵒᵖ c.symm ⥤ (HomologicalComplex V c) def opUnitIso : 𝟭 (HomologicalComplex V c)ᵒᵖ ≅ opFunctor V c ⋙ opInverse V c := NatIso.ofComponents (fun X => - (HomologicalComplex.Hom.isoOfComponents (fun i => Iso.refl _) fun i j _ => by + (HomologicalComplex.Hom.isoOfComponents (fun _ => Iso.refl _) fun i j _ => by simp only [Iso.refl_hom, Category.id_comp, unopSymm_d, op_d, Quiver.Hom.unop_op, Category.comp_id] : (Opposite.unop X).op.unopSymm ≅ unop X).op) @@ -138,7 +138,7 @@ def opUnitIso : 𝟭 (HomologicalComplex V c)ᵒᵖ ≅ opFunctor V c ⋙ opInve /-- Auxiliary definition for `opEquivalence`. -/ def opCounitIso : opInverse V c ⋙ opFunctor V c ≅ 𝟭 (HomologicalComplex Vᵒᵖ c.symm) := NatIso.ofComponents - fun X => HomologicalComplex.Hom.isoOfComponents fun i => Iso.refl _ + fun X => HomologicalComplex.Hom.isoOfComponents fun _ => Iso.refl _ /-- 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ᵒᵖ`. -/ @@ -174,7 +174,7 @@ def unopInverse : HomologicalComplex V c.symm ⥤ (HomologicalComplex Vᵒᵖ c) def unopUnitIso : 𝟭 (HomologicalComplex Vᵒᵖ c)ᵒᵖ ≅ unopFunctor V c ⋙ unopInverse V c := NatIso.ofComponents (fun X => - (HomologicalComplex.Hom.isoOfComponents (fun i => Iso.refl _) fun i j _ => by + (HomologicalComplex.Hom.isoOfComponents (fun _ => Iso.refl _) fun i j _ => by simp only [Iso.refl_hom, Category.id_comp, unopSymm_d, op_d, Quiver.Hom.unop_op, Category.comp_id] : (Opposite.unop X).op.unopSymm ≅ unop X).op) @@ -189,7 +189,7 @@ def unopUnitIso : 𝟭 (HomologicalComplex Vᵒᵖ c)ᵒᵖ ≅ unopFunctor V c /-- Auxiliary definition for `unopEquivalence`. -/ def unopCounitIso : unopInverse V c ⋙ unopFunctor V c ≅ 𝟭 (HomologicalComplex V c.symm) := NatIso.ofComponents - fun X => HomologicalComplex.Hom.isoOfComponents fun i => Iso.refl _ + fun X => HomologicalComplex.Hom.isoOfComponents fun _ => Iso.refl _ /-- 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`. -/ diff --git a/Mathlib/Algebra/Homology/Single.lean b/Mathlib/Algebra/Homology/Single.lean index f29c9eed69daf9..a9cbef23cd3c9d 100644 --- a/Mathlib/Algebra/Homology/Single.lean +++ b/Mathlib/Algebra/Homology/Single.lean @@ -34,7 +34,7 @@ variable {ι : Type*} [DecidableEq ι] (c : ComplexShape ι) noncomputable def single (j : ι) : V ⥤ HomologicalComplex V c where obj A := { X := fun i => if i = j then A else 0 - d := fun i j => 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 } diff --git a/Mathlib/Algebra/IsPrimePow.lean b/Mathlib/Algebra/IsPrimePow.lean index 1aa00c6f318189..c21cf0363fe867 100644 --- a/Mathlib/Algebra/IsPrimePow.lean +++ b/Mathlib/Algebra/IsPrimePow.lean @@ -27,7 +27,7 @@ theorem isPrimePow_def : IsPrimePow n ↔ ∃ (p : R) (k : ℕ), Prime p ∧ 0 < natural `k` such that `n` can be written as `p^(k+1)`. -/ theorem isPrimePow_iff_pow_succ : IsPrimePow n ↔ ∃ (p : R) (k : ℕ), Prime p ∧ p ^ (k + 1) = n := (isPrimePow_def _).trans - ⟨fun ⟨p, k, hp, hk, hn⟩ => ⟨p, k - 1, hp, by rwa [Nat.sub_add_cancel hk]⟩, fun ⟨p, k, hp, hn⟩ => + ⟨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 diff --git a/Mathlib/Algebra/Lie/BaseChange.lean b/Mathlib/Algebra/Lie/BaseChange.lean index 232b3327a85d38..47f4ab1bcd2c5f 100644 --- a/Mathlib/Algebra/Lie/BaseChange.lean +++ b/Mathlib/Algebra/Lie/BaseChange.lean @@ -118,7 +118,7 @@ instance instLieRingModule : LieRingModule (A ⊗[R] L) (A ⊗[R] M) where 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 t x m := map_smul _ _ _ + lie_smul _ _ _ := map_smul _ _ _ end ExtendScalars diff --git a/Mathlib/Algebra/Lie/Derivation/Basic.lean b/Mathlib/Algebra/Lie/Derivation/Basic.lean index 00c92eef36252d..38387717253251 100644 --- a/Mathlib/Algebra/Lie/Derivation/Basic.lean +++ b/Mathlib/Algebra/Lie/Derivation/Basic.lean @@ -104,7 +104,7 @@ lemma apply_lie_eq_add (D : LieDerivation R L L) (a b : L) : /-- 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) := - fun z hz => + fun _ hz => have zero : D1 0 = D2 0 := by simp only [map_zero] have smul : ∀ (r : R), ∀ {x : L}, D1 x = D2 x → D1 (r • x) = D2 (r • x) := fun _ _ hx => by simp only [map_smul, hx] diff --git a/Mathlib/Algebra/Lie/DirectSum.lean b/Mathlib/Algebra/Lie/DirectSum.lean index 973c229bb0534a..d6222f0c9db3e3 100644 --- a/Mathlib/Algebra/Lie/DirectSum.lean +++ b/Mathlib/Algebra/Lie/DirectSum.lean @@ -41,7 +41,7 @@ variable [∀ i, AddCommGroup (M i)] [∀ i, Module R (M i)] variable [∀ i, LieRingModule L (M i)] [∀ i, LieModule R L (M i)] instance : LieRingModule L (⨁ i, M i) where - bracket x m := m.mapRange (fun i m' => ⁅x, m'⁆) fun i => lie_zero x + bracket x m := m.mapRange (fun _ m' => ⁅x, m'⁆) fun _ => lie_zero x add_lie x y m := by refine DFinsupp.ext fun _ => ?_ -- Porting note: Originally `ext` simp only [mapRange_apply, add_apply, add_lie] @@ -96,7 +96,7 @@ variable [∀ i, LieRing (L i)] [∀ i, LieAlgebra R (L i)] instance lieRing : LieRing (⨁ i, L i) := { (inferInstance : AddCommGroup _) with - bracket := zipWith (fun i => fun x y => ⁅x, y⁆) fun i => lie_zero 0 + bracket := zipWith (fun _ => fun x y => ⁅x, y⁆) fun _ => lie_zero 0 add_lie := fun x y z => by refine DFinsupp.ext fun _ => ?_ -- Porting note: Originally `ext` simp only [zipWith_apply, add_apply, add_lie] diff --git a/Mathlib/Algebra/Lie/Subalgebra.lean b/Mathlib/Algebra/Lie/Subalgebra.lean index be459970fb9770..6421cf0fe0753e 100644 --- a/Mathlib/Algebra/Lie/Subalgebra.lean +++ b/Mathlib/Algebra/Lie/Subalgebra.lean @@ -461,7 +461,7 @@ instance completeLattice : CompleteLattice (LieSubalgebra R L) := top := ⊤ le_top := fun _ _ _ ↦ trivial inf := (· ⊓ ·) - le_inf := fun N₁ N₂ N₃ h₁₂ h₁₃ m hm ↦ ⟨h₁₂ hm, h₁₃ hm⟩ + le_inf := fun _ _ _ h₁₂ h₁₃ _ hm ↦ ⟨h₁₂ hm, h₁₃ hm⟩ inf_le_left := fun _ _ _ ↦ And.left inf_le_right := fun _ _ _ ↦ And.right } @@ -694,7 +694,7 @@ def ofEq (h : (L₁' : Set L₁) = L₁'') : L₁' ≃ₗ⁅R⁆ L₁'' := ext x change x ∈ (L₁' : Set L₁) ↔ x ∈ (L₁'' : Set L₁) rw [h]) with - map_lie' := @fun x y ↦ rfl } + map_lie' := @fun _ _ ↦ rfl } @[simp] theorem ofEq_apply (L L' : LieSubalgebra R L₁) (h : (L : Set L₁) = L') (x : L) : diff --git a/Mathlib/Algebra/Lie/Submodule.lean b/Mathlib/Algebra/Lie/Submodule.lean index 1ce9ee98b69dcc..6c64bbfcaee742 100644 --- a/Mathlib/Algebra/Lie/Submodule.lean +++ b/Mathlib/Algebra/Lie/Submodule.lean @@ -885,7 +885,7 @@ Submodules. -/ invFun := comap e left_inv := fun N ↦ by ext; simp right_inv := fun N ↦ by ext; simp [e.apply_eq_iff_eq_symm_apply] - map_rel_iff' := fun {N N'} ↦ Set.image_subset_image_iff e.injective + map_rel_iff' := fun {_ _} ↦ Set.image_subset_image_iff e.injective end LieSubmodule @@ -1386,7 +1386,7 @@ def LieSubalgebra.topEquiv : (⊤ : LieSubalgebra R L) ≃ₗ⁅R⁆ L := { (⊤ : LieSubalgebra R L).incl with invFun := fun x ↦ ⟨x, Set.mem_univ x⟩ left_inv := fun x ↦ by ext; rfl - right_inv := fun x ↦ rfl } + right_inv := fun _ ↦ rfl } @[simp] theorem LieSubalgebra.topEquiv_apply (x : (⊤ : LieSubalgebra R L)) : LieSubalgebra.topEquiv x = x := diff --git a/Mathlib/Algebra/Lie/TensorProduct.lean b/Mathlib/Algebra/Lie/TensorProduct.lean index 0fe6b3f7fb9e88..0974b6a2d5a2d2 100644 --- a/Mathlib/Algebra/Lie/TensorProduct.lean +++ b/Mathlib/Algebra/Lie/TensorProduct.lean @@ -51,7 +51,7 @@ instance lieRingModule : LieRingModule L (M ⊗[R] N) where simp only [hasBracketAux, LinearMap.lTensor_add, LinearMap.rTensor_add, LieHom.map_add, LinearMap.add_apply] abel - lie_add x := LinearMap.map_add _ + lie_add _ := LinearMap.map_add _ leibniz_lie x y t := by suffices (hasBracketAux x).comp (hasBracketAux y) = hasBracketAux ⁅x, y⁆ + (hasBracketAux y).comp (hasBracketAux x) by @@ -69,7 +69,7 @@ instance lieModule : LieModule R L (M ⊗[R] N) where change hasBracketAux (c • x) _ = c • hasBracketAux _ _ simp only [hasBracketAux, smul_add, LinearMap.rTensor_smul, LinearMap.smul_apply, LinearMap.lTensor_smul, LieHom.map_smul, LinearMap.add_apply] - lie_smul c x := LinearMap.map_smul _ c + lie_smul c _ := LinearMap.map_smul _ c @[simp] theorem lie_tmul_right (x : L) (m : M) (n : N) : ⁅x, m ⊗ₜ[R] n⁆ = ⁅x, m⁆ ⊗ₜ n + m ⊗ₜ ⁅x, n⁆ := diff --git a/Mathlib/Algebra/Module/BigOperators.lean b/Mathlib/Algebra/Module/BigOperators.lean index d15e7274ec57a5..06ae5152f2d7ff 100644 --- a/Mathlib/Algebra/Module/BigOperators.lean +++ b/Mathlib/Algebra/Module/BigOperators.lean @@ -41,7 +41,7 @@ lemma Fintype.sum_smul_sum [Fintype α] [Fintype β] (f : α → R) (g : β → end AddCommMonoid -theorem Finset.cast_card [CommSemiring R] (s : Finset α) : (s.card : R) = ∑ a ∈ s, 1 := by +theorem Finset.cast_card [CommSemiring R] (s : Finset α) : (s.card : R) = ∑ _ ∈ s, 1 := by rw [Finset.sum_const, Nat.smul_one_eq_cast] open Finset diff --git a/Mathlib/Algebra/Module/CharacterModule.lean b/Mathlib/Algebra/Module/CharacterModule.lean index ec58e2bbe758b0..1f39cb315264c6 100644 --- a/Mathlib/Algebra/Module/CharacterModule.lean +++ b/Mathlib/Algebra/Module/CharacterModule.lean @@ -108,10 +108,10 @@ Any character `c` in `(A ⊗ B)⋆` induces a linear map `A → B⋆` by `a ↦ CharacterModule (A ⊗[R] B) →ₗ[R] (A →ₗ[R] CharacterModule B) where toFun c := { toFun := (c.comp <| TensorProduct.mk R A B ·) - map_add' := fun a a' ↦ DFunLike.ext _ _ fun b ↦ + map_add' := fun _ _ ↦ DFunLike.ext _ _ fun b ↦ congr(c <| $(map_add (mk R A B) _ _) b).trans (c.map_add _ _) map_smul' := fun r a ↦ by ext; exact congr(c $(TensorProduct.tmul_smul _ _ _)).symm } - map_add' c c' := rfl + map_add' _ _ := rfl map_smul' r c := by ext; exact congr(c $(TensorProduct.tmul_smul _ _ _)).symm /-- diff --git a/Mathlib/Algebra/Module/Equiv/Basic.lean b/Mathlib/Algebra/Module/Equiv/Basic.lean index 502f5ddd8ebdfe..35af015470723d 100644 --- a/Mathlib/Algebra/Module/Equiv/Basic.lean +++ b/Mathlib/Algebra/Module/Equiv/Basic.lean @@ -78,9 +78,9 @@ instance automorphismGroup : Group (M ≃ₗ[R] M) where mul f g := g.trans f one := LinearEquiv.refl R M inv f := f.symm - mul_assoc f g h := rfl - mul_one f := ext fun x ↦ rfl - one_mul f := ext fun x ↦ rfl + mul_assoc _ _ _ := rfl + mul_one _ := ext fun _ ↦ rfl + one_mul _ := ext fun _ ↦ rfl inv_mul_cancel f := ext <| f.left_inv @[simp] diff --git a/Mathlib/Algebra/Module/Injective.lean b/Mathlib/Algebra/Module/Injective.lean index a2e077efec5f70..9ed163e6256bfa 100644 --- a/Mathlib/Algebra/Module/Injective.lean +++ b/Mathlib/Algebra/Module/Injective.lean @@ -126,7 +126,7 @@ instance : Inf (ExtensionOf i f) where refine ⟨X1.le (Set.mem_range_self _), X2.le (Set.mem_range_self _), ?_⟩ rw [← X1.is_extension x, ← X2.is_extension x] : x ∈ X1.toLinearPMap.eqLocus X2.toLinearPMap) - is_extension := fun m => X1.is_extension _ } + is_extension := fun _ => X1.is_extension _ } instance : SemilatticeInf (ExtensionOf i f) := Function.Injective.semilatticeInf ExtensionOf.toLinearPMap diff --git a/Mathlib/Algebra/Module/LinearMap/Defs.lean b/Mathlib/Algebra/Module/LinearMap/Defs.lean index e2c0d892238461..eceefd6b766ab6 100644 --- a/Mathlib/Algebra/Module/LinearMap/Defs.lean +++ b/Mathlib/Algebra/Module/LinearMap/Defs.lean @@ -286,7 +286,7 @@ as a `σ`-semilinear map for any ring homomorphism `σ` which we know is the ide @[simps] def id' {σ : R →+* R} [RingHomId σ] : M →ₛₗ[σ] M where toFun x := x - map_add' x y := rfl + map_add' _ _ := rfl map_smul' r x := by have := (RingHomId.eq_id : σ = _) subst this diff --git a/Mathlib/Algebra/Module/LinearMap/End.lean b/Mathlib/Algebra/Module/LinearMap/End.lean index 0c0b70a6385544..f75595188a8c15 100644 --- a/Mathlib/Algebra/Module/LinearMap/End.lean +++ b/Mathlib/Algebra/Module/LinearMap/End.lean @@ -67,7 +67,7 @@ instance _root_.Module.End.instNontrivial [Nontrivial M] : Nontrivial (Module.En instance _root_.Module.End.monoid : Monoid (Module.End R M) where mul := (· * ·) one := (1 : M →ₗ[R] M) - mul_assoc f g h := LinearMap.ext fun x ↦ rfl + mul_assoc _ _ _ := LinearMap.ext fun _ ↦ rfl mul_one := comp_id one_mul := id_comp diff --git a/Mathlib/Algebra/Module/LocalizedModule.lean b/Mathlib/Algebra/Module/LocalizedModule.lean index f9a2368b9a8189..8cb4bff99cb6b1 100644 --- a/Mathlib/Algebra/Module/LocalizedModule.lean +++ b/Mathlib/Algebra/Module/LocalizedModule.lean @@ -59,7 +59,7 @@ theorem r.isEquiv : IsEquiv _ (r S M) := have hu2' := congr_arg ((u1 * s1) • ·) hu2.symm simp only [← mul_smul, smul_assoc, mul_assoc, mul_comm, mul_left_comm] at hu1' hu2' ⊢ rw [hu2', hu1'] - symm := fun ⟨m1, s1⟩ ⟨m2, s2⟩ ⟨u, hu⟩ => ⟨u, hu.symm⟩ } + symm := fun ⟨_, _⟩ ⟨_, _⟩ ⟨u, hu⟩ => ⟨u, hu.symm⟩ } instance r.setoid : Setoid (M × S) where r := r S M @@ -484,7 +484,7 @@ variable (S M) def mkLinearMap : M →ₗ[R] LocalizedModule S M where toFun m := mk m 1 map_add' x y := by simp [mk_add_mk] - map_smul' r x := (smul'_mk _ _ _).symm + map_smul' _ _ := (smul'_mk _ _ _).symm end diff --git a/Mathlib/Algebra/Module/Submodule/Bilinear.lean b/Mathlib/Algebra/Module/Submodule/Bilinear.lean index d6c065576cbbfa..4ec89546d980da 100644 --- a/Mathlib/Algebra/Module/Submodule/Bilinear.lean +++ b/Mathlib/Algebra/Module/Submodule/Bilinear.lean @@ -80,7 +80,7 @@ theorem map₂_bot_right (f : M →ₗ[R] N →ₗ[R] P) (p : Submodule R M) : m @[simp] theorem map₂_bot_left (f : M →ₗ[R] N →ₗ[R] P) (q : Submodule R N) : map₂ f ⊥ q = ⊥ := eq_bot_iff.2 <| - map₂_le.2 fun m hm n hn => by + map₂_le.2 fun m hm n _ => by rw [Submodule.mem_bot] at hm ⊢ rw [hm, LinearMap.map_zero₂] diff --git a/Mathlib/Algebra/Module/Submodule/Equiv.lean b/Mathlib/Algebra/Module/Submodule/Equiv.lean index f5de6d41357b8e..30f945c04ad802 100644 --- a/Mathlib/Algebra/Module/Submodule/Equiv.lean +++ b/Mathlib/Algebra/Module/Submodule/Equiv.lean @@ -231,7 +231,7 @@ noncomputable def comap_equiv_self_of_inj_of_le {f : M →ₗ[R] N} {p : Submodu (hf : Injective f) (h : p ≤ LinearMap.range f) : p.comap f ≃ₗ[R] p := LinearEquiv.ofBijective - ((f ∘ₗ (p.comap f).subtype).codRestrict p <| fun ⟨x, hx⟩ ↦ mem_comap.mp hx) + ((f ∘ₗ (p.comap f).subtype).codRestrict p <| fun ⟨_, hx⟩ ↦ mem_comap.mp hx) (⟨fun x y hxy ↦ by simpa using hf (Subtype.ext_iff.mp hxy), fun ⟨x, hx⟩ ↦ by obtain ⟨y, rfl⟩ := h hx; exact ⟨⟨y, hx⟩, by simp [Subtype.ext_iff]⟩⟩) diff --git a/Mathlib/Algebra/Module/Submodule/Map.lean b/Mathlib/Algebra/Module/Submodule/Map.lean index 0e08a969e1c074..8e6b50ba4e4654 100644 --- a/Mathlib/Algebra/Module/Submodule/Map.lean +++ b/Mathlib/Algebra/Module/Submodule/Map.lean @@ -463,8 +463,8 @@ def comapSubtypeEquivOfLe {p q : Submodule R M} (hpq : p ≤ q) : comap q.subtyp invFun x := ⟨⟨x, hpq x.2⟩, x.2⟩ left_inv x := by simp only [coe_mk, SetLike.eta, LinearEquiv.coe_coe] right_inv x := by simp only [Subtype.coe_mk, SetLike.eta, LinearEquiv.coe_coe] - map_add' x y := rfl - map_smul' c x := rfl + map_add' _ _ := rfl + map_smul' _ _ := rfl -- Porting note: The original theorem generated by `simps` was using `LinearEquiv.toLinearMap`, -- different from the theorem on Lean 3, and not simp-normal form. diff --git a/Mathlib/Algebra/Module/Submodule/Range.lean b/Mathlib/Algebra/Module/Submodule/Range.lean index 32fdf052d8793d..40e7e2b4527896 100644 --- a/Mathlib/Algebra/Module/Submodule/Range.lean +++ b/Mathlib/Algebra/Module/Submodule/Range.lean @@ -175,7 +175,7 @@ theorem range_eq_bot {f : M →ₛₗ[τ₁₂] M₂} : range f = ⊥ ↔ f = 0 theorem range_le_ker_iff {f : M →ₛₗ[τ₁₂] M₂} {g : M₂ →ₛₗ[τ₂₃] M₃} : range f ≤ ker g ↔ (g.comp f : M →ₛₗ[τ₁₃] M₃) = 0 := - ⟨fun h => ker_eq_top.1 <| eq_top_iff'.2 fun x => h <| ⟨_, rfl⟩, fun h x hx => + ⟨fun h => ker_eq_top.1 <| eq_top_iff'.2 fun _ => h <| ⟨_, rfl⟩, fun h x hx => mem_ker.2 <| Exists.elim hx fun y hy => by rw [← hy, ← comp_apply, h, zero_apply]⟩ theorem comap_le_comap_iff {f : F} (hf : range f = ⊤) {p p'} : comap f p ≤ comap f p' ↔ p ≤ p' := diff --git a/Mathlib/Algebra/MonoidAlgebra/Grading.lean b/Mathlib/Algebra/MonoidAlgebra/Grading.lean index e13d03a50b709e..e6e0a806f2d7f5 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Grading.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Grading.lean @@ -48,7 +48,7 @@ abbrev gradeBy (f : M → ι) (i : ι) : Submodule R R[M] where 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) - smul_mem' a m h := Set.Subset.trans Finsupp.support_smul h + smul_mem' _ _ h := Set.Subset.trans Finsupp.support_smul h /-- The submodule corresponding to each grade. -/ abbrev grade (m : M) : Submodule R R[M] := diff --git a/Mathlib/Algebra/MvPolynomial/Basic.lean b/Mathlib/Algebra/MvPolynomial/Basic.lean index 722c1bdf7b69af..1c4137397a564a 100644 --- a/Mathlib/Algebra/MvPolynomial/Basic.lean +++ b/Mathlib/Algebra/MvPolynomial/Basic.lean @@ -373,7 +373,7 @@ theorem induction_on' {P : MvPolynomial σ R → Prop} (p : MvPolynomial σ R) Finsupp.induction p (suffices P (monomial 0 0) by rwa [monomial_zero] at this show P (monomial 0 0) from h1 0 0) - fun a b f _ha _hb hPf => h2 _ _ (h1 _ _) hPf + fun _ _ _ _ha _hb hPf => h2 _ _ (h1 _ _) hPf /-- Similar to `MvPolynomial.induction_on` but only a weak form of `h_add` is required. -/ theorem induction_on''' {M : MvPolynomial σ R → Prop} (p : MvPolynomial σ R) (h_C : ∀ a, M (C a)) diff --git a/Mathlib/Algebra/MvPolynomial/CommRing.lean b/Mathlib/Algebra/MvPolynomial/CommRing.lean index 71f9d8c13a24db..7e4cbd57dbbc29 100644 --- a/Mathlib/Algebra/MvPolynomial/CommRing.lean +++ b/Mathlib/Algebra/MvPolynomial/CommRing.lean @@ -151,7 +151,7 @@ functions out of the type `σ`, -/ def homEquiv : (MvPolynomial σ ℤ →+* S) ≃ (σ → S) where toFun f := f ∘ X invFun f := eval₂Hom (Int.castRingHom S) f - left_inv f := RingHom.ext <| eval₂Hom_X _ _ + left_inv _ := RingHom.ext <| eval₂Hom_X _ _ right_inv f := funext fun x => by simp only [coe_eval₂Hom, Function.comp_apply, eval₂_X] end Eval diff --git a/Mathlib/Algebra/MvPolynomial/PDeriv.lean b/Mathlib/Algebra/MvPolynomial/PDeriv.lean index 2f36da703dccde..2f9c43a1a86014 100644 --- a/Mathlib/Algebra/MvPolynomial/PDeriv.lean +++ b/Mathlib/Algebra/MvPolynomial/PDeriv.lean @@ -79,7 +79,7 @@ theorem pderiv_one {i : σ} : pderiv i (1 : MvPolynomial σ R) = 0 := pderiv_C @[simp] theorem pderiv_X [DecidableEq σ] (i j : σ) : - pderiv i (X j : MvPolynomial σ R) = Pi.single (f := fun j => _) i 1 j := by + pderiv i (X j : MvPolynomial σ R) = Pi.single (f := fun _ => _) i 1 j := by rw [pderiv_def, mkDerivation_X] @[simp] diff --git a/Mathlib/Algebra/Order/Antidiag/Finsupp.lean b/Mathlib/Algebra/Order/Antidiag/Finsupp.lean index 05c533be798686..3564d4ffb40768 100644 --- a/Mathlib/Algebra/Order/Antidiag/Finsupp.lean +++ b/Mathlib/Algebra/Order/Antidiag/Finsupp.lean @@ -39,7 +39,7 @@ variable [DecidableEq ι] [AddCommMonoid μ] [HasAntidiagonal μ] [DecidableEq /-- The finset of functions `ι →₀ μ` with support contained in `s` and sum equal to `n`. -/ 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 f g hfg ↦ Subtype.ext (congr_arg (⇑) hfg)⟩ + simpa using (mem_piAntidiag.1 f.2).2⟩, fun _ _ hfg ↦ Subtype.ext (congr_arg (⇑) hfg)⟩ @[simp] lemma mem_finsuppAntidiag : f ∈ finsuppAntidiag s n ↔ s.sum f = n ∧ f.support ⊆ s := by simp [finsuppAntidiag, ← DFunLike.coe_fn_eq, subset_iff] diff --git a/Mathlib/Algebra/Order/Antidiag/Pi.lean b/Mathlib/Algebra/Order/Antidiag/Pi.lean index fea1cd40e9b830..e61fa45890bab2 100644 --- a/Mathlib/Algebra/Order/Antidiag/Pi.lean +++ b/Mathlib/Algebra/Order/Antidiag/Pi.lean @@ -226,7 +226,7 @@ lemma nsmul_piAntidiag [DecidableEq (ι → ℕ)] (s : Finset ι) (m : ℕ) {n : lemma map_nsmul_piAntidiag (s : Finset ι) (m : ℕ) {n : ℕ} (hn : n ≠ 0) : (piAntidiag s m).map - ⟨(n • ·), fun f g h ↦ funext fun i ↦ mul_right_injective₀ hn (congr_fun h i)⟩ = + ⟨(n • ·), fun _ _ h ↦ funext fun i ↦ mul_right_injective₀ hn (congr_fun h i)⟩ = (piAntidiag s (n * m)).filter fun f : ι → ℕ ↦ ∀ i ∈ s, n ∣ f i := by classical rw [map_eq_image]; exact nsmul_piAntidiag _ _ hn @@ -237,7 +237,7 @@ lemma nsmul_piAntidiag_univ [Fintype ι] (m : ℕ) {n : ℕ} (hn : n ≠ 0) : lemma map_nsmul_piAntidiag_univ [Fintype ι] (m : ℕ) {n : ℕ} (hn : n ≠ 0) : (piAntidiag (univ : Finset ι) m).map - ⟨(n • ·), fun f g h ↦ funext fun i ↦ mul_right_injective₀ hn (congr_fun h i)⟩ = + ⟨(n • ·), fun _ _ h ↦ funext fun i ↦ mul_right_injective₀ hn (congr_fun h i)⟩ = (piAntidiag univ (n * m)).filter fun f : ι → ℕ ↦ ∀ i, n ∣ f i := by simpa using map_nsmul_piAntidiag (univ : Finset ι) m hn diff --git a/Mathlib/Algebra/Order/Antidiag/Prod.lean b/Mathlib/Algebra/Order/Antidiag/Prod.lean index 6f49ffaa10635d..b41df751f36635 100644 --- a/Mathlib/Algebra/Order/Antidiag/Prod.lean +++ b/Mathlib/Algebra/Order/Antidiag/Prod.lean @@ -181,7 +181,7 @@ def sigmaAntidiagonalEquivProd [AddMonoid A] [HasAntidiagonal A] : rintro ⟨n, ⟨k, l⟩, h⟩ rw [mem_antidiagonal] at h exact Sigma.subtype_ext h rfl - right_inv x := rfl + right_inv _ := rfl variable {A : Type*} [CanonicallyOrderedAddCommMonoid A] diff --git a/Mathlib/Algebra/Order/CauSeq/Basic.lean b/Mathlib/Algebra/Order/CauSeq/Basic.lean index b390f7b8dceaf2..380eb60f96e799 100644 --- a/Mathlib/Algebra/Order/CauSeq/Basic.lean +++ b/Mathlib/Algebra/Order/CauSeq/Basic.lean @@ -374,21 +374,21 @@ def LimZero {abv : β → α} (f : CauSeq β abv) : Prop := theorem add_limZero {f g : CauSeq β abv} (hf : LimZero f) (hg : LimZero g) : LimZero (f + g) | ε, ε0 => - (exists_forall_ge_and (hf _ <| half_pos ε0) (hg _ <| half_pos ε0)).imp fun i H j ij => by + (exists_forall_ge_and (hf _ <| half_pos ε0) (hg _ <| half_pos ε0)).imp fun _ H j ij => by let ⟨H₁, H₂⟩ := H _ ij simpa [add_halves ε] using lt_of_le_of_lt (abv_add abv _ _) (add_lt_add H₁ H₂) theorem mul_limZero_right (f : CauSeq β abv) {g} (hg : LimZero g) : LimZero (f * g) | ε, ε0 => let ⟨F, F0, hF⟩ := f.bounded' 0 - (hg _ <| div_pos ε0 F0).imp fun i H j ij => by + (hg _ <| div_pos ε0 F0).imp fun _ H j ij => by have := mul_lt_mul' (le_of_lt <| hF j) (H _ ij) (abv_nonneg abv _) F0 rwa [mul_comm F, div_mul_cancel₀ _ (ne_of_gt F0), ← abv_mul] at this theorem mul_limZero_left {f} (g : CauSeq β abv) (hg : LimZero f) : LimZero (f * g) | ε, ε0 => let ⟨G, G0, hG⟩ := g.bounded' 0 - (hg _ <| div_pos ε0 G0).imp fun i H j ij => by + (hg _ <| div_pos ε0 G0).imp fun _ H j ij => by have := mul_lt_mul'' (H _ ij) (hG j) (abv_nonneg abv _) (abv_nonneg abv _) rwa [div_mul_cancel₀ _ (ne_of_gt G0), ← abv_mul] at this @@ -430,7 +430,7 @@ theorem sub_equiv_sub {f1 f2 g1 g2 : CauSeq β abv} (hf : f1 ≈ f2) (hg : g1 theorem equiv_def₃ {f g : CauSeq β abv} (h : f ≈ g) {ε : α} (ε0 : 0 < ε) : ∃ i, ∀ j ≥ i, ∀ k ≥ j, abv (f k - g j) < ε := - (exists_forall_ge_and (h _ <| half_pos ε0) (f.cauchy₃ <| half_pos ε0)).imp fun i H j ij k jk => by + (exists_forall_ge_and (h _ <| half_pos ε0) (f.cauchy₃ <| half_pos ε0)).imp fun _ H j ij k jk => by let ⟨h₁, h₂⟩ := H _ ij have := lt_of_le_of_lt (abv_add abv (f j - g j) _) (add_lt_add h₁ (h₂ _ jk)) rwa [sub_add_sub_cancel', add_halves] at this @@ -749,14 +749,14 @@ theorem coe_inf (f g : CauSeq α abs) : ⇑(f ⊓ g) = (f : ℕ → α) ⊓ g := theorem sup_limZero {f g : CauSeq α abs} (hf : LimZero f) (hg : LimZero g) : LimZero (f ⊔ g) | ε, ε0 => - (exists_forall_ge_and (hf _ ε0) (hg _ ε0)).imp fun i H j ij => by + (exists_forall_ge_and (hf _ ε0) (hg _ ε0)).imp fun _ H j ij => by let ⟨H₁, H₂⟩ := H _ ij rw [abs_lt] at H₁ H₂ ⊢ exact ⟨lt_sup_iff.mpr (Or.inl H₁.1), sup_lt_iff.mpr ⟨H₁.2, H₂.2⟩⟩ theorem inf_limZero {f g : CauSeq α abs} (hf : LimZero f) (hg : LimZero g) : LimZero (f ⊓ g) | ε, ε0 => - (exists_forall_ge_and (hf _ ε0) (hg _ ε0)).imp fun i H j ij => by + (exists_forall_ge_and (hf _ ε0) (hg _ ε0)).imp fun _ H j ij => by let ⟨H₁, H₂⟩ := H _ ij rw [abs_lt] at H₁ H₂ ⊢ exact ⟨lt_inf_iff.mpr ⟨H₁.1, H₂.1⟩, inf_lt_iff.mpr (Or.inl H₁.2)⟩ diff --git a/Mathlib/Algebra/Order/CauSeq/Completion.lean b/Mathlib/Algebra/Order/CauSeq/Completion.lean index 1cf2efa956c830..ff8a280c51ac87 100644 --- a/Mathlib/Algebra/Order/CauSeq/Completion.lean +++ b/Mathlib/Algebra/Order/CauSeq/Completion.lean @@ -239,13 +239,13 @@ lemma ofRat_div (x y : β) : ofRat (x / y) = (ofRat x / ofRat y : Cauchy abv) := noncomputable instance Cauchy.divisionRing : DivisionRing (Cauchy abv) where exists_pair_ne := ⟨0, 1, zero_ne_one⟩ inv_zero := inv_zero - mul_inv_cancel x := CauSeq.Completion.mul_inv_cancel + mul_inv_cancel _ := CauSeq.Completion.mul_inv_cancel nnqsmul := (· • ·) qsmul := (· • ·) nnratCast_def q := by simp_rw [← ofRat_nnratCast, NNRat.cast_def, ofRat_div, ofRat_natCast] ratCast_def q := by rw [← ofRat_ratCast, Rat.cast_def, ofRat_div, ofRat_natCast, ofRat_intCast] - nnqsmul_def q x := Quotient.inductionOn x fun f ↦ congr_arg mk <| ext fun i ↦ NNRat.smul_def _ _ - qsmul_def q x := Quotient.inductionOn x fun f ↦ congr_arg mk <| ext fun i ↦ Rat.smul_def _ _ + nnqsmul_def _ x := Quotient.inductionOn x fun _ ↦ congr_arg mk <| ext fun _ ↦ NNRat.smul_def _ _ + qsmul_def _ x := Quotient.inductionOn x fun _ ↦ congr_arg mk <| ext fun _ ↦ Rat.smul_def _ _ /-- Show the first 10 items of a representative of this equivalence class of cauchy sequences. diff --git a/Mathlib/Algebra/Order/CompleteField.lean b/Mathlib/Algebra/Order/CompleteField.lean index 680ebceb3f631e..d4a66915b8a75b 100644 --- a/Mathlib/Algebra/Order/CompleteField.lean +++ b/Mathlib/Algebra/Order/CompleteField.lean @@ -202,7 +202,7 @@ theorem coe_lt_inducedMap_iff : (q : β) < inducedMap α β a ↔ (q : α) < a : exact mod_cast hq theorem lt_inducedMap_iff : b < inducedMap α β a ↔ ∃ q : ℚ, b < q ∧ (q : α) < a := - ⟨fun h => (exists_rat_btwn h).imp fun q => And.imp_right coe_lt_inducedMap_iff.1, + ⟨fun h => (exists_rat_btwn h).imp fun _ => And.imp_right coe_lt_inducedMap_iff.1, fun ⟨q, hbq, hqa⟩ => hbq.trans <| by rwa [coe_lt_inducedMap_iff]⟩ @[simp] diff --git a/Mathlib/Algebra/Order/Field/Canonical/Defs.lean b/Mathlib/Algebra/Order/Field/Canonical/Defs.lean index f09b170c98fabe..0242074ec46977 100644 --- a/Mathlib/Algebra/Order/Field/Canonical/Defs.lean +++ b/Mathlib/Algebra/Order/Field/Canonical/Defs.lean @@ -23,7 +23,7 @@ class CanonicallyLinearOrderedSemifield (α : Type*) extends CanonicallyOrderedC instance (priority := 100) CanonicallyLinearOrderedSemifield.toLinearOrderedCommGroupWithZero [CanonicallyLinearOrderedSemifield α] : LinearOrderedCommGroupWithZero α := { ‹CanonicallyLinearOrderedSemifield α› with - mul_le_mul_left := fun a b h c ↦ mul_le_mul_of_nonneg_left h <| zero_le _ } + mul_le_mul_left := fun _ _ h _ ↦ mul_le_mul_of_nonneg_left h <| zero_le _ } -- See note [lower instance priority] instance (priority := 100) CanonicallyLinearOrderedSemifield.toCanonicallyLinearOrderedAddCommMonoid diff --git a/Mathlib/Algebra/Order/Floor.lean b/Mathlib/Algebra/Order/Floor.lean index 09bdb68063e384..da812710841b2e 100644 --- a/Mathlib/Algebra/Order/Floor.lean +++ b/Mathlib/Algebra/Order/Floor.lean @@ -1584,7 +1584,7 @@ variable [LinearOrderedRing α] [FloorRing α] instance (priority := 100) FloorRing.toFloorSemiring : FloorSemiring α where floor a := ⌊a⌋.toNat ceil a := ⌈a⌉.toNat - floor_of_neg {a} ha := Int.toNat_of_nonpos (Int.floor_nonpos ha.le) + floor_of_neg {_} ha := Int.toNat_of_nonpos (Int.floor_nonpos ha.le) gc_floor {a n} ha := by rw [Int.le_toNat (Int.floor_nonneg.2 ha), Int.le_floor, Int.cast_natCast] gc_ceil a n := by rw [Int.toNat_le, Int.ceil_le, Int.cast_natCast] diff --git a/Mathlib/Algebra/Order/Group/Cone.lean b/Mathlib/Algebra/Order/Group/Cone.lean index 6d794594f08df4..5f110e86b0c0e7 100644 --- a/Mathlib/Algebra/Order/Group/Cone.lean +++ b/Mathlib/Algebra/Order/Group/Cone.lean @@ -117,4 +117,4 @@ def LinearOrderedCommGroup.mkOfCone LinearOrderedCommGroup G where __ := OrderedCommGroup.mkOfCone C le_total a b := by simpa using mem_or_inv_mem (b / a) - decidableLE a b := dec _ + decidableLE _ _ := dec _ diff --git a/Mathlib/Algebra/Order/Group/Defs.lean b/Mathlib/Algebra/Order/Group/Defs.lean index 53b53337c45d3d..7d7d5e71225f0a 100644 --- a/Mathlib/Algebra/Order/Group/Defs.lean +++ b/Mathlib/Algebra/Order/Group/Defs.lean @@ -54,7 +54,7 @@ instance OrderedCommGroup.to_covariantClass_left_le (α : Type u) [OrderedCommGr @[to_additive OrderedAddCommGroup.toOrderedCancelAddCommMonoid] instance (priority := 100) OrderedCommGroup.toOrderedCancelCommMonoid [OrderedCommGroup α] : OrderedCancelCommMonoid α := -{ ‹OrderedCommGroup α› with le_of_mul_le_mul_left := fun a b c ↦ le_of_mul_le_mul_left' } +{ ‹OrderedCommGroup α› with le_of_mul_le_mul_left := fun _ _ _ ↦ le_of_mul_le_mul_left' } example (α : Type u) [OrderedAddCommGroup α] : CovariantClass α α (swap (· + ·)) (· < ·) := IsRightCancelAdd.covariant_swap_add_lt_of_covariant_swap_add_le α diff --git a/Mathlib/Algebra/Order/GroupWithZero/Unbundled.lean b/Mathlib/Algebra/Order/GroupWithZero/Unbundled.lean index b238cd2ab171e0..fbec3165e23ef1 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Unbundled.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Unbundled.lean @@ -1048,7 +1048,7 @@ variable [PartialOrder M₀] {a b c d : M₀} @[simp] lemma pow_pos [ZeroLEOneClass M₀] [PosMulStrictMono M₀] (ha : 0 < a) : ∀ n, 0 < a ^ n | 0 => by nontriviality; rw [pow_zero]; exact zero_lt_one - | n + 1 => pow_succ a _ ▸ mul_pos (pow_pos ha _) ha + | _ + 1 => pow_succ a _ ▸ mul_pos (pow_pos ha _) ha lemma mul_self_lt_mul_self [PosMulStrictMono M₀] [MulPosMono M₀] (ha : 0 ≤ a) (hab : a < b) : a * a < b * b := mul_lt_mul' hab.le hab ha <| ha.trans_lt hab diff --git a/Mathlib/Algebra/Order/GroupWithZero/WithZero.lean b/Mathlib/Algebra/Order/GroupWithZero/WithZero.lean index f17648684e9226..d5b2da40325ae4 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/WithZero.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/WithZero.lean @@ -56,7 +56,7 @@ instance {α : Type*} [Mul α] [Preorder α] [CovariantClass α α (· * ·) (· simp only [zero_mul, le_refl] | ⟨(x : α), _⟩, 0, _, _ => by simp only [mul_zero, WithZero.zero_le] - | ⟨(x : α), hx⟩, (a : α), 0, h => + | ⟨(x : α), _⟩, (a : α), 0, h => (lt_irrefl 0 (lt_of_lt_of_le (WithZero.zero_lt_coe a) h)).elim | ⟨(x : α), hx⟩, (a : α), (b : α), h => by dsimp only @@ -72,7 +72,7 @@ instance {α : Type*} [Mul α] [Preorder α] [CovariantClass α α (swap (· * simp only [mul_zero, le_refl] | ⟨(x : α), _⟩, 0, _, _ => by simp only [zero_mul, WithZero.zero_le] - | ⟨(x : α), hx⟩, (a : α), 0, h => + | ⟨(x : α), _⟩, (a : α), 0, h => (lt_irrefl 0 (lt_of_lt_of_le (WithZero.zero_lt_coe a) h)).elim | ⟨(x : α), hx⟩, (a : α), (b : α), h => by dsimp only diff --git a/Mathlib/Algebra/Order/Hom/Basic.lean b/Mathlib/Algebra/Order/Hom/Basic.lean index b97b19b03d22d4..a90bc7fe9e004e 100644 --- a/Mathlib/Algebra/Order/Hom/Basic.lean +++ b/Mathlib/Algebra/Order/Hom/Basic.lean @@ -323,7 +323,7 @@ instance (priority := 100) RingSeminormClass.toNonnegHomClass [NonUnitalNonAssoc -- See note [lower instance priority] instance (priority := 100) MulRingSeminormClass.toRingSeminormClass [NonAssocRing α] [OrderedSemiring β] [MulRingSeminormClass F α β] : RingSeminormClass F α β := - { ‹MulRingSeminormClass F α β› with map_mul_le_mul := fun f a b => (map_mul _ _ _).le } + { ‹MulRingSeminormClass F α β› with map_mul_le_mul := fun _ _ _ => (map_mul _ _ _).le } -- See note [lower instance priority] instance (priority := 100) MulRingNormClass.toRingNormClass [NonAssocRing α] diff --git a/Mathlib/Algebra/Order/Monoid/Defs.lean b/Mathlib/Algebra/Order/Monoid/Defs.lean index 61e8c9e8a30d9c..c2b31a4a0ca967 100644 --- a/Mathlib/Algebra/Order/Monoid/Defs.lean +++ b/Mathlib/Algebra/Order/Monoid/Defs.lean @@ -77,7 +77,7 @@ theorem OrderedCancelCommMonoid.toContravariantClassRight : instance (priority := 100) OrderedCancelCommMonoid.toCancelCommMonoid : CancelCommMonoid α := { ‹OrderedCancelCommMonoid α› with mul_left_cancel := - fun a b c h => (le_of_mul_le_mul_left' h.le).antisymm <| le_of_mul_le_mul_left' h.ge } + fun _ _ _ h => (le_of_mul_le_mul_left' h.le).antisymm <| le_of_mul_le_mul_left' h.ge } end OrderedCancelCommMonoid diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean index f33502550e3da9..ca4ff6cabcb059 100644 --- a/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean @@ -1034,7 +1034,7 @@ to the appropriate `CovariantClass`. -/ (i.e. `c + a < c + b → a < b`) is a `left_cancel AddSemigroup`."] def Contravariant.toLeftCancelSemigroup [ContravariantClass α α (· * ·) (· ≤ ·)] : LeftCancelSemigroup α := - { ‹Semigroup α› with mul_left_cancel := fun a b c => mul_left_cancel'' } + { ‹Semigroup α› with mul_left_cancel := fun _ _ _ => mul_left_cancel'' } /- This is not instance, since we want to have an instance from `RightCancelSemigroup`s to the appropriate `CovariantClass`. -/ @@ -1045,7 +1045,7 @@ to the appropriate `CovariantClass`. -/ (`a + c < b + c → a < b`) is a `right_cancel AddSemigroup`."] def Contravariant.toRightCancelSemigroup [ContravariantClass α α (swap (· * ·)) (· ≤ ·)] : RightCancelSemigroup α := - { ‹Semigroup α› with mul_right_cancel := fun a b c => mul_right_cancel'' } + { ‹Semigroup α› with mul_right_cancel := fun _ _ _ => mul_right_cancel'' } end PartialOrder diff --git a/Mathlib/Algebra/Order/Ring/Basic.lean b/Mathlib/Algebra/Order/Ring/Basic.lean index 5e64f73cc40ea3..0dac73109c9d0a 100644 --- a/Mathlib/Algebra/Order/Ring/Basic.lean +++ b/Mathlib/Algebra/Order/Ring/Basic.lean @@ -99,7 +99,7 @@ abbrev OrderedRing.toStrictOrderedRing (α : Type*) [OrderedRing α] [NoZeroDivisors α] [Nontrivial α] : StrictOrderedRing α where __ := ‹OrderedRing α› __ := ‹NoZeroDivisors α› - mul_pos a b ap bp := (mul_nonneg ap.le bp.le).lt_of_ne' (mul_ne_zero ap.ne' bp.ne') + mul_pos _ _ ap bp := (mul_nonneg ap.le bp.le).lt_of_ne' (mul_ne_zero ap.ne' bp.ne') section StrictOrderedSemiring diff --git a/Mathlib/Algebra/Order/Ring/Canonical.lean b/Mathlib/Algebra/Order/Ring/Canonical.lean index 1f64f689d1e795..95f47cbf6819ff 100644 --- a/Mathlib/Algebra/Order/Ring/Canonical.lean +++ b/Mathlib/Algebra/Order/Ring/Canonical.lean @@ -65,8 +65,8 @@ instance (priority := 100) toOrderedCommMonoid : OrderedCommMonoid α where instance (priority := 100) toOrderedCommSemiring : OrderedCommSemiring α := { ‹CanonicallyOrderedCommSemiring α› with zero_le_one := zero_le _, - mul_le_mul_of_nonneg_left := fun a b c h _ => mul_le_mul_left' h _, - mul_le_mul_of_nonneg_right := fun a b c h _ => mul_le_mul_right' h _ } + mul_le_mul_of_nonneg_left := fun _ _ _ h _ => mul_le_mul_left' h _, + mul_le_mul_of_nonneg_right := fun _ _ _ h _ => mul_le_mul_right' h _ } @[simp] protected theorem mul_pos : 0 < a * b ↔ 0 < a ∧ 0 < b := by diff --git a/Mathlib/Algebra/Order/Ring/Cone.lean b/Mathlib/Algebra/Order/Ring/Cone.lean index 71c21076f00933..097bfc9afe3ca9 100644 --- a/Mathlib/Algebra/Order/Ring/Cone.lean +++ b/Mathlib/Algebra/Order/Ring/Cone.lean @@ -83,4 +83,4 @@ due to non-customisable fields: `lt`, `decidableLT`, `decidableEq`, `compare`. - __ := OrderedRing.mkOfCone C __ := OrderedRing.toStrictOrderedRing R le_total a b := by simpa using mem_or_neg_mem (b - a) - decidableLE a b := dec _ + decidableLE _ _ := dec _ diff --git a/Mathlib/Algebra/Order/Ring/Rat.lean b/Mathlib/Algebra/Order/Ring/Rat.lean index 88cca6d79229f7..12e6c49ad09a54 100644 --- a/Mathlib/Algebra/Order/Ring/Rat.lean +++ b/Mathlib/Algebra/Order/Ring/Rat.lean @@ -31,8 +31,8 @@ instance instLinearOrderedCommRing : LinearOrderedCommRing ℚ where __ := Rat.linearOrder __ := Rat.commRing zero_le_one := by decide - add_le_add_left := fun a b ab c => Rat.add_le_add_left.2 ab - mul_pos a b ha hb := (Rat.mul_nonneg ha.le hb.le).lt_of_ne' (mul_ne_zero ha.ne' hb.ne') + add_le_add_left := fun _ _ ab _ => Rat.add_le_add_left.2 ab + mul_pos _ _ ha hb := (Rat.mul_nonneg ha.le hb.le).lt_of_ne' (mul_ne_zero ha.ne' hb.ne') -- Extra instances to short-circuit type class resolution instance : LinearOrderedRing ℚ := by infer_instance diff --git a/Mathlib/Algebra/Polynomial/EraseLead.lean b/Mathlib/Algebra/Polynomial/EraseLead.lean index 7f0f5dd10d6e49..9f38cdcb5190bb 100644 --- a/Mathlib/Algebra/Polynomial/EraseLead.lean +++ b/Mathlib/Algebra/Polynomial/EraseLead.lean @@ -321,14 +321,14 @@ theorem map_natDegree_eq_sub {S F : Type*} [Semiring S] (φ_mon : ∀ n c, c ≠ 0 → (φ (monomial n c)).natDegree = n - k) : (φ p).natDegree = p.natDegree - k := mono_map_natDegree_eq k (fun j => j - k) (by simp_all) - (@fun m n h => (tsub_lt_tsub_iff_right h).mpr) + (@fun _ _ h => (tsub_lt_tsub_iff_right h).mpr) (φ_k _) φ_mon theorem map_natDegree_eq_natDegree {S F : Type*} [Semiring S] [FunLike F R[X] S[X]] [AddMonoidHomClass F R[X] S[X]] {φ : F} (p) (φ_mon_nat : ∀ n c, c ≠ 0 → (φ (monomial n c)).natDegree = n) : (φ p).natDegree = p.natDegree := - (map_natDegree_eq_sub (fun f h => (Nat.not_lt_zero _ h).elim) (by simpa)).trans + (map_natDegree_eq_sub (fun _ h => (Nat.not_lt_zero _ h).elim) (by simpa)).trans p.natDegree.sub_zero theorem card_support_eq' {n : ℕ} (k : Fin n → ℕ) (x : Fin n → R) (hk : Function.Injective k) @@ -347,7 +347,7 @@ theorem card_support_eq' {n : ℕ} (k : Fin n → ℕ) (x : Fin n → R) (hk : F theorem card_support_eq {n : ℕ} : f.support.card = n ↔ - ∃ (k : Fin n → ℕ) (x : Fin n → R) (hk : StrictMono k) (hx : ∀ i, x i ≠ 0), + ∃ (k : Fin n → ℕ) (x : Fin n → R) (_ : StrictMono k) (_ : ∀ i, x i ≠ 0), f = ∑ i, C (x i) * X ^ k i := by refine ⟨?_, fun ⟨k, x, hk, hx, hf⟩ => hf.symm ▸ card_support_eq' k x hk.injective hx⟩ induction n generalizing f with @@ -392,7 +392,7 @@ theorem card_support_eq {n : ℕ} : all_goals exact H theorem card_support_eq_one : f.support.card = 1 ↔ - ∃ (k : ℕ) (x : R) (hx : x ≠ 0), f = C x * X ^ k := by + ∃ (k : ℕ) (x : R) (_ : x ≠ 0), f = C x * X ^ k := by refine ⟨fun h => ?_, ?_⟩ · obtain ⟨k, x, _, hx, rfl⟩ := card_support_eq.mp h exact ⟨k 0, x 0, hx 0, Fin.sum_univ_one _⟩ @@ -401,7 +401,7 @@ theorem card_support_eq_one : f.support.card = 1 ↔ theorem card_support_eq_two : f.support.card = 2 ↔ - ∃ (k m : ℕ) (hkm : k < m) (x y : R) (hx : x ≠ 0) (hy : y ≠ 0), + ∃ (k m : ℕ) (_ : k < m) (x y : R) (_ : x ≠ 0) (_ : y ≠ 0), f = C x * X ^ k + C y * X ^ m := by refine ⟨fun h => ?_, ?_⟩ · obtain ⟨k, x, hk, hx, rfl⟩ := card_support_eq.mp h @@ -413,7 +413,7 @@ theorem card_support_eq_two : theorem card_support_eq_three : f.support.card = 3 ↔ - ∃ (k m n : ℕ) (hkm : k < m) (hmn : m < n) (x y z : R) (hx : x ≠ 0) (hy : y ≠ 0) (hz : z ≠ 0), + ∃ (k m n : ℕ) (_ : k < m) (_ : m < n) (x y z : R) (_ : x ≠ 0) (_ : y ≠ 0) (_ : z ≠ 0), f = C x * X ^ k + C y * X ^ m + C z * X ^ n := by refine ⟨fun h => ?_, ?_⟩ · obtain ⟨k, x, hk, hx, rfl⟩ := card_support_eq.mp h diff --git a/Mathlib/Algebra/Polynomial/FieldDivision.lean b/Mathlib/Algebra/Polynomial/FieldDivision.lean index 06134da2f5675c..6a82a21dcee8ff 100644 --- a/Mathlib/Algebra/Polynomial/FieldDivision.lean +++ b/Mathlib/Algebra/Polynomial/FieldDivision.lean @@ -323,8 +323,8 @@ instance instEuclideanDomain : EuclideanDomain R[X] := r := _ r_wellFounded := degree_lt_wf quotient_mul_add_remainder_eq := quotient_mul_add_remainder_eq_aux - remainder_lt := fun p q hq => remainder_lt_aux _ hq - mul_left_not_lt := fun p q hq => not_lt_of_ge (degree_le_mul_left _ hq) } + remainder_lt := fun _ _ hq => remainder_lt_aux _ hq + mul_left_not_lt := fun _ _ hq => not_lt_of_ge (degree_le_mul_left _ hq) } 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 diff --git a/Mathlib/Algebra/Polynomial/GroupRingAction.lean b/Mathlib/Algebra/Polynomial/GroupRingAction.lean index 586acacc30c033..a14a7d6e696b80 100644 --- a/Mathlib/Algebra/Polynomial/GroupRingAction.lean +++ b/Mathlib/Algebra/Polynomial/GroupRingAction.lean @@ -128,9 +128,9 @@ protected noncomputable def polynomial (g : P →+*[M] Q) : P[X] →+*[M] Q[X] w smul_mul', smul_C, smul_pow', smul_X, coe_fn_coe] -- Porting note: added `.toRingHom` map_zero' := Polynomial.map_zero g.toRingHom - map_add' p q := Polynomial.map_add g.toRingHom + map_add' _ _ := Polynomial.map_add g.toRingHom map_one' := Polynomial.map_one g.toRingHom - map_mul' p q := Polynomial.map_mul g.toRingHom + map_mul' _ _ := Polynomial.map_mul g.toRingHom @[simp] theorem coe_polynomial (g : P →+*[M] Q) : (g.polynomial : P[X] → Q[X]) = map g := rfl diff --git a/Mathlib/Algebra/Polynomial/Laurent.lean b/Mathlib/Algebra/Polynomial/Laurent.lean index c5523266588fe6..08c3c4ff40db24 100644 --- a/Mathlib/Algebra/Polynomial/Laurent.lean +++ b/Mathlib/Algebra/Polynomial/Laurent.lean @@ -278,7 +278,7 @@ protected theorem induction_on' {M : R[T;T⁻¹] → Prop} (p : R[T;T⁻¹]) exact (mul_one _).symm theorem commute_T (n : ℤ) (f : R[T;T⁻¹]) : Commute (T n) f := - f.induction_on' (fun p q Tp Tq => Commute.add_right Tp Tq) fun m a => + f.induction_on' (fun _ _ Tp Tq => Commute.add_right Tp Tq) fun m a => show T n * _ = _ by rw [T, T, ← single_eq_C, single_mul_single, single_mul_single, single_mul_single] simp [add_comm] @@ -492,7 +492,7 @@ variable [CommSemiring R] instance algebraPolynomial (R : Type*) [CommSemiring R] : Algebra R[X] R[T;T⁻¹] := { Polynomial.toLaurent with commutes' := fun f l => by simp [mul_comm] - smul_def' := fun f l => rfl } + smul_def' := fun _ _ => rfl } theorem algebraMap_X_pow (n : ℕ) : algebraMap R[X] R[T;T⁻¹] (X ^ n) = T n := Polynomial.toLaurent_X_pow n diff --git a/Mathlib/Algebra/Polynomial/Mirror.lean b/Mathlib/Algebra/Polynomial/Mirror.lean index 542e5670d10178..def8942a33b30c 100644 --- a/Mathlib/Algebra/Polynomial/Mirror.lean +++ b/Mathlib/Algebra/Polynomial/Mirror.lean @@ -139,7 +139,7 @@ theorem mirror_leadingCoeff : p.mirror.leadingCoeff = p.trailingCoeff := by rw [← p.mirror_mirror, mirror_trailingCoeff, p.mirror_mirror] theorem coeff_mul_mirror : - (p * p.mirror).coeff (p.natDegree + p.natTrailingDegree) = p.sum fun n => (· ^ 2) := by + (p * p.mirror).coeff (p.natDegree + p.natTrailingDegree) = p.sum fun _ => (· ^ 2) := by rw [coeff_mul, Finset.Nat.sum_antidiagonal_eq_sum_range_succ_mk] refine (Finset.sum_congr rfl fun n hn => ?_).trans diff --git a/Mathlib/Algebra/Polynomial/Module/Basic.lean b/Mathlib/Algebra/Polynomial/Module/Basic.lean index 43595606fd85c4..9a18a3951bc2ea 100644 --- a/Mathlib/Algebra/Polynomial/Module/Basic.lean +++ b/Mathlib/Algebra/Polynomial/Module/Basic.lean @@ -250,7 +250,7 @@ theorem map_smul (f : M →ₗ[R] M') (p : R[X]) (q : PolynomialModule R M) : @[simps! (config := .lemmasOnly)] def eval (r : R) : PolynomialModule R M →ₗ[R] M where toFun p := p.sum fun i m => r ^ i • m - map_add' x y := Finsupp.sum_add_index' (fun _ => smul_zero _) fun _ _ _ => smul_add _ _ _ + map_add' _ _ := Finsupp.sum_add_index' (fun _ => smul_zero _) fun _ _ _ => smul_add _ _ _ map_smul' s m := by refine (Finsupp.sum_smul_index' ?_).trans ?_ · exact fun i => smul_zero _ diff --git a/Mathlib/Algebra/Polynomial/RingDivision.lean b/Mathlib/Algebra/Polynomial/RingDivision.lean index 87a240f2594150..2cd957ced397df 100644 --- a/Mathlib/Algebra/Polynomial/RingDivision.lean +++ b/Mathlib/Algebra/Polynomial/RingDivision.lean @@ -741,6 +741,7 @@ theorem rootMultiplicity_mul {p q : R[X]} {x : R} (hpq : p * q ≠ 0) : multiplicity.mul' (prime_X_sub_C x)] open Multiset in +set_option linter.unusedVariables false in theorem exists_multiset_roots [DecidableEq R] : ∀ {p : R[X]} (_ : p ≠ 0), ∃ s : Multiset R, (Multiset.card s : WithBot ℕ) ≤ degree p ∧ ∀ a, s.count a = rootMultiplicity a p @@ -751,6 +752,11 @@ theorem exists_multiset_roots [DecidableEq R] : have hpd : 0 < degree p := degree_pos_of_root hp hx have hd0 : p /ₘ (X - C x) ≠ 0 := fun h => by rw [← mul_divByMonic_eq_iff_isRoot.2 hx, h, mul_zero] at hp; exact hp rfl + #adaptation_note + /-- + Since https://github.com/leanprover/lean4/pull/5338, this is considered unused, + because it is only used in the decreasing_by clause. + -/ have wf : degree (p /ₘ (X - C x)) < degree p := degree_divByMonic_lt _ (monic_X_sub_C x) hp ((degree_X_sub_C x).symm ▸ by decide) let ⟨t, htd, htr⟩ := @exists_multiset_roots _ (p /ₘ (X - C x)) hd0 diff --git a/Mathlib/Algebra/Polynomial/Roots.lean b/Mathlib/Algebra/Polynomial/Roots.lean index 59f7f94c789936..2c831cb0552f51 100644 --- a/Mathlib/Algebra/Polynomial/Roots.lean +++ b/Mathlib/Algebra/Polynomial/Roots.lean @@ -498,7 +498,7 @@ theorem bUnion_roots_finite {R S : Type*} [Semiring R] [CommRing S] [IsDomain S] · exact Set.image_subset_iff.2 fun f hf i _ => hf.2 i · refine fun x hx y hy hxy => (ext_iff_natDegree_le hx.1 hy.1).2 fun i hi => ?_ exact id congr_fun hxy ⟨i, Nat.lt_succ_of_le hi⟩) - fun i _ => Finset.finite_toSet _ + fun _ _ => Finset.finite_toSet _ theorem mem_rootSet' {p : T[X]} {S : Type*} [CommRing S] [IsDomain S] [Algebra T S] {a : S} : a ∈ p.rootSet S ↔ p.map (algebraMap T S) ≠ 0 ∧ aeval a p = 0 := by diff --git a/Mathlib/Algebra/Polynomial/Splits.lean b/Mathlib/Algebra/Polynomial/Splits.lean index 3b0f053ebb0ea7..d20613df7c738e 100644 --- a/Mathlib/Algebra/Polynomial/Splits.lean +++ b/Mathlib/Algebra/Polynomial/Splits.lean @@ -370,7 +370,7 @@ theorem splits_of_exists_multiset {f : K[X]} {s : Multiset L} theorem splits_of_splits_id {f : K[X]} : Splits (RingHom.id K) f → Splits i f := UniqueFactorizationMonoid.induction_on_prime f (fun _ => splits_zero _) (fun _ hu _ => splits_of_degree_le_one _ ((isUnit_iff_degree_eq_zero.1 hu).symm ▸ by decide)) - fun a p ha0 hp ih hfi => + fun _ p ha0 hp ih hfi => splits_mul _ (splits_of_degree_eq_one _ ((splits_of_splits_mul _ (mul_ne_zero hp.1 ha0) hfi).1.def.resolve_left hp.1 hp.irreducible diff --git a/Mathlib/Algebra/Polynomial/Taylor.lean b/Mathlib/Algebra/Polynomial/Taylor.lean index 4a89d16c0bea71..418f3fbd7124f5 100644 --- a/Mathlib/Algebra/Polynomial/Taylor.lean +++ b/Mathlib/Algebra/Polynomial/Taylor.lean @@ -32,7 +32,7 @@ variable {R : Type*} [Semiring R] (r : R) (f : R[X]) /-- The Taylor expansion of a polynomial `f` at `r`. -/ def taylor (r : R) : R[X] →ₗ[R] R[X] where toFun f := f.comp (X + C r) - map_add' f g := add_comp + map_add' _ _ := add_comp map_smul' c f := by simp only [smul_eq_C_mul, C_mul_comp, RingHom.id_apply] theorem taylor_apply : taylor r f = f.comp (X + C r) := diff --git a/Mathlib/Algebra/Quandle.lean b/Mathlib/Algebra/Quandle.lean index f037884dabe103..d02c6b1972aa11 100644 --- a/Mathlib/Algebra/Quandle.lean +++ b/Mathlib/Algebra/Quandle.lean @@ -599,11 +599,11 @@ def EnvelGroup (R : Type*) [Rack R] := -- TODO: is there a non-invasive way of defining the instance directly? instance (R : Type*) [Rack R] : DivInvMonoid (EnvelGroup R) where mul a b := - Quotient.liftOn₂ a b (fun a b => ⟦PreEnvelGroup.mul a b⟧) fun a b a' b' ⟨ha⟩ ⟨hb⟩ => + Quotient.liftOn₂ a b (fun a b => ⟦PreEnvelGroup.mul a b⟧) fun _ _ _ _ ⟨ha⟩ ⟨hb⟩ => Quotient.sound (PreEnvelGroupRel'.congr_mul ha hb).rel one := ⟦unit⟧ inv a := - Quotient.liftOn a (fun a => ⟦PreEnvelGroup.inv a⟧) fun a a' ⟨ha⟩ => + Quotient.liftOn a (fun a => ⟦PreEnvelGroup.inv a⟧) fun _ _ ⟨ha⟩ => Quotient.sound (PreEnvelGroupRel'.congr_inv ha).rel mul_assoc a b c := Quotient.inductionOn₃ a b c fun a b c => Quotient.sound (PreEnvelGroupRel'.assoc a b c).rel @@ -643,9 +643,9 @@ open PreEnvelGroupRel' theorem well_def {R : Type*} [Rack R] {G : Type*} [Group G] (f : R →◃ Quandle.Conj G) : ∀ {a b : PreEnvelGroup R}, PreEnvelGroupRel' R a b → toEnvelGroup.mapAux f a = toEnvelGroup.mapAux f b - | a, _, PreEnvelGroupRel'.refl => rfl - | a, b, PreEnvelGroupRel'.symm h => (well_def f h).symm - | a, b, PreEnvelGroupRel'.trans hac hcb => Eq.trans (well_def f hac) (well_def f hcb) + | _, _, PreEnvelGroupRel'.refl => rfl + | _, _, PreEnvelGroupRel'.symm h => (well_def f h).symm + | _, _, PreEnvelGroupRel'.trans hac hcb => Eq.trans (well_def f hac) (well_def f hcb) | _, _, PreEnvelGroupRel'.congr_mul ha hb => by simp [toEnvelGroup.mapAux, well_def f ha, well_def f hb] | _, _, congr_inv ha => by simp [toEnvelGroup.mapAux, well_def f ha] @@ -664,7 +664,7 @@ def toEnvelGroup.map {R : Type*} [Rack R] {G : Type*} [Group G] : (R →◃ Quandle.Conj G) ≃ (EnvelGroup R →* G) where toFun f := { toFun := fun x => - Quotient.liftOn x (toEnvelGroup.mapAux f) fun a b ⟨hab⟩ => + Quotient.liftOn x (toEnvelGroup.mapAux f) fun _ _ ⟨hab⟩ => toEnvelGroup.mapAux.well_def f hab map_one' := by change Quotient.liftOn ⟦Rack.PreEnvelGroup.unit⟧ (toEnvelGroup.mapAux f) _ = 1 diff --git a/Mathlib/Algebra/Ring/BooleanRing.lean b/Mathlib/Algebra/Ring/BooleanRing.lean index f04b26d3b23f6b..985d2359dfa85d 100644 --- a/Mathlib/Algebra/Ring/BooleanRing.lean +++ b/Mathlib/Algebra/Ring/BooleanRing.lean @@ -534,7 +534,7 @@ instance : BooleanRing Bool where left_distrib := and_xor_distrib_left right_distrib := and_xor_distrib_right mul_self := Bool.and_self - zero_mul a := rfl + zero_mul _ := rfl mul_zero a := by cases a <;> rfl nsmul := nsmulRec zsmul := zsmulRec diff --git a/Mathlib/Algebra/Ring/Hom/Defs.lean b/Mathlib/Algebra/Ring/Hom/Defs.lean index 86672a2bb1c985..85b96d8538cfb7 100644 --- a/Mathlib/Algebra/Ring/Hom/Defs.lean +++ b/Mathlib/Algebra/Ring/Hom/Defs.lean @@ -258,7 +258,7 @@ instance : MonoidWithZero (α →ₙ+* α) where mul := comp mul_one := comp_id one_mul := id_comp - mul_assoc f g h := comp_assoc _ _ _ + mul_assoc _ _ _ := comp_assoc _ _ _ zero := 0 mul_zero := comp_zero zero_mul := zero_comp @@ -595,9 +595,9 @@ lemma mul_def (f g : α →+* α) : f * g = f.comp g := rfl instance instMonoid : Monoid (α →+* α) where mul_one := comp_id one_mul := id_comp - mul_assoc f g h := comp_assoc _ _ _ + mul_assoc _ _ _ := comp_assoc _ _ _ npow n f := (npowRec n f).copy f^[n] <| by induction n <;> simp [npowRec, *] - npow_succ n f := DFunLike.coe_injective <| Function.iterate_succ _ _ + npow_succ _ _ := DFunLike.coe_injective <| Function.iterate_succ _ _ @[simp, norm_cast] lemma coe_pow (f : α →+* α) (n : ℕ) : ⇑(f ^ n) = f^[n] := rfl diff --git a/Mathlib/Algebra/Ring/Prod.lean b/Mathlib/Algebra/Ring/Prod.lean index 0f8d3362f0ae83..2883cf4e33ea0f 100644 --- a/Mathlib/Algebra/Ring/Prod.lean +++ b/Mathlib/Algebra/Ring/Prod.lean @@ -314,7 +314,7 @@ def prodZeroRing : R ≃+* R × S where invFun := Prod.fst map_add' := by simp map_mul' := by simp - left_inv x := rfl + left_inv _ := rfl right_inv x := by cases x; simp [eq_iff_true_of_subsingleton] /-- A ring `R` is isomorphic to `S × R` when `S` is the zero ring -/ @@ -324,7 +324,7 @@ def zeroRingProd : R ≃+* S × R where invFun := Prod.snd map_add' := by simp map_mul' := by simp - left_inv x := rfl + left_inv _ := rfl right_inv x := by cases x; simp [eq_iff_true_of_subsingleton] end RingEquiv diff --git a/Mathlib/Algebra/Ring/Subring/Basic.lean b/Mathlib/Algebra/Ring/Subring/Basic.lean index 4d2d0317d2fcfb..9de90d6c1a621a 100644 --- a/Mathlib/Algebra/Ring/Subring/Basic.lean +++ b/Mathlib/Algebra/Ring/Subring/Basic.lean @@ -662,15 +662,15 @@ variable {K : Type u} [DivisionRing K] instance instField : Field (center K) where inv a := ⟨a⁻¹, Set.inv_mem_center a.prop⟩ - mul_inv_cancel a ha := Subtype.ext <| mul_inv_cancel₀ <| Subtype.coe_injective.ne ha + mul_inv_cancel _ ha := Subtype.ext <| mul_inv_cancel₀ <| Subtype.coe_injective.ne ha div a b := ⟨a / b, Set.div_mem_center a.prop b.prop⟩ - div_eq_mul_inv a b := Subtype.ext <| div_eq_mul_inv _ _ + div_eq_mul_inv _ _ := Subtype.ext <| div_eq_mul_inv _ _ inv_zero := Subtype.ext inv_zero -- TODO: use a nicer defeq nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl qsmul := _ - qsmul_def := fun q x => rfl + qsmul_def := fun _ _ => rfl @[simp] theorem center.coe_inv (a : center K) : ((a⁻¹ : center K) : K) = (a : K)⁻¹ := @@ -796,15 +796,15 @@ theorem closure_induction₂ {s : Set R} {p : R → R → Prop} {a b : R} (ha : theorem mem_closure_iff {s : Set R} {x} : x ∈ closure s ↔ x ∈ AddSubgroup.closure (Submonoid.closure s : Set R) := ⟨fun h => - closure_induction h (fun x hx => AddSubgroup.subset_closure <| Submonoid.subset_closure hx) + closure_induction h (fun _ hx => AddSubgroup.subset_closure <| Submonoid.subset_closure hx) (AddSubgroup.zero_mem _) (AddSubgroup.subset_closure (Submonoid.one_mem (Submonoid.closure s))) - (fun x y hx hy => AddSubgroup.add_mem _ hx hy) (fun x hx => AddSubgroup.neg_mem _ hx) - fun x y hx hy => + (fun _ _ hx hy => AddSubgroup.add_mem _ hx hy) (fun _ hx => AddSubgroup.neg_mem _ hx) + fun x _ hx hy => AddSubgroup.closure_induction hy (fun q hq => AddSubgroup.closure_induction hx - (fun p hp => AddSubgroup.subset_closure ((Submonoid.closure s).mul_mem hp hq)) + (fun _ hp => AddSubgroup.subset_closure ((Submonoid.closure s).mul_mem hp hq)) (by rw [zero_mul q]; apply AddSubgroup.zero_mem _) (fun p₁ p₂ ihp₁ ihp₂ => by rw [add_mul p₁ p₂ q]; apply AddSubgroup.add_mem _ ihp₁ ihp₂) fun x hx => by @@ -817,10 +817,10 @@ theorem mem_closure_iff {s : Set R} {x} : rw [f]; apply AddSubgroup.neg_mem _ hz, fun h => AddSubgroup.closure_induction (p := (· ∈ closure s)) h - (fun x hx => - Submonoid.closure_induction hx (fun x hx => subset_closure hx) (one_mem _) fun x y hx hy => + (fun _ hx => + Submonoid.closure_induction hx (fun _ hx => subset_closure hx) (one_mem _) fun _ _ hx hy => mul_mem hx hy) - (zero_mem _) (fun x y hx hy => add_mem hx hy) fun x hx => neg_mem hx⟩ + (zero_mem _) (fun _ _ hx hy => add_mem hx hy) fun _ hx => neg_mem hx⟩ /-- If all elements of `s : Set A` commute pairwise, then `closure s` is a commutative ring. -/ def closureCommRingOfComm {s : Set R} (hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a) : @@ -851,7 +851,7 @@ theorem exists_list_of_mem_closure {s : Set R} {x : R} (h : x ∈ closure s) : ⟨[], by simp⟩ (fun x y ⟨l, hl1, hl2⟩ ⟨m, hm1, hm2⟩ => ⟨l ++ m, fun t ht => (List.mem_append.1 ht).elim (hl1 t) (hm1 t), by simp [hl2, hm2]⟩) - fun x ⟨L, hL⟩ => + fun _ ⟨L, hL⟩ => ⟨L.map (List.cons (-1)), List.forall_mem_map.2 fun j hj => List.forall_mem_cons.2 ⟨Or.inr rfl, hL.1 j hj⟩, hL.2 ▸ diff --git a/Mathlib/Algebra/RingQuot.lean b/Mathlib/Algebra/RingQuot.lean index 1da65c2031d8e8..b524909addd9a2 100644 --- a/Mathlib/Algebra/RingQuot.lean +++ b/Mathlib/Algebra/RingQuot.lean @@ -440,7 +440,7 @@ factors uniquely through a morphism `RingQuot r →+* T`. irreducible_def lift {r : R → R → Prop} : { f : R →+* T // ∀ ⦃x y⦄, r x y → f x = f y } ≃ (RingQuot r →+* T) := { toFun := fun f ↦ preLift f.prop - invFun := fun F ↦ ⟨F.comp (mkRingHom r), fun x y h ↦ congr_arg F (mkRingHom_rel h)⟩ + invFun := fun F ↦ ⟨F.comp (mkRingHom r), fun _ _ h ↦ congr_arg F (mkRingHom_rel h)⟩ left_inv := fun f ↦ by ext simp only [preLift_def, mkRingHom_def, RingHom.coe_comp, RingHom.coe_mk, MonoidHom.coe_mk, @@ -464,7 +464,7 @@ theorem lift_unique (f : R →+* T) {r : R → R → Prop} (w : ∀ ⦃x y⦄, r simp [h] theorem eq_lift_comp_mkRingHom {r : R → R → Prop} (f : RingQuot r →+* T) : - f = lift ⟨f.comp (mkRingHom r), fun x y h ↦ congr_arg f (mkRingHom_rel h)⟩ := by + f = lift ⟨f.comp (mkRingHom r), fun _ _ h ↦ congr_arg f (mkRingHom_rel h)⟩ := by conv_lhs => rw [← lift.apply_symm_apply f] rw [lift_def] rfl @@ -619,7 +619,7 @@ theorem liftAlgHom_unique (f : A →ₐ[S] B) {s : A → A → Prop} (w : ∀ simp [h] theorem eq_liftAlgHom_comp_mkAlgHom {s : A → A → Prop} (f : RingQuot s →ₐ[S] B) : - f = liftAlgHom S ⟨f.comp (mkAlgHom S s), fun x y h ↦ congr_arg f (mkAlgHom_rel S h)⟩ := by + f = liftAlgHom S ⟨f.comp (mkAlgHom S s), fun _ _ h ↦ congr_arg f (mkAlgHom_rel S h)⟩ := by conv_lhs => rw [← (liftAlgHom S).apply_symm_apply f] rw [liftAlgHom] rfl diff --git a/Mathlib/Algebra/Star/CentroidHom.lean b/Mathlib/Algebra/Star/CentroidHom.lean index 219cabaedcbfd1..8e07bcb8be477c 100644 --- a/Mathlib/Algebra/Star/CentroidHom.lean +++ b/Mathlib/Algebra/Star/CentroidHom.lean @@ -43,7 +43,7 @@ instance : Star (CentroidHom α) where instance instStarAddMonoid : StarAddMonoid (CentroidHom α) where star_involutive f := ext (fun _ => by rw [star_apply, star_apply, star_star, star_star]) - star_add f g := ext fun _ => star_add _ _ + star_add _ _ := ext fun _ => star_add _ _ instance : Star (Subsemiring.center (CentroidHom α)) where star f := ⟨star (f : CentroidHom α), Subsemiring.mem_center_iff.mpr (fun g => ext (fun a => diff --git a/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean b/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean index 61e7ac629195fc..9534d0d547a626 100644 --- a/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean +++ b/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean @@ -556,8 +556,8 @@ variable [IsScalarTower R A A] [SMulCommClass R A A] theorem star_adjoin_comm (s : Set A) : star (NonUnitalAlgebra.adjoin R s) = NonUnitalAlgebra.adjoin R (star s) := have this : - ∀ t : Set A, NonUnitalAlgebra.adjoin R (star t) ≤ star (NonUnitalAlgebra.adjoin R t) := fun t => - NonUnitalAlgebra.adjoin_le fun x hx => NonUnitalAlgebra.subset_adjoin R hx + ∀ 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))) (this s) diff --git a/Mathlib/Algebra/Star/Subalgebra.lean b/Mathlib/Algebra/Star/Subalgebra.lean index 7d0b23cd8f0432..bdcd995bb0c5f5 100644 --- a/Mathlib/Algebra/Star/Subalgebra.lean +++ b/Mathlib/Algebra/Star/Subalgebra.lean @@ -329,8 +329,8 @@ variable (R) /-- 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 t => - Algebra.adjoin_le fun x hx => Algebra.subset_adjoin hx + have this : ∀ 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) variable {R} diff --git a/Mathlib/AlgebraicGeometry/Cover/Open.lean b/Mathlib/AlgebraicGeometry/Cover/Open.lean index b49a2ae091e066..d24109a03e4e46 100644 --- a/Mathlib/AlgebraicGeometry/Cover/Open.lean +++ b/Mathlib/AlgebraicGeometry/Cover/Open.lean @@ -109,7 +109,7 @@ def OpenCover.bind (f : ∀ x : 𝒰.J, OpenCover (𝒰.obj x)) : OpenCover X wh rw [hz, hy] -- Porting note: weirdly, even though no input is needed, `inferInstance` does not work -- `PresheafedSpace.IsOpenImmersion.comp` is marked as `instance` - IsOpen x := PresheafedSpace.IsOpenImmersion.comp _ _ + IsOpen _ := PresheafedSpace.IsOpenImmersion.comp _ _ /-- An isomorphism `X ⟶ Y` is an open cover of `Y`. -/ @[simps J obj map] @@ -168,7 +168,7 @@ def OpenCover.pullbackCover {X W : Scheme.{u}} (𝒰 : X.OpenCover) (f : W ⟶ X W.OpenCover where J := 𝒰.J obj x := pullback f (𝒰.map x) - map x := pullback.fst _ _ + map _ := pullback.fst _ _ f x := 𝒰.f (f.1.base x) covers x := by rw [← @@ -198,7 +198,7 @@ def OpenCover.pullbackCover' {X W : Scheme.{u}} (𝒰 : X.OpenCover) (f : W ⟶ W.OpenCover where J := 𝒰.J obj x := pullback (𝒰.map x) f - map x := pullback.snd _ _ + map _ := pullback.snd _ _ f x := 𝒰.f (f.1.base x) covers x := by rw [← @@ -261,7 +261,7 @@ def OpenCover.inter {X : Scheme.{u}} (𝒰₁ : Scheme.OpenCover.{v₁} X) covers x := by rw [IsOpenImmersion.range_pullback_to_base_of_left] exact ⟨𝒰₁.covers x, 𝒰₂.covers x⟩ - IsOpen x := inferInstance + IsOpen _ := inferInstance /-- An affine open cover of `X` consists of a family of open immersions into `X` from @@ -372,13 +372,13 @@ attribute [instance] OpenCover.Hom.isOpen /-- The identity morphism in the category of open covers of a scheme. -/ def OpenCover.Hom.id {X : Scheme.{u}} (𝓤 : OpenCover.{v} X) : 𝓤.Hom 𝓤 where idx j := j - app j := 𝟙 _ + app _ := 𝟙 _ /-- The composition of two morphisms in the category of open covers of a scheme. -/ def OpenCover.Hom.comp {X : Scheme.{u}} {𝓤 𝓥 𝓦 : OpenCover.{v} X} (f : 𝓤.Hom 𝓥) (g : 𝓥.Hom 𝓦) : 𝓤.Hom 𝓦 where idx j := g.idx <| f.idx j - app j := f.app _ ≫ g.app _ + app _ := f.app _ ≫ g.app _ instance OpenCover.category {X : Scheme.{u}} : Category (OpenCover.{v} X) where Hom 𝓤 𝓥 := 𝓤.Hom 𝓥 diff --git a/Mathlib/AlgebraicGeometry/Gluing.lean b/Mathlib/AlgebraicGeometry/Gluing.lean index 6bd24a246c33d4..2907eed57c7e5b 100644 --- a/Mathlib/AlgebraicGeometry/Gluing.lean +++ b/Mathlib/AlgebraicGeometry/Gluing.lean @@ -313,15 +313,15 @@ def gluedCover : Scheme.GlueData.{u} where J := 𝒰.J U := 𝒰.obj V := fun ⟨x, y⟩ => pullback (𝒰.map x) (𝒰.map y) - f x y := pullback.fst _ _ - f_id x := inferInstance - t x y := (pullbackSymmetry _ _).hom + f _ _ := pullback.fst _ _ + f_id _ := inferInstance + t _ _ := (pullbackSymmetry _ _).hom t_id x := by simp t' x y z := gluedCoverT' 𝒰 x y z t_fac x y z := by apply pullback.hom_ext <;> simp -- The `cocycle` field could have been `by tidy` but lean timeouts. cocycle x y z := glued_cover_cocycle 𝒰 x y z - f_open x := inferInstance + f_open _ := inferInstance /-- The canonical morphism from the gluing of an open cover of `X` into `X`. This is an isomorphism, as witnessed by an `IsIso` instance. -/ diff --git a/Mathlib/AlgebraicGeometry/GluingOneHypercover.lean b/Mathlib/AlgebraicGeometry/GluingOneHypercover.lean index 57c59570b18b70..374d5034df6ebf 100644 --- a/Mathlib/AlgebraicGeometry/GluingOneHypercover.lean +++ b/Mathlib/AlgebraicGeometry/GluingOneHypercover.lean @@ -42,7 +42,7 @@ noncomputable def oneHypercover : Scheme.zariskiTopology.OneHypercover D.glued w I₁ _ _ := PUnit Y i₁ i₂ _ := D.V (i₁, i₂) p₁ i₁ i₂ _ := D.f i₁ i₂ - p₂ i₁ i₂ j := D.t i₁ i₂ ≫ D.f i₂ i₁ + p₂ i₁ i₂ _ := D.t i₁ i₂ ≫ D.f i₂ i₁ w i₁ i₂ _ := by simp only [Category.assoc, Scheme.GlueData.glue_condition] mem₀ := by refine zariskiTopology.superset_covering ?_ (zariskiTopology_openCover D.openCover) diff --git a/Mathlib/AlgebraicGeometry/Limits.lean b/Mathlib/AlgebraicGeometry/Limits.lean index 903e50c8aefa61..5124bdbd6e750f 100644 --- a/Mathlib/AlgebraicGeometry/Limits.lean +++ b/Mathlib/AlgebraicGeometry/Limits.lean @@ -53,7 +53,7 @@ section Initial @[simps] def Scheme.emptyTo (X : Scheme.{u}) : ∅ ⟶ X := ⟨{ base := ⟨fun x => PEmpty.elim x, by fun_prop⟩ - c := { app := fun U => CommRingCat.punitIsTerminal.from _ } }, fun x => PEmpty.elim x⟩ + c := { app := fun _ => CommRingCat.punitIsTerminal.from _ } }, fun x => PEmpty.elim x⟩ @[ext] theorem Scheme.empty_ext {X : Scheme.{u}} (f g : ∅ ⟶ X) : f = g := diff --git a/Mathlib/AlgebraicGeometry/Modules/Tilde.lean b/Mathlib/AlgebraicGeometry/Modules/Tilde.lean index d4c07982358ac5..7fd34c2070d7a4 100644 --- a/Mathlib/AlgebraicGeometry/Modules/Tilde.lean +++ b/Mathlib/AlgebraicGeometry/Modules/Tilde.lean @@ -57,7 +57,7 @@ def isFraction {U : Opens (PrimeSpectrum R)} (f : ∀ 𝔭 : U, Localizations M The property of a function `f : ∏_{x ∈ U}, Mₓ` being a fraction is stable under restriction. -/ def isFractionPrelocal : PrelocalPredicate (Localizations M) where - pred {U} f := isFraction M f + pred {_} f := isFraction M f res := by rintro V U i f ⟨m, s, w⟩; exact ⟨m, s, fun x => w (i x)⟩ /-- diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean b/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean index 9b5b16f7d5f16a..2cd009c1f7312c 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean @@ -137,7 +137,7 @@ protected lemma mk' {P : MorphismProperty Scheme} [P.RespectsIso] the target. -/ instance inf (P Q : MorphismProperty Scheme) [IsLocalAtTarget P] [IsLocalAtTarget Q] : IsLocalAtTarget (P ⊓ Q) where - iff_of_openCover' {X Y} f 𝒰 := + iff_of_openCover' {_ _} f 𝒰 := ⟨fun h i ↦ ⟨(iff_of_openCover' f 𝒰).mp h.left i, (iff_of_openCover' f 𝒰).mp h.right i⟩, fun h ↦ ⟨(iff_of_openCover' f 𝒰).mpr (fun i ↦ (h i).left), (iff_of_openCover' f 𝒰).mpr (fun i ↦ (h i).right)⟩⟩ @@ -222,7 +222,7 @@ protected lemma mk' {P : MorphismProperty Scheme} [P.RespectsIso] the target. -/ instance inf (P Q : MorphismProperty Scheme) [IsLocalAtSource P] [IsLocalAtSource Q] : IsLocalAtSource (P ⊓ Q) where - iff_of_openCover' {X Y} f 𝒰 := + iff_of_openCover' {_ _} f 𝒰 := ⟨fun h i ↦ ⟨(iff_of_openCover' f 𝒰).mp h.left i, (iff_of_openCover' f 𝒰).mp h.right i⟩, fun h ↦ ⟨(iff_of_openCover' f 𝒰).mpr (fun i ↦ (h i).left), (iff_of_openCover' f 𝒰).mpr (fun i ↦ (h i).right)⟩⟩ @@ -323,7 +323,7 @@ theorem arrow_mk_iso_iff theorem respectsIso_mk {P : AffineTargetMorphismProperty} (h₁ : ∀ {X Y Z} (e : X ≅ Y) (f : Y ⟶ Z) [IsAffine Z], P f → P (e.hom ≫ f)) - (h₂ : ∀ {X Y Z} (e : Y ≅ Z) (f : X ⟶ Y) [h : IsAffine Y], + (h₂ : ∀ {X Y Z} (e : Y ≅ Z) (f : X ⟶ Y) [IsAffine Y], P f → @P _ _ (f ≫ e.hom) (isAffine_of_isIso e.inv)) : P.toProperty.RespectsIso := by apply MorphismProperty.RespectsIso.mk diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Constructors.lean b/Mathlib/AlgebraicGeometry/Morphisms/Constructors.lean index 878d9b451bd277..d817f2b6c1a4ce 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Constructors.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Constructors.lean @@ -123,7 +123,7 @@ instance HasAffineProperty.diagonal_affineProperty_isLocal {Q : AffineTargetMorphismProperty} [Q.IsLocal] : Q.diagonal.IsLocal where respectsIso := inferInstance - to_basicOpen {X Y} _ f r hf := + to_basicOpen {_ Y} _ f r hf := diagonal_of_diagonal_of_isPullback (targetAffineLocally Q) (isPullback_morphismRestrict f (Y.basicOpen r)).flip ((diagonal_iff (targetAffineLocally Q)).mp hf) diff --git a/Mathlib/AlgebraicGeometry/Morphisms/FiniteType.lean b/Mathlib/AlgebraicGeometry/Morphisms/FiniteType.lean index 4424a0eed09948..def22435c69c04 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/FiniteType.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/FiniteType.lean @@ -57,7 +57,7 @@ instance locallyOfFiniteType_comp {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) theorem locallyOfFiniteType_of_comp {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) [LocallyOfFiniteType (f ≫ g)] : LocallyOfFiniteType f := - HasRingHomProperty.of_comp (fun f g ↦ RingHom.FiniteType.of_comp_finiteType) ‹_› + HasRingHomProperty.of_comp (fun _ _ ↦ RingHom.FiniteType.of_comp_finiteType) ‹_› open scoped TensorProduct in lemma locallyOfFiniteType_stableUnderBaseChange : diff --git a/Mathlib/AlgebraicGeometry/Morphisms/IsIso.lean b/Mathlib/AlgebraicGeometry/Morphisms/IsIso.lean index 8626fd8f7cf5fd..ad9b6dcc7c5f60 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/IsIso.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/IsIso.lean @@ -36,7 +36,7 @@ lemma isomorphisms_eq_stalkwise : instance : IsLocalAtTarget (isomorphisms Scheme) := isomorphisms_eq_isOpenImmersion_inf_surjective ▸ inferInstance -instance : HasAffineProperty (isomorphisms Scheme) fun X Y f _ ↦ IsAffine X ∧ IsIso (f.app ⊤) := by +instance : HasAffineProperty (isomorphisms Scheme) fun X _ f _ ↦ IsAffine X ∧ IsIso (f.app ⊤) := by convert HasAffineProperty.of_isLocalAtTarget (isomorphisms Scheme) with X Y f hY exact ⟨fun ⟨_, _⟩ ↦ (arrow_mk_iso_iff (isomorphisms _) (arrowIsoSpecΓOfIsAffine f)).mpr (inferInstanceAs (IsIso (Spec.map (f.app ⊤)))), diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean index 567d07ccb66d08..35a672056282e3 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean @@ -454,7 +454,7 @@ theorem carrier.asIdeal.ne_top : carrier.asIdeal f_deg hm q ≠ ⊤ := fun rid = theorem carrier.asIdeal.prime : (carrier.asIdeal f_deg hm q).IsPrime := (carrier.asIdeal.homogeneous f_deg hm q).isPrime_of_homogeneous_mem_or_mem (carrier.asIdeal.ne_top f_deg hm q) fun {x y} ⟨nx, hnx⟩ ⟨ny, hny⟩ hxy => - show (∀ i, _ ∈ _) ∨ ∀ i, _ ∈ _ by + 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 dsimp diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/StructureSheaf.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/StructureSheaf.lean index e6fe728b2d0421..adedf076c90dc5 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/StructureSheaf.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/StructureSheaf.lean @@ -180,9 +180,9 @@ def structurePresheafInCommRing : Presheaf CommRingCat (ProjectiveSpectrum.top map i := { toFun := (structureSheafInType 𝒜).1.map i map_zero' := rfl - map_add' := fun x y => rfl + map_add' := fun _ _ => rfl map_one' := rfl - map_mul' := fun x y => rfl } + map_mul' := fun _ _ => rfl } -- These lemmas have always been bad (#7657), but leanprover/lean4#2644 made `simp` start noticing attribute [nolint simpNF] @@ -192,7 +192,7 @@ attribute [nolint simpNF] valued structure presheaf. -/ def structurePresheafCompForget : structurePresheafInCommRing 𝒜 ⋙ forget CommRingCat ≅ (structureSheafInType 𝒜).1 := - NatIso.ofComponents (fun U => Iso.refl _) (by aesop_cat) + NatIso.ofComponents (fun _ => Iso.refl _) (by aesop_cat) end ProjectiveSpectrum.StructureSheaf diff --git a/Mathlib/AlgebraicGeometry/Pullbacks.lean b/Mathlib/AlgebraicGeometry/Pullbacks.lean index 1b43cf9c18bfdf..a20cda1ec55677 100644 --- a/Mathlib/AlgebraicGeometry/Pullbacks.lean +++ b/Mathlib/AlgebraicGeometry/Pullbacks.lean @@ -197,8 +197,8 @@ def gluing : Scheme.GlueData.{u} where U i := pullback (𝒰.map i ≫ f) g V := fun ⟨i, j⟩ => v 𝒰 f g i j -- `p⁻¹(Uᵢ ∩ Uⱼ)` where `p : Uᵢ ×[Z] Y ⟶ Uᵢ ⟶ X`. - f i j := pullback.fst _ _ - f_id i := inferInstance + f _ _ := pullback.fst _ _ + f_id _ := inferInstance f_open := inferInstance t i j := t 𝒰 f g i j t_id i := t_id 𝒰 f g i diff --git a/Mathlib/AlgebraicGeometry/Sites/BigZariski.lean b/Mathlib/AlgebraicGeometry/Sites/BigZariski.lean index c96f49a5dbd359..854935ddae1df6 100644 --- a/Mathlib/AlgebraicGeometry/Sites/BigZariski.lean +++ b/Mathlib/AlgebraicGeometry/Sites/BigZariski.lean @@ -38,7 +38,7 @@ namespace Scheme /-- The Zariski pretopology on the category of schemes. -/ def zariskiPretopology : Pretopology (Scheme.{u}) where coverings Y S := ∃ (U : OpenCover.{u} Y), S = Presieve.ofArrows U.obj U.map - has_isos Y X f _ := ⟨openCoverOfIsIso f, (Presieve.ofArrows_pUnit _).symm⟩ + has_isos _ _ f _ := ⟨openCoverOfIsIso f, (Presieve.ofArrows_pUnit _).symm⟩ pullbacks := by rintro Y X f _ ⟨U, rfl⟩ exact ⟨U.pullbackCover' f, (Presieve.ofArrows_pullback _ _ _).symm⟩ diff --git a/Mathlib/AlgebraicGeometry/Spec.lean b/Mathlib/AlgebraicGeometry/Spec.lean index 1defa7db8f0e82..80690a03c20225 100644 --- a/Mathlib/AlgebraicGeometry/Spec.lean +++ b/Mathlib/AlgebraicGeometry/Spec.lean @@ -78,7 +78,7 @@ theorem Spec.topMap_comp {R S T : CommRingCat.{u}} (f : R ⟶ S) (g : S ⟶ T) : @[simps! obj map] def Spec.toTop : CommRingCat.{u}ᵒᵖ ⥤ TopCat where obj R := Spec.topObj (unop R) - map {R S} f := Spec.topMap f.unop + map {_ _} f := Spec.topMap f.unop /-- The spectrum of a commutative ring, as a `SheafedSpace`. -/ diff --git a/Mathlib/AlgebraicGeometry/StructureSheaf.lean b/Mathlib/AlgebraicGeometry/StructureSheaf.lean index fcd5788d019060..7541f38a34b7c0 100644 --- a/Mathlib/AlgebraicGeometry/StructureSheaf.lean +++ b/Mathlib/AlgebraicGeometry/StructureSheaf.lean @@ -117,7 +117,7 @@ variable (R) in the sense that if it holds on `U` it holds on any open subset `V` of `U`. -/ def isFractionPrelocal : PrelocalPredicate (Localizations R) where - pred {U} f := IsFraction f + pred {_} f := IsFraction f res := by rintro V U i f ⟨r, s, w⟩; exact ⟨r, s, fun x => w (i x)⟩ /-- We will define the structure sheaf as @@ -225,12 +225,12 @@ structure presheaf. @[simps] def structurePresheafInCommRing : Presheaf CommRingCat (PrimeSpectrum.Top R) where obj U := CommRingCat.of ((structureSheafInType R).1.obj U) - map {U V} i := + map {_ _} i := { toFun := (structureSheafInType R).1.map i map_zero' := rfl - map_add' := fun x y => rfl + map_add' := fun _ _ => rfl map_one' := rfl - map_mul' := fun x y => rfl } + map_mul' := fun _ _ => rfl } -- These lemmas have always been bad (#7657), but leanprover/lean4#2644 made `simp` start noticing attribute [nolint simpNF] AlgebraicGeometry.structurePresheafInCommRing_map_apply @@ -240,7 +240,7 @@ with the `Type` valued structure presheaf. -/ def structurePresheafCompForget : structurePresheafInCommRing R ⋙ forget CommRingCat ≅ (structureSheafInType R).1 := - NatIso.ofComponents fun U => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ open TopCat.Presheaf @@ -378,13 +378,13 @@ a section of the structure sheaf. -/ def toOpen (U : Opens (PrimeSpectrum.Top R)) : CommRingCat.of R ⟶ (structureSheaf R).1.obj (op U) where toFun f := - ⟨fun x => algebraMap R _ f, fun x => + ⟨fun _ => algebraMap R _ f, fun x => ⟨U, x.2, 𝟙 _, f, 1, fun y => ⟨(Ideal.ne_top_iff_one _).1 y.1.2.1, by rw [RingHom.map_one, mul_one]⟩⟩⟩ - map_one' := Subtype.eq <| funext fun x => RingHom.map_one _ - map_mul' f g := Subtype.eq <| funext fun x => RingHom.map_mul _ _ _ - map_zero' := Subtype.eq <| funext fun x => RingHom.map_zero _ - map_add' f g := Subtype.eq <| funext fun x => RingHom.map_add _ _ _ + map_one' := Subtype.eq <| funext fun _ => RingHom.map_one _ + map_mul' _ _ := Subtype.eq <| funext fun _ => RingHom.map_mul _ _ _ + map_zero' := Subtype.eq <| funext fun _ => RingHom.map_zero _ + map_add' _ _ := Subtype.eq <| funext fun _ => RingHom.map_add _ _ _ @[simp] theorem toOpen_res (U V : Opens (PrimeSpectrum.Top R)) (i : V ⟶ U) : @@ -570,7 +570,7 @@ def toBasicOpen (f : R) : @[simp] theorem toBasicOpen_mk' (s f : R) (g : Submonoid.powers s) : toBasicOpen R s (IsLocalization.mk' (Localization.Away s) f g) = - const R f g (PrimeSpectrum.basicOpen s) fun x hx => Submonoid.powers_le.2 hx g.2 := + const R f g (PrimeSpectrum.basicOpen s) fun _ hx => Submonoid.powers_le.2 hx g.2 := (IsLocalization.lift_mk'_spec _ _ _ _).2 <| by rw [toOpen_eq_const, toOpen_eq_const, const_mul_cancel'] @@ -624,7 +624,7 @@ Every section can locally be represented on basic opens `basicOpen g` as a fract theorem locally_const_basicOpen (U : Opens (PrimeSpectrum.Top R)) (s : (structureSheaf R).1.obj (op U)) (x : U) : ∃ (f g : R) (i : PrimeSpectrum.basicOpen g ⟶ U), x.1 ∈ PrimeSpectrum.basicOpen g ∧ - (const R f g (PrimeSpectrum.basicOpen g) fun y hy => hy) = + (const R f g (PrimeSpectrum.basicOpen g) fun _ hy => hy) = (structureSheaf R).1.map i.op s := by -- First, any section `s` can be represented as a fraction `f/g` on some open neighborhood of `x` -- and we may pass to a `basicOpen h`, since these form a basis @@ -671,14 +671,14 @@ theorem normalize_finite_fraction_representation (U : Opens (PrimeSpectrum.Top R (h_cover : U ≤ ⨆ i ∈ t, PrimeSpectrum.basicOpen (h i)) (hs : ∀ i : ι, - (const R (a i) (h i) (PrimeSpectrum.basicOpen (h i)) fun y hy => hy) = + (const R (a i) (h i) (PrimeSpectrum.basicOpen (h i)) fun _ hy => hy) = (structureSheaf R).1.map (iDh i).op s) : ∃ (a' h' : ι → R) (iDh' : ∀ i : ι, PrimeSpectrum.basicOpen (h' i) ⟶ U), (U ≤ ⨆ i ∈ t, PrimeSpectrum.basicOpen (h' i)) ∧ (∀ (i) (_ : i ∈ t) (j) (_ : j ∈ t), a' i * h' j = h' i * a' j) ∧ ∀ i ∈ t, (structureSheaf R).1.map (iDh' i).op s = - const R (a' i) (h' i) (PrimeSpectrum.basicOpen (h' i)) fun y hy => hy := by + const R (a' i) (h' i) (PrimeSpectrum.basicOpen (h' i)) fun _ hy => hy := by -- First we show that the fractions `(a i * h j) / (h i * h j)` and `(h i * a j) / (h i * h j)` -- coincide in the localization of `R` at `h i * h j` have fractions_eq : @@ -1070,7 +1070,7 @@ This is a generalization of the fact that, for fixed `U`, the comap of the ident to OO_X(U) is the identity. -/ theorem comap_id_eq_map (U V : Opens (PrimeSpectrum.Top R)) (iVU : V ⟶ U) : - (comap (RingHom.id R) U V fun p hpV => leOfHom iVU <| hpV) = + (comap (RingHom.id R) U V fun _ hpV => leOfHom iVU <| hpV) = (structureSheaf R).1.map iVU.op := RingHom.ext fun s => Subtype.eq <| funext fun p => by rw [comap_apply] diff --git a/Mathlib/AlgebraicTopology/CechNerve.lean b/Mathlib/AlgebraicTopology/CechNerve.lean index 5f4b8181e1ed0a..b6270d870a146c 100644 --- a/Mathlib/AlgebraicTopology/CechNerve.lean +++ b/Mathlib/AlgebraicTopology/CechNerve.lean @@ -67,7 +67,7 @@ def mapCechNerve {f g : Arrow C} def augmentedCechNerve : SimplicialObject.Augmented C where left := f.cechNerve right := f.right - hom := { app := fun i => WidePullback.base _ } + hom := { app := fun _ => WidePullback.base _ } /-- The morphism between augmented Čech nerve associated to a morphism of arrows. -/ @[simps] @@ -211,7 +211,7 @@ def augmentedCechConerve : CosimplicialObject.Augmented C where left := f.left right := f.cechConerve hom := - { app := fun i => (WidePushout.head _ : f.left ⟶ _) } + { app := fun _ => (WidePushout.head _ : f.left ⟶ _) } /-- The morphism between augmented Čech conerves associated to a morphism of arrows. -/ @[simps] @@ -357,7 +357,7 @@ def wideCospan.limitCone [Finite ι] (X : C) : LimitCone (wideCospan ι X) where subsingleton } } isLimit := { lift := fun s => Limits.Pi.lift fun j => s.π.app (some j) - fac := fun s j => Option.casesOn j (by subsingleton) fun j => limit.lift_π _ _ + fac := fun s j => Option.casesOn j (by subsingleton) fun _ => limit.lift_π _ _ uniq := fun s f h => by dsimp ext j @@ -405,7 +405,7 @@ lemma wideCospan.limitIsoPi_hom_comp_pi [Finite ι] (X : C) (j : ι) : naturally isomorphic to a simplicial object sending `[n]` to `Xⁿ⁺¹` (when `C` is `G-Set`, this is `EG`, the universal cover of the classifying space of `G`. -/ def iso (X : C) : (Arrow.mk (terminal.from X)).cechNerve ≅ cechNerveTerminalFrom X := - NatIso.ofComponents (fun m => wideCospan.limitIsoPi _ _) (fun {m n} f => by + NatIso.ofComponents (fun _ => wideCospan.limitIsoPi _ _) (fun {m n} f => by dsimp only [cechNerveTerminalFrom, Arrow.cechNerve] ext ⟨j⟩ simp only [Category.assoc, limit.lift_π, Fan.mk_π_app] diff --git a/Mathlib/AlgebraicTopology/DoldKan/GammaCompN.lean b/Mathlib/AlgebraicTopology/DoldKan/GammaCompN.lean index 91df76ad66660f..8b92fd134e5711 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/GammaCompN.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/GammaCompN.lean @@ -32,7 +32,7 @@ variable {C : Type*} [Category C] [Preadditive C] [HasFiniteCoproducts C] /-- The isomorphism `(Γ₀.splitting K).nondegComplex ≅ K` for all `K : ChainComplex C ℕ`. -/ @[simps!] def Γ₀NondegComplexIso (K : ChainComplex C ℕ) : (Γ₀.splitting K).nondegComplex ≅ K := - HomologicalComplex.Hom.isoOfComponents (fun n => Iso.refl _) + HomologicalComplex.Hom.isoOfComponents (fun _ => Iso.refl _) (by rintro _ n (rfl : n + 1 = _) dsimp diff --git a/Mathlib/AlgebraicTopology/DoldKan/Homotopies.lean b/Mathlib/AlgebraicTopology/DoldKan/Homotopies.lean index bbb305c218ea04..1c3db5df719f3e 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/Homotopies.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/Homotopies.lean @@ -151,7 +151,7 @@ theorem hσ'_naturality (q : ℕ) (n m : ℕ) (hnm : c.Rel m n) {X Y : Simplicia /-- For each q, `Hσ q` is a natural transformation. -/ def natTransHσ (q : ℕ) : alternatingFaceMapComplex C ⟶ alternatingFaceMapComplex C where - app X := Hσ q + app _ := Hσ q naturality _ _ f := by unfold Hσ rw [nullHomotopicMap'_comp, comp_nullHomotopicMap'] diff --git a/Mathlib/AlgebraicTopology/DoldKan/Projections.lean b/Mathlib/AlgebraicTopology/DoldKan/Projections.lean index 6802bb367805a9..36a1005cae771e 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/Projections.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/Projections.lean @@ -147,7 +147,7 @@ theorem Q_idem (q : ℕ) : (Q q : K[X] ⟶ K[X]) ≫ Q q = Q q := by /-- For each `q`, `P q` is a natural transformation. -/ @[simps] def natTransP (q : ℕ) : alternatingFaceMapComplex C ⟶ alternatingFaceMapComplex C where - app X := P q + app _ := P q naturality _ _ f := by induction' q with q hq · dsimp [alternatingFaceMapComplex] @@ -172,7 +172,7 @@ theorem Q_f_naturality (q n : ℕ) {X Y : SimplicialObject C} (f : X ⟶ Y) : /-- For each `q`, `Q q` is a natural transformation. -/ @[simps] def natTransQ (q : ℕ) : alternatingFaceMapComplex C ⟶ alternatingFaceMapComplex C where - app X := Q q + app _ := Q q theorem map_P {D : Type*} [Category D] [Preadditive D] (G : C ⥤ D) [G.Additive] (X : SimplicialObject C) (q n : ℕ) : diff --git a/Mathlib/AlgebraicTopology/ExtraDegeneracy.lean b/Mathlib/AlgebraicTopology/ExtraDegeneracy.lean index 478287d6c7e9c8..383f0ae621d5f5 100644 --- a/Mathlib/AlgebraicTopology/ExtraDegeneracy.lean +++ b/Mathlib/AlgebraicTopology/ExtraDegeneracy.lean @@ -181,7 +181,7 @@ open SSet.standardSimplex in protected noncomputable def extraDegeneracy (Δ : SimplexCategory) : SimplicialObject.Augmented.ExtraDegeneracy (standardSimplex.obj Δ) where s' _ := objMk (OrderHom.const _ 0) - s n f := (objEquiv _ _).symm + s _ f := (objEquiv _ _).symm (shift (objEquiv _ _ f)) s'_comp_ε := by dsimp diff --git a/Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean b/Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean index 2a8bb0c418f7e9..2af55680d6b61a 100644 --- a/Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean +++ b/Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean @@ -299,14 +299,14 @@ attribute [local instance] Path.Homotopic.setoid instance : CategoryTheory.Groupoid (FundamentalGroupoid X) where Hom x y := Path.Homotopic.Quotient x.as y.as id x := ⟦Path.refl x.as⟧ - comp {x y z} := Path.Homotopic.Quotient.comp - id_comp {x y} f := + comp {_ _ _} := Path.Homotopic.Quotient.comp + id_comp {x _} f := Quotient.inductionOn f fun a => show ⟦(Path.refl x.as).trans a⟧ = ⟦a⟧ from Quotient.sound ⟨Path.Homotopy.reflTrans a⟩ - comp_id {x y} f := + comp_id {_ y} f := Quotient.inductionOn f fun a => show ⟦a.trans (Path.refl y.as)⟧ = ⟦a⟧ from Quotient.sound ⟨Path.Homotopy.transRefl a⟩ - assoc {w x y z} f g h := + assoc {_ _ _ _} f g h := Quotient.inductionOn₃ f g h fun p q r => show ⟦(p.trans q).trans r⟧ = ⟦p.trans (q.trans r)⟧ from Quotient.sound ⟨Path.Homotopy.transAssoc p q r⟩ @@ -318,11 +318,11 @@ instance : CategoryTheory.Groupoid (FundamentalGroupoid X) where rw [Quotient.eq] exact ⟨h.symm₂⟩) p - inv_comp {x y} f := + inv_comp {_ y} f := Quotient.inductionOn f fun a => show ⟦a.symm.trans a⟧ = ⟦Path.refl y.as⟧ from Quotient.sound ⟨(Path.Homotopy.reflSymmTrans a).symm⟩ - comp_inv {x y} f := + comp_inv {x _} f := Quotient.inductionOn f fun a => show ⟦a.trans a.symm⟧ = ⟦Path.refl x.as⟧ from Quotient.sound ⟨(Path.Homotopy.reflTransSymm a).symm⟩ @@ -337,7 +337,7 @@ def fundamentalGroupoidFunctor : TopCat ⥤ CategoryTheory.Grpd where map f := { obj := fun x => ⟨f x.as⟩ map := fun {X Y} p => by exact Path.Homotopic.Quotient.mapFn p f - map_id := fun X => rfl + map_id := fun _ => rfl map_comp := fun {x y z} p q => by refine Quotient.inductionOn₂ p q fun a b => ?_ simp only [comp_eq, ← Path.Homotopic.map_lift, ← Path.Homotopic.comp_lift, Path.map_trans] } diff --git a/Mathlib/AlgebraicTopology/FundamentalGroupoid/Product.lean b/Mathlib/AlgebraicTopology/FundamentalGroupoid/Product.lean index 667572acea631f..e6ebf8e4a8192a 100644 --- a/Mathlib/AlgebraicTopology/FundamentalGroupoid/Product.lean +++ b/Mathlib/AlgebraicTopology/FundamentalGroupoid/Product.lean @@ -150,14 +150,14 @@ def prodToProdTop : πₓ A × πₓ B ⥤ πₓ (TopCat.of (A × B)) where obj g := ⟨g.fst.as, g.snd.as⟩ map {x y} p := match x, y, p with - | (x₀, x₁), (y₀, y₁), (p₀, p₁) => @Path.Homotopic.prod _ _ (_) (_) _ _ _ _ p₀ p₁ + | (_, _), (_, _), (p₀, p₁) => @Path.Homotopic.prod _ _ (_) (_) _ _ _ _ p₀ p₁ map_id := by rintro ⟨x₀, x₁⟩ simp only [CategoryTheory.prod_id, FundamentalGroupoid.id_eq_path_refl] rfl map_comp {x y z} f g := match x, y, z, f, g with - | (x₀, x₁), (y₀, y₁), (z₀, z₁), (f₀, f₁), (g₀, g₁) => + | (_, _), (_, _), (_, _), (f₀, f₁), (g₀, g₁) => (Path.Homotopic.comp_prod_eq_prod_comp f₀ f₁ g₀ g₁).symm theorem prodToProdTop_map {x₀ x₁ : πₓ A} {y₀ y₁ : πₓ B} (p₀ : x₀ ⟶ x₁) (p₁ : y₀ ⟶ y₁) : diff --git a/Mathlib/AlgebraicTopology/SimplexCategory.lean b/Mathlib/AlgebraicTopology/SimplexCategory.lean index 38c94b643e51d0..036111e7e6ab63 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory.lean @@ -131,7 +131,7 @@ end Hom instance smallCategory : SmallCategory.{0} SimplexCategory where Hom n m := SimplexCategory.Hom n m - id m := SimplexCategory.Hom.id _ + id _ := SimplexCategory.Hom.id _ comp f g := SimplexCategory.Hom.comp g f @[simp] diff --git a/Mathlib/AlgebraicTopology/SimplicialCategory/SimplicialObject.lean b/Mathlib/AlgebraicTopology/SimplicialCategory/SimplicialObject.lean index 966e00873375ee..899ce960ebcf05 100644 --- a/Mathlib/AlgebraicTopology/SimplicialCategory/SimplicialObject.lean +++ b/Mathlib/AlgebraicTopology/SimplicialCategory/SimplicialObject.lean @@ -31,7 +31,7 @@ noncomputable instance : EnrichedCategory SSet.{v} (SimplicialObject D) := inferInstanceAs (EnrichedCategory (_ ⥤ Type v) (_ ⥤ D)) noncomputable instance : SimplicialCategory (SimplicialObject D) where - homEquiv K L := Functor.natTransEquiv.symm + homEquiv _ _ := Functor.natTransEquiv.symm noncomputable instance : SimplicialCategory SSet.{v} := inferInstanceAs (SimplicialCategory (SimplicialObject (Type v))) diff --git a/Mathlib/AlgebraicTopology/SimplicialObject.lean b/Mathlib/AlgebraicTopology/SimplicialObject.lean index c15da7cf1c35d5..d99137665f53db 100644 --- a/Mathlib/AlgebraicTopology/SimplicialObject.lean +++ b/Mathlib/AlgebraicTopology/SimplicialObject.lean @@ -446,7 +446,7 @@ def augment (X : SimplicialObject C) (X₀ : C) (f : X _[0] ⟶ X₀) left := X right := X₀ hom := - { app := fun i => X.map (SimplexCategory.const _ _ 0).op ≫ f + { app := fun _ => X.map (SimplexCategory.const _ _ 0).op ≫ f naturality := by intro i j g dsimp @@ -775,7 +775,7 @@ def augment (X : CosimplicialObject C) (X₀ : C) (f : X₀ ⟶ X.obj [0]) left := X₀ right := X hom := - { app := fun i => f ≫ X.map (SimplexCategory.const _ _ 0) + { app := fun _ => f ≫ X.map (SimplexCategory.const _ _ 0) naturality := by intro i j g dsimp diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Basic.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Basic.lean index 2a21c558b5ebbd..b11a417a297e74 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Basic.lean @@ -164,6 +164,13 @@ def boundary (n : ℕ) : SSet.{u} where /-- The boundary `∂Δ[n]` of the `n`-th standard simplex -/ scoped[Simplicial] notation3 "∂Δ[" n "]" => SSet.boundary n +#adaptation_note +/-- +The new unused variable linter in +https://github.com/leanprover/lean4/pull/5338 +flags `{ α : Δ[n].obj m // _ }`. +-/ +set_option linter.unusedVariables false in /-- The inclusion of the boundary of the `n`-th standard simplex into that standard simplex. -/ def boundaryInclusion (n : ℕ) : ∂Δ[n] ⟶ Δ[n] where app m (α : { α : Δ[n].obj m // _ }) := α @@ -184,6 +191,13 @@ def horn (n : ℕ) (i : Fin (n + 1)) : SSet where /-- The `i`-th horn `Λ[n, i]` of the standard `n`-simplex -/ scoped[Simplicial] notation3 "Λ[" n ", " i "]" => SSet.horn (n : ℕ) i +#adaptation_note +/-- +The new unused variable linter in +https://github.com/leanprover/lean4/pull/5338 +flags `{ α : Δ[n].obj m // _ }`. +-/ +set_option linter.unusedVariables false in /-- The inclusion of the `i`-th horn of the `n`-th standard simplex into that standard simplex. -/ def hornInclusion (n : ℕ) (i : Fin (n + 1)) : Λ[n, i] ⟶ Δ[n] where app m (α : { α : Δ[n].obj m // _ }) := α @@ -437,7 +451,7 @@ noncomputable def standardSimplex : SimplexCategory ⥤ SSet.Augmented.{u} where obj Δ := { left := SSet.standardSimplex.obj Δ right := terminal _ - hom := { app := fun Δ' => terminal.from _ } } + hom := { app := fun _ => terminal.from _ } } map θ := { left := SSet.standardSimplex.map θ right := terminal.from _ } diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Nerve.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Nerve.lean index 9e299bd44fc83b..c82254637aaf34 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Nerve.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Nerve.lean @@ -39,7 +39,7 @@ instance {C : Type*} [Category C] {Δ : SimplexCategoryᵒᵖ} : Category ((nerv @[simps] def nerveFunctor : Cat ⥤ SSet where obj C := nerve C - map F := { app := fun Δ => (F.mapComposableArrows _).obj } + map F := { app := fun _ => (F.mapComposableArrows _).obj } namespace Nerve diff --git a/Mathlib/AlgebraicTopology/SplitSimplicialObject.lean b/Mathlib/AlgebraicTopology/SplitSimplicialObject.lean index 156266bbc5e76c..246867b17fe5c1 100644 --- a/Mathlib/AlgebraicTopology/SplitSimplicialObject.lean +++ b/Mathlib/AlgebraicTopology/SplitSimplicialObject.lean @@ -339,7 +339,7 @@ instance : Category (Split C) where Hom := Split.Hom id S := { F := 𝟙 _ - f := fun n => 𝟙 _ } + f := fun _ => 𝟙 _ } comp Φ₁₂ Φ₂₃ := { F := Φ₁₂.F ≫ Φ₂₃.F f := fun n => Φ₁₂.f n ≫ Φ₂₃.f n diff --git a/Mathlib/Analysis/Analytic/Basic.lean b/Mathlib/Analysis/Analytic/Basic.lean index cd994fb7364b81..04e001a4a25bcc 100644 --- a/Mathlib/Analysis/Analytic/Basic.lean +++ b/Mathlib/Analysis/Analytic/Basic.lean @@ -292,7 +292,7 @@ theorem radius_eq_top_iff_summable_norm (p : FormalMultilinearSeries 𝕜 E F) : /-- If the radius of `p` is positive, then `‖pₙ‖` grows at most geometrically. -/ theorem le_mul_pow_of_radius_pos (p : FormalMultilinearSeries 𝕜 E F) (h : 0 < p.radius) : - ∃ (C r : _) (hC : 0 < C) (_ : 0 < r), ∀ n, ‖p n‖ ≤ C * r ^ n := by + ∃ (C r : _) (_ : 0 < C) (_ : 0 < r), ∀ n, ‖p n‖ ≤ C * r ^ n := by rcases ENNReal.lt_iff_exists_nnreal_btwn.1 h with ⟨r, r0, rlt⟩ have rpos : 0 < (r : ℝ) := by simp [ENNReal.coe_pos.1 r0] rcases norm_le_div_pow_of_pos_of_lt_radius p rpos rlt with ⟨C, Cpos, hCp⟩ diff --git a/Mathlib/Analysis/Analytic/CPolynomial.lean b/Mathlib/Analysis/Analytic/CPolynomial.lean index 9576f0b22c613e..263a5246c148b2 100644 --- a/Mathlib/Analysis/Analytic/CPolynomial.lean +++ b/Mathlib/Analysis/Analytic/CPolynomial.lean @@ -567,7 +567,7 @@ open FormalMultilinearSeries protected theorem hasFiniteFPowerSeriesOnBall : HasFiniteFPowerSeriesOnBall f f.toFormalMultilinearSeries 0 (Fintype.card ι + 1) ⊤ := - .mk' (fun m hm ↦ dif_neg (Nat.succ_le_iff.mp hm).ne) ENNReal.zero_lt_top fun y _ ↦ by + .mk' (fun _ hm ↦ dif_neg (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 diff --git a/Mathlib/Analysis/Analytic/Composition.lean b/Mathlib/Analysis/Analytic/Composition.lean index c73176c9a5ec5c..e439182fb3de17 100644 --- a/Mathlib/Analysis/Analytic/Composition.lean +++ b/Mathlib/Analysis/Analytic/Composition.lean @@ -186,7 +186,7 @@ def compAlongComposition {n : ℕ} (p : FormalMultilinearSeries 𝕜 E F) (c : C simp only [applyComposition_update, ContinuousMultilinearMap.map_smul] cont := f.cont.comp <| - continuous_pi fun i => (coe_continuous _).comp <| continuous_pi fun j => continuous_apply _ + continuous_pi fun _ => (coe_continuous _).comp <| continuous_pi fun _ => continuous_apply _ @[simp] theorem compAlongComposition_apply {n : ℕ} (p : FormalMultilinearSeries 𝕜 E F) (c : Composition n) diff --git a/Mathlib/Analysis/Analytic/Constructions.lean b/Mathlib/Analysis/Analytic/Constructions.lean index 42de038a5780f5..61e423dab7c7dd 100644 --- a/Mathlib/Analysis/Analytic/Constructions.lean +++ b/Mathlib/Analysis/Analytic/Constructions.lean @@ -456,7 +456,7 @@ lemma HasFPowerSeriesWithinOnBall.pi apply FormalMultilinearSeries.le_radius_pi (fun i ↦ ?_) exact (hf i).r_le r_pos := hr - hasSum {y} m hy := Pi.hasSum.2 (fun i ↦ (hf i).hasSum m hy) + hasSum {_} m hy := Pi.hasSum.2 (fun i ↦ (hf i).hasSum m hy) lemma hasFPowerSeriesWithinOnBall_pi_iff (hr : 0 < r) : HasFPowerSeriesWithinOnBall (fun x ↦ (f · x)) (FormalMultilinearSeries.pi p) s e r diff --git a/Mathlib/Analysis/Asymptotics/Asymptotics.lean b/Mathlib/Analysis/Asymptotics/Asymptotics.lean index 15ae960d1d41e7..47377b0bb7c8cf 100644 --- a/Mathlib/Analysis/Asymptotics/Asymptotics.lean +++ b/Mathlib/Analysis/Asymptotics/Asymptotics.lean @@ -1822,7 +1822,7 @@ theorem IsBigOWith.right_le_sub_of_lt_one {f₁ f₂ : α → E'} (h : IsBigOWit theorem IsBigOWith.right_le_add_of_lt_one {f₁ f₂ : α → E'} (h : IsBigOWith c l f₁ f₂) (hc : c < 1) : IsBigOWith (1 / (1 - c)) l f₂ fun x => f₁ x + f₂ x := - (h.neg_right.right_le_sub_of_lt_one hc).neg_right.of_neg_left.congr rfl (fun x ↦ rfl) fun x ↦ by + (h.neg_right.right_le_sub_of_lt_one hc).neg_right.of_neg_left.congr rfl (fun _ ↦ rfl) fun x ↦ by rw [neg_sub, sub_neg_eq_add] @[deprecated (since := "2024-01-31")] @@ -1872,7 +1872,7 @@ theorem isBigO_nat_atTop_iff {f : ℕ → E''} {g : ℕ → F''} (h : ∀ x, g x theorem isBigO_one_nat_atTop_iff {f : ℕ → E''} : f =O[atTop] (fun _n => 1 : ℕ → ℝ) ↔ ∃ C, ∀ n, ‖f n‖ ≤ C := - Iff.trans (isBigO_nat_atTop_iff fun n h => (one_ne_zero h).elim) <| by + Iff.trans (isBigO_nat_atTop_iff fun _ h => (one_ne_zero h).elim) <| by simp only [norm_one, mul_one] theorem isBigOWith_pi {ι : Type*} [Fintype ι] {E' : ι → Type*} [∀ i, NormedAddCommGroup (E' i)] @@ -1958,8 +1958,8 @@ theorem isBigOWith_congr (e : PartialHomeomorph α β) {b : β} (hb : b ∈ e.ta rwa [ContinuousAt, e.rightInvOn hb] at this, fun h => (h.comp_tendsto (e.continuousAt_symm hb)).congr' rfl - ((e.eventually_right_inverse hb).mono fun x hx => congr_arg f hx) - ((e.eventually_right_inverse hb).mono fun x hx => congr_arg g hx)⟩ + ((e.eventually_right_inverse hb).mono fun _ hx => congr_arg f hx) + ((e.eventually_right_inverse hb).mono fun _ hx => congr_arg g hx)⟩ /-- Transfer `IsBigO` over a `PartialHomeomorph`. -/ theorem isBigO_congr (e : PartialHomeomorph α β) {b : β} (hb : b ∈ e.target) {f : β → E} diff --git a/Mathlib/Analysis/BoxIntegral/Basic.lean b/Mathlib/Analysis/BoxIntegral/Basic.lean index e9d54c402baeff..77776a456f6e39 100644 --- a/Mathlib/Analysis/BoxIntegral/Basic.lean +++ b/Mathlib/Analysis/BoxIntegral/Basic.lean @@ -872,11 +872,11 @@ less than or equal to `ε * B J`. Then `f` is McShane integrable on `I` with integral `g I`. -/ theorem HasIntegral.mcShane_of_forall_isLittleO (B : ι →ᵇᵃ[I] ℝ) (hB0 : ∀ J, 0 ≤ B J) - (g : ι →ᵇᵃ[I] F) (H : ∀ (c : ℝ≥0), ∀ x ∈ Box.Icc I, ∀ ε > (0 : ℝ), ∃ δ > 0, ∀ J ≤ I, + (g : ι →ᵇᵃ[I] F) (H : ∀ (_ : ℝ≥0), ∀ x ∈ Box.Icc I, ∀ ε > (0 : ℝ), ∃ δ > 0, ∀ J ≤ I, Box.Icc J ⊆ Metric.closedBall x δ → dist (vol J (f x)) (g J) ≤ ε * B J) : HasIntegral I McShane f vol (g I) := (HasIntegral.of_bRiemann_eq_false_of_forall_isLittleO (l := McShane) rfl B hB0 g ∅ countable_empty - (fun ⟨_x, hx⟩ => hx.elim) fun c x hx => hx.2.elim) <| by + (fun ⟨_x, hx⟩ => hx.elim) fun _ _ hx => hx.2.elim) <| by simpa only [McShane, Bool.coe_sort_false, false_imp_iff, true_imp_iff, diff_empty] using H end BoxIntegral diff --git a/Mathlib/Analysis/BoxIntegral/Partition/Basic.lean b/Mathlib/Analysis/BoxIntegral/Partition/Basic.lean index 788c55499703d4..c8af644f555c90 100644 --- a/Mathlib/Analysis/BoxIntegral/Partition/Basic.lean +++ b/Mathlib/Analysis/BoxIntegral/Partition/Basic.lean @@ -113,9 +113,9 @@ instance : LE (Prepartition I) := instance partialOrder : PartialOrder (Prepartition I) where le := (· ≤ ·) - le_refl π I hI := ⟨I, hI, le_rfl⟩ - le_trans π₁ π₂ π₃ h₁₂ h₂₃ I₁ hI₁ := - let ⟨I₂, hI₂, hI₁₂⟩ := h₁₂ hI₁ + le_refl _ I hI := ⟨I, hI, le_rfl⟩ + le_trans _ _ _ h₁₂ h₂₃ _ hI₁ := + let ⟨_, hI₂, hI₁₂⟩ := h₁₂ hI₁ let ⟨I₃, hI₃, hI₂₃⟩ := h₂₃ hI₂ ⟨I₃, hI₃, hI₁₂.trans hI₂₃⟩ le_antisymm := by @@ -129,7 +129,7 @@ instance partialOrder : PartialOrder (Prepartition I) where instance : OrderTop (Prepartition I) where top := single I I le_rfl - le_top π J hJ := ⟨I, by simp, π.le_of_mem hJ⟩ + le_top π _ hJ := ⟨I, by simp, π.le_of_mem hJ⟩ instance : OrderBot (Prepartition I) where bot := ⟨∅, @@ -558,11 +558,11 @@ theorem sum_fiberwise {α M} [AddCommMonoid M] (π : Prepartition I) (f : Box ι @[simps] def disjUnion (π₁ π₂ : Prepartition I) (h : Disjoint π₁.iUnion π₂.iUnion) : Prepartition I where boxes := π₁.boxes ∪ π₂.boxes - le_of_mem' J hJ := (Finset.mem_union.1 hJ).elim π₁.le_of_mem π₂.le_of_mem + le_of_mem' _ hJ := (Finset.mem_union.1 hJ).elim π₁.le_of_mem π₂.le_of_mem pairwiseDisjoint := suffices ∀ J₁ ∈ π₁, ∀ J₂ ∈ π₂, J₁ ≠ J₂ → Disjoint (J₁ : Set (ι → ℝ)) J₂ by simpa [pairwise_union_of_symmetric (symmetric_disjoint.comap _), pairwiseDisjoint] - fun J₁ h₁ J₂ h₂ _ => h.mono (π₁.subset_iUnion h₁) (π₂.subset_iUnion h₂) + fun _ h₁ _ h₂ _ => h.mono (π₁.subset_iUnion h₁) (π₂.subset_iUnion h₂) @[simp] theorem mem_disjUnion (H : Disjoint π₁.iUnion π₂.iUnion) : diff --git a/Mathlib/Analysis/BoxIntegral/Partition/Split.lean b/Mathlib/Analysis/BoxIntegral/Partition/Split.lean index 06363982a75387..3e39d436eeb976 100644 --- a/Mathlib/Analysis/BoxIntegral/Partition/Split.lean +++ b/Mathlib/Analysis/BoxIntegral/Partition/Split.lean @@ -78,7 +78,7 @@ theorem splitLower_eq_self : I.splitLower i x = I ↔ I.upper i ≤ x := by theorem splitLower_def [DecidableEq ι] {i x} (h : x ∈ Ioo (I.lower i) (I.upper i)) (h' : ∀ j, I.lower j < update I.upper i x j := (forall_update_iff I.upper fun j y => I.lower j < y).2 - ⟨h.1, fun j _ => I.lower_lt_upper _⟩) : + ⟨h.1, fun _ _ => I.lower_lt_upper _⟩) : I.splitLower i x = (⟨I.lower, update I.upper i x, h'⟩ : Box ι) := by simp (config := { unfoldPartialApp := true }) only [splitLower, mk'_eq_coe, min_eq_left h.2.le, update, and_self] @@ -114,7 +114,7 @@ theorem splitUpper_eq_self : I.splitUpper i x = I ↔ x ≤ I.lower i := by theorem splitUpper_def [DecidableEq ι] {i x} (h : x ∈ Ioo (I.lower i) (I.upper i)) (h' : ∀ j, update I.lower i x j < I.upper j := (forall_update_iff I.lower fun j y => y < I.upper j).2 - ⟨h.2, fun j _ => I.lower_lt_upper _⟩) : + ⟨h.2, fun _ _ => I.lower_lt_upper _⟩) : I.splitUpper i x = (⟨update I.lower i x, I.upper, h'⟩ : Box ι) := by simp (config := { unfoldPartialApp := true }) only [splitUpper, mk'_eq_coe, max_eq_left h.1.le, update, and_self] diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unique.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unique.lean index 155a1b6dd519cd..00f8c9bf97f184 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unique.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unique.lean @@ -33,7 +33,7 @@ variable {𝕜 A : Type*} [RCLike 𝕜] theorem RCLike.uniqueContinuousFunctionalCalculus_of_compactSpace_spectrum [TopologicalSpace A] [T2Space A] [Ring A] [StarRing A] [Algebra 𝕜 A] [h : ∀ a : A, CompactSpace (spectrum 𝕜 a)] : UniqueContinuousFunctionalCalculus 𝕜 A where - eq_of_continuous_of_map_id s hs φ ψ hφ hψ h := + eq_of_continuous_of_map_id s _ φ ψ hφ hψ h := ContinuousMap.starAlgHom_ext_map_X hφ hψ <| by convert h using 1 all_goals exact congr_arg _ (by ext; simp) diff --git a/Mathlib/Analysis/CStarAlgebra/Module/Defs.lean b/Mathlib/Analysis/CStarAlgebra/Module/Defs.lean index a94e81711816a6..c8481551954738 100644 --- a/Mathlib/Analysis/CStarAlgebra/Module/Defs.lean +++ b/Mathlib/Analysis/CStarAlgebra/Module/Defs.lean @@ -253,7 +253,7 @@ protected lemma norm_triangle [CompleteSpace A] (x y : E) : ‖x + y‖ ≤ ‖x /-- This allows us to get `NormedAddCommGroup` and `NormedSpace` instances on `E` via `NormedAddCommGroup.ofCore` and `NormedSpace.ofCore`. -/ lemma normedSpaceCore [CompleteSpace A] : NormedSpace.Core ℂ E where - norm_nonneg x := CStarModule.norm_nonneg + norm_nonneg _ := CStarModule.norm_nonneg norm_eq_zero_iff x := norm_zero_iff x norm_smul c x := by simp [norm_eq_sqrt_norm_inner_self, norm_smul, ← mul_assoc] norm_triangle x y := CStarModule.norm_triangle x y diff --git a/Mathlib/Analysis/CStarAlgebra/Multiplier.lean b/Mathlib/Analysis/CStarAlgebra/Multiplier.lean index 3c84852d4f4050..d5f3b758aada7b 100644 --- a/Mathlib/Analysis/CStarAlgebra/Multiplier.lean +++ b/Mathlib/Analysis/CStarAlgebra/Multiplier.lean @@ -363,7 +363,7 @@ instance instAlgebra : Algebra 𝕜 𝓜(𝕜, A) where simp_rw [Prod.algebraMap_apply, Algebra.algebraMap_eq_smul_one, smul_apply, one_apply, mul_smul_comm, smul_mul_assoc] } map_one' := ext (𝕜 := 𝕜) (A := A) _ _ <| map_one <| algebraMap 𝕜 ((A →L[𝕜] A) × (A →L[𝕜] A)) - map_mul' k₁ k₂ := + map_mul' _ _ := ext (𝕜 := 𝕜) (A := A) _ _ <| Prod.ext (map_mul (algebraMap 𝕜 (A →L[𝕜] A)) _ _) ((map_mul (algebraMap 𝕜 (A →L[𝕜] A)) _ _).trans (Algebra.commutes _ _)) diff --git a/Mathlib/Analysis/Calculus/BumpFunction/InnerProduct.lean b/Mathlib/Analysis/Calculus/BumpFunction/InnerProduct.lean index c5c01358f87478..c501d76685ccc7 100644 --- a/Mathlib/Analysis/Calculus/BumpFunction/InnerProduct.lean +++ b/Mathlib/Analysis/Calculus/BumpFunction/InnerProduct.lean @@ -45,7 +45,7 @@ noncomputable def ContDiffBumpBase.ofInnerProductSpace : ContDiffBumpBase E wher · refine smoothTransition.contDiffAt.comp _ (ContDiffAt.div ?_ ?_ hR.ne') · exact contDiffAt_fst.sub (contDiffAt_snd.norm ℝ hx) · exact contDiffAt_fst.sub contDiffAt_const - eq_one R hR x hx := smoothTransition.one_of_one_le <| (one_le_div <| sub_pos.2 hR).2 <| + eq_one _ hR _ hx := smoothTransition.one_of_one_le <| (one_le_div <| sub_pos.2 hR).2 <| sub_le_sub_left hx _ support R hR := by ext x diff --git a/Mathlib/Analysis/Calculus/ContDiff/Basic.lean b/Mathlib/Analysis/Calculus/ContDiff/Basic.lean index 56efdab13165b6..f4d4b2b3d92ccf 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/Basic.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/Basic.lean @@ -1776,7 +1776,7 @@ def restrContDiff (f : PartialHomeomorph E F) (n : ℕ) : PartialHomeomorph E F haveI H : f.IsImage {x | ContDiffAt 𝕜 n f x ∧ ContDiffAt 𝕜 n f.symm (f x)} {y | ContDiffAt 𝕜 n f.symm y ∧ ContDiffAt 𝕜 n f (f.symm y)} := fun x hx ↦ by simp [hx, and_comm] - H.restr <| isOpen_iff_mem_nhds.2 fun x ⟨hxs, hxf, hxf'⟩ ↦ + H.restr <| isOpen_iff_mem_nhds.2 fun _ ⟨hxs, hxf, hxf'⟩ ↦ inter_mem (f.open_source.mem_nhds hxs) <| hxf.eventually.and <| f.continuousAt hxs hxf'.eventually diff --git a/Mathlib/Analysis/Calculus/LineDeriv/Basic.lean b/Mathlib/Analysis/Calculus/LineDeriv/Basic.lean index c3b79965c35ff5..3de1ac70f45587 100644 --- a/Mathlib/Analysis/Calculus/LineDeriv/Basic.lean +++ b/Mathlib/Analysis/Calculus/LineDeriv/Basic.lean @@ -176,7 +176,7 @@ theorem LineDifferentiableWithinAt.mono (h : LineDifferentiableWithinAt 𝕜 f t theorem HasLineDerivWithinAt.congr_mono (h : HasLineDerivWithinAt 𝕜 f f' s x v) (ht : EqOn f₁ f t) (hx : f₁ x = f x) (h₁ : t ⊆ s) : HasLineDerivWithinAt 𝕜 f₁ f' t x v := - HasDerivWithinAt.congr_mono h (fun y hy ↦ ht hy) (by simpa using hx) (preimage_mono h₁) + HasDerivWithinAt.congr_mono h (fun _ hy ↦ ht hy) (by simpa using hx) (preimage_mono h₁) theorem HasLineDerivWithinAt.congr (h : HasLineDerivWithinAt 𝕜 f f' s x v) (hs : EqOn f₁ f s) (hx : f₁ x = f x) : HasLineDerivWithinAt 𝕜 f₁ f' s x v := @@ -199,7 +199,7 @@ theorem LineDifferentiableWithinAt.congr (h : LineDifferentiableWithinAt 𝕜 f theorem lineDerivWithin_congr (hs : EqOn f₁ f s) (hx : f₁ x = f x) : lineDerivWithin 𝕜 f₁ s x v = lineDerivWithin 𝕜 f s x v := - derivWithin_congr (fun y hy ↦ hs hy) (by simpa using hx) + derivWithin_congr (fun _ hy ↦ hs hy) (by simpa using hx) theorem lineDerivWithin_congr' (hs : EqOn f₁ f s) (hx : x ∈ s) : lineDerivWithin 𝕜 f₁ s x v = lineDerivWithin 𝕜 f s x v := diff --git a/Mathlib/Analysis/Calculus/LocalExtr/Polynomial.lean b/Mathlib/Analysis/Calculus/LocalExtr/Polynomial.lean index 062cf3b3b7880b..0713f405463731 100644 --- a/Mathlib/Analysis/Calculus/LocalExtr/Polynomial.lean +++ b/Mathlib/Analysis/Calculus/LocalExtr/Polynomial.lean @@ -59,14 +59,14 @@ theorem card_roots_le_derivative (p : ℝ[X]) : Multiset.card p.roots = ∑ x ∈ p.roots.toFinset, p.roots.count x := (Multiset.toFinset_sum_count_eq _).symm _ = ∑ x ∈ p.roots.toFinset, (p.roots.count x - 1 + 1) := - (Eq.symm <| Finset.sum_congr rfl fun x hx => tsub_add_cancel_of_le <| + (Eq.symm <| Finset.sum_congr rfl fun _ hx => tsub_add_cancel_of_le <| Nat.succ_le_iff.2 <| Multiset.count_pos.2 <| Multiset.mem_toFinset.1 hx) _ = (∑ x ∈ p.roots.toFinset, (p.rootMultiplicity x - 1)) + p.roots.toFinset.card := by simp only [Finset.sum_add_distrib, Finset.card_eq_sum_ones, count_roots] _ ≤ (∑ x ∈ p.roots.toFinset, p.derivative.rootMultiplicity x) + ((p.derivative.roots.toFinset \ p.roots.toFinset).card + 1) := (add_le_add - (Finset.sum_le_sum fun x _ => rootMultiplicity_sub_one_le_derivative_rootMultiplicity _ _) + (Finset.sum_le_sum fun _ _ => rootMultiplicity_sub_one_le_derivative_rootMultiplicity _ _) p.card_roots_toFinset_le_card_roots_derivative_diff_roots_succ) _ ≤ (∑ x ∈ p.roots.toFinset, p.derivative.roots.count x) + ((∑ x ∈ p.derivative.roots.toFinset \ p.roots.toFinset, diff --git a/Mathlib/Analysis/Calculus/MeanValue.lean b/Mathlib/Analysis/Calculus/MeanValue.lean index 703da3c9d5c78d..9e0dbaf2abcb97 100644 --- a/Mathlib/Analysis/Calculus/MeanValue.lean +++ b/Mathlib/Analysis/Calculus/MeanValue.lean @@ -1039,14 +1039,14 @@ of the real line. If `f` is differentiable on the interior of `D` and `f'` is no lemma monotoneOn_of_hasDerivWithinAt_nonneg {D : Set ℝ} (hD : Convex ℝ D) {f f' : ℝ → ℝ} (hf : ContinuousOn f D) (hf' : ∀ x ∈ interior D, HasDerivWithinAt f (f' x) (interior D) x) (hf'₀ : ∀ x ∈ interior D, 0 ≤ f' x) : MonotoneOn f D := - monotoneOn_of_deriv_nonneg hD hf (fun x hx ↦ (hf' _ hx).differentiableWithinAt) fun x hx ↦ by + monotoneOn_of_deriv_nonneg hD hf (fun _ hx ↦ (hf' _ hx).differentiableWithinAt) fun x hx ↦ by rw [deriv_eqOn isOpen_interior hf' hx]; exact hf'₀ _ hx /-- Let `f : ℝ → ℝ` be a differentiable function. If `f'` is nonnegative, then `f` is a monotone function. -/ lemma monotone_of_hasDerivAt_nonneg {f f' : ℝ → ℝ} (hf : ∀ x, HasDerivAt f (f' x) x) (hf' : 0 ≤ f') : Monotone f := - monotone_of_deriv_nonneg (fun x ↦ (hf _).differentiableAt) fun x ↦ by + monotone_of_deriv_nonneg (fun _ ↦ (hf _).differentiableAt) fun x ↦ by rw [(hf _).deriv]; exact hf' _ /-- Let `f` be a function continuous on a convex (or, equivalently, connected) subset `D` @@ -1114,14 +1114,14 @@ of the real line. If `f` is differentiable on the interior of `D` and `f'` is no lemma antitoneOn_of_hasDerivWithinAt_nonpos {D : Set ℝ} (hD : Convex ℝ D) {f f' : ℝ → ℝ} (hf : ContinuousOn f D) (hf' : ∀ x ∈ interior D, HasDerivWithinAt f (f' x) (interior D) x) (hf'₀ : ∀ x ∈ interior D, f' x ≤ 0) : AntitoneOn f D := - antitoneOn_of_deriv_nonpos hD hf (fun x hx ↦ (hf' _ hx).differentiableWithinAt) fun x hx ↦ by + antitoneOn_of_deriv_nonpos hD hf (fun _ hx ↦ (hf' _ hx).differentiableWithinAt) fun x hx ↦ by rw [deriv_eqOn isOpen_interior hf' hx]; exact hf'₀ _ hx /-- Let `f : ℝ → ℝ` be a differentiable function. If `f'` is nonpositive, then `f` is an antitone function. -/ lemma antitone_of_hasDerivAt_nonpos {f f' : ℝ → ℝ} (hf : ∀ x, HasDerivAt f (f' x) x) (hf' : f' ≤ 0) : Antitone f := - antitone_of_deriv_nonpos (fun x ↦ (hf _).differentiableAt) fun x ↦ by + antitone_of_deriv_nonpos (fun _ ↦ (hf _).differentiableAt) fun x ↦ by rw [(hf _).deriv]; exact hf' _ /-! ### Functions `f : E → ℝ` -/ diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean index f9c084804d861c..303996fd5e2ddf 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Basic.lean @@ -400,7 +400,7 @@ section PosRealAction instance posRealAction : MulAction { x : ℝ // 0 < x } ℍ where smul x z := mk ((x : ℝ) • (z : ℂ)) <| by simpa using mul_pos x.2 z.2 - one_smul z := Subtype.ext <| one_smul _ _ + one_smul _ := Subtype.ext <| one_smul _ _ mul_smul x y z := Subtype.ext <| mul_smul (x : ℝ) y (z : ℂ) variable (x : { x : ℝ // 0 < x }) (z : ℍ) diff --git a/Mathlib/Analysis/Convex/Basic.lean b/Mathlib/Analysis/Convex/Basic.lean index 3c3fc373308f38..4f249aa4e30230 100644 --- a/Mathlib/Analysis/Convex/Basic.lean +++ b/Mathlib/Analysis/Convex/Basic.lean @@ -76,7 +76,7 @@ theorem convex_iff_pointwise_add_subset : (by rintro hA a b ha hb hab w ⟨au, ⟨u, hu, rfl⟩, bv, ⟨v, hv, rfl⟩, rfl⟩ exact hA hu hv ha hb hab) - fun h x hx y hy a b ha hb hab => (h ha hb hab) (Set.add_mem_add ⟨_, hx, rfl⟩ ⟨_, hy, rfl⟩) + fun h _ hx _ hy _ _ ha hb hab => (h ha hb hab) (Set.add_mem_add ⟨_, hx, rfl⟩ ⟨_, hy, rfl⟩) alias ⟨Convex.set_combo_subset, _⟩ := convex_iff_pointwise_add_subset @@ -655,7 +655,7 @@ def stdSimplexEquivIcc : stdSimplex 𝕜 (Fin 2) ≃ Icc (0 : 𝕜) 1 where calc (1 : 𝕜) - f.1 0 = f.1 0 + f.1 1 - f.1 0 := by rw [← Fin.sum_univ_two f.1, f.2.2] _ = f.1 1 := add_sub_cancel_left _ _ - right_inv x := Subtype.eq rfl + right_inv _ := Subtype.eq rfl end OrderedRing diff --git a/Mathlib/Analysis/Convex/Body.lean b/Mathlib/Analysis/Convex/Body.lean index 219c7807cb05dc..db92e77472f197 100644 --- a/Mathlib/Analysis/Convex/Body.lean +++ b/Mathlib/Analysis/Convex/Body.lean @@ -181,7 +181,7 @@ noncomputable instance : PseudoMetricSpace (ConvexBody V) where dist K L := Metric.hausdorffDist (K : Set V) L dist_self _ := Metric.hausdorffDist_self_zero dist_comm _ _ := Metric.hausdorffDist_comm - dist_triangle K L M := Metric.hausdorffDist_triangle hausdorffEdist_ne_top + dist_triangle _ _ _ := Metric.hausdorffDist_triangle hausdorffEdist_ne_top @[simp, norm_cast] theorem hausdorffDist_coe : Metric.hausdorffDist (K : Set V) L = dist K L := diff --git a/Mathlib/Analysis/Convex/Caratheodory.lean b/Mathlib/Analysis/Convex/Caratheodory.lean index 6bae295f47f1a4..356e64e002984b 100644 --- a/Mathlib/Analysis/Convex/Caratheodory.lean +++ b/Mathlib/Analysis/Convex/Caratheodory.lean @@ -142,7 +142,7 @@ variable {s : Set E} /-- **Carathéodory's convexity theorem** -/ theorem convexHull_eq_union : convexHull 𝕜 s = - ⋃ (t : Finset E) (hss : ↑t ⊆ s) (hai : AffineIndependent 𝕜 ((↑) : t → E)), convexHull 𝕜 ↑t := by + ⋃ (t : Finset E) (_ : ↑t ⊆ s) (_ : AffineIndependent 𝕜 ((↑) : t → E)), convexHull 𝕜 ↑t := by apply Set.Subset.antisymm · intro x hx simp only [exists_prop, Set.mem_iUnion] diff --git a/Mathlib/Analysis/Convex/Combination.lean b/Mathlib/Analysis/Convex/Combination.lean index 399464ada74063..87bc0806851213 100644 --- a/Mathlib/Analysis/Convex/Combination.lean +++ b/Mathlib/Analysis/Convex/Combination.lean @@ -390,7 +390,7 @@ theorem Set.Finite.convexHull_eq {s : Set E} (hs : s.Finite) : convexHull R s = /-- A weak version of Carathéodory's theorem. -/ theorem convexHull_eq_union_convexHull_finite_subsets (s : Set E) : - convexHull R s = ⋃ (t : Finset E) (w : ↑t ⊆ s), convexHull R ↑t := by + convexHull R s = ⋃ (t : Finset E) (_ : ↑t ⊆ s), convexHull R ↑t := by refine Subset.antisymm ?_ ?_ · rw [_root_.convexHull_eq] rintro x ⟨ι, t, w, z, hw₀, hw₁, hz, rfl⟩ diff --git a/Mathlib/Analysis/Convex/Gauge.lean b/Mathlib/Analysis/Convex/Gauge.lean index df43239a123dee..5ecb5e8b2c4cdb 100644 --- a/Mathlib/Analysis/Convex/Gauge.lean +++ b/Mathlib/Analysis/Convex/Gauge.lean @@ -201,7 +201,7 @@ theorem Convex.gauge_le (hs : Convex ℝ s) (h₀ : (0 : E) ∈ s) (absorbs : Ab exact eq_empty_iff_forall_not_mem.2 fun x hx => ha <| (gauge_nonneg _).trans hx theorem Balanced.starConvex (hs : Balanced ℝ s) : StarConvex ℝ 0 s := - starConvex_zero_iff.2 fun x hx a ha₀ ha₁ => + starConvex_zero_iff.2 fun _ hx a ha₀ ha₁ => hs _ (by rwa [Real.norm_of_nonneg ha₀]) (smul_mem_smul_set hx) theorem le_gauge_of_not_mem (hs₀ : StarConvex ℝ 0 s) (hs₂ : Absorbs ℝ s {x}) (hx : x ∉ a • s) : diff --git a/Mathlib/Analysis/Convex/Normed.lean b/Mathlib/Analysis/Convex/Normed.lean index bfb9ac2e29cd37..235a27716dee47 100644 --- a/Mathlib/Analysis/Convex/Normed.lean +++ b/Mathlib/Analysis/Convex/Normed.lean @@ -112,7 +112,7 @@ instance (priority := 100) NormedSpace.instPathConnectedSpace : PathConnectedSpa TopologicalAddGroup.pathConnectedSpace instance (priority := 100) NormedSpace.instLocPathConnectedSpace : LocPathConnectedSpace E := - locPathConnected_of_bases (fun x => Metric.nhds_basis_ball) fun x r r_pos => + locPathConnected_of_bases (fun _ => Metric.nhds_basis_ball) fun x r r_pos => (convex_ball x r).isPathConnected <| by simp [r_pos] theorem Wbtw.dist_add_dist {x y z : P} (h : Wbtw ℝ x y z) : diff --git a/Mathlib/Analysis/Convex/Segment.lean b/Mathlib/Analysis/Convex/Segment.lean index 9f5026dbeb8cc3..1c4e577df9e16a 100644 --- a/Mathlib/Analysis/Convex/Segment.lean +++ b/Mathlib/Analysis/Convex/Segment.lean @@ -171,14 +171,14 @@ end DenselyOrdered theorem segment_eq_image (x y : E) : [x -[𝕜] y] = (fun θ : 𝕜 => (1 - θ) • x + θ • y) '' Icc (0 : 𝕜) 1 := - Set.ext fun z => + Set.ext fun _ => ⟨fun ⟨a, b, ha, hb, hab, hz⟩ => ⟨b, ⟨hb, hab ▸ le_add_of_nonneg_left ha⟩, hab ▸ hz ▸ by simp only [add_sub_cancel_right]⟩, fun ⟨θ, ⟨hθ₀, hθ₁⟩, hz⟩ => ⟨1 - θ, θ, sub_nonneg.2 hθ₁, hθ₀, sub_add_cancel _ _, hz⟩⟩ theorem openSegment_eq_image (x y : E) : openSegment 𝕜 x y = (fun θ : 𝕜 => (1 - θ) • x + θ • y) '' Ioo (0 : 𝕜) 1 := - Set.ext fun z => + Set.ext fun _ => ⟨fun ⟨a, b, ha, hb, hab, hz⟩ => ⟨b, ⟨hb, hab ▸ lt_add_of_pos_left _ ha⟩, hab ▸ hz ▸ by simp only [add_sub_cancel_right]⟩, fun ⟨θ, ⟨hθ₀, hθ₁⟩, hz⟩ => ⟨1 - θ, θ, sub_pos.2 hθ₁, hθ₀, sub_add_cancel _ _, hz⟩⟩ diff --git a/Mathlib/Analysis/InnerProductSpace/Adjoint.lean b/Mathlib/Analysis/InnerProductSpace/Adjoint.lean index d70316a5027b3d..b6803862c58c6f 100644 --- a/Mathlib/Analysis/InnerProductSpace/Adjoint.lean +++ b/Mathlib/Analysis/InnerProductSpace/Adjoint.lean @@ -528,8 +528,8 @@ noncomputable def linearIsometryEquiv : unitary (H →L[𝕜] H) ≃* (H ≃ₗ inv_val := by ext; simp } exact IsUnit.mem_unitary_of_star_mul_self ⟨e', rfl⟩ <| (e : H →L[𝕜] H).norm_map_iff_adjoint_comp_self.mp e.norm_map } - left_inv u := Subtype.ext rfl - right_inv e := LinearIsometryEquiv.ext fun x ↦ rfl + left_inv _ := Subtype.ext rfl + right_inv _ := LinearIsometryEquiv.ext fun _ ↦ rfl map_mul' u v := by ext; rfl @[simp] diff --git a/Mathlib/Analysis/InnerProductSpace/Basic.lean b/Mathlib/Analysis/InnerProductSpace/Basic.lean index 1e37689bab1f99..6862b4376ce2a7 100644 --- a/Mathlib/Analysis/InnerProductSpace/Basic.lean +++ b/Mathlib/Analysis/InnerProductSpace/Basic.lean @@ -470,7 +470,7 @@ def toNormedAddCommGroup : NormedAddCommGroup F := simp only [← inner_self_eq_norm_mul_norm, inner_add_add_self, mul_add, mul_comm, map_add] linarith exact nonneg_le_nonneg_of_sq_le_sq (add_nonneg (sqrt_nonneg _) (sqrt_nonneg _)) this - eq_zero_of_map_eq_zero' := fun x hx => + eq_zero_of_map_eq_zero' := fun _ hx => normSq_eq_zero.1 <| (sqrt_eq_zero inner_self_nonneg).1 hx } attribute [local instance] toNormedAddCommGroup @@ -2040,7 +2040,7 @@ theorem OrthogonalFamily.inner_right_dfinsupp ⟪V i v, l.sum fun j => V j⟫ = l.sum fun j => fun w => ⟪V i v, V j w⟫ := DFinsupp.inner_sum (fun j => V j) l (V i v) _ = l.sum fun j => fun w => ite (i = j) ⟪V i v, V j w⟫ 0 := - (congr_arg l.sum <| funext fun j => funext <| hV.eq_ite v) + (congr_arg l.sum <| funext fun _ => funext <| hV.eq_ite v) _ = ⟪v, l i⟫ := by simp only [DFinsupp.sum, Submodule.coe_inner, Finset.sum_ite_eq, ite_eq_left_iff, DFinsupp.mem_support_toFun] @@ -2240,7 +2240,7 @@ def InnerProductSpace.rclikeToReal : InnerProductSpace ℝ E := NormedSpace.restrictScalars ℝ 𝕜 E with norm_sq_eq_inner := norm_sq_eq_inner - conj_symm := fun x y => inner_re_symm _ _ + conj_symm := fun _ _ => inner_re_symm _ _ add_left := fun x y z => by change re ⟪x + y, z⟫ = re ⟪x, z⟫ + re ⟪y, z⟫ simp only [inner_add_left, map_add] diff --git a/Mathlib/Analysis/LocallyConvex/Bounded.lean b/Mathlib/Analysis/LocallyConvex/Bounded.lean index 9463b8d6760d75..8ec28cb68b8abc 100644 --- a/Mathlib/Analysis/LocallyConvex/Bounded.lean +++ b/Mathlib/Analysis/LocallyConvex/Bounded.lean @@ -244,7 +244,7 @@ theorem isVonNBounded_of_smul_tendsto_zero {ε : ι → 𝕜} {l : Filter ι} [l theorem isVonNBounded_iff_smul_tendsto_zero {ε : ι → 𝕜} {l : Filter ι} [l.NeBot] (hε : Tendsto ε l (𝓝[≠] 0)) {S : Set E} : IsVonNBounded 𝕜 S ↔ ∀ x : ι → E, (∀ n, x n ∈ S) → Tendsto (ε • x) l (𝓝 0) := - ⟨fun hS x hxS => hS.smul_tendsto_zero (Eventually.of_forall hxS) (le_trans hε nhdsWithin_le_nhds), + ⟨fun hS _ hxS => hS.smul_tendsto_zero (Eventually.of_forall hxS) (le_trans hε nhdsWithin_le_nhds), isVonNBounded_of_smul_tendsto_zero (by exact hε self_mem_nhdsWithin)⟩ end sequence diff --git a/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean b/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean index b4165a1a770533..dff476482e1670 100644 --- a/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean +++ b/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean @@ -648,7 +648,7 @@ protected theorem _root_.WithSeminorms.equicontinuous_TFAE {κ : Type*} theorem _root_.WithSeminorms.uniformEquicontinuous_iff_exists_continuous_seminorm {κ : Type*} {q : SeminormFamily 𝕜₂ F ι'} [UniformSpace E] [UniformAddGroup E] [u : UniformSpace F] - [hu : UniformAddGroup F] (hq : WithSeminorms q) [ContinuousSMul 𝕜 E] + [UniformAddGroup F] (hq : WithSeminorms q) [ContinuousSMul 𝕜 E] (f : κ → E →ₛₗ[σ₁₂] F) : UniformEquicontinuous ((↑) ∘ f) ↔ ∀ i, ∃ p : Seminorm 𝕜 E, Continuous p ∧ ∀ k, (q i).comp (f k) ≤ p := @@ -656,7 +656,7 @@ theorem _root_.WithSeminorms.uniformEquicontinuous_iff_exists_continuous_seminor theorem _root_.WithSeminorms.uniformEquicontinuous_iff_bddAbove_and_continuous_iSup {κ : Type*} {q : SeminormFamily 𝕜₂ F ι'} [UniformSpace E] [UniformAddGroup E] [u : UniformSpace F] - [hu : UniformAddGroup F] (hq : WithSeminorms q) [ContinuousSMul 𝕜 E] + [UniformAddGroup F] (hq : WithSeminorms q) [ContinuousSMul 𝕜 E] (f : κ → E →ₛₗ[σ₁₂] F) : UniformEquicontinuous ((↑) ∘ f) ↔ ∀ i, BddAbove (range fun k ↦ (q i).comp (f k)) ∧ diff --git a/Mathlib/Analysis/Normed/Affine/ContinuousAffineMap.lean b/Mathlib/Analysis/Normed/Affine/ContinuousAffineMap.lean index 5e63c0037ade04..7491177284cf86 100644 --- a/Mathlib/Analysis/Normed/Affine/ContinuousAffineMap.lean +++ b/Mathlib/Analysis/Normed/Affine/ContinuousAffineMap.lean @@ -220,7 +220,7 @@ def toConstProdContinuousLinearMap : (V →ᴬ[𝕜] W) ≃ₗᵢ[𝕜] W × (V right_inv := by rintro ⟨v, f⟩; ext <;> simp map_add' _ _ := rfl map_smul' _ _ := rfl - norm_map' f := rfl + norm_map' _ := rfl @[simp] theorem toConstProdContinuousLinearMap_fst (f : V →ᴬ[𝕜] W) : diff --git a/Mathlib/Analysis/Normed/Algebra/Exponential.lean b/Mathlib/Analysis/Normed/Algebra/Exponential.lean index e211c1cfd4a8de..43b9083f92da7a 100644 --- a/Mathlib/Analysis/Normed/Algebra/Exponential.lean +++ b/Mathlib/Analysis/Normed/Algebra/Exponential.lean @@ -470,7 +470,7 @@ commute then `NormedSpace.exp 𝕂 (∑ i, f i) = ∏ i, NormedSpace.exp 𝕂 (f theorem exp_sum_of_commute {ι} (s : Finset ι) (f : ι → 𝔸) (h : (s : Set ι).Pairwise fun i j => Commute (f i) (f j)) : exp 𝕂 (∑ i ∈ s, f i) = - s.noncommProd (fun i => exp 𝕂 (f i)) fun i hi j hj _ => (h.of_refl hi hj).exp 𝕂 := by + s.noncommProd (fun i => exp 𝕂 (f i)) fun _ hi _ hj _ => (h.of_refl hi hj).exp 𝕂 := by classical induction' s using Finset.induction_on with a s ha ih · simp diff --git a/Mathlib/Analysis/Normed/Algebra/MatrixExponential.lean b/Mathlib/Analysis/Normed/Algebra/MatrixExponential.lean index a481e6f7c4823d..2ef0c05b42a5d3 100644 --- a/Mathlib/Analysis/Normed/Algebra/MatrixExponential.lean +++ b/Mathlib/Analysis/Normed/Algebra/MatrixExponential.lean @@ -127,7 +127,7 @@ nonrec theorem exp_add_of_commute (A B : Matrix m m 𝔸) (h : Commute A B) : nonrec theorem exp_sum_of_commute {ι} (s : Finset ι) (f : ι → Matrix m m 𝔸) (h : (s : Set ι).Pairwise fun i j => Commute (f i) (f j)) : exp 𝕂 (∑ i ∈ s, f i) = - s.noncommProd (fun i => exp 𝕂 (f i)) fun i hi j hj _ => (h.of_refl hi hj).exp 𝕂 := by + s.noncommProd (fun i => exp 𝕂 (f i)) fun _ hi _ hj _ => (h.of_refl hi hj).exp 𝕂 := by letI : SeminormedRing (Matrix m m 𝔸) := Matrix.linftyOpSemiNormedRing letI : NormedRing (Matrix m m 𝔸) := Matrix.linftyOpNormedRing letI : NormedAlgebra 𝕂 (Matrix m m 𝔸) := Matrix.linftyOpNormedAlgebra diff --git a/Mathlib/Analysis/Normed/Algebra/Spectrum.lean b/Mathlib/Analysis/Normed/Algebra/Spectrum.lean index fa49b3701161ca..04202dd932598d 100644 --- a/Mathlib/Analysis/Normed/Algebra/Spectrum.lean +++ b/Mathlib/Analysis/Normed/Algebra/Spectrum.lean @@ -552,8 +552,8 @@ def equivAlgHom : characterSpace 𝕜 A ≃ (A →ₐ[𝕜] 𝕜) where invFun f := { val := f.toContinuousLinearMap property := by rw [eq_set_map_one_map_mul]; exact ⟨map_one f, map_mul f⟩ } - left_inv f := Subtype.ext <| ContinuousLinearMap.ext fun x => rfl - right_inv f := AlgHom.ext fun x => rfl + left_inv _ := Subtype.ext <| ContinuousLinearMap.ext fun _ => rfl + right_inv _ := AlgHom.ext fun _ => rfl @[simp] theorem equivAlgHom_coe (f : characterSpace 𝕜 A) : ⇑(equivAlgHom f) = f := diff --git a/Mathlib/Analysis/Normed/Group/Basic.lean b/Mathlib/Analysis/Normed/Group/Basic.lean index 04e1413e4bea8b..e379a64547598f 100644 --- a/Mathlib/Analysis/Normed/Group/Basic.lean +++ b/Mathlib/Analysis/Normed/Group/Basic.lean @@ -285,7 +285,7 @@ existing `UniformSpace` instance on `E`)."] abbrev GroupSeminorm.toSeminormedGroup [Group E] (f : GroupSeminorm E) : SeminormedGroup E where dist x y := f (x / y) norm := f - dist_eq x y := rfl + dist_eq _ _ := rfl dist_self x := by simp only [div_self', map_one_eq_zero] dist_triangle := le_map_div_add_map_div f dist_comm := map_div_rev f diff --git a/Mathlib/Analysis/Normed/Group/Hom.lean b/Mathlib/Analysis/Normed/Group/Hom.lean index 36439765ebe215..7cde007647e8d3 100644 --- a/Mathlib/Analysis/Normed/Group/Hom.lean +++ b/Mathlib/Analysis/Normed/Group/Hom.lean @@ -630,7 +630,7 @@ variable {V W V₁ V₂ V₃ : Type*} [SeminormedAddCommGroup V] [SeminormedAddC @[simps!] def incl (s : AddSubgroup V) : NormedAddGroupHom s V where toFun := (Subtype.val : s → V) - map_add' v w := AddSubgroup.coe_add _ _ _ + map_add' _ _ := AddSubgroup.coe_add _ _ _ bound' := ⟨1, fun v => by rw [one_mul, AddSubgroup.coe_norm]⟩ theorem norm_incl {V' : AddSubgroup V} (x : V') : ‖incl _ x‖ = ‖x‖ := diff --git a/Mathlib/Analysis/Normed/Group/SemiNormedGrp.lean b/Mathlib/Analysis/Normed/Group/SemiNormedGrp.lean index bb705ce63bda8f..40b402cc07b735 100644 --- a/Mathlib/Analysis/Normed/Group/SemiNormedGrp.lean +++ b/Mathlib/Analysis/Normed/Group/SemiNormedGrp.lean @@ -131,7 +131,7 @@ instance : CoeSort SemiNormedGrp₁ Type* where instance : LargeCategory.{u} SemiNormedGrp₁ where Hom X Y := { f : NormedAddGroupHom X Y // f.NormNoninc } id X := ⟨NormedAddGroupHom.id X, NormedAddGroupHom.NormNoninc.id⟩ - comp {X Y Z} f g := ⟨g.1.comp f.1, g.2.comp f.2⟩ + comp {_ _ _} f g := ⟨g.1.comp f.1, g.2.comp f.2⟩ -- Porting note (#10754): added instance instance instFunLike (X Y : SemiNormedGrp₁) : FunLike (X ⟶ Y) X Y where diff --git a/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Kernels.lean b/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Kernels.lean index f70d7104b5b932..7bc0416e6ac23a 100644 --- a/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Kernels.lean +++ b/Mathlib/Analysis/Normed/Group/SemiNormedGrp/Kernels.lean @@ -78,7 +78,7 @@ instance : HasCokernels SemiNormedGrp₁.{u} where simp -- This used to be the end of the proof before leanprover/lean4#2644 erw [zero_apply]) - fun s m w => + fun _ _ w => Subtype.eq (NormedAddGroupHom.lift_unique f.1.range _ _ _ (congr_arg Subtype.val w : _)) } @@ -123,7 +123,7 @@ instance hasLimit_parallelPair {V W : SemiNormedGrp.{u}} (f g : V ⟶ W) : NormedAddGroupHom.ker.lift (Fork.ι c) _ <| show NormedAddGroupHom.compHom (f - g) c.ι = 0 by rw [AddMonoidHom.map_sub, AddMonoidHom.sub_apply, sub_eq_zero]; exact c.condition) - (fun c => NormedAddGroupHom.ker.incl_comp_lift _ _ _) fun c g h => by + (fun _ => NormedAddGroupHom.ker.incl_comp_lift _ _ _) fun c g h => by -- Porting note: the `simp_rw` was `rw [← h]` but motive is not type correct in mathlib4 ext x; dsimp; simp_rw [← h]; rfl} @@ -179,7 +179,7 @@ def isColimitCokernelCocone {X Y : SemiNormedGrp.{u}} (f : X ⟶ Y) : simp -- This used to be the end of the proof before leanprover/lean4#2644 erw [zero_apply]) - fun s m w => NormedAddGroupHom.lift_unique f.range _ _ _ w + fun _ _ w => NormedAddGroupHom.lift_unique f.range _ _ _ w instance : HasCokernels SemiNormedGrp.{u} where has_colimit f := diff --git a/Mathlib/Analysis/Normed/Group/Seminorm.lean b/Mathlib/Analysis/Normed/Group/Seminorm.lean index 06d80361d16b3a..eede911fb046db 100644 --- a/Mathlib/Analysis/Normed/Group/Seminorm.lean +++ b/Mathlib/Analysis/Normed/Group/Seminorm.lean @@ -145,7 +145,7 @@ end NonarchAddGroupSeminormClass instance (priority := 100) NonarchAddGroupSeminormClass.toAddGroupSeminormClass [FunLike F E ℝ] [AddGroup E] [NonarchAddGroupSeminormClass F E] : AddGroupSeminormClass F E ℝ := { ‹NonarchAddGroupSeminormClass F E› with - map_add_le_add := fun f x y => + map_add_le_add := fun f _ _ => haveI h_nonneg : ∀ a, 0 ≤ f a := by intro a rw [← NonarchAddGroupSeminormClass.map_zero f, ← sub_self a] @@ -346,7 +346,7 @@ noncomputable instance : Inf (GroupSeminorm E) := map_one' := ciInf_eq_of_forall_ge_of_forall_gt_exists_lt -- Porting note: replace `add_nonneg` with `positivity` once we have the extension - (fun x => add_nonneg (apply_nonneg _ _) (apply_nonneg _ _)) fun r hr => + (fun _ => add_nonneg (apply_nonneg _ _) (apply_nonneg _ _)) fun r hr => ⟨1, by rwa [div_one, map_one_eq_zero p, map_one_eq_zero q, add_zero]⟩ mul_le' := fun x y => le_ciInf_add_ciInf fun u v => by @@ -370,8 +370,8 @@ noncomputable instance : Lattice (GroupSeminorm E) := inf_le_right := fun p q x => ciInf_le_of_le mul_bddBelow_range_add (1 : E) <| by simpa only [div_one x, map_one_eq_zero p, zero_add (q x)] using le_rfl - le_inf := fun a b c hb hc x => - le_ciInf fun u => (le_map_add_map_div a _ _).trans <| add_le_add (hb _) (hc _) } + le_inf := fun a _ _ hb hc _ => + le_ciInf fun _ => (le_map_add_map_div a _ _).trans <| add_le_add (hb _) (hc _) } end CommGroup @@ -427,7 +427,7 @@ theorem smul_sup (r : R) (p q : AddGroupSeminorm E) : r • (p ⊔ q) = r • p have Real.smul_max : ∀ x y : ℝ, r • max x y = max (r • x) (r • y) := fun x y => by simpa only [← smul_eq_mul, ← NNReal.smul_def, smul_one_smul ℝ≥0 r (_ : ℝ)] using mul_max_of_nonneg x y (r • (1 : ℝ≥0) : ℝ≥0).coe_nonneg - ext fun x => Real.smul_max _ _ + ext fun _ => Real.smul_max _ _ end AddGroupSeminorm @@ -483,7 +483,7 @@ instance : Zero (NonarchAddGroupSeminorm E) := ⟨{ toFun := 0 map_zero' := Pi.zero_apply _ add_le_max' := fun r s => by simp only [Pi.zero_apply]; rw [max_eq_right]; rfl - neg' := fun x => rfl }⟩ + neg' := fun _ => rfl }⟩ @[simp, norm_cast] theorem coe_zero : ⇑(0 : NonarchAddGroupSeminorm E) = 0 := @@ -588,7 +588,7 @@ theorem smul_sup (r : R) (p q : GroupSeminorm E) : r • (p ⊔ q) = r • p ⊔ have Real.smul_max : ∀ x y : ℝ, r • max x y = max (r • x) (r • y) := fun x y => by simpa only [← smul_eq_mul, ← NNReal.smul_def, smul_one_smul ℝ≥0 r (_ : ℝ)] using mul_max_of_nonneg x y (r • (1 : ℝ≥0) : ℝ≥0).coe_nonneg - ext fun x => Real.smul_max _ _ + ext fun _ => Real.smul_max _ _ end GroupSeminorm @@ -642,7 +642,7 @@ theorem smul_sup (r : R) (p q : NonarchAddGroupSeminorm E) : r • (p ⊔ q) = r have Real.smul_max : ∀ x y : ℝ, r • max x y = max (r • x) (r • y) := fun x y => by simpa only [← smul_eq_mul, ← NNReal.smul_def, smul_one_smul ℝ≥0 r (_ : ℝ)] using mul_max_of_nonneg x y (r • (1 : ℝ≥0) : ℝ≥0).coe_nonneg - ext fun x => Real.smul_max _ _ + ext fun _ => Real.smul_max _ _ end NonarchAddGroupSeminorm diff --git a/Mathlib/Analysis/Normed/Lp/LpEquiv.lean b/Mathlib/Analysis/Normed/Lp/LpEquiv.lean index 144ad83e536db1..013c08de891cde 100644 --- a/Mathlib/Analysis/Normed/Lp/LpEquiv.lean +++ b/Mathlib/Analysis/Normed/Lp/LpEquiv.lean @@ -152,7 +152,7 @@ dependencies. -/ /-- The canonical map between `lp (fun _ : α ↦ E) ∞` and `α →ᵇ E` as a `LinearIsometryEquiv`. -/ noncomputable def lpBCFₗᵢ : lp (fun _ : α ↦ E) ∞ ≃ₗᵢ[𝕜] α →ᵇ E := { AddEquiv.lpBCF with - map_smul' := fun k f ↦ rfl + map_smul' := fun _ _ ↦ rfl norm_map' := fun f ↦ by simp only [norm_eq_iSup_norm, lp.norm_eq_ciSup]; rfl } @[deprecated (since := "2024-03-16")] alias lpBcfₗᵢ := lpBCFₗᵢ diff --git a/Mathlib/Analysis/Normed/Lp/PiLp.lean b/Mathlib/Analysis/Normed/Lp/PiLp.lean index decc9152899804..2fed648aba0904 100644 --- a/Mathlib/Analysis/Normed/Lp/PiLp.lean +++ b/Mathlib/Analysis/Normed/Lp/PiLp.lean @@ -740,7 +740,7 @@ def _root_.LinearIsometryEquiv.piLpCurry : toLinearEquiv := WithLp.linearEquiv _ _ _ ≪≫ₗ LinearEquiv.piCurry 𝕜 α - ≪≫ₗ (LinearEquiv.piCongrRight fun i => (WithLp.linearEquiv _ _ _).symm) + ≪≫ₗ (LinearEquiv.piCongrRight fun _ => (WithLp.linearEquiv _ _ _).symm) ≪≫ₗ (WithLp.linearEquiv _ _ _).symm norm_map' := (WithLp.equiv p _).symm.surjective.forall.2 fun x => by simp_rw [← coe_nnnorm, NNReal.coe_inj] diff --git a/Mathlib/Analysis/Normed/Lp/lpSpace.lean b/Mathlib/Analysis/Normed/Lp/lpSpace.lean index dfe8bef80fdec2..0c44871b94833d 100644 --- a/Mathlib/Analysis/Normed/Lp/lpSpace.lean +++ b/Mathlib/Analysis/Normed/Lp/lpSpace.lean @@ -471,7 +471,7 @@ instance normedAddCommGroup [hp : Fact (1 ≤ p)] : NormedAddCommGroup (lp E p) intro i gcongr apply norm_add_le - eq_zero_of_map_eq_zero' := fun f => norm_eq_zero_iff.1 } + eq_zero_of_map_eq_zero' := fun _ => norm_eq_zero_iff.1 } -- TODO: define an `ENNReal` version of `IsConjExponent`, and then express this inequality -- in a better version which also covers the case `p = 1, q = ∞`. diff --git a/Mathlib/Analysis/Normed/Operator/BoundedLinearMaps.lean b/Mathlib/Analysis/Normed/Operator/BoundedLinearMaps.lean index 4d0fea4e147c44..39c1d73dc03d4e 100644 --- a/Mathlib/Analysis/Normed/Operator/BoundedLinearMaps.lean +++ b/Mathlib/Analysis/Normed/Operator/BoundedLinearMaps.lean @@ -145,7 +145,7 @@ theorem comp {g : F → G} (hg : IsBoundedLinearMap 𝕜 g) (hf : IsBoundedLinea protected theorem tendsto (x : E) (hf : IsBoundedLinearMap 𝕜 f) : Tendsto f (𝓝 x) (𝓝 (f x)) := let ⟨hf, M, _, hM⟩ := hf tendsto_iff_norm_sub_tendsto_zero.2 <| - squeeze_zero (fun e => norm_nonneg _) + squeeze_zero (fun _ => norm_nonneg _) (fun e => calc ‖f e - f x‖ = ‖hf.mk' f (e - x)‖ := by rw [(hf.mk' _).map_sub e x]; rfl diff --git a/Mathlib/Analysis/NormedSpace/BallAction.lean b/Mathlib/Analysis/NormedSpace/BallAction.lean index 262d4babb606c7..f095bd6baf5d43 100644 --- a/Mathlib/Analysis/NormedSpace/BallAction.lean +++ b/Mathlib/Analysis/NormedSpace/BallAction.lean @@ -31,8 +31,8 @@ instance mulActionClosedBallBall : MulAction (closedBall (0 : 𝕜) 1) (ball (0 simpa only [norm_smul, one_mul] using mul_lt_mul' (mem_closedBall_zero_iff.1 c.2) (mem_ball_zero_iff.1 x.2) (norm_nonneg _) one_pos⟩ - one_smul x := Subtype.ext <| one_smul 𝕜 _ - mul_smul c₁ c₂ x := Subtype.ext <| mul_smul _ _ _ + one_smul _c₂ := Subtype.ext <| one_smul 𝕜 _ + mul_smul _ _ _ := Subtype.ext <| mul_smul _ _ _ instance continuousSMul_closedBall_ball : ContinuousSMul (closedBall (0 : 𝕜) 1) (ball (0 : E) r) := ⟨(continuous_subtype_val.fst'.smul continuous_subtype_val.snd').subtype_mk _⟩ @@ -45,8 +45,8 @@ instance mulActionClosedBallClosedBall : simpa only [norm_smul, one_mul] using mul_le_mul (mem_closedBall_zero_iff.1 c.2) (mem_closedBall_zero_iff.1 x.2) (norm_nonneg _) zero_le_one⟩ - one_smul x := Subtype.ext <| one_smul 𝕜 _ - mul_smul c₁ c₂ x := Subtype.ext <| mul_smul _ _ _ + one_smul _ := Subtype.ext <| one_smul 𝕜 _ + mul_smul _ _ _ := Subtype.ext <| mul_smul _ _ _ instance continuousSMul_closedBall_closedBall : ContinuousSMul (closedBall (0 : 𝕜) 1) (closedBall (0 : E) r) := @@ -79,8 +79,8 @@ instance mulActionSphereSphere : MulAction (sphere (0 : 𝕜) 1) (sphere (0 : E) mem_sphere_zero_iff_norm.2 <| by rw [norm_smul, mem_sphere_zero_iff_norm.1 c.coe_prop, mem_sphere_zero_iff_norm.1 x.coe_prop, one_mul]⟩ - one_smul x := Subtype.ext <| one_smul _ _ - mul_smul c₁ c₂ x := Subtype.ext <| mul_smul _ _ _ + one_smul _ := Subtype.ext <| one_smul _ _ + mul_smul _ _ _ := Subtype.ext <| mul_smul _ _ _ instance continuousSMul_sphere_sphere : ContinuousSMul (sphere (0 : 𝕜) 1) (sphere (0 : E) r) := ⟨(continuous_subtype_val.fst'.smul continuous_subtype_val.snd').subtype_mk _⟩ diff --git a/Mathlib/Analysis/NormedSpace/ENorm.lean b/Mathlib/Analysis/NormedSpace/ENorm.lean index 48c17b7994ce9b..313555960cd593 100644 --- a/Mathlib/Analysis/NormedSpace/ENorm.lean +++ b/Mathlib/Analysis/NormedSpace/ENorm.lean @@ -109,9 +109,9 @@ theorem map_sub_le (x y : V) : e (x - y) ≤ e x + e y := instance partialOrder : PartialOrder (ENorm 𝕜 V) where le e₁ e₂ := ∀ x, e₁ x ≤ e₂ x - le_refl e x := le_rfl - le_trans e₁ e₂ e₃ h₁₂ h₂₃ x := le_trans (h₁₂ x) (h₂₃ x) - le_antisymm e₁ e₂ h₁₂ h₂₁ := ext fun x => le_antisymm (h₁₂ x) (h₂₁ x) + le_refl _ _ := le_rfl + le_trans _ _ _ h₁₂ h₂₃ x := le_trans (h₁₂ x) (h₂₃ x) + le_antisymm _ _ h₁₂ h₂₁ := ext fun x => le_antisymm (h₁₂ x) (h₂₁ x) /-- The `ENorm` sending each non-zero vector to infinity. -/ noncomputable instance : Top (ENorm 𝕜 V) := @@ -146,14 +146,14 @@ noncomputable instance : SemilatticeSup (ENorm 𝕜 V) := lt := (· < ·) sup := fun e₁ e₂ => { toFun := fun x => max (e₁ x) (e₂ x) - eq_zero' := fun x h => e₁.eq_zero_iff.1 (ENNReal.max_eq_zero_iff.1 h).1 - map_add_le' := fun x y => + eq_zero' := fun _ h => e₁.eq_zero_iff.1 (ENNReal.max_eq_zero_iff.1 h).1 + map_add_le' := fun _ _ => max_le (le_trans (e₁.map_add_le _ _) <| add_le_add (le_max_left _ _) (le_max_left _ _)) (le_trans (e₂.map_add_le _ _) <| add_le_add (le_max_right _ _) (le_max_right _ _)) map_smul_le' := fun c x => le_of_eq <| by simp only [map_smul, ENNReal.mul_max] } - le_sup_left := fun e₁ e₂ x => le_max_left _ _ - le_sup_right := fun e₁ e₂ x => le_max_right _ _ - sup_le := fun e₁ e₂ e₃ h₁ h₂ x => max_le (h₁ x) (h₂ x) } + le_sup_left := fun _ _ _ => le_max_left _ _ + le_sup_right := fun _ _ _ => le_max_right _ _ + sup_le := fun _ _ _ h₁ h₂ x => max_le (h₁ x) (h₂ x) } @[simp, norm_cast] theorem coe_max (e₁ e₂ : ENorm 𝕜 V) : ⇑(e₁ ⊔ e₂) = fun x => max (e₁ x) (e₂ x) := diff --git a/Mathlib/Analysis/NormedSpace/Multilinear/Basic.lean b/Mathlib/Analysis/NormedSpace/Multilinear/Basic.lean index 4b87da345fe311..ceb978b4e25e75 100644 --- a/Mathlib/Analysis/NormedSpace/Multilinear/Basic.lean +++ b/Mathlib/Analysis/NormedSpace/Multilinear/Basic.lean @@ -648,8 +648,8 @@ def prodL : invFun f := ((ContinuousLinearMap.fst 𝕜 G G').compContinuousMultilinearMap f, (ContinuousLinearMap.snd 𝕜 G G').compContinuousMultilinearMap f) - map_add' f g := rfl - map_smul' c f := rfl + map_add' _ _ := rfl + map_smul' _ _ := rfl left_inv f := by ext <;> rfl right_inv f := by ext <;> rfl norm_map' f := opNorm_prod f.1 f.2 @@ -873,7 +873,7 @@ ones. We register this bijection as a linear isometry in `ContinuousMultilinearMap.piFieldEquiv`. -/ protected def piFieldEquiv : G ≃ₗᵢ[𝕜] ContinuousMultilinearMap 𝕜 (fun _ : ι => 𝕜) G where toFun z := ContinuousMultilinearMap.mkPiRing 𝕜 ι z - invFun f := f fun i => 1 + invFun f := f fun _ => 1 map_add' z z' := by ext m simp [smul_add] @@ -902,7 +902,7 @@ variable (𝕜 E G G') def compContinuousMultilinearMapL : (G →L[𝕜] G') →L[𝕜] ContinuousMultilinearMap 𝕜 E G →L[𝕜] ContinuousMultilinearMap 𝕜 E G' := LinearMap.mkContinuous₂ - (LinearMap.mk₂ 𝕜 compContinuousMultilinearMap (fun f₁ f₂ g => rfl) (fun c f g => rfl) + (LinearMap.mk₂ 𝕜 compContinuousMultilinearMap (fun _ _ _ => rfl) (fun _ _ _ => rfl) (fun f g₁ g₂ => by ext1; apply f.map_add) (fun c f g => by ext1; simp)) 1 diff --git a/Mathlib/Analysis/NormedSpace/Multilinear/Curry.lean b/Mathlib/Analysis/NormedSpace/Multilinear/Curry.lean index 433b3db5d9d543..702bd8dea02d93 100644 --- a/Mathlib/Analysis/NormedSpace/Multilinear/Curry.lean +++ b/Mathlib/Analysis/NormedSpace/Multilinear/Curry.lean @@ -169,8 +169,8 @@ def continuousMultilinearCurryLeftEquiv : Ei 0 →L[𝕜] ContinuousMultilinearMap 𝕜 (fun i : Fin n => Ei i.succ) G := LinearIsometryEquiv.ofBounds { toFun := ContinuousMultilinearMap.curryLeft - map_add' := fun f₁ f₂ => rfl - map_smul' := fun c f => rfl + map_add' := fun _ _ => rfl + map_smul' := fun _ _ => rfl invFun := ContinuousLinearMap.uncurryLeft left_inv := ContinuousMultilinearMap.uncurry_curryLeft right_inv := ContinuousLinearMap.curry_uncurryLeft } @@ -283,8 +283,8 @@ def continuousMultilinearCurryRightEquiv : ContinuousMultilinearMap 𝕜 (fun i : Fin n => Ei <| castSucc i) (Ei (last n) →L[𝕜] G) := LinearIsometryEquiv.ofBounds { toFun := ContinuousMultilinearMap.curryRight - map_add' := fun f₁ f₂ => rfl - map_smul' := fun c f => rfl + map_add' := fun _ _ => rfl + map_smul' := fun _ _ => rfl invFun := ContinuousMultilinearMap.uncurryRight left_inv := ContinuousMultilinearMap.uncurry_curryRight right_inv := ContinuousMultilinearMap.curry_uncurryRight } diff --git a/Mathlib/Analysis/ODE/PicardLindelof.lean b/Mathlib/Analysis/ODE/PicardLindelof.lean index 9c46abf777613c..1f6996fcbf20ef 100644 --- a/Mathlib/Analysis/ODE/PicardLindelof.lean +++ b/Mathlib/Analysis/ODE/PicardLindelof.lean @@ -81,9 +81,9 @@ instance : Inhabited (PicardLindelof E) := ⟨⟨0, 0, 0, ⟨0, le_rfl, le_rfl⟩, 0, 0, 0, 0, { ht₀ := by rw [Subtype.coe_mk, Icc_self]; exact mem_singleton _ hR := le_rfl - lipschitz := fun t _ => (LipschitzWith.const 0).lipschitzOnWith + lipschitz := fun _ _ => (LipschitzWith.const 0).lipschitzOnWith cont := fun _ _ => by simpa only [Pi.zero_apply] using continuousOn_const - norm_le := fun t _ x _ => norm_zero.le + norm_le := fun _ _ _ _ => norm_zero.le C_mul_le_R := (zero_mul _).le }⟩⟩ theorem tMin_le_tMax : v.tMin ≤ v.tMax := diff --git a/Mathlib/Analysis/Quaternion.lean b/Mathlib/Analysis/Quaternion.lean index 3466df2251849a..8319c5915f21ac 100644 --- a/Mathlib/Analysis/Quaternion.lean +++ b/Mathlib/Analysis/Quaternion.lean @@ -50,8 +50,8 @@ noncomputable instance : NormedAddCommGroup ℍ := @InnerProductSpace.Core.toNormedAddCommGroup ℝ ℍ _ _ _ { toInner := inferInstance conj_symm := fun x y => by simp [inner_def, mul_comm] - nonneg_re := fun x => normSq_nonneg - definite := fun x => normSq_eq_zero.1 + nonneg_re := fun _ => normSq_nonneg + definite := fun _ => normSq_eq_zero.1 add_left := fun x y z => by simp only [inner_def, add_mul, add_re] smul_left := fun x y r => by simp [inner_def] } diff --git a/Mathlib/Analysis/RCLike/Basic.lean b/Mathlib/Analysis/RCLike/Basic.lean index 69097ee6513a0e..076e45a1a3a711 100644 --- a/Mathlib/Analysis/RCLike/Basic.lean +++ b/Mathlib/Analysis/RCLike/Basic.lean @@ -693,11 +693,11 @@ theorem norm_sq_re_conj_add (x : K) : ‖conj x + x‖ ^ 2 = re (conj x + x) ^ 2 /-! ### Cauchy sequences -/ -theorem isCauSeq_re (f : CauSeq K norm) : IsCauSeq abs fun n => re (f n) := fun ε ε0 => +theorem isCauSeq_re (f : CauSeq K norm) : IsCauSeq abs fun n => re (f n) := fun _ ε0 => (f.cauchy ε0).imp fun i H j ij => lt_of_le_of_lt (by simpa only [map_sub] using abs_re_le_norm (f j - f i)) (H _ ij) -theorem isCauSeq_im (f : CauSeq K norm) : IsCauSeq abs fun n => im (f n) := fun ε ε0 => +theorem isCauSeq_im (f : CauSeq K norm) : IsCauSeq abs fun n => im (f n) := fun _ ε0 => (f.cauchy ε0).imp fun i H j ij => lt_of_le_of_lt (by simpa only [map_sub] using abs_im_le_norm (f j - f i)) (H _ ij) @@ -725,8 +725,8 @@ noncomputable instance Real.instRCLike : RCLike ℝ where I_mul_I_ax := Or.intro_left _ rfl re_add_im_ax z := by simp only [add_zero, mul_zero, Algebra.id.map_eq_id, RingHom.id_apply, AddMonoidHom.id_apply] - ofReal_re_ax f := rfl - ofReal_im_ax r := rfl + ofReal_re_ax _ := rfl + ofReal_im_ax _ := rfl mul_re_ax z w := by simp only [sub_zero, mul_zero, AddMonoidHom.zero_apply, AddMonoidHom.id_apply] mul_im_ax z w := by simp only [add_zero, zero_mul, mul_zero, AddMonoidHom.zero_apply] conj_re_ax z := by simp only [starRingEnd_apply, star_id_of_comm] @@ -858,7 +858,7 @@ scoped[ComplexOrder] attribute [instance] RCLike.toOrderedSMul lemma _root_.StarModule.instOrderedSMul {A : Type*} [NonUnitalRing A] [StarRing A] [PartialOrder A] [StarOrderedRing A] [Module K A] [StarModule K A] [IsScalarTower K A A] [SMulCommClass K A A] : OrderedSMul K A where - smul_lt_smul_of_pos {x y c} hxy hc := StarModule.smul_lt_smul_of_pos hxy hc + smul_lt_smul_of_pos {_ _ _} hxy hc := StarModule.smul_lt_smul_of_pos hxy hc lt_of_smul_lt_smul_of_pos {x y c} hxy hc := by have : c⁻¹ • c • x < c⁻¹ • c • y := StarModule.smul_lt_smul_of_pos hxy (RCLike.inv_pos_of_pos hc) diff --git a/Mathlib/Analysis/Seminorm.lean b/Mathlib/Analysis/Seminorm.lean index a448a13eadcc87..751860a0f37b25 100644 --- a/Mathlib/Analysis/Seminorm.lean +++ b/Mathlib/Analysis/Seminorm.lean @@ -231,7 +231,7 @@ theorem smul_sup [SMul R ℝ] [SMul R ℝ≥0] [IsScalarTower R ℝ≥0 ℝ] (r have real.smul_max : ∀ x y : ℝ, r • max x y = max (r • x) (r • y) := fun x y => by simpa only [← smul_eq_mul, ← NNReal.smul_def, smul_one_smul ℝ≥0 r (_ : ℝ)] using mul_max_of_nonneg x y (r • (1 : ℝ≥0) : ℝ≥0).coe_nonneg - ext fun x => real.smul_max _ _ + ext fun _ => real.smul_max _ _ instance instPartialOrder : PartialOrder (Seminorm 𝕜 E) := PartialOrder.lift _ DFunLike.coe_injective @@ -462,8 +462,8 @@ noncomputable instance instLattice : Lattice (Seminorm 𝕜 E) := inf_le_right := fun p q x => ciInf_le_of_le bddBelow_range_add 0 <| by simp only [sub_self, map_zero, zero_add, sub_zero]; rfl - le_inf := fun a b c hab hac x => - le_ciInf fun u => (le_map_add_map_sub a _ _).trans <| add_le_add (hab _) (hac _) } + le_inf := fun a _ _ hab hac _ => + le_ciInf fun _ => (le_map_add_map_sub a _ _).trans <| add_le_add (hab _) (hac _) } theorem smul_inf [SMul R ℝ] [SMul R ℝ≥0] [IsScalarTower R ℝ≥0 ℝ] (r : R) (p q : Seminorm 𝕜 E) : r • (p ⊓ q) = r • p ⊓ r • q := by @@ -533,7 +533,7 @@ protected theorem coe_sSup_eq' {s : Set <| Seminorm 𝕜 E} protected theorem bddAbove_iff {s : Set <| Seminorm 𝕜 E} : BddAbove s ↔ BddAbove ((↑) '' s : Set (E → ℝ)) := - ⟨fun ⟨q, hq⟩ => ⟨q, forall_mem_image.2 fun p hp => hq hp⟩, fun H => + ⟨fun ⟨q, hq⟩ => ⟨q, forall_mem_image.2 fun _ hp => hq hp⟩, fun H => ⟨sSup s, fun p hp x => by dsimp rw [Seminorm.coe_sSup_eq' H, iSup_apply] diff --git a/Mathlib/Analysis/SpecialFunctions/Complex/LogBounds.lean b/Mathlib/Analysis/SpecialFunctions/Complex/LogBounds.lean index f5e05a1e202df7..d5f625bba8628b 100644 --- a/Mathlib/Analysis/SpecialFunctions/Complex/LogBounds.lean +++ b/Mathlib/Analysis/SpecialFunctions/Complex/LogBounds.lean @@ -31,7 +31,7 @@ namespace Complex lemma continuousOn_one_add_mul_inv {z : ℂ} (hz : 1 + z ∈ slitPlane) : ContinuousOn (fun t : ℝ ↦ (1 + t • z)⁻¹) (Set.Icc 0 1) := ContinuousOn.inv₀ (by fun_prop) - (fun t ht ↦ slitPlane_ne_zero <| StarConvex.add_smul_mem starConvex_one_slitPlane hz ht.1 ht.2) + (fun _ ht ↦ slitPlane_ne_zero <| StarConvex.add_smul_mem starConvex_one_slitPlane hz ht.1 ht.2) open intervalIntegral in /-- Represent `log (1 + z)` as an integral over the unit interval -/ diff --git a/Mathlib/Analysis/SpecialFunctions/Complex/LogDeriv.lean b/Mathlib/Analysis/SpecialFunctions/Complex/LogDeriv.lean index f92d4934e22ece..40f804326f3c64 100644 --- a/Mathlib/Analysis/SpecialFunctions/Complex/LogDeriv.lean +++ b/Mathlib/Analysis/SpecialFunctions/Complex/LogDeriv.lean @@ -43,8 +43,8 @@ noncomputable def expPartialHomeomorph : PartialHomeomorph ℂ ℂ := map_target' := fun z h => by simp only [mem_setOf, log_im, mem_Ioo, neg_pi_lt_arg, arg_lt_pi_iff, true_and] exact h.imp_left le_of_lt - left_inv' := fun x hx => log_exp hx.1 (le_of_lt hx.2) - right_inv' := fun x hx => exp_log <| slitPlane_ne_zero hx } + left_inv' := fun _ hx => log_exp hx.1 (le_of_lt hx.2) + right_inv' := fun _ hx => exp_log <| slitPlane_ne_zero hx } continuous_exp.continuousOn isOpenMap_exp (isOpen_Ioo.preimage continuous_im) theorem hasStrictDerivAt_log {x : ℂ} (h : x ∈ slitPlane) : HasStrictDerivAt log x⁻¹ x := diff --git a/Mathlib/Analysis/SpecialFunctions/Exp.lean b/Mathlib/Analysis/SpecialFunctions/Exp.lean index 8d018a967ecb06..5d7dc418a5c497 100644 --- a/Mathlib/Analysis/SpecialFunctions/Exp.lean +++ b/Mathlib/Analysis/SpecialFunctions/Exp.lean @@ -387,7 +387,7 @@ theorem isLittleO_pow_exp_atTop {n : ℕ} : (fun x : ℝ => x ^ n) =o[atTop] Rea @[simp] theorem isBigO_exp_comp_exp_comp {f g : α → ℝ} : ((fun x => exp (f x)) =O[l] fun x => exp (g x)) ↔ IsBoundedUnder (· ≤ ·) l (f - g) := - Iff.trans (isBigO_iff_isBoundedUnder_le_div <| Eventually.of_forall fun x => exp_ne_zero _) <| by + Iff.trans (isBigO_iff_isBoundedUnder_le_div <| Eventually.of_forall fun _ => exp_ne_zero _) <| by simp only [norm_eq_abs, abs_exp, ← exp_sub, isBoundedUnder_le_exp_comp, Pi.sub_def] @[simp] diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/Asymptotics.lean b/Mathlib/Analysis/SpecialFunctions/Pow/Asymptotics.lean index 58b6a5277c22c7..46b43a71b54e12 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/Asymptotics.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/Asymptotics.lean @@ -198,7 +198,7 @@ theorem isBigO_cpow_rpow (hl : IsBoundedUnder (· ≤ ·) l fun x => |(g x).im|) calc (fun x => f x ^ g x) =O[l] (show α → ℝ from fun x => abs (f x) ^ (g x).re / Real.exp (arg (f x) * im (g x))) := - isBigO_of_le _ fun x => (abs_cpow_le _ _).trans (le_abs_self _) + isBigO_of_le _ fun _ => (abs_cpow_le _ _).trans (le_abs_self _) _ =Θ[l] (show α → ℝ from fun x => abs (f x) ^ (g x).re / (1 : ℝ)) := ((isTheta_refl _ _).div (isTheta_exp_arg_mul_im hl)) _ =ᶠ[l] (show α → ℝ from fun x => abs (f x) ^ (g x).re) := by @@ -211,7 +211,7 @@ theorem isTheta_cpow_rpow (hl_im : IsBoundedUnder (· ≤ ·) l fun x => |(g x). calc (fun x => f x ^ g x) =Θ[l] (show α → ℝ from fun x => abs (f x) ^ (g x).re / Real.exp (arg (f x) * im (g x))) := - isTheta_of_norm_eventuallyEq' <| hl.mono fun x => abs_cpow_of_imp + isTheta_of_norm_eventuallyEq' <| hl.mono fun _ => abs_cpow_of_imp _ =Θ[l] (show α → ℝ from fun x => abs (f x) ^ (g x).re / (1 : ℝ)) := ((isTheta_refl _ _).div (isTheta_exp_arg_mul_im hl_im)) _ =ᶠ[l] (show α → ℝ from fun x => abs (f x) ^ (g x).re) := by @@ -282,7 +282,7 @@ open Asymptotics /-- `x ^ s = o(exp(b * x))` as `x → ∞` for any real `s` and positive `b`. -/ theorem isLittleO_rpow_exp_pos_mul_atTop (s : ℝ) {b : ℝ} (hb : 0 < b) : (fun x : ℝ => x ^ s) =o[atTop] fun x => exp (b * x) := - isLittleO_of_tendsto (fun x h => absurd h (exp_pos _).ne') <| by + isLittleO_of_tendsto (fun _ h => absurd h (exp_pos _).ne') <| by simpa only [div_eq_mul_inv, exp_neg, neg_mul] using tendsto_rpow_mul_exp_neg_mul_atTop_nhds_zero s b hb diff --git a/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean b/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean index b712f2e3cd5681..abdc88a5f991e5 100644 --- a/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean +++ b/Mathlib/Analysis/SpecialFunctions/Pow/Real.lean @@ -1040,6 +1040,14 @@ theorem isRat_rpow_neg {a b : ℝ} {nb : ℕ} IsRat (a ^ b) num den := by rwa [pb.out, Real.rpow_intCast] +#adaptation_note +/-- +Since https://github.com/leanprover/lean4/pull/5338, +the unused variable linter can not see usages of variables in +`haveI' : ⋯ =Q ⋯ := ⟨⟩` clauses, so generates many false positives. +-/ +set_option linter.unusedVariables false + /-- Evaluates expressions of the form `a ^ b` when `a` and `b` are both reals. -/ @[norm_num (_ : ℝ) ^ (_ : ℝ)] def evalRPow : NormNumExt where eval {u α} e := do diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Basic.lean index ff16ee4d5471a4..8e6add75779d2e 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Basic.lean @@ -502,7 +502,7 @@ theorem sin_eq_zero_iff {x : ℝ} : sin x = 0 ↔ ∃ n : ℤ, (n : ℝ) * π = le_of_not_gt fun h₃ => (sin_pos_of_pos_of_lt_pi h₃ (Int.sub_floor_div_mul_lt _ pi_pos)).ne (by simp [sub_eq_add_neg, sin_add, h, sin_int_mul_pi]))⟩, - fun ⟨n, hn⟩ => hn ▸ sin_int_mul_pi _⟩ + fun ⟨_, hn⟩ => hn ▸ sin_int_mul_pi _⟩ theorem sin_ne_zero_iff {x : ℝ} : sin x ≠ 0 ↔ ∀ n : ℤ, (n : ℝ) * π ≠ x := by rw [← not_exists, not_iff_not, sin_eq_zero_iff] @@ -524,7 +524,7 @@ theorem cos_eq_one_iff (x : ℝ) : cos x = 1 ↔ ∃ n : ℤ, (n : ℝ) * (2 * mul_comm (2 : ℤ), Int.cast_mul, mul_assoc, Int.cast_two] at hn rw [← hn, cos_int_mul_two_pi_add_pi] at h exact absurd h (by norm_num)⟩, - fun ⟨n, hn⟩ => hn ▸ cos_int_mul_two_pi _⟩ + fun ⟨_, hn⟩ => hn ▸ cos_int_mul_two_pi _⟩ theorem cos_eq_one_iff_of_lt_of_lt {x : ℝ} (hx₁ : -(2 * π) < x) (hx₂ : x < 2 * π) : cos x = 1 ↔ x = 0 := diff --git a/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean b/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean index ee32d7d2f76661..b472107dc47f5a 100644 --- a/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean +++ b/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean @@ -198,7 +198,7 @@ attribute [local instance] HasBinaryBiproducts.of_hasBinaryProducts /-- The arrows pseudo-equal to a zero morphism are precisely the zero morphisms. -/ theorem pseudoZero_aux {P : C} (Q : C) (f : Over P) : f ≈ (0 : Q ⟶ P) ↔ f.hom = 0 := - ⟨fun ⟨R, p, q, ep, _, comm⟩ => zero_of_epi_comp p (by simp [comm]), fun hf => + ⟨fun ⟨R, p, q, _, _, comm⟩ => zero_of_epi_comp p (by simp [comm]), fun hf => ⟨biprod f.1 Q, biprod.fst, biprod.snd, inferInstance, inferInstance, by rw [hf, Over.coe_hom, HasZeroMorphisms.comp_zero, HasZeroMorphisms.comp_zero]⟩⟩ diff --git a/Mathlib/CategoryTheory/Adjunction/Evaluation.lean b/Mathlib/CategoryTheory/Adjunction/Evaluation.lean index 9fa052e5ca51b4..d7491bf0972fe7 100644 --- a/Mathlib/CategoryTheory/Adjunction/Evaluation.lean +++ b/Mathlib/CategoryTheory/Adjunction/Evaluation.lean @@ -36,7 +36,7 @@ def evaluationLeftAdjoint (c : C) : D ⥤ C ⥤ D where { obj := fun t => ∐ fun _ : c ⟶ t => d map := fun f => Sigma.desc fun g => (Sigma.ι fun _ => d) <| g ≫ f} map {_ d₂} f := - { app := fun e => Sigma.desc fun h => f ≫ Sigma.ι (fun _ => d₂) h + { app := fun _ => Sigma.desc fun h => f ≫ Sigma.ι (fun _ => d₂) h naturality := by intros dsimp @@ -50,7 +50,7 @@ def evaluationAdjunctionRight (c : C) : evaluationLeftAdjoint D c ⊣ (evaluatio { homEquiv := fun d F => { toFun := fun f => Sigma.ι (fun _ => d) (𝟙 _) ≫ f.app c invFun := fun f => - { app := fun e => Sigma.desc fun h => f ≫ F.map h + { app := fun _ => Sigma.desc fun h => f ≫ F.map h naturality := by intros dsimp @@ -95,7 +95,7 @@ def evaluationRightAdjoint (c : C) : D ⥤ C ⥤ D where { obj := fun t => ∏ᶜ fun _ : t ⟶ c => d map := fun f => Pi.lift fun g => Pi.π _ <| f ≫ g } map f := - { app := fun t => Pi.lift fun g => Pi.π _ g ≫ f + { app := fun _ => Pi.lift fun g => Pi.π _ g ≫ f naturality := by intros dsimp @@ -108,7 +108,7 @@ def evaluationAdjunctionLeft (c : C) : (evaluation _ _).obj c ⊣ evaluationRigh Adjunction.mkOfHomEquiv { homEquiv := fun F d => { toFun := fun f => - { app := fun t => Pi.lift fun g => F.map g ≫ f + { app := fun _ => Pi.lift fun g => F.map g ≫ f naturality := by intros dsimp diff --git a/Mathlib/CategoryTheory/Adjunction/FullyFaithful.lean b/Mathlib/CategoryTheory/Adjunction/FullyFaithful.lean index 2bdec90917b380..0c46fa9aba37ce 100644 --- a/Mathlib/CategoryTheory/Adjunction/FullyFaithful.lean +++ b/Mathlib/CategoryTheory/Adjunction/FullyFaithful.lean @@ -128,7 +128,7 @@ lemma full_L_of_isSplitEpi_unit_app [∀ X, IsSplitEpi (h.unit.app X)] : L.Full /-- If the unit is an isomorphism, then the left adjoint is fully faithful. -/ noncomputable def fullyFaithfulLOfIsIsoUnit [IsIso h.unit] : L.FullyFaithful where - preimage {X Y} f := h.homEquiv _ (L.obj Y) f ≫ inv (h.unit.app Y) + preimage {_ Y} f := h.homEquiv _ (L.obj Y) f ≫ inv (h.unit.app Y) /-- If each component of the counit is an epimorphism, then the right adjoint is faithful. -/ lemma faithful_R_of_epi_counit_app [∀ X, Epi (h.counit.app X)] : R.Faithful where diff --git a/Mathlib/CategoryTheory/Adjunction/Lifting/Left.lean b/Mathlib/CategoryTheory/Adjunction/Lifting/Left.lean index e4d139ca0cb2b9..e8cd5e6498b69d 100644 --- a/Mathlib/CategoryTheory/Adjunction/Lifting/Left.lean +++ b/Mathlib/CategoryTheory/Adjunction/Lifting/Left.lean @@ -122,6 +122,13 @@ variable [HasReflexiveCoequalizers A] noncomputable def constructLeftAdjointObj (Y : B) : A := coequalizer (F'.map (U.map (adj₁.counit.app Y))) (otherMap _ _ adj₁ adj₂ Y) +#adaptation_note +/-- +The new unused variable linter in +https://github.com/leanprover/lean4/pull/5338 +flags `{ z : F.obj (U.obj X) ⟶ R.obj Y // _ }`. +-/ +set_option linter.unusedVariables false in /-- The homset equivalence which helps show that `R` is a right adjoint. -/ @[simps!] -- Porting note: Originally `@[simps (config := { rhsMd := semireducible })]` noncomputable def constructLeftAdjointEquiv [∀ X : B, RegularEpi (adj₁.counit.app X)] (Y : A) diff --git a/Mathlib/CategoryTheory/Bicategory/Coherence.lean b/Mathlib/CategoryTheory/Bicategory/Coherence.lean index 8721c45df98f37..d22809944d403a 100644 --- a/Mathlib/CategoryTheory/Bicategory/Coherence.lean +++ b/Mathlib/CategoryTheory/Bicategory/Coherence.lean @@ -187,7 +187,7 @@ def normalize (B : Type u) [Quiver.{v + 1} B] : obj a := ⟨a⟩ map f := ⟨normalizeAux nil f⟩ map₂ η := eqToHom <| Discrete.ext <| normalizeAux_congr nil η - mapId a := eqToIso <| Discrete.ext rfl + mapId _ := eqToIso <| Discrete.ext rfl mapComp f g := eqToIso <| Discrete.ext <| normalizeAux_nil_comp f g /-- Auxiliary definition for `normalizeEquiv`. -/ @@ -232,7 +232,7 @@ def inclusion (B : Type u) [Quiver.{v + 1} B] : Pseudofunctor (LocallyDiscrete (Paths B)) (FreeBicategory B) := { -- All the conditions for 2-morphisms are trivial thanks to the coherence theorem! preinclusion B with - mapId := fun a => Iso.refl _ + mapId := fun _ => Iso.refl _ mapComp := fun f g => inclusionMapCompAux f.as g.as } end FreeBicategory diff --git a/Mathlib/CategoryTheory/Bicategory/End.lean b/Mathlib/CategoryTheory/Bicategory/End.lean index 8210d2a2cdcd0b..a231874f15b0db 100644 --- a/Mathlib/CategoryTheory/Bicategory/End.lean +++ b/Mathlib/CategoryTheory/Bicategory/End.lean @@ -36,8 +36,8 @@ open Bicategory attribute [local simp] EndMonoidal in instance (X : C) : MonoidalCategory (EndMonoidal X) where tensorObj f g := f ≫ g - whiskerLeft {f g h} η := f ◁ η - whiskerRight {f g} η h := η ▷ h + whiskerLeft {f _ _} η := f ◁ η + whiskerRight {_ _} η h := η ▷ h tensorUnit := 𝟙 _ associator f g h := α_ f g h leftUnitor f := λ_ f diff --git a/Mathlib/CategoryTheory/Bicategory/Free.lean b/Mathlib/CategoryTheory/Bicategory/Free.lean index e423dd24b31be6..8241aa309f05ea 100644 --- a/Mathlib/CategoryTheory/Bicategory/Free.lean +++ b/Mathlib/CategoryTheory/Bicategory/Free.lean @@ -148,7 +148,7 @@ end instance homCategory (a b : FreeBicategory B) : Category (a ⟶ b) where Hom f g := Quot (@Rel _ _ a b f g) id f := Quot.mk Rel (Hom₂.id f) - comp := @fun f g h => Quot.map₂ Hom₂.vcomp Rel.vcomp_right Rel.vcomp_left + comp := @fun _ _ _ => Quot.map₂ Hom₂.vcomp Rel.vcomp_right Rel.vcomp_left id_comp := by rintro f g ⟨η⟩ exact Quot.sound (Rel.id_comp η) @@ -162,19 +162,19 @@ instance homCategory (a b : FreeBicategory B) : Category (a ⟶ b) where /-- Bicategory structure on the free bicategory. -/ instance bicategory : Bicategory (FreeBicategory B) where homCategory := @fun (a b : B) => FreeBicategory.homCategory a b - whiskerLeft := @fun a b c f g h η => Quot.map (Hom₂.whisker_left f) (Rel.whisker_left f g h) η - whiskerLeft_id := @fun a b c f g => Quot.sound (Rel.whisker_left_id f g) - associator := @fun a b c d f g h => + whiskerLeft := @fun _ _ _ f g h η => Quot.map (Hom₂.whisker_left f) (Rel.whisker_left f g h) η + whiskerLeft_id := @fun _ _ _ f g => Quot.sound (Rel.whisker_left_id f g) + associator := @fun _ _ _ _ f g h => { hom := Quot.mk Rel (Hom₂.associator f g h) inv := Quot.mk Rel (Hom₂.associator_inv f g h) hom_inv_id := Quot.sound (Rel.associator_hom_inv f g h) inv_hom_id := Quot.sound (Rel.associator_inv_hom f g h) } - leftUnitor := @fun a b f => + leftUnitor := @fun _ _ f => { hom := Quot.mk Rel (Hom₂.left_unitor f) inv := Quot.mk Rel (Hom₂.left_unitor_inv f) hom_inv_id := Quot.sound (Rel.left_unitor_hom_inv f) inv_hom_id := Quot.sound (Rel.left_unitor_inv_hom f) } - rightUnitor := @fun a b f => + rightUnitor := @fun _ _ f => { hom := Quot.mk Rel (Hom₂.right_unitor f) inv := Quot.mk Rel (Hom₂.right_unitor_inv f) hom_inv_id := Quot.sound (Rel.right_unitor_hom_inv f) @@ -188,8 +188,8 @@ instance bicategory : Bicategory (FreeBicategory B) where comp_whiskerLeft := by rintro a b c d f g h h' ⟨η⟩ exact Quot.sound (Rel.comp_whisker_left f g η) - whiskerRight := @fun a b c f g η h => Quot.map (Hom₂.whisker_right h) (Rel.whisker_right f g h) η - id_whiskerRight := @fun a b c f g => Quot.sound (Rel.id_whisker_right f g) + whiskerRight := @fun _ _ _ f g η h => Quot.map (Hom₂.whisker_right h) (Rel.whisker_right f g h) η + id_whiskerRight := @fun _ _ _ f g => Quot.sound (Rel.id_whisker_right f g) comp_whiskerRight := by rintro a b c f g h ⟨η⟩ ⟨θ⟩ i exact Quot.sound (Rel.comp_whisker_right i η θ) @@ -205,8 +205,8 @@ instance bicategory : Bicategory (FreeBicategory B) where whisker_exchange := by rintro a b c f g h i ⟨η⟩ ⟨θ⟩ exact Quot.sound (Rel.whisker_exchange η θ) - pentagon := @fun a b c d e f g h i => Quot.sound (Rel.pentagon f g h i) - triangle := @fun a b c f g => Quot.sound (Rel.triangle f g) + pentagon := @fun _ _ _ _ _ f g h i => Quot.sound (Rel.pentagon f g h i) + triangle := @fun _ _ _ f g => Quot.sound (Rel.triangle f g) variable {a b c d : FreeBicategory B} @@ -327,9 +327,9 @@ theorem liftHom₂_congr {a b : FreeBicategory B} {f g : a ⟶ b} {η θ : Hom def lift : Pseudofunctor (FreeBicategory B) C where obj := F.obj map := liftHom F - mapId a := Iso.refl _ - mapComp f g := Iso.refl _ - map₂ := Quot.lift (liftHom₂ F) fun η θ H => liftHom₂_congr F H + mapId _ := Iso.refl _ + mapComp _ _ := Iso.refl _ + map₂ := Quot.lift (liftHom₂ F) fun _ _ H => liftHom₂_congr F H -- Porting note: We'd really prefer not to be doing this by hand. -- in mathlib3 `tidy` did these inductions for us. map₂_comp := by diff --git a/Mathlib/CategoryTheory/Bicategory/FunctorBicategory.lean b/Mathlib/CategoryTheory/Bicategory/FunctorBicategory.lean index 121c253c24500e..9822588b0753f7 100644 --- a/Mathlib/CategoryTheory/Bicategory/FunctorBicategory.lean +++ b/Mathlib/CategoryTheory/Bicategory/FunctorBicategory.lean @@ -72,11 +72,11 @@ variable (B C) -- Porting note: verified that projections are correct and changed @[simps] to @[simps!] @[simps!] instance OplaxFunctor.bicategory : Bicategory (OplaxFunctor B C) where - whiskerLeft {F G H} η _ _ Γ := OplaxNatTrans.whiskerLeft η Γ - whiskerRight {F G H} _ _ Γ η := OplaxNatTrans.whiskerRight Γ η - associator {F G H} I := OplaxNatTrans.associator - leftUnitor {F G} := OplaxNatTrans.leftUnitor - rightUnitor {F G} := OplaxNatTrans.rightUnitor + whiskerLeft {_ _ _} η _ _ Γ := OplaxNatTrans.whiskerLeft η Γ + whiskerRight {_ _ _} _ _ Γ η := OplaxNatTrans.whiskerRight Γ η + associator {_ _ _} _ := OplaxNatTrans.associator + leftUnitor {_ _} := OplaxNatTrans.leftUnitor + rightUnitor {_ _} := OplaxNatTrans.rightUnitor whisker_exchange {a b c f g h i} η θ := by ext exact whisker_exchange _ _ diff --git a/Mathlib/CategoryTheory/Bicategory/LocallyDiscrete.lean b/Mathlib/CategoryTheory/Bicategory/LocallyDiscrete.lean index 3ddbc22d951aad..2e93d740e778df 100644 --- a/Mathlib/CategoryTheory/Bicategory/LocallyDiscrete.lean +++ b/Mathlib/CategoryTheory/Bicategory/LocallyDiscrete.lean @@ -94,17 +94,17 @@ variable [Category.{v} C] equalities between 1-morphisms. -/ instance locallyDiscreteBicategory : Bicategory (LocallyDiscrete C) where - whiskerLeft f g h η := eqToHom (congr_arg₂ (· ≫ ·) rfl (LocallyDiscrete.eq_of_hom η)) - whiskerRight η h := eqToHom (congr_arg₂ (· ≫ ·) (LocallyDiscrete.eq_of_hom η) rfl) + whiskerLeft _ _ _ η := eqToHom (congr_arg₂ (· ≫ ·) rfl (LocallyDiscrete.eq_of_hom η)) + whiskerRight η _ := eqToHom (congr_arg₂ (· ≫ ·) (LocallyDiscrete.eq_of_hom η) rfl) associator f g h := eqToIso <| by apply Discrete.ext; simp leftUnitor f := eqToIso <| by apply Discrete.ext; simp rightUnitor f := eqToIso <| by apply Discrete.ext; simp /-- A locally discrete bicategory is strict. -/ instance locallyDiscreteBicategory.strict : Strict (LocallyDiscrete C) where - id_comp f := Discrete.ext (Category.id_comp _) - comp_id f := Discrete.ext (Category.comp_id _) - assoc f g h := Discrete.ext (Category.assoc _ _ _) + id_comp _ := Discrete.ext (Category.id_comp _) + comp_id _ := Discrete.ext (Category.comp_id _) + assoc _ _ _ := Discrete.ext (Category.assoc _ _ _) attribute [local simp] Strict.leftUnitor_eqToIso Strict.rightUnitor_eqToIso Strict.associator_eqToIso diff --git a/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Oplax.lean b/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Oplax.lean index d6c4159d767cf1..28abd4f9c4360a 100644 --- a/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Oplax.lean +++ b/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Oplax.lean @@ -77,7 +77,7 @@ variable (F : OplaxFunctor B C) @[simps] def id : OplaxNatTrans F F where app a := 𝟙 (F.obj a) - naturality {a b} f := (ρ_ (F.map f)).hom ≫ (λ_ (F.map f)).inv + naturality {_ _} f := (ρ_ (F.map f)).hom ≫ (λ_ (F.map f)).inv instance : Inhabited (OplaxNatTrans F F) := ⟨id F⟩ diff --git a/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Strong.lean b/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Strong.lean index 28d84af3a9c06e..d118ec2577a11c 100644 --- a/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Strong.lean +++ b/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Strong.lean @@ -108,7 +108,7 @@ naturality 2-cell is an isomorphism. -/ noncomputable def mkOfOplax' {F G : OplaxFunctor B C} (η : OplaxNatTrans F G) [∀ a b (f : a ⟶ b), IsIso (η.naturality f)] : StrongOplaxNatTrans F G where app := η.app - naturality := fun f => asIso (η.naturality _) + naturality := fun _ => asIso (η.naturality _) variable (F : OplaxFunctor B C) diff --git a/Mathlib/CategoryTheory/Bicategory/SingleObj.lean b/Mathlib/CategoryTheory/Bicategory/SingleObj.lean index 73341c73d8e162..5a01fd30b13ce5 100644 --- a/Mathlib/CategoryTheory/Bicategory/SingleObj.lean +++ b/Mathlib/CategoryTheory/Bicategory/SingleObj.lean @@ -50,7 +50,7 @@ instance : Bicategory (MonoidalSingleObj C) where Hom _ _ := C id _ := 𝟙_ C comp X Y := tensorObj X Y - whiskerLeft X Y Z f := X ◁ f + whiskerLeft X _ _ f := X ◁ f whiskerRight f Z := f ▷ Z associator X Y Z := α_ X Y Z leftUnitor X := λ_ X @@ -75,7 +75,7 @@ def endMonoidalStarFunctor : MonoidalFunctor (EndMonoidal (MonoidalSingleObj.sta obj X := X map f := f ε := 𝟙 _ - μ X Y := 𝟙 _ + μ _ _ := 𝟙 _ /-- The equivalence between the endomorphisms of the single object when we promote a monoidal category to a single object bicategory, diff --git a/Mathlib/CategoryTheory/Category/Bipointed.lean b/Mathlib/CategoryTheory/Category/Bipointed.lean index e85c5549e371dd..b8a57ae187af4a 100644 --- a/Mathlib/CategoryTheory/Category/Bipointed.lean +++ b/Mathlib/CategoryTheory/Category/Bipointed.lean @@ -191,7 +191,7 @@ def pointedToBipointedFstBipointedToPointedFstAdjunction : cases x · exact f.map_snd.symm · rfl - right_inv := fun f => Pointed.Hom.ext rfl } + right_inv := fun _ => Pointed.Hom.ext rfl } homEquiv_naturality_left_symm := fun f g => by apply Bipointed.Hom.ext funext x @@ -211,7 +211,7 @@ def pointedToBipointedSndBipointedToPointedSndAdjunction : cases x · exact f.map_fst.symm · rfl - right_inv := fun f => Pointed.Hom.ext rfl } + right_inv := fun _ => Pointed.Hom.ext rfl } homEquiv_naturality_left_symm := fun f g => by apply Bipointed.Hom.ext funext x diff --git a/Mathlib/CategoryTheory/Category/Cat.lean b/Mathlib/CategoryTheory/Category/Cat.lean index 9838804baf16f5..7d16c775e8b1d8 100644 --- a/Mathlib/CategoryTheory/Category/Cat.lean +++ b/Mathlib/CategoryTheory/Category/Cat.lean @@ -56,13 +56,13 @@ instance bicategory : Bicategory.{max v u, max v u} Cat.{v, u} where id C := 𝟭 C comp F G := F ⋙ G homCategory := fun _ _ => Functor.category - whiskerLeft {C} {D} {E} F G H η := whiskerLeft F η - whiskerRight {C} {D} {E} F G η H := whiskerRight η H - associator {A} {B} {C} D := Functor.associator - leftUnitor {A} B := Functor.leftUnitor - rightUnitor {A} B := Functor.rightUnitor - pentagon := fun {A} {B} {C} {D} {E}=> Functor.pentagon - triangle {A} {B} {C} := Functor.triangle + whiskerLeft {_} {_} {_} F _ _ η := whiskerLeft F η + whiskerRight {_} {_} {_} _ _ η H := whiskerRight η H + associator {_} {_} {_} _ := Functor.associator + leftUnitor {_} _ := Functor.leftUnitor + rightUnitor {_} _ := Functor.rightUnitor + pentagon := fun {_} {_} {_} {_} {_}=> Functor.pentagon + triangle {_} {_} {_} := Functor.triangle /-- `Cat` is a strict bicategory. -/ instance bicategory.strict : Bicategory.Strict Cat.{v, u} where diff --git a/Mathlib/CategoryTheory/Category/Cat/Limit.lean b/Mathlib/CategoryTheory/Category/Cat/Limit.lean index 8fb276edac4bec..92300512f30e64 100644 --- a/Mathlib/CategoryTheory/Category/Cat/Limit.lean +++ b/Mathlib/CategoryTheory/Category/Cat/Limit.lean @@ -59,7 +59,7 @@ def homDiagram {F : J ⥤ Cat.{v, v}} (X Y : limit (F ⋙ Cat.objects.{v, v})) : @[simps] instance (F : J ⥤ Cat.{v, v}) : Category (limit (F ⋙ Cat.objects)) where Hom X Y := limit (homDiagram X Y) - id X := Types.Limit.mk.{v, v} (homDiagram X X) (fun j => 𝟙 _) fun j j' f => by simp + id X := Types.Limit.mk.{v, v} (homDiagram X X) (fun _ => 𝟙 _) fun j j' f => by simp comp {X Y Z} f g := Types.Limit.mk.{v, v} (homDiagram X Z) (fun j => limit.π (homDiagram X Y) j f ≫ limit.π (homDiagram Y Z) j g) fun j j' h => by @@ -84,7 +84,7 @@ def limitCone (F : J ⥤ Cat.{v, v}) : Cone F where { app := fun j => { obj := limit.π (F ⋙ Cat.objects) j map := fun f => limit.π (homDiagram _ _) j f } - naturality := fun j j' f => + naturality := fun _ _ f => CategoryTheory.Functor.ext (fun X => (congr_fun (limit.w (F ⋙ Cat.objects) f) X).symm) fun X Y h => (congr_fun (limit.w (homDiagram X Y) f) h).symm } diff --git a/Mathlib/CategoryTheory/Category/PartialFun.lean b/Mathlib/CategoryTheory/Category/PartialFun.lean index b448e2cf2a62f6..f0a25329d70dbd 100644 --- a/Mathlib/CategoryTheory/Category/PartialFun.lean +++ b/Mathlib/CategoryTheory/Category/PartialFun.lean @@ -85,8 +85,8 @@ This is the computable part of the equivalence `PartialFunEquivPointed`. -/ def pointedToPartialFun : Pointed.{u} ⥤ PartialFun where obj X := { x : X // x ≠ X.point } map f := PFun.toSubtype _ f.toFun ∘ Subtype.val - map_id X := - PFun.ext fun a b => + map_id _ := + PFun.ext fun _ b => PFun.mem_toSubtype_iff (b := b).trans (Subtype.coe_inj.trans Part.mem_some_iff.symm) map_comp f g := by -- Porting note: the proof was changed because the original mathlib3 proof no longer works @@ -123,7 +123,7 @@ noncomputable def partialFunEquivPointed : PartialFun.{u} ≌ Pointed where unitIso := NatIso.ofComponents (fun X => PartialFun.Iso.mk { toFun := fun a => ⟨some a, some_ne_none a⟩ invFun := fun a => Option.get _ (Option.ne_none_iff_isSome.1 a.2) - left_inv := fun a => Option.get_some _ _ + left_inv := fun _ => Option.get_some _ _ right_inv := fun a => by simp only [some_get, Subtype.coe_eta] }) fun f => PFun.ext fun a b => by @@ -164,7 +164,7 @@ adding a point. -/ noncomputable def typeToPartialFunIsoPartialFunToPointed : typeToPartialFun ⋙ partialFunToPointed ≅ typeToPointed := NatIso.ofComponents - (fun X => + (fun _ => { hom := ⟨id, rfl⟩ inv := ⟨id, rfl⟩ hom_inv_id := rfl diff --git a/Mathlib/CategoryTheory/Category/Pointed.lean b/Mathlib/CategoryTheory/Category/Pointed.lean index 8e963c0fc6da98..48b87c4aa95bcb 100644 --- a/Mathlib/CategoryTheory/Category/Pointed.lean +++ b/Mathlib/CategoryTheory/Category/Pointed.lean @@ -122,7 +122,7 @@ def typeToPointedForgetAdjunction : typeToPointed ⊣ forget Pointed := cases x · exact f.map_point.symm · rfl - right_inv := fun f => funext fun _ => rfl } + right_inv := fun _ => funext fun _ => rfl } homEquiv_naturality_left_symm := fun f g => by apply Pointed.Hom.ext funext x diff --git a/Mathlib/CategoryTheory/Category/RelCat.lean b/Mathlib/CategoryTheory/Category/RelCat.lean index 7136d606db093a..ae907547bf19bf 100644 --- a/Mathlib/CategoryTheory/Category/RelCat.lean +++ b/Mathlib/CategoryTheory/Category/RelCat.lean @@ -37,7 +37,7 @@ instance RelCat.inhabited : Inhabited RelCat := by unfold RelCat; infer_instance /-- The category of types with binary relations as morphisms. -/ instance rel : LargeCategory RelCat where Hom X Y := X → Y → Prop - id X x y := x = y + id _ x y := x = y comp f g x z := ∃ y, f x y ∧ g y z @@ -121,7 +121,7 @@ open Opposite /-- The argument-swap isomorphism from `RelCat` to its opposite. -/ def opFunctor : RelCat ⥤ RelCatᵒᵖ where obj X := op X - map {X Y} r := op (fun y x => r x y) + map {_ _} r := op (fun y x => r x y) map_id X := by congr simp only [unop_op, RelCat.Hom.rel_id] @@ -137,7 +137,7 @@ def opFunctor : RelCat ⥤ RelCatᵒᵖ where /-- The other direction of `opFunctor`. -/ def unopFunctor : RelCatᵒᵖ ⥤ RelCat where obj X := unop X - map {X Y} r x y := unop r y x + map {_ _} r x y := unop r y x map_id X := by dsimp ext x y diff --git a/Mathlib/CategoryTheory/Category/TwoP.lean b/Mathlib/CategoryTheory/Category/TwoP.lean index 9a4f129f06e4e9..49fda51da739cc 100644 --- a/Mathlib/CategoryTheory/Category/TwoP.lean +++ b/Mathlib/CategoryTheory/Category/TwoP.lean @@ -141,7 +141,7 @@ noncomputable def pointedToTwoPFstForgetCompBipointedToPointedFstAdjunction : cases x · exact f.map_snd.symm · rfl - right_inv := fun f => Pointed.Hom.ext rfl } + right_inv := fun _ => Pointed.Hom.ext rfl } homEquiv_naturality_left_symm := fun f g => by apply Bipointed.Hom.ext funext x @@ -160,7 +160,7 @@ noncomputable def pointedToTwoPSndForgetCompBipointedToPointedSndAdjunction : cases x · exact f.map_fst.symm · rfl - right_inv := fun f => Pointed.Hom.ext rfl } + right_inv := fun _ => Pointed.Hom.ext rfl } homEquiv_naturality_left_symm := fun f g => by apply Bipointed.Hom.ext funext x diff --git a/Mathlib/CategoryTheory/Category/ULift.lean b/Mathlib/CategoryTheory/Category/ULift.lean index 9752f42a1cf1eb..f70fe083dec2fd 100644 --- a/Mathlib/CategoryTheory/Category/ULift.lean +++ b/Mathlib/CategoryTheory/Category/ULift.lean @@ -66,12 +66,12 @@ def ULift.equivalence : C ≌ ULift.{u₂} C where inv := 𝟙 _ } counitIso := { hom := - { app := fun X => 𝟙 _ + { app := fun _ => 𝟙 _ naturality := fun X Y f => by change f ≫ 𝟙 _ = 𝟙 _ ≫ f simp } inv := - { app := fun X => 𝟙 _ + { app := fun _ => 𝟙 _ naturality := fun X Y f => by change f ≫ 𝟙 _ = 𝟙 _ ≫ f simp } @@ -118,7 +118,7 @@ theorem objUp_objDown {C} (A : ULiftHom C) : ULiftHom.objUp A.objDown = A := instance ULiftHom.category : Category.{max v₂ v₁} (ULiftHom.{v₂} C) where Hom A B := ULift.{v₂} <| A.objDown ⟶ B.objDown - id A := ⟨𝟙 _⟩ + id _ := ⟨𝟙 _⟩ comp f g := ⟨f.down ≫ g.down⟩ /-- One half of the quivalence between `C` and `ULiftHom C`. -/ @@ -137,8 +137,8 @@ def ULiftHom.down : ULiftHom C ⥤ C where def ULiftHom.equiv : C ≌ ULiftHom C where functor := ULiftHom.up inverse := ULiftHom.down - unitIso := NatIso.ofComponents fun A => eqToIso rfl - counitIso := NatIso.ofComponents fun A => eqToIso rfl + unitIso := NatIso.ofComponents fun _ => eqToIso rfl + counitIso := NatIso.ofComponents fun _ => eqToIso rfl end ULiftHom /- Porting note: we want to keep around the category instance on `D` @@ -159,7 +159,7 @@ def AsSmall.{w, v, u} (D : Type u) [Category.{v} D] := ULift.{max w v} D instance : SmallCategory (AsSmall.{w₁} C) where Hom X Y := ULift.{max w₁ u₁} <| X.down ⟶ Y.down - id X := ⟨𝟙 _⟩ + id _ := ⟨𝟙 _⟩ comp f g := ⟨f.down ≫ g.down⟩ /-- One half of the equivalence between `C` and `AsSmall C`. -/ @@ -179,8 +179,8 @@ def AsSmall.down : AsSmall C ⥤ C where def AsSmall.equiv : C ≌ AsSmall C where functor := AsSmall.up inverse := AsSmall.down - unitIso := NatIso.ofComponents fun X => eqToIso rfl - counitIso := NatIso.ofComponents fun X => eqToIso <| ULift.ext _ _ rfl + unitIso := NatIso.ofComponents fun _ => eqToIso rfl + counitIso := NatIso.ofComponents fun _ => eqToIso <| ULift.ext _ _ rfl instance [Inhabited C] : Inhabited (AsSmall C) := ⟨⟨default⟩⟩ diff --git a/Mathlib/CategoryTheory/ChosenFiniteProducts/FunctorCategory.lean b/Mathlib/CategoryTheory/ChosenFiniteProducts/FunctorCategory.lean index 265a1793d3a1dc..3a4eaa80fc91fc 100644 --- a/Mathlib/CategoryTheory/ChosenFiniteProducts/FunctorCategory.lean +++ b/Mathlib/CategoryTheory/ChosenFiniteProducts/FunctorCategory.lean @@ -50,7 +50,7 @@ def fst : chosenProd F₁ F₂ ⟶ F₁ where /-- The second projection `chosenProd F₁ F₂ ⟶ F₂`. -/ @[simps] def snd : chosenProd F₁ F₂ ⟶ F₂ where - app j := ChosenFiniteProducts.snd _ _ + app _ := ChosenFiniteProducts.snd _ _ /-- `Functor.chosenProd F₁ F₂` is a binary product of `F₁` and `F₂`. -/ noncomputable def isLimit : IsLimit (BinaryFan.mk (fst F₁ F₂) (snd F₁ F₂)) := diff --git a/Mathlib/CategoryTheory/Closed/Types.lean b/Mathlib/CategoryTheory/Closed/Types.lean index 503e71b9441cf2..ec79009ce89688 100644 --- a/Mathlib/CategoryTheory/Closed/Types.lean +++ b/Mathlib/CategoryTheory/Closed/Types.lean @@ -34,7 +34,7 @@ for any `X : Type v₁`. -/ def Types.binaryProductAdjunction (X : Type v₁) : Limits.Types.binaryProductFunctor.obj X ⊣ coyoneda.obj (Opposite.op X) where unit := { app := fun Z (z : Z) x => ⟨x, z⟩ } - counit := { app := fun Z xf => xf.2 xf.1 } + counit := { app := fun _ xf => xf.2 xf.1 } instance (X : Type v₁) : (Types.binaryProductFunctor.obj X).IsLeftAdjoint := ⟨_, ⟨Types.binaryProductAdjunction X⟩⟩ diff --git a/Mathlib/CategoryTheory/Closed/Zero.lean b/Mathlib/CategoryTheory/Closed/Zero.lean index 459ba941f8d894..7931f396900e37 100644 --- a/Mathlib/CategoryTheory/Closed/Zero.lean +++ b/Mathlib/CategoryTheory/Closed/Zero.lean @@ -61,7 +61,7 @@ def equivPUnit [HasZeroObject C] : C ≌ Discrete PUnit.{w + 1} where (fun X => { hom := default inv := default }) - fun f => Subsingleton.elim _ _ + fun _ => Subsingleton.elim _ _ counitIso := Functor.punitExt _ _ end CategoryTheory diff --git a/Mathlib/CategoryTheory/CofilteredSystem.lean b/Mathlib/CategoryTheory/CofilteredSystem.lean index 2424d1f7ae761f..fba99256f7078f 100644 --- a/Mathlib/CategoryTheory/CofilteredSystem.lean +++ b/Mathlib/CategoryTheory/CofilteredSystem.lean @@ -272,7 +272,7 @@ instance toEventualRanges_finite [∀ j, Finite (F.obj j)] : ∀ j, Finite (F.to def toEventualRangesSectionsEquiv : F.toEventualRanges.sections ≃ F.sections where toFun s := ⟨_, fun f => Subtype.coe_inj.2 <| s.prop f⟩ invFun s := - ⟨fun j => ⟨_, mem_iInter₂.2 fun i f => ⟨_, s.prop f⟩⟩, fun f => Subtype.ext <| s.prop f⟩ + ⟨fun _ => ⟨_, mem_iInter₂.2 fun _ f => ⟨_, s.prop f⟩⟩, fun f => Subtype.ext <| s.prop f⟩ left_inv _ := by ext rfl diff --git a/Mathlib/CategoryTheory/Comma/Presheaf.lean b/Mathlib/CategoryTheory/Comma/Presheaf.lean index 671b3ef28ec5f1..8fa1a25d073e5c 100644 --- a/Mathlib/CategoryTheory/Comma/Presheaf.lean +++ b/Mathlib/CategoryTheory/Comma/Presheaf.lean @@ -207,7 +207,7 @@ def restrictedYonedaObj {F : Cᵒᵖ ⥤ Type v} (η : F ⟶ A) : @[simps] def restrictedYonedaObjMap₁ {F G : Cᵒᵖ ⥤ Type v} {η : F ⟶ A} {μ : G ⟶ A} (ε : F ⟶ G) (hε : ε ≫ μ = η) : restrictedYonedaObj η ⟶ restrictedYonedaObj μ where - app s u := u.map₁ ε hε + app _ u := u.map₁ ε hε /-- 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 @@ -227,7 +227,7 @@ def restrictedYoneda (A : Cᵒᵖ ⥤ Type v) : Over A ⥤ (CostructuredArrow yo def toOverYonedaCompRestrictedYoneda (A : Cᵒᵖ ⥤ Type v) : CostructuredArrow.toOver yoneda A ⋙ restrictedYoneda A ≅ yoneda := NatIso.ofComponents - (fun s => NatIso.ofComponents (fun t => OverArrows.costructuredArrowIso _ _) (by aesop_cat)) + (fun s => NatIso.ofComponents (fun _ => OverArrows.costructuredArrowIso _ _) (by aesop_cat)) (by aesop_cat) /-! ### Construction of the backward functor `((CostructuredArrow yoneda A)ᵒᵖ ⥤ Type v) ⥤ Over A` -/ @@ -379,7 +379,7 @@ def yonedaCollectionPresheaf (A : Cᵒᵖ ⥤ Type v) (F : (CostructuredArrow yo @[simps] def yonedaCollectionPresheafMap₁ {F G : (CostructuredArrow yoneda A)ᵒᵖ ⥤ Type v} (η : F ⟶ G) : yonedaCollectionPresheaf A F ⟶ yonedaCollectionPresheaf A G where - app X := YonedaCollection.map₁ η + app _ := YonedaCollection.map₁ η naturality := by intros ext @@ -396,7 +396,7 @@ def yonedaCollectionFunctor (A : Cᵒᵖ ⥤ Type v) : @[simps] def yonedaCollectionPresheafToA (F : (CostructuredArrow yoneda A)ᵒᵖ ⥤ Type v) : yonedaCollectionPresheaf A F ⟶ A where - app X := YonedaCollection.yonedaEquivFst + app _ := YonedaCollection.yonedaEquivFst /-- This is the reverse direction of the equivalence we're constructing. -/ @[simps! obj map] diff --git a/Mathlib/CategoryTheory/ComposableArrows.lean b/Mathlib/CategoryTheory/ComposableArrows.lean index 49706164e20373..0fcf2d10bbac50 100644 --- a/Mathlib/CategoryTheory/ComposableArrows.lean +++ b/Mathlib/CategoryTheory/ComposableArrows.lean @@ -212,7 +212,7 @@ lemma ext {F G : ComposableArrows C n} (h : ∀ i, F.obj i = G.obj i) (w : ∀ (i : ℕ) (hi : i < n), F.map' i (i + 1) = eqToHom (h _) ≫ G.map' i (i + 1) ≫ eqToHom (h _).symm) : F = G := Functor.ext_of_iso - (isoMk (fun i => eqToIso (h i)) (fun i hi => by simp [w i hi])) h (fun i => rfl) + (isoMk (fun i => eqToIso (h i)) (fun i hi => by simp [w i hi])) h (fun _ => rfl) /-- Constructor for morphisms in `ComposableArrows C 0`. -/ @[simps!] @@ -450,7 +450,7 @@ def whiskerLeftFunctor (Φ : Fin (n + 1) ⥤ Fin (m + 1)) : @[simps] def _root_.Fin.succFunctor (n : ℕ) : Fin n ⥤ Fin (n + 1) where obj i := i.succ - map {i j} hij := homOfLE (Fin.succ_le_succ_iff.2 (leOfHom hij)) + map {_ _} hij := homOfLE (Fin.succ_le_succ_iff.2 (leOfHom hij)) /-- The functor `ComposableArrows C (n + 1) ⥤ ComposableArrows C n` which forgets the first arrow. -/ diff --git a/Mathlib/CategoryTheory/ConcreteCategory/BundledHom.lean b/Mathlib/CategoryTheory/ConcreteCategory/BundledHom.lean index e4763010998ab1..9c4cd7abf9e84b 100644 --- a/Mathlib/CategoryTheory/ConcreteCategory/BundledHom.lean +++ b/Mathlib/CategoryTheory/ConcreteCategory/BundledHom.lean @@ -112,10 +112,10 @@ end This is useful for building categories such as `CommMonCat` from `MonCat`. -/ def map (F : ∀ {α}, d α → c α) : BundledHom (MapHom hom @F) where - toFun α β {iα} {iβ} f := 𝒞.toFun (F iα) (F iβ) f - id α {iα} := 𝒞.id (F iα) - comp := @fun α β γ iα iβ iγ f g => 𝒞.comp (F iα) (F iβ) (F iγ) f g - hom_ext := @fun α β iα iβ f g h => 𝒞.hom_ext (F iα) (F iβ) h + toFun _ _ {iα} {iβ} f := 𝒞.toFun (F iα) (F iβ) f + id _ {iα} := 𝒞.id (F iα) + comp := @fun _ _ _ iα iβ iγ f g => 𝒞.comp (F iα) (F iβ) (F iγ) f g + hom_ext := @fun _ _ iα iβ _ _ h => 𝒞.hom_ext (F iα) (F iβ) h section @@ -140,7 +140,7 @@ instance forget₂ (F : ∀ {α}, d α → c α) [ParentProjection @F] : HasForget₂ (Bundled d) (Bundled c) where forget₂ := { obj := fun X => ⟨X, F X.2⟩ - map := @fun X Y f => f } + map := @fun _ _ f => f } instance forget₂_full (F : ∀ {α}, d α → c α) [ParentProjection @F] : Functor.Full (CategoryTheory.forget₂ (Bundled d) (Bundled c)) where diff --git a/Mathlib/CategoryTheory/Core.lean b/Mathlib/CategoryTheory/Core.lean index e7b1e69ea7ddc1..46edfe5dbabf75 100644 --- a/Mathlib/CategoryTheory/Core.lean +++ b/Mathlib/CategoryTheory/Core.lean @@ -39,7 +39,7 @@ instance coreCategory : Groupoid.{v₁} (Core C) where Hom (X Y : C) := X ≅ Y id (X : C) := Iso.refl X comp f g := Iso.trans f g - inv {X Y} f := Iso.symm f + inv {_ _} f := Iso.symm f namespace Core diff --git a/Mathlib/CategoryTheory/Dialectica/Basic.lean b/Mathlib/CategoryTheory/Dialectica/Basic.lean index 37bab00c84ac7c..5a3a8b031e0f8e 100644 --- a/Mathlib/CategoryTheory/Dialectica/Basic.lean +++ b/Mathlib/CategoryTheory/Dialectica/Basic.lean @@ -92,7 +92,7 @@ instance : Category (Dial C) where F := π₂ le := by simp } - comp {X Y Z} (F G : Dial.Hom ..) := { + comp {_ _ _} (F G : Dial.Hom ..) := { f := F.f ≫ G.f F := π(π₁, prod.map F.f (𝟙 _) ≫ G.F) ≫ F.F le := comp_le_lemma F G diff --git a/Mathlib/CategoryTheory/DiscreteCategory.lean b/Mathlib/CategoryTheory/DiscreteCategory.lean index 59798018c96239..a6f0f73828116f 100644 --- a/Mathlib/CategoryTheory/DiscreteCategory.lean +++ b/Mathlib/CategoryTheory/DiscreteCategory.lean @@ -73,7 +73,7 @@ See -/ instance discreteCategory (α : Type u₁) : SmallCategory (Discrete α) where Hom X Y := ULift (PLift (X.as = Y.as)) - id X := ULift.up (PLift.up rfl) + id _ := ULift.up (PLift.up rfl) comp {X Y Z} g f := by cases X cases Y @@ -188,7 +188,7 @@ composition of two discrete functors. @[simps!] def functorComp {I : Type u₁} {J : Type u₁'} (f : J → C) (g : I → J) : Discrete.functor (f ∘ g) ≅ Discrete.functor (Discrete.mk ∘ g) ⋙ Discrete.functor f := - NatIso.ofComponents fun X => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ /-- For functors out of a discrete category, a natural transformation is just a collection of maps, @@ -272,8 +272,8 @@ protected def opposite (α : Type u₁) : (Discrete α)ᵒᵖ ≌ Discrete α := let F : Discrete α ⥤ (Discrete α)ᵒᵖ := Discrete.functor fun x => op (Discrete.mk x) { functor := F.leftOp inverse := F - unitIso := NatIso.ofComponents fun ⟨X⟩ => Iso.refl _ - counitIso := Discrete.natIso fun ⟨X⟩ => Iso.refl _ } + unitIso := NatIso.ofComponents fun ⟨_⟩ => Iso.refl _ + counitIso := Discrete.natIso fun ⟨_⟩ => Iso.refl _ } variable {C : Type u₂} [Category.{v₂} C] @@ -297,7 +297,7 @@ def piEquivalenceFunctorDiscrete (J : Type u₂) (C : Type u₁) [Category.{v₁ { obj := fun F j => F.obj ⟨j⟩ map := fun f j => f.app ⟨j⟩ } unitIso := Iso.refl _ - counitIso := NatIso.ofComponents (fun F => (NatIso.ofComponents (fun j => Iso.refl _) + counitIso := NatIso.ofComponents (fun F => (NatIso.ofComponents (fun _ => Iso.refl _) (by rintro ⟨x⟩ ⟨y⟩ f obtain rfl : x = y := Discrete.eq_of_hom f diff --git a/Mathlib/CategoryTheory/EffectiveEpi/Basic.lean b/Mathlib/CategoryTheory/EffectiveEpi/Basic.lean index 4259ae6bf495b9..926d6cb6a6e7a1 100644 --- a/Mathlib/CategoryTheory/EffectiveEpi/Basic.lean +++ b/Mathlib/CategoryTheory/EffectiveEpi/Basic.lean @@ -255,11 +255,11 @@ def EffectiveEpiFamilyStruct.reindex (e : α' ≃ α) (P : EffectiveEpiFamilyStruct (fun a => X (e a)) (fun a => π (e a))) : EffectiveEpiFamilyStruct X π where - desc := fun f h => P.desc (fun a => f _) (fun a₁ a₂ => h _ _) + desc := fun f h => P.desc (fun _ => f _) (fun _ _ => h _ _) fac _ _ a := by obtain ⟨a,rfl⟩ := e.surjective a apply P.fac - uniq _ _ m hm := P.uniq _ _ _ fun a => hm _ + uniq _ _ _ hm := P.uniq _ _ _ fun _ => hm _ /-- Reindex the indexing type of an effective epi family. diff --git a/Mathlib/CategoryTheory/EffectiveEpi/Comp.lean b/Mathlib/CategoryTheory/EffectiveEpi/Comp.lean index a8b4353556eb62..1cc9f9ce246815 100644 --- a/Mathlib/CategoryTheory/EffectiveEpi/Comp.lean +++ b/Mathlib/CategoryTheory/EffectiveEpi/Comp.lean @@ -81,7 +81,7 @@ noncomputable def effectiveEpiFamilyStructOfComp {C : Type*} [Category C] fac {W} φ h i := by dsimp rw [← cancel_epi (g i), ← assoc, EffectiveEpiFamily.fac _ (fun i => g i ≫ f i)] - uniq {W} φ h m hm := EffectiveEpiFamily.uniq _ (fun i => g i ≫ f i) _ _ _ + uniq {W} φ _ m hm := EffectiveEpiFamily.uniq _ (fun i => g i ≫ f i) _ _ _ (fun i => by rw [assoc, hm]) lemma effectiveEpiFamily_of_effectiveEpi_epi_comp {α : Type*} {B : C} {X Y : α → C} diff --git a/Mathlib/CategoryTheory/Endomorphism.lean b/Mathlib/CategoryTheory/Endomorphism.lean index 93109c730da290..483f7963bef826 100644 --- a/Mathlib/CategoryTheory/Endomorphism.lean +++ b/Mathlib/CategoryTheory/Endomorphism.lean @@ -140,8 +140,8 @@ are (multiplicatively) equivalent to automorphisms of that object. def unitsEndEquivAut : (End X)ˣ ≃* Aut X where toFun f := ⟨f.1, f.2, f.4, f.3⟩ invFun f := ⟨f.1, f.2, f.4, f.3⟩ - left_inv := fun ⟨f₁, f₂, f₃, f₄⟩ => rfl - right_inv := fun ⟨f₁, f₂, f₃, f₄⟩ => rfl + left_inv := fun ⟨_, _, _, _⟩ => rfl + right_inv := fun ⟨_, _, _, _⟩ => rfl map_mul' f g := by cases f; cases g; rfl /-- The inclusion of `Aut X` to `End X` as a monoid homomorphism. -/ diff --git a/Mathlib/CategoryTheory/Enriched/Basic.lean b/Mathlib/CategoryTheory/Enriched/Basic.lean index f8f9518c24febc..5d8c33011683ec 100644 --- a/Mathlib/CategoryTheory/Enriched/Basic.lean +++ b/Mathlib/CategoryTheory/Enriched/Basic.lean @@ -147,7 +147,7 @@ def enrichedCategoryTypeOfCategory (C : Type u₁) [𝒞 : Category.{v} C] : EnrichedCategory (Type v) C where Hom := 𝒞.Hom id X _ := 𝟙 X - comp X Y Z p := p.1 ≫ p.2 + comp _ _ _ p := p.1 ≫ p.2 id_comp X Y := by ext; simp comp_id X Y := by ext; simp assoc W X Y Z := by ext ⟨f, g, h⟩; simp @@ -281,7 +281,7 @@ attribute [reassoc (attr := simp)] EnrichedFunctor.map_comp @[simps] def EnrichedFunctor.id (C : Type u₁) [EnrichedCategory V C] : EnrichedFunctor V C C where obj X := X - map X Y := 𝟙 _ + map _ _ := 𝟙 _ instance : Inhabited (EnrichedFunctor V C C) := ⟨EnrichedFunctor.id V C⟩ @@ -292,7 +292,7 @@ def EnrichedFunctor.comp {C : Type u₁} {D : Type u₂} {E : Type u₃} [Enrich [EnrichedCategory V D] [EnrichedCategory V E] (F : EnrichedFunctor V C D) (G : EnrichedFunctor V D E) : EnrichedFunctor V C E where obj X := G.obj (F.obj X) - map X Y := F.map _ _ ≫ G.map _ _ + map _ _ := F.map _ _ ≫ G.map _ _ section @@ -419,7 +419,7 @@ def enrichedFunctorTypeEquivFunctor {C : Type u₁} [𝒞 : EnrichedCategory (Ty map_comp := fun f g => congr_fun (F.map_comp _ _ _) ⟨f, g⟩ } invFun F := { obj := fun X => F.obj X - map := fun X Y f => F.map f + map := fun _ _ f => F.map f 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 } left_inv _ := rfl diff --git a/Mathlib/CategoryTheory/FiberedCategory/BasedCategory.lean b/Mathlib/CategoryTheory/FiberedCategory/BasedCategory.lean index bfcd82955db95b..53193088726606 100644 --- a/Mathlib/CategoryTheory/FiberedCategory/BasedCategory.lean +++ b/Mathlib/CategoryTheory/FiberedCategory/BasedCategory.lean @@ -279,11 +279,11 @@ instance bicategory : Bicategory (BasedCategory.{v₂, u₂} 𝒮) where id 𝒳 := 𝟭 𝒳 comp F G := F ⋙ G homCategory 𝒳 𝒴 := homCategory 𝒳 𝒴 - whiskerLeft {𝒳 𝒴 𝒵} F {G H} α := whiskerLeft F α - whiskerRight {𝒳 𝒴 𝒵} F G α H := whiskerRight α H - associator F G H := BasedNatIso.id _ - leftUnitor {𝒳 𝒴} F := BasedNatIso.id F - rightUnitor {𝒳 𝒴} F := BasedNatIso.id F + whiskerLeft {_ _ _} F {_ _} α := whiskerLeft F α + whiskerRight {_ _ _} _ _ α H := whiskerRight α H + associator _ _ _ := BasedNatIso.id _ + leftUnitor {_ _} F := BasedNatIso.id F + rightUnitor {_ _} F := BasedNatIso.id F /-- The bicategory structure on `BasedCategory.{v₂, u₂} 𝒮` is strict. -/ instance : Bicategory.Strict (BasedCategory.{v₂, u₂} 𝒮) where diff --git a/Mathlib/CategoryTheory/FiberedCategory/HomLift.lean b/Mathlib/CategoryTheory/FiberedCategory/HomLift.lean index 8de8bf2c924015..b9bc045f14acbb 100644 --- a/Mathlib/CategoryTheory/FiberedCategory/HomLift.lean +++ b/Mathlib/CategoryTheory/FiberedCategory/HomLift.lean @@ -180,25 +180,25 @@ instance lift_comp_eqToHom {R S S' : 𝒮} {a b : 𝒳} (f : R ⟶ S) (φ : a lemma comp_eqToHom_lift_iff {R S : 𝒮} {a' a b : 𝒳} (f : R ⟶ S) (φ : a ⟶ b) (h : a' = a) : p.IsHomLift f (eqToHom h ≫ φ) ↔ p.IsHomLift f φ where mp hφ' := by subst h; simpa using hφ' - mpr hφ := inferInstance + mpr _ := inferInstance @[simp] lemma eqToHom_comp_lift_iff {R S : 𝒮} {a b b' : 𝒳} (f : R ⟶ S) (φ : a ⟶ b) (h : b = b') : p.IsHomLift f (φ ≫ eqToHom h) ↔ p.IsHomLift f φ where mp hφ' := by subst h; simpa using hφ' - mpr hφ := inferInstance + mpr _ := inferInstance @[simp] lemma lift_eqToHom_comp_iff {R' R S : 𝒮} {a b : 𝒳} (f : R ⟶ S) (φ : a ⟶ b) (h : R' = R) : p.IsHomLift (eqToHom h ≫ f) φ ↔ p.IsHomLift f φ where mp hφ' := by subst h; simpa using hφ' - mpr hφ := inferInstance + mpr _ := inferInstance @[simp] lemma lift_comp_eqToHom_iff {R S S' : 𝒮} {a b : 𝒳} (f : R ⟶ S) (φ : a ⟶ b) (h : S = S') : p.IsHomLift (f ≫ eqToHom h) φ ↔ p.IsHomLift f φ where mp := fun hφ' => by subst h; simpa using hφ' - mpr := fun hφ => inferInstance + mpr := fun _ => inferInstance section diff --git a/Mathlib/CategoryTheory/Filtered/Basic.lean b/Mathlib/CategoryTheory/Filtered/Basic.lean index 688a1d9ce43a82..16dc0ee0d321c6 100644 --- a/Mathlib/CategoryTheory/Filtered/Basic.lean +++ b/Mathlib/CategoryTheory/Filtered/Basic.lean @@ -540,7 +540,7 @@ example (α : Type u) [SemilatticeInf α] [OrderBot α] : IsCofiltered α := by example (α : Type u) [SemilatticeInf α] [OrderTop α] : IsCofiltered α := by infer_instance instance : IsCofiltered (Discrete PUnit) where - cone_objs X Y := ⟨⟨PUnit.unit⟩, ⟨⟨by trivial⟩⟩, ⟨⟨by subsingleton⟩⟩, trivial⟩ + cone_objs _ Y := ⟨⟨PUnit.unit⟩, ⟨⟨by trivial⟩⟩, ⟨⟨by subsingleton⟩⟩, trivial⟩ cone_maps X Y f g := ⟨⟨PUnit.unit⟩, ⟨⟨by trivial⟩⟩, by apply ULift.ext subsingleton⟩ diff --git a/Mathlib/CategoryTheory/FinCategory/AsType.lean b/Mathlib/CategoryTheory/FinCategory/AsType.lean index 1ba7c2d3cd2207..dafd99f417b235 100644 --- a/Mathlib/CategoryTheory/FinCategory/AsType.lean +++ b/Mathlib/CategoryTheory/FinCategory/AsType.lean @@ -43,7 +43,7 @@ abbrev AsType : Type := @[simps (config := .lemmasOnly) id comp] noncomputable instance categoryAsType : SmallCategory (AsType α) where Hom i j := Fin (Fintype.card (@Quiver.Hom (ObjAsType α) _ i j)) - id i := Fintype.equivFin _ (𝟙 _) + id _ := Fintype.equivFin _ (𝟙 _) comp f g := Fintype.equivFin _ ((Fintype.equivFin _).symm f ≫ (Fintype.equivFin _).symm g) attribute [local simp] categoryAsType_id categoryAsType_comp @@ -52,13 +52,13 @@ attribute [local simp] categoryAsType_id categoryAsType_comp @[simps] noncomputable def asTypeToObjAsType : AsType α ⥤ ObjAsType α where obj := id - map {X Y} := (Fintype.equivFin _).symm + map {_ _} := (Fintype.equivFin _).symm /-- The "identity" functor from `ObjAsType α` to `AsType α`. -/ @[simps] noncomputable def objAsTypeToAsType : ObjAsType α ⥤ AsType α where obj := id - map {X Y} := Fintype.equivFin _ + map {_ _} := Fintype.equivFin _ /-- The constructed category (`AsType α`) is equivalent to `ObjAsType α`. -/ noncomputable def asTypeEquivObjAsType : AsType α ≌ ObjAsType α where diff --git a/Mathlib/CategoryTheory/Functor/Const.lean b/Mathlib/CategoryTheory/Functor/Const.lean index 5c783b8742f00b..6d6844ebf3690a 100644 --- a/Mathlib/CategoryTheory/Functor/Const.lean +++ b/Mathlib/CategoryTheory/Functor/Const.lean @@ -47,16 +47,16 @@ is (naturally isomorphic to) the opposite of the constant functor `J ⥤ C` send -/ @[simps] def opObjOp (X : C) : (const Jᵒᵖ).obj (op X) ≅ ((const J).obj X).op where - hom := { app := fun j => 𝟙 _ } - inv := { app := fun j => 𝟙 _ } + hom := { app := fun _ => 𝟙 _ } + inv := { app := fun _ => 𝟙 _ } /-- The constant functor `Jᵒᵖ ⥤ C` sending everything to `unop X` is (naturally isomorphic to) the opposite of the constant functor `J ⥤ Cᵒᵖ` sending everything to `X`. -/ def opObjUnop (X : Cᵒᵖ) : (const Jᵒᵖ).obj (unop X) ≅ ((const J).obj X).leftOp where - hom := { app := fun j => 𝟙 _ } - inv := { app := fun j => 𝟙 _ } + hom := { app := fun _ => 𝟙 _ } + inv := { app := fun _ => 𝟙 _ } -- Lean needs some help with universes here. @[simp] @@ -96,7 +96,7 @@ instance [Nonempty J] : Faithful (const J : C ⥤ J ⥤ C) where def compConstIso (F : C ⥤ D) : F ⋙ Functor.const J ≅ Functor.const J ⋙ (whiskeringRight J C D).obj F := NatIso.ofComponents - (fun X => NatIso.ofComponents (fun j => Iso.refl _) (by aesop_cat)) + (fun X => NatIso.ofComponents (fun _ => Iso.refl _) (by aesop_cat)) (by aesop_cat) end diff --git a/Mathlib/CategoryTheory/Functor/Currying.lean b/Mathlib/CategoryTheory/Functor/Currying.lean index e130aedb422c82..5c8021e9a84c08 100644 --- a/Mathlib/CategoryTheory/Functor/Currying.lean +++ b/Mathlib/CategoryTheory/Functor/Currying.lean @@ -91,13 +91,13 @@ def currying : C ⥤ D ⥤ E ≌ C × D ⥤ E where /-- `F.flip` is isomorphic to uncurrying `F`, swapping the variables, and currying. -/ @[simps!] def flipIsoCurrySwapUncurry (F : C ⥤ D ⥤ E) : F.flip ≅ curry.obj (Prod.swap _ _ ⋙ uncurry.obj F) := - NatIso.ofComponents fun d => NatIso.ofComponents fun c => Iso.refl _ + NatIso.ofComponents fun d => NatIso.ofComponents fun _ => Iso.refl _ /-- The uncurrying of `F.flip` is isomorphic to swapping the factors followed by the uncurrying of `F`. -/ @[simps!] def uncurryObjFlip (F : C ⥤ D ⥤ E) : uncurry.obj F.flip ≅ Prod.swap _ _ ⋙ uncurry.obj F := - NatIso.ofComponents fun p => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ variable (B C D E) diff --git a/Mathlib/CategoryTheory/Functor/EpiMono.lean b/Mathlib/CategoryTheory/Functor/EpiMono.lean index 428607bf319fa5..b5e733749ce52a 100644 --- a/Mathlib/CategoryTheory/Functor/EpiMono.lean +++ b/Mathlib/CategoryTheory/Functor/EpiMono.lean @@ -170,13 +170,13 @@ instance (priority := 100) preservesMonomorphisms_of_isRightAdjoint (F : C ⥤ D instance (priority := 100) reflectsMonomorphisms_of_faithful (F : C ⥤ D) [Faithful F] : ReflectsMonomorphisms F where - reflects {X} {Y} f hf := + 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 hf := + 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]))⟩ @@ -253,8 +253,8 @@ namespace CategoryTheory.Adjunction variable {C D : Type*} [Category C] [Category D] {F : C ⥤ D} {F' : D ⥤ C} {A B : C} -theorem strongEpi_map_of_strongEpi (adj : F ⊣ F') (f : A ⟶ B) [h₁ : F'.PreservesMonomorphisms] - [h₂ : F.PreservesEpimorphisms] [StrongEpi f] : StrongEpi (F.map f) := +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 intro rw [adj.hasLiftingProperty_iff] diff --git a/Mathlib/CategoryTheory/Functor/Flat.lean b/Mathlib/CategoryTheory/Functor/Flat.lean index 81deab9624ac3a..01a05f0a295f29 100644 --- a/Mathlib/CategoryTheory/Functor/Flat.lean +++ b/Mathlib/CategoryTheory/Functor/Flat.lean @@ -125,7 +125,7 @@ noncomputable def lift : s.pt ⟶ F.obj c.pt := (F.map <| hc.lift <| (Cones.postcompose - ({ app := fun X => 𝟙 _ } : + ({ app := fun _ => 𝟙 _ } : (s.toStructuredArrow ⋙ pre s.pt K F) ⋙ proj s.pt F ⟶ K)).obj <| (StructuredArrow.proj s.pt F).mapCone s') @@ -275,7 +275,7 @@ noncomputable instance lanPreservesFiniteLimitsOfPreservesFiniteLimits (F : C theorem flat_iff_lan_flat (F : C ⥤ D) : RepresentablyFlat F ↔ RepresentablyFlat (F.op.lan : _ ⥤ Dᵒᵖ ⥤ Type u₁) := - ⟨fun H => inferInstance, fun H => by + ⟨fun _ => inferInstance, fun H => by haveI := preservesFiniteLimitsOfFlat (F.op.lan : _ ⥤ Dᵒᵖ ⥤ Type u₁) haveI : PreservesFiniteLimits F := by apply preservesFiniteLimitsOfPreservesFiniteLimitsOfSize.{u₁} diff --git a/Mathlib/CategoryTheory/Functor/FunctorHom.lean b/Mathlib/CategoryTheory/Functor/FunctorHom.lean index bd8ab6a9e031ef..3f4312c687eaa6 100644 --- a/Mathlib/CategoryTheory/Functor/FunctorHom.lean +++ b/Mathlib/CategoryTheory/Functor/FunctorHom.lean @@ -203,6 +203,6 @@ lemma associator_hom_apply (K L M N : C ⥤ D) {X : C} noncomputable instance : EnrichedCategory (C ⥤ Type max v' v u) (C ⥤ D) where Hom := functorHom id F := natTransEquiv.symm (𝟙 F) - comp F G H := { app := fun X ⟨f, g⟩ => f.comp g } + comp F G H := { app := fun _ ⟨f, g⟩ => f.comp g } end CategoryTheory.Enriched.Functor diff --git a/Mathlib/CategoryTheory/Functor/OfSequence.lean b/Mathlib/CategoryTheory/Functor/OfSequence.lean index ef7b877cddbf6c..48ad42ce9d5c90 100644 --- a/Mathlib/CategoryTheory/Functor/OfSequence.lean +++ b/Mathlib/CategoryTheory/Functor/OfSequence.lean @@ -43,7 +43,7 @@ def map : ∀ {X : ℕ → C} (_ : ∀ n, X n ⟶ X (n + 1)) (i j : ℕ), i ≤ | _, _, 0, 0 => fun _ ↦ 𝟙 _ | _, f, 0, 1 => fun _ ↦ f 0 | _, f, 0, l + 1 => fun _ ↦ f 0 ≫ map (fun n ↦ f (n + 1)) 0 l (by omega) - | _, _, k + 1, 0 => nofun + | _, _, _ + 1, 0 => nofun | _, f, k + 1, l + 1 => fun _ ↦ map (fun n ↦ f (n + 1)) k l (by omega) lemma map_id (i : ℕ) : map f i i (by omega) = 𝟙 _ := by diff --git a/Mathlib/CategoryTheory/Functor/Trifunctor.lean b/Mathlib/CategoryTheory/Functor/Trifunctor.lean index 14409f1efe9045..f1293cf7bb2217 100644 --- a/Mathlib/CategoryTheory/Functor/Trifunctor.lean +++ b/Mathlib/CategoryTheory/Functor/Trifunctor.lean @@ -31,7 +31,7 @@ variable (F₁₂ : C₁ ⥤ C₂ ⥤ C₁₂) (G : C₁₂ ⥤ C₃ ⥤ C₄) def bifunctorComp₁₂Obj (X₁ : C₁) : C₂ ⥤ C₃ ⥤ C₄ where obj X₂ := { obj := fun X₃ => (G.obj ((F₁₂.obj X₁).obj X₂)).obj X₃ - map := fun {X₃ Y₃} φ => (G.obj ((F₁₂.obj X₁).obj X₂)).map φ } + map := fun {_ _} φ => (G.obj ((F₁₂.obj X₁).obj X₂)).map φ } map {X₂ Y₂} φ := { app := fun X₃ => (G.map ((F₁₂.obj X₁).map φ)).app X₃ } @@ -59,7 +59,7 @@ variable (F : C₁ ⥤ C₂₃ ⥤ C₄) (G₂₃ : C₂ ⥤ C₃ ⥤ C₂₃) def bifunctorComp₂₃Obj (X₁ : C₁) : C₂ ⥤ C₃ ⥤ C₄ where obj X₂ := { obj := fun X₃ => (F.obj X₁).obj ((G₂₃.obj X₂).obj X₃) - map := fun {X₃ Y₃} φ => (F.obj X₁).map ((G₂₃.obj X₂).map φ) } + map := fun {_ _} φ => (F.obj X₁).map ((G₂₃.obj X₂).map φ) } map {X₂ Y₂} φ := { app := fun X₃ => (F.obj X₁).map ((G₂₃.map φ).app X₃) naturality := fun {X₃ Y₃} φ => by diff --git a/Mathlib/CategoryTheory/Galois/Basic.lean b/Mathlib/CategoryTheory/Galois/Basic.lean index 77db617102e028..131a2e864a5bb1 100644 --- a/Mathlib/CategoryTheory/Galois/Basic.lean +++ b/Mathlib/CategoryTheory/Galois/Basic.lean @@ -172,7 +172,7 @@ section then `F ⋙ E` is again a fiber functor. -/ noncomputable def compRight (E : FintypeCat.{w} ⥤ FintypeCat.{t}) [E.IsEquivalence] : FiberFunctor (F ⋙ E) where - preservesQuotientsByFiniteGroups G := compPreservesColimitsOfShape F E + preservesQuotientsByFiniteGroups _ := compPreservesColimitsOfShape F E end diff --git a/Mathlib/CategoryTheory/Galois/Examples.lean b/Mathlib/CategoryTheory/Galois/Examples.lean index a3bbd1400e05ce..f52783a0ae08a4 100644 --- a/Mathlib/CategoryTheory/Galois/Examples.lean +++ b/Mathlib/CategoryTheory/Galois/Examples.lean @@ -79,8 +79,8 @@ noncomputable instance : PreservesFiniteLimits (forget (Action FintypeCat (MonCa /-- The category of finite `G`-sets is a `PreGaloisCategory`. -/ instance : PreGaloisCategory (Action FintypeCat (MonCat.of G)) where - hasQuotientsByFiniteGroups G _ _ := inferInstance - monoInducesIsoOnDirectSummand {X Y} i h := + hasQuotientsByFiniteGroups _ _ _ := inferInstance + monoInducesIsoOnDirectSummand {_ _} i _ := ⟨Action.imageComplement G i, Action.imageComplementIncl G i, ⟨isColimitOfReflects (Action.forget _ _ ⋙ FintypeCat.incl) <| (isColimitMapCoconeBinaryCofanEquiv (forget _) i _).symm @@ -90,7 +90,7 @@ instance : PreGaloisCategory (Action FintypeCat (MonCat.of G)) where noncomputable instance : FiberFunctor (Action.forget FintypeCat (MonCat.of G)) where preservesFiniteCoproducts := ⟨fun _ _ ↦ inferInstance⟩ preservesQuotientsByFiniteGroups _ _ _ := inferInstance - reflectsIsos := ⟨fun f (h : IsIso f.hom) => inferInstance⟩ + reflectsIsos := ⟨fun f (_ : IsIso f.hom) => inferInstance⟩ /-- The forgetful functor from finite `G`-sets to sets is a `FiberFunctor`. -/ noncomputable instance : FiberFunctor (forget₂ (Action FintypeCat (MonCat.of G)) FintypeCat) := diff --git a/Mathlib/CategoryTheory/Galois/IsFundamentalgroup.lean b/Mathlib/CategoryTheory/Galois/IsFundamentalgroup.lean index 7e9841375b05fb..0e137b3d0c354f 100644 --- a/Mathlib/CategoryTheory/Galois/IsFundamentalgroup.lean +++ b/Mathlib/CategoryTheory/Galois/IsFundamentalgroup.lean @@ -242,7 +242,7 @@ variable [FiberFunctor F] /-- `Aut F` is a fundamental group for `F`. -/ instance : IsFundamentalGroup F (Aut F) where - naturality g X Y f x := (FunctorToFintypeCat.naturality F F g.hom f x).symm + naturality g _ _ f x := (FunctorToFintypeCat.naturality F F g.hom f x).symm transitive_of_isGalois X := FiberFunctor.isPretransitive_of_isConnected F X continuous_smul X := continuousSMul_aut_fiber F X non_trivial' g h := by diff --git a/Mathlib/CategoryTheory/Generator.lean b/Mathlib/CategoryTheory/Generator.lean index bd219bca91faa2..0424d4339d3869 100644 --- a/Mathlib/CategoryTheory/Generator.lean +++ b/Mathlib/CategoryTheory/Generator.lean @@ -395,7 +395,7 @@ theorem isSeparator_def (G : C) : hG _ _ fun H hH h => by obtain rfl := Set.mem_singleton_iff.1 hH exact hfg h, - fun hG X Y f g hfg => hG _ _ fun h => hfg _ (Set.mem_singleton _) _⟩ + fun hG _ _ _ _ hfg => hG _ _ fun _ => hfg _ (Set.mem_singleton _) _⟩ theorem IsSeparator.def {G : C} : IsSeparator G → ∀ ⦃X Y : C⦄ (f g : X ⟶ Y), (∀ h : G ⟶ X, h ≫ f = h ≫ g) → f = g := @@ -407,7 +407,7 @@ theorem isCoseparator_def (G : C) : hG _ _ fun H hH h => by obtain rfl := Set.mem_singleton_iff.1 hH exact hfg h, - fun hG X Y f g hfg => hG _ _ fun h => hfg _ (Set.mem_singleton _) _⟩ + fun hG _ _ _ _ hfg => hG _ _ fun _ => hfg _ (Set.mem_singleton _) _⟩ theorem IsCoseparator.def {G : C} : IsCoseparator G → ∀ ⦃X Y : C⦄ (f g : X ⟶ Y), (∀ h : Y ⟶ G, f ≫ h = g ≫ h) → f = g := @@ -419,7 +419,7 @@ theorem isDetector_def (G : C) : hG _ fun H hH h => by obtain rfl := Set.mem_singleton_iff.1 hH exact hf h, - fun hG X Y f hf => hG _ fun h => hf _ (Set.mem_singleton _) _⟩ + fun hG _ _ _ hf => hG _ fun _ => hf _ (Set.mem_singleton _) _⟩ theorem IsDetector.def {G : C} : IsDetector G → ∀ ⦃X Y : C⦄ (f : X ⟶ Y), (∀ h : G ⟶ Y, ∃! h', h' ≫ f = h) → IsIso f := @@ -431,7 +431,7 @@ theorem isCodetector_def (G : C) : hG _ fun H hH h => by obtain rfl := Set.mem_singleton_iff.1 hH exact hf h, - fun hG X Y f hf => hG _ fun h => hf _ (Set.mem_singleton _) _⟩ + fun hG _ _ _ hf => hG _ fun _ => hf _ (Set.mem_singleton _) _⟩ theorem IsCodetector.def {G : C} : IsCodetector G → ∀ ⦃X Y : C⦄ (f : X ⟶ Y), (∀ h : X ⟶ G, ∃! h', f ≫ h' = h) → IsIso f := diff --git a/Mathlib/CategoryTheory/GlueData.lean b/Mathlib/CategoryTheory/GlueData.lean index 826e0567ead86f..b43f3893e3bca2 100644 --- a/Mathlib/CategoryTheory/GlueData.lean +++ b/Mathlib/CategoryTheory/GlueData.lean @@ -231,8 +231,8 @@ def mapGlueData : GlueData C' where U i := F.obj (D.U i) V i := F.obj (D.V i) f i j := F.map (D.f i j) - f_mono i j := preserves_mono_of_preservesLimit _ _ - f_id i := inferInstance + f_mono _ _ := preserves_mono_of_preservesLimit _ _ + f_id _ := inferInstance t i j := F.map (D.t i j) t_id i := by simp [D.t_id i] @@ -251,8 +251,8 @@ def diagramIso : D.diagram.multispan ⋙ F ≅ (D.mapGlueData F).diagram.multisp NatIso.ofComponents (fun x => match x with - | WalkingMultispan.left a => Iso.refl _ - | WalkingMultispan.right b => Iso.refl _) + | WalkingMultispan.left _ => Iso.refl _ + | WalkingMultispan.right _ => Iso.refl _) (by rintro (⟨_, _⟩ | _) _ (_ | _ | _) · erw [Category.comp_id, Category.id_comp, Functor.map_id] diff --git a/Mathlib/CategoryTheory/GradedObject/Trifunctor.lean b/Mathlib/CategoryTheory/GradedObject/Trifunctor.lean index b0d783ab327b14..1394e3cc58cec3 100644 --- a/Mathlib/CategoryTheory/GradedObject/Trifunctor.lean +++ b/Mathlib/CategoryTheory/GradedObject/Trifunctor.lean @@ -42,7 +42,7 @@ def mapTrifunctorObj {I₁ : Type*} (X₁ : GradedObject I₁ C₁) (I₂ I₃ : GradedObject I₂ C₂ ⥤ GradedObject I₃ C₃ ⥤ GradedObject (I₁ × I₂ × I₃) C₄ where obj X₂ := { obj := fun X₃ x => ((F.obj (X₁ x.1)).obj (X₂ x.2.1)).obj (X₃ x.2.2) - map := fun {X₃ Y₃} φ x => ((F.obj (X₁ x.1)).obj (X₂ x.2.1)).map (φ x.2.2) } + map := fun {_ _} φ x => ((F.obj (X₁ x.1)).obj (X₂ x.2.1)).map (φ x.2.2) } map {X₂ Y₂} φ := { app := fun X₃ x => ((F.obj (X₁ x.1)).map (φ x.2.1)).app (X₃ x.2.2) } @@ -77,7 +77,7 @@ def mapTrifunctorMapNatTrans (α : F ⟶ F') (I₁ I₂ I₃ : Type*) : mapTrifunctor F I₁ I₂ I₃ ⟶ mapTrifunctor F' I₁ I₂ I₃ where app X₁ := { app := fun X₂ => - { app := fun X₃ i => ((α.app _).app _).app _ } + { app := fun _ _ => ((α.app _).app _).app _ } naturality := fun {X₂ Y₂} φ => by ext X₃ ⟨i₁, i₂, i₃⟩ dsimp @@ -184,7 +184,7 @@ noncomputable def mapTrifunctorMapFunctorObj (X₁ : GradedObject I₁ C₁) GradedObject I₂ C₂ ⥤ GradedObject I₃ C₃ ⥤ GradedObject J C₄ where obj X₂ := { obj := fun X₃ => mapTrifunctorMapObj F p X₁ X₂ X₃ - map := fun {X₃ Y₃} φ => mapTrifunctorMapMap F p (𝟙 X₁) (𝟙 X₂) φ + map := fun {_ _} φ => mapTrifunctorMapMap F p (𝟙 X₁) (𝟙 X₂) φ map_id := fun X₃ => by dsimp ext j i₁ i₂ i₃ h diff --git a/Mathlib/CategoryTheory/Grothendieck.lean b/Mathlib/CategoryTheory/Grothendieck.lean index 59e0d242c7d005..5a361423ddbc94 100644 --- a/Mathlib/CategoryTheory/Grothendieck.lean +++ b/Mathlib/CategoryTheory/Grothendieck.lean @@ -105,7 +105,7 @@ attribute [local simp] eqToHom_map instance : Category (Grothendieck F) where Hom X Y := Grothendieck.Hom X Y id X := Grothendieck.id X - comp := @fun X Y Z f g => Grothendieck.comp f g + comp := @fun _ _ _ f g => Grothendieck.comp f g comp_id := @fun X Y f => by dsimp; ext · simp @@ -147,7 +147,7 @@ variable (F) @[simps!] def forget : Grothendieck F ⥤ C where obj X := X.1 - map := @fun X Y f => f.1 + map := @fun _ _ f => f.1 end @@ -225,7 +225,7 @@ universe v over category `Over E`. -/ def functor {E : Cat.{v,u}} : (E ⥤ Cat.{v,u}) ⥤ Over (T := Cat.{v,u}) E where obj F := Over.mk (X := E) (Y := Cat.of (Grothendieck F)) (Grothendieck.forget F) - map {F G} α := Over.homMk (X:= E) (Grothendieck.map α) Grothendieck.functor_comp_forget + map {_ _} α := Over.homMk (X:= E) (Grothendieck.map α) Grothendieck.functor_comp_forget map_id F := by ext exact Grothendieck.map_id_eq (F := F) diff --git a/Mathlib/CategoryTheory/Groupoid.lean b/Mathlib/CategoryTheory/Groupoid.lean index 4799bc38793172..a880d7c21b5a3b 100644 --- a/Mathlib/CategoryTheory/Groupoid.lean +++ b/Mathlib/CategoryTheory/Groupoid.lean @@ -96,8 +96,8 @@ variable (X Y) def Groupoid.isoEquivHom : (X ≅ Y) ≃ (X ⟶ Y) where toFun := Iso.hom invFun f := ⟨f, Groupoid.inv f, (by aesop_cat), (by aesop_cat)⟩ - left_inv i := Iso.ext rfl - right_inv f := rfl + left_inv _ := Iso.ext rfl + right_inv _ := rfl variable (C) @@ -105,7 +105,7 @@ variable (C) @[simps] noncomputable def Groupoid.invFunctor : C ⥤ Cᵒᵖ where obj := Opposite.op - map {X Y} f := (inv f).op + map {_ _} f := (inv f).op end diff --git a/Mathlib/CategoryTheory/Groupoid/Subgroupoid.lean b/Mathlib/CategoryTheory/Groupoid/Subgroupoid.lean index 54c934333769cf..efe02380cebd5c 100644 --- a/Mathlib/CategoryTheory/Groupoid/Subgroupoid.lean +++ b/Mathlib/CategoryTheory/Groupoid/Subgroupoid.lean @@ -221,13 +221,13 @@ instance : CompleteLattice (Subgroupoid C) := refine fun s => ⟨fun S Ss F => ?_, fun T Tl F fT => ?_⟩ <;> simp only [mem_sInf] exacts [fun hp => hp S Ss, fun S Ss => Tl Ss fT]) with bot := ⊥ - bot_le := fun S => empty_subset _ + bot_le := fun _ => empty_subset _ top := ⊤ - le_top := fun S => subset_univ _ + le_top := fun _ => subset_univ _ inf := (· ⊓ ·) - le_inf := fun R S T RS RT _ pR => ⟨RS pR, RT pR⟩ - inf_le_left := fun R S _ => And.left - inf_le_right := fun R S _ => And.right } + le_inf := fun _ _ _ RS RT _ pR => ⟨RS pR, RT pR⟩ + inf_le_left := fun _ _ _ => And.left + inf_le_right := fun _ _ _ => And.right } theorem le_objs {S T : Subgroupoid C} (h : S ≤ T) : S.objs ⊆ T.objs := fun s ⟨γ, hγ⟩ => ⟨γ, @h ⟨s, s, γ⟩ hγ⟩ diff --git a/Mathlib/CategoryTheory/GuitartExact/Basic.lean b/Mathlib/CategoryTheory/GuitartExact/Basic.lean index c87d10938f0ce6..cb64500850d994 100644 --- a/Mathlib/CategoryTheory/GuitartExact/Basic.lean +++ b/Mathlib/CategoryTheory/GuitartExact/Basic.lean @@ -215,8 +215,8 @@ def costructuredArrowDownwardsPrecomp dsimp rw [← CostructuredArrow.w φ, structuredArrowDownwards_map] rfl) - map_id A := rfl - map_comp φ φ' := rfl + map_id _ := rfl + map_comp _ _ := rfl end diff --git a/Mathlib/CategoryTheory/IsConnected.lean b/Mathlib/CategoryTheory/IsConnected.lean index 4f4fd20d39dbe4..6363451584e8aa 100644 --- a/Mathlib/CategoryTheory/IsConnected.lean +++ b/Mathlib/CategoryTheory/IsConnected.lean @@ -91,7 +91,7 @@ private def liftToDiscrete {α : Type u₂} (F : J ⥤ Discrete α) : J ⥤ Disc /-- Implementation detail of `isoConstant`. -/ private def factorThroughDiscrete {α : Type u₂} (F : J ⥤ Discrete α) : liftToDiscrete F ⋙ Discrete.functor F.obj ≅ F := - NatIso.ofComponents (fun j => eqToIso Function.apply_invFun_apply) (by aesop_cat) + NatIso.ofComponents (fun _ => eqToIso Function.apply_invFun_apply) (by aesop_cat) end IsPreconnected.IsoConstantAux @@ -102,7 +102,7 @@ def isoConstant [IsPreconnected J] {α : Type u₂} (F : J ⥤ Discrete α) (j : F ≅ (Functor.const J).obj (F.obj j) := (IsPreconnected.IsoConstantAux.factorThroughDiscrete F).symm ≪≫ isoWhiskerRight (IsPreconnected.iso_constant _ j).some _ - ≪≫ NatIso.ofComponents (fun j' => eqToIso Function.apply_invFun_apply) (by aesop_cat) + ≪≫ NatIso.ofComponents (fun _ => eqToIso Function.apply_invFun_apply) (by aesop_cat) /-- If `J` is connected, any functor to a discrete category is constant on objects. The converse is given in `IsConnected.of_any_functor_const_on_obj`. @@ -225,7 +225,7 @@ theorem isPreconnected_of_equivalent {K : Type u₂} [Category.{v₂} K] [IsPrec isoWhiskerLeft e.inverse (isoConstant (e.functor ⋙ F) (e.inverse.obj k)) _ ≅ e.inverse ⋙ (Functor.const J).obj (F.obj k) := isoWhiskerLeft _ ((F ⋙ Functor.const J).mapIso (e.counitIso.app k)) - _ ≅ (Functor.const K).obj (F.obj k) := NatIso.ofComponents fun X => Iso.refl _⟩ + _ ≅ (Functor.const K).obj (F.obj k) := NatIso.ofComponents fun _ => Iso.refl _⟩ lemma isPreconnected_iff_of_equivalence {K : Type u₂} [Category.{v₂} K] (e : J ≌ K) : IsPreconnected J ↔ IsPreconnected K := diff --git a/Mathlib/CategoryTheory/IsomorphismClasses.lean b/Mathlib/CategoryTheory/IsomorphismClasses.lean index 847b0684305c1e..d14b1824f039df 100644 --- a/Mathlib/CategoryTheory/IsomorphismClasses.lean +++ b/Mathlib/CategoryTheory/IsomorphismClasses.lean @@ -39,7 +39,7 @@ end Category -/ def isomorphismClasses : Cat.{v, u} ⥤ Type u where obj C := Quotient (isIsomorphicSetoid C.α) - map {C D} F := Quot.map F.obj fun X Y ⟨f⟩ => ⟨F.mapIso f⟩ + map {_ _} F := Quot.map F.obj fun _ _ ⟨f⟩ => ⟨F.mapIso f⟩ map_id {C} := by -- Porting note: this used to be `tidy` dsimp; apply funext; intro x apply @Quot.recOn _ _ _ x diff --git a/Mathlib/CategoryTheory/Limits/ConeCategory.lean b/Mathlib/CategoryTheory/Limits/ConeCategory.lean index dd971c3b5c792e..f7427f3b613766 100644 --- a/Mathlib/CategoryTheory/Limits/ConeCategory.lean +++ b/Mathlib/CategoryTheory/Limits/ConeCategory.lean @@ -145,12 +145,12 @@ def Cone.equivCostructuredArrow (F : J ⥤ C) : Cone F ≌ CostructuredArrow (co functor := Cone.toCostructuredArrow F inverse := Cone.fromCostructuredArrow F unitIso := NatIso.ofComponents Cones.eta - counitIso := NatIso.ofComponents fun c => (CostructuredArrow.eta _).symm + counitIso := NatIso.ofComponents fun _ => (CostructuredArrow.eta _).symm /-- A cone is a limit cone iff it is terminal. -/ def Cone.isLimitEquivIsTerminal {F : J ⥤ C} (c : Cone F) : IsLimit c ≃ IsTerminal c := IsLimit.isoUniqueConeMorphism.toEquiv.trans - { toFun := fun h => IsTerminal.ofUnique _ + { toFun := fun _ => IsTerminal.ofUnique _ invFun := fun h s => ⟨⟨IsTerminal.from h s⟩, fun a => IsTerminal.hom_ext h a _⟩ left_inv := by aesop_cat right_inv := by aesop_cat } @@ -304,12 +304,12 @@ def Cocone.equivStructuredArrow (F : J ⥤ C) : Cocone F ≌ StructuredArrow F ( functor := Cocone.toStructuredArrow F inverse := Cocone.fromStructuredArrow F unitIso := NatIso.ofComponents Cocones.eta - counitIso := NatIso.ofComponents fun c => (StructuredArrow.eta _).symm + counitIso := NatIso.ofComponents fun _ => (StructuredArrow.eta _).symm /-- A cocone is a colimit cocone iff it is initial. -/ def Cocone.isColimitEquivIsInitial {F : J ⥤ C} (c : Cocone F) : IsColimit c ≃ IsInitial c := IsColimit.isoUniqueCoconeMorphism.toEquiv.trans - { toFun := fun h => IsInitial.ofUnique _ + { toFun := fun _ => IsInitial.ofUnique _ invFun := fun h s => ⟨⟨IsInitial.to h s⟩, fun a => IsInitial.hom_ext h a _⟩ left_inv := by aesop_cat right_inv := by aesop_cat } diff --git a/Mathlib/CategoryTheory/Limits/Cones.lean b/Mathlib/CategoryTheory/Limits/Cones.lean index 157d042f4667c1..29912d06cb23ce 100644 --- a/Mathlib/CategoryTheory/Limits/Cones.lean +++ b/Mathlib/CategoryTheory/Limits/Cones.lean @@ -195,7 +195,7 @@ def equiv (F : J ⥤ C) : Cone F ≅ ΣX, F.cones.obj X where /-- A map to the vertex of a cone naturally induces a cone by composition. -/ @[simps] def extensions (c : Cone F) : yoneda.obj c.pt ⋙ uliftFunctor.{u₁} ⟶ F.cones where - app X f := (const J).map f.down ≫ c.π + app _ f := (const J).map f.down ≫ c.π /-- A map to the vertex of a cone induces a cone by composition. -/ @[simps] @@ -231,7 +231,7 @@ def equiv (F : J ⥤ C) : Cocone F ≅ ΣX, F.cocones.obj X where /-- A map from the vertex of a cocone naturally induces a cocone by composition. -/ @[simps] def extensions (c : Cocone F) : coyoneda.obj (op c.pt) ⋙ uliftFunctor.{u₁} ⟶ F.cocones where - app X f := c.ι ≫ (const J).map f.down + app _ f := c.ι ≫ (const J).map f.down /-- A map from the vertex of a cocone induces a cocone by composition. -/ @[simps] diff --git a/Mathlib/CategoryTheory/Limits/Connected.lean b/Mathlib/CategoryTheory/Limits/Connected.lean index bdf8561e455a95..82a4900695c0d7 100644 --- a/Mathlib/CategoryTheory/Limits/Connected.lean +++ b/Mathlib/CategoryTheory/Limits/Connected.lean @@ -64,12 +64,12 @@ namespace ProdPreservesConnectedLimits /-- (Impl). The obvious natural transformation from (X × K -) to K. -/ @[simps] -def γ₂ {K : J ⥤ C} (X : C) : K ⋙ prod.functor.obj X ⟶ K where app Y := Limits.prod.snd +def γ₂ {K : J ⥤ C} (X : C) : K ⋙ prod.functor.obj X ⟶ K where app _ := Limits.prod.snd /-- (Impl). The obvious natural transformation from (X × K -) to X -/ @[simps] def γ₁ {K : J ⥤ C} (X : C) : K ⋙ prod.functor.obj X ⟶ (Functor.const J).obj X where - app Y := Limits.prod.fst + app _ := Limits.prod.fst /-- (Impl). Given a cone for (X × K -), produce a cone for K using the natural transformation `γ₂` -/ diff --git a/Mathlib/CategoryTheory/Limits/Constructions/BinaryProducts.lean b/Mathlib/CategoryTheory/Limits/Constructions/BinaryProducts.lean index 9f345d49e3cf58..93baeb3c4ad9d3 100644 --- a/Mathlib/CategoryTheory/Limits/Constructions/BinaryProducts.lean +++ b/Mathlib/CategoryTheory/Limits/Constructions/BinaryProducts.lean @@ -33,7 +33,7 @@ def isBinaryProductOfIsTerminalIsPullback (F : Discrete WalkingPair ⥤ C) (c : lift s := hc.lift (PullbackCone.mk (s.π.app ⟨WalkingPair.left⟩) (s.π.app ⟨WalkingPair.right⟩) (hX.hom_ext _ _)) - fac s j := + fac _ j := Discrete.casesOn j fun j => WalkingPair.casesOn j (hc.fac _ WalkingCospan.left) (hc.fac _ WalkingCospan.right) uniq s m J := by @@ -120,7 +120,7 @@ def isBinaryCoproductOfIsInitialIsPushout (F : Discrete WalkingPair ⥤ C) (c : desc s := hc.desc (PushoutCocone.mk (s.ι.app ⟨WalkingPair.left⟩) (s.ι.app ⟨WalkingPair.right⟩) (hX.hom_ext _ _)) - fac s j := + fac _ j := Discrete.casesOn j fun j => WalkingPair.casesOn j (hc.fac _ WalkingSpan.left) (hc.fac _ WalkingSpan.right) uniq s m J := by diff --git a/Mathlib/CategoryTheory/Limits/Constructions/Filtered.lean b/Mathlib/CategoryTheory/Limits/Constructions/Filtered.lean index 38bfd50516c2af..423e5cc93ea1b2 100644 --- a/Mathlib/CategoryTheory/Limits/Constructions/Filtered.lean +++ b/Mathlib/CategoryTheory/Limits/Constructions/Filtered.lean @@ -58,7 +58,7 @@ def liftToFinsetColimitCocone [HasFilteredColimitsOfSize.{w, w} C] (F : Discrete { desc := fun s => colimit.desc (liftToFinsetObj F) { pt := s.pt - ι := { app := fun t => Sigma.desc fun x => s.ι.app x } } + ι := { app := fun _ => Sigma.desc fun x => s.ι.app x } } uniq := fun s m h => by apply colimit.hom_ext rintro t diff --git a/Mathlib/CategoryTheory/Limits/Constructions/LimitsOfProductsAndEqualizers.lean b/Mathlib/CategoryTheory/Limits/Constructions/LimitsOfProductsAndEqualizers.lean index 5cf6eebed99237..bd52c4c1ea3b75 100644 --- a/Mathlib/CategoryTheory/Limits/Constructions/LimitsOfProductsAndEqualizers.lean +++ b/Mathlib/CategoryTheory/Limits/Constructions/LimitsOfProductsAndEqualizers.lean @@ -55,7 +55,7 @@ def buildLimit (i : Fork s t) : Cone F where pt := i.pt π := - { app := fun j => i.ι ≫ c₁.π.app ⟨_⟩ + { app := fun _ => i.ι ≫ c₁.π.app ⟨_⟩ naturality := fun j₁ j₂ f => by dsimp rw [Category.id_comp, Category.assoc, ← hs ⟨⟨_, _⟩, f⟩, i.condition_assoc, ht] } @@ -264,7 +264,7 @@ def buildColimit (i : Cofork s t) : Cocone F where pt := i.pt ι := - { app := fun j => c₂.ι.app ⟨_⟩ ≫ i.π + { app := fun _ => c₂.ι.app ⟨_⟩ ≫ i.π naturality := fun j₁ j₂ f => by dsimp have reassoced (f : (p : J × J) × (p.fst ⟶ p.snd)) {W : C} {h : _ ⟶ W} : diff --git a/Mathlib/CategoryTheory/Limits/FunctorCategory/Basic.lean b/Mathlib/CategoryTheory/Limits/FunctorCategory/Basic.lean index 0b2e0d72e2f6e4..78e8c5a55bbddb 100644 --- a/Mathlib/CategoryTheory/Limits/FunctorCategory/Basic.lean +++ b/Mathlib/CategoryTheory/Limits/FunctorCategory/Basic.lean @@ -399,7 +399,7 @@ def colimitIsoFlipCompColim [HasColimitsOfShape J C] (F : J ⥤ K ⥤ C) : colim /-- A variant of `colimit_iso_flip_comp_colim` where the arguments of `F` are flipped. -/ @[simps!] def colimitFlipIsoCompColim [HasColimitsOfShape J C] (F : K ⥤ J ⥤ C) : colimit F.flip ≅ F ⋙ colim := - let f := fun k => + let f := fun _ => colimitObjIsoColimitCompEvaluation _ _ ≪≫ HasColimit.isoOfNatIso (flipCompEvaluation _ _) NatIso.ofComponents f diff --git a/Mathlib/CategoryTheory/Limits/HasLimits.lean b/Mathlib/CategoryTheory/Limits/HasLimits.lean index 5478f806f7e4b2..75d8b50abec230 100644 --- a/Mathlib/CategoryTheory/Limits/HasLimits.lean +++ b/Mathlib/CategoryTheory/Limits/HasLimits.lean @@ -494,10 +494,10 @@ def constLimAdj : (const J : C ⥤ J ⥤ C) ⊣ lim := Adjunction.mk' { homEquiv := fun c g ↦ { toFun := fun f => limit.lift _ ⟨c, f⟩ invFun := fun f => - { app := fun j => f ≫ limit.π _ _ } + { app := fun _ => f ≫ limit.π _ _ } left_inv := by aesop_cat right_inv := by aesop_cat } - unit := { app := fun c => limit.lift _ ⟨_, 𝟙 _⟩ } + unit := { app := fun _ => limit.lift _ ⟨_, 𝟙 _⟩ } counit := { app := fun g => { app := limit.π _ } } } instance : IsRightAdjoint (lim : (J ⥤ C) ⥤ C) := @@ -1030,7 +1030,7 @@ def colimConstAdj : (colim : (J ⥤ C) ⥤ C) ⊣ const J := Adjunction.mk' { left_inv := by aesop_cat right_inv := by aesop_cat } unit := { app := fun g => { app := colimit.ι _ } } - counit := { app := fun c => colimit.desc _ ⟨_, 𝟙 _⟩ } } + counit := { app := fun _ => colimit.desc _ ⟨_, 𝟙 _⟩ } } instance : IsLeftAdjoint (colim : (J ⥤ C) ⥤ C) := ⟨_, ⟨colimConstAdj⟩⟩ diff --git a/Mathlib/CategoryTheory/Limits/Indization/IndObject.lean b/Mathlib/CategoryTheory/Limits/Indization/IndObject.lean index 737104b5fb924f..e51a540125e55c 100644 --- a/Mathlib/CategoryTheory/Limits/Indization/IndObject.lean +++ b/Mathlib/CategoryTheory/Limits/Indization/IndObject.lean @@ -107,10 +107,10 @@ instance : P.toCostructuredArrow.Final := def yoneda (X : C) : IndObjectPresentation (yoneda.obj X) where I := Discrete PUnit.{v + 1} F := Functor.fromPUnit X - ι := { app := fun s => 𝟙 _ } + ι := { app := fun _ => 𝟙 _ } isColimit := { desc := fun s => s.ι.app ⟨PUnit.unit⟩ - uniq := fun s m h => h ⟨PUnit.unit⟩ } + uniq := fun _ _ h => h ⟨PUnit.unit⟩ } end IndObjectPresentation diff --git a/Mathlib/CategoryTheory/Limits/IsConnected.lean b/Mathlib/CategoryTheory/Limits/IsConnected.lean index a0e0dd26b49f2d..97d144d9c19bb0 100644 --- a/Mathlib/CategoryTheory/Limits/IsConnected.lean +++ b/Mathlib/CategoryTheory/Limits/IsConnected.lean @@ -50,7 +50,7 @@ def constPUnitFunctor : C ⥤ Type w := (Functor.const C).obj PUnit.{w + 1} @[simps] def pUnitCocone : Cocone (constPUnitFunctor.{w} C) where pt := PUnit - ι := { app := fun X => id } + ι := { app := fun _ => id } /-- If `C` is connected, the cocone on `constPUnitFunctor` with cone point `PUnit` is a colimit cocone. -/ diff --git a/Mathlib/CategoryTheory/Limits/IsLimit.lean b/Mathlib/CategoryTheory/Limits/IsLimit.lean index 76802822f383d1..663c41495a8197 100644 --- a/Mathlib/CategoryTheory/Limits/IsLimit.lean +++ b/Mathlib/CategoryTheory/Limits/IsLimit.lean @@ -191,7 +191,7 @@ variable {t : Cone F} 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 b => rfl + 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. -/ diff --git a/Mathlib/CategoryTheory/Limits/Lattice.lean b/Mathlib/CategoryTheory/Limits/Lattice.lean index ccf7e6cf116241..4e07dc534469f9 100644 --- a/Mathlib/CategoryTheory/Limits/Lattice.lean +++ b/Mathlib/CategoryTheory/Limits/Lattice.lean @@ -32,7 +32,7 @@ variable {J : Type w} [SmallCategory J] [FinCategory J] def finiteLimitCone [SemilatticeInf α] [OrderTop α] (F : J ⥤ α) : LimitCone F where cone := { pt := Finset.univ.inf F.obj - π := { app := fun j => homOfLE (Finset.inf_le (Fintype.complete _)) } } + π := { app := fun _ => homOfLE (Finset.inf_le (Fintype.complete _)) } } isLimit := { lift := fun s => homOfLE (Finset.le_inf fun j _ => (s.π.app j).down.down) } /-- @@ -41,7 +41,7 @@ The colimit cocone over any functor from a finite diagram into a `SemilatticeSup def finiteColimitCocone [SemilatticeSup α] [OrderBot α] (F : J ⥤ α) : ColimitCocone F where cocone := { pt := Finset.univ.sup F.obj - ι := { app := fun i => homOfLE (Finset.le_sup (Fintype.complete _)) } } + ι := { app := fun _ => homOfLE (Finset.le_sup (Fintype.complete _)) } } isColimit := { desc := fun s => homOfLE (Finset.sup_le fun j _ => (s.ι.app j).down.down) } -- see Note [lower instance priority] @@ -170,7 +170,7 @@ variable {J : Type u} [SmallCategory J] def limitCone (F : J ⥤ α) : LimitCone F where cone := { pt := iInf F.obj - π := { app := fun j => homOfLE (CompleteLattice.sInf_le _ _ (Set.mem_range_self _)) } } + π := { app := fun _ => homOfLE (CompleteLattice.sInf_le _ _ (Set.mem_range_self _)) } } isLimit := { lift := fun s => homOfLE (CompleteLattice.le_sInf _ _ (by rintro _ ⟨j, rfl⟩; exact (s.π.app j).le)) } @@ -180,7 +180,7 @@ def limitCone (F : J ⥤ α) : LimitCone F where def colimitCocone (F : J ⥤ α) : ColimitCocone F where cocone := { pt := iSup F.obj - ι := { app := fun j => homOfLE (CompleteLattice.le_sSup _ _ (Set.mem_range_self _)) } } + ι := { app := fun _ => homOfLE (CompleteLattice.le_sSup _ _ (Set.mem_range_self _)) } } isColimit := { desc := fun s => homOfLE (CompleteLattice.sSup_le _ _ (by rintro _ ⟨j, rfl⟩; exact (s.ι.app j).le)) } diff --git a/Mathlib/CategoryTheory/Limits/Opposites.lean b/Mathlib/CategoryTheory/Limits/Opposites.lean index a988e6bc1335df..c630f89557f363 100644 --- a/Mathlib/CategoryTheory/Limits/Opposites.lean +++ b/Mathlib/CategoryTheory/Limits/Opposites.lean @@ -849,7 +849,7 @@ def CokernelCofork.IsColimit.ofπOp {X Y Q : C} (p : Y ⟶ Q) {f : X ⟶ Y} IsLimit (KernelFork.ofι p.op (show p.op ≫ f.op = 0 by rw [← op_comp, w, op_zero])) := KernelFork.IsLimit.ofι _ _ (fun x hx => (h.desc (CokernelCofork.ofπ x.unop (Quiver.Hom.op_inj hx))).op) - (fun x hx => Quiver.Hom.unop_inj (Cofork.IsColimit.π_desc h)) + (fun _ _ => Quiver.Hom.unop_inj (Cofork.IsColimit.π_desc h)) (fun x hx b hb => Quiver.Hom.unop_inj (Cofork.IsColimit.hom_ext h (by simpa only [Quiver.Hom.unop_op, Cofork.IsColimit.π_desc] using Quiver.Hom.op_inj hb))) @@ -860,7 +860,7 @@ def CokernelCofork.IsColimit.ofπUnop {X Y Q : Cᵒᵖ} (p : Y ⟶ Q) {f : X ⟶ IsLimit (KernelFork.ofι p.unop (show p.unop ≫ f.unop = 0 by rw [← unop_comp, w, unop_zero])) := KernelFork.IsLimit.ofι _ _ (fun x hx => (h.desc (CokernelCofork.ofπ x.op (Quiver.Hom.unop_inj hx))).unop) - (fun x hx => Quiver.Hom.op_inj (Cofork.IsColimit.π_desc h)) + (fun _ _ => Quiver.Hom.op_inj (Cofork.IsColimit.π_desc h)) (fun x hx b hb => Quiver.Hom.op_inj (Cofork.IsColimit.hom_ext h (by simpa only [Quiver.Hom.op_unop, Cofork.IsColimit.π_desc] using Quiver.Hom.unop_inj hb))) @@ -871,7 +871,7 @@ def KernelFork.IsLimit.ofιOp {K X Y : C} (i : K ⟶ X) {f : X ⟶ Y} (show f.op ≫ i.op = 0 by rw [← op_comp, w, op_zero])) := CokernelCofork.IsColimit.ofπ _ _ (fun x hx => (h.lift (KernelFork.ofι x.unop (Quiver.Hom.op_inj hx))).op) - (fun x hx => Quiver.Hom.unop_inj (Fork.IsLimit.lift_ι h)) + (fun _ _ => Quiver.Hom.unop_inj (Fork.IsLimit.lift_ι h)) (fun x hx b hb => Quiver.Hom.unop_inj (Fork.IsLimit.hom_ext h (by simpa only [Quiver.Hom.unop_op, Fork.IsLimit.lift_ι] using Quiver.Hom.op_inj hb))) @@ -883,7 +883,7 @@ def KernelFork.IsLimit.ofιUnop {K X Y : Cᵒᵖ} (i : K ⟶ X) {f : X ⟶ Y} (show f.unop ≫ i.unop = 0 by rw [← unop_comp, w, unop_zero])) := CokernelCofork.IsColimit.ofπ _ _ (fun x hx => (h.lift (KernelFork.ofι x.op (Quiver.Hom.unop_inj hx))).unop) - (fun x hx => Quiver.Hom.op_inj (Fork.IsLimit.lift_ι h)) + (fun _ _ => Quiver.Hom.op_inj (Fork.IsLimit.lift_ι h)) (fun x hx b hb => Quiver.Hom.op_inj (Fork.IsLimit.hom_ext h (by simpa only [Quiver.Hom.op_unop, Fork.IsLimit.lift_ι] using Quiver.Hom.unop_inj hb))) diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Basic.lean b/Mathlib/CategoryTheory/Limits/Preserves/Basic.lean index 0926bbae01d71f..f5abc3a11449f8 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Basic.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Basic.lean @@ -145,7 +145,7 @@ instance idPreservesLimits : PreservesLimitsOfSize.{w', w} (𝟭 C) where { preservesLimit := fun {K} => ⟨fun {c} h => - ⟨fun s => h.lift ⟨s.pt, fun j => s.π.app j, fun j j' f => s.π.naturality f⟩, by + ⟨fun s => h.lift ⟨s.pt, fun j => s.π.app j, fun _ _ f => s.π.naturality f⟩, by cases K; rcases c with ⟨_, _, _⟩; intro s j; cases s; exact h.fac _ j, by cases K; rcases c with ⟨_, _, _⟩; intro s m w; rcases s with ⟨_, _, _⟩; exact h.uniq _ m w⟩⟩ } @@ -155,7 +155,7 @@ instance idPreservesColimits : PreservesColimitsOfSize.{w', w} (𝟭 C) where { preservesColimit := fun {K} => ⟨fun {c} h => - ⟨fun s => h.desc ⟨s.pt, fun j => s.ι.app j, fun j j' f => s.ι.naturality f⟩, by + ⟨fun s => h.desc ⟨s.pt, fun j => s.ι.app j, fun _ _ f => s.ι.naturality f⟩, by cases K; rcases c with ⟨_, _, _⟩; intro s j; cases s; exact h.fac _ j, by cases K; rcases c with ⟨_, _, _⟩; intro s m w; rcases s with ⟨_, _, _⟩; exact h.uniq _ m w⟩⟩ } @@ -451,7 +451,7 @@ instance idReflectsLimits : ReflectsLimitsOfSize.{w, w'} (𝟭 C) where { reflectsLimit := fun {K} => ⟨fun {c} h => - ⟨fun s => h.lift ⟨s.pt, fun j => s.π.app j, fun j j' f => s.π.naturality f⟩, by + ⟨fun s => h.lift ⟨s.pt, fun j => s.π.app j, fun _ _ f => s.π.naturality f⟩, by cases K; rcases c with ⟨_, _, _⟩; intro s j; cases s; exact h.fac _ j, by cases K; rcases c with ⟨_, _, _⟩; intro s m w; rcases s with ⟨_, _, _⟩; exact h.uniq _ m w⟩⟩ } @@ -461,7 +461,7 @@ instance idReflectsColimits : ReflectsColimitsOfSize.{w, w'} (𝟭 C) where { reflectsColimit := fun {K} => ⟨fun {c} h => - ⟨fun s => h.desc ⟨s.pt, fun j => s.ι.app j, fun j j' f => s.ι.naturality f⟩, by + ⟨fun s => h.desc ⟨s.pt, fun j => s.ι.app j, fun _ _ f => s.ι.naturality f⟩, by cases K; rcases c with ⟨_, _, _⟩; intro s j; cases s; exact h.fac _ j, by cases K; rcases c with ⟨_, _, _⟩; intro s m w; rcases s with ⟨_, _, _⟩; exact h.uniq _ m w⟩⟩ } @@ -707,7 +707,7 @@ instance fullyFaithfulReflectsLimits [F.Full] [F.Faithful] : ReflectsLimitsOfSiz reflectsLimitsOfShape {J} 𝒥₁ := { reflectsLimit := fun {K} => { reflects := fun {c} t => - (IsLimit.mkConeMorphism fun s => + (IsLimit.mkConeMorphism fun _ => (Cones.functoriality K F).preimage (t.liftConeMorphism _)) <| by apply fun s m => (Cones.functoriality K F).map_injective _ intro s m @@ -720,7 +720,7 @@ instance fullyFaithfulReflectsColimits [F.Full] [F.Faithful] : reflectsColimitsOfShape {J} 𝒥₁ := { reflectsColimit := fun {K} => { reflects := fun {c} t => - (IsColimit.mkCoconeMorphism fun s => + (IsColimit.mkCoconeMorphism fun _ => (Cocones.functoriality K F).preimage (t.descCoconeMorphism _)) <| by apply fun s m => (Cocones.functoriality K F).map_injective _ intro s m diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Zero.lean b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Zero.lean index f13d94165852eb..1b3b19cbe41531 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Zero.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Shapes/Zero.lean @@ -178,13 +178,13 @@ variable [HasZeroObject D] [HasZeroMorphisms D] /-- A zero functor preserves limits. -/ def preservesLimitsOfShapeOfIsZero : PreservesLimitsOfShape J G where - preservesLimit {K} := ⟨fun hc => by + preservesLimit {K} := ⟨fun _ => by rw [Functor.isZero_iff] at hG exact IsLimit.ofIsZero _ ((K ⋙ G).isZero (fun X ↦ hG _)) (hG _)⟩ /-- A zero functor preserves colimits. -/ def preservesColimitsOfShapeOfIsZero : PreservesColimitsOfShape J G where - preservesColimit {K} := ⟨fun hc => by + preservesColimit {K} := ⟨fun _ => by rw [Functor.isZero_iff] at hG exact IsColimit.ofIsZero _ ((K ⋙ G).isZero (fun X ↦ hG _)) (hG _)⟩ diff --git a/Mathlib/CategoryTheory/Limits/Presheaf.lean b/Mathlib/CategoryTheory/Limits/Presheaf.lean index 8dd0215926fc0a..5dc588dc02b386 100644 --- a/Mathlib/CategoryTheory/Limits/Presheaf.lean +++ b/Mathlib/CategoryTheory/Limits/Presheaf.lean @@ -74,7 +74,7 @@ def restrictedYonedaHomEquiv' (P : Cᵒᵖ ⥤ Type v₁) (E : ℰ) : (Functor.const (CostructuredArrow yoneda P)).obj E) ≃ (P ⟶ (restrictedYoneda A).obj E) where toFun f := - { app := fun X x => f.app (CostructuredArrow.mk (yonedaEquiv.symm x)) + { app := fun _ x => f.app (CostructuredArrow.mk (yonedaEquiv.symm x)) naturality := fun {X₁ X₂} φ => by ext x let ψ : CostructuredArrow.mk (yonedaEquiv.symm (P.toPrefunctor.map φ x)) ⟶ diff --git a/Mathlib/CategoryTheory/Limits/Shapes/BinaryProducts.lean b/Mathlib/CategoryTheory/Limits/Shapes/BinaryProducts.lean index 1c442221fe5323..0d8529d45ba774 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/BinaryProducts.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/BinaryProducts.lean @@ -210,7 +210,7 @@ def BinaryFan.IsLimit.mk {X Y : C} (s : BinaryFan X Y) rintro t (rfl | rfl) · exact hl₁ _ _ · exact hl₂ _ _) - fun t m h => uniq _ _ _ (h ⟨WalkingPair.left⟩) (h ⟨WalkingPair.right⟩) + fun _ _ h => uniq _ _ _ (h ⟨WalkingPair.left⟩) (h ⟨WalkingPair.right⟩) theorem BinaryFan.IsLimit.hom_ext {W X Y : C} {s : BinaryFan X Y} (h : IsLimit s) {f g : W ⟶ s.pt} (h₁ : f ≫ s.fst = g ≫ s.fst) (h₂ : f ≫ s.snd = g ≫ s.snd) : f = g := @@ -247,7 +247,7 @@ def BinaryCofan.IsColimit.mk {X Y : C} (s : BinaryCofan X Y) rintro t (rfl | rfl) · exact hd₁ _ _ · exact hd₂ _ _) - fun t m h => uniq _ _ _ (h ⟨WalkingPair.left⟩) (h ⟨WalkingPair.right⟩) + fun _ _ h => uniq _ _ _ (h ⟨WalkingPair.left⟩) (h ⟨WalkingPair.right⟩) theorem BinaryCofan.IsColimit.hom_ext {W X Y : C} {s : BinaryCofan X Y} (h : IsColimit s) {f g : s.pt ⟶ W} (h₁ : s.inl ≫ f = s.inl ≫ g) (h₂ : s.inr ≫ f = s.inr ≫ g) : f = g := @@ -1021,7 +1021,7 @@ variable {C} [Category.{v} C] [HasBinaryProducts C] def prod.functor : C ⥤ C ⥤ C where obj X := { obj := fun Y => X ⨯ Y - map := fun {Y Z} => prod.map (𝟙 X) } + map := fun {_ _} => prod.map (𝟙 X) } map f := { app := fun T => prod.map f (𝟙 T) } @@ -1042,7 +1042,7 @@ variable {C} [Category.{v} C] [HasBinaryCoproducts C] def coprod.functor : C ⥤ C ⥤ C where obj X := { obj := fun Y => X ⨿ Y - map := fun {Y Z} => coprod.map (𝟙 X) } + map := fun {_ _} => coprod.map (𝟙 X) } map f := { app := fun T => coprod.map f (𝟙 T) } /-- The coproduct functor can be decomposed. -/ diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean b/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean index 7a16ef661d0bff..ba161d31082771 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean @@ -176,7 +176,7 @@ attribute [local aesop safe cases (rule_sets := [CategoryTheory])] Eq /-- Extract the cone from a bicone. -/ def toConeFunctor : Bicone F ⥤ Cone (Discrete.functor F) where obj B := { pt := B.pt, π := { app := fun j => B.π j.as } } - map {X Y} F := { hom := F.hom, w := fun _ => F.wπ _ } + map {_ _} F := { hom := F.hom, w := fun _ => F.wπ _ } /-- A shorthand for `toConeFunctor.obj` -/ abbrev toCone (B : Bicone F) : Cone (Discrete.functor F) := toConeFunctor.obj B @@ -197,7 +197,7 @@ theorem toCone_proj (B : Bicone F) (j : J) : Fan.proj B.toCone j = B.π j := rfl /-- Extract the cocone from a bicone. -/ def toCoconeFunctor : Bicone F ⥤ Cocone (Discrete.functor F) where obj B := { pt := B.pt, ι := { app := fun j => B.ι j.as } } - map {X Y} F := { hom := F.hom, w := fun _ => F.wι _ } + map {_ _} F := { hom := F.hom, w := fun _ => F.wι _ } /-- A shorthand for `toCoconeFunctor.obj` -/ abbrev toCocone (B : Bicone F) : Cocone (Discrete.functor F) := toCoconeFunctor.obj B @@ -862,7 +862,7 @@ def kernelForkBiproductToSubtype (p : Set K) : rw [dif_neg k.2] simp only [zero_comp]) isLimit := - KernelFork.IsLimit.ofι _ _ (fun {W} g _ => g ≫ biproduct.toSubtype f pᶜ) + KernelFork.IsLimit.ofι _ _ (fun {_} g _ => g ≫ biproduct.toSubtype f pᶜ) (by intro W' g' w ext j @@ -898,7 +898,7 @@ def cokernelCoforkBiproductFromSubtype (p : Set K) : · simp only [zero_comp] · exact not_not.mpr k.2) isColimit := - CokernelCofork.IsColimit.ofπ _ _ (fun {W} g _ => biproduct.fromSubtype f pᶜ ≫ g) + CokernelCofork.IsColimit.ofπ _ _ (fun {_} g _ => biproduct.fromSubtype f pᶜ ≫ g) (by intro W g' w ext j diff --git a/Mathlib/CategoryTheory/Limits/Shapes/ConcreteCategory.lean b/Mathlib/CategoryTheory/Limits/Shapes/ConcreteCategory.lean index 3388588964ed59..6c954e928f31d5 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/ConcreteCategory.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/ConcreteCategory.lean @@ -263,7 +263,7 @@ def multiequalizerEquivAux (I : MulticospanIndex C) : (I.multicospan ⋙ forget C).sections ≃ { x : ∀ i : I.L, I.left i // ∀ i : I.R, I.fst i (x _) = I.snd i (x _) } where toFun x := - ⟨fun i => x.1 (WalkingMulticospan.left _), fun i => by + ⟨fun _ => x.1 (WalkingMulticospan.left _), fun i => by have a := x.2 (WalkingMulticospan.Hom.fst i) have b := x.2 (WalkingMulticospan.Hom.snd i) rw [← b] at a @@ -271,7 +271,7 @@ def multiequalizerEquivAux (I : MulticospanIndex C) : invFun x := { val := fun j => match j with - | WalkingMulticospan.left a => x.1 _ + | WalkingMulticospan.left _ => x.1 _ | WalkingMulticospan.right b => I.fst b (x.1 _) property := by rintro (a | b) (a' | b') (f | f | f) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean b/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean index 05a92677fd9090..0bc2aff0e4a460 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean @@ -494,8 +494,8 @@ def Fork.IsLimit.homIso {X Y : C} {f g : X ⟶ Y} {t : Fork f g} (ht : IsLimit t (Z ⟶ t.pt) ≃ { h : Z ⟶ X // h ≫ f = h ≫ g } where toFun k := ⟨k ≫ t.ι, by simp only [Category.assoc, t.condition]⟩ invFun h := (Fork.IsLimit.lift' ht _ h.prop).1 - left_inv k := Fork.IsLimit.hom_ext ht (Fork.IsLimit.lift' _ _ _).prop - right_inv h := Subtype.ext (Fork.IsLimit.lift' ht _ _).prop + left_inv _ := Fork.IsLimit.hom_ext ht (Fork.IsLimit.lift' _ _ _).prop + right_inv _ := Subtype.ext (Fork.IsLimit.lift' ht _ _).prop /-- The bijection of `Fork.IsLimit.homIso` is natural in `Z`. -/ theorem Fork.IsLimit.homIso_natural {X Y : C} {f g : X ⟶ Y} {t : Fork f g} (ht : IsLimit t) @@ -513,8 +513,8 @@ def Cofork.IsColimit.homIso {X Y : C} {f g : X ⟶ Y} {t : Cofork f g} (ht : IsC (t.pt ⟶ Z) ≃ { h : Y ⟶ Z // f ≫ h = g ≫ h } where toFun k := ⟨t.π ≫ k, by simp only [← Category.assoc, t.condition]⟩ invFun h := (Cofork.IsColimit.desc' ht _ h.prop).1 - left_inv k := Cofork.IsColimit.hom_ext ht (Cofork.IsColimit.desc' _ _ _).prop - right_inv h := Subtype.ext (Cofork.IsColimit.desc' ht _ _).prop + left_inv _ := Cofork.IsColimit.hom_ext ht (Cofork.IsColimit.desc' _ _ _).prop + right_inv _ := Subtype.ext (Cofork.IsColimit.desc' ht _ _).prop /-- The bijection of `Cofork.IsColimit.homIso` is natural in `Z`. -/ theorem Cofork.IsColimit.homIso_natural {X Y : C} {f g : X ⟶ Y} {t : Cofork f g} {Z Z' : C} @@ -767,7 +767,7 @@ def idFork (h : f = g) : Fork f g := /-- 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 s => Category.comp_id _) fun s m h => by + Fork.IsLimit.mk _ (fun s => Fork.ι s) (fun _ => Category.comp_id _) fun s m h => by convert h exact (Category.comp_id _).symm @@ -927,7 +927,7 @@ def idCofork (h : f = g) : Cofork f g := /-- 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 s => Category.id_comp _) fun s m h => by + Cofork.IsColimit.mk _ (fun s => Cofork.π s) (fun _ => Category.id_comp _) fun s m h => by convert h exact (Category.id_comp _).symm diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean b/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean index b829a05e80be7d..9015e814eea120 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Kernels.lean @@ -154,7 +154,7 @@ def KernelFork.IsLimit.ofι {W : C} (g : W ⟶ X) (eq : g ≫ f = 0) def KernelFork.IsLimit.ofι' {X Y K : C} {f : X ⟶ Y} (i : K ⟶ X) (w : i ≫ f = 0) (h : ∀ {A : C} (k : A ⟶ X) (_ : k ≫ f = 0), { l : A ⟶ K // l ≫ i = k}) [hi : Mono i] : IsLimit (KernelFork.ofι i w) := - ofι _ _ (fun {A} k hk => (h k hk).1) (fun {A} k hk => (h k hk).2) (fun {A} k hk m hm => by + ofι _ _ (fun {_} k hk => (h k hk).1) (fun {_} k hk => (h k hk).2) (fun {A} k hk m hm => by rw [← cancel_mono i, (h k hk).2, hm]) /-- Every kernel of `f` induces a kernel of `f ≫ g` if `g` is mono. -/ @@ -188,7 +188,7 @@ def KernelFork.IsLimit.ofId {X Y : C} (f : X ⟶ Y) (hf : f = 0) : /-- Any zero object identifies to the kernel of a given monomorphisms. -/ def KernelFork.IsLimit.ofMonoOfIsZero {X Y : C} {f : X ⟶ Y} (c : KernelFork f) (hf : Mono f) (h : IsZero c.pt) : IsLimit c := - isLimitAux _ (fun s => 0) (fun s => by rw [zero_comp, ← cancel_mono f, zero_comp, s.condition]) + isLimitAux _ (fun _ => 0) (fun s => by rw [zero_comp, ← cancel_mono f, zero_comp, s.condition]) (fun _ _ _ => h.eq_of_tgt _ _) lemma KernelFork.IsLimit.isIso_ι {X Y : C} {f : X ⟶ Y} (c : KernelFork f) @@ -429,11 +429,11 @@ open ZeroObject /-- The morphism from the zero object determines a cone on a kernel diagram -/ def kernel.zeroKernelFork : KernelFork f where pt := 0 - π := { app := fun j => 0 } + π := { app := fun _ => 0 } /-- The map from the zero object is a kernel of a monomorphism -/ def kernel.isLimitConeZeroCone [Mono f] : IsLimit (kernel.zeroKernelFork f) := - Fork.IsLimit.mk _ (fun s => 0) + Fork.IsLimit.mk _ (fun _ => 0) (fun s => by rw [zero_comp] refine (zero_of_comp_mono f ?_).symm @@ -453,7 +453,7 @@ theorem kernel.ι_of_mono [HasKernel f] [Mono f] : kernel.ι f = 0 := def zeroKernelOfCancelZero {X Y : C} (f : X ⟶ Y) (hf : ∀ (Z : C) (g : Z ⟶ X) (_ : g ≫ f = 0), g = 0) : IsLimit (KernelFork.ofι (0 : 0 ⟶ X) (show 0 ≫ f = 0 by simp)) := - Fork.IsLimit.mk _ (fun s => 0) (fun s => by rw [hf _ _ (KernelFork.condition s), zero_comp]) + Fork.IsLimit.mk _ (fun _ => 0) (fun s => by rw [hf _ _ (KernelFork.condition s), zero_comp]) fun s m _ => by dsimp; apply HasZeroObject.to_zero_ext end HasZeroObject @@ -574,7 +574,7 @@ def CokernelCofork.IsColimit.ofπ {Z : C} (g : Y ⟶ Z) (eq : f ≫ g = 0) def CokernelCofork.IsColimit.ofπ' {X Y Q : C} {f : X ⟶ Y} (p : Y ⟶ Q) (w : f ≫ p = 0) (h : ∀ {A : C} (k : Y ⟶ A) (_ : f ≫ k = 0), { l : Q ⟶ A // p ≫ l = k}) [hp : Epi p] : IsColimit (CokernelCofork.ofπ p w) := - ofπ _ _ (fun {A} k hk => (h k hk).1) (fun {A} k hk => (h k hk).2) (fun {A} k hk m hm => by + ofπ _ _ (fun {_} k hk => (h k hk).1) (fun {_} k hk => (h k hk).2) (fun {A} k hk m hm => by rw [← cancel_epi p, (h k hk).2, hm]) /-- Every cokernel of `f` induces a cokernel of `g ≫ f` if `g` is epi. -/ @@ -620,7 +620,7 @@ def CokernelCofork.IsColimit.ofId {X Y : C} (f : X ⟶ Y) (hf : f = 0) : /-- Any zero object identifies to the cokernel of a given epimorphisms. -/ def CokernelCofork.IsColimit.ofEpiOfIsZero {X Y : C} {f : X ⟶ Y} (c : CokernelCofork f) (hf : Epi f) (h : IsZero c.pt) : IsColimit c := - isColimitAux _ (fun s => 0) (fun s => by rw [comp_zero, ← cancel_epi f, comp_zero, s.condition]) + isColimitAux _ (fun _ => 0) (fun s => by rw [comp_zero, ← cancel_epi f, comp_zero, s.condition]) (fun _ _ _ => h.eq_of_src _ _) lemma CokernelCofork.IsColimit.isIso_π {X Y : C} {f : X ⟶ Y} (c : CokernelCofork f) @@ -882,11 +882,11 @@ open ZeroObject /-- The morphism to the zero object determines a cocone on a cokernel diagram -/ def cokernel.zeroCokernelCofork : CokernelCofork f where pt := 0 - ι := { app := fun j => 0 } + ι := { app := fun _ => 0 } /-- The morphism to the zero object is a cokernel of an epimorphism -/ def cokernel.isColimitCoconeZeroCocone [Epi f] : IsColimit (cokernel.zeroCokernelCofork f) := - Cofork.IsColimit.mk _ (fun s => 0) + Cofork.IsColimit.mk _ (fun _ => 0) (fun s => by erw [zero_comp] refine (zero_of_epi_comp f ?_).symm @@ -978,7 +978,7 @@ instance cokernel.of_kernel_of_mono [HasKernel f] [HasCokernel (kernel.ι f)] [M def zeroCokernelOfZeroCancel {X Y : C} (f : X ⟶ Y) (hf : ∀ (Z : C) (g : Y ⟶ Z) (_ : f ≫ g = 0), g = 0) : IsColimit (CokernelCofork.ofπ (0 : Y ⟶ 0) (show f ≫ 0 = 0 by simp)) := - Cofork.IsColimit.mk _ (fun s => 0) + Cofork.IsColimit.mk _ (fun _ => 0) (fun s => by rw [hf _ _ (CokernelCofork.condition s), comp_zero]) fun s m _ => by apply HasZeroObject.from_zero_ext diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean b/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean index 3b1dc95db77ed0..54c25d54c53c4d 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean @@ -321,7 +321,7 @@ def ofι (I : MulticospanIndex.{w} C) (P : C) (ι : ∀ a, P ⟶ I.left a) π := { app := fun x => match x with - | WalkingMulticospan.left a => ι _ + | WalkingMulticospan.left _ => ι _ | WalkingMulticospan.right b => ι (I.fstTo b) ≫ I.fst b naturality := by rintro (_ | _) (_ | _) (_ | _ | _) <;> @@ -415,8 +415,8 @@ noncomputable def ofPiFork (c : Fork I.fstPiMap I.sndPiMap) : Multifork I where π := { app := fun x => match x with - | WalkingMulticospan.left a => c.ι ≫ Pi.π _ _ - | WalkingMulticospan.right b => c.ι ≫ I.fstPiMap ≫ Pi.π _ _ + | WalkingMulticospan.left _ => c.ι ≫ Pi.π _ _ + | WalkingMulticospan.right _ => c.ι ≫ I.fstPiMap ≫ Pi.π _ _ naturality := by rintro (_ | _) (_ | _) (_ | _ | _) · simp @@ -518,7 +518,7 @@ def ofπ (I : MultispanIndex.{w} C) (P : C) (π : ∀ b, I.right b ⟶ P) { app := fun x => match x with | WalkingMultispan.left a => I.fst a ≫ π _ - | WalkingMultispan.right b => π _ + | WalkingMultispan.right _ => π _ naturality := by rintro (_ | _) (_ | _) (_ | _ | _) <;> dsimp <;> simp only [Functor.map_id, MultispanIndex.multispan_obj_left, diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/CommSq.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/CommSq.lean index 978cc03484cb2c..44fa57f388d94a 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/CommSq.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/CommSq.lean @@ -584,7 +584,7 @@ open ZeroObject theorem zero_left (X : C) : IsPullback (0 : 0 ⟶ X) (0 : (0 : C) ⟶ 0) (𝟙 X) (0 : 0 ⟶ X) := { w := by simp isLimit' := - ⟨{ lift := fun s => 0 + ⟨{ lift := fun _ => 0 fac := fun s => by simpa [eq_iff_true_of_subsingleton] using @PullbackCone.equalizer_ext _ _ _ _ _ _ _ s _ 0 (𝟙 _) @@ -886,7 +886,7 @@ open ZeroObject theorem zero_right (X : C) : IsPushout (0 : X ⟶ 0) (𝟙 X) (0 : (0 : C) ⟶ 0) (0 : X ⟶ 0) := { w := by simp isColimit' := - ⟨{ desc := fun s => 0 + ⟨{ desc := fun _ => 0 fac := fun s => by have c := @PushoutCocone.coequalizer_ext _ _ _ _ _ _ _ s _ 0 (𝟙 _) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean index e71c318301bbd6..5b6bfbf8ab8b4c 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Mono.lean @@ -62,7 +62,7 @@ The pullback cone `(𝟙 X, 𝟙 X)` for the pair `(f, f)` is a limit if `f` is shown in `mono_of_pullback_is_id`. -/ def isLimitMkIdId (f : X ⟶ Y) [Mono f] : IsLimit (mk (𝟙 X) (𝟙 X) rfl : PullbackCone f f) := - IsLimit.mk _ (fun s => s.fst) (fun s => Category.comp_id _) + IsLimit.mk _ (fun s => s.fst) (fun _ => Category.comp_id _) (fun s => by rw [← cancel_mono f, Category.comp_id, s.condition]) fun s m m₁ _ => by simpa using m₁ @@ -246,7 +246,7 @@ The pushout cocone `(𝟙 X, 𝟙 X)` for the pair `(f, f)` is a colimit if `f` shown in `epi_of_isColimit_mk_id_id`. -/ def isColimitMkIdId (f : X ⟶ Y) [Epi f] : IsColimit (mk (𝟙 Y) (𝟙 Y) rfl : PushoutCocone f f) := - IsColimit.mk _ (fun s => s.inl) (fun s => Category.id_comp _) + IsColimit.mk _ (fun s => s.inl) (fun _ => Category.id_comp _) (fun s => by rw [← cancel_epi f, Category.id_comp, s.condition]) fun s m m₁ _ => by simpa using m₁ diff --git a/Mathlib/CategoryTheory/Limits/Shapes/StrongEpi.lean b/Mathlib/CategoryTheory/Limits/Shapes/StrongEpi.lean index ba11c501a2ea98..2abdbdfda2ec48 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/StrongEpi.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/StrongEpi.lean @@ -125,12 +125,12 @@ theorem strongMono_of_strongMono [StrongMono (f ≫ g)] : StrongMono f := /-- An isomorphism is in particular a strong epimorphism. -/ instance (priority := 100) strongEpi_of_isIso [IsIso f] : StrongEpi f where epi := by infer_instance - llp {X Y} z := HasLiftingProperty.of_left_iso _ _ + 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 {X Y} z := HasLiftingProperty.of_right_iso _ _ + rlp {_ _} _ := HasLiftingProperty.of_right_iso _ _ 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 := diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Terminal.lean b/Mathlib/CategoryTheory/Limits/Shapes/Terminal.lean index 37a4e622da924d..eb36394aaa77b8 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Terminal.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Terminal.lean @@ -332,11 +332,11 @@ abbrev initial.to [HasInitial C] (P : C) : ⊥_ C ⟶ P := /-- A terminal object is terminal. -/ def terminalIsTerminal [HasTerminal C] : IsTerminal (⊤_ C) where - lift s := terminal.from _ + lift _ := terminal.from _ /-- An initial object is initial. -/ def initialIsInitial [HasInitial C] : IsInitial (⊥_ C) where - desc s := initial.to _ + desc _ := initial.to _ instance uniqueToTerminal [HasTerminal C] (P : C) : Unique (P ⟶ ⊤_ C) := isTerminalEquivUnique _ (⊤_ C) terminalIsTerminal P @@ -378,22 +378,22 @@ instance initial.isSplitEpi_to {Y : C} [HasInitial C] (f : Y ⟶ ⊥_ C) : IsSpl /-- An initial object is terminal in the opposite category. -/ def terminalOpOfInitial {X : C} (t : IsInitial X) : IsTerminal (Opposite.op X) where lift s := (t.to s.pt.unop).op - uniq s m _ := Quiver.Hom.unop_inj (t.hom_ext _ _) + uniq _ _ _ := Quiver.Hom.unop_inj (t.hom_ext _ _) /-- An initial object in the opposite category is terminal in the original category. -/ def terminalUnopOfInitial {X : Cᵒᵖ} (t : IsInitial X) : IsTerminal X.unop where lift s := (t.to (Opposite.op s.pt)).unop - uniq s m _ := Quiver.Hom.op_inj (t.hom_ext _ _) + uniq _ _ _ := Quiver.Hom.op_inj (t.hom_ext _ _) /-- A terminal object is initial in the opposite category. -/ def initialOpOfTerminal {X : C} (t : IsTerminal X) : IsInitial (Opposite.op X) where desc s := (t.from s.pt.unop).op - uniq s m _ := Quiver.Hom.unop_inj (t.hom_ext _ _) + uniq _ _ _ := Quiver.Hom.unop_inj (t.hom_ext _ _) /-- A terminal object in the opposite category is initial in the original category. -/ def initialUnopOfTerminal {X : Cᵒᵖ} (t : IsTerminal X) : IsInitial X.unop where desc s := (t.from (Opposite.op s.pt)).unop - uniq s m _ := Quiver.Hom.op_inj (t.hom_ext _ _) + uniq _ _ _ := Quiver.Hom.op_inj (t.hom_ext _ _) instance hasInitial_op_of_hasTerminal [HasTerminal C] : HasInitial Cᵒᵖ := (initialOpOfTerminal terminalIsTerminal).hasInitial @@ -413,7 +413,7 @@ instance {J : Type*} [Category J] {C : Type*} [Category C] [HasTerminal C] : { cone := { pt := ⊤_ C π := { app := fun _ => terminal.from _ } } - isLimit := { lift := fun s => terminal.from _ } } + isLimit := { lift := fun _ => terminal.from _ } } /-- The limit of the constant `⊤_ C` functor is `⊤_ C`. -/ @[simps hom] @@ -423,7 +423,7 @@ def limitConstTerminal {J : Type*} [Category J] {C : Type*} [Category C] [HasTer inv := limit.lift ((CategoryTheory.Functor.const J).obj (⊤_ C)) { pt := ⊤_ C - π := { app := fun j => terminal.from _ } } + π := { app := fun _ => terminal.from _ } } @[reassoc (attr := simp)] theorem limitConstTerminal_inv_π {J : Type*} [Category J] {C : Type*} [Category C] [HasTerminal C] @@ -437,7 +437,7 @@ instance {J : Type*} [Category J] {C : Type*} [Category C] [HasInitial C] : { cocone := { pt := ⊥_ C ι := { app := fun _ => initial.to _ } } - isColimit := { desc := fun s => initial.to _ } } + isColimit := { desc := fun _ => initial.to _ } } /-- The colimit of the constant `⊥_ C` functor is `⊥_ C`. -/ @[simps inv] @@ -446,7 +446,7 @@ def colimitConstInitial {J : Type*} [Category J] {C : Type*} [Category C] [HasIn hom := colimit.desc ((CategoryTheory.Functor.const J).obj (⊥_ C)) { pt := ⊥_ C - ι := { app := fun j => initial.to _ } } + ι := { app := fun _ => initial.to _ } } inv := initial.to _ @[reassoc (attr := simp)] @@ -566,7 +566,7 @@ 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 π := - { app := fun i => inv (F.map (hX.from _)) + { app := fun _ => inv (F.map (hX.from _)) naturality := by intro i j f dsimp @@ -635,7 +635,7 @@ 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 ι := - { app := fun i => inv (F.map (hX.to _)) + { app := fun _ => inv (F.map (hX.to _)) naturality := by intro i j f dsimp diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Types.lean b/Mathlib/CategoryTheory/Limits/Shapes/Types.lean index 5f9021a6e2f50a..f0c5334a885590 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Types.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Types.lean @@ -216,7 +216,7 @@ theorem binaryProductIso_inv_comp_snd (X Y : Type u) : def binaryProductFunctor : Type u ⥤ Type u ⥤ Type u where obj X := { obj := fun Y => X × Y - map := fun { Y₁ Y₂} f => (binaryProductLimit X Y₂).lift + map := fun { _ Y₂} f => (binaryProductLimit X Y₂).lift (BinaryFan.mk _root_.Prod.fst (_root_.Prod.snd ≫ f)) } map {X₁ X₂} f := { app := fun Y => @@ -346,7 +346,7 @@ def productLimitCone {J : Type v} (F : J → TypeMax.{v, u}) : π := Discrete.natTrans (fun ⟨j⟩ f => f j) } isLimit := { lift := fun s x j => s.π.app ⟨j⟩ x - uniq := fun s m w => funext fun x => funext fun j => (congr_fun (w ⟨j⟩) x : _) } + uniq := fun _ _ w => funext fun x => funext fun j => (congr_fun (w ⟨j⟩) x : _) } /-- The categorical product in `TypeMax.{v, u}` is the type theoretic product `Π j, F j`. -/ noncomputable def productIso {J : Type v} (F : J → TypeMax.{v, u}) : ∏ᶜ F ≅ ∀ j, F j := @@ -524,8 +524,8 @@ def coequalizerColimit : Limits.ColimitCocone (parallelPair f g) where (fun a b (h : CoequalizerRel f g a b) => by cases h apply congr_fun s.condition)) - (fun s => rfl) - (fun s m hm => funext (fun x => Quot.inductionOn x (congr_fun hm))) + (fun _ => rfl) + (fun _ _ hm => funext (fun x => Quot.inductionOn x (congr_fun hm))) /-- If `π : Y ⟶ Z` is an equalizer for `(f, g)`, and `U ⊆ Y` such that `f ⁻¹' U = g ⁻¹' U`, then `π ⁻¹' (π '' U) = U`. @@ -613,7 +613,7 @@ def pullbackLimitCone (f : X ⟶ Z) (g : Y ⟶ Z) : Limits.LimitCone (cospan f g cone := pullbackCone f g isLimit := PullbackCone.isLimitAux _ (fun s x => ⟨⟨s.fst x, s.snd x⟩, congr_fun s.condition x⟩) - (by aesop) (by aesop) fun s m w => + (by aesop) (by aesop) fun _ _ w => funext fun x => Subtype.ext <| Prod.ext (congr_fun (w WalkingCospan.left) x) (congr_fun (w WalkingCospan.right) x) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/WideEqualizers.lean b/Mathlib/CategoryTheory/Limits/Shapes/WideEqualizers.lean index 6193cbb5c65874..e8a53e2075d207 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/WideEqualizers.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/WideEqualizers.lean @@ -329,8 +329,8 @@ def Trident.IsLimit.homIso [Nonempty J] {t : Trident f} (ht : IsLimit t) (Z : C) (Z ⟶ t.pt) ≃ { h : Z ⟶ X // ∀ j₁ j₂, h ≫ f j₁ = h ≫ f j₂ } where toFun k := ⟨k ≫ t.ι, by simp⟩ invFun h := (Trident.IsLimit.lift' ht _ h.prop).1 - left_inv k := Trident.IsLimit.hom_ext ht (Trident.IsLimit.lift' _ _ _).prop - right_inv h := Subtype.ext (Trident.IsLimit.lift' ht _ _).prop + left_inv _ := Trident.IsLimit.hom_ext ht (Trident.IsLimit.lift' _ _ _).prop + right_inv _ := Subtype.ext (Trident.IsLimit.lift' ht _ _).prop /-- The bijection of `Trident.IsLimit.homIso` is natural in `Z`. -/ theorem Trident.IsLimit.homIso_natural [Nonempty J] {t : Trident f} (ht : IsLimit t) {Z Z' : C} @@ -349,8 +349,8 @@ def Cotrident.IsColimit.homIso [Nonempty J] {t : Cotrident f} (ht : IsColimit t) (t.pt ⟶ Z) ≃ { h : Y ⟶ Z // ∀ j₁ j₂, f j₁ ≫ h = f j₂ ≫ h } where toFun k := ⟨t.π ≫ k, by simp⟩ invFun h := (Cotrident.IsColimit.desc' ht _ h.prop).1 - left_inv k := Cotrident.IsColimit.hom_ext ht (Cotrident.IsColimit.desc' _ _ _).prop - right_inv h := Subtype.ext (Cotrident.IsColimit.desc' ht _ _).prop + left_inv _ := Cotrident.IsColimit.hom_ext ht (Cotrident.IsColimit.desc' _ _ _).prop + right_inv _ := Subtype.ext (Cotrident.IsColimit.desc' ht _ _).prop /-- The bijection of `Cotrident.IsColimit.homIso` is natural in `Z`. -/ theorem Cotrident.IsColimit.homIso_natural [Nonempty J] {t : Cotrident f} {Z Z' : C} (q : Z ⟶ Z') diff --git a/Mathlib/CategoryTheory/Limits/Shapes/WidePullbacks.lean b/Mathlib/CategoryTheory/Limits/Shapes/WidePullbacks.lean index 9d41486241eb2d..8b87766c91f50e 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/WidePullbacks.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/WidePullbacks.lean @@ -461,22 +461,22 @@ def widePushoutShapeUnop : (WidePushoutShape J)ᵒᵖ ⥤ WidePullbackShape J := /-- The inverse of the unit isomorphism of the equivalence `widePushoutShapeOpEquiv : (WidePushoutShape J)ᵒᵖ ≌ WidePullbackShape J` -/ def widePushoutShapeOpUnop : widePushoutShapeUnop J ⋙ widePullbackShapeOp J ≅ 𝟭 _ := - NatIso.ofComponents fun X => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ /-- The counit isomorphism of the equivalence `widePullbackShapeOpEquiv : (WidePullbackShape J)ᵒᵖ ≌ WidePushoutShape J` -/ def widePushoutShapeUnopOp : widePushoutShapeOp J ⋙ widePullbackShapeUnop J ≅ 𝟭 _ := - NatIso.ofComponents fun X => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ /-- The inverse of the unit isomorphism of the equivalence `widePullbackShapeOpEquiv : (WidePullbackShape J)ᵒᵖ ≌ WidePushoutShape J` -/ def widePullbackShapeOpUnop : widePullbackShapeUnop J ⋙ widePushoutShapeOp J ≅ 𝟭 _ := - NatIso.ofComponents fun X => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ /-- The counit isomorphism of the equivalence `widePushoutShapeOpEquiv : (WidePushoutShape J)ᵒᵖ ≌ WidePullbackShape J` -/ def widePullbackShapeUnopOp : widePullbackShapeOp J ⋙ widePushoutShapeUnop J ≅ 𝟭 _ := - NatIso.ofComponents fun X => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ /-- The duality equivalence `(WidePushoutShape J)ᵒᵖ ≌ WidePullbackShape J` -/ @[simps] diff --git a/Mathlib/CategoryTheory/Limits/Shapes/ZeroMorphisms.lean b/Mathlib/CategoryTheory/Limits/Shapes/ZeroMorphisms.lean index 259375ddca69ad..baf5c502afa9e2 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/ZeroMorphisms.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/ZeroMorphisms.lean @@ -144,7 +144,7 @@ section variable [HasZeroMorphisms D] instance : HasZeroMorphisms (C ⥤ D) where - zero F G := ⟨{ app := fun X => 0 }⟩ + zero F G := ⟨{ app := fun _ => 0 }⟩ comp_zero := fun η H => by ext X; dsimp; apply comp_zero zero_comp := fun F {G H} η => by @@ -252,7 +252,7 @@ open ZeroObject code should generally ask for an instance of `HasZeroMorphisms` separately, even if it already asks for an instance of `HasZeroObjects`. -/ def zeroMorphismsOfZeroObject : HasZeroMorphisms C where - zero X Y := { zero := (default : X ⟶ 0) ≫ default } + zero X _ := { zero := (default : X ⟶ 0) ≫ default } zero_comp X {Y Z} f := by change ((default : X ⟶ 0) ≫ default) ≫ f = (default : X ⟶ 0) ≫ default rw [Category.assoc] @@ -378,14 +378,14 @@ theorem idZeroEquivIsoZero_apply_inv (X : C) (h : 𝟙 X = 0) : ((idZeroEquivIso /-- If `0 : X ⟶ Y` is a monomorphism, then `X ≅ 0`. -/ @[simps] -def isoZeroOfMonoZero {X Y : C} (h : Mono (0 : X ⟶ Y)) : X ≅ 0 where +def isoZeroOfMonoZero {X Y : C} (_ : Mono (0 : X ⟶ Y)) : X ≅ 0 where hom := 0 inv := 0 hom_inv_id := (cancel_mono (0 : X ⟶ Y)).mp (by simp) /-- If `0 : X ⟶ Y` is an epimorphism, then `Y ≅ 0`. -/ @[simps] -def isoZeroOfEpiZero {X Y : C} (h : Epi (0 : X ⟶ Y)) : Y ≅ 0 where +def isoZeroOfEpiZero {X Y : C} (_ : Epi (0 : X ⟶ Y)) : Y ≅ 0 where hom := 0 inv := 0 hom_inv_id := (cancel_epi (0 : X ⟶ Y)).mp (by simp) @@ -523,7 +523,7 @@ def monoFactorisationZero (X Y : C) : MonoFactorisation (0 : X ⟶ Y) where -/ def imageFactorisationZero (X Y : C) : ImageFactorisation (0 : X ⟶ Y) where F := monoFactorisationZero X Y - isImage := { lift := fun F' => 0 } + isImage := { lift := fun _ => 0 } instance hasImage_zero {X Y : C} : HasImage (0 : X ⟶ Y) := HasImage.mk <| imageFactorisationZero _ _ diff --git a/Mathlib/CategoryTheory/Limits/Yoneda.lean b/Mathlib/CategoryTheory/Limits/Yoneda.lean index 2442748a1c2e5c..ed9f8ff3d339e2 100644 --- a/Mathlib/CategoryTheory/Limits/Yoneda.lean +++ b/Mathlib/CategoryTheory/Limits/Yoneda.lean @@ -113,7 +113,7 @@ def yonedaJointlyReflectsLimits (F : J ⥤ Cᵒᵖ) (c : Cone F) application of `yoneda.obj X` for all `X : C`. -/ noncomputable def Limits.Cocone.isColimitYonedaEquiv {F : J ⥤ C} (c : Cocone F) : IsColimit c ≃ ∀ (X : C), IsLimit ((yoneda.obj X).mapCone c.op) where - toFun h X := isLimitOfPreserves _ h.op + toFun h _ := isLimitOfPreserves _ h.op invFun h := IsLimit.unop (yonedaJointlyReflectsLimits _ _ h) left_inv _ := Subsingleton.elim _ _ right_inv _ := by ext; apply Subsingleton.elim @@ -154,7 +154,7 @@ def coyonedaJointlyReflectsLimits (F : J ⥤ C) (c : Cone F) /-- A cone is limit iff it is so after the application of `coyoneda.obj X` for all `X : Cᵒᵖ`. -/ noncomputable def Limits.Cone.isLimitCoyonedaEquiv {F : J ⥤ C} (c : Cone F) : IsLimit c ≃ ∀ (X : Cᵒᵖ), IsLimit ((coyoneda.obj X).mapCone c) where - toFun h X := isLimitOfPreserves _ h + toFun h _ := isLimitOfPreserves _ h invFun h := coyonedaJointlyReflectsLimits _ _ h left_inv _ := Subsingleton.elim _ _ right_inv _ := by ext; apply Subsingleton.elim diff --git a/Mathlib/CategoryTheory/Localization/CalculusOfFractions.lean b/Mathlib/CategoryTheory/Localization/CalculusOfFractions.lean index 07d49115d1bb73..ab6a1a44daa7d8 100644 --- a/Mathlib/CategoryTheory/Localization/CalculusOfFractions.lean +++ b/Mathlib/CategoryTheory/Localization/CalculusOfFractions.lean @@ -433,7 +433,7 @@ namespace Localization noncomputable instance : Category (Localization W) where Hom X Y := Localization.Hom W X Y - id X := Localization.Hom.mk (ofHom W (𝟙 _)) + id _ := Localization.Hom.mk (ofHom W (𝟙 _)) comp f g := f.comp g comp_id := by rintro (X Y : C) f @@ -581,7 +581,7 @@ when `W` has a left calculus of fractions. -/ noncomputable def lift (F : C ⥤ E) (hF : W.IsInvertedBy F) : Localization W ⥤ E where obj X := F.obj X - map {X Y : C} f := f.map F hF + map {_ _ : C} f := f.map F hF map_id := by intro (X : C) dsimp @@ -605,7 +605,7 @@ noncomputable def lift (F : C ⥤ E) (hF : W.IsInvertedBy F) : rw [F.map_comp, F.map_comp, map_comp_map_s_assoc] lemma fac (F : C ⥤ E) (hF : W.IsInvertedBy F) : Q W ⋙ lift F hF = F := - Functor.ext (fun X => rfl) (fun X Y f => by + Functor.ext (fun _ => rfl) (fun X Y f => by dsimp [lift] rw [Q_map, Hom.map_mk, id_comp, comp_id, map_ofHom]) diff --git a/Mathlib/CategoryTheory/Localization/Composition.lean b/Mathlib/CategoryTheory/Localization/Composition.lean index e89a94183c8dd4..0c3a841aa980e2 100644 --- a/Mathlib/CategoryTheory/Localization/Composition.lean +++ b/Mathlib/CategoryTheory/Localization/Composition.lean @@ -42,7 +42,7 @@ def StrictUniversalPropertyFixedTarget.comp refine MorphismProperty.IsInvertedBy.of_le _ _ _ ?_ hW₂₃ simpa only [MorphismProperty.IsInvertedBy.map_iff, h₁.fac F] using hF) fac F hF := by rw [Functor.assoc, h₂.fac, h₁.fac] - uniq F₁ F₂ h := h₂.uniq _ _ (h₁.uniq _ _ (by simpa only [Functor.assoc] using h)) + uniq _ _ h := h₂.uniq _ _ (h₁.uniq _ _ (by simpa only [Functor.assoc] using h)) end Localization diff --git a/Mathlib/CategoryTheory/Localization/Construction.lean b/Mathlib/CategoryTheory/Localization/Construction.lean index 67313fe4674843..464e45092daf63 100644 --- a/Mathlib/CategoryTheory/Localization/Construction.lean +++ b/Mathlib/CategoryTheory/Localization/Construction.lean @@ -163,7 +163,7 @@ def lift : W.Localization ⥤ D := @[simp] theorem fac : W.Q ⋙ lift G hG = G := - Functor.ext (fun X => rfl) + Functor.ext (fun _ => rfl) (by intro X Y f simp only [Functor.comp_map, eqToHom_refl, comp_id, id_comp] @@ -197,7 +197,7 @@ localization with respect to a morphism_property `W` -/ def objEquiv : C ≃ W.Localization where toFun := W.Q.obj invFun X := X.as.obj - left_inv X := rfl + left_inv _ := rfl right_inv := by rintro ⟨⟨X⟩⟩ rfl diff --git a/Mathlib/CategoryTheory/Localization/Predicate.lean b/Mathlib/CategoryTheory/Localization/Predicate.lean index dd06454204670b..b56d44cf24b6c8 100644 --- a/Mathlib/CategoryTheory/Localization/Predicate.lean +++ b/Mathlib/CategoryTheory/Localization/Predicate.lean @@ -95,7 +95,7 @@ of the localization. -/ @[simps] def strictUniversalPropertyFixedTargetId (hW : W ≤ MorphismProperty.isomorphisms C) : StrictUniversalPropertyFixedTarget (𝟭 C) W E where - inverts X Y f hf := hW f hf + inverts _ _ f hf := hW f hf lift F _ := F fac F hF := by cases F diff --git a/Mathlib/CategoryTheory/Monad/Adjunction.lean b/Mathlib/CategoryTheory/Monad/Adjunction.lean index ebd45343a99da7..7c5e8d990bb5a0 100644 --- a/Mathlib/CategoryTheory/Monad/Adjunction.lean +++ b/Mathlib/CategoryTheory/Monad/Adjunction.lean @@ -76,12 +76,12 @@ def toComonad (h : L ⊣ R) : Comonad D where /-- 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 X => Iso.refl _) + MonadIso.mk (NatIso.ofComponents fun _ => Iso.refl _) /-- 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 X => Iso.refl _) + ComonadIso.mk (NatIso.ofComponents fun _ => Iso.refl _) /-- Given an adjunction `L ⊣ R`, if `L ⋙ R` is abstractly isomorphic to the identity functor, then the @@ -165,8 +165,8 @@ def Monad.comparison (h : L ⊣ R) : D ⥤ h.toMonad.Algebra where -/ @[simps] def Monad.comparisonForget (h : L ⊣ R) : Monad.comparison h ⋙ h.toMonad.forget ≅ R where - hom := { app := fun X => 𝟙 _ } - inv := { app := fun X => 𝟙 _ } + hom := { app := fun _ => 𝟙 _ } + inv := { app := fun _ => 𝟙 _ } theorem Monad.left_comparison (h : L ⊣ R) : L ⋙ Monad.comparison h = h.toMonad.free := rfl @@ -210,8 +210,8 @@ def Comonad.comparison (h : L ⊣ R) : C ⥤ h.toComonad.Coalgebra where @[simps] def Comonad.comparisonForget {L : C ⥤ D} {R : D ⥤ C} (h : L ⊣ R) : Comonad.comparison h ⋙ h.toComonad.forget ≅ L where - hom := { app := fun X => 𝟙 _ } - inv := { app := fun X => 𝟙 _ } + hom := { app := fun _ => 𝟙 _ } + inv := { app := fun _ => 𝟙 _ } theorem Comonad.left_comparison (h : L ⊣ R) : R ⋙ Comonad.comparison h = h.toComonad.cofree := rfl diff --git a/Mathlib/CategoryTheory/Monad/Kleisli.lean b/Mathlib/CategoryTheory/Monad/Kleisli.lean index 1bea86e9b33ada..e432473e5223b6 100644 --- a/Mathlib/CategoryTheory/Monad/Kleisli.lean +++ b/Mathlib/CategoryTheory/Monad/Kleisli.lean @@ -44,7 +44,7 @@ instance [Inhabited C] (T : Monad C) : Inhabited (Kleisli T) := instance category : Category (Kleisli T) where Hom := fun X Y : C => X ⟶ (T : C ⥤ C).obj Y id X := T.η.app X - comp {X} {Y} {Z} f g := f ≫ (T : C ⥤ C).map g ≫ T.μ.app Z + comp {_} {_} {Z} f g := f ≫ (T : C ⥤ C).map g ≫ T.μ.app Z id_comp {X} {Y} f := by dsimp -- Porting note: unfold comp rw [← T.η.naturality_assoc f, T.left_unit] @@ -70,7 +70,7 @@ def toKleisli : C ⥤ Kleisli T where def fromKleisli : Kleisli T ⥤ C where obj X := T.obj X map {_} {Y} f := T.map f ≫ T.μ.app Y - map_id X := T.right_unit _ + map_id _ := T.right_unit _ map_comp {X} {Y} {Z} f g := by -- Porting note: hack for missing unfold_projs tactic change T.map (f ≫ T.map g ≫ T.μ.app Z) ≫ T.μ.app Z = _ @@ -92,7 +92,7 @@ def adj : toKleisli T ⊣ fromKleisli T := /-- The composition of the adjunction gives the original functor. -/ def toKleisliCompFromKleisliIsoSelf : toKleisli T ⋙ fromKleisli T ≅ T := - NatIso.ofComponents fun X => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ end Adjunction @@ -116,7 +116,7 @@ instance [Inhabited C] (U : Comonad C) : Inhabited (Cokleisli U) := instance category : Category (Cokleisli U) where Hom := fun X Y : C => (U : C ⥤ C).obj X ⟶ Y id X := U.ε.app X - comp {X} {Y} {Z} f g := U.δ.app X ≫ (U : C ⥤ C).map f ≫ g + comp {X} {_} {_} f g := U.δ.app X ≫ (U : C ⥤ C).map f ≫ g id_comp f := by dsimp; rw [U.right_counit_assoc] assoc {X} {Y} {Z} {W} f g h := by -- Porting note: working around lack of unfold_projs @@ -143,7 +143,7 @@ def toCokleisli : C ⥤ Cokleisli U where def fromCokleisli : Cokleisli U ⥤ C where obj X := U.obj X map {X} {_} f := U.δ.app X ≫ U.map f - map_id X := U.right_counit _ + map_id _ := U.right_counit _ map_comp {X} {Y} {_} f g := by -- Porting note: working around lack of unfold_projs change U.δ.app X ≫ U.map (U.δ.app X ≫ U.map f ≫ g) = @@ -164,7 +164,7 @@ def adj : fromCokleisli U ⊣ toCokleisli U := /-- The composition of the adjunction gives the original functor. -/ def toCokleisliCompFromCokleisliIsoSelf : toCokleisli U ⋙ fromCokleisli U ≅ U := - NatIso.ofComponents fun X => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ end Adjunction diff --git a/Mathlib/CategoryTheory/Monad/Monadicity.lean b/Mathlib/CategoryTheory/Monad/Monadicity.lean index 5dbca1937d5e94..134144358f808c 100644 --- a/Mathlib/CategoryTheory/Monad/Monadicity.lean +++ b/Mathlib/CategoryTheory/Monad/Monadicity.lean @@ -79,6 +79,13 @@ def comparisonLeftAdjointObj (A : adj.toMonad.Algebra) [HasCoequalizer (F.map A.a) (adj.counit.app _)] : D := coequalizer (F.map A.a) (adj.counit.app _) +#adaptation_note +/-- +The new unused variable linter in +https://github.com/leanprover/lean4/pull/5338 +flags `{ f : F.obj A.A ⟶ B // _ }`. +-/ +set_option linter.unusedVariables false in /-- We have a bijection of homsets which will be used to construct the left adjoint to the comparison functor. diff --git a/Mathlib/CategoryTheory/Monad/Products.lean b/Mathlib/CategoryTheory/Monad/Products.lean index e7991fb4ef4d1b..2a42c1d2a6ff17 100644 --- a/Mathlib/CategoryTheory/Monad/Products.lean +++ b/Mathlib/CategoryTheory/Monad/Products.lean @@ -41,8 +41,8 @@ variable [HasBinaryProducts C] @[simps!] def prodComonad : Comonad C where toFunctor := prod.functor.obj X - ε := { app := fun Y => Limits.prod.snd } - δ := { app := fun Y => prod.lift Limits.prod.fst (𝟙 _) } + ε := { app := fun _ => Limits.prod.snd } + δ := { app := fun _ => prod.lift Limits.prod.fst (𝟙 _) } /-- The forward direction of the equivalence from coalgebras for the product comonad to the over category. @@ -88,8 +88,8 @@ variable [HasBinaryCoproducts C] @[simps!] def coprodMonad : Monad C where toFunctor := coprod.functor.obj X - η := { app := fun Y => coprod.inr } - μ := { app := fun Y => coprod.desc coprod.inl (𝟙 _) } + η := { app := fun _ => coprod.inr } + μ := { app := fun _ => coprod.desc coprod.inl (𝟙 _) } /-- The forward direction of the equivalence from algebras for the coproduct monad to the under category. diff --git a/Mathlib/CategoryTheory/Monad/Types.lean b/Mathlib/CategoryTheory/Monad/Types.lean index 2dc1cadcd2fa9b..cddd9633c3ae80 100644 --- a/Mathlib/CategoryTheory/Monad/Types.lean +++ b/Mathlib/CategoryTheory/Monad/Types.lean @@ -34,7 +34,7 @@ variable (m : Type u → Type u) [_root_.Monad m] [LawfulMonad m] @[simps!] def ofTypeMonad : Monad (Type u) where toFunctor := ofTypeFunctor m - η := ⟨@pure m _, fun α β f => funext fun x => (LawfulApplicative.map_pure f x).symm⟩ + η := ⟨@pure m _, fun _ _ f => funext fun x => (LawfulApplicative.map_pure f x).symm⟩ μ := ⟨@joinM m _, fun α β (f : α → β) => funext fun a => by apply joinM_map_map⟩ assoc α := funext fun a => by apply joinM_map_joinM left_unit α := funext fun a => by apply joinM_pure @@ -48,7 +48,7 @@ def eq : KleisliCat m ≌ Kleisli (ofTypeMonad m) where functor := { obj := fun X => X map := fun f => f - map_id := fun X => rfl + map_id := fun _ => rfl map_comp := fun f g => by --unfold_projs funext t @@ -59,7 +59,7 @@ def eq : KleisliCat m ≌ Kleisli (ofTypeMonad m) where inverse := { obj := fun X => X map := fun f => f - map_id := fun X => rfl + map_id := fun _ => rfl map_comp := fun f g => by --unfold_projs -- Porting note: Need these instances for some lemmas below. diff --git a/Mathlib/CategoryTheory/Monoidal/Cartesian/Comon_.lean b/Mathlib/CategoryTheory/Monoidal/Cartesian/Comon_.lean index 371f989126f86e..0f5506988110de 100644 --- a/Mathlib/CategoryTheory/Monoidal/Cartesian/Comon_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Cartesian/Comon_.lean @@ -61,4 +61,4 @@ to the category itself, via the forgetful functor. functor := Comon_.forget C inverse := cartesianComon_ C unitIso := NatIso.ofComponents (fun A => iso_cartesianComon_ A) - counitIso := NatIso.ofComponents (fun X => Iso.refl _) + counitIso := NatIso.ofComponents (fun _ => Iso.refl _) diff --git a/Mathlib/CategoryTheory/Monoidal/Comon_.lean b/Mathlib/CategoryTheory/Monoidal/Comon_.lean index 61c63c58ac9024..498a20b561c799 100644 --- a/Mathlib/CategoryTheory/Monoidal/Comon_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Comon_.lean @@ -282,7 +282,7 @@ theorem tensorObj_comul (A B : Comon_ C) : def forgetMonoidal : MonoidalFunctor (Comon_ C) C := { forget C with ε := 𝟙 _ - μ := fun X Y => 𝟙 _ } + μ := fun _ _ => 𝟙 _ } @[simp] theorem forgetMonoidal_toFunctor : (forgetMonoidal C).toFunctor = forget C := rfl @[simp] theorem forgetMonoidal_ε : (forgetMonoidal C).ε = 𝟙 (𝟙_ C) := rfl diff --git a/Mathlib/CategoryTheory/Monoidal/Discrete.lean b/Mathlib/CategoryTheory/Monoidal/Discrete.lean index 9ff8e09d5151e1..5cd7283da6587f 100644 --- a/Mathlib/CategoryTheory/Monoidal/Discrete.lean +++ b/Mathlib/CategoryTheory/Monoidal/Discrete.lean @@ -32,7 +32,7 @@ instance Discrete.monoidal : MonoidalCategory (Discrete M) where tensorHom f g := eqToHom (by dsimp; rw [eq_of_hom f, eq_of_hom g]) leftUnitor X := Discrete.eqToIso (one_mul X.as) rightUnitor X := Discrete.eqToIso (mul_one X.as) - associator X Y Z := Discrete.eqToIso (mul_assoc _ _ _) + associator _ _ _ := Discrete.eqToIso (mul_assoc _ _ _) @[to_additive (attr := simp) Discrete.addMonoidal_tensorUnit_as] lemma Discrete.monoidal_tensorUnit_as : (𝟙_ (Discrete M)).as = 1 := rfl @@ -62,7 +62,7 @@ variable {K : Type u} [Monoid K] def Discrete.monoidalFunctorComp (F : M →* N) (G : N →* K) : Discrete.monoidalFunctor F ⊗⋙ Discrete.monoidalFunctor G ≅ Discrete.monoidalFunctor (G.comp F) where - hom := { app := fun X => 𝟙 _ } - inv := { app := fun X => 𝟙 _ } + hom := { app := fun _ => 𝟙 _ } + inv := { app := fun _ => 𝟙 _ } end CategoryTheory diff --git a/Mathlib/CategoryTheory/Monoidal/Free/Basic.lean b/Mathlib/CategoryTheory/Monoidal/Free/Basic.lean index dede6e2f542958..0b89555d628e93 100644 --- a/Mathlib/CategoryTheory/Monoidal/Free/Basic.lean +++ b/Mathlib/CategoryTheory/Monoidal/Free/Basic.lean @@ -158,7 +158,7 @@ instance : MonoidalCategory (F C) where tensorHom_def := by rintro W X Y Z ⟨f⟩ ⟨g⟩ exact Quotient.sound (tensorHom_def _ _) - tensor_id X Y := Quot.sound tensor_id + tensor_id _ _ := Quot.sound tensor_id tensor_comp := @fun X₁ Y₁ Z₁ X₂ Y₂ Z₂ => by rintro ⟨f₁⟩ ⟨f₂⟩ ⟨g₁⟩ ⟨g₂⟩ exact Quotient.sound (tensor_comp _ _ _ _) @@ -179,8 +179,8 @@ instance : MonoidalCategory (F C) where rightUnitor_naturality := @fun X Y => by rintro ⟨f⟩ exact Quotient.sound (ρ_naturality _) - pentagon W X Y Z := Quotient.sound pentagon - triangle X Y := Quotient.sound triangle + pentagon _ _ _ _ := Quotient.sound pentagon + triangle _ _ := Quotient.sound triangle @[simp] theorem mk_comp {X Y Z : F C} (f : X ⟶ᵐ Y) (g : Y ⟶ᵐ Z) : @@ -366,7 +366,7 @@ def project : MonoidalFunctor (F C) D where -- In any case I don't understand why we need to specify `using Quotient.recOn`. map_comp := by rintro _ _ _ ⟨_⟩ ⟨_⟩; rfl ε := 𝟙 _ - μ X Y := 𝟙 _ + μ _ _ := 𝟙 _ μ_natural_left := fun f _ => by induction' f using Quotient.recOn · dsimp diff --git a/Mathlib/CategoryTheory/Monoidal/Free/Coherence.lean b/Mathlib/CategoryTheory/Monoidal/Free/Coherence.lean index 267ea5f8e51c9f..2a14ad4a827e98 100644 --- a/Mathlib/CategoryTheory/Monoidal/Free/Coherence.lean +++ b/Mathlib/CategoryTheory/Monoidal/Free/Coherence.lean @@ -161,7 +161,7 @@ def fullNormalize : F C ⥤ N C where @[simp] def tensorFunc : F C ⥤ N C ⥤ F C where obj X := Discrete.functor fun n => inclusion.obj ⟨n⟩ ⊗ X - map f := Discrete.natTrans (fun n => _ ◁ f) + map f := Discrete.natTrans (fun _ => _ ◁ f) theorem tensorFunc_map_app {X Y : F C} (f : X ⟶ Y) (n) : ((tensorFunc C).map f).app n = _ ◁ f := rfl @@ -197,7 +197,7 @@ def normalizeIsoApp' : theorem normalizeIsoApp_eq : ∀ (X : F C) (n : N C), normalizeIsoApp C X n = normalizeIsoApp' C X n.as - | of X, _ => rfl + | of _, _ => rfl | unit, _ => rfl | tensor X Y, n => by rw [normalizeIsoApp, normalizeIsoApp'] diff --git a/Mathlib/CategoryTheory/Monoidal/Functor.lean b/Mathlib/CategoryTheory/Monoidal/Functor.lean index 1581d1d32ba355..11f402b27a233d 100644 --- a/Mathlib/CategoryTheory/Monoidal/Functor.lean +++ b/Mathlib/CategoryTheory/Monoidal/Functor.lean @@ -343,7 +343,7 @@ variable (C : Type u₁) [Category.{v₁} C] [MonoidalCategory.{v₁} C] def id : LaxMonoidalFunctor.{v₁, v₁} C C := { 𝟭 C with ε := 𝟙 _ - μ := fun X Y => 𝟙 _ } + μ := fun _ _ => 𝟙 _ } instance : Inhabited (LaxMonoidalFunctor C C) := ⟨id C⟩ @@ -359,7 +359,7 @@ variable (C : Type u₁) [Category.{v₁} C] [MonoidalCategory.{v₁} C] def id : OplaxMonoidalFunctor.{v₁, v₁} C C := { 𝟭 C with η := 𝟙 _ - δ := fun X Y => 𝟙 _ } + δ := fun _ _ => 𝟙 _ } instance : Inhabited (OplaxMonoidalFunctor C C) := ⟨id C⟩ @@ -478,7 +478,7 @@ variable (C : Type u₁) [Category.{v₁} C] [MonoidalCategory.{v₁} C] def id : MonoidalFunctor.{v₁, v₁} C C := { 𝟭 C with ε := 𝟙 _ - μ := fun X Y => 𝟙 _ } + μ := fun _ _ => 𝟙 _ } instance : Inhabited (MonoidalFunctor C C) := ⟨id C⟩ @@ -579,7 +579,7 @@ variable (C) def diag : MonoidalFunctor C (C × C) := { Functor.diag C with ε := 𝟙 _ - μ := fun X Y => 𝟙 _ } + μ := fun _ _ => 𝟙 _ } end MonoidalFunctor diff --git a/Mathlib/CategoryTheory/Monoidal/FunctorCategory.lean b/Mathlib/CategoryTheory/Monoidal/FunctorCategory.lean index 5a69edb48708be..e06040b2769afa 100644 --- a/Mathlib/CategoryTheory/Monoidal/FunctorCategory.lean +++ b/Mathlib/CategoryTheory/Monoidal/FunctorCategory.lean @@ -165,7 +165,7 @@ the natural pointwise monoidal structure on the functor category `C ⥤ D` is also braided. -/ instance functorCategoryBraided : BraidedCategory (C ⥤ D) where - braiding F G := NatIso.ofComponents fun X => β_ _ _ + braiding F G := NatIso.ofComponents fun _ => β_ _ _ hexagon_forward F G H := by ext X; apply hexagon_forward hexagon_reverse F G H := by ext X; apply hexagon_reverse diff --git a/Mathlib/CategoryTheory/Monoidal/Functorial.lean b/Mathlib/CategoryTheory/Monoidal/Functorial.lean index 5f9d7be6fbb249..652d56766ced52 100644 --- a/Mathlib/CategoryTheory/Monoidal/Functorial.lean +++ b/Mathlib/CategoryTheory/Monoidal/Functorial.lean @@ -132,7 +132,7 @@ section instance laxMonoidalId : LaxMonoidal.{v₁, v₁} (id : C → C) where ε := 𝟙 _ - μ X Y := 𝟙 _ + μ _ _ := 𝟙 _ end diff --git a/Mathlib/CategoryTheory/Monoidal/Internal/FunctorCategory.lean b/Mathlib/CategoryTheory/Monoidal/Internal/FunctorCategory.lean index 6d90406b86532e..6678552572fca0 100644 --- a/Mathlib/CategoryTheory/Monoidal/Internal/FunctorCategory.lean +++ b/Mathlib/CategoryTheory/Monoidal/Internal/FunctorCategory.lean @@ -86,7 +86,7 @@ def inverse : (C ⥤ Mon_ D) ⥤ Mon_ (C ⥤ D) where map α := { hom := { app := fun X => (α.app X).hom - naturality := fun X Y f => congr_arg Mon_.Hom.hom (α.naturality f) } } + naturality := fun _ _ f => congr_arg Mon_.Hom.hom (α.naturality f) } } /-- The unit for the equivalence `Mon_ (C ⥤ D) ≌ C ⥤ Mon_ D`. -/ @@ -170,7 +170,7 @@ private def inverse : (C ⥤ Comon_ D) ⥤ Comon_ (C ⥤ D) where map α := { hom := { app := fun X => (α.app X).hom - naturality := fun X Y f => congr_arg Comon_.Hom.hom (α.naturality f) } + naturality := fun _ _ f => congr_arg Comon_.Hom.hom (α.naturality f) } hom_counit := by ext x; dsimp; rw [(α.app x).hom_counit] hom_comul := by ext x; dsimp; rw [(α.app x).hom_comul] } diff --git a/Mathlib/CategoryTheory/Monoidal/Internal/Module.lean b/Mathlib/CategoryTheory/Monoidal/Internal/Module.lean index 2e6df6e377f897..4bdf23e5898f46 100644 --- a/Mathlib/CategoryTheory/Monoidal/Internal/Module.lean +++ b/Mathlib/CategoryTheory/Monoidal/Internal/Module.lean @@ -88,7 +88,7 @@ theorem algebraMap (A : Mon_ (ModuleCat.{u} R)) (r : R) : algebraMap R A.X r = A @[simps!] def functor : Mon_ (ModuleCat.{u} R) ⥤ AlgebraCat R where obj A := AlgebraCat.of R A.X - map {A B} f := + map {_ _} f := { f.hom.toAddMonoidHom with toFun := f.hom map_one' := LinearMap.congr_fun f.one_hom (1 : R) @@ -173,8 +173,8 @@ def monModuleEquivalenceAlgebra : Mon_ (ModuleCat.{u} R) ≌ AlgebraCat R where { hom := { hom := { toFun := _root_.id - map_add' := fun x y => rfl - map_smul' := fun r a => rfl } + map_add' := fun _ _ => rfl + map_smul' := fun _ _ => rfl } mul_hom := by -- Porting note: `ext` did not pick up `TensorProduct.ext` refine TensorProduct.ext ?_ @@ -183,8 +183,8 @@ def monModuleEquivalenceAlgebra : Mon_ (ModuleCat.{u} R) ≌ AlgebraCat R where inv := { hom := { toFun := _root_.id - map_add' := fun x y => rfl - map_smul' := fun r a => rfl } + map_add' := fun _ _ => rfl + map_smul' := fun _ _ => rfl } mul_hom := by -- Porting note: `ext` did not pick up `TensorProduct.ext` refine TensorProduct.ext ?_ @@ -196,17 +196,17 @@ def monModuleEquivalenceAlgebra : Mon_ (ModuleCat.{u} R) ≌ AlgebraCat R where { hom := { toFun := _root_.id map_zero' := rfl - map_add' := fun x y => rfl + map_add' := fun _ _ => rfl map_one' := (algebraMap R A).map_one map_mul' := fun x y => @LinearMap.mul'_apply R _ _ _ _ _ _ x y - commutes' := fun r => rfl } + commutes' := fun _ => rfl } inv := { toFun := _root_.id map_zero' := rfl - map_add' := fun x y => rfl + map_add' := fun _ _ => rfl map_one' := (algebraMap R A).map_one.symm map_mul' := fun x y => (@LinearMap.mul'_apply R _ _ _ _ _ _ x y).symm - commutes' := fun r => rfl } }) + commutes' := fun _ => rfl } }) -- These lemmas have always been bad (#7657), but leanprover/lean4#2644 made `simp` start noticing attribute [nolint simpNF] ModuleCat.MonModuleEquivalenceAlgebra.functor_map_apply @@ -221,11 +221,11 @@ def monModuleEquivalenceAlgebraForget : (fun A => { hom := { toFun := _root_.id - map_add' := fun x y => rfl - map_smul' := fun c x => rfl } + map_add' := fun _ _ => rfl + map_smul' := fun _ _ => rfl } inv := { toFun := _root_.id - map_add' := fun x y => rfl - map_smul' := fun c x => rfl } }) + map_add' := fun _ _ => rfl + map_smul' := fun _ _ => rfl } }) end ModuleCat diff --git a/Mathlib/CategoryTheory/Monoidal/Internal/Types.lean b/Mathlib/CategoryTheory/Monoidal/Internal/Types.lean index 00d58af2f33d21..35b5ae5310477a 100644 --- a/Mathlib/CategoryTheory/Monoidal/Internal/Types.lean +++ b/Mathlib/CategoryTheory/Monoidal/Internal/Types.lean @@ -73,11 +73,11 @@ noncomputable def monTypeEquivalenceMon : Mon_ (Type u) ≌ MonCat.{u} where { hom := { toFun := id map_one' := rfl - map_mul' := fun x y => rfl } + map_mul' := fun _ _ => rfl } inv := { toFun := id map_one' := rfl - map_mul' := fun x y => rfl } }) + map_mul' := fun _ _ => rfl } }) (by aesop_cat) /-- The equivalence `Mon_ (Type u) ≌ MonCat.{u}` @@ -85,7 +85,7 @@ is naturally compatible with the forgetful functors to `Type u`. -/ noncomputable def monTypeEquivalenceMonForget : MonTypeEquivalenceMon.functor ⋙ forget MonCat ≅ Mon_.forget (Type u) := - NatIso.ofComponents (fun A => Iso.refl _) (by aesop_cat) + NatIso.ofComponents (fun _ => Iso.refl _) (by aesop_cat) noncomputable instance monTypeInhabited : Inhabited (Mon_ (Type u)) := ⟨MonTypeEquivalenceMon.inverse.obj (MonCat.of PUnit)⟩ @@ -134,11 +134,11 @@ noncomputable def commMonTypeEquivalenceCommMon : CommMon_ (Type u) ≌ CommMonC { hom := { toFun := id map_one' := rfl - map_mul' := fun x y => rfl } + map_mul' := fun _ _ => rfl } inv := { toFun := id map_one' := rfl - map_mul' := fun x y => rfl } }) + map_mul' := fun _ _ => rfl } }) (by aesop_cat) /-- The equivalences `Mon_ (Type u) ≌ MonCat.{u}` and `CommMon_ (Type u) ≌ CommMonCat.{u}` @@ -147,7 +147,7 @@ are naturally compatible with the forgetful functors to `MonCat` and `Mon_ (Type noncomputable def commMonTypeEquivalenceCommMonForget : CommMonTypeEquivalenceCommMon.functor ⋙ forget₂ CommMonCat MonCat ≅ CommMon_.forget₂Mon_ (Type u) ⋙ MonTypeEquivalenceMon.functor := - NatIso.ofComponents (fun A => Iso.refl _) (by aesop_cat) + NatIso.ofComponents (fun _ => Iso.refl _) (by aesop_cat) noncomputable instance commMonTypeInhabited : Inhabited (CommMon_ (Type u)) := ⟨CommMonTypeEquivalenceCommMon.inverse.obj (CommMonCat.of PUnit)⟩ diff --git a/Mathlib/CategoryTheory/Monoidal/Limits.lean b/Mathlib/CategoryTheory/Monoidal/Limits.lean index e13b3fa646109f..aaf3b03b9b3539 100644 --- a/Mathlib/CategoryTheory/Monoidal/Limits.lean +++ b/Mathlib/CategoryTheory/Monoidal/Limits.lean @@ -49,7 +49,7 @@ instance limitLaxMonoidal : LaxMonoidal fun F : J ⥤ C => limit F := .ofTensorH (ε := limit.lift _ { pt := _ - π := { app := fun j => 𝟙 _ } }) + π := { app := fun _ => 𝟙 _ } }) (μ := fun F G => limit.lift (F ⊗ G) { pt := limit F ⊗ limit G @@ -122,7 +122,7 @@ theorem limLax_ε : (@limLax J _ C _ _ _).ε = limit.lift _ { pt := _ - π := { app := fun j => 𝟙 _ } } := + π := { app := fun _ => 𝟙 _ } } := rfl @[simp] diff --git a/Mathlib/CategoryTheory/Monoidal/Mon_.lean b/Mathlib/CategoryTheory/Monoidal/Mon_.lean index 2202d88535f6ae..be13f54b4dd13c 100644 --- a/Mathlib/CategoryTheory/Monoidal/Mon_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Mon_.lean @@ -503,7 +503,7 @@ variable (C) def forgetMonoidal : MonoidalFunctor (Mon_ C) C := { forget C with ε := 𝟙 _ - μ := fun X Y => 𝟙 _ } + μ := fun _ _ => 𝟙 _ } @[simp] theorem forgetMonoidal_toFunctor : (forgetMonoidal C).toFunctor = forget C := rfl @[simp] theorem forgetMonoidal_ε : (forgetMonoidal C).ε = 𝟙 (𝟙_ C) := rfl diff --git a/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean b/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean index 813049284961d3..09ea239996ebd3 100644 --- a/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean +++ b/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean @@ -46,8 +46,8 @@ section def monoidalOfHasFiniteProducts [HasTerminal C] [HasBinaryProducts C] : MonoidalCategory C := letI : MonoidalCategoryStruct C := { tensorObj := fun X Y ↦ X ⨯ Y - whiskerLeft := fun X _ _ g ↦ Limits.prod.map (𝟙 _) g - whiskerRight := fun {_ _} f Y ↦ Limits.prod.map f (𝟙 _) + whiskerLeft := fun _ _ _ g ↦ Limits.prod.map (𝟙 _) g + whiskerRight := fun {_ _} f _ ↦ Limits.prod.map f (𝟙 _) tensorHom := fun f g ↦ Limits.prod.map f g tensorUnit := ⊤_ C associator := prod.associator @@ -168,8 +168,8 @@ section def monoidalOfHasFiniteCoproducts [HasInitial C] [HasBinaryCoproducts C] : MonoidalCategory C := letI : MonoidalCategoryStruct C := { tensorObj := fun X Y ↦ X ⨿ Y - whiskerLeft := fun X _ _ g ↦ Limits.coprod.map (𝟙 _) g - whiskerRight := fun {_ _} f Y ↦ Limits.coprod.map f (𝟙 _) + whiskerLeft := fun _ _ _ g ↦ Limits.coprod.map (𝟙 _) g + whiskerRight := fun {_ _} f _ ↦ Limits.coprod.map f (𝟙 _) tensorHom := fun f g ↦ Limits.coprod.map f g tensorUnit := ⊥_ C associator := coprod.associator diff --git a/Mathlib/CategoryTheory/Monoidal/Opposite.lean b/Mathlib/CategoryTheory/Monoidal/Opposite.lean index 3866aa1f3735a0..e1d90560271b13 100644 --- a/Mathlib/CategoryTheory/Monoidal/Opposite.lean +++ b/Mathlib/CategoryTheory/Monoidal/Opposite.lean @@ -152,7 +152,7 @@ instance monoidalCategoryOp : MonoidalCategory Cᵒᵖ where whiskerLeft X _ _ f := (X.unop ◁ f.unop).op whiskerRight f X := (f.unop ▷ X.unop).op tensorHom f g := (f.unop ⊗ g.unop).op - tensorHom_def f g := Quiver.Hom.unop_inj (tensorHom_def' _ _) + tensorHom_def _ _ := Quiver.Hom.unop_inj (tensorHom_def' _ _) tensorUnit := op (𝟙_ C) associator X Y Z := (α_ (unop X) (unop Y) (unop Z)).symm.op leftUnitor X := (λ_ (unop X)).symm.op @@ -231,7 +231,7 @@ instance monoidalCategoryMop : MonoidalCategory Cᴹᵒᵖ where whiskerLeft X _ _ f := (f.unmop ▷ X.unmop).mop whiskerRight f X := (X.unmop ◁ f.unmop).mop tensorHom f g := (g.unmop ⊗ f.unmop).mop - tensorHom_def f g := Quiver.Hom.unmop_inj (tensorHom_def' _ _) + tensorHom_def _ _ := Quiver.Hom.unmop_inj (tensorHom_def' _ _) tensorUnit := mop (𝟙_ C) associator X Y Z := (α_ (unmop Z) (unmop Y) (unmop X)).symm.mop leftUnitor X := (ρ_ (unmop X)).mop diff --git a/Mathlib/CategoryTheory/Monoidal/Preadditive.lean b/Mathlib/CategoryTheory/Monoidal/Preadditive.lean index 7133ba4faabc07..96881368dc909e 100644 --- a/Mathlib/CategoryTheory/Monoidal/Preadditive.lean +++ b/Mathlib/CategoryTheory/Monoidal/Preadditive.lean @@ -178,7 +178,7 @@ theorem biproduct_ι_comp_leftDistributor_inv {J : Type} [Fintype J] (X : C) (f theorem leftDistributor_assoc {J : Type} [Fintype J] (X Y : C) (f : J → C) : (asIso (𝟙 X) ⊗ leftDistributor Y f) ≪≫ leftDistributor X _ = - (α_ X Y (⨁ f)).symm ≪≫ leftDistributor (X ⊗ Y) f ≪≫ biproduct.mapIso fun j => α_ X Y _ := by + (α_ X Y (⨁ f)).symm ≪≫ leftDistributor (X ⊗ Y) f ≪≫ biproduct.mapIso fun _ => α_ X Y _ := by ext simp only [Category.comp_id, Category.assoc, eqToHom_refl, Iso.trans_hom, Iso.symm_hom, asIso_hom, comp_zero, comp_dite, Preadditive.sum_comp, Preadditive.comp_sum, tensor_sum, @@ -234,7 +234,7 @@ theorem biproduct_ι_comp_rightDistributor_inv {J : Type} [Fintype J] (f : J → theorem rightDistributor_assoc {J : Type} [Fintype J] (f : J → C) (X Y : C) : (rightDistributor f X ⊗ asIso (𝟙 Y)) ≪≫ rightDistributor _ Y = - α_ (⨁ f) X Y ≪≫ rightDistributor f (X ⊗ Y) ≪≫ biproduct.mapIso fun j => (α_ _ X Y).symm := by + α_ (⨁ f) X Y ≪≫ rightDistributor f (X ⊗ Y) ≪≫ biproduct.mapIso fun _ => (α_ _ X Y).symm := by ext simp only [Category.comp_id, Category.assoc, eqToHom_refl, Iso.symm_hom, Iso.trans_hom, asIso_hom, comp_zero, comp_dite, Preadditive.sum_comp, Preadditive.comp_sum, sum_tensor, @@ -250,7 +250,7 @@ theorem leftDistributor_rightDistributor_assoc {J : Type _} [Fintype J] (leftDistributor X f ⊗ asIso (𝟙 Y)) ≪≫ rightDistributor _ Y = α_ X (⨁ f) Y ≪≫ (asIso (𝟙 X) ⊗ rightDistributor _ Y) ≪≫ - leftDistributor X _ ≪≫ biproduct.mapIso fun j => (α_ _ _ _).symm := by + leftDistributor X _ ≪≫ biproduct.mapIso fun _ => (α_ _ _ _).symm := by ext simp only [Category.comp_id, Category.assoc, eqToHom_refl, Iso.symm_hom, Iso.trans_hom, asIso_hom, comp_zero, comp_dite, Preadditive.sum_comp, Preadditive.comp_sum, sum_tensor, diff --git a/Mathlib/CategoryTheory/Monoidal/Rigid/FunctorCategory.lean b/Mathlib/CategoryTheory/Monoidal/Rigid/FunctorCategory.lean index f520a501aff977..99fcf06d2a3dae 100644 --- a/Mathlib/CategoryTheory/Monoidal/Rigid/FunctorCategory.lean +++ b/Mathlib/CategoryTheory/Monoidal/Rigid/FunctorCategory.lean @@ -30,7 +30,7 @@ instance functorHasRightDual [RightRigidCategory D] (F : C ⥤ D) : HasRightDual map_comp := fun f g => by simp [comp_rightAdjointMate] } exact := { evaluation' := - { app := fun X => ε_ _ _ + { app := fun _ => ε_ _ _ naturality := fun X Y f => by dsimp rw [Category.comp_id, Functor.map_inv, ← id_tensor_comp_tensor_id, Category.assoc, @@ -38,7 +38,7 @@ instance functorHasRightDual [RightRigidCategory D] (F : C ⥤ D) : HasRightDual rightAdjointMate_comp_evaluation, ← MonoidalCategory.whiskerLeft_comp_assoc, IsIso.hom_inv_id, MonoidalCategory.whiskerLeft_id, Category.id_comp] } coevaluation' := - { app := fun X => η_ _ _ + { app := fun _ => η_ _ _ naturality := fun X Y f => by dsimp rw [Functor.map_inv, Category.id_comp, ← id_tensor_comp_tensor_id, @@ -55,12 +55,12 @@ instance functorHasLeftDual [LeftRigidCategory D] (F : C ⥤ D) : HasLeftDual F map_comp := fun f g => by simp [comp_leftAdjointMate] } exact := { evaluation' := - { app := fun X => ε_ _ _ + { app := fun _ => ε_ _ _ naturality := fun X Y f => by dsimp simp [tensorHom_def, leftAdjointMate_comp_evaluation] } coevaluation' := - { app := fun X => η_ _ _ + { app := fun _ => η_ _ _ naturality := fun X Y f => by dsimp simp [tensorHom_def, coevaluation_comp_leftAdjointMate_assoc] } } diff --git a/Mathlib/CategoryTheory/Monoidal/Subcategory.lean b/Mathlib/CategoryTheory/Monoidal/Subcategory.lean index 5e77ff34ecfb7b..c9d7bd3fe93127 100644 --- a/Mathlib/CategoryTheory/Monoidal/Subcategory.lean +++ b/Mathlib/CategoryTheory/Monoidal/Subcategory.lean @@ -64,7 +64,7 @@ When `P` is a monoidal predicate, the full subcategory for `P` inherits the mono -/ instance fullMonoidalSubcategory : MonoidalCategory (FullSubcategory P) := Monoidal.induced (fullSubcategoryInclusion P) - { μIso := fun X Y => eqToIso rfl + { μIso := fun _ _ => eqToIso rfl εIso := eqToIso rfl } /-- The forgetful monoidal functor from a full monoidal subcategory into the original category @@ -74,7 +74,7 @@ instance fullMonoidalSubcategory : MonoidalCategory (FullSubcategory P) := def fullMonoidalSubcategoryInclusion : MonoidalFunctor (FullSubcategory P) C where toFunctor := fullSubcategoryInclusion P ε := 𝟙 _ - μ X Y := 𝟙 _ + μ _ _ := 𝟙 _ instance fullMonoidalSubcategory.full : (fullMonoidalSubcategoryInclusion P).Full := FullSubcategory.full P @@ -116,7 +116,7 @@ def fullMonoidalSubcategory.map (h : ∀ ⦃X⦄, P X → P' X) : MonoidalFunctor (FullSubcategory P) (FullSubcategory P') where toFunctor := FullSubcategory.map h ε := 𝟙 _ - μ X Y := 𝟙 _ + μ _ _ := 𝟙 _ instance fullMonoidalSubcategory.map_full (h : ∀ ⦃X⦄, P X → P' X) : (fullMonoidalSubcategory.map h).Full where @@ -200,10 +200,10 @@ instance fullMonoidalClosedSubcategory : MonoidalClosed (FullSubcategory P) wher adj := { unit := { app := fun Y => (ihom.coev X.1).app Y.1 - naturality := fun Y Z f => ihom.coev_naturality X.1 f } + naturality := fun _ _ f => ihom.coev_naturality X.1 f } counit := { app := fun Y => (ihom.ev X.1).app Y.1 - naturality := fun Y Z f => ihom.ev_naturality X.1 f } + naturality := fun _ _ f => ihom.ev_naturality X.1 f } left_triangle_components := fun X ↦ by simp [FullSubcategory.comp_def, FullSubcategory.id_def] right_triangle_components := fun Y ↦ diff --git a/Mathlib/CategoryTheory/Monoidal/Transport.lean b/Mathlib/CategoryTheory/Monoidal/Transport.lean index 19d755f6f034bc..bda1093a68af07 100644 --- a/Mathlib/CategoryTheory/Monoidal/Transport.lean +++ b/Mathlib/CategoryTheory/Monoidal/Transport.lean @@ -160,7 +160,7 @@ attribute [local simp] transportStruct in def transport (e : C ≌ D) : MonoidalCategory.{v₂} D := letI : MonoidalCategoryStruct.{v₂} D := transportStruct e induced e.inverse - { μIso := fun X Y => e.unitIso.app _ + { μIso := fun _ _ => e.unitIso.app _ εIso := e.unitIso.app _ } /-- A type synonym for `D`, which will carry the transported monoidal structure. -/ diff --git a/Mathlib/CategoryTheory/Monoidal/Types/Coyoneda.lean b/Mathlib/CategoryTheory/Monoidal/Types/Coyoneda.lean index 475acc453b566b..bcc39bf0542db1 100644 --- a/Mathlib/CategoryTheory/Monoidal/Types/Coyoneda.lean +++ b/Mathlib/CategoryTheory/Monoidal/Types/Coyoneda.lean @@ -30,7 +30,7 @@ def coyonedaTensorUnit (C : Type u) [Category.{v} C] [MonoidalCategory C] : LaxMonoidalFunctor C (Type v) := .ofTensorHom (F := coyoneda.obj (op (𝟙_ C))) (ε := fun _p => 𝟙 _) - (μ := fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) + (μ := fun _ _ p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) (μ_natural := by aesop_cat) (associativity := fun X Y Z => by ext ⟨⟨f, g⟩, h⟩; dsimp at f g h diff --git a/Mathlib/CategoryTheory/MorphismProperty/Concrete.lean b/Mathlib/CategoryTheory/MorphismProperty/Concrete.lean index 5b79e2725971f7..f343d8580e6542 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Concrete.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Concrete.lean @@ -126,7 +126,7 @@ def functorialSurjectiveInjectiveFactorizationData : ext x exact congr_fun φ.w x } p := - { app := fun f y => y.1 + { app := fun _ y => y.1 naturality := by intros; rfl; } fac := rfl hi := by diff --git a/Mathlib/CategoryTheory/Opposites.lean b/Mathlib/CategoryTheory/Opposites.lean index 6d4f00e441da3f..8cb8e3e027660b 100644 --- a/Mathlib/CategoryTheory/Opposites.lean +++ b/Mathlib/CategoryTheory/Opposites.lean @@ -171,12 +171,12 @@ protected def unop (F : Cᵒᵖ ⥤ Dᵒᵖ) : C ⥤ D where /-- The isomorphism between `F.op.unop` and `F`. -/ @[simps!] def opUnopIso (F : C ⥤ D) : F.op.unop ≅ F := - NatIso.ofComponents fun X => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ /-- The isomorphism between `F.unop.op` and `F`. -/ @[simps!] def unopOpIso (F : Cᵒᵖ ⥤ Dᵒᵖ) : F.unop.op ≅ F := - NatIso.ofComponents fun X => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ variable (C D) @@ -187,7 +187,7 @@ def opHom : (C ⥤ D)ᵒᵖ ⥤ Cᵒᵖ ⥤ Dᵒᵖ where obj F := (unop F).op map α := { app := fun X => (α.unop.app (unop X)).op - naturality := fun X Y f => Quiver.Hom.unop_inj (α.unop.naturality f.unop).symm } + naturality := fun _ _ f => Quiver.Hom.unop_inj (α.unop.naturality f.unop).symm } /-- Take the "unopposite" of a functor is functorial. -/ @@ -197,7 +197,7 @@ def opInv : (Cᵒᵖ ⥤ Dᵒᵖ) ⥤ (C ⥤ D)ᵒᵖ where map α := Quiver.Hom.op { app := fun X => (α.app (op X)).unop - naturality := fun X Y f => Quiver.Hom.op_inj <| (α.naturality f.op).symm } + naturality := fun _ _ f => Quiver.Hom.op_inj <| (α.naturality f.op).symm } variable {C D} @@ -246,12 +246,12 @@ instance leftOp_full {F : C ⥤ Dᵒᵖ} [Full F] : Full F.leftOp where /-- The isomorphism between `F.leftOp.rightOp` and `F`. -/ @[simps!] def leftOpRightOpIso (F : C ⥤ Dᵒᵖ) : F.leftOp.rightOp ≅ F := - NatIso.ofComponents fun X => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ /-- The isomorphism between `F.rightOp.leftOp` and `F`. -/ @[simps!] def rightOpLeftOpIso (F : Cᵒᵖ ⥤ D) : F.rightOp.leftOp ≅ F := - NatIso.ofComponents fun X => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ /-- Whenever possible, it is advisable to use the isomorphism `rightOpLeftOpIso` instead of this equality of functors. -/ @@ -363,7 +363,7 @@ taking `op` of each component gives a natural transformation `G.rightOp ⟶ F.ri -/ @[simps] protected def rightOp (α : F ⟶ G) : G.rightOp ⟶ F.rightOp where - app X := (α.app _).op + app _ := (α.app _).op naturality X Y f := Quiver.Hom.unop_inj (by simp) @[simp] diff --git a/Mathlib/CategoryTheory/PUnit.lean b/Mathlib/CategoryTheory/PUnit.lean index d3c89945af0f3c..b561c063d44681 100644 --- a/Mathlib/CategoryTheory/PUnit.lean +++ b/Mathlib/CategoryTheory/PUnit.lean @@ -55,7 +55,7 @@ def equiv : Discrete PUnit.{w + 1} ⥤ C ≌ C where { obj := fun F => F.obj ⟨⟨⟩⟩ map := fun θ => θ.app ⟨⟨⟩⟩ } inverse := Functor.const _ - unitIso := NatIso.ofComponents fun X => Discrete.natIso fun i => Iso.refl _ + unitIso := NatIso.ofComponents fun _ => Discrete.natIso fun _ => Iso.refl _ counitIso := NatIso.ofComponents Iso.refl end Functor diff --git a/Mathlib/CategoryTheory/PathCategory.lean b/Mathlib/CategoryTheory/PathCategory.lean index 4f0b3ec8497906..714ff9a26e3bc6 100644 --- a/Mathlib/CategoryTheory/PathCategory.lean +++ b/Mathlib/CategoryTheory/PathCategory.lean @@ -37,7 +37,7 @@ namespace Paths instance categoryPaths : Category.{max u₁ v₁} (Paths V) where Hom := fun X Y : V => Quiver.Path X Y - id X := Quiver.Path.nil + id _ := Quiver.Path.nil comp f g := Quiver.Path.comp f g variable {V} @@ -57,7 +57,7 @@ def lift {C} [Category C] (φ : V ⥤q C) : Paths V ⥤ C where map {X} {Y} f := @Quiver.Path.rec V _ X (fun Y _ => φ.obj X ⟶ φ.obj Y) (𝟙 <| φ.obj X) (fun _ f ihp => ihp ≫ φ.map f) Y f - map_id X := rfl + map_id _ := rfl map_comp f g := by induction g with | nil => @@ -221,7 +221,7 @@ def quotientPathsEquiv : Quotient (pathsHomRel C) ≌ C where apply Quot.sound apply Quotient.CompClosure.of simp [Category.comp_id, Category.id_comp, pathsHomRel]) - counitIso := NatIso.ofComponents (fun X => Iso.refl _) (fun f => by simp [Quot.liftOn_mk]) + counitIso := NatIso.ofComponents (fun _ => Iso.refl _) (fun f => by simp [Quot.liftOn_mk]) functor_unitIso_comp X := by cases X simp only [pathsHomRel, pathComposition_obj, pathComposition_map, Functor.id_obj, diff --git a/Mathlib/CategoryTheory/Pi/Basic.lean b/Mathlib/CategoryTheory/Pi/Basic.lean index 166b83c21ef2a7..6827f96279d677 100644 --- a/Mathlib/CategoryTheory/Pi/Basic.lean +++ b/Mathlib/CategoryTheory/Pi/Basic.lean @@ -111,7 +111,7 @@ def comapComp (f : K → J) (g : J → I) : comap C g ⋙ comap (C ∘ g) f ≅ /-- The natural isomorphism between pulling back then evaluating, and just evaluating. -/ @[simps!] def comapEvalIsoEval (h : J → I) (j : J) : comap C h ⋙ eval (C ∘ h) j ≅ eval C (h j) := - NatIso.ofComponents (fun f => Iso.refl _) (by simp only [Iso.refl]; aesop_cat) + NatIso.ofComponents (fun _ => Iso.refl _) (by simp only [Iso.refl]; aesop_cat) end @@ -141,7 +141,7 @@ def sum : (∀ i, C i) ⥤ (∀ j, D j) ⥤ ∀ s : I ⊕ J, Sum.elim C D s wher match s with | .inl i => X i | .inr j => Y j - map := fun {Y} {Y'} f s => + map := fun {_} {_} f s => match s with | .inl i => 𝟙 (X i) | .inr j => f j } @@ -348,7 +348,7 @@ def Pi.optionEquivalence (C' : Option J → Type u₁) [∀ i, Category.{v₁} ( | some i => Prod.snd _ _ ⋙ (Pi.eval _ i)) unitIso := NatIso.pi' (fun i => match i with | none => Iso.refl _ - | some i => Iso.refl _) + | some _ => Iso.refl _) counitIso := by exact Iso.refl _ namespace Equivalence diff --git a/Mathlib/CategoryTheory/Preadditive/FunctorCategory.lean b/Mathlib/CategoryTheory/Preadditive/FunctorCategory.lean index f1786b2cbca395..8df532c9e1251c 100644 --- a/Mathlib/CategoryTheory/Preadditive/FunctorCategory.lean +++ b/Mathlib/CategoryTheory/Preadditive/FunctorCategory.lean @@ -20,7 +20,7 @@ open CategoryTheory.Limits Preadditive variable {C D : Type*} [Category C] [Category D] [Preadditive D] instance {F G : C ⥤ D} : Zero (F ⟶ G) where - zero := { app := fun X => 0 } + zero := { app := fun _ => 0 } instance {F G : C ⥤ D} : Add (F ⟶ G) where add α β := { app := fun X => α.app X + β.app X } diff --git a/Mathlib/CategoryTheory/Preadditive/Mat.lean b/Mathlib/CategoryTheory/Preadditive/Mat.lean index d3d9783dc37c79..9d44442e07dd38 100644 --- a/Mathlib/CategoryTheory/Preadditive/Mat.lean +++ b/Mathlib/CategoryTheory/Preadditive/Mat.lean @@ -298,8 +298,8 @@ variable {C} -/ @[simps] def isoBiproductEmbedding (M : Mat_ C) : M ≅ ⨁ fun i => (embedding C).obj (M.X i) where - hom := biproduct.lift fun i j k => if h : j = i then eqToHom (congr_arg M.X h) else 0 - inv := biproduct.desc fun i j k => if h : i = k then eqToHom (congr_arg M.X h) else 0 + hom := biproduct.lift fun i j _ => if h : j = i then eqToHom (congr_arg M.X h) else 0 + inv := biproduct.desc fun i _ k => if h : i = k then eqToHom (congr_arg M.X h) else 0 hom_inv_id := by simp only [biproduct.lift_desc] funext i j diff --git a/Mathlib/CategoryTheory/Preadditive/Projective.lean b/Mathlib/CategoryTheory/Preadditive/Projective.lean index e0900aad10375c..c593644a263b3e 100644 --- a/Mathlib/CategoryTheory/Preadditive/Projective.lean +++ b/Mathlib/CategoryTheory/Preadditive/Projective.lean @@ -92,8 +92,8 @@ instance zero_projective [HasZeroObject C] : Projective (0 : C) := end -theorem of_iso {P Q : C} (i : P ≅ Q) (hP : Projective P) : Projective Q where - factors f e e_epi := +theorem of_iso {P Q : C} (i : P ≅ Q) (_ : Projective P) : Projective Q where + factors f e _ := let ⟨f', hf'⟩ := Projective.factors (i.hom ≫ f) e ⟨i.inv ≫ f', by simp [hf']⟩ diff --git a/Mathlib/CategoryTheory/Preadditive/Schur.lean b/Mathlib/CategoryTheory/Preadditive/Schur.lean index 2fd3b980f6f59d..9c571b370957fd 100644 --- a/Mathlib/CategoryTheory/Preadditive/Schur.lean +++ b/Mathlib/CategoryTheory/Preadditive/Schur.lean @@ -66,9 +66,9 @@ noncomputable instance [HasKernels C] {X : C} [Simple X] : DivisionRing (End X) haveI := isIso_of_hom_simple hf exact IsIso.inv_hom_id f nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl qsmul := _ - qsmul_def := fun q a => rfl + qsmul_def := fun _ _ => rfl open Module diff --git a/Mathlib/CategoryTheory/Preadditive/Yoneda/Basic.lean b/Mathlib/CategoryTheory/Preadditive/Yoneda/Basic.lean index 3e19f976a5b181..1d23ec18a08669 100644 --- a/Mathlib/CategoryTheory/Preadditive/Yoneda/Basic.lean +++ b/Mathlib/CategoryTheory/Preadditive/Yoneda/Basic.lean @@ -41,8 +41,8 @@ def preadditiveYonedaObj (Y : C) : Cᵒᵖ ⥤ ModuleCat.{v} (End Y) where obj X := ModuleCat.of _ (X.unop ⟶ Y) map f := ModuleCat.asHom { toFun := fun g => f.unop ≫ g - map_add' := fun g g' => comp_add _ _ _ _ _ _ - map_smul' := fun r g => Eq.symm <| Category.assoc _ _ _ } + map_add' := fun _ _ => comp_add _ _ _ _ _ _ + map_smul' := fun _ _ => Eq.symm <| Category.assoc _ _ _ } /-- The Yoneda embedding for preadditive categories sends an object `Y` to the presheaf sending an object `X` to the group of morphisms `X ⟶ Y`. At each point, we get an additional `End Y`-module @@ -52,11 +52,11 @@ structure, see `preadditiveYonedaObj`. def preadditiveYoneda : C ⥤ Cᵒᵖ ⥤ AddCommGrp.{v} where obj Y := preadditiveYonedaObj Y ⋙ forget₂ _ _ map f := - { app := fun X => + { app := fun _ => { toFun := fun g => g ≫ f map_zero' := Limits.zero_comp - map_add' := fun g g' => add_comp _ _ _ _ _ _ } - naturality := fun X X' g => AddCommGrp.ext fun x => Category.assoc _ _ _ } + map_add' := fun _ _ => add_comp _ _ _ _ _ _ } + naturality := fun _ _ _ => AddCommGrp.ext fun _ => Category.assoc _ _ _ } map_id _ := by ext; dsimp; simp map_comp f g := by ext; dsimp; simp @@ -68,8 +68,8 @@ def preadditiveCoyonedaObj (X : Cᵒᵖ) : C ⥤ ModuleCat.{v} (End X) where obj Y := ModuleCat.of _ (unop X ⟶ Y) map f := ModuleCat.asHom { toFun := fun g => g ≫ f - map_add' := fun g g' => add_comp _ _ _ _ _ _ - map_smul' := fun r g => Category.assoc _ _ _ } + map_add' := fun _ _ => add_comp _ _ _ _ _ _ + map_smul' := fun _ _ => Category.assoc _ _ _ } /-- 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 @@ -79,12 +79,12 @@ structure, see `preadditiveCoyonedaObj`. def preadditiveCoyoneda : Cᵒᵖ ⥤ C ⥤ AddCommGrp.{v} where obj X := preadditiveCoyonedaObj X ⋙ forget₂ _ _ map f := - { app := fun Y => + { app := fun _ => { toFun := fun g => f.unop ≫ g map_zero' := Limits.comp_zero - map_add' := fun g g' => comp_add _ _ _ _ _ _ } - naturality := fun Y Y' g => - AddCommGrp.ext fun x => Eq.symm <| Category.assoc _ _ _ } + map_add' := fun _ _ => comp_add _ _ _ _ _ _ } + naturality := fun _ _ _ => + AddCommGrp.ext fun _ => Eq.symm <| Category.assoc _ _ _ } map_id _ := by ext; dsimp; simp map_comp f g := by ext; dsimp; simp diff --git a/Mathlib/CategoryTheory/Products/Basic.lean b/Mathlib/CategoryTheory/Products/Basic.lean index 58958ff88a2dea..83d4a027d4ac08 100644 --- a/Mathlib/CategoryTheory/Products/Basic.lean +++ b/Mathlib/CategoryTheory/Products/Basic.lean @@ -171,9 +171,9 @@ def evaluation : C ⥤ (C ⥤ D) ⥤ D where obj X := { obj := fun F => F.obj X map := fun α => α.app X } - map {X} {Y} f := + map {_} {_} f := { app := fun F => F.map f - naturality := fun {F} {G} α => Eq.symm (α.naturality f) } + naturality := fun {_} {_} α => Eq.symm (α.naturality f) } /-- The "evaluation of `F` at `X`" functor, as a functor `C × (C ⥤ D) ⥤ D`. @@ -193,7 +193,7 @@ variable {C} /-- The constant functor followed by the evaluation functor is just the identity. -/ @[simps!] def Functor.constCompEvaluationObj (X : C) : Functor.const C ⋙ (evaluation C D).obj X ≅ 𝟭 D := - NatIso.ofComponents fun Y => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ end @@ -219,12 +219,12 @@ def prod' (F : A ⥤ B) (G : A ⥤ C) : A ⥤ B × C where /-- The product `F.prod' G` followed by projection on the first component is isomorphic to `F` -/ @[simps!] def prod'CompFst (F : A ⥤ B) (G : A ⥤ C) : F.prod' G ⋙ CategoryTheory.Prod.fst B C ≅ F := - NatIso.ofComponents fun X => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ /-- The product `F.prod' G` followed by projection on the second component is isomorphic to `G` -/ @[simps!] def prod'CompSnd (F : A ⥤ B) (G : A ⥤ C) : F.prod' G ⋙ CategoryTheory.Prod.snd B C ≅ G := - NatIso.ofComponents fun X => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ section diff --git a/Mathlib/CategoryTheory/Quotient.lean b/Mathlib/CategoryTheory/Quotient.lean index 5a1f9831b20554..2379d976800bca 100644 --- a/Mathlib/CategoryTheory/Quotient.lean +++ b/Mathlib/CategoryTheory/Quotient.lean @@ -188,7 +188,7 @@ lemma lift_unique' (F₁ F₂ : Quotient r ⥤ D) (h : functor r ⋙ F₁ = func /-- The original functor factors through the induced functor. -/ def lift.isLift : functor r ⋙ lift r F H ≅ F := - NatIso.ofComponents fun X ↦ Iso.refl _ + NatIso.ofComponents fun _ ↦ Iso.refl _ @[simp] theorem lift.isLift_hom (X : C) : (lift.isLift r F H).hom.app X = 𝟙 (F.obj X) := diff --git a/Mathlib/CategoryTheory/Shift/CommShift.lean b/Mathlib/CategoryTheory/Shift/CommShift.lean index e75c095dca2712..62d33df9efcfe1 100644 --- a/Mathlib/CategoryTheory/Shift/CommShift.lean +++ b/Mathlib/CategoryTheory/Shift/CommShift.lean @@ -149,7 +149,7 @@ namespace CommShift variable (C) in instance id : CommShift (𝟭 C) A where - iso := fun a => rightUnitor _ ≪≫ (leftUnitor _).symm + iso := fun _ => rightUnitor _ ≪≫ (leftUnitor _).symm instance comp [F.CommShift A] [G.CommShift A] : (F ⋙ G).CommShift A where iso a := (Functor.associator _ _ _).symm ≪≫ isoWhiskerRight (F.commShiftIso a) _ ≪≫ diff --git a/Mathlib/CategoryTheory/Shift/SingleFunctors.lean b/Mathlib/CategoryTheory/Shift/SingleFunctors.lean index 9b845c8a62a64e..115e77228da252 100644 --- a/Mathlib/CategoryTheory/Shift/SingleFunctors.lean +++ b/Mathlib/CategoryTheory/Shift/SingleFunctors.lean @@ -118,7 +118,7 @@ attribute [local simp] comm comm_assoc /-- The identity morphism in `SingleFunctors C D A`. -/ @[simps] def id : Hom F F where - hom a := 𝟙 _ + hom _ := 𝟙 _ variable {F G H} @@ -168,7 +168,7 @@ variable (C D) @[simps] def evaluation (a : A) : SingleFunctors C D A ⥤ C ⥤ D where obj F := F.functor a - map {F G} φ := φ.hom a + map {_ _} φ := φ.hom a variable {C D} @@ -237,7 +237,7 @@ variable {C E' A} @[simps!] def postcompPostcompIso (G : D ⥤ E) (G' : E ⥤ E') [G.CommShift A] [G'.CommShift A] : (F.postcomp G).postcomp G' ≅ F.postcomp (G ⋙ G') := - isoMk (fun a => Functor.associator _ _ _) (fun n a a' ha' => by + isoMk (fun _ => Functor.associator _ _ _) (fun n a a' ha' => by ext X simp [Functor.commShiftIso_comp_inv_app]) diff --git a/Mathlib/CategoryTheory/Sigma/Basic.lean b/Mathlib/CategoryTheory/Sigma/Basic.lean index 6e1f7a6bfe594c..d7550a04b32887 100644 --- a/Mathlib/CategoryTheory/Sigma/Basic.lean +++ b/Mathlib/CategoryTheory/Sigma/Basic.lean @@ -136,7 +136,7 @@ lemma desc_map_mk {i : I} (X Y : C i) (f : X ⟶ Y) : (desc F).map (SigmaHom.mk `F i`. -/ def inclDesc (i : I) : incl i ⋙ desc F ≅ F i := - NatIso.ofComponents fun X => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ @[simp] lemma inclDesc_hom_app (i : I) (X : C i) : (inclDesc F i).hom.app X = 𝟙 ((F i).obj X) := @@ -202,7 +202,7 @@ variable (I) /-- The functor `Sigma.map` applied to the identity function is just the identity functor. -/ @[simps!] def mapId : map C (id : I → I) ≅ 𝟭 (Σi, C i) := - natIso fun i => NatIso.ofComponents fun X => Iso.refl _ + natIso fun i => NatIso.ofComponents fun _ => Iso.refl _ variable {I} {K : Type w₃} diff --git a/Mathlib/CategoryTheory/Sites/Closed.lean b/Mathlib/CategoryTheory/Sites/Closed.lean index fb3b323b44de08..49c58c3039641f 100644 --- a/Mathlib/CategoryTheory/Sites/Closed.lean +++ b/Mathlib/CategoryTheory/Sites/Closed.lean @@ -269,7 +269,7 @@ def topologyOfClosureOperator (c : ∀ X : C, ClosureOperator (Sieve X)) The topology given by the closure operator `J.close` on a Grothendieck topology is the same as `J`. -/ theorem topologyOfClosureOperator_self : - (topologyOfClosureOperator J₁.closureOperator fun X Y => J₁.pullback_close) = J₁ := by + (topologyOfClosureOperator J₁.closureOperator fun _ _ => J₁.pullback_close) = J₁ := by ext X S apply GrothendieckTopology.close_eq_top_iff_mem diff --git a/Mathlib/CategoryTheory/Sites/ConcreteSheafification.lean b/Mathlib/CategoryTheory/Sites/ConcreteSheafification.lean index 8d46116dc8326c..fa351aa7cb9821 100644 --- a/Mathlib/CategoryTheory/Sites/ConcreteSheafification.lean +++ b/Mathlib/CategoryTheory/Sites/ConcreteSheafification.lean @@ -573,8 +573,8 @@ noncomputable def plusPlusAdjunction : plusPlusSheaf J D ⊣ sheafToPresheaf J D { homEquiv := fun P Q => { toFun := fun e => J.toSheafify P ≫ e.val invFun := fun e => ⟨J.sheafifyLift e Q.2⟩ - left_inv := fun e => Sheaf.Hom.ext <| (J.sheafifyLift_unique _ _ _ rfl).symm - right_inv := fun e => J.toSheafify_sheafifyLift _ _ } + left_inv := fun _ => Sheaf.Hom.ext <| (J.sheafifyLift_unique _ _ _ rfl).symm + right_inv := fun _ => J.toSheafify_sheafifyLift _ _ } homEquiv_naturality_left_symm := by intro P Q R η γ; ext1; dsimp; symm apply J.sheafifyMap_sheafifyLift diff --git a/Mathlib/CategoryTheory/Sites/Coverage.lean b/Mathlib/CategoryTheory/Sites/Coverage.lean index 648975e7b07ec2..666be866cab49f 100644 --- a/Mathlib/CategoryTheory/Sites/Coverage.lean +++ b/Mathlib/CategoryTheory/Sites/Coverage.lean @@ -236,13 +236,13 @@ def toGrothendieck (K : Coverage C) : GrothendieckTopology C where intro Z g hg rw [← Sieve.pullback_comp] exact hS hg - transitive' X S hS R hR := .transitive _ _ _ hS hR + transitive' _ _ hS _ hR := .transitive _ _ _ hS hR instance : PartialOrder (Coverage C) where le A B := A.covering ≤ B.covering - le_refl A X := le_refl _ - le_trans A B C h1 h2 X := le_trans (h1 X) (h2 X) - le_antisymm A B h1 h2 := Coverage.ext <| funext <| + le_refl _ _ := le_refl _ + le_trans _ _ _ h1 h2 X := le_trans (h1 X) (h2 X) + le_antisymm _ _ h1 h2 := Coverage.ext <| funext <| fun X => le_antisymm (h1 X) (h2 X) variable (C) in diff --git a/Mathlib/CategoryTheory/Sites/EffectiveEpimorphic.lean b/Mathlib/CategoryTheory/Sites/EffectiveEpimorphic.lean index 3a67742995d2b1..f0f3a969c48668 100644 --- a/Mathlib/CategoryTheory/Sites/EffectiveEpimorphic.lean +++ b/Mathlib/CategoryTheory/Sites/EffectiveEpimorphic.lean @@ -102,13 +102,13 @@ def effectiveEpiStructOfIsColimit {X Y : C} (f : Y ⟶ X) Cocone (Sieve.generateSingleton f).arrows.diagram := { pt := W ι := { - app := fun ⟨T,hT⟩ => hT.choose ≫ e + app := fun ⟨_,hT⟩ => hT.choose ≫ e naturality := by rintro ⟨A,hA⟩ ⟨B,hB⟩ (q : A ⟶ B) dsimp; simp only [← Category.assoc, Category.comp_id] apply h rw [Category.assoc, hB.choose_spec, hA.choose_spec, Over.w] } } - { desc := fun {W} e h => Hf.desc (aux e h) + { desc := fun {_} e h => Hf.desc (aux e h) fac := by intro W e h dsimp @@ -214,14 +214,14 @@ def effectiveEpiFamilyStructOfIsColimit {B : C} {α : Type*} Cocone (Sieve.generateFamily X π).arrows.diagram := { pt := W ι := { - app := fun ⟨T,hT⟩ => hT.choose_spec.choose ≫ e hT.choose + app := fun ⟨_,hT⟩ => hT.choose_spec.choose ≫ e hT.choose naturality := by intro ⟨A,a,(g₁ : A.left ⟶ _),ha⟩ ⟨B,b,(g₂ : B.left ⟶ _),hb⟩ (q : A ⟶ B) dsimp; rw [Category.comp_id, ← Category.assoc] apply h; rw [Category.assoc] generalize_proofs h1 h2 h3 h4 rw [h2.choose_spec, h4.choose_spec, Over.w] } } - { desc := fun {W} e h => H.desc (aux e h) + { desc := fun {_} e h => H.desc (aux e h) fac := by intro W e h a dsimp diff --git a/Mathlib/CategoryTheory/Sites/EqualizerSheafCondition.lean b/Mathlib/CategoryTheory/Sites/EqualizerSheafCondition.lean index 44e39a7bba0c90..c2a70eaeecba14 100644 --- a/Mathlib/CategoryTheory/Sites/EqualizerSheafCondition.lean +++ b/Mathlib/CategoryTheory/Sites/EqualizerSheafCondition.lean @@ -66,7 +66,7 @@ variable (P R) /-- Show that `FirstObj` is isomorphic to `FamilyOfElements`. -/ @[simps] def firstObjEqFamily : FirstObj P R ≅ R.FamilyOfElements P where - hom t Y f hf := Pi.π (fun f : ΣY, { f : Y ⟶ X // R f } => P.obj (op f.1)) ⟨_, _, hf⟩ t + hom t _ _ hf := Pi.π (fun f : ΣY, { f : Y ⟶ X // R f } => P.obj (op f.1)) ⟨_, _, hf⟩ t inv := Pi.lift fun f x => x _ f.2.2 instance : Inhabited (FirstObj P (⊥ : Presieve X)) := diff --git a/Mathlib/CategoryTheory/Sites/Grothendieck.lean b/Mathlib/CategoryTheory/Sites/Grothendieck.lean index 0d3552925cc54d..aaf3d4a203a5ba 100644 --- a/Mathlib/CategoryTheory/Sites/Grothendieck.lean +++ b/Mathlib/CategoryTheory/Sites/Grothendieck.lean @@ -207,8 +207,8 @@ See [MM92] Chapter III, Section 2, example (a), or https://en.wikipedia.org/wiki/Grothendieck_topology#The_discrete_and_indiscrete_topologies -/ def trivial : GrothendieckTopology C where - sieves X := {⊤} - top_mem' X := rfl + sieves _ := {⊤} + top_mem' _ := rfl pullback_stable' X Y S f hf := by rw [Set.mem_singleton_iff] at hf ⊢ simp [hf] @@ -221,7 +221,7 @@ def trivial : GrothendieckTopology C where See https://en.wikipedia.org/wiki/Grothendieck_topology#The_discrete_and_indiscrete_topologies. -/ def discrete : GrothendieckTopology C where - sieves X := Set.univ + sieves _ := Set.univ top_mem' := by simp pullback_stable' X Y f := by simp transitive' := by simp @@ -241,9 +241,9 @@ theorem le_def {J₁ J₂ : GrothendieckTopology C} : J₁ ≤ J₂ ↔ (J₁ : /-- See -/ instance : PartialOrder (GrothendieckTopology C) := { instLEGrothendieckTopology with - le_refl := fun J₁ => le_def.mpr le_rfl - le_trans := fun J₁ J₂ J₃ h₁₂ h₂₃ => le_def.mpr (le_trans h₁₂ h₂₃) - le_antisymm := fun J₁ J₂ h₁₂ h₂₁ => GrothendieckTopology.ext (le_antisymm h₁₂ h₂₁) } + le_refl := fun _ => le_def.mpr le_rfl + le_trans := fun _ _ _ h₁₂ h₂₃ => le_def.mpr (le_trans h₁₂ h₂₃) + le_antisymm := fun _ _ h₁₂ h₂₁ => GrothendieckTopology.ext (le_antisymm h₁₂ h₂₁) } /-- See -/ instance : InfSet (GrothendieckTopology C) where @@ -323,7 +323,7 @@ See https://ncatlab.org/nlab/show/dense+topology, or [MM92] Chapter III, Section -/ def dense : GrothendieckTopology C where sieves X S := ∀ {Y : C} (f : Y ⟶ X), ∃ (Z : _) (g : Z ⟶ Y), S (g ≫ f) - top_mem' X Y f := ⟨Y, 𝟙 Y, ⟨⟩⟩ + top_mem' _ Y _ := ⟨Y, 𝟙 Y, ⟨⟩⟩ pullback_stable' := by intro X Y S h H Z f rcases H (f ≫ h) with ⟨W, g, H'⟩ @@ -355,7 +355,7 @@ See https://ncatlab.org/nlab/show/atomic+site, or [MM92] Chapter III, Section 2, -/ def atomic (hro : RightOreCondition C) : GrothendieckTopology C where sieves X S := ∃ (Y : _) (f : Y ⟶ X), S f - top_mem' X := ⟨_, 𝟙 _, ⟨⟩⟩ + top_mem' _ := ⟨_, 𝟙 _, ⟨⟩⟩ pullback_stable' := by rintro X Y S h ⟨Z, f, hf⟩ rcases hro h f with ⟨W, g, k, comm⟩ @@ -394,15 +394,15 @@ theorem ext (S T : J.Cover X) (h : ∀ ⦃Y⦄ (f : Y ⟶ X), S f ↔ T f) : S = instance : OrderTop (J.Cover X) := { (inferInstance : Preorder (J.Cover X)) with top := ⟨⊤, J.top_mem _⟩ - le_top := fun S Y f _ => by tauto } + le_top := fun _ _ _ _ => by tauto } instance : SemilatticeInf (J.Cover X) := { (inferInstance : Preorder _) with inf := fun S T => ⟨S ⊓ T, J.intersection_covering S.condition T.condition⟩ - le_antisymm := fun S T h1 h2 => ext _ _ fun {Y} f => ⟨by apply h1, by apply h2⟩ - inf_le_left := fun S T Y f hf => hf.1 - inf_le_right := fun S T Y f hf => hf.2 - le_inf := fun S T W h1 h2 Y f h => ⟨h1 _ h, h2 _ h⟩ } + le_antisymm := fun _ _ h1 h2 => ext _ _ fun {Y} f => ⟨by apply h1, by apply h2⟩ + inf_le_left := fun _ _ _ _ hf => hf.1 + inf_le_right := fun _ _ _ _ hf => hf.2 + le_inf := fun _ _ _ h1 h2 _ _ h => ⟨h1 _ h, h2 _ h⟩ } instance : Inhabited (J.Cover X) := ⟨⊤⟩ diff --git a/Mathlib/CategoryTheory/Sites/InducedTopology.lean b/Mathlib/CategoryTheory/Sites/InducedTopology.lean index 718bea16efa743..c5be7f7e1ffda0 100644 --- a/Mathlib/CategoryTheory/Sites/InducedTopology.lean +++ b/Mathlib/CategoryTheory/Sites/InducedTopology.lean @@ -66,7 +66,7 @@ then the set `{ T ∩ mor(C) | T ∈ K }` is a grothendieck topology of `C`. -/ @[simps] def inducedTopology : GrothendieckTopology C where - sieves X S := K _ (S.functorPushforward G) + sieves _ S := K _ (S.functorPushforward G) top_mem' X := by change K _ _ rw [Sieve.functorPushforward_top] diff --git a/Mathlib/CategoryTheory/Sites/IsSheafFor.lean b/Mathlib/CategoryTheory/Sites/IsSheafFor.lean index 136e553138ef31..5e870d3f0cab61 100644 --- a/Mathlib/CategoryTheory/Sites/IsSheafFor.lean +++ b/Mathlib/CategoryTheory/Sites/IsSheafFor.lean @@ -440,7 +440,7 @@ def natTransEquivCompatibleFamily {P : Cᵒᵖ ⥤ Type v₁} : rw [← FunctorToTypes.naturality _ _ α g.op] rfl invFun t := - { app := fun Y f => t.1 _ f.2 + { app := fun _ f => t.1 _ f.2 naturality := fun Y Z g => by ext ⟨f, hf⟩ apply t.2.to_sieveCompatible _ } @@ -656,7 +656,7 @@ theorem isSheafFor_subsieve (P : Cᵒᵖ ⥤ Type w) {S : Sieve X} {R : Presieve (h : (S : Presieve X) ≤ R) (trans : ∀ ⦃Y⦄ (f : Y ⟶ X), IsSheafFor P (S.pullback f : Presieve Y)) : IsSheafFor P R := - isSheafFor_subsieve_aux P h (by simpa using trans (𝟙 _)) fun Y f _ => (trans f).isSeparatedFor + isSheafFor_subsieve_aux P h (by simpa using trans (𝟙 _)) fun _ f _ => (trans f).isSeparatedFor section Arrows diff --git a/Mathlib/CategoryTheory/Sites/Limits.lean b/Mathlib/CategoryTheory/Sites/Limits.lean index 1c38d0e033185f..5e19d921a4291b 100644 --- a/Mathlib/CategoryTheory/Sites/Limits.lean +++ b/Mathlib/CategoryTheory/Sites/Limits.lean @@ -138,7 +138,7 @@ theorem isSheaf_of_isLimit (F : K ⥤ Sheaf J D) (E : Cone (F ⋙ sheafToPreshea instance (F : K ⥤ Sheaf J D) : CreatesLimit F (sheafToPresheaf J D) := createsLimitOfReflectsIso fun E hE => { liftedCone := ⟨⟨E.pt, isSheaf_of_isLimit _ _ hE⟩, - ⟨fun t => ⟨E.π.app _⟩, fun u v e => Sheaf.Hom.ext <| E.π.naturality _⟩⟩ + ⟨fun _ => ⟨E.π.app _⟩, fun _ _ _ => Sheaf.Hom.ext <| E.π.naturality _⟩⟩ validLift := Cones.ext (eqToIso rfl) fun j => by dsimp simp diff --git a/Mathlib/CategoryTheory/Sites/LocallyFullyFaithful.lean b/Mathlib/CategoryTheory/Sites/LocallyFullyFaithful.lean index 780045646d7191..96bf30d33b13fa 100644 --- a/Mathlib/CategoryTheory/Sites/LocallyFullyFaithful.lean +++ b/Mathlib/CategoryTheory/Sites/LocallyFullyFaithful.lean @@ -41,7 +41,7 @@ This is the image sieve of `f` under `yonedaMap G V` and hence the name. See `Functor.imageSieve_eq_imageSieve`. -/ def Functor.imageSieve {U V : C} (f : G.obj U ⟶ G.obj V) : Sieve U where - arrows Y i := ∃ l, G.map l = G.map i ≫ f + arrows _ i := ∃ l, G.map l = G.map i ≫ f downward_closed := by rintro Y₁ Y₂ i₁ ⟨l, hl⟩ i₂ exact ⟨i₂ ≫ l, by simp [hl]⟩ @@ -55,7 +55,7 @@ For two arrows `f₁ f₂ : U ⟶ V`, the arrows `i` such that `i ≫ f₁ = i -/ @[simps] def Sieve.equalizer {U V : C} (f₁ f₂ : U ⟶ V) : Sieve U where - arrows Y i := i ≫ f₁ = i ≫ f₂ + arrows _ i := i ≫ f₁ = i ≫ f₂ downward_closed := by aesop @[simp] diff --git a/Mathlib/CategoryTheory/Sites/NonabelianCohomology/H1.lean b/Mathlib/CategoryTheory/Sites/NonabelianCohomology/H1.lean index 2f3b34ebb98a91..44a948a9222b1d 100644 --- a/Mathlib/CategoryTheory/Sites/NonabelianCohomology/H1.lean +++ b/Mathlib/CategoryTheory/Sites/NonabelianCohomology/H1.lean @@ -99,14 +99,14 @@ lemma one_ev (i j : I) {T : C} (a : T ⟶ U i) (b : T ⟶ U j) : variable {G U} instance : Mul (OneCochain G U) where - mul γ₁ γ₂ := { ev := fun i j T a b ↦ γ₁.ev i j a b * γ₂.ev i j a b } + mul γ₁ γ₂ := { ev := fun i j _ a b ↦ γ₁.ev i j a b * γ₂.ev i j a b } @[simp] lemma mul_ev (γ₁ γ₂ : OneCochain G U) (i j : I) {T : C} (a : T ⟶ U i) (b : T ⟶ U j) : (γ₁ * γ₂).ev i j a b = γ₁.ev i j a b * γ₂.ev i j a b := rfl instance : Inv (OneCochain G U) where - inv γ := { ev := fun i j T a b ↦ (γ.ev i j a b) ⁻¹} + inv γ := { ev := fun i j _ a b ↦ (γ.ev i j a b) ⁻¹} @[simp] lemma inv_ev (γ : OneCochain G U) (i j : I) {T : C} (a : T ⟶ U i) (b : T ⟶ U j) : diff --git a/Mathlib/CategoryTheory/Sites/Over.lean b/Mathlib/CategoryTheory/Sites/Over.lean index e374b3c585bdfc..f012575ed625ce 100644 --- a/Mathlib/CategoryTheory/Sites/Over.lean +++ b/Mathlib/CategoryTheory/Sites/Over.lean @@ -139,7 +139,7 @@ lemma over_forget_coverPreserving (X : C) : lemma over_forget_compatiblePreserving (X : C) : CompatiblePreserving J (Over.forget X) where - compatible {F Z T x hx Y₁ Y₂ W f₁ f₂ g₁ g₂ hg₁ hg₂ h} := by + compatible {_ Z _ _ hx Y₁ Y₂ W f₁ f₂ g₁ g₂ hg₁ hg₂ h} := by let W' : Over X := Over.mk (f₁ ≫ Y₁.hom) let g₁' : W' ⟶ Y₁ := Over.homMk f₁ let g₂' : W' ⟶ Y₂ := Over.homMk f₂ (by simpa using h.symm =≫ Z.hom) @@ -168,7 +168,7 @@ lemma over_map_coverPreserving {X Y : C} (f : X ⟶ Y) : lemma over_map_compatiblePreserving {X Y : C} (f : X ⟶ Y) : CompatiblePreserving (J.over Y) (Over.map f) where - compatible {F Z T x hx Y₁ Y₂ W f₁ f₂ g₁ g₂ hg₁ hg₂ h} := by + compatible {F Z _ x hx Y₁ Y₂ W f₁ f₂ g₁ g₂ hg₁ hg₂ h} := by let W' : Over X := Over.mk (f₁.left ≫ Y₁.hom) let g₁' : W' ⟶ Y₁ := Over.homMk f₁.left let g₂' : W' ⟶ Y₂ := Over.homMk f₂.left diff --git a/Mathlib/CategoryTheory/Sites/Plus.lean b/Mathlib/CategoryTheory/Sites/Plus.lean index 9fe18afba43baf..f4a6a9467b839c 100644 --- a/Mathlib/CategoryTheory/Sites/Plus.lean +++ b/Mathlib/CategoryTheory/Sites/Plus.lean @@ -39,7 +39,7 @@ variable (P : Cᵒᵖ ⥤ D) @[simps] def diagram (X : C) : (J.Cover X)ᵒᵖ ⥤ D where obj S := multiequalizer (S.unop.index P) - map {S T} f := + map {S _} f := Multiequalizer.lift _ _ (fun I => Multiequalizer.ι (S.unop.index P) (I.map f.unop)) (fun I => Multiequalizer.condition (S.unop.index P) (Cover.Relation.mk' (I.r.map f.unop))) @@ -56,7 +56,7 @@ between diagrams whose colimits define the values of `plus`. -/ @[simps] def diagramNatTrans {P Q : Cᵒᵖ ⥤ D} (η : P ⟶ Q) (X : C) : J.diagram P X ⟶ J.diagram Q X where app W := - Multiequalizer.lift _ _ (fun i => Multiequalizer.ι _ _ ≫ η.app _) (fun i => by + Multiequalizer.lift _ _ (fun _ => Multiequalizer.ι _ _ ≫ η.app _) (fun i => by dsimp only erw [Category.assoc, Category.assoc, ← η.naturality, ← η.naturality, Multiequalizer.condition_assoc] diff --git a/Mathlib/CategoryTheory/Sites/Pretopology.lean b/Mathlib/CategoryTheory/Sites/Pretopology.lean index 8163bb4bac21be..a70e13cc0de8b4 100644 --- a/Mathlib/CategoryTheory/Sites/Pretopology.lean +++ b/Mathlib/CategoryTheory/Sites/Pretopology.lean @@ -83,9 +83,9 @@ variable (C) instance : PartialOrder (Pretopology C) := { Pretopology.LE with - le_refl := fun K => le_def.mpr le_rfl - le_trans := fun K₁ K₂ K₃ h₁₂ h₂₃ => le_def.mpr (le_trans h₁₂ h₂₃) - le_antisymm := fun K₁ K₂ h₁₂ h₂₁ => Pretopology.ext (le_antisymm h₁₂ h₂₁) } + le_refl := fun _ => le_def.mpr le_rfl + le_trans := fun _ _ _ h₁₂ h₂₃ => le_def.mpr (le_trans h₁₂ h₂₃) + le_antisymm := fun _ _ h₁₂ h₂₁ => Pretopology.ext (le_antisymm h₁₂ h₂₁) } instance : OrderTop (Pretopology C) where top := @@ -105,7 +105,7 @@ See , or [MM92] Chapter III, Section -/ def toGrothendieck (K : Pretopology C) : GrothendieckTopology C where sieves X S := ∃ R ∈ K X, R ≤ (S : Presieve _) - top_mem' X := ⟨Presieve.singleton (𝟙 _), K.has_isos _, fun _ _ _ => ⟨⟩⟩ + top_mem' _ := ⟨Presieve.singleton (𝟙 _), K.has_isos _, fun _ _ _ => ⟨⟩⟩ pullback_stable' X Y S g := by rintro ⟨R, hR, RS⟩ refine ⟨_, K.pullbacks g _ hR, ?_⟩ @@ -152,7 +152,7 @@ def gi : GaloisInsertion (toGrothendieck C) (ofGrothendieck C) where · rintro h X S ⟨R, hR, RS⟩ apply J.superset_covering _ (h _ hR) rwa [Sieve.giGenerate.gc] - le_l_u J X S hS := ⟨S, J.superset_covering (Sieve.le_generate S.arrows) hS, le_rfl⟩ + le_l_u J _ S hS := ⟨S, J.superset_covering (Sieve.le_generate S.arrows) hS, le_rfl⟩ choice x _ := toGrothendieck C x choice_eq _ _ := rfl @@ -164,7 +164,7 @@ See -/ def trivial : Pretopology C where coverings X S := ∃ (Y : _) (f : Y ⟶ X) (_ : IsIso f), S = Presieve.singleton f - has_isos X Y f i := ⟨_, _, i, rfl⟩ + has_isos _ _ _ i := ⟨_, _, i, rfl⟩ pullbacks X Y f S := by rintro ⟨Z, g, i, rfl⟩ refine ⟨pullback g f, pullback.snd _ _, ?_, ?_⟩ diff --git a/Mathlib/CategoryTheory/Sites/Sheaf.lean b/Mathlib/CategoryTheory/Sites/Sheaf.lean index 80f0edcd7ebfbd..07e5279a343961 100644 --- a/Mathlib/CategoryTheory/Sites/Sheaf.lean +++ b/Mathlib/CategoryTheory/Sites/Sheaf.lean @@ -97,7 +97,7 @@ def conesEquivSieveCompatibleFamily : (S.arrows.diagram.op ⋙ P).cones.obj E ≃ { x : FamilyOfElements (P ⋙ coyoneda.obj E) (S : Presieve X) // x.SieveCompatible } where toFun π := - ⟨fun Y f h => π.app (op ⟨Over.mk f, h⟩), fun X Y f g hf => by + ⟨fun _ f h => π.app (op ⟨Over.mk f, h⟩), fun X Y f g hf => by apply (id_comp _).symm.trans dsimp exact π.naturality (Quiver.Hom.op (Over.homMk _ (by rfl)))⟩ @@ -109,8 +109,8 @@ def conesEquivSieveCompatibleFamily : rw [id_comp] convert rfl rw [Over.w] } - left_inv π := rfl - right_inv x := rfl + left_inv _ := rfl + right_inv _ := rfl -- These lemmas have always been bad (#7657), but leanprover/lean4#2644 made `simp` start noticing attribute [nolint simpNF] CategoryTheory.Presheaf.conesEquivSieveCompatibleFamily_apply_coe @@ -419,8 +419,8 @@ def sheafEquivSheafOfTypes : Sheaf J (Type w) ≌ SheafOfTypes J where inverse := { obj := fun S => ⟨S.val, (isSheaf_iff_isSheaf_of_type _ _).2 S.2⟩ map := fun f => ⟨f.val⟩ } - unitIso := NatIso.ofComponents fun X => Iso.refl _ - counitIso := NatIso.ofComponents fun X => Iso.refl _ + unitIso := NatIso.ofComponents fun _ => Iso.refl _ + counitIso := NatIso.ofComponents fun _ => Iso.refl _ instance : Inhabited (Sheaf (⊥ : GrothendieckTopology C) (Type w)) := ⟨(sheafEquivSheafOfTypes _).inverse.obj default⟩ @@ -481,7 +481,7 @@ instance Sheaf.Hom.addCommGroup : AddCommGroup (P ⟶ Q) := (fun _ _ => by aesop_cat) (fun _ _ => by aesop_cat) instance : Preadditive (Sheaf J A) where - homGroup P Q := Sheaf.Hom.addCommGroup + homGroup _ _ := Sheaf.Hom.addCommGroup end Preadditive @@ -515,7 +515,7 @@ section MultiequalizerConditions /-- 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 I => E.ι _) + lift := fun E : Multifork _ => hP.amalgamate S (fun _ => E.ι _) (fun _ _ r => E.condition ⟨_, _, r⟩) fac := by rintro (E : Multifork _) (a | b) diff --git a/Mathlib/CategoryTheory/Sites/SheafHom.lean b/Mathlib/CategoryTheory/Sites/SheafHom.lean index 196eeab7477ac3..d49a0a625c7ff4 100644 --- a/Mathlib/CategoryTheory/Sites/SheafHom.lean +++ b/Mathlib/CategoryTheory/Sites/SheafHom.lean @@ -84,7 +84,7 @@ def presheafHomSectionsEquiv : (presheafHom F G).sections ≃ (F ⟶ G) where (Over.homMk f : Over.mk f ⟶ Over.mk (𝟙 X₁)).op) rw [← s.2 f.op, presheafHom_map_app_op_mk_id] rfl } - invFun f := ⟨fun X => whiskerLeft _ f, fun _ => rfl⟩ + invFun f := ⟨fun _ => whiskerLeft _ f, fun _ => rfl⟩ left_inv s := by dsimp ext ⟨X⟩ ⟨Y : Over X⟩ @@ -92,7 +92,7 @@ def presheafHomSectionsEquiv : (presheafHom F G).sections ≃ (F ⟶ G) where dsimp at H ⊢ rw [← H] apply presheafHom_map_app_op_mk_id - right_inv f := rfl + right_inv _ := rfl variable {F G} diff --git a/Mathlib/CategoryTheory/Sites/Sieves.lean b/Mathlib/CategoryTheory/Sites/Sieves.lean index 172573aad92660..d974d994459f04 100644 --- a/Mathlib/CategoryTheory/Sites/Sieves.lean +++ b/Mathlib/CategoryTheory/Sites/Sieves.lean @@ -130,7 +130,7 @@ theorem ofArrows_pUnit : (ofArrows _ fun _ : PUnit => f) = singleton f := by exact ofArrows.mk PUnit.unit theorem ofArrows_pullback [HasPullbacks C] {ι : Type*} (Z : ι → C) (g : ∀ i : ι, Z i ⟶ X) : - (ofArrows (fun i => pullback (g i) f) fun i => pullback.snd _ _) = + (ofArrows (fun i => pullback (g i) f) fun _ => pullback.snd _ _) = pullbackArrows f (ofArrows Z g) := by funext T ext h @@ -144,7 +144,7 @@ theorem ofArrows_pullback [HasPullbacks C] {ι : Type*} (Z : ι → C) (g : ∀ theorem ofArrows_bind {ι : Type*} (Z : ι → C) (g : ∀ i : ι, Z i ⟶ X) (j : ∀ ⦃Y⦄ (f : Y ⟶ X), ofArrows Z g f → Type*) (W : ∀ ⦃Y⦄ (f : Y ⟶ X) (H), j f H → C) (k : ∀ ⦃Y⦄ (f : Y ⟶ X) (H i), W f H i ⟶ Y) : - ((ofArrows Z g).bind fun Y f H => ofArrows (W f H) (k f H)) = + ((ofArrows Z g).bind fun _ f H => ofArrows (W f H) (k f H)) = ofArrows (fun i : Σi, j _ (ofArrows.mk i) => W (g i.1) _ i.2) fun ij => k (g ij.1) _ ij.2 ≫ g ij.1 := by funext Y @@ -267,7 +267,7 @@ open Lattice /-- The supremum of a collection of sieves: the union of them all. -/ protected def sup (𝒮 : Set (Sieve X)) : Sieve X where - arrows Y := { f | ∃ S ∈ 𝒮, Sieve.arrows S f } + arrows _ := { f | ∃ S ∈ 𝒮, Sieve.arrows S f } downward_closed {_ _ f} hf _ := by obtain ⟨S, hS, hf⟩ := hf exact ⟨S, hS, S.downward_closed hf _⟩ @@ -279,12 +279,12 @@ protected def inf (𝒮 : Set (Sieve X)) : Sieve X where /-- The union of two sieves is a sieve. -/ protected def union (S R : Sieve X) : Sieve X where - arrows Y f := S f ∨ R f + arrows _ f := S f ∨ R f downward_closed := by rintro _ _ _ (h | h) g <;> simp [h] /-- The intersection of two sieves is a sieve. -/ protected def inter (S R : Sieve X) : Sieve X where - arrows Y f := S f ∧ R f + arrows _ f := S f ∧ R f downward_closed := by rintro _ _ _ ⟨h₁, h₂⟩ g simp [h₁, h₂] @@ -294,9 +294,9 @@ We generate this directly rather than using the galois insertion for nicer defin -/ instance : CompleteLattice (Sieve X) where le S R := ∀ ⦃Y⦄ (f : Y ⟶ X), S f → R f - le_refl S f q := id - le_trans S₁ S₂ S₃ S₁₂ S₂₃ Y f h := S₂₃ _ (S₁₂ _ h) - le_antisymm S R p q := Sieve.ext fun Y f => ⟨p _, q _⟩ + le_refl _ _ _ := id + le_trans _ _ _ S₁₂ S₂₃ _ _ h := S₂₃ _ (S₁₂ _ h) + le_antisymm _ _ p q := Sieve.ext fun _ _ => ⟨p _, q _⟩ top := { arrows := fun _ => Set.univ downward_closed := fun _ _ => ⟨⟩ } @@ -307,8 +307,8 @@ instance : CompleteLattice (Sieve X) where inf := Sieve.inter sSup := Sieve.sup sInf := Sieve.inf - le_sSup 𝒮 S hS Y f hf := ⟨S, hS, hf⟩ - sSup_le := fun s a ha Y f ⟨b, hb, hf⟩ => (ha b hb) _ hf + le_sSup _ S hS _ _ hf := ⟨S, hS, hf⟩ + sSup_le := fun _ _ ha _ _ ⟨b, hb, hf⟩ => (ha b hb) _ hf sInf_le _ _ hS _ _ h := h _ hS le_sInf _ _ hS _ _ hf _ hR := hS _ hR _ hf le_sup_left _ _ _ _ := Or.inl @@ -362,7 +362,7 @@ produce a sieve on `X`. -/ @[simps] def bind (S : Presieve X) (R : ∀ ⦃Y⦄ ⦃f : Y ⟶ X⦄, S f → Sieve Y) : Sieve X where - arrows := S.bind fun Y f h => R h + arrows := S.bind fun _ _ h => R h downward_closed := by rintro Y Z f ⟨W, f, h, hh, hf, rfl⟩ g exact ⟨_, g ≫ f, _, hh, by simp [hf]⟩ @@ -370,7 +370,7 @@ def bind (S : Presieve X) (R : ∀ ⦃Y⦄ ⦃f : Y ⟶ X⦄, S f → Sieve Y) : open Order Lattice theorem generate_le_iff (R : Presieve X) (S : Sieve X) : generate R ≤ S ↔ R ≤ S := - ⟨fun H Y g hg => H _ ⟨_, 𝟙 _, _, hg, id_comp _⟩, fun ss Y f => by + ⟨fun H _ _ hg => H _ ⟨_, 𝟙 _, _, hg, id_comp _⟩, fun ss Y f => by rintro ⟨Z, f, g, hg, rfl⟩ exact S.downward_closed (ss Z hg) f⟩ @@ -470,7 +470,7 @@ lemma ofArrows_eq_ofObjects {X : C} (hX : IsTerminal X) That is, `Sieve.pullback S h := (≫ h) '⁻¹ S`. -/ @[simps] def pullback (h : Y ⟶ X) (S : Sieve X) : Sieve Y where - arrows Y sl := S (sl ≫ h) + arrows _ sl := S (sl ≫ h) downward_closed g := by simp [g] @[simp] @@ -506,7 +506,7 @@ factors through some `g : Z ⟶ Y` which is in `R`. -/ @[simps] def pushforward (f : Y ⟶ X) (R : Sieve Y) : Sieve X where - arrows Z gf := ∃ g, g ≫ f = gf ∧ R g + arrows _ gf := ∃ g, g ≫ f = gf ∧ R g downward_closed := fun ⟨j, k, z⟩ h => ⟨h ≫ j, by simp [k], by simp [z]⟩ theorem pushforward_apply_comp {R : Sieve Y} {Z : C} {g : Z ⟶ Y} (hg : R g) (f : Y ⟶ X) : @@ -767,11 +767,11 @@ def functor (S : Sieve X) : Cᵒᵖ ⥤ Type v₁ where presheaves. -/ @[simps] -def natTransOfLe {S T : Sieve X} (h : S ≤ T) : S.functor ⟶ T.functor where app Y f := ⟨f.1, h _ f.2⟩ +def natTransOfLe {S T : Sieve X} (h : S ≤ T) : S.functor ⟶ T.functor where app _ f := ⟨f.1, h _ f.2⟩ /-- The natural inclusion from the functor induced by a sieve to the yoneda embedding. -/ @[simps] -def functorInclusion (S : Sieve X) : S.functor ⟶ yoneda.obj X where app Y f := f.1 +def functorInclusion (S : Sieve X) : S.functor ⟶ yoneda.obj X where app _ f := f.1 theorem natTransOfLe_comm {S T : Sieve X} (h : S ≤ T) : natTransOfLe h ≫ functorInclusion _ = functorInclusion _ := @@ -806,7 +806,7 @@ theorem sieveOfSubfunctor_functorInclusion : sieveOfSubfunctor S.functorInclusio exact ⟨⟨_, hf⟩, rfl⟩ instance functorInclusion_top_isIso : IsIso (⊤ : Sieve X).functorInclusion := - ⟨⟨{ app := fun Y a => ⟨a, ⟨⟩⟩ }, rfl, rfl⟩⟩ + ⟨⟨{ app := fun _ a => ⟨a, ⟨⟩⟩ }, rfl, rfl⟩⟩ end Sieve diff --git a/Mathlib/CategoryTheory/Sites/Spaces.lean b/Mathlib/CategoryTheory/Sites/Spaces.lean index d5faa18723e48b..c85c6bdae24c93 100644 --- a/Mathlib/CategoryTheory/Sites/Spaces.lean +++ b/Mathlib/CategoryTheory/Sites/Spaces.lean @@ -43,7 +43,7 @@ open CategoryTheory TopologicalSpace CategoryTheory.Limits /-- The Grothendieck topology associated to a topological space. -/ def grothendieckTopology : GrothendieckTopology (Opens T) where sieves X S := ∀ x ∈ X, ∃ (U : _) (f : U ⟶ X), S f ∧ x ∈ U - top_mem' X x hx := ⟨_, 𝟙 _, trivial, hx⟩ + top_mem' _ _ hx := ⟨_, 𝟙 _, trivial, hx⟩ pullback_stable' X Y S f hf y hy := by rcases hf y (f.le hy) with ⟨U, g, hg, hU⟩ refine ⟨U ⊓ Y, homOfLE inf_le_right, ?_, hU, hy⟩ @@ -56,7 +56,7 @@ def grothendieckTopology : GrothendieckTopology (Opens T) where /-- 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 - has_isos X Y f i x hx := ⟨_, _, Presieve.singleton_self _, (inv f).le hx⟩ + has_isos _ _ f _ _ hx := ⟨_, _, Presieve.singleton_self _, (inv f).le hx⟩ pullbacks X Y f S hS x hx := by rcases hS _ (f.le hx) with ⟨U, g, hg, hU⟩ refine ⟨_, _, Presieve.pullbackArrows.mk _ _ hg, ?_⟩ diff --git a/Mathlib/CategoryTheory/Sites/Subsheaf.lean b/Mathlib/CategoryTheory/Sites/Subsheaf.lean index 198726f465d9b6..be30cc3fa8ebc1 100644 --- a/Mathlib/CategoryTheory/Sites/Subsheaf.lean +++ b/Mathlib/CategoryTheory/Sites/Subsheaf.lean @@ -57,7 +57,7 @@ instance : PartialOrder (Subpresheaf F) := PartialOrder.lift Subpresheaf.obj (fun _ _ => Subpresheaf.ext) instance : Top (Subpresheaf F) := - ⟨⟨fun U => ⊤, @fun U V _ x _ => by aesop_cat⟩⟩ + ⟨⟨fun _ => ⊤, @fun U _ _ x _ => by aesop_cat⟩⟩ instance : Nonempty (Subpresheaf F) := inferInstance @@ -66,7 +66,7 @@ instance : Nonempty (Subpresheaf F) := @[simps!] def Subpresheaf.toPresheaf : Cᵒᵖ ⥤ Type w where obj U := G.obj U - map := @fun U V i x => ⟨F.map i x, G.map i x.prop⟩ + map := @fun _ _ i x => ⟨F.map i x, G.map i x.prop⟩ map_id X := by ext ⟨x, _⟩ dsimp @@ -81,7 +81,7 @@ instance {U} : CoeHead (G.toPresheaf.obj U) (F.obj U) where /-- The inclusion of a subpresheaf to the original presheaf. -/ @[simps] -def Subpresheaf.ι : G.toPresheaf ⟶ F where app U x := x +def Subpresheaf.ι : G.toPresheaf ⟶ F where app _ x := x instance : Mono G.ι := ⟨@fun _ _ _ e => @@ -255,7 +255,7 @@ theorem Subpresheaf.sheafify_sheafify (h : Presieve.IsSheaf J F) : /-- The lift of a presheaf morphism onto the sheafification subpresheaf. -/ noncomputable def Subpresheaf.sheafifyLift (f : G.toPresheaf ⟶ F') (h : Presieve.IsSheaf J F') : (G.sheafify J).toPresheaf ⟶ F' where - app U s := (h (G.sieveOfSection s.1) s.prop).amalgamate + app _ s := (h (G.sieveOfSection s.1) s.prop).amalgamate (_) ((G.family_of_elements_compatible s.1).compPresheafMap f) naturality := by intro U V i diff --git a/Mathlib/CategoryTheory/Sites/Types.lean b/Mathlib/CategoryTheory/Sites/Types.lean index fca7e5d9739866..b1ba30f51c8e27 100644 --- a/Mathlib/CategoryTheory/Sites/Types.lean +++ b/Mathlib/CategoryTheory/Sites/Types.lean @@ -48,7 +48,7 @@ theorem generate_discretePresieve_mem (α : Type u) : open Presieve theorem isSheaf_yoneda' {α : Type u} : IsSheaf typesGrothendieckTopology (yoneda.obj α) := - fun β S hs x hx => + fun β _ hs x hx => ⟨fun y => x _ (hs y) PUnit.unit, fun γ f h => funext fun z => by convert congr_fun (hx (𝟙 _) (fun _ => z) (hs <| f z) h rfl) PUnit.unit using 1, @@ -76,7 +76,7 @@ def eval (P : Type uᵒᵖ ⥤ Type u) (α : Type u) (s : P.obj (op α)) (x : α noncomputable def typesGlue (S : Type uᵒᵖ ⥤ Type u) (hs : IsSheaf typesGrothendieckTopology S) (α : Type u) (f : α → S.obj (op PUnit)) : S.obj (op α) := (hs.isSheafFor _ _ (generate_discretePresieve_mem α)).amalgamate - (fun β g hg => S.map (↾fun _ => PUnit.unit).op <| f <| g <| Classical.choose hg) + (fun _ g hg => S.map (↾fun _ => PUnit.unit).op <| f <| g <| Classical.choose hg) fun β γ δ g₁ g₂ f₁ f₂ hf₁ hf₂ h => (hs.isSheafFor _ _ (generate_discretePresieve_mem δ)).isSeparatedFor.ext fun ε g ⟨x, _⟩ => by have : f₁ (Classical.choose hf₁) = f₂ (Classical.choose hf₂) := diff --git a/Mathlib/CategoryTheory/Sites/Whiskering.lean b/Mathlib/CategoryTheory/Sites/Whiskering.lean index 17685ddf1e50ac..5f9c74a7af9c3a 100644 --- a/Mathlib/CategoryTheory/Sites/Whiskering.lean +++ b/Mathlib/CategoryTheory/Sites/Whiskering.lean @@ -75,7 +75,7 @@ If `η : F ⟶ G` is a natural transformation then we obtain a morphism of funct `sheafCompose J F ⟶ sheafCompose J G` by whiskering with `η` on the level of presheaves. -/ def sheafCompose_map : sheafCompose J F ⟶ sheafCompose J G where - app := fun X => .mk <| whiskerLeft _ η + app := fun _ => .mk <| whiskerLeft _ η @[simp] lemma sheafCompose_id : sheafCompose_map (F := F) J (𝟙 _) = 𝟙 _ := rfl @@ -97,8 +97,8 @@ def multicospanComp : (S.index (P ⋙ F)).multicospan ≅ (S.index P).multicospa NatIso.ofComponents (fun t => match t with - | WalkingMulticospan.left a => Iso.refl _ - | WalkingMulticospan.right b => Iso.refl _) + | WalkingMulticospan.left _ => Iso.refl _ + | WalkingMulticospan.right _ => Iso.refl _) (by rintro (a | b) (a | b) (f | f | f) all_goals aesop_cat) diff --git a/Mathlib/CategoryTheory/Skeletal.lean b/Mathlib/CategoryTheory/Skeletal.lean index af988c24022a57..5bc475b8043428 100644 --- a/Mathlib/CategoryTheory/Skeletal.lean +++ b/Mathlib/CategoryTheory/Skeletal.lean @@ -144,7 +144,7 @@ instance ThinSkeleton.preorder : Preorder (ThinSkeleton C) where le_refl := by refine Quotient.ind fun a => ?_ exact ⟨𝟙 _⟩ - le_trans a b c := Quotient.inductionOn₃ a b c fun A B C => Nonempty.map2 (· ≫ ·) + le_trans a b c := Quotient.inductionOn₃ a b c fun _ _ _ => Nonempty.map2 (· ≫ ·) /-- The functor from a category to its thin skeleton. -/ @[simps] @@ -171,8 +171,8 @@ variable {C} {D} /-- A functor `C ⥤ D` computably lowers to a functor `ThinSkeleton C ⥤ ThinSkeleton D`. -/ @[simps] def map (F : C ⥤ D) : ThinSkeleton C ⥤ ThinSkeleton D where - obj := Quotient.map F.obj fun X₁ X₂ ⟨hX⟩ => ⟨F.mapIso hX⟩ - map {X} {Y} := Quotient.recOnSubsingleton₂ X Y fun x y k => homOfLE (k.le.elim fun t => ⟨F.map t⟩) + obj := Quotient.map F.obj fun _ _ ⟨hX⟩ => ⟨F.mapIso hX⟩ + map {X} {Y} := Quotient.recOnSubsingleton₂ X Y fun _ _ k => homOfLE (k.le.elim fun t => ⟨F.map t⟩) theorem comp_toThinSkeleton (F : C ⥤ D) : F ⋙ toThinSkeleton D = toThinSkeleton C ⋙ map F := rfl @@ -205,7 +205,7 @@ def map₂Functor (F : C ⥤ D ⥤ E) : ThinSkeleton C → ThinSkeleton D ⥤ Th { obj := fun y => map₂ObjMap F x y map := fun {y₁} {y₂} => @Quotient.recOnSubsingleton C (isIsomorphicSetoid C) (fun x => (y₁ ⟶ y₂) → (map₂ObjMap F x y₁ ⟶ map₂ObjMap F x y₂)) _ x fun X - => Quotient.recOnSubsingleton₂ y₁ y₂ fun Y₁ Y₂ hY => + => Quotient.recOnSubsingleton₂ y₁ y₂ fun _ _ hY => homOfLE (hY.le.elim fun g => ⟨(F.obj X).map g⟩) } /-- This provides natural transformations `map₂Functor F x₁ ⟶ map₂Functor F x₂` given @@ -270,11 +270,11 @@ theorem skeletal : Skeletal (ThinSkeleton C) := fun X Y => theorem map_comp_eq (F : E ⥤ D) (G : D ⥤ C) : map (F ⋙ G) = map F ⋙ map G := Functor.eq_of_iso skeletal <| - NatIso.ofComponents fun X => Quotient.recOnSubsingleton X fun x => Iso.refl _ + NatIso.ofComponents fun X => Quotient.recOnSubsingleton X fun _ => Iso.refl _ theorem map_id_eq : map (𝟭 C) = 𝟭 (ThinSkeleton C) := Functor.eq_of_iso skeletal <| - NatIso.ofComponents fun X => Quotient.recOnSubsingleton X fun x => Iso.refl _ + NatIso.ofComponents fun X => Quotient.recOnSubsingleton X fun _ => Iso.refl _ theorem map_iso_eq {F₁ F₂ : D ⥤ C} (h : F₁ ≅ F₂) : map F₁ = map F₂ := Functor.eq_of_iso skeletal diff --git a/Mathlib/CategoryTheory/Subobject/Comma.lean b/Mathlib/CategoryTheory/Subobject/Comma.lean index 790b33bdc54e10..222e8506745502 100644 --- a/Mathlib/CategoryTheory/Subobject/Comma.lean +++ b/Mathlib/CategoryTheory/Subobject/Comma.lean @@ -94,7 +94,7 @@ def subobjectEquiv [HasLimits C] [PreservesLimits T] (A : StructuredArrow S T) : Subobject A ≃o { P : Subobject A.right // ∃ q, q ≫ T.map P.arrow = A.hom } where toFun P := ⟨projectSubobject P, projectSubobject_factors P⟩ invFun P := liftSubobject P.val P.prop.choose_spec - left_inv P := lift_projectSubobject _ _ + left_inv _ := lift_projectSubobject _ _ right_inv P := Subtype.ext (by simp only [liftSubobject, homMk_right, projectSubobject_mk, Subobject.mk_arrow, Subtype.coe_eta]) map_rel_iff' := by @@ -199,7 +199,7 @@ def quotientEquiv [HasColimits C] [PreservesColimits S] (A : CostructuredArrow S Subobject (op A) ≃o { P : Subobject (op A.left) // ∃ q, S.map P.arrow.unop ≫ q = A.hom } where toFun P := ⟨projectQuotient P, projectQuotient_factors P⟩ invFun P := liftQuotient P.val P.prop.choose_spec - left_inv P := lift_projectQuotient _ _ + left_inv _ := lift_projectQuotient _ _ right_inv P := Subtype.ext (by simp only [liftQuotient, Quiver.Hom.unop_op, homMk_left, Quiver.Hom.op_unop, projectQuotient_mk, Subobject.mk_arrow]) map_rel_iff' := by diff --git a/Mathlib/CategoryTheory/Subobject/Limits.lean b/Mathlib/CategoryTheory/Subobject/Limits.lean index 26f73bd07b7d26..32719bd80347cc 100644 --- a/Mathlib/CategoryTheory/Subobject/Limits.lean +++ b/Mathlib/CategoryTheory/Subobject/Limits.lean @@ -212,7 +212,7 @@ instance kernelSubobject_comp_mono_isIso (f : X ⟶ Y) [HasKernel f] {Z : C} (h @[simps] def cokernelOrderHom [HasCokernels C] (X : C) : Subobject X →o (Subobject (op X))ᵒᵈ where toFun := - Subobject.lift (fun A f _ => Subobject.mk (cokernel.π f).op) + Subobject.lift (fun _ f _ => Subobject.mk (cokernel.π f).op) (by rintro A B f g hf hg i rfl refine Subobject.mk_eq_mk_of_comm _ _ (Iso.op ?_) (Quiver.Hom.unop_inj ?_) @@ -234,7 +234,7 @@ def cokernelOrderHom [HasCokernels C] (X : C) : Subobject X →o (Subobject (op @[simps] def kernelOrderHom [HasKernels C] (X : C) : (Subobject (op X))ᵒᵈ →o Subobject X where toFun := - Subobject.lift (fun A f _ => Subobject.mk (kernel.ι f.unop)) + Subobject.lift (fun _ f _ => Subobject.mk (kernel.ι f.unop)) (by rintro A B f g hf hg i rfl refine Subobject.mk_eq_mk_of_comm _ _ ?_ ?_ diff --git a/Mathlib/CategoryTheory/Subobject/MonoOver.lean b/Mathlib/CategoryTheory/Subobject/MonoOver.lean index e2cfc4d68b3304..85e334fd857b69 100644 --- a/Mathlib/CategoryTheory/Subobject/MonoOver.lean +++ b/Mathlib/CategoryTheory/Subobject/MonoOver.lean @@ -355,7 +355,7 @@ def imageForgetAdj : image ⊣ forget X := e := k.left fac := Over.w k } · apply image.lift_fac - left_inv := fun k => Subsingleton.elim _ _ + left_inv := fun _ => Subsingleton.elim _ _ right_inv := fun k => by ext1 change factorThruImage _ ≫ image.lift _ = _ diff --git a/Mathlib/CategoryTheory/Subobject/Types.lean b/Mathlib/CategoryTheory/Subobject/Types.lean index cb2e06f94b8b17..9cc556ebe11f3d 100644 --- a/Mathlib/CategoryTheory/Subobject/Types.lean +++ b/Mathlib/CategoryTheory/Subobject/Types.lean @@ -50,7 +50,7 @@ noncomputable def Types.monoOverEquivalenceSet (α : Type u) : MonoOver α ≌ S unitIso := NatIso.ofComponents fun f => MonoOver.isoMk (Equiv.ofInjective f.1.hom ((mono_iff_injective _).mp f.2)).toIso - counitIso := NatIso.ofComponents fun s => eqToIso Subtype.range_val + counitIso := NatIso.ofComponents fun _ => eqToIso Subtype.range_val instance : WellPowered (Type u) := wellPowered_of_essentiallySmall_monoOver fun α => diff --git a/Mathlib/CategoryTheory/Subterminal.lean b/Mathlib/CategoryTheory/Subterminal.lean index d4eee3243382b2..3c93a95c72ddc5 100644 --- a/Mathlib/CategoryTheory/Subterminal.lean +++ b/Mathlib/CategoryTheory/Subterminal.lean @@ -142,16 +142,16 @@ def subterminalsEquivMonoOverTerminal [HasTerminal C] : Subterminals C ≌ MonoO functor := { obj := fun X => ⟨Over.mk (terminal.from X.1), X.2.mono_terminal_from⟩ map := fun f => MonoOver.homMk f (by ext1 ⟨⟨⟩⟩) - map_id := fun X => rfl - map_comp := fun f g => rfl } + map_id := fun _ => rfl + map_comp := fun _ _ => rfl } inverse := { obj := fun X => ⟨X.obj.left, fun Z f g => by rw [← cancel_mono X.arrow] subsingleton⟩ map := fun f => f.1 - map_id := fun X => rfl - map_comp := fun f g => rfl } + map_id := fun _ => rfl + map_comp := fun _ _ => rfl } -- Porting note: the original definition was triggering a timeout, using `NatIso.ofComponents` -- in the definition of the natural isomorphisms makes the situation slightly better unitIso := NatIso.ofComponents (fun X => Iso.refl X) (by subsingleton) diff --git a/Mathlib/CategoryTheory/Sums/Basic.lean b/Mathlib/CategoryTheory/Sums/Basic.lean index 51c5a75bafa707..661d3f9c715c1f 100644 --- a/Mathlib/CategoryTheory/Sums/Basic.lean +++ b/Mathlib/CategoryTheory/Sums/Basic.lean @@ -48,12 +48,12 @@ instance sum : Category.{v₁} (C ⊕ D) where | inr X => 𝟙 X comp {X Y Z} f g := match X, Y, Z, f, g with - | inl X, inl Y, inl Z, f, g => f ≫ g - | inr X, inr Y, inr Z, f, g => f ≫ g + | inl _, inl _, inl _, f, g => f ≫ g + | inr _, inr _, inr _, f, g => f ≫ g assoc {W X Y Z} f g h := match X, Y, Z, W with - | inl X, inl Y, inl Z, inl W => Category.assoc f g h - | inr X, inr Y, inr Z, inr W => Category.assoc f g h + | inl _, inl _, inl _, inl _ => Category.assoc f g h + | inr _, inr _, inr _, inr _ => Category.assoc f g h @[aesop norm -10 destruct (rule_sets := [CategoryTheory])] theorem hom_inl_inr_false {X : C} {Y : D} (f : Sum.inl X ⟶ Sum.inr Y) : False := by @@ -84,13 +84,13 @@ variable (C : Type u₁) [Category.{v₁} C] (D : Type u₁) [Category.{v₁} D] @[simps] def inl_ : C ⥤ C ⊕ D where obj X := inl X - map {X Y} f := f + map {_ _} f := f /-- `inr_` is the functor `X ↦ inr X`. -/ @[simps] def inr_ : D ⥤ C ⊕ D where obj X := inr X - map {X Y} f := f + map {_ _} f := f /- Porting note: `aesop_cat` not firing on `map_comp` where autotac in Lean 3 did but `map_id` was ok. -/ @@ -160,8 +160,8 @@ def sum (F : A ⥤ B) (G : C ⥤ D) : A ⊕ C ⥤ B ⊕ D where | inr X => inr (G.obj X) map {X Y} f := match X, Y, f with - | inl X, inl Y, f => F.map f - | inr X, inr Y, f => G.map f + | inl _, inl _, f => F.map f + | inr _, inr _, f => G.map f map_id {X} := by cases X <;> (erw [Functor.map_id]; rfl) map_comp {X Y Z} f g := match X, Y, Z, f, g with @@ -187,12 +187,12 @@ def sum' (F : A ⥤ C) (G : B ⥤ C) : A ⊕ B ⥤ C where /-- The sum `F.sum' G` precomposed with the left inclusion functor is isomorphic to `F` -/ @[simps!] def inlCompSum' (F : A ⥤ C) (G : B ⥤ C) : Sum.inl_ A B ⋙ F.sum' G ≅ F := - NatIso.ofComponents fun X => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ /-- The sum `F.sum' G` precomposed with the right inclusion functor is isomorphic to `G` -/ @[simps!] def inrCompSum' (F : A ⥤ C) (G : B ⥤ C) : Sum.inr_ A B ⋙ F.sum' G ≅ G := - NatIso.ofComponents fun X => Iso.refl _ + NatIso.ofComponents fun _ => Iso.refl _ @[simp] theorem sum_obj_inl (F : A ⥤ B) (G : C ⥤ D) (a : A) : (F.sum G).obj (inl a) = inl (F.obj a) := diff --git a/Mathlib/CategoryTheory/Types.lean b/Mathlib/CategoryTheory/Types.lean index b2b29e06f39d9d..a084aa296a6af6 100644 --- a/Mathlib/CategoryTheory/Types.lean +++ b/Mathlib/CategoryTheory/Types.lean @@ -41,7 +41,7 @@ universe v v' w u u' @[to_additive existing CategoryTheory.types] instance types : LargeCategory (Type u) where Hom a b := a → b - id a := id + id _ := id comp f g := g ∘ f theorem types_hom {α β : Type u} : (α ⟶ β) = (α → β) := @@ -191,7 +191,7 @@ Write this as `uliftFunctor.{5, 2}` to get `Type 2 ⥤ Type 5`. @[pp_with_univ] def uliftFunctor : Type u ⥤ Type max u v where obj X := ULift.{v} X - map {X} {Y} f := fun x : ULift.{v} X => ULift.up (f x.down) + map {X} {_} f := fun x : ULift.{v} X => ULift.up (f x.down) @[simp] theorem uliftFunctor_obj {X : Type u} : uliftFunctor.obj.{v} X = ULift.{v} X := @@ -264,7 +264,7 @@ def ofTypeFunctor (m : Type u → Type v) [_root_.Functor m] [LawfulFunctor m] : map_id := fun α => by funext X; apply id_map /- Porting note: original proof is via `fun α => _root_.Functor.map_id` but I cannot get Lean to find this. Reproduced its original proof -/ - map_comp f g := funext fun a => LawfulFunctor.comp_map f g _ + map_comp f g := funext fun _ => LawfulFunctor.comp_map f g _ variable (m : Type u → Type v) [_root_.Functor m] [LawfulFunctor m] diff --git a/Mathlib/CategoryTheory/Widesubcategory.lean b/Mathlib/CategoryTheory/Widesubcategory.lean index e225caffbde77f..ae12360cb74f5d 100644 --- a/Mathlib/CategoryTheory/Widesubcategory.lean +++ b/Mathlib/CategoryTheory/Widesubcategory.lean @@ -55,13 +55,13 @@ instance InducedWideCategory.category : Category (InducedWideCategory D F P) where Hom X Y := {f : F X ⟶ F Y | P f} id X := ⟨𝟙 (F X), P.id_mem (F X)⟩ - comp {X Y Z} f g := ⟨f.1 ≫ g.1, P.comp_mem _ _ f.2 g.2⟩ + comp {_ _ _} f g := ⟨f.1 ≫ g.1, P.comp_mem _ _ f.2 g.2⟩ /-- The forgetful functor from an induced wide category to the original category. -/ @[simps] def wideInducedFunctor : InducedWideCategory D F P ⥤ D where obj := F - map {X Y} f := f.1 + map {_ _} f := f.1 /-- The induced functor `wideInducedFunctor F P : InducedWideCategory D F P ⥤ D` is faithful. -/ diff --git a/Mathlib/CategoryTheory/WithTerminal.lean b/Mathlib/CategoryTheory/WithTerminal.lean index 3c35d0efb590eb..3ac83acd3454e3 100644 --- a/Mathlib/CategoryTheory/WithTerminal.lean +++ b/Mathlib/CategoryTheory/WithTerminal.lean @@ -91,7 +91,7 @@ attribute [nolint simpNF] comp.eq_4 instance : Category.{v} (WithTerminal C) where Hom X Y := Hom X Y - id X := id _ + id _ := id _ comp := comp assoc {a b c d} f g h := by -- Porting note: it would be nice to automate this away as well. @@ -133,7 +133,7 @@ def map {D : Type*} [Category D] (F : C ⥤ D) : WithTerminal C ⥤ WithTerminal | star => star map {X Y} f := match X, Y, f with - | of x, of y, f => F.map (down f) + | of _, of _, f => F.map (down f) | of _, star, _ => PUnit.unit | star, star, _ => PUnit.unit @@ -141,7 +141,7 @@ def map {D : Type*} [Category D] (F : C ⥤ D) : WithTerminal C ⥤ WithTerminal @[simps!] def mapId (C : Type*) [Category C] : map (𝟭 C) ≅ 𝟭 (WithTerminal C) := NatIso.ofComponents (fun X => match X with - | of x => Iso.refl _ + | of _ => Iso.refl _ | star => Iso.refl _) (by aesop_cat) /-- A natural isomorphism between the functor `map (F ⋙ G) ` and `map F ⋙ map G `. -/ @@ -149,7 +149,7 @@ def mapId (C : Type*) [Category C] : map (𝟭 C) ≅ 𝟭 (WithTerminal C) := def mapComp {D E : Type*} [Category D] [Category E] (F : C ⥤ D) (G : D ⥤ E) : map (F ⋙ G) ≅ map F ⋙ map G := NatIso.ofComponents (fun X => match X with - | of x => Iso.refl _ + | of _ => Iso.refl _ | star => Iso.refl _) (by aesop_cat) /-- From a natural transformation of functors `C ⥤ D`, the induced natural transformation @@ -285,7 +285,7 @@ def lift {D : Type*} [Category D] {Z : D} (F : C ⥤ D) (M : ∀ x : C, F.obj x | star => Z map {X Y} f := match X, Y, f with - | of x, of y, f => F.map (down f) + | of _, of _, f => F.map (down f) | of x, star, _ => M x | star, star, _ => 𝟙 Z @@ -293,8 +293,8 @@ def lift {D : Type*} [Category D] {Z : D} (F : C ⥤ D) (M : ∀ x : C, F.obj x @[simps!] def inclLift {D : Type*} [Category D] {Z : D} (F : C ⥤ D) (M : ∀ x : C, F.obj x ⟶ Z) (hM : ∀ (x y : C) (f : x ⟶ y), F.map f ≫ M y = M x) : incl ⋙ lift F M hM ≅ F where - hom := { app := fun X => 𝟙 _ } - inv := { app := fun X => 𝟙 _ } + hom := { app := fun _ => 𝟙 _ } + inv := { app := fun _ => 𝟙 _ } /-- The isomorphism between `(lift F _ _).obj WithTerminal.star` with `Z`. -/ @[simps!] @@ -435,7 +435,7 @@ def map {D : Type*} [Category D] (F : C ⥤ D) : WithInitial C ⥤ WithInitial D | star => star map {X Y} f := match X, Y, f with - | of x, of y, f => F.map (down f) + | of _, of _, f => F.map (down f) | star, of _, _ => PUnit.unit | star, star, _ => PUnit.unit @@ -443,7 +443,7 @@ def map {D : Type*} [Category D] (F : C ⥤ D) : WithInitial C ⥤ WithInitial D @[simps!] def mapId (C : Type*) [Category C] : map (𝟭 C) ≅ 𝟭 (WithInitial C) := NatIso.ofComponents (fun X => match X with - | of x => Iso.refl _ + | of _ => Iso.refl _ | star => Iso.refl _) (by aesop_cat) /-- A natural isomorphism between the functor `map (F ⋙ G) ` and `map F ⋙ map G `. -/ @@ -451,7 +451,7 @@ def mapId (C : Type*) [Category C] : map (𝟭 C) ≅ 𝟭 (WithInitial C) := def mapComp {D E : Type*} [Category D] [Category E] (F : C ⥤ D) (G : D ⥤ E) : map (F ⋙ G) ≅ map F ⋙ map G := NatIso.ofComponents (fun X => match X with - | of x => Iso.refl _ + | of _ => Iso.refl _ | star => Iso.refl _) (by aesop_cat) /-- From a natural transformation of functors `C ⥤ D`, the induced natural transformation @@ -583,16 +583,16 @@ def lift {D : Type*} [Category D] {Z : D} (F : C ⥤ D) (M : ∀ x : C, Z ⟶ F. | star => Z map {X Y} f := match X, Y, f with - | of x, of y, f => F.map (down f) - | star, of x, _ => M _ + | of _, of _, f => F.map (down f) + | star, of _, _ => M _ | star, star, _ => 𝟙 _ /-- The isomorphism between `incl ⋙ lift F _ _` with `F`. -/ @[simps!] def inclLift {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) : incl ⋙ lift F M hM ≅ F where - hom := { app := fun X => 𝟙 _ } - inv := { app := fun X => 𝟙 _ } + hom := { app := fun _ => 𝟙 _ } + inv := { app := fun _ => 𝟙 _ } /-- The isomorphism between `(lift F _ _).obj WithInitial.star` with `Z`. -/ @[simps!] diff --git a/Mathlib/CategoryTheory/Yoneda.lean b/Mathlib/CategoryTheory/Yoneda.lean index f06afc7170c1c1..d056292dbff450 100644 --- a/Mathlib/CategoryTheory/Yoneda.lean +++ b/Mathlib/CategoryTheory/Yoneda.lean @@ -39,7 +39,7 @@ def yoneda : C ⥤ Cᵒᵖ ⥤ Type v₁ where { obj := fun Y => unop Y ⟶ X map := fun f g => f.unop ≫ g } map f := - { app := fun Y g => g ≫ f } + { app := fun _ g => g ≫ f } /-- The co-Yoneda embedding, as a functor from `Cᵒᵖ` into co-presheaves on `C`. -/ @@ -49,7 +49,7 @@ def coyoneda : Cᵒᵖ ⥤ C ⥤ Type v₁ where { obj := fun Y => unop X ⟶ Y map := fun f g => g ≫ f } map f := - { app := fun Y g => f.unop ≫ g } + { app := fun _ g => f.unop ≫ g } namespace Yoneda @@ -399,7 +399,7 @@ and elements of `F.obj X`, without any universe switching. -/ 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 Y f ↦ F.map f.op ξ } + invFun ξ := { app := fun _ f ↦ F.map f.op ξ } left_inv := by intro η ext Y f @@ -506,7 +506,7 @@ def yonedaCompUliftFunctorEquiv (F : Cᵒᵖ ⥤ Type max v₁ w) (X : C) : (yoneda.obj X ⋙ uliftFunctor ⟶ F) ≃ F.obj (op X) where toFun φ := φ.app (op X) (ULift.up (𝟙 _)) invFun f := - { app := fun Y x => F.map (ULift.down x).op f } + { app := fun _ x => F.map (ULift.down x).op f } left_inv φ := by ext Y f dsimp @@ -524,7 +524,7 @@ See . -/ def yonedaLemma : yonedaPairing C ≅ yonedaEvaluation C := NatIso.ofComponents - (fun X ↦ Equiv.toIso (yonedaEquiv.trans Equiv.ulift.symm)) + (fun _ ↦ Equiv.toIso (yonedaEquiv.trans Equiv.ulift.symm)) (by intro (X, F) (Y, G) f ext (a : yoneda.obj X.unop ⟶ F) apply ULift.ext @@ -539,7 +539,7 @@ variable {C} /-- The curried version of yoneda lemma when `C` is small. -/ def curriedYonedaLemma {C : Type u₁} [SmallCategory C] : (yoneda.op ⋙ coyoneda : Cᵒᵖ ⥤ (Cᵒᵖ ⥤ Type u₁) ⥤ Type u₁) ≅ evaluation Cᵒᵖ (Type u₁) := - NatIso.ofComponents (fun X ↦ NatIso.ofComponents (fun F ↦ Equiv.toIso yonedaEquiv)) (by + NatIso.ofComponents (fun X ↦ NatIso.ofComponents (fun _ ↦ Equiv.toIso yonedaEquiv)) (by intro X Y f ext a b dsimp [yonedaEquiv] @@ -551,7 +551,7 @@ def largeCurriedYonedaLemma {C : Type u₁} [Category.{v₁} C] : evaluation Cᵒᵖ (Type v₁) ⋙ (whiskeringRight _ _ _).obj uliftFunctor.{u₁} := NatIso.ofComponents (fun X => NatIso.ofComponents - (fun Y => Equiv.toIso <| yonedaEquiv.trans Equiv.ulift.symm) + (fun _ => Equiv.toIso <| yonedaEquiv.trans Equiv.ulift.symm) (by intros Y Z f ext g @@ -572,7 +572,7 @@ def yonedaOpCompYonedaObj {C : Type u₁} [Category.{v₁} C] (P : Cᵒᵖ ⥤ T def curriedYonedaLemma' {C : Type u₁} [SmallCategory C] : yoneda ⋙ (whiskeringLeft Cᵒᵖ (Cᵒᵖ ⥤ Type u₁)ᵒᵖ (Type u₁)).obj yoneda.op ≅ 𝟭 (Cᵒᵖ ⥤ Type u₁) := - NatIso.ofComponents (fun F ↦ NatIso.ofComponents (fun X ↦ Equiv.toIso yonedaEquiv) (by + NatIso.ofComponents (fun F ↦ NatIso.ofComponents (fun _ ↦ Equiv.toIso yonedaEquiv) (by intro X Y f ext a dsimp [yonedaEquiv] @@ -595,7 +595,7 @@ and elements of `F.obj X.unop`, without any universe switching. -/ def coyonedaEquiv {X : C} {F : C ⥤ Type v₁} : (coyoneda.obj (op X) ⟶ F) ≃ F.obj X where toFun η := η.app X (𝟙 X) - invFun ξ := { app := fun Y x ↦ F.map x ξ } + invFun ξ := { app := fun _ x ↦ F.map x ξ } left_inv := fun η ↦ by ext Y (x : X ⟶ Y) dsimp @@ -677,7 +677,7 @@ def coyonedaCompUliftFunctorEquiv (F : C ⥤ Type max v₁ w) (X : Cᵒᵖ) : (coyoneda.obj X ⋙ uliftFunctor ⟶ F) ≃ F.obj X.unop where toFun φ := φ.app X.unop (ULift.up (𝟙 _)) invFun f := - { app := fun Y x => F.map (ULift.down x) f } + { app := fun _ x => F.map (ULift.down x) f } left_inv φ := by ext Y f dsimp @@ -695,7 +695,7 @@ See . -/ def coyonedaLemma : coyonedaPairing C ≅ coyonedaEvaluation C := NatIso.ofComponents - (fun X ↦ Equiv.toIso (coyonedaEquiv.trans Equiv.ulift.symm)) + (fun _ ↦ Equiv.toIso (coyonedaEquiv.trans Equiv.ulift.symm)) (by intro (X, F) (Y, G) f ext (a : coyoneda.obj (op X) ⟶ F) apply ULift.ext @@ -709,7 +709,7 @@ variable {C} /-- The curried version of coyoneda lemma when `C` is small. -/ def curriedCoyonedaLemma {C : Type u₁} [SmallCategory C] : coyoneda.rightOp ⋙ coyoneda ≅ evaluation C (Type u₁) := - NatIso.ofComponents (fun X ↦ NatIso.ofComponents (fun F ↦ Equiv.toIso coyonedaEquiv)) (by + NatIso.ofComponents (fun X ↦ NatIso.ofComponents (fun _ ↦ Equiv.toIso coyonedaEquiv)) (by intro X Y f ext a b simp [coyonedaEquiv, ← FunctorToTypes.naturality]) @@ -720,7 +720,7 @@ def largeCurriedCoyonedaLemma {C : Type u₁} [Category.{v₁} C] : evaluation C (Type v₁) ⋙ (whiskeringRight _ _ _).obj uliftFunctor.{u₁} := NatIso.ofComponents (fun X => NatIso.ofComponents - (fun Y => Equiv.toIso <| coyonedaEquiv.trans Equiv.ulift.symm) + (fun _ => Equiv.toIso <| coyonedaEquiv.trans Equiv.ulift.symm) (by intros Y Z f ext g @@ -741,7 +741,7 @@ def coyonedaCompYonedaObj {C : Type u₁} [Category.{v₁} C] (P : C ⥤ Type v def curriedCoyonedaLemma' {C : Type u₁} [SmallCategory C] : yoneda ⋙ (whiskeringLeft C (C ⥤ Type u₁)ᵒᵖ (Type u₁)).obj coyoneda.rightOp ≅ 𝟭 (C ⥤ Type u₁) := - NatIso.ofComponents (fun F ↦ NatIso.ofComponents (fun X ↦ Equiv.toIso coyonedaEquiv) (by + NatIso.ofComponents (fun F ↦ NatIso.ofComponents (fun _ ↦ Equiv.toIso coyonedaEquiv) (by intro X Y f ext a simp [coyonedaEquiv, ← FunctorToTypes.naturality])) @@ -763,7 +763,7 @@ variable {D : Type*} [Category.{v₁} D] (F : C ⥤ D) /-- The natural transformation `yoneda.obj X ⟶ F.op ⋙ yoneda.obj (F.obj X)` when `F : C ⥤ D` and `X : C`. -/ def yonedaMap (X : C) : yoneda.obj X ⟶ F.op ⋙ yoneda.obj (F.obj X) where - app X f := F.map f + app _ f := F.map f @[simp] lemma yonedaMap_app_apply {Y : C} {X : Cᵒᵖ} (f : X.unop ⟶ Y) : diff --git a/Mathlib/Combinatorics/Additive/FreimanHom.lean b/Mathlib/Combinatorics/Additive/FreimanHom.lean index 01cf0ef4b01c3c..dab82259694cf2 100644 --- a/Mathlib/Combinatorics/Additive/FreimanHom.lean +++ b/Mathlib/Combinatorics/Additive/FreimanHom.lean @@ -147,7 +147,7 @@ lemma IsMulFreimanIso.mul_eq_mul (hf : IsMulFreimanIso 2 A B f) {a b c d : α} lemma isMulFreimanHom_two : IsMulFreimanHom 2 A B f ↔ MapsTo f A B ∧ ∀ a ∈ A, ∀ b ∈ A, ∀ c ∈ A, ∀ d ∈ A, a * b = c * d → f a * f b = f c * f d where - mp hf := ⟨hf.mapsTo, fun a ha b hb c hc d hd ↦ hf.mul_eq_mul ha hb hc hd⟩ + mp hf := ⟨hf.mapsTo, fun _ ha _ hb _ hc _ hd ↦ hf.mul_eq_mul ha hb hc hd⟩ mpr hf := ⟨hf.1, by aesop (add simp card_eq_two)⟩ /-- Characterisation of `2`-Freiman homs. -/ @@ -155,7 +155,7 @@ lemma isMulFreimanHom_two : lemma isMulFreimanIso_two : IsMulFreimanIso 2 A B f ↔ BijOn f A B ∧ ∀ a ∈ A, ∀ b ∈ A, ∀ c ∈ A, ∀ d ∈ A, f a * f b = f c * f d ↔ a * b = c * d where - mp hf := ⟨hf.bijOn, fun a ha b hb c hc d hd => hf.mul_eq_mul ha hb hc hd⟩ + mp hf := ⟨hf.bijOn, fun _ ha _ hb _ hc _ hd => hf.mul_eq_mul ha hb hc hd⟩ mpr hf := ⟨hf.1, by aesop (add simp card_eq_two)⟩ @[to_additive] lemma isMulFreimanHom_id (hA : A₁ ⊆ A₂) : IsMulFreimanHom n A₁ A₂ id where @@ -235,7 +235,7 @@ lemma isMulFreimanIso_empty : IsMulFreimanIso n (∅ : Set α) (∅ : Set β) f @[to_additive] lemma IsMulFreimanHom.mul (h₁ : IsMulFreimanHom n A B₁ f₁) (h₂ : IsMulFreimanHom n A B₂ f₂) : IsMulFreimanHom n A (B₁ * B₂) (f₁ * f₂) where -- TODO: Extract `Set.MapsTo.mul` from this proof - mapsTo a ha := mul_mem_mul (h₁.mapsTo ha) (h₂.mapsTo ha) + mapsTo _ ha := mul_mem_mul (h₁.mapsTo ha) (h₂.mapsTo ha) map_prod_eq_map_prod s t hsA htA hs ht h := by rw [Pi.mul_def, prod_map_mul, prod_map_mul, h₁.map_prod_eq_map_prod hsA htA hs ht h, h₂.map_prod_eq_map_prod hsA htA hs ht h] @@ -328,7 +328,7 @@ variable [CommMonoid α] [DivisionCommMonoid β] {A : Set α} {B : Set β} {f : @[to_additive] lemma IsMulFreimanHom.inv (hf : IsMulFreimanHom n A B f) : IsMulFreimanHom n A B⁻¹ f⁻¹ where -- TODO: Extract `Set.MapsTo.inv` from this proof - mapsTo a ha := inv_mem_inv.2 (hf.mapsTo ha) + mapsTo _ ha := inv_mem_inv.2 (hf.mapsTo ha) map_prod_eq_map_prod s t hsA htA hs ht h := by rw [Pi.inv_def, prod_map_inv, prod_map_inv, hf.map_prod_eq_map_prod hsA htA hs ht h] @@ -336,7 +336,7 @@ lemma IsMulFreimanHom.inv (hf : IsMulFreimanHom n A B f) : IsMulFreimanHom n A B {f₁ f₂ : α → β} (h₁ : IsMulFreimanHom n A B₁ f₁) (h₂ : IsMulFreimanHom n A B₂ f₂) : IsMulFreimanHom n A (B₁ / B₂) (f₁ / f₂) where -- TODO: Extract `Set.MapsTo.div` from this proof - mapsTo a ha := div_mem_div (h₁.mapsTo ha) (h₂.mapsTo ha) + mapsTo _ ha := div_mem_div (h₁.mapsTo ha) (h₂.mapsTo ha) map_prod_eq_map_prod s t hsA htA hs ht h := by rw [Pi.div_def, prod_map_div, prod_map_div, h₁.map_prod_eq_map_prod hsA htA hs ht h, h₂.map_prod_eq_map_prod hsA htA hs ht h] diff --git a/Mathlib/Combinatorics/Colex.lean b/Mathlib/Combinatorics/Colex.lean index 54e26b8a2cc4ce..1513265923d821 100644 --- a/Mathlib/Combinatorics/Colex.lean +++ b/Mathlib/Combinatorics/Colex.lean @@ -120,8 +120,8 @@ private lemma antisymm_aux (hst : toColex s ≤ toColex t) (hts : toColex t ≤ exact hb₂ hb₁ instance instPartialOrder : PartialOrder (Colex α) where - le_refl s a ha ha' := (ha' ha).elim - le_antisymm s t hst hts := Colex.ext <| (antisymm_aux hst hts).antisymm (antisymm_aux hts hst) + le_refl _ _ ha ha' := (ha' ha).elim + le_antisymm _ _ hst hts := Colex.ext <| (antisymm_aux hst hts).antisymm (antisymm_aux hts hst) le_trans s t u hst htu a has hau := by by_cases hat : a ∈ ofColex t · have ⟨b, hbu, hbt, hab⟩ := htu hat hau diff --git a/Mathlib/Combinatorics/Digraph/Basic.lean b/Mathlib/Combinatorics/Digraph/Basic.lean index b6c97992885be4..f29d31b9e8121a 100644 --- a/Mathlib/Combinatorics/Digraph/Basic.lean +++ b/Mathlib/Combinatorics/Digraph/Basic.lean @@ -176,19 +176,19 @@ instance completeAtomicBooleanAlgebra : CompleteAtomicBooleanAlgebra (Digraph V) sdiff := (· \ ·) top := Digraph.completeDigraph V bot := Digraph.emptyDigraph V - le_top := fun x v w _ ↦ trivial - bot_le := fun x v w h ↦ h.elim - sdiff_eq := fun x y ↦ rfl - inf_compl_le_bot := fun G v w h ↦ absurd h.1 h.2 + le_top := fun _ _ _ _ ↦ trivial + bot_le := fun _ _ _ h ↦ h.elim + sdiff_eq := fun _ _ ↦ rfl + inf_compl_le_bot := fun _ _ _ h ↦ absurd h.1 h.2 top_le_sup_compl := fun G v w _ ↦ by tauto sSup := sSup - le_sSup := fun s G hG a b hab ↦ ⟨G, hG, hab⟩ + le_sSup := fun _ G hG _ _ hab ↦ ⟨G, hG, hab⟩ sSup_le := fun s G hG a b ↦ by rintro ⟨H, hH, hab⟩ exact hG _ hH hab sInf := sInf - sInf_le := fun s G hG a b hab ↦ hab hG - le_sInf := fun s G hG a b hab ↦ fun H hH ↦ hG _ hH hab + sInf_le := fun _ _ hG _ _ hab ↦ hab hG + le_sInf := fun _ _ hG _ _ hab ↦ fun _ hH ↦ hG _ hH hab iInf_iSup_eq := fun f ↦ by ext; simp [Classical.skolem] } @[simp] theorem top_adj (v w : V) : (⊤ : Digraph V).Adj v w := trivial diff --git a/Mathlib/Combinatorics/Enumerative/DoubleCounting.lean b/Mathlib/Combinatorics/Enumerative/DoubleCounting.lean index 0264391a003850..3d913effaea150 100644 --- a/Mathlib/Combinatorics/Enumerative/DoubleCounting.lean +++ b/Mathlib/Combinatorics/Enumerative/DoubleCounting.lean @@ -198,10 +198,10 @@ variable [Fintype α] [Fintype β] {r : α → β → Prop} theorem card_le_card_of_leftTotal_unique (h₁ : LeftTotal r) (h₂ : LeftUnique r) : Fintype.card α ≤ Fintype.card β := - card_le_card_of_forall_subsingleton r (by simpa using h₁) fun b _ a₁ ha₁ a₂ ha₂ ↦ h₂ ha₁.2 ha₂.2 + card_le_card_of_forall_subsingleton r (by simpa using h₁) fun _ _ _ ha₁ _ ha₂ ↦ h₂ ha₁.2 ha₂.2 theorem card_le_card_of_rightTotal_unique (h₁ : RightTotal r) (h₂ : RightUnique r) : Fintype.card β ≤ Fintype.card α := - card_le_card_of_forall_subsingleton' r (by simpa using h₁) fun b _ a₁ ha₁ a₂ ha₂ ↦ h₂ ha₁.2 ha₂.2 + card_le_card_of_forall_subsingleton' r (by simpa using h₁) fun _ _ _ ha₁ _ ha₂ ↦ h₂ ha₁.2 ha₂.2 end Fintype diff --git a/Mathlib/Combinatorics/Enumerative/DyckWord.lean b/Mathlib/Combinatorics/Enumerative/DyckWord.lean index 220e3d4c4f1414..cd58430af7c763 100644 --- a/Mathlib/Combinatorics/Enumerative/DyckWord.lean +++ b/Mathlib/Combinatorics/Enumerative/DyckWord.lean @@ -406,8 +406,8 @@ section Order instance : Preorder DyckWord where le := Relation.ReflTransGen (fun p q ↦ p = q.insidePart ∨ p = q.outsidePart) - le_refl p := Relation.ReflTransGen.refl - le_trans p q r := Relation.ReflTransGen.trans + le_refl _ := Relation.ReflTransGen.refl + le_trans _ _ _ := Relation.ReflTransGen.trans lemma le_add_self (p q : DyckWord) : q ≤ p + q := by by_cases h : p = 0 diff --git a/Mathlib/Combinatorics/Hall/Basic.lean b/Mathlib/Combinatorics/Hall/Basic.lean index 52a8937ef30822..70a89a8ee97907 100644 --- a/Mathlib/Combinatorics/Hall/Basic.lean +++ b/Mathlib/Combinatorics/Hall/Basic.lean @@ -86,7 +86,7 @@ theorem hallMatchingsOn.nonempty {ι : Type u} {α : Type v} [DecidableEq α] (t def hallMatchingsFunctor {ι : Type u} {α : Type v} (t : ι → Finset α) : (Finset ι)ᵒᵖ ⥤ Type max u v where obj ι' := hallMatchingsOn t ι'.unop - map {ι' ι''} g f := hallMatchingsOn.restrict t (CategoryTheory.leOfHom g.unop) f + map {_ _} g f := hallMatchingsOn.restrict t (CategoryTheory.leOfHom g.unop) f instance hallMatchingsOn.finite {ι : Type u} {α : Type v} (t : ι → Finset α) (ι' : Finset ι) : Finite (hallMatchingsOn t ι') := by diff --git a/Mathlib/Combinatorics/SimpleGraph/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Basic.lean index ed55cb02e74c69..008ba18f37ef67 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Basic.lean @@ -237,7 +237,7 @@ instance hasCompl : HasCompl (SimpleGraph V) where compl G := { Adj := fun v w => v ≠ w ∧ ¬G.Adj v w symm := fun v w ⟨hne, _⟩ => ⟨hne.symm, by rwa [adj_comm]⟩ - loopless := fun v ⟨hne, _⟩ => (hne rfl).elim } + loopless := fun _ ⟨hne, _⟩ => (hne rfl).elim } @[simp] theorem compl_adj (G : SimpleGraph V) (v w : V) : Gᶜ.Adj v w ↔ v ≠ w ∧ ¬G.Adj v w := @@ -256,7 +256,7 @@ theorem sdiff_adj (x y : SimpleGraph V) (v w : V) : (x \ y).Adj v w ↔ x.Adj v instance supSet : SupSet (SimpleGraph V) where sSup s := { Adj := fun a b => ∃ G ∈ s, Adj G a b - symm := fun a b => Exists.imp fun _ => And.imp_right Adj.symm + symm := fun _ _ => Exists.imp fun _ => And.imp_right Adj.symm loopless := by rintro a ⟨G, _, ha⟩ exact ha.ne rfl } @@ -308,26 +308,26 @@ instance completeAtomicBooleanAlgebra : CompleteAtomicBooleanAlgebra (SimpleGrap sdiff := (· \ ·) top := completeGraph V bot := emptyGraph V - le_top := fun x v w h => x.ne_of_adj h - bot_le := fun x v w h => h.elim + le_top := fun x _ _ h => x.ne_of_adj h + bot_le := fun _ _ _ h => h.elim sdiff_eq := fun x y => by ext v w refine ⟨fun h => ⟨h.1, ⟨?_, h.2⟩⟩, fun h => ⟨h.1, h.2.2⟩⟩ rintro rfl exact x.irrefl h.1 - inf_compl_le_bot := fun G v w h => False.elim <| h.2.2 h.1 + inf_compl_le_bot := fun _ _ _ h => False.elim <| h.2.2 h.1 top_le_sup_compl := fun G v w hvw => by by_cases h : G.Adj v w · exact Or.inl h · exact Or.inr ⟨hvw, h⟩ sSup := sSup - le_sSup := fun s G hG a b hab => ⟨G, hG, hab⟩ + le_sSup := fun _ G hG _ _ hab => ⟨G, hG, hab⟩ sSup_le := fun s G hG a b => by rintro ⟨H, hH, hab⟩ exact hG _ hH hab sInf := sInf - sInf_le := fun s G hG a b hab => hab.1 hG - le_sInf := fun s G hG a b hab => ⟨fun H hH => hG _ hH hab, hab.ne⟩ + sInf_le := fun _ _ hG _ _ hab => hab.1 hG + le_sInf := fun _ _ hG _ _ hab => ⟨fun _ hH => hG _ hH hab, hab.ne⟩ iInf_iSup_eq := fun f => by ext; simp [Classical.skolem] } @[simp] @@ -555,7 +555,7 @@ variable (s : Set (Sym2 V)) /-- `fromEdgeSet` constructs a `SimpleGraph` from a set of edges, without loops. -/ def fromEdgeSet : SimpleGraph V where Adj := Sym2.ToRel s ⊓ Ne - symm v w h := ⟨Sym2.toRel_symmetric s h.1, h.2.symm⟩ + symm _ _ h := ⟨Sym2.toRel_symmetric s h.1, h.2.symm⟩ @[simp] theorem fromEdgeSet_adj : (fromEdgeSet s).Adj v w ↔ s(v, w) ∈ s ∧ v ≠ w := diff --git a/Mathlib/Combinatorics/SimpleGraph/Connectivity/WalkCounting.lean b/Mathlib/Combinatorics/SimpleGraph/Connectivity/WalkCounting.lean index 51818e23758132..2585da22203514 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Connectivity/WalkCounting.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Connectivity/WalkCounting.lean @@ -64,7 +64,7 @@ Note that `u` and `v` may be the same. -/ def walkLengthTwoEquivCommonNeighbors (u v : V) : {p : G.Walk u v // p.length = 2} ≃ G.commonNeighbors u v where toFun p := ⟨p.val.getVert 1, match p with - | ⟨.cons _ (.cons _ .nil), hp⟩ => ⟨‹G.Adj u _›, ‹G.Adj _ v›.symm⟩⟩ + | ⟨.cons _ (.cons _ .nil), _⟩ => ⟨‹G.Adj u _›, ‹G.Adj _ v›.symm⟩⟩ invFun w := ⟨w.prop.1.toWalk.concat w.prop.2.symm, rfl⟩ left_inv | ⟨.cons _ (.cons _ .nil), hp⟩ => by rfl right_inv _ := rfl diff --git a/Mathlib/Combinatorics/SimpleGraph/Maps.lean b/Mathlib/Combinatorics/SimpleGraph/Maps.lean index 93f6348a4d8971..77a6eacef6ab14 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Maps.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Maps.lean @@ -129,7 +129,7 @@ theorem comap_surjective (f : V ↪ W) : Function.Surjective (SimpleGraph.comap theorem map_le_iff_le_comap (f : V ↪ W) (G : SimpleGraph V) (G' : SimpleGraph W) : G.map f ≤ G' ↔ G ≤ G'.comap f := - ⟨fun h u v ha => h ⟨_, _, ha, rfl, rfl⟩, by + ⟨fun h _ _ ha => h ⟨_, _, ha, rfl, rfl⟩, by rintro h _ _ ⟨u, v, ha, rfl, rfl⟩ exact h ha⟩ diff --git a/Mathlib/Combinatorics/SimpleGraph/Regularity/Bound.lean b/Mathlib/Combinatorics/SimpleGraph/Regularity/Bound.lean index 5ee0f683c85af1..05fda50393f3ed 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Regularity/Bound.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Regularity/Bound.lean @@ -40,7 +40,7 @@ def stepBound (n : ℕ) : ℕ := theorem le_stepBound : id ≤ stepBound := fun n => Nat.le_mul_of_pos_right _ <| pow_pos (by norm_num) n -theorem stepBound_mono : Monotone stepBound := fun a b h => +theorem stepBound_mono : Monotone stepBound := fun _ _ h => Nat.mul_le_mul h <| Nat.pow_le_pow_of_le_right (by norm_num) h theorem stepBound_pos_iff {n : ℕ} : 0 < stepBound n ↔ 0 < n := diff --git a/Mathlib/Combinatorics/SimpleGraph/Regularity/Energy.lean b/Mathlib/Combinatorics/SimpleGraph/Regularity/Energy.lean index 2691d38a6f4b2b..54e5c27b5c9064 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Regularity/Energy.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Regularity/Energy.lean @@ -43,7 +43,7 @@ theorem energy_le_one : P.energy G ≤ 1 := div_le_of_le_mul₀ (sq_nonneg _) zero_le_one <| calc ∑ uv ∈ P.parts.offDiag, G.edgeDensity uv.1 uv.2 ^ 2 ≤ P.parts.offDiag.card • (1 : ℚ) := - sum_le_card_nsmul _ _ 1 fun uv _ => + sum_le_card_nsmul _ _ 1 fun _ _ => (sq_le_one_iff <| G.edgeDensity_nonneg _ _).2 <| G.edgeDensity_le_one _ _ _ = P.parts.offDiag.card := Nat.smul_one_eq_cast _ _ ≤ _ := by diff --git a/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean b/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean index 529afbfeaee474..f4078873ab459d 100644 --- a/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean +++ b/Mathlib/Combinatorics/SimpleGraph/StronglyRegular.lean @@ -57,7 +57,7 @@ for empty graphs, since there are no pairs of adjacent vertices. -/ theorem bot_strongly_regular : (⊥ : SimpleGraph V).IsSRGWith (Fintype.card V) 0 ℓ 0 where card := rfl regular := bot_degree - of_adj := fun v w h => h.elim + of_adj := fun _ _ h => h.elim of_not_adj := fun v w _h => by simp only [card_eq_zero, Fintype.card_ofFinset, forall_true_left, not_false_iff, bot_adj] ext diff --git a/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean b/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean index c0cc9e7d6ca212..9d6763e5a5474e 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Subgraph.lean @@ -434,20 +434,20 @@ def completelyDistribLatticeMinimalAxioms : CompletelyDistribLattice.MinimalAxio inf := (· ⊓ ·) top := ⊤ bot := ⊥ - le_top := fun G' => ⟨Set.subset_univ _, fun a b => G'.adj_sub⟩ - bot_le := fun G' => ⟨Set.empty_subset _, fun a b => False.elim⟩ + le_top := fun G' => ⟨Set.subset_univ _, fun _ _ => G'.adj_sub⟩ + bot_le := fun _ => ⟨Set.empty_subset _, fun _ _ => False.elim⟩ sSup := sSup -- Porting note: needed `apply` here to modify elaboration; previously the term itself was fine. - le_sSup := fun s G' hG' => ⟨by apply Set.subset_iUnion₂ G' hG', fun a b hab => ⟨G', hG', hab⟩⟩ + le_sSup := fun s G' hG' => ⟨by apply Set.subset_iUnion₂ G' hG', fun _ _ hab => ⟨G', hG', hab⟩⟩ sSup_le := fun s G' hG' => - ⟨Set.iUnion₂_subset fun H hH => (hG' _ hH).1, by + ⟨Set.iUnion₂_subset fun _ hH => (hG' _ hH).1, by rintro a b ⟨H, hH, hab⟩ exact (hG' _ hH).2 hab⟩ sInf := sInf - sInf_le := fun s G' hG' => ⟨Set.iInter₂_subset G' hG', fun a b hab => hab.1 hG'⟩ - le_sInf := fun s G' hG' => - ⟨Set.subset_iInter₂ fun H hH => (hG' _ hH).1, fun a b hab => - ⟨fun H hH => (hG' _ hH).2 hab, G'.adj_sub hab⟩⟩ + sInf_le := fun _ G' hG' => ⟨Set.iInter₂_subset G' hG', fun _ _ hab => hab.1 hG'⟩ + le_sInf := 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 := fun f => Subgraph.ext (by simpa using iInf_iSup_eq) (by ext; simp [Classical.skolem]) } diff --git a/Mathlib/Computability/Ackermann.lean b/Mathlib/Computability/Ackermann.lean index 211e594b146702..ace0d47e3ed958 100644 --- a/Mathlib/Computability/Ackermann.lean +++ b/Mathlib/Computability/Ackermann.lean @@ -175,7 +175,7 @@ theorem lt_ack_right (m n : ℕ) : n < ack m n := -- we reorder the arguments to appease the equation compiler private theorem ack_strict_mono_left' : ∀ {m₁ m₂} (n), m₁ < m₂ → ack m₁ n < ack m₂ n - | m, 0, n => fun h => (not_lt_zero m h).elim + | m, 0, _ => fun h => (not_lt_zero m h).elim | 0, m + 1, 0 => fun _h => by simpa using one_lt_ack_succ_right m 0 | 0, m + 1, n + 1 => fun h => by rw [ack_zero, ack_succ_succ] diff --git a/Mathlib/Computability/Halting.lean b/Mathlib/Computability/Halting.lean index a2de5176d359ba..58c788970098d5 100644 --- a/Mathlib/Computability/Halting.lean +++ b/Mathlib/Computability/Halting.lean @@ -162,7 +162,7 @@ open Nat.Partrec.Code Computable theorem computable_iff {p : α → Prop} : ComputablePred p ↔ ∃ f : α → Bool, Computable f ∧ p = fun a => (f a : Prop) := - ⟨fun ⟨D, h⟩ => ⟨_, h, funext fun a => propext (Bool.decide_iff _).symm⟩, by + ⟨fun ⟨_, h⟩ => ⟨_, h, funext fun _ => propext (Bool.decide_iff _).symm⟩, by rintro ⟨f, h, rfl⟩; exact ⟨by infer_instance, by simpa using h⟩⟩ protected theorem not {p : α → Prop} (hp : ComputablePred p) : ComputablePred fun a => ¬p a := by diff --git a/Mathlib/Computability/Language.lean b/Mathlib/Computability/Language.lean index a8779cd1c92831..4e40a3919b388b 100644 --- a/Mathlib/Computability/Language.lean +++ b/Mathlib/Computability/Language.lean @@ -248,7 +248,7 @@ theorem one_add_kstar_mul_self_eq_kstar (l : Language α) : 1 + l∗ * l = l∗ instance : KleeneAlgebra (Language α) := { Language.instSemiring, Set.completeAtomicBooleanAlgebra with kstar := fun L ↦ L∗, - one_le_kstar := fun a l hl ↦ ⟨[], hl, by simp⟩, + one_le_kstar := fun a _ hl ↦ ⟨[], hl, by simp⟩, mul_kstar_le_kstar := fun a ↦ (one_add_self_mul_kstar_eq_kstar a).le.trans' le_sup_right, kstar_mul_le_kstar := fun a ↦ (one_add_kstar_mul_self_eq_kstar a).le.trans' le_sup_right, kstar_mul_le_self := fun l m h ↦ by diff --git a/Mathlib/Computability/Partrec.lean b/Mathlib/Computability/Partrec.lean index 543c6f0ffa9796..543e6b98af5867 100644 --- a/Mathlib/Computability/Partrec.lean +++ b/Mathlib/Computability/Partrec.lean @@ -47,7 +47,7 @@ variable (H : ∃ n, true ∈ p n ∧ ∀ k < n, (p k).Dom) def rfindX : { n // true ∈ p n ∧ ∀ m < n, false ∈ p m } := suffices ∀ k, (∀ n < k, false ∈ p n) → { n // true ∈ p n ∧ ∀ m < n, false ∈ p m } from - this 0 fun n => (Nat.not_lt_zero _).elim + this 0 fun _ => (Nat.not_lt_zero _).elim @WellFounded.fix _ _ (lbp p) (wf_lbp p H) (by intro m IH al @@ -102,7 +102,7 @@ theorem mem_rfind {p : ℕ →. Bool} {n : ℕ} : theorem rfind_min' {p : ℕ → Bool} {m : ℕ} (pm : p m) : ∃ n ∈ rfind p, n ≤ m := have : true ∈ (p : ℕ →. Bool) m := ⟨trivial, pm⟩ - let ⟨n, hn⟩ := dom_iff_mem.1 <| (@rfind_dom p).2 ⟨m, this, fun {k} _ => ⟨⟩⟩ + let ⟨n, hn⟩ := dom_iff_mem.1 <| (@rfind_dom p).2 ⟨m, this, fun {_} _ => ⟨⟩⟩ ⟨n, hn, not_lt.1 fun h => by injection mem_unique this (rfind_min hn h)⟩ theorem rfind_zero_none (p : ℕ →. Bool) (p0 : p 0 = Part.none) : rfind p = Part.none := @@ -118,7 +118,7 @@ theorem rfindOpt_spec {α} {f : ℕ → Option α} {a} (h : a ∈ rfindOpt f) : ⟨n, mem_coe.1 h₂⟩ theorem rfindOpt_dom {α} {f : ℕ → Option α} : (rfindOpt f).Dom ↔ ∃ n a, a ∈ f n := - ⟨fun h => (rfindOpt_spec ⟨h, rfl⟩).imp fun n h => ⟨_, h⟩, fun h => by + ⟨fun h => (rfindOpt_spec ⟨h, rfl⟩).imp fun _ h => ⟨_, h⟩, fun h => by have h' : ∃ n, (f n).isSome := h.imp fun n => Option.isSome_iff_exists.2 have s := Nat.find_spec h' have fd : (rfind fun n => (f n).isSome).Dom := @@ -179,8 +179,8 @@ protected theorem some : Partrec some := of_primrec Primrec.id theorem none : Partrec fun _ => none := - (of_primrec (Nat.Primrec.const 1)).rfind.of_eq fun n => - eq_none_iff.2 fun a ⟨h, _⟩ => by simp at h + (of_primrec (Nat.Primrec.const 1)).rfind.of_eq fun _ => + eq_none_iff.2 fun _ ⟨h, _⟩ => by simp at h theorem prec' {f g h} (hf : Partrec f) (hg : Partrec g) (hh : Partrec h) : Partrec fun a => (f a).bind fun n => n.rec (g a) diff --git a/Mathlib/Computability/PartrecCode.lean b/Mathlib/Computability/PartrecCode.lean index 74b64e82859abd..77e572cb6f2a63 100644 --- a/Mathlib/Computability/PartrecCode.lean +++ b/Mathlib/Computability/PartrecCode.lean @@ -492,7 +492,7 @@ instance : Membership (ℕ →. ℕ) Code := @[simp] theorem eval_const : ∀ n m, eval (Code.const n) m = Part.some n - | 0, m => rfl + | 0, _ => rfl | n + 1, m => by simp! [eval_const n m] @[simp] diff --git a/Mathlib/Computability/Primrec.lean b/Mathlib/Computability/Primrec.lean index 350ee120e6376c..17cbe2ce38bec5 100644 --- a/Mathlib/Computability/Primrec.lean +++ b/Mathlib/Computability/Primrec.lean @@ -619,7 +619,7 @@ protected theorem beq [DecidableEq α] : Primrec₂ (@BEq.beq α _) := have : PrimrecRel fun a b : ℕ => a = b := (PrimrecPred.and nat_le nat_le.swap).of_eq fun a => by simp [le_antisymm_iff] (this.comp₂ (Primrec.encode.comp₂ Primrec₂.left) (Primrec.encode.comp₂ Primrec₂.right)).of_eq - fun a b => encode_injective.eq_iff + fun _ _ => encode_injective.eq_iff protected theorem eq [DecidableEq α] : PrimrecRel (@Eq α) := Primrec.beq @@ -1097,7 +1097,7 @@ def subtype {p : α → Prop} [DecidablePred p] (hp : PrimrecPred p) : Primcodab ⟨have : Primrec fun n => (@decode α _ n).bind fun a => Option.guard p a := option_bind .decode (option_guard (hp.comp snd).to₂ snd) nat_iff.1 <| (encode_iff.2 this).of_eq fun n => - show _ = encode ((@decode α _ n).bind fun a => _) by + show _ = encode ((@decode α _ n).bind fun _ => _) by cases' @decode α _ n with a; · rfl dsimp [Option.guard] by_cases h : p a <;> simp [h]; rfl⟩ @@ -1355,8 +1355,8 @@ theorem natPair : @Primrec' 2 fun v => v.head.pair v.tail.head := protected theorem encode : ∀ {n}, @Primrec' n encode | 0 => (const 0).of_eq fun v => by rw [v.eq_nil]; rfl - | n + 1 => - (succ.comp₁ _ (natPair.comp₂ _ head (tail Primrec'.encode))).of_eq fun ⟨a :: l, e⟩ => rfl + | _ + 1 => + (succ.comp₁ _ (natPair.comp₂ _ head (tail Primrec'.encode))).of_eq fun ⟨_ :: _, _⟩ => rfl theorem sqrt : @Primrec' 1 fun v => v.head.sqrt := by suffices H : ∀ n : ℕ, n.sqrt = diff --git a/Mathlib/Computability/Reduce.lean b/Mathlib/Computability/Reduce.lean index 131ccd8fadbc5f..f3131659de7716 100644 --- a/Mathlib/Computability/Reduce.lean +++ b/Mathlib/Computability/Reduce.lean @@ -325,7 +325,7 @@ protected theorem liftOn_eq {φ} (p : Set ℕ) (f : Set ℕ → φ) @[reducible, simp] protected def liftOn₂ {φ} (d₁ d₂ : ManyOneDegree) (f : Set ℕ → Set ℕ → φ) (h : ∀ p₁ p₂ q₁ q₂, ManyOneEquiv p₁ p₂ → ManyOneEquiv q₁ q₂ → f p₁ q₁ = f p₂ q₂) : φ := - d₁.liftOn (fun p => d₂.liftOn (f p) fun q₁ q₂ hq => h _ _ _ _ (by rfl) hq) + d₁.liftOn (fun p => d₂.liftOn (f p) fun _ _ hq => h _ _ _ _ (by rfl) hq) (by intro p₁ p₂ hp induction d₂ using ManyOneDegree.ind_on diff --git a/Mathlib/Computability/RegularExpressions.lean b/Mathlib/Computability/RegularExpressions.lean index cbcdb86be98771..7835066c73ec15 100644 --- a/Mathlib/Computability/RegularExpressions.lean +++ b/Mathlib/Computability/RegularExpressions.lean @@ -373,7 +373,7 @@ protected theorem map_pow (f : α → β) (P : RegularExpression α) : theorem map_id : ∀ P : RegularExpression α, P.map id = P | 0 => rfl | 1 => rfl - | char a => rfl + | char _ => rfl | R + S => by simp_rw [map, map_id] | comp R S => by simp_rw [map, map_id]; rfl | star R => by simp_rw [map, map_id] @@ -384,7 +384,7 @@ theorem map_id : ∀ P : RegularExpression α, P.map id = P theorem map_map (g : β → γ) (f : α → β) : ∀ P : RegularExpression α, (P.map f).map g = P.map (g ∘ f) | 0 => rfl | 1 => rfl - | char a => rfl + | char _ => rfl | R + S => by simp only [map, Function.comp_apply, map_map] | comp R S => by simp only [map, Function.comp_apply, map_map] | star R => by simp only [map, Function.comp_apply, map_map] diff --git a/Mathlib/Computability/TuringMachine.lean b/Mathlib/Computability/TuringMachine.lean index 0309fcce41a02c..a9037ff96e553c 100644 --- a/Mathlib/Computability/TuringMachine.lean +++ b/Mathlib/Computability/TuringMachine.lean @@ -562,9 +562,9 @@ theorem Tape.mk'_nth_nat {Γ} [Inhabited Γ] (L R : ListBlank Γ) (n : ℕ) : @[simp] theorem Tape.move_left_nth {Γ} [Inhabited Γ] : ∀ (T : Tape Γ) (i : ℤ), (T.move Dir.left).nth i = T.nth (i - 1) - | ⟨_, L, _⟩, -(n + 1 : ℕ) => (ListBlank.nth_succ _ _).symm - | ⟨_, L, _⟩, 0 => (ListBlank.nth_zero _).symm - | ⟨a, L, R⟩, 1 => (ListBlank.nth_zero _).trans (ListBlank.head_cons _ _) + | ⟨_, _, _⟩, -(_ + 1 : ℕ) => (ListBlank.nth_succ _ _).symm + | ⟨_, _, _⟩, 0 => (ListBlank.nth_zero _).symm + | ⟨_, _, _⟩, 1 => (ListBlank.nth_zero _).trans (ListBlank.head_cons _ _) | ⟨a, L, R⟩, (n + 1 : ℕ) + 1 => by rw [add_sub_cancel_right] change (R.cons a).nth (n + 1) = R.nth n @@ -850,7 +850,7 @@ def FRespects {σ₁ σ₂} (f₂ : σ₂ → Option σ₂) (tr : σ₁ → σ theorem frespects_eq {σ₁ σ₂} {f₂ : σ₂ → Option σ₂} {tr : σ₁ → σ₂} {a₂ b₂} (h : f₂ a₂ = f₂ b₂) : ∀ {b₁}, FRespects f₂ tr a₂ b₁ ↔ FRespects f₂ tr b₂ b₁ - | some b₁ => reaches₁_eq h + | some _ => reaches₁_eq h | none => by unfold FRespects; rw [h] theorem fun_respects {σ₁ σ₂ f₁ f₂} {tr : σ₁ → σ₂} : @@ -2257,9 +2257,9 @@ def trInit (k : K) (L : List (Γ k)) : List Γ'₂₁ := theorem step_run {k : K} (q : Stmt₂) (v : σ) (S : ∀ k, List (Γ k)) : ∀ s : StAct₂ k, TM2.stepAux (stRun s q) v S = TM2.stepAux q (stVar v (S k) s) (update S k (stWrite v (S k) s)) - | StAct.push f => rfl + | StAct.push _ => rfl | StAct.peek f => by unfold stWrite; rw [Function.update_eq_self]; rfl - | StAct.pop f => rfl + | StAct.pop _ => rfl end diff --git a/Mathlib/Condensed/Discrete/LocallyConstant.lean b/Mathlib/Condensed/Discrete/LocallyConstant.lean index ca028c4a70293f..40b0e6e7d03a91 100644 --- a/Mathlib/Condensed/Discrete/LocallyConstant.lean +++ b/Mathlib/Condensed/Discrete/LocallyConstant.lean @@ -84,7 +84,7 @@ def functorToPresheaves : Type (max u w) ⥤ ((CompHausLike.{u} P)ᵒᵖ ⥤ Typ obj X := { obj := fun ⟨S⟩ ↦ LocallyConstant S X map := fun f g ↦ g.comap f.unop } - map f := { app := fun S t ↦ t.map f } + map f := { app := fun _ t ↦ t.map f } /-- Locally constant maps are the same as continuous maps when the target is equipped with the discrete @@ -291,13 +291,13 @@ The unit of the adjunciton is given by mapping each element to the corresponding -/ @[simps] def unit : 𝟭 _ ⟶ functor P hs ⋙ (sheafSections _ _).obj ⟨CompHausLike.of P PUnit.{u+1}⟩ where - app X x := LocallyConstant.const _ x + app _ x := LocallyConstant.const _ x /-- The unit of the adjunction is an iso. -/ noncomputable def unitIso : 𝟭 (Type max u w) ≅ functor.{u, w} P hs ⋙ (sheafSections _ _).obj ⟨CompHausLike.of P PUnit.{u+1}⟩ where hom := unit P hs - inv := { app := fun X f ↦ f.toFun PUnit.unit } + inv := { app := fun _ f ↦ f.toFun PUnit.unit } lemma adjunction_left_triangle [HasExplicitFiniteCoproducts.{u} P] (X : Type max u w) : functorToPresheaves.{u, w}.map ((unit P hs).app X) ≫ diff --git a/Mathlib/Control/EquivFunctor.lean b/Mathlib/Control/EquivFunctor.lean index ecbf36b36a8a59..6b7e9c7c574e15 100644 --- a/Mathlib/Control/EquivFunctor.lean +++ b/Mathlib/Control/EquivFunctor.lean @@ -81,7 +81,7 @@ end instance (priority := 100) ofLawfulFunctor (f : Type u₀ → Type u₁) [Functor f] [LawfulFunctor f] : EquivFunctor f where - map {α β} e := Functor.map e + map {_ _} e := Functor.map e map_refl' α := by ext apply LawfulFunctor.id_map diff --git a/Mathlib/Control/EquivFunctor/Instances.lean b/Mathlib/Control/EquivFunctor/Instances.lean index 13987af2679b90..62f3c1590452d8 100644 --- a/Mathlib/Control/EquivFunctor/Instances.lean +++ b/Mathlib/Control/EquivFunctor/Instances.lean @@ -38,6 +38,6 @@ instance EquivFunctorFinset : EquivFunctor Finset where simp [h'] instance EquivFunctorFintype : EquivFunctor Fintype where - map e s := Fintype.ofBijective e e.bijective + map e _ := Fintype.ofBijective e e.bijective map_refl' α := by ext; simp [eq_iff_true_of_subsingleton] map_trans' := by simp [eq_iff_true_of_subsingleton] diff --git a/Mathlib/Control/Functor/Multivariate.lean b/Mathlib/Control/Functor/Multivariate.lean index 993d066487aa98..5234cb42fc0e86 100644 --- a/Mathlib/Control/Functor/Multivariate.lean +++ b/Mathlib/Control/Functor/Multivariate.lean @@ -157,7 +157,7 @@ private def f : { p_1 : (α ::: β) i // PredLast α pp p_1 } | _, α, Fin2.fs i, x => ⟨x.val, cast (by simp only [PredLast]; erw [const_iff_true]) x.property⟩ - | _, α, Fin2.fz, x => ⟨x.val, x.property⟩ + | _, _, Fin2.fz, x => ⟨x.val, x.property⟩ private def g : ∀ n α, @@ -165,7 +165,7 @@ private def g : { p_1 // ofRepeat (PredLast' α pp i p_1) } | _, α, Fin2.fs i, x => ⟨x.val, cast (by simp only [PredLast]; erw [const_iff_true]) x.property⟩ - | _, α, Fin2.fz, x => ⟨x.val, x.property⟩ + | _, _, Fin2.fz, x => ⟨x.val, x.property⟩ theorem LiftP_PredLast_iff {β} (P : β → Prop) (x : F (α ::: β)) : LiftP' (PredLast' _ P) x ↔ LiftP (PredLast _ P) x := by @@ -191,7 +191,7 @@ private def f' : fun i : Fin2 (n + 1) => { p_1 : (α ::: β) i × _ // RelLast α rr p_1.fst p_1.snd } | _, α, Fin2.fs i, x => ⟨x.val, cast (by simp only [RelLast]; erw [repeatEq_iff_eq]) x.property⟩ - | _, α, Fin2.fz, x => ⟨x.val, x.property⟩ + | _, _, Fin2.fz, x => ⟨x.val, x.property⟩ private def g' : ∀ n α, @@ -200,7 +200,7 @@ private def g' : { p_1 : _ × _ // ofRepeat (RelLast' α rr i (TypeVec.prod.mk _ p_1.1 p_1.2)) } | _, α, Fin2.fs i, x => ⟨x.val, cast (by simp only [RelLast]; erw [repeatEq_iff_eq]) x.property⟩ - | _, α, Fin2.fz, x => ⟨x.val, x.property⟩ + | _, _, Fin2.fz, x => ⟨x.val, x.property⟩ theorem LiftR_RelLast_iff (x y : F (α ::: β)) : LiftR' (RelLast' _ rr) x y ↔ LiftR (RelLast (i := _) _ rr) x y := by diff --git a/Mathlib/Control/Traversable/Basic.lean b/Mathlib/Control/Traversable/Basic.lean index eff2d5afd70563..20827287d137a1 100644 --- a/Mathlib/Control/Traversable/Basic.lean +++ b/Mathlib/Control/Traversable/Basic.lean @@ -144,7 +144,7 @@ end Preserves /-- The identity applicative transformation from an applicative functor to itself. -/ def idTransformation : ApplicativeTransformation F F where - app α := id + app _ := id preserves_pure' := by simp preserves_seq' x y := by simp @@ -158,7 +158,7 @@ variable {H : Type u → Type s} [Applicative H] /-- The composition of applicative transformations. -/ def comp (η' : ApplicativeTransformation G H) (η : ApplicativeTransformation F G) : ApplicativeTransformation F H where - app α x := η' (η x) + app _ x := η' (η x) -- Porting note: something has gone wrong with `simp [functor_norm]`, -- which should suffice for the next two. preserves_pure' x := by simp only [preserves_pure] diff --git a/Mathlib/Control/Traversable/Lemmas.lean b/Mathlib/Control/Traversable/Lemmas.lean index 7b98b4bf635c35..3b10199bdc92d3 100644 --- a/Mathlib/Control/Traversable/Lemmas.lean +++ b/Mathlib/Control/Traversable/Lemmas.lean @@ -46,7 +46,7 @@ to `F`, defined by `pure : Π {α}, α → F α`. -/ def PureTransformation : ApplicativeTransformation Id F where app := @pure F _ - preserves_pure' x := rfl + preserves_pure' _ := rfl preserves_seq' f x := by simp only [map_pure, seq_pure] rfl diff --git a/Mathlib/Data/Analysis/Filter.lean b/Mathlib/Data/Analysis/Filter.lean index aaae456a711cdc..2664265881a852 100644 --- a/Mathlib/Data/Analysis/Filter.lean +++ b/Mathlib/Data/Analysis/Filter.lean @@ -113,8 +113,8 @@ def ofFilter (f : Filter α) : f.Realizer := { f := Subtype.val pt := ⟨univ, univ_mem⟩ inf := fun ⟨_, h₁⟩ ⟨_, h₂⟩ ↦ ⟨_, inter_mem h₁ h₂⟩ - inf_le_left := fun ⟨x, _⟩ ⟨y, _⟩ ↦ inter_subset_left - inf_le_right := fun ⟨x, _⟩ ⟨y, _⟩ ↦ inter_subset_right }, + inf_le_left := fun ⟨_, _⟩ ⟨_, _⟩ ↦ inter_subset_left + inf_le_right := fun ⟨_, _⟩ ⟨_, _⟩ ↦ inter_subset_right }, filter_eq <| Set.ext fun _ ↦ by simp [exists_mem_subset_iff]⟩ /-- Transfer a filter realizer to another realizer on a different base type. -/ diff --git a/Mathlib/Data/Bool/Count.lean b/Mathlib/Data/Bool/Count.lean index 197ccefd5156d3..8f71b21123ee05 100644 --- a/Mathlib/Data/Bool/Count.lean +++ b/Mathlib/Data/Bool/Count.lean @@ -40,7 +40,7 @@ theorem count_true_add_count_false (l : List Bool) : count true l + count false theorem Chain.count_not : ∀ {b : Bool} {l : List Bool}, Chain (· ≠ ·) b l → count (!b) l = count b l + length l % 2 - | b, [], _h => rfl + | _, [], _h => rfl | b, x :: l, h => by obtain rfl : b = !x := Bool.eq_not_iff.2 (rel_of_chain_cons h) rw [Bool.not_not, count_cons_self, count_cons_of_ne x.not_ne_self, diff --git a/Mathlib/Data/Complex/Abs.lean b/Mathlib/Data/Complex/Abs.lean index a43a2daaf814f2..ce85a60f52f8cb 100644 --- a/Mathlib/Data/Complex/Abs.lean +++ b/Mathlib/Data/Complex/Abs.lean @@ -226,7 +226,7 @@ theorem range_normSq : range normSq = Ici 0 := local notation "abs'" => _root_.abs -theorem isCauSeq_re (f : CauSeq ℂ Complex.abs) : IsCauSeq abs' fun n => (f n).re := fun ε ε0 => +theorem isCauSeq_re (f : CauSeq ℂ Complex.abs) : IsCauSeq abs' fun n => (f n).re := fun _ ε0 => (f.cauchy ε0).imp fun i H j ij => lt_of_le_of_lt (by simpa using abs_re_le_abs (f j - f i)) (H _ ij) @@ -257,7 +257,7 @@ theorem equiv_limAux (f : CauSeq ℂ Complex.abs) : (exists_forall_ge_and (CauSeq.equiv_lim ⟨_, isCauSeq_re f⟩ _ (half_pos ε0)) (CauSeq.equiv_lim ⟨_, isCauSeq_im f⟩ _ (half_pos ε0))).imp - fun i H j ij => by + fun _ H j ij => by cases' H _ ij with H₁ H₂ apply lt_of_le_of_lt (abs_le_abs_re_add_abs_im _) dsimp [limAux] at * diff --git a/Mathlib/Data/Complex/Module.lean b/Mathlib/Data/Complex/Module.lean index 880e0c28ab5d89..219999ee957ae0 100644 --- a/Mathlib/Data/Complex/Module.lean +++ b/Mathlib/Data/Complex/Module.lean @@ -313,7 +313,7 @@ def lift : { I' : A // I' * I' = -1 } ≃ (ℂ →ₐ[ℝ] A) where toFun I' := liftAux I' I'.prop invFun F := ⟨F I, by rw [← map_mul, I_mul_I, map_neg, map_one]⟩ left_inv I' := Subtype.ext <| liftAux_apply_I (I' : A) I'.prop - right_inv F := algHom_ext <| liftAux_apply_I _ _ + right_inv _ := algHom_ext <| liftAux_apply_I _ _ -- When applied to `Complex.I` itself, `lift` is the identity. @[simp] @@ -479,7 +479,7 @@ def Complex.selfAdjointEquiv : selfAdjoint ℂ ≃ₗ[ℝ] ℝ where toFun := fun z ↦ (z : ℂ).re invFun := fun x ↦ ⟨x, conj_ofReal x⟩ left_inv := fun z ↦ Subtype.ext <| conj_eq_iff_re.mp z.property.star_eq - right_inv := fun x ↦ rfl + right_inv := fun _ ↦ rfl map_add' := by simp map_smul' := by simp diff --git a/Mathlib/Data/Complex/Order.lean b/Mathlib/Data/Complex/Order.lean index 1b8327a6d9187d..47d0dd85378f3b 100644 --- a/Mathlib/Data/Complex/Order.lean +++ b/Mathlib/Data/Complex/Order.lean @@ -38,9 +38,9 @@ protected def partialOrder : PartialOrder ℂ where dsimp rw [lt_iff_le_not_le] tauto - le_refl x := ⟨le_rfl, rfl⟩ - le_trans x y z h₁ h₂ := ⟨h₁.1.trans h₂.1, h₁.2.trans h₂.2⟩ - le_antisymm z w h₁ h₂ := ext (h₁.1.antisymm h₂.1) h₁.2 + le_refl _ := ⟨le_rfl, rfl⟩ + le_trans _ _ _ h₁ h₂ := ⟨h₁.1.trans h₂.1, h₁.2.trans h₂.2⟩ + le_antisymm _ _ h₁ h₂ := ext (h₁.1.antisymm h₂.1) h₁.2 namespace _root_.ComplexOrder diff --git a/Mathlib/Data/DFinsupp/Basic.lean b/Mathlib/Data/DFinsupp/Basic.lean index 11111a2e35ca6f..e8b0e30b975ab9 100644 --- a/Mathlib/Data/DFinsupp/Basic.lean +++ b/Mathlib/Data/DFinsupp/Basic.lean @@ -131,7 +131,7 @@ theorem mapRange_apply (f : ∀ i, β₁ i → β₂ i) (hf : ∀ i, f i 0 = 0) rfl @[simp] -theorem mapRange_id (h : ∀ i, id (0 : β₁ i) = 0 := fun i => rfl) (g : Π₀ i : ι, β₁ i) : +theorem mapRange_id (h : ∀ i, id (0 : β₁ i) = 0 := fun _ => rfl) (g : Π₀ i : ι, β₁ i) : mapRange (fun i => (id : β₁ i → β₁ i)) h g = g := by ext rfl @@ -1356,7 +1356,7 @@ theorem sigmaCurry_single [∀ i, DecidableEq (α i)] [∀ i j, Zero (δ i j)] /-- The natural map between `Π₀ i (j : α i), δ i j` and `Π₀ (i : Σ i, α i), δ i.1 i.2`, inverse of `curry`. -/ def sigmaUncurry [∀ i j, Zero (δ i j)] [DecidableEq ι] (f : Π₀ (i) (j), δ i j) : - Π₀ i : Σi, _, δ i.1 i.2 where + Π₀ i : Σ_, _, δ i.1 i.2 where toFun i := f i.1 i.2 support' := f.support'.bind fun s => @@ -1422,7 +1422,7 @@ theorem sigmaUncurry_single [∀ i j, Zero (δ i j)] [∀ i, DecidableEq (α i)] This is the dfinsupp version of `Equiv.piCurry`. -/ def sigmaCurryEquiv [∀ i j, Zero (δ i j)] [DecidableEq ι] : - (Π₀ i : Σi, _, δ i.1 i.2) ≃ Π₀ (i) (j), δ i j where + (Π₀ i : Σ_, _, δ i.1 i.2) ≃ Π₀ (i) (j), δ i j where toFun := sigmaCurry invFun := sigmaUncurry left_inv f := by @@ -1776,7 +1776,7 @@ theorem _root_.AddSubmonoid.mem_iSup_iff_exists_dfinsupp [AddCommMonoid γ] (S : /-- A variant of `AddSubmonoid.mem_iSup_iff_exists_dfinsupp` with the RHS fully unfolded. -/ theorem _root_.AddSubmonoid.mem_iSup_iff_exists_dfinsupp' [AddCommMonoid γ] (S : ι → AddSubmonoid γ) [∀ (i) (x : S i), Decidable (x ≠ 0)] (x : γ) : - x ∈ iSup S ↔ ∃ f : Π₀ i, S i, (f.sum fun i xi => ↑xi) = x := by + x ∈ iSup S ↔ ∃ f : Π₀ i, S i, (f.sum fun _ xi => ↑xi) = x := by rw [AddSubmonoid.mem_iSup_iff_exists_dfinsupp] simp_rw [sumAddHom_apply] rfl diff --git a/Mathlib/Data/DFinsupp/Order.lean b/Mathlib/Data/DFinsupp/Order.lean index ebb4970f7a3ceb..6ace1dada4df5e 100644 --- a/Mathlib/Data/DFinsupp/Order.lean +++ b/Mathlib/Data/DFinsupp/Order.lean @@ -68,8 +68,8 @@ variable [∀ i, Preorder (α i)] {f g : Π₀ i, α i} instance : Preorder (Π₀ i, α i) := { (inferInstance : LE (DFinsupp α)) with - le_refl := fun f i ↦ le_rfl - le_trans := fun f g h hfg hgh i ↦ (hfg i).trans (hgh i) } + le_refl := fun _ _ ↦ le_rfl + le_trans := fun _ _ _ hfg hgh i ↦ (hfg i).trans (hgh i) } lemma lt_def : f < g ↔ f ≤ g ∧ ∃ i, f i < g i := Pi.lt_def @[simp, norm_cast] lemma coe_lt_coe : ⇑f < g ↔ f < g := Iff.rfl diff --git a/Mathlib/Data/ENNReal/Basic.lean b/Mathlib/Data/ENNReal/Basic.lean index 11fe99146aa064..cd2388d50e256b 100644 --- a/Mathlib/Data/ENNReal/Basic.lean +++ b/Mathlib/Data/ENNReal/Basic.lean @@ -526,7 +526,7 @@ theorem lt_iff_exists_rat_btwn : rcases lt_iff_exists_coe.1 cb with ⟨r, rfl, _⟩ rcases (NNReal.lt_iff_exists_rat_btwn _ _).1 (coe_lt_coe.1 pc) with ⟨q, hq0, pq, qr⟩ exact ⟨q, hq0, coe_lt_coe.2 pq, lt_trans (coe_lt_coe.2 qr) cb⟩, - fun ⟨q, _, qa, qb⟩ => lt_trans qa qb⟩ + fun ⟨_, _, qa, qb⟩ => lt_trans qa qb⟩ theorem lt_iff_exists_real_btwn : a < b ↔ ∃ r : ℝ, 0 ≤ r ∧ a < ENNReal.ofReal r ∧ (ENNReal.ofReal r : ℝ≥0∞) < b := diff --git a/Mathlib/Data/ENNReal/Inv.lean b/Mathlib/Data/ENNReal/Inv.lean index 19655b9e5fb17c..0f9c29a783d26c 100644 --- a/Mathlib/Data/ENNReal/Inv.lean +++ b/Mathlib/Data/ENNReal/Inv.lean @@ -465,7 +465,7 @@ def orderIsoIicCoe (a : ℝ≥0) : Iic (a : ℝ≥0∞) ≃o Iic a := OrderIso.symm { toFun := fun x => ⟨x, coe_le_coe.2 x.2⟩ invFun := fun x => ⟨ENNReal.toNNReal x, coe_le_coe.1 <| coe_toNNReal_le_self.trans x.2⟩ - left_inv := fun x => Subtype.ext <| toNNReal_coe _ + left_inv := fun _ => Subtype.ext <| toNNReal_coe _ right_inv := fun x => Subtype.ext <| coe_toNNReal (ne_top_of_le_ne_top coe_ne_top x.2) map_rel_iff' := fun {_ _} => by simp only [Equiv.coe_fn_mk, Subtype.mk_le_mk, coe_le_coe, Subtype.coe_le_coe] } diff --git a/Mathlib/Data/ENNReal/Real.lean b/Mathlib/Data/ENNReal/Real.lean index e9cc940e486125..bccf679b634a59 100644 --- a/Mathlib/Data/ENNReal/Real.lean +++ b/Mathlib/Data/ENNReal/Real.lean @@ -541,7 +541,7 @@ theorem add_iInf {a : ℝ≥0∞} : a + iInf f = ⨅ b, a + f b := by theorem iInf_add_iInf (h : ∀ i j, ∃ k, f k + g k ≤ f i + g j) : iInf f + iInf g = ⨅ a, f a + g a := suffices ⨅ a, f a + g a ≤ iInf f + iInf g from - le_antisymm (le_iInf fun a => add_le_add (iInf_le _ _) (iInf_le _ _)) this + le_antisymm (le_iInf fun _ => add_le_add (iInf_le _ _) (iInf_le _ _)) this calc ⨅ a, f a + g a ≤ ⨅ (a) (a'), f a + g a' := le_iInf₂ fun a a' => let ⟨k, h⟩ := h a a'; iInf_le_of_le k h diff --git a/Mathlib/Data/Fin/Tuple/Basic.lean b/Mathlib/Data/Fin/Tuple/Basic.lean index c89677f2b5daeb..6f1f772191c56e 100644 --- a/Mathlib/Data/Fin/Tuple/Basic.lean +++ b/Mathlib/Data/Fin/Tuple/Basic.lean @@ -195,7 +195,7 @@ theorem consCases_cons {P : (∀ i : Fin n.succ, α i) → Sort v} (h : ∀ x₀ def consInduction {α : Sort*} {P : ∀ {n : ℕ}, (Fin n → α) → Sort v} (h0 : P Fin.elim0) (h : ∀ {n} (x₀) (x : Fin n → α), P x → P (Fin.cons x₀ x)) : ∀ {n : ℕ} (x : Fin n → α), P x | 0, x => by convert h0 - | n + 1, x => consCases (fun x₀ x ↦ h _ _ <| consInduction h0 h _) x + | _ + 1, x => consCases (fun _ _ ↦ h _ _ <| consInduction h0 h _) x theorem cons_injective_of_injective {α} {x₀ : α} {x : Fin n → α} (hx₀ : x₀ ∉ Set.range x) (hx : Function.Injective x) : Function.Injective (cons x₀ x : Fin n.succ → α) := by @@ -710,7 +710,7 @@ def snocInduction {α : Sort*} (h0 : P Fin.elim0) (h : ∀ {n} (x : Fin n → α) (x₀), P x → P (Fin.snoc x x₀)) : ∀ {n : ℕ} (x : Fin n → α), P x | 0, x => by convert h0 - | n + 1, x => snocCases (fun x₀ x ↦ h _ _ <| snocInduction h0 h _) x + | _ + 1, x => snocCases (fun _ _ ↦ h _ _ <| snocInduction h0 h _) x end TupleRight @@ -947,7 +947,7 @@ def find : ∀ {n : ℕ} (p : Fin n → Prop) [DecidablePred p], Option (Fin n) /-- If `find p = some i`, then `p i` holds -/ theorem find_spec : ∀ {n : ℕ} (p : Fin n → Prop) [DecidablePred p] {i : Fin n} (_ : i ∈ Fin.find p), p i - | 0, p, I, i, hi => Option.noConfusion hi + | 0, _, _, _, hi => Option.noConfusion hi | n + 1, p, I, i, hi => by rw [find] at hi cases' h : find fun i : Fin n ↦ p (i.castLT (Nat.lt_succ_of_lt i.2)) with j @@ -965,7 +965,7 @@ theorem find_spec : /-- `find p` does not return `none` if and only if `p i` holds at some index `i`. -/ theorem isSome_find_iff : ∀ {n : ℕ} {p : Fin n → Prop} [DecidablePred p], (find p).isSome ↔ ∃ i, p i - | 0, p, _ => iff_of_false (fun h ↦ Bool.noConfusion h) fun ⟨i, _⟩ ↦ Fin.elim0 i + | 0, _, _ => iff_of_false (fun h ↦ Bool.noConfusion h) fun ⟨i, _⟩ ↦ Fin.elim0 i | n + 1, p, _ => ⟨fun h ↦ by rw [Option.isSome_iff_exists] at h @@ -990,7 +990,7 @@ the indices where `p` holds. -/ theorem find_min : ∀ {n : ℕ} {p : Fin n → Prop} [DecidablePred p] {i : Fin n} (_ : i ∈ Fin.find p) {j : Fin n} (_ : j < i), ¬p j - | 0, p, _, i, hi, _, _, _ => Option.noConfusion hi + | 0, _, _, _, hi, _, _, _ => Option.noConfusion hi | n + 1, p, _, i, hi, ⟨j, hjn⟩, hj, hpj => by rw [find] at hi cases' h : find fun i : Fin n ↦ p (i.castLT (Nat.lt_succ_of_lt i.2)) with k diff --git a/Mathlib/Data/Fin/Tuple/Reflection.lean b/Mathlib/Data/Fin/Tuple/Reflection.lean index 2caca583ee4d89..d671fe0358d8aa 100644 --- a/Mathlib/Data/Fin/Tuple/Reflection.lean +++ b/Mathlib/Data/Fin/Tuple/Reflection.lean @@ -39,7 +39,7 @@ def seq : ∀ {m}, (Fin m → α → β) → (Fin m → α) → Fin m → β @[simp] theorem seq_eq : ∀ {m} (f : Fin m → α → β) (v : Fin m → α), seq f v = fun i => f i (v i) - | 0, f, v => Subsingleton.elim _ _ + | 0, _, _ => Subsingleton.elim _ _ | n + 1, f, v => funext fun i => by simp_rw [seq, seq_eq] @@ -140,7 +140,7 @@ example [AddCommMonoid α] (a : Fin 3 → α) : ∑ i, a i = a 0 + a 1 + a 2 := -/ @[simp] theorem sum_eq [AddCommMonoid α] : ∀ {m} (a : Fin m → α), sum a = ∑ i, a i - | 0, a => rfl + | 0, _ => rfl | 1, a => (Fintype.sum_unique a).symm | n + 2, a => by rw [Fin.sum_univ_castSucc, sum, sum_eq] diff --git a/Mathlib/Data/FinEnum.lean b/Mathlib/Data/FinEnum.lean index c2d94fcfa23add..f4a3ae5c5e0e22 100644 --- a/Mathlib/Data/FinEnum.lean +++ b/Mathlib/Data/FinEnum.lean @@ -138,7 +138,7 @@ instance PSigma.finEnum [FinEnum α] [∀ a, FinEnum (β a)] : FinEnum (Σ'a, β instance PSigma.finEnumPropLeft {α : Prop} {β : α → Type v} [∀ a, FinEnum (β a)] [Decidable α] : FinEnum (Σ'a, β a) := if h : α then ofList ((toList (β h)).map <| PSigma.mk h) fun ⟨a, Ba⟩ => by simp - else ofList [] fun ⟨a, Ba⟩ => (h a).elim + else ofList [] fun ⟨a, _⟩ => (h a).elim instance PSigma.finEnumPropRight {β : α → Prop} [FinEnum α] [∀ a, Decidable (β a)] : FinEnum (Σ'a, β a) := diff --git a/Mathlib/Data/Finite/Card.lean b/Mathlib/Data/Finite/Card.lean index c16b94bbcd01b5..397130772c82fe 100644 --- a/Mathlib/Data/Finite/Card.lean +++ b/Mathlib/Data/Finite/Card.lean @@ -43,7 +43,7 @@ def Finite.equivFinOfCardEq [Finite α] {n : ℕ} (h : Nat.card α = n) : α ≃ apply Finite.equivFin theorem Nat.card_eq (α : Type*) : - Nat.card α = if h : Finite α then @Fintype.card α (Fintype.ofFinite α) else 0 := by + Nat.card α = if _ : Finite α then @Fintype.card α (Fintype.ofFinite α) else 0 := by cases finite_or_infinite α · letI := Fintype.ofFinite α simp only [*, Nat.card_eq_fintype_card, dif_pos] diff --git a/Mathlib/Data/Finmap.lean b/Mathlib/Data/Finmap.lean index c4d3fe1b9820d8..9d6ec0b616a210 100644 --- a/Mathlib/Data/Finmap.lean +++ b/Mathlib/Data/Finmap.lean @@ -110,7 +110,7 @@ theorem liftOn_toFinmap {γ} (s : AList β) (f : AList β → γ) (H) : liftOn def liftOn₂ {γ} (s₁ s₂ : Finmap β) (f : AList β → AList β → γ) (H : ∀ a₁ b₁ a₂ b₂ : AList β, a₁.entries ~ a₂.entries → b₁.entries ~ b₂.entries → f a₁ b₁ = f a₂ b₂) : γ := - liftOn s₁ (fun l₁ => liftOn s₂ (f l₁) fun b₁ b₂ p => H _ _ _ _ (Perm.refl _) p) fun a₁ a₂ p => by + liftOn s₁ (fun l₁ => liftOn s₂ (f l₁) fun _ _ p => H _ _ _ _ (Perm.refl _) p) fun a₁ a₂ p => by have H' : f a₁ = f a₂ := funext fun _ => H _ _ _ _ p (Perm.refl _) simp only [H'] diff --git a/Mathlib/Data/Finset/Basic.lean b/Mathlib/Data/Finset/Basic.lean index e86ab424aa5fb5..d8f077efcc2ea0 100644 --- a/Mathlib/Data/Finset/Basic.lean +++ b/Mathlib/Data/Finset/Basic.lean @@ -273,9 +273,9 @@ instance : HasSSubset (Finset α) := instance partialOrder : PartialOrder (Finset α) where le := (· ⊆ ·) lt := (· ⊂ ·) - le_refl s a := id - le_trans s t u hst htu a ha := htu <| hst ha - le_antisymm s t hst hts := ext fun a => ⟨@hst _, @hts _⟩ + le_refl _ _ := id + le_trans _ _ _ hst htu _ ha := htu <| hst ha + le_antisymm _ _ hst hts := ext fun _ => ⟨@hst _, @hts _⟩ instance : IsRefl (Finset α) (· ⊆ ·) := show IsRefl (Finset α) (· ≤ ·) by infer_instance @@ -2603,7 +2603,7 @@ lemma range_nontrivial {n : ℕ} (hn : 1 < n) : (Finset.range n).Nontrivial := b theorem exists_nat_subset_range (s : Finset ℕ) : ∃ n : ℕ, s ⊆ range n := s.induction_on (by simp) - fun a s _ ⟨n, hn⟩ => ⟨max (a + 1) n, insert_subset (by simp) (hn.trans (by simp))⟩ + fun a _ _ ⟨n, hn⟩ => ⟨max (a + 1) n, insert_subset (by simp) (hn.trans (by simp))⟩ end Range @@ -2637,7 +2637,7 @@ def notMemRangeEquiv (k : ℕ) : { n // n ∉ range k } ≃ ℕ where rw [Subtype.ext_iff_val] apply Nat.sub_add_cancel simpa using j.2 - right_inv j := Nat.add_sub_cancel_right _ _ + right_inv _ := Nat.add_sub_cancel_right _ _ @[simp] theorem coe_notMemRangeEquiv (k : ℕ) : diff --git a/Mathlib/Data/Finset/Card.lean b/Mathlib/Data/Finset/Card.lean index 6cd9aef810c640..653bbfc7a2fe2d 100644 --- a/Mathlib/Data/Finset/Card.lean +++ b/Mathlib/Data/Finset/Card.lean @@ -254,7 +254,7 @@ theorem fiber_card_ne_zero_iff_mem_image (s : Finset α) (f : α → β) [Decida lemma card_filter_le_iff (s : Finset α) (P : α → Prop) [DecidablePred P] (n : ℕ) : (s.filter P).card ≤ n ↔ ∀ s' ⊆ s, n < s'.card → ∃ a ∈ s', ¬ P a := (s.1.card_filter_le_iff P n).trans ⟨fun H s' hs' h ↦ H s'.1 (by aesop) h, - fun H s' hs' h ↦ H ⟨s', nodup_of_le hs' s.2⟩ (fun x hx ↦ subset_of_le hs' hx) h⟩ + fun H s' hs' h ↦ H ⟨s', nodup_of_le hs' s.2⟩ (fun _ hx ↦ subset_of_le hs' hx) h⟩ @[simp] theorem card_map (f : α ↪ β) : (s.map f).card = s.card := @@ -443,7 +443,7 @@ theorem inj_on_of_surj_on_of_card_le (f : ∀ a ∈ s, β) (hf : ∀ a ha, f a h have hsg : Surjective g := fun x => let ⟨y, hy⟩ := surj_on_of_inj_on_of_card_le (fun (x : { x // x ∈ t }) (_ : x ∈ t.attach) => g x) - (fun x _ => show g x ∈ s.attach from mem_attach _ _) (fun x y _ _ hxy => hg hxy) (by simpa) + (fun x _ => show g x ∈ s.attach from mem_attach _ _) (fun _ _ _ _ hxy => hg hxy) (by simpa) x (mem_attach _ _) ⟨y, hy.snd.symm⟩ have hif : Injective f' := @@ -696,7 +696,7 @@ theorem card_eq_succ : s.card = n + 1 ↔ ∃ a t, a ∉ t ∧ insert a t = s let ⟨a, has⟩ := card_pos.mp (h.symm ▸ Nat.zero_lt_succ _ : 0 < s.card) ⟨a, s.erase a, s.not_mem_erase a, insert_erase has, by simp only [h, card_erase_of_mem has, Nat.add_sub_cancel_right]⟩, - fun ⟨a, t, hat, s_eq, n_eq⟩ => s_eq ▸ n_eq ▸ card_insert_of_not_mem hat⟩ + fun ⟨_, _, hat, s_eq, n_eq⟩ => s_eq ▸ n_eq ▸ card_insert_of_not_mem hat⟩ theorem card_eq_two : s.card = 2 ↔ ∃ x y, x ≠ y ∧ s = {x, y} := by constructor diff --git a/Mathlib/Data/Finset/Functor.lean b/Mathlib/Data/Finset/Functor.lean index 1359446c44d7e9..219d4336368e28 100644 --- a/Mathlib/Data/Finset/Functor.lean +++ b/Mathlib/Data/Finset/Functor.lean @@ -37,8 +37,8 @@ construct `Functor Finset` when working classically. -/ protected instance functor : Functor Finset where map f s := s.image f instance lawfulFunctor : LawfulFunctor Finset where - id_map s := image_id - comp_map f g s := image_image.symm + id_map _ := image_id + comp_map _ _ _ := image_image.symm map_const {α} {β} := by simp only [Functor.mapConst, Functor.map] @[simp] @@ -115,8 +115,8 @@ instance lawfulApplicative : LawfulApplicative Finset := obtain ⟨_, _, rfl⟩ := hf exact hb pure_seq := fun f s => by simp only [pure_def, seq_def, sup_singleton, fmap_def] - map_pure := fun f a => image_singleton _ _ - seq_pure := fun s a => sup_singleton'' _ _ + map_pure := fun _ _ => image_singleton _ _ + seq_pure := fun _ _ => sup_singleton'' _ _ seq_assoc := fun s t u => by ext a simp_rw [seq_def, fmap_def] @@ -153,9 +153,9 @@ theorem bind_def {α β} : (· >>= ·) = sup (α := Finset α) (β := β) := instance : LawfulMonad Finset := { Finset.lawfulApplicative with - bind_pure_comp := fun f s => sup_singleton'' _ _ - bind_map := fun t s => rfl - pure_bind := fun t s => sup_singleton + bind_pure_comp := fun _ _ => sup_singleton'' _ _ + bind_map := fun _ _ => rfl + pure_bind := fun _ _ => sup_singleton bind_assoc := fun s f g => by simp only [bind, ← sup_biUnion, sup_eq_biUnion, biUnion_biUnion] } end Monad diff --git a/Mathlib/Data/Finset/Grade.lean b/Mathlib/Data/Finset/Grade.lean index 4c5c5fc907f851..73c5f16bbbb907 100644 --- a/Mathlib/Data/Finset/Grade.lean +++ b/Mathlib/Data/Finset/Grade.lean @@ -47,7 +47,7 @@ lemma isAtom_iff : IsAtom s ↔ ∃ a, s = {a} := by simp [← bot_covBy_iff, co instance instGradeMinOrder : GradeMinOrder ℕ (Multiset α) where grade := card grade_strictMono := card_strictMono - covBy_grade s t := CovBy.card_multiset + covBy_grade _ _ := CovBy.card_multiset isMin_grade s hs := by rw [isMin_iff_eq_bot.1 hs]; exact isMin_bot @[simp] lemma grade_eq (m : Multiset α) : grade ℕ m = card m := rfl diff --git a/Mathlib/Data/Finset/Image.lean b/Mathlib/Data/Finset/Image.lean index 88939058da20c0..7901095ab605f2 100644 --- a/Mathlib/Data/Finset/Image.lean +++ b/Mathlib/Data/Finset/Image.lean @@ -141,7 +141,7 @@ theorem _root_.Function.Commute.finset_map {f g : α ↪ α} (h : Function.Commu @[simp] theorem map_subset_map {s₁ s₂ : Finset α} : s₁.map f ⊆ s₂.map f ↔ s₁ ⊆ s₂ := - ⟨fun h x xs => (mem_map' _).1 <| h <| (mem_map' f).2 xs, + ⟨fun h _ xs => (mem_map' _).1 <| h <| (mem_map' f).2 xs, fun h => by simp [subset_def, Multiset.map_subset_map h]⟩ @[gcongr] alias ⟨_, _root_.GCongr.finsetMap_subset⟩ := map_subset_map @@ -625,7 +625,7 @@ elements belong to `s`. -/ protected def subtype {α} (p : α → Prop) [DecidablePred p] (s : Finset α) : Finset (Subtype p) := (s.filter p).attach.map ⟨fun x => ⟨x.1, by simpa using (Finset.mem_filter.1 x.2).2⟩, - fun x y H => Subtype.eq <| Subtype.mk.inj H⟩ + fun _ _ H => Subtype.eq <| Subtype.mk.inj H⟩ @[simp] theorem mem_subtype {p : α → Prop} [DecidablePred p] {s : Finset α} : diff --git a/Mathlib/Data/Finset/Lattice.lean b/Mathlib/Data/Finset/Lattice.lean index b41a111701bda1..6f66f021e480f1 100644 --- a/Mathlib/Data/Finset/Lattice.lean +++ b/Mathlib/Data/Finset/Lattice.lean @@ -629,7 +629,7 @@ protected theorem lt_sup_iff : a < s.sup f ↔ ∃ b ∈ s, a < f b := by @[simp] protected theorem sup_lt_iff (ha : ⊥ < a) : s.sup f < a ↔ ∀ b ∈ s, f b < a := - ⟨fun hs b hb => lt_of_le_of_lt (le_sup hb) hs, + ⟨fun hs _ hb => lt_of_le_of_lt (le_sup hb) hs, Finset.cons_induction_on s (fun _ => ha) fun c t hc => by simpa only [sup_cons, sup_lt_iff, mem_cons, forall_eq_or_imp] using And.imp_right⟩ diff --git a/Mathlib/Data/Finset/NatAntidiagonal.lean b/Mathlib/Data/Finset/NatAntidiagonal.lean index c5cb7f832ea29c..d1860f6db928e9 100644 --- a/Mathlib/Data/Finset/NatAntidiagonal.lean +++ b/Mathlib/Data/Finset/NatAntidiagonal.lean @@ -149,12 +149,12 @@ theorem antidiagonal.snd_lt {n : ℕ} {kl : ℕ × ℕ} (hlk : kl ∈ antidiagon /-- The set `antidiagonal n` is equivalent to `Fin (n+1)`, via the first projection. --/ @[simps] def antidiagonalEquivFin (n : ℕ) : antidiagonal n ≃ Fin (n + 1) where - toFun := fun ⟨⟨i, j⟩, h⟩ ↦ ⟨i, antidiagonal.fst_lt h⟩ + toFun := fun ⟨⟨i, _⟩, h⟩ ↦ ⟨i, antidiagonal.fst_lt h⟩ invFun := fun ⟨i, h⟩ ↦ ⟨⟨i, n - i⟩, by rw [mem_antidiagonal, add_comm, Nat.sub_add_cancel] exact Nat.le_of_lt_succ h⟩ left_inv := by rintro ⟨⟨i, j⟩, h⟩; ext; rfl - right_inv x := rfl + right_inv _ := rfl end Nat diff --git a/Mathlib/Data/Finset/NoncommProd.lean b/Mathlib/Data/Finset/NoncommProd.lean index 6074576260a479..7140198dd82379 100644 --- a/Mathlib/Data/Finset/NoncommProd.lean +++ b/Mathlib/Data/Finset/NoncommProd.lean @@ -202,7 +202,7 @@ theorem noncommProd_commute (s : Multiset α) (comm) (y : α) (h : ∀ x ∈ s, exact Commute.list_prod_right _ _ h theorem mul_noncommProd_erase [DecidableEq α] (s : Multiset α) {a : α} (h : a ∈ s) (comm) - (comm' := fun x hx y hy hxy ↦ comm (s.mem_of_mem_erase hx) (s.mem_of_mem_erase hy) hxy) : + (comm' := fun _ hx _ hy hxy ↦ comm (s.mem_of_mem_erase hx) (s.mem_of_mem_erase hy) hxy) : a * (s.erase a).noncommProd comm' = s.noncommProd comm := by induction' s using Quotient.inductionOn with l simp only [quot_mk_to_coe, mem_coe, coe_erase, noncommProd_coe] at comm h ⊢ @@ -213,7 +213,7 @@ theorem mul_noncommProd_erase [DecidableEq α] (s : Multiset α) {a : α} (h : a exact comm hx hy hxy theorem noncommProd_erase_mul [DecidableEq α] (s : Multiset α) {a : α} (h : a ∈ s) (comm) - (comm' := fun x hx y hy hxy ↦ comm (s.mem_of_mem_erase hx) (s.mem_of_mem_erase hy) hxy) : + (comm' := fun _ hx _ hy hxy ↦ comm (s.mem_of_mem_erase hx) (s.mem_of_mem_erase hy) hxy) : (s.erase a).noncommProd comm' * a = s.noncommProd comm := by suffices ∀ b ∈ erase s a, Commute a b by rw [← (noncommProd_commute (s.erase a) comm' a this).eq, mul_noncommProd_erase s h comm comm'] @@ -317,7 +317,7 @@ variable [FunLike F β γ] @[to_additive] theorem map_noncommProd [MonoidHomClass F β γ] (s : Finset α) (f : α → β) (comm) (g : F) : g (s.noncommProd f comm) = - s.noncommProd (fun i => g (f i)) fun x hx y hy _ => (comm.of_refl hx hy).map g := by + s.noncommProd (fun i => g (f i)) fun _ hx _ hy _ => (comm.of_refl hx hy).map g := by simp [noncommProd, Multiset.map_noncommProd] @[deprecated (since := "2024-07-23")] alias noncommProd_map := map_noncommProd @@ -340,14 +340,14 @@ theorem noncommProd_commute (s : Finset α) (f : α → β) (comm) (y : β) exact h x hx theorem mul_noncommProd_erase [DecidableEq α] (s : Finset α) {a : α} (h : a ∈ s) (f : α → β) (comm) - (comm' := fun x hx y hy hxy ↦ comm (s.mem_of_mem_erase hx) (s.mem_of_mem_erase hy) hxy) : + (comm' := fun _ hx _ hy hxy ↦ comm (s.mem_of_mem_erase hx) (s.mem_of_mem_erase hy) hxy) : f a * (s.erase a).noncommProd f comm' = s.noncommProd f comm := by classical simpa only [← Multiset.map_erase_of_mem _ _ h] using Multiset.mul_noncommProd_erase (s.1.map f) (Multiset.mem_map_of_mem f h) _ theorem noncommProd_erase_mul [DecidableEq α] (s : Finset α) {a : α} (h : a ∈ s) (f : α → β) (comm) - (comm' := fun x hx y hy hxy ↦ comm (s.mem_of_mem_erase hx) (s.mem_of_mem_erase hy) hxy) : + (comm' := fun _ hx _ hy hxy ↦ comm (s.mem_of_mem_erase hx) (s.mem_of_mem_erase hy) hxy) : (s.erase a).noncommProd f comm' * f a = s.noncommProd f comm := by classical simpa only [← Multiset.map_erase_of_mem _ _ h] using diff --git a/Mathlib/Data/Finset/Order.lean b/Mathlib/Data/Finset/Order.lean index 09570b4726fd68..f5a514599efdbb 100644 --- a/Mathlib/Data/Finset/Order.lean +++ b/Mathlib/Data/Finset/Order.lean @@ -18,9 +18,9 @@ theorem Directed.finset_le {r : α → α → Prop} [IsTrans α r] {ι} [hι : N (D : Directed r f) (s : Finset ι) : ∃ z, ∀ i ∈ s, r (f i) (f z) := show ∃ z, ∀ i ∈ s.1, r (f i) (f z) from Multiset.induction_on s.1 (let ⟨z⟩ := hι; ⟨z, fun _ ↦ by simp⟩) - fun i s ⟨j, H⟩ ↦ + fun i _ ⟨j, H⟩ ↦ let ⟨k, h₁, h₂⟩ := D i j - ⟨k, fun a h ↦ (Multiset.mem_cons.1 h).casesOn (fun h ↦ h.symm ▸ h₁) + ⟨k, fun _ h ↦ (Multiset.mem_cons.1 h).casesOn (fun h ↦ h.symm ▸ h₁) fun h ↦ _root_.trans (H _ h) h₂⟩ theorem Finset.exists_le [Nonempty α] [Preorder α] [IsDirected α (· ≤ ·)] (s : Finset α) : diff --git a/Mathlib/Data/Finset/Preimage.lean b/Mathlib/Data/Finset/Preimage.lean index 657acee0659191..520e3ea422f204 100644 --- a/Mathlib/Data/Finset/Preimage.lean +++ b/Mathlib/Data/Finset/Preimage.lean @@ -46,7 +46,7 @@ theorem preimage_univ {f : α → β} [Fintype α] [Fintype β] (hf) : preimage @[simp] theorem preimage_inter [DecidableEq α] [DecidableEq β] {f : α → β} {s t : Finset β} (hs : Set.InjOn f (f ⁻¹' ↑s)) (ht : Set.InjOn f (f ⁻¹' ↑t)) : - (preimage (s ∩ t) f fun x₁ hx₁ x₂ hx₂ => + (preimage (s ∩ t) f fun _ hx₁ _ hx₂ => hs (mem_of_mem_inter_left hx₁) (mem_of_mem_inter_left hx₂)) = preimage s f hs ∩ preimage t f ht := Finset.coe_injective (by simp) @@ -54,8 +54,8 @@ theorem preimage_inter [DecidableEq α] [DecidableEq β] {f : α → β} {s t : @[simp] theorem preimage_union [DecidableEq α] [DecidableEq β] {f : α → β} {s t : Finset β} (hst) : preimage (s ∪ t) f hst = - (preimage s f fun x₁ hx₁ x₂ hx₂ => hst (mem_union_left _ hx₁) (mem_union_left _ hx₂)) ∪ - preimage t f fun x₁ hx₁ x₂ hx₂ => hst (mem_union_right _ hx₁) (mem_union_right _ hx₂) := + (preimage s f fun _ hx₁ _ hx₂ => hst (mem_union_left _ hx₁) (mem_union_left _ hx₂)) ∪ + preimage t f fun _ hx₁ _ hx₂ => hst (mem_union_right _ hx₁) (mem_union_right _ hx₂) := Finset.coe_injective (by simp) @[simp, nolint simpNF] -- Porting note: linter complains that LHS doesn't simplify diff --git a/Mathlib/Data/Finset/Union.lean b/Mathlib/Data/Finset/Union.lean index 3df81fb5d2be10..fd0fac60d95eef 100644 --- a/Mathlib/Data/Finset/Union.lean +++ b/Mathlib/Data/Finset/Union.lean @@ -69,7 +69,7 @@ lemma coe_disjiUnion {h} : (s.disjiUnion t h : Set β) = ⋃ x ∈ (s : Set α), lemma disjiUnion_disjiUnion (s : Finset α) (f : α → Finset β) (g : β → Finset γ) (h1 h2) : (s.disjiUnion f h1).disjiUnion g h2 = s.attach.disjiUnion - (fun a ↦ ((f a).disjiUnion g) fun b hb c hc ↦ + (fun a ↦ ((f a).disjiUnion g) fun _ hb _ hc ↦ h2 (mem_disjiUnion.mpr ⟨_, a.prop, hb⟩) (mem_disjiUnion.mpr ⟨_, a.prop, hc⟩)) fun a _ b _ hab ↦ disjoint_left.mpr fun x hxa hxb ↦ by diff --git a/Mathlib/Data/Finsupp/Basic.lean b/Mathlib/Data/Finsupp/Basic.lean index a9e39269baa785..9d44b568a65db6 100644 --- a/Mathlib/Data/Finsupp/Basic.lean +++ b/Mathlib/Data/Finsupp/Basic.lean @@ -471,7 +471,7 @@ theorem mapDomain_sum [Zero N] {f : α → β} {s : α →₀ N} {v : α → N theorem mapDomain_support [DecidableEq β] {f : α → β} {s : α →₀ M} : (s.mapDomain f).support ⊆ s.support.image f := Finset.Subset.trans support_sum <| - Finset.Subset.trans (Finset.biUnion_mono fun a _ => support_single_subset) <| by + Finset.Subset.trans (Finset.biUnion_mono fun _ _ => support_single_subset) <| by rw [Finset.biUnion_singleton] theorem mapDomain_apply' (S : Set α) {f : α → β} (x : α →₀ M) (hS : (x.support : Set α) ⊆ S) @@ -1669,7 +1669,7 @@ This is the `Finsupp` version of `Equiv.Pi_curry`. -/ noncomputable def sigmaFinsuppEquivPiFinsupp : ((Σj, ιs j) →₀ α) ≃ ∀ j, ιs j →₀ α where toFun := split invFun f := - onFinset (Finset.univ.sigma fun j => (f j).support) (fun ji => f ji.1 ji.2) fun g hg => + onFinset (Finset.univ.sigma fun j => (f j).support) (fun ji => f ji.1 ji.2) fun _ hg => Finset.mem_sigma.mpr ⟨Finset.mem_univ _, mem_support_iff.mpr hg⟩ left_inv f := by ext diff --git a/Mathlib/Data/Finsupp/Multiset.lean b/Mathlib/Data/Finsupp/Multiset.lean index 4d4b1f940f9a8f..9e68300b843cc6 100644 --- a/Mathlib/Data/Finsupp/Multiset.lean +++ b/Mathlib/Data/Finsupp/Multiset.lean @@ -128,7 +128,7 @@ the multiplicities of the elements of `s`. -/ def toFinsupp : Multiset α ≃+ (α →₀ ℕ) where toFun s := ⟨s.toFinset, fun a => s.count a, fun a => by simp⟩ invFun f := Finsupp.toMultiset f - map_add' s t := Finsupp.ext fun _ => count_add _ _ _ + map_add' _ _ := Finsupp.ext fun _ => count_add _ _ _ right_inv f := Finsupp.ext fun a => by simp only [Finsupp.toMultiset_apply, Finsupp.sum, Multiset.count_sum', diff --git a/Mathlib/Data/Finsupp/Order.lean b/Mathlib/Data/Finsupp/Order.lean index 2d4dbe742d79c4..cb0d481298010d 100644 --- a/Mathlib/Data/Finsupp/Order.lean +++ b/Mathlib/Data/Finsupp/Order.lean @@ -73,8 +73,8 @@ variable [Preorder α] {f g : ι →₀ α} {i : ι} {a b : α} instance preorder : Preorder (ι →₀ α) := { Finsupp.instLEFinsupp with - le_refl := fun f i => le_rfl - le_trans := fun f g h hfg hgh i => (hfg i).trans (hgh i) } + le_refl := fun _ _ => le_rfl + le_trans := fun _ _ _ hfg hgh i => (hfg i).trans (hgh i) } lemma lt_def : f < g ↔ f ≤ g ∧ ∃ i, f i < g i := Pi.lt_def @[simp, norm_cast] lemma coe_lt_coe : ⇑f < g ↔ f < g := Iff.rfl diff --git a/Mathlib/Data/Fintype/Card.lean b/Mathlib/Data/Fintype/Card.lean index 45c0a90562ef59..641354c5ca1aea 100644 --- a/Mathlib/Data/Fintype/Card.lean +++ b/Mathlib/Data/Fintype/Card.lean @@ -899,7 +899,7 @@ theorem exists_not_mem_finset [Infinite α] (s : Finset α) : ∃ x, x ∉ s := not_forall.1 fun h => Fintype.false ⟨s, h⟩ -- see Note [lower instance priority] -instance (priority := 100) (α : Type*) [H : Infinite α] : Nontrivial α := +instance (priority := 100) (α : Type*) [Infinite α] : Nontrivial α := ⟨let ⟨x, _hx⟩ := exists_not_mem_finset (∅ : Finset α) let ⟨y, hy⟩ := exists_not_mem_finset ({x} : Finset α) ⟨y, x, by simpa only [mem_singleton] using hy⟩⟩ @@ -977,7 +977,7 @@ private noncomputable def natEmbeddingAux (α : Type*) [Infinite α] : ℕ → letI := Classical.decEq α Classical.choose (exists_not_mem_finset - ((Multiset.range n).pmap (fun m (hm : m < n) => natEmbeddingAux _ m) fun _ => + ((Multiset.range n).pmap (fun m (_ : m < n) => natEmbeddingAux _ m) fun _ => Multiset.mem_range.1).toFinset) private theorem natEmbeddingAux_injective (α : Type*) [Infinite α] : diff --git a/Mathlib/Data/Fintype/Order.lean b/Mathlib/Data/Fintype/Order.lean index 127472ab51f1dd..9e9c7d1d134d19 100644 --- a/Mathlib/Data/Fintype/Order.lean +++ b/Mathlib/Data/Fintype/Order.lean @@ -88,9 +88,9 @@ noncomputable abbrev toCompleteLattice [Lattice α] [BoundedOrder α] : Complete sSup := fun s => s.toFinset.sup id sInf := fun s => s.toFinset.inf id le_sSup := fun _ _ ha => Finset.le_sup (f := id) (Set.mem_toFinset.mpr ha) - sSup_le := fun s _ ha => Finset.sup_le fun b hb => ha _ <| Set.mem_toFinset.mp hb + sSup_le := fun _ _ ha => Finset.sup_le fun _ hb => ha _ <| Set.mem_toFinset.mp hb sInf_le := fun _ _ ha => Finset.inf_le (Set.mem_toFinset.mpr ha) - le_sInf := fun s _ ha => Finset.le_inf fun b hb => ha _ <| Set.mem_toFinset.mp hb + le_sInf := fun _ _ ha => Finset.le_inf fun _ hb => ha _ <| Set.mem_toFinset.mp hb -- See note [reducible non-instances] /-- A finite bounded distributive lattice is completely distributive. -/ diff --git a/Mathlib/Data/Fintype/Quotient.lean b/Mathlib/Data/Fintype/Quotient.lean index 1675f05ea0a49a..611a8d77d5b385 100644 --- a/Mathlib/Data/Fintype/Quotient.lean +++ b/Mathlib/Data/Fintype/Quotient.lean @@ -25,7 +25,7 @@ corresponding quotient type, then there is a corresponding term in the quotient of the product of the setoids indexed by `l`. -/ def Quotient.finChoiceAux {ι : Type*} [DecidableEq ι] {α : ι → Type*} [S : ∀ i, Setoid (α i)] : ∀ l : List ι, (∀ i ∈ l, Quotient (S i)) → @Quotient (∀ i ∈ l, α i) (by infer_instance) - | [], _ => ⟦fun i h => nomatch List.not_mem_nil _ h⟧ + | [], _ => ⟦fun _ h => nomatch List.not_mem_nil _ h⟧ | i :: l, f => by refine Quotient.liftOn₂ (f i (List.mem_cons_self _ _)) (Quotient.finChoiceAux l fun j h => f j (List.mem_cons_of_mem _ h)) ?_ ?_ @@ -40,7 +40,7 @@ def Quotient.finChoiceAux {ι : Type*} [DecidableEq ι] {α : ι → Type*} [S : theorem Quotient.finChoiceAux_eq {ι : Type*} [DecidableEq ι] {α : ι → Type*} [S : ∀ i, Setoid (α i)] : ∀ (l : List ι) (f : ∀ i ∈ l, α i), (Quotient.finChoiceAux l fun i h => ⟦f i h⟧) = ⟦f⟧ - | [], f => Quotient.sound fun i h => nomatch List.not_mem_nil _ h + | [], _ => Quotient.sound fun _ h => nomatch List.not_mem_nil _ h | i :: l, f => by simp only [finChoiceAux, Quotient.finChoiceAux_eq l, eq_mpr_eq_cast, lift_mk] refine Quotient.sound fun j h => ?_ @@ -66,7 +66,7 @@ def Quotient.finChoice {ι : Type*} [DecidableEq ι] [Fintype ι] {α : ι → T · exact eqRec_heq (φ := fun l : Multiset ι => @Quotient (∀ i ∈ l, α i) (by infer_instance)) (Quotient.sound h) (g a) · change HEq (g a) (g b); congr 1; exact Quotient.sound h)) - (fun f => ⟦fun i => f i (Finset.mem_univ _)⟧) (fun a b h => Quotient.sound fun i => by apply h) + (fun f => ⟦fun i => f i (Finset.mem_univ _)⟧) (fun _ _ h => Quotient.sound fun i => by apply h) theorem Quotient.finChoice_eq {ι : Type*} [DecidableEq ι] [Fintype ι] {α : ι → Type*} [∀ i, Setoid (α i)] (f : ∀ i, α i) : (Quotient.finChoice fun i => ⟦f i⟧) = ⟦f⟧ := by diff --git a/Mathlib/Data/Fintype/Sum.lean b/Mathlib/Data/Fintype/Sum.lean index 2e15afba5679f8..371313c49a3766 100644 --- a/Mathlib/Data/Fintype/Sum.lean +++ b/Mathlib/Data/Fintype/Sum.lean @@ -35,7 +35,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`. -/ -def fintypeOfFintypeNe (a : α) (h : Fintype { b // b ≠ a }) : Fintype α := +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/Int/Bitwise.lean b/Mathlib/Data/Int/Bitwise.lean index 664c817a6e578e..e0bc3e616150f6 100644 --- a/Mathlib/Data/Int/Bitwise.lean +++ b/Mathlib/Data/Int/Bitwise.lean @@ -404,7 +404,7 @@ attribute [local simp] Int.zero_div theorem shiftLeft_add : ∀ (m : ℤ) (n : ℕ) (k : ℤ), m <<< (n + k) = (m <<< (n : ℤ)) <<< k | (m : ℕ), n, (k : ℕ) => congr_arg ofNat (by simp [Nat.shiftLeft_eq, Nat.pow_add, mul_assoc]) - | -[m+1], n, (k : ℕ) => congr_arg negSucc (Nat.shiftLeft'_add _ _ _ _) + | -[_+1], _, (k : ℕ) => congr_arg negSucc (Nat.shiftLeft'_add _ _ _ _) | (m : ℕ), n, -[k+1] => subNatNat_elim n k.succ (fun n k i => (↑m) <<< i = (Nat.shiftLeft' false m n) >>> k) (fun (i n : ℕ) => diff --git a/Mathlib/Data/Int/LeastGreatest.lean b/Mathlib/Data/Int/LeastGreatest.lean index afe3c87b5a130d..9e3c23e0cbff13 100644 --- a/Mathlib/Data/Int/LeastGreatest.lean +++ b/Mathlib/Data/Int/LeastGreatest.lean @@ -77,7 +77,7 @@ integers, with an explicit upper bound and a proof that it is somewhere true, re the greatest value for which the predicate is true. -/ def greatestOfBdd {P : ℤ → Prop} [DecidablePred P] (b : ℤ) (Hb : ∀ z : ℤ, P z → z ≤ b) (Hinh : ∃ z : ℤ, P z) : { ub : ℤ // P ub ∧ ∀ z : ℤ, P z → z ≤ ub } := - have Hbdd' : ∀ z : ℤ, P (-z) → -b ≤ z := fun z h => neg_le.1 (Hb _ h) + have Hbdd' : ∀ z : ℤ, P (-z) → -b ≤ z := fun _ h => neg_le.1 (Hb _ h) have Hinh' : ∃ z : ℤ, P (-z) := let ⟨elt, Helt⟩ := Hinh ⟨-elt, by rw [neg_neg]; exact Helt⟩ diff --git a/Mathlib/Data/Int/Lemmas.lean b/Mathlib/Data/Int/Lemmas.lean index 61ccb22c02adb3..e989bd71419b0e 100644 --- a/Mathlib/Data/Int/Lemmas.lean +++ b/Mathlib/Data/Int/Lemmas.lean @@ -108,7 +108,7 @@ end Intervals theorem toNat_of_nonpos : ∀ {z : ℤ}, z ≤ 0 → z.toNat = 0 | 0, _ => rfl | (n + 1 : ℕ), h => (h.not_lt (by simp)).elim - | -[n+1], _ => rfl + | -[_+1], _ => rfl /-! ### bitwise ops diff --git a/Mathlib/Data/List/Basic.lean b/Mathlib/Data/List/Basic.lean index daea69185dee8a..0d8e6a7b48ee42 100644 --- a/Mathlib/Data/List/Basic.lean +++ b/Mathlib/Data/List/Basic.lean @@ -316,7 +316,7 @@ theorem getLast_cons_cons (a₁ a₂ : α) (l : List α) : theorem dropLast_append_getLast : ∀ {l : List α} (h : l ≠ []), dropLast l ++ [getLast l h] = l | [], h => absurd rfl h - | [a], h => rfl + | [_], _ => rfl | a :: b :: l, h => by rw [dropLast_cons₂, cons_append, getLast_cons (cons_ne_nil _ _)] congr @@ -381,16 +381,16 @@ theorem dropLast_append_getLast? : ∀ {l : List α}, ∀ a ∈ l.getLast?, drop theorem getLastI_eq_getLast? [Inhabited α] : ∀ l : List α, l.getLastI = l.getLast?.iget | [] => by simp [getLastI, Inhabited.default] - | [a] => rfl - | [a, b] => rfl - | [a, b, c] => rfl + | [_] => rfl + | [_, _] => rfl + | [_, _, _] => rfl | _ :: _ :: c :: l => by simp [getLastI, getLastI_eq_getLast? (c :: l)] #adaptation_note /-- 2024-07-10: removed `@[simp]` since the LHS simplifies using the simp set. -/ theorem getLast?_append_cons : ∀ (l₁ : List α) (a : α) (l₂ : List α), getLast? (l₁ ++ a :: l₂) = getLast? (a :: l₂) - | [], a, l₂ => rfl - | [b], a, l₂ => rfl + | [], _, _ => rfl + | [_], _, _ => rfl | b :: c :: l₁, a, l₂ => by rw [cons_append, cons_append, getLast?_cons_cons, ← cons_append, getLast?_append_cons (c :: l₁)] @@ -468,7 +468,7 @@ theorem cons_head?_tail : ∀ {l : List α} {a : α}, a ∈ head? l → a :: tai theorem head!_mem_head? [Inhabited α] : ∀ {l : List α}, l ≠ [] → head! l ∈ head? l | [], h => by contradiction - | a :: l, _ => rfl + | _ :: _, _ => rfl theorem cons_head!_tail [Inhabited α] {l : List α} (h : l ≠ []) : head! l :: tail l = l := cons_head?_tail (head!_mem_head? h) @@ -861,7 +861,7 @@ theorem modifyNthTail_modifyNthTail_same {f g : List α → List α} (n : ℕ) ( theorem modifyNth_eq_set (f : α → α) : ∀ (n) (l : List α), modifyNth f n l = ((fun a => set l n (f a)) <$> l[n]?).getD l | 0, l => by cases l <;> simp - | n + 1, [] => rfl + | _ + 1, [] => rfl | n + 1, b :: l => (congr_arg (cons b) (modifyNth_eq_set f n l)).trans <| by cases h : l[n]? <;> simp [h] @@ -994,8 +994,8 @@ theorem zipWith_nil (f : α → β → γ) (l : List α) : zipWith f l [] = [] : @[simp] theorem zipWith_flip (f : α → β → γ) : ∀ as bs, zipWith (flip f) bs as = zipWith f as bs | [], [] => rfl - | [], b :: bs => rfl - | a :: as, [] => rfl + | [], _ :: _ => rfl + | _ :: _, [] => rfl | a :: as, b :: bs => by simp! [zipWith_flip] rfl @@ -1153,7 +1153,7 @@ section Scanl variable {f : β → α → β} {b : β} {a : α} {l : List α} theorem length_scanl : ∀ a l, length (scanl f a l) = l.length + 1 - | a, [] => rfl + | _, [] => rfl | a, x :: l => by rw [scanl, length_cons, length_cons, ← succ_eq_add_one, congr_arg succ] exact length_scanl _ _ @@ -1244,7 +1244,7 @@ variable {f : α → α → α} theorem foldl1_eq_foldr1 [hassoc : Std.Associative f] : ∀ a b l, foldl f a (l ++ [b]) = foldr f b (a :: l) - | a, b, nil => rfl + | _, _, nil => rfl | a, b, c :: l => by simp only [cons_append, foldl_cons, foldr_cons, foldl1_eq_foldr1 _ _ l] rw [hassoc.assoc] @@ -1259,7 +1259,7 @@ theorem foldl_eq_of_comm_of_assoc [hcomm : Std.Commutative f] [hassoc : Std.Asso theorem foldl_eq_foldr [Std.Commutative f] [Std.Associative f] : ∀ a l, foldl f a l = foldr f a l - | a, nil => rfl + | _, nil => rfl | a, b :: l => by simp only [foldr_cons, foldl_eq_of_comm_of_assoc] rw [foldl_eq_foldr a l] @@ -1274,11 +1274,11 @@ variable (hf : ∀ a b c, f (f a b) c = f (f a c) b) include hf theorem foldl_eq_of_comm' : ∀ a b l, foldl f a (b :: l) = f (foldl f a l) b - | a, b, [] => rfl + | _, _, [] => rfl | a, b, c :: l => by rw [foldl, foldl, foldl, ← foldl_eq_of_comm' .., foldl, hf] theorem foldl_eq_foldr' : ∀ a l, foldl f a l = foldr (flip f) a l - | a, [] => rfl + | _, [] => rfl | a, b :: l => by rw [foldl_eq_of_comm' hf, foldr, foldl_eq_foldr' ..]; rfl end FoldlEqFoldlr' @@ -1289,7 +1289,7 @@ variable {f : α → β → β} theorem foldr_eq_of_comm' (hf : ∀ a b c, f a (f b c) = f b (f a c)) : ∀ a b l, foldr f a (b :: l) = foldr f (f b a) l - | a, b, [] => rfl + | _, _, [] => rfl | a, b, c :: l => by rw [foldr, foldr, foldr, hf, ← foldr_eq_of_comm' hf ..]; rfl end FoldlEqFoldlr' @@ -1306,7 +1306,7 @@ local notation l " <*> " a => foldl op a l theorem foldl_op_eq_op_foldr_assoc : ∀ {l : List α} {a₁ a₂}, ((l <*> a₁) ⋆ a₂) = a₁ ⋆ l.foldr (· ⋆ ·) a₂ - | [], a₁, a₂ => rfl + | [], _, _ => rfl | a :: l, a₁, a₂ => by simp only [foldl_cons, foldr_cons, foldl_assoc, ha.assoc]; rw [foldl_op_eq_op_foldr_assoc] @@ -1716,7 +1716,7 @@ lemma map_filter' {f : α → β} (hf : Injective f) (l : List α) lemma filter_attach' (l : List α) (p : {a // a ∈ l} → Bool) [DecidableEq α] : l.attach.filter p = - (l.filter fun x => ∃ h, p ⟨x, h⟩).attach.map (Subtype.map id fun x => mem_of_mem_filter) := by + (l.filter fun x => ∃ h, p ⟨x, h⟩).attach.map (Subtype.map id fun _ => mem_of_mem_filter) := by classical refine map_injective_iff.2 Subtype.coe_injective ?_ simp [comp_def, map_filter' _ Subtype.coe_injective] @@ -1724,7 +1724,7 @@ lemma filter_attach' (l : List α) (p : {a // a ∈ l} → Bool) [DecidableEq α -- Porting note: `Lean.Internal.coeM` forces us to type-ascript `{x // x ∈ l}` lemma filter_attach (l : List α) (p : α → Bool) : (l.attach.filter fun x => p x : List {x // x ∈ l}) = - (l.filter p).attach.map (Subtype.map id fun x => mem_of_mem_filter) := + (l.filter p).attach.map (Subtype.map id fun _ => mem_of_mem_filter) := map_injective_iff.2 Subtype.coe_injective <| by simp_rw [map_map, comp_def, Subtype.map, id, ← Function.comp_apply (g := Subtype.val), ← filter_map, attach_map_subtype_val] @@ -1887,7 +1887,7 @@ theorem map_diff [DecidableEq β] {f : α → β} (finj : Injective f) {l₁ l theorem erase_diff_erase_sublist_of_sublist {a : α} : ∀ {l₁ l₂ : List α}, l₁ <+ l₂ → (l₂.erase a).diff (l₁.erase a) <+ l₂.diff l₁ - | [], l₂, _ => erase_sublist _ _ + | [], _, _ => erase_sublist _ _ | b :: l₁, l₂, h => if heq : b = a then by simp only [heq, erase_cons_head, diff_cons]; rfl else by diff --git a/Mathlib/Data/List/Chain.lean b/Mathlib/Data/List/Chain.lean index 965aee596b8380..65eb76b1208730 100644 --- a/Mathlib/Data/List/Chain.lean +++ b/Mathlib/Data/List/Chain.lean @@ -42,7 +42,7 @@ theorem Chain.iff_mem {a : α} {l : List α} : constructor · exact ⟨mem_cons_self _ _, mem_cons_self _ _, r⟩ · exact IH.imp fun a b ⟨am, bm, h⟩ => ⟨mem_cons_of_mem _ am, mem_cons_of_mem _ bm, h⟩, - Chain.imp fun a b h => h.2.2⟩ + Chain.imp fun _ _ h => h.2.2⟩ theorem chain_singleton {a b : α} : Chain R a [b] ↔ R a b := by simp only [chain_cons, Chain.nil, and_true] @@ -95,7 +95,7 @@ theorem chain_of_chain_pmap {S : β → β → Prop} {p : α → Prop} (f : ∀ protected theorem Chain.pairwise [IsTrans α R] : ∀ {a : α} {l : List α}, Chain R a l → Pairwise R (a :: l) - | a, [], Chain.nil => pairwise_singleton _ _ + | _, [], Chain.nil => pairwise_singleton _ _ | a, _, @Chain.cons _ _ _ b l h hb => hb.pairwise.cons (by @@ -178,10 +178,10 @@ theorem chain'_cons {x y l} : Chain' R (x :: y :: l) ↔ R x y ∧ Chain' R (y : theorem chain'_isInfix : ∀ l : List α, Chain' (fun x y => [x, y] <:+: l) l | [] => chain'_nil - | [a] => chain'_singleton _ + | [_] => chain'_singleton _ | a :: b :: l => chain'_cons.2 - ⟨⟨[], l, by simp⟩, (chain'_isInfix (b :: l)).imp fun x y h => h.trans ⟨[a], [], by simp⟩⟩ + ⟨⟨[], l, by simp⟩, (chain'_isInfix (b :: l)).imp fun _ _ h => h.trans ⟨[a], [], by simp⟩⟩ theorem chain'_split {a : α} : ∀ {l₁ l₂ : List α}, Chain' R (l₁ ++ a :: l₂) ↔ Chain' R (l₁ ++ [a]) ∧ Chain' R (a :: l₂) diff --git a/Mathlib/Data/List/Destutter.lean b/Mathlib/Data/List/Destutter.lean index 5f80cabc726319..df3a1ad3b5778c 100644 --- a/Mathlib/Data/List/Destutter.lean +++ b/Mathlib/Data/List/Destutter.lean @@ -71,7 +71,7 @@ theorem mem_destutter' (a) : a ∈ l.destutter' R a := by · assumption theorem destutter'_is_chain : ∀ l : List α, ∀ {a b}, R a b → (l.destutter' R b).Chain R a - | [], a, b, h => chain_singleton.mpr h + | [], _, _, h => chain_singleton.mpr h | c :: l, a, b, h => by rw [destutter'] split_ifs with hbc diff --git a/Mathlib/Data/List/InsertNth.lean b/Mathlib/Data/List/InsertNth.lean index 00cef198f31e7b..83437b99c7356b 100644 --- a/Mathlib/Data/List/InsertNth.lean +++ b/Mathlib/Data/List/InsertNth.lean @@ -56,7 +56,7 @@ theorem insertNth_eraseIdx_of_ge : n < length as → n ≤ m → insertNth m a (as.eraseIdx n) = (as.insertNth (m + 1) a).eraseIdx n | 0, 0, [], has, _ => (lt_irrefl _ has).elim | 0, 0, _ :: as, _, _ => by simp [eraseIdx, insertNth] - | 0, m + 1, a :: as, _, _ => rfl + | 0, _ + 1, _ :: _, _, _ => rfl | n + 1, m + 1, a :: as, has, hmn => congr_arg (cons a) <| insertNth_eraseIdx_of_ge n m as (Nat.lt_of_succ_lt_succ has) (Nat.le_of_succ_le_succ hmn) @@ -77,7 +77,7 @@ theorem insertNth_comm (a b : α) : ∀ (i j : ℕ) (l : List α) (_ : i ≤ j) (_ : j ≤ length l), (l.insertNth i a).insertNth (j + 1) b = (l.insertNth j b).insertNth i a | 0, j, l => by simp [insertNth] - | i + 1, 0, l => fun h => (Nat.not_lt_zero _ h).elim + | _ + 1, 0, _ => fun h => (Nat.not_lt_zero _ h).elim | i + 1, j + 1, [] => by simp | i + 1, j + 1, c :: l => fun h₀ h₁ => by simp only [insertNth_succ_cons, cons.injEq, true_and] @@ -90,7 +90,7 @@ After nightly-2024-09-06 we can remove the `_root_` prefixes below. theorem mem_insertNth {a b : α} : ∀ {n : ℕ} {l : List α} (_ : n ≤ l.length), a ∈ l.insertNth n b ↔ a = b ∨ a ∈ l | 0, as, _ => by simp - | n + 1, [], h => (Nat.not_succ_le_zero _ h).elim + | _ + 1, [], h => (Nat.not_succ_le_zero _ h).elim | n + 1, a' :: as, h => by rw [List.insertNth_succ_cons, mem_cons, mem_insertNth (Nat.le_of_succ_le_succ h), ← _root_.or_assoc, @or_comm (a = a'), _root_.or_assoc, mem_cons] diff --git a/Mathlib/Data/List/Lattice.lean b/Mathlib/Data/List/Lattice.lean index 5a0ae92ccc6c01..67914f83dc5012 100644 --- a/Mathlib/Data/List/Lattice.lean +++ b/Mathlib/Data/List/Lattice.lean @@ -55,7 +55,7 @@ theorem mem_union_right (l₁ : List α) (h : a ∈ l₂) : a ∈ l₁ ∪ l₂ mem_union_iff.2 (Or.inr h) theorem sublist_suffix_of_union : ∀ l₁ l₂ : List α, ∃ t, t <+ l₁ ∧ t ++ l₂ = l₁ ∪ l₂ - | [], l₂ => ⟨[], by rfl, rfl⟩ + | [], _ => ⟨[], by rfl, rfl⟩ | a :: l₁, l₂ => let ⟨t, s, e⟩ := sublist_suffix_of_union l₁ l₂ if h : a ∈ l₁ ∪ l₂ then diff --git a/Mathlib/Data/List/Lemmas.lean b/Mathlib/Data/List/Lemmas.lean index b055f1b1872225..3c8d4449318836 100644 --- a/Mathlib/Data/List/Lemmas.lean +++ b/Mathlib/Data/List/Lemmas.lean @@ -97,7 +97,7 @@ theorem mapAccumr_eq_foldr {σ : Type*} (f : α → σ → σ × β) : ∀ (as : let r := f a s.1 (r.1, r.2 :: s.2) ) (s, []) as - | [], s => rfl + | [], _ => rfl | a :: as, s => by simp only [mapAccumr, foldr, mapAccumr_eq_foldr f as] @@ -107,9 +107,9 @@ theorem mapAccumr₂_eq_foldr {σ φ : Type*} (f : α → β → σ → σ × φ let r := f ab.1 ab.2 s.1 (r.1, r.2 :: s.2) ) (s, []) (as.zip bs) - | [], [], s => rfl - | a :: as, [], s => rfl - | [], b :: bs, s => rfl + | [], [], _ => rfl + | _ :: _, [], _ => rfl + | [], _ :: _, _ => rfl | a :: as, b :: bs, s => by simp only [mapAccumr₂, foldr, mapAccumr₂_eq_foldr f as] rfl diff --git a/Mathlib/Data/List/Lex.lean b/Mathlib/Data/List/Lex.lean index 9431966564a45c..fef097d96a69f9 100644 --- a/Mathlib/Data/List/Lex.lean +++ b/Mathlib/Data/List/Lex.lean @@ -67,11 +67,11 @@ instance isOrderConnected (r : α → α → Prop) [IsOrderConnected α r] [IsTr IsOrderConnected (List α) (Lex r) where conn := aux where aux - | _, [], c :: l₃, nil => Or.inr nil - | _, [], c :: l₃, rel _ => Or.inr nil - | _, [], c :: l₃, cons _ => Or.inr nil - | _, b :: l₂, c :: l₃, nil => Or.inl nil - | a :: l₁, b :: l₂, c :: l₃, rel h => (IsOrderConnected.conn _ b _ h).imp rel rel + | _, [], _ :: _, nil => Or.inr nil + | _, [], _ :: _, rel _ => Or.inr nil + | _, [], _ :: _, cons _ => Or.inr nil + | _, _ :: _, _ :: _, nil => Or.inl nil + | _ :: _, b :: _, _ :: _, rel h => (IsOrderConnected.conn _ b _ h).imp rel rel | a :: l₁, b :: l₂, _ :: l₃, cons h => by rcases trichotomous_of r a b with (ab | rfl | ab) · exact Or.inl (rel ab) @@ -83,8 +83,8 @@ instance isTrichotomous (r : α → α → Prop) [IsTrichotomous α r] : trichotomous := aux where aux | [], [] => Or.inr (Or.inl rfl) - | [], b :: l₂ => Or.inl nil - | a :: l₁, [] => Or.inr (Or.inr nil) + | [], _ :: _ => Or.inl nil + | _ :: _, [] => Or.inr (Or.inr nil) | a :: l₁, b :: l₂ => by rcases trichotomous_of r a b with (ab | rfl | ab) · exact Or.inl (rel ab) @@ -106,7 +106,7 @@ instance isStrictTotalOrder (r : α → α → Prop) [IsStrictTotalOrder α r] : instance decidableRel [DecidableEq α] (r : α → α → Prop) [DecidableRel r] : DecidableRel (Lex r) | l₁, [] => isFalse fun h => by cases h - | [], b :: l₂ => isTrue Lex.nil + | [], _ :: _ => isTrue Lex.nil | a :: l₁, b :: l₂ => by haveI := decidableRel r l₁ l₂ refine decidable_of_iff (r a b ∨ a = b ∧ Lex r l₁ l₂) ⟨fun h => ?_, fun h => ?_⟩ diff --git a/Mathlib/Data/List/MinMax.lean b/Mathlib/Data/List/MinMax.lean index 52a8f59fb71674..b99e001bd5f4f0 100644 --- a/Mathlib/Data/List/MinMax.lean +++ b/Mathlib/Data/List/MinMax.lean @@ -211,7 +211,7 @@ theorem index_of_argmin : theorem mem_argmax_iff : m ∈ argmax f l ↔ m ∈ l ∧ (∀ a ∈ l, f a ≤ f m) ∧ ∀ a ∈ l, f m ≤ f a → l.indexOf m ≤ l.indexOf a := - ⟨fun hm => ⟨argmax_mem hm, fun a ha => le_of_mem_argmax ha hm, fun _ => index_of_argmax hm⟩, + ⟨fun hm => ⟨argmax_mem hm, fun _ ha => le_of_mem_argmax ha hm, fun _ => index_of_argmax hm⟩, by rintro ⟨hml, ham, hma⟩ cases' harg : argmax f l with n diff --git a/Mathlib/Data/List/Perm.lean b/Mathlib/Data/List/Perm.lean index 6c00caa35fe6e0..be40ad9d20e430 100644 --- a/Mathlib/Data/List/Perm.lean +++ b/Mathlib/Data/List/Perm.lean @@ -97,7 +97,7 @@ theorem rel_perm_imp (hr : RightUnique r) : (Forall₂ r ⇒ Forall₂ r ⇒ (· have : (flip (Forall₂ r) ∘r Perm ∘r Forall₂ r) b d := ⟨a, h₁, c, h, h₂⟩ have : ((flip (Forall₂ r) ∘r Forall₂ r) ∘r Perm) b d := by rwa [← forall₂_comp_perm_eq_perm_comp_forall₂, ← Relation.comp_assoc] at this - let ⟨b', ⟨c', hbc, hcb⟩, hbd⟩ := this + let ⟨b', ⟨_, hbc, hcb⟩, hbd⟩ := this have : b' = b := right_unique_forall₂' hr hcb hbc this ▸ hbd diff --git a/Mathlib/Data/List/Permutation.lean b/Mathlib/Data/List/Permutation.lean index dfa46749569338..a08663b6819164 100644 --- a/Mathlib/Data/List/Permutation.lean +++ b/Mathlib/Data/List/Permutation.lean @@ -53,7 +53,7 @@ namespace List theorem permutationsAux2_fst (t : α) (ts : List α) (r : List β) : ∀ (ys : List α) (f : List α → β), (permutationsAux2 t ts r ys f).1 = ys ++ ts - | [], f => rfl + | [], _ => rfl | y :: ys, f => by simp [permutationsAux2, permutationsAux2_fst t _ _ ys] @[simp] diff --git a/Mathlib/Data/List/Rotate.lean b/Mathlib/Data/List/Rotate.lean index 8b6479898785be..1a80659086cc63 100644 --- a/Mathlib/Data/List/Rotate.lean +++ b/Mathlib/Data/List/Rotate.lean @@ -51,7 +51,7 @@ theorem rotate'_cons_succ (l : List α) (a : α) (n : ℕ) : @[simp] theorem length_rotate' : ∀ (l : List α) (n : ℕ), (l.rotate' n).length = l.length | [], _ => by simp - | a :: l, 0 => rfl + | _ :: _, 0 => rfl | a :: l, n + 1 => by rw [List.rotate', length_rotate' (l ++ [a]) n]; simp theorem rotate'_eq_drop_append_take : diff --git a/Mathlib/Data/List/Sigma.lean b/Mathlib/Data/List/Sigma.lean index ba2c572fe94801..7064c0948f068d 100644 --- a/Mathlib/Data/List/Sigma.lean +++ b/Mathlib/Data/List/Sigma.lean @@ -63,7 +63,7 @@ theorem not_mem_keys {a} {l : List (Sigma β)} : a ∉ l.keys ↔ ∀ b : β a, theorem not_eq_key {a} {l : List (Sigma β)} : a ∉ l.keys ↔ ∀ s : Sigma β, s ∈ l → a ≠ s.1 := Iff.intro (fun h₁ s h₂ e => absurd (mem_keys_of_mem h₂) (by rwa [e] at h₁)) fun f h₁ => - let ⟨b, h₂⟩ := exists_of_mem_keys h₁ + let ⟨_, h₂⟩ := exists_of_mem_keys h₁ f _ h₂ rfl /-! ### `NodupKeys` -/ diff --git a/Mathlib/Data/List/Sort.lean b/Mathlib/Data/List/Sort.lean index be93169d29b884..de5be483d4ecfc 100644 --- a/Mathlib/Data/List/Sort.lean +++ b/Mathlib/Data/List/Sort.lean @@ -213,7 +213,7 @@ theorem orderedInsert_nil (a : α) : [].orderedInsert r a = [a] := rfl theorem orderedInsert_length : ∀ (L : List α) (a : α), (L.orderedInsert r a).length = L.length + 1 - | [], a => rfl + | [], _ => rfl | hd :: tl, a => by dsimp [orderedInsert] split_ifs <;> simp [orderedInsert_length tl] @@ -313,7 +313,7 @@ variable {r} it. -/ theorem Sorted.insertionSort_eq : ∀ {l : List α}, Sorted r l → insertionSort r l = l | [], _ => rfl - | [a], _ => rfl + | [_], _ => rfl | a :: b :: l, h => by rw [insertionSort, Sorted.insertionSort_eq, orderedInsert, if_pos] exacts [rel_of_sorted_cons h _ (mem_cons_self _ _), h.tail] diff --git a/Mathlib/Data/List/Sublists.lean b/Mathlib/Data/List/Sublists.lean index 3d8300bd2d98a8..5521bdab8a956a 100644 --- a/Mathlib/Data/List/Sublists.lean +++ b/Mathlib/Data/List/Sublists.lean @@ -205,7 +205,7 @@ theorem sublistsLenAux_append : ∀ (n : ℕ) (l : List α) (f : List α → β) (g : β → γ) (r : List β) (s : List γ), sublistsLenAux n l (g ∘ f) (r.map g ++ s) = (sublistsLenAux n l f r).map g ++ s | 0, l, f, g, r, s => by unfold sublistsLenAux; simp - | n + 1, [], f, g, r, s => rfl + | _ + 1, [], _, _, _, _ => rfl | n + 1, a :: l, f, g, r, s => by unfold sublistsLenAux simp only [show (g ∘ f) ∘ List.cons a = g ∘ f ∘ List.cons a by rfl, sublistsLenAux_append, diff --git a/Mathlib/Data/List/TFAE.lean b/Mathlib/Data/List/TFAE.lean index f9bce9204f88bd..3dd02febe8c138 100644 --- a/Mathlib/Data/List/TFAE.lean +++ b/Mathlib/Data/List/TFAE.lean @@ -33,7 +33,7 @@ theorem tfae_singleton (p) : TFAE [p] := by simp [TFAE, -eq_iff_iff] theorem tfae_cons_of_mem {a b} {l : List Prop} (h : b ∈ l) : TFAE (a :: l) ↔ (a ↔ b) ∧ TFAE l := ⟨fun H => ⟨H a (by simp) b (Mem.tail a h), - fun p hp q hq => H _ (Mem.tail a hp) _ (Mem.tail a hq)⟩, + fun _ hp _ hq => H _ (Mem.tail a hp) _ (Mem.tail a hq)⟩, by rintro ⟨ab, H⟩ p (_ | ⟨_, hp⟩) q (_ | ⟨_, hq⟩) · rfl diff --git a/Mathlib/Data/List/Zip.lean b/Mathlib/Data/List/Zip.lean index cb8b7daa47501d..a05e606d213ad4 100644 --- a/Mathlib/Data/List/Zip.lean +++ b/Mathlib/Data/List/Zip.lean @@ -31,7 +31,7 @@ variable {α : Type u} {β γ δ ε : Type*} @[simp] theorem zip_swap : ∀ (l₁ : List α) (l₂ : List β), (zip l₁ l₂).map Prod.swap = zip l₂ l₁ - | [], l₂ => zip_nil_right.symm + | [], _ => zip_nil_right.symm | l₁, [] => by rw [zip_nil_right]; rfl | a :: l₁, b :: l₂ => by simp only [zip_cons_cons, map_cons, zip_swap l₁ l₂, Prod.swap_prod_mk] diff --git a/Mathlib/Data/Matrix/Basic.lean b/Mathlib/Data/Matrix/Basic.lean index 63bc543ba910b6..551793cf8e46b2 100644 --- a/Mathlib/Data/Matrix/Basic.lean +++ b/Mathlib/Data/Matrix/Basic.lean @@ -1169,7 +1169,7 @@ variable [CommSemiring R] [Semiring α] [Semiring β] [Algebra R α] [Algebra R instance instAlgebra : Algebra R (Matrix n n α) where toRingHom := (Matrix.scalar n).comp (algebraMap R α) - commutes' r x := scalar_commute _ (fun r' => Algebra.commutes _ _) _ + commutes' _ _ := scalar_commute _ (fun _ => Algebra.commutes _ _) _ smul_def' r x := by ext; simp [Matrix.scalar, Algebra.smul_def r] theorem algebraMap_matrix_apply {r : R} {i j : n} : @@ -1359,7 +1359,7 @@ def mapMatrix (f : α →+* β) : Matrix m m α →+* Matrix m m β := { f.toAddMonoidHom.mapMatrix with toFun := fun M => M.map f map_one' := by simp - map_mul' := fun L M => Matrix.map_mul } + map_mul' := fun _ _ => Matrix.map_mul } @[simp] theorem mapMatrix_id : (RingHom.id α).mapMatrix = RingHom.id (Matrix m m α) := diff --git a/Mathlib/Data/Matrix/DMatrix.lean b/Mathlib/Data/Matrix/DMatrix.lean index 2b482b6e0ee610..cf00fbd7719648 100644 --- a/Mathlib/Data/Matrix/DMatrix.lean +++ b/Mathlib/Data/Matrix/DMatrix.lean @@ -49,7 +49,7 @@ theorem map_apply {M : DMatrix m n α} {β : m → n → Type w} {f : ∀ ⦃i j @[simp] theorem map_map {M : DMatrix m n α} {β : m → n → Type w} {γ : m → n → Type z} {f : ∀ ⦃i j⦄, α i j → β i j} {g : ∀ ⦃i j⦄, β i j → γ i j} : - (M.map f).map g = M.map fun i j x => g (f x) := by ext; simp + (M.map f).map g = M.map fun _ _ x => g (f x) := by ext; simp /-- The transpose of a dmatrix. -/ def transpose (M : DMatrix m n α) : DMatrix n m fun j i => α i j diff --git a/Mathlib/Data/Matrix/DualNumber.lean b/Mathlib/Data/Matrix/DualNumber.lean index 27fb548c656399..22d54e1cafe273 100644 --- a/Mathlib/Data/Matrix/DualNumber.lean +++ b/Mathlib/Data/Matrix/DualNumber.lean @@ -23,8 +23,8 @@ open Matrix TrivSqZeroExt def Matrix.dualNumberEquiv : Matrix n n (DualNumber R) ≃ₐ[R] DualNumber (Matrix n n R) where toFun A := ⟨of fun i j => (A i j).fst, of fun i j => (A i j).snd⟩ invFun d := of fun i j => (d.fst i j, d.snd i j) - left_inv A := Matrix.ext fun i j => TrivSqZeroExt.ext rfl rfl - right_inv d := TrivSqZeroExt.ext (Matrix.ext fun i j => rfl) (Matrix.ext fun i j => rfl) + left_inv _ := Matrix.ext fun _ _ => TrivSqZeroExt.ext rfl rfl + right_inv _ := TrivSqZeroExt.ext (Matrix.ext fun _ _ => rfl) (Matrix.ext fun _ _ => rfl) map_mul' A B := by ext · dsimp [mul_apply] @@ -33,7 +33,7 @@ def Matrix.dualNumberEquiv : Matrix n n (DualNumber R) ≃ₐ[R] DualNumber (Mat · simp_rw [snd_mul, smul_eq_mul, op_smul_eq_mul] simp only [mul_apply, snd_sum, DualNumber.snd_mul, snd_mk, of_apply, fst_mk, add_apply] rw [← Finset.sum_add_distrib] - map_add' A B := TrivSqZeroExt.ext rfl rfl + map_add' _ _ := TrivSqZeroExt.ext rfl rfl commutes' r := by simp_rw [algebraMap_eq_inl', algebraMap_eq_diagonal, Pi.algebraMap_def, Algebra.id.map_eq_self, algebraMap_eq_inl, ← diagonal_map (inl_zero R), map_apply, fst_inl, diff --git a/Mathlib/Data/Matrix/Reflection.lean b/Mathlib/Data/Matrix/Reflection.lean index 7ac86af668d1c7..222e7f76799ece 100644 --- a/Mathlib/Data/Matrix/Reflection.lean +++ b/Mathlib/Data/Matrix/Reflection.lean @@ -51,7 +51,7 @@ example (P : Matrix (Fin 2) (Fin 3) α → Prop) : ``` -/ theorem forall_iff : ∀ {m n} (P : Matrix (Fin m) (Fin n) α → Prop), Forall P ↔ ∀ x, P x - | 0, n, P => Iff.symm Fin.forall_fin_zero_pi + | 0, _, _ => Iff.symm Fin.forall_fin_zero_pi | m + 1, n, P => by simp only [Forall, FinVec.forall_iff, forall_iff] exact Iff.symm Fin.forall_fin_succ_pi @@ -73,7 +73,7 @@ example (P : Matrix (Fin 2) (Fin 3) α → Prop) : ``` -/ theorem exists_iff : ∀ {m n} (P : Matrix (Fin m) (Fin n) α → Prop), Exists P ↔ ∃ x, P x - | 0, n, P => Iff.symm Fin.exists_fin_zero_pi + | 0, _, _ => Iff.symm Fin.exists_fin_zero_pi | m + 1, n, P => by simp only [Exists, FinVec.exists_iff, exists_iff] exact Iff.symm Fin.exists_fin_succ_pi @@ -95,7 +95,7 @@ example (a b c d : α) : transpose !![a, b; c, d] = !![a, c; b, d] := (transpose -/ @[simp] theorem transposeᵣ_eq : ∀ {m n} (A : Matrix (Fin m) (Fin n) α), transposeᵣ A = transpose A - | _, 0, A => Subsingleton.elim _ _ + | _, 0, _ => Subsingleton.elim _ _ | m, n + 1, A => Matrix.ext fun i j => by simp_rw [transposeᵣ, transposeᵣ_eq] diff --git a/Mathlib/Data/Matroid/Basic.lean b/Mathlib/Data/Matroid/Basic.lean index 5f098b5a7e0536..69571ed264c5ee 100644 --- a/Mathlib/Data/Matroid/Basic.lean +++ b/Mathlib/Data/Matroid/Basic.lean @@ -410,11 +410,11 @@ theorem Base.infinite_of_infinite (hB : M.Base B) (h : B.Infinite) (hB₁ : M.Ba by_contra (fun hB_inf ↦ (hB₁.finite_of_finite (not_infinite.mp hB_inf) hB).not_infinite h) theorem Base.finite [FiniteRk M] (hB : M.Base B) : B.Finite := - let ⟨B₀,hB₀⟩ := ‹FiniteRk M›.exists_finite_base + let ⟨_,hB₀⟩ := ‹FiniteRk M›.exists_finite_base hB₀.1.finite_of_finite hB₀.2 hB theorem Base.infinite [InfiniteRk M] (hB : M.Base B) : B.Infinite := - let ⟨B₀,hB₀⟩ := ‹InfiniteRk M›.exists_infinite_base + let ⟨_,hB₀⟩ := ‹InfiniteRk M›.exists_infinite_base hB₀.1.infinite_of_infinite hB₀.2 hB theorem empty_not_base [h : RkPos M] : ¬M.Base ∅ := diff --git a/Mathlib/Data/Matroid/Closure.lean b/Mathlib/Data/Matroid/Closure.lean index 10fddef9acbd1d..0ae2d183049777 100644 --- a/Mathlib/Data/Matroid/Closure.lean +++ b/Mathlib/Data/Matroid/Closure.lean @@ -176,7 +176,7 @@ lemma closure_mono (M : Matroid α) : Monotone M.closure := @[simp] lemma closure_closure (M : Matroid α) (X : Set α) : M.closure (M.closure X) = M.closure X := (M.subset_closure _).antisymm' (subset_sInter - (fun F hF ↦ (closure_subset_closure _ (sInter_subset_of_mem hF)).trans hF.1.closure.subset)) + (fun _ hF ↦ (closure_subset_closure _ (sInter_subset_of_mem hF)).trans hF.1.closure.subset)) lemma closure_subset_closure_of_subset_closure (hXY : X ⊆ M.closure Y) : M.closure X ⊆ M.closure Y := @@ -462,7 +462,7 @@ lemma closure_biInter_eq_biInter_closure_of_biUnion_indep {ι : Type*} {A : Set convert closure_iInter_eq_iInter_closure_of_iUnion_indep (Is := fun i : A ↦ I i) (by simpa) <;> simp -lemma Indep.closure_iInter_eq_biInter_closure_of_forall_subset [hι : Nonempty ι] {Js : ι → Set α} +lemma Indep.closure_iInter_eq_biInter_closure_of_forall_subset [Nonempty ι] {Js : ι → Set α} (hI : M.Indep I) (hJs : ∀ i, Js i ⊆ I) : M.closure (⋂ i, Js i) = ⋂ i, M.closure (Js i) := closure_iInter_eq_iInter_closure_of_iUnion_indep _ (hI.subset <| by simpa) diff --git a/Mathlib/Data/Matroid/Dual.lean b/Mathlib/Data/Matroid/Dual.lean index 3d79fbd6d5b3c6..73ac1b2d68eba5 100644 --- a/Mathlib/Data/Matroid/Dual.lean +++ b/Mathlib/Data/Matroid/Dual.lean @@ -41,7 +41,7 @@ section dual @[simps] def dualIndepMatroid (M : Matroid α) : IndepMatroid α where E := M.E Indep I := I ⊆ M.E ∧ ∃ B, M.Base B ∧ Disjoint I B - indep_empty := ⟨empty_subset M.E, M.exists_base.imp (fun B hB ↦ ⟨hB, empty_disjoint _⟩)⟩ + indep_empty := ⟨empty_subset M.E, M.exists_base.imp (fun _ hB ↦ ⟨hB, empty_disjoint _⟩)⟩ indep_subset := by rintro I J ⟨hJE, B, hB, hJB⟩ hIJ exact ⟨hIJ.trans hJE, ⟨B, hB, disjoint_of_subset_left hIJ hJB⟩⟩ diff --git a/Mathlib/Data/Matroid/IndepAxioms.lean b/Mathlib/Data/Matroid/IndepAxioms.lean index 3d56e013d70fa8..74e8d39c7eafb6 100644 --- a/Mathlib/Data/Matroid/IndepAxioms.lean +++ b/Mathlib/Data/Matroid/IndepAxioms.lean @@ -380,7 +380,7 @@ protected def ofFinset [DecidableEq α] (E : Set α) (Indep : Finset α → Prop (E := E) (Indep := (fun I ↦ (∀ (J : Finset α), (J : Set α) ⊆ I → Indep J))) (indep_empty := by simpa [subset_empty_iff]) - (indep_subset := ( fun I J hJ hIJ K hKI ↦ hJ _ (hKI.trans hIJ) )) + (indep_subset := ( fun _ _ hJ hIJ _ hKI ↦ hJ _ (hKI.trans hIJ) )) (indep_aug := by intro I J hI hIfin hJ hJfin hIJ rw [ncard_eq_toFinset_card _ hIfin, ncard_eq_toFinset_card _ hJfin] at hIJ @@ -388,7 +388,7 @@ protected def ofFinset [DecidableEq α] (E : Set α) (Indep : Finset α → Prop simp only [Finite.mem_toFinset] at aug obtain ⟨e, heJ, heI, hi⟩ := aug exact ⟨e, heJ, heI, fun K hK ↦ indep_subset hi <| Finset.coe_subset.1 (by simpa)⟩ ) - (indep_compact := fun I h J hJ ↦ h _ hJ J.finite_toSet _ Subset.rfl ) + (indep_compact := fun _ h J hJ ↦ h _ hJ J.finite_toSet _ Subset.rfl ) (subset_ground := fun I hI x hxI ↦ by simpa using subset_ground <| hI {x} (by simpa) ) @[simp] theorem ofFinset_E [DecidableEq α] (E : Set α) Indep indep_empty indep_subset indep_aug diff --git a/Mathlib/Data/Matroid/Map.lean b/Mathlib/Data/Matroid/Map.lean index bf22fe80c5b92d..4cd4e5646e477c 100644 --- a/Mathlib/Data/Matroid/Map.lean +++ b/Mathlib/Data/Matroid/Map.lean @@ -116,7 +116,7 @@ def comap (N : Matroid β) (f : α → β) : Matroid α := { E := f ⁻¹' N.E Indep := fun I ↦ N.Indep (f '' I) ∧ InjOn f I indep_empty := by simp - indep_subset := fun I J h hIJ ↦ ⟨h.1.subset (image_subset _ hIJ), InjOn.mono hIJ h.2⟩ + indep_subset := fun _ _ h hIJ ↦ ⟨h.1.subset (image_subset _ hIJ), InjOn.mono hIJ h.2⟩ indep_aug := by rintro I B ⟨hI, hIinj⟩ hImax hBmax obtain ⟨I', hII', hI', hI'inj⟩ := (not_maximal_subset_iff ⟨hI, hIinj⟩).1 hImax @@ -156,7 +156,7 @@ def comap (N : Matroid β) (f : α → β) : Matroid α := refine ⟨J₀, hIJ₀, hJ, hbj.injOn, hJ₀X, fun K hK hKinj hKX hJ₀K ↦ ?_⟩ rw [← hKinj.image_eq_image_iff hJ₀K Subset.rfl, hJmax hK (image_subset_range _ _) (image_subset f hKX) (image_subset f hJ₀K)] - subset_ground := fun I hI e heI ↦ hI.1.subset_ground ⟨e, heI, rfl⟩ } + subset_ground := fun _ hI e heI ↦ hI.1.subset_ground ⟨e, heI, rfl⟩ } @[simp] lemma comap_indep_iff : (N.comap f).Indep I ↔ N.Indep (f '' I) ∧ InjOn f I := Iff.rfl diff --git a/Mathlib/Data/Matroid/Restrict.lean b/Mathlib/Data/Matroid/Restrict.lean index 013d3c6c687406..3e9f613bea804e 100644 --- a/Mathlib/Data/Matroid/Restrict.lean +++ b/Mathlib/Data/Matroid/Restrict.lean @@ -75,7 +75,7 @@ section restrict E := R Indep I := M.Indep I ∧ I ⊆ R indep_empty := ⟨M.empty_indep, empty_subset _⟩ - indep_subset := fun I J h hIJ ↦ ⟨h.1.subset hIJ, hIJ.trans h.2⟩ + indep_subset := fun _ _ h hIJ ↦ ⟨h.1.subset hIJ, hIJ.trans h.2⟩ indep_aug := by rintro I I' ⟨hI, hIY⟩ (hIn : ¬ M.Basis' I R) (hI' : M.Basis' I' R) rw [basis'_iff_basis_inter_ground] at hIn hI' @@ -111,7 +111,7 @@ section restrict simp only [hIJ, and_assoc, maximal_subset_iff, hJ.indep, hJ.subset, and_imp, true_and, hJ.subset.trans hAR] exact fun K hK _ hKA hJK ↦ hJ.eq_of_subset_indep hK hJK hKA - subset_ground I := And.right + subset_ground _ := And.right /-- Change the ground set of a matroid to some `R : Set α`. The independent sets of the restriction are the independent subsets of the new ground set. Most commonly used when `R ⊆ M.E`, diff --git a/Mathlib/Data/Multiset/Basic.lean b/Mathlib/Data/Multiset/Basic.lean index 0c4fb024e449e1..b54ec18a4e5313 100644 --- a/Mathlib/Data/Multiset/Basic.lean +++ b/Mathlib/Data/Multiset/Basic.lean @@ -171,7 +171,7 @@ def rec (C_0 : C 0) (C_cons : ∀ a m, C m → C (a ::ₘ m)) (C_cons_heq : ∀ a a' m b, HEq (C_cons a (a' ::ₘ m) (C_cons a' m b)) (C_cons a' (a ::ₘ m) (C_cons a m b))) (m : Multiset α) : C m := - Quotient.hrecOn m (@List.rec α (fun l => C ⟦l⟧) C_0 fun a l b => C_cons a ⟦l⟧ b) fun l l' h => + Quotient.hrecOn m (@List.rec α (fun l => C ⟦l⟧) C_0 fun a l b => C_cons a ⟦l⟧ b) fun _ _ h => h.rec_heq (fun hl _ ↦ by congr 1; exact Quot.sound hl) (C_cons_heq _ _ ⟦_⟧ _) @@ -593,10 +593,10 @@ instance : ContravariantClass (Multiset α) (Multiset α) (· + ·) (· ≤ ·) ⟨fun _s _t _u => add_le_add_iff_left'.1⟩ instance instAddCommMonoid : AddCancelCommMonoid (Multiset α) where - add_comm := fun s t => Quotient.inductionOn₂ s t fun l₁ l₂ => Quot.sound perm_append_comm + add_comm := fun s t => Quotient.inductionOn₂ s t fun _ _ => Quot.sound perm_append_comm add_assoc := fun s₁ s₂ s₃ => Quotient.inductionOn₃ s₁ s₂ s₃ fun l₁ l₂ l₃ => congr_arg _ <| append_assoc l₁ l₂ l₃ - zero_add := fun s => Quot.inductionOn s fun l => rfl + zero_add := fun s => Quot.inductionOn s fun _ => rfl add_zero := fun s => Quotient.inductionOn s fun l => congr_arg _ <| append_nil l add_left_cancel := fun _ _ _ h => le_antisymm (Multiset.add_le_add_iff_left'.mp h.le) (Multiset.add_le_add_iff_left'.mp h.ge) @@ -1403,7 +1403,7 @@ variable {m : Multiset α} /-- If `p` is a decidable predicate, so is the predicate that all elements of a multiset satisfy `p`. -/ -protected def decidableForallMultiset {p : α → Prop} [hp : ∀ a, Decidable (p a)] : +protected def decidableForallMultiset {p : α → Prop} [∀ a, Decidable (p a)] : Decidable (∀ a ∈ m, p a) := Quotient.recOnSubsingleton m fun l => decidable_of_iff (∀ a ∈ l, p a) <| by simp @@ -1414,7 +1414,7 @@ instance decidableDforallMultiset {p : ∀ a ∈ m, Prop} [_hp : ∀ (a) (h : a (@Multiset.decidableForallMultiset _ m.attach (fun a => p a.1 a.2) _) /-- decidable equality for functions whose domain is bounded by multisets -/ -instance decidableEqPiMultiset {β : α → Type*} [h : ∀ a, DecidableEq (β a)] : +instance decidableEqPiMultiset {β : α → Type*} [∀ a, DecidableEq (β a)] : DecidableEq (∀ a ∈ m, β a) := fun f g => decidable_of_iff (∀ (a) (h : a ∈ m), f a h = g a h) (by simp [Function.funext_iff]) @@ -1740,11 +1740,11 @@ variable {p} @[simp] theorem filter_cons_of_pos {a : α} (s) : p a → filter p (a ::ₘ s) = a ::ₘ filter p s := - Quot.inductionOn s fun l h => congr_arg ofList <| List.filter_cons_of_pos <| by simpa using h + Quot.inductionOn s fun _ h => congr_arg ofList <| List.filter_cons_of_pos <| by simpa using h @[simp] theorem filter_cons_of_neg {a : α} (s) : ¬p a → filter p (a ::ₘ s) = filter p s := - Quot.inductionOn s fun l h => congr_arg ofList <| List.filter_cons_of_neg <| by simpa using h + Quot.inductionOn s fun _ h => congr_arg ofList <| List.filter_cons_of_neg <| by simpa using h @[simp] theorem mem_filter {a : α} {s} : a ∈ filter p s ↔ a ∈ s ∧ p a := @@ -2518,7 +2518,7 @@ theorem rel_replicate_left {m : Multiset α} {a : α} {r : α → α → Prop} { obtain ⟨b, hb1, hb2⟩ := exists_mem_of_rel_of_mem (rel_flip.2 h) hx rwa [eq_of_mem_replicate hb1] at hb2⟩, fun h => - rel_of_forall (fun x y hx hy => (eq_of_mem_replicate hx).symm ▸ h.2 _ hy) + rel_of_forall (fun _ _ hx hy => (eq_of_mem_replicate hx).symm ▸ h.2 _ hy) (Eq.trans (card_replicate _ _) h.1.symm)⟩ theorem rel_replicate_right {m : Multiset α} {a : α} {r : α → α → Prop} {n : ℕ} : @@ -2558,7 +2558,7 @@ theorem map_injective {f : α → β} (hf : Function.Injective f) : lemma filter_attach' (s : Multiset α) (p : {a // a ∈ s} → Prop) [DecidableEq α] [DecidablePred p] : s.attach.filter p = - (s.filter fun x ↦ ∃ h, p ⟨x, h⟩).attach.map (Subtype.map id fun x ↦ mem_of_mem_filter) := by + (s.filter fun x ↦ ∃ h, p ⟨x, h⟩).attach.map (Subtype.map id fun _ ↦ mem_of_mem_filter) := by classical refine Multiset.map_injective Subtype.val_injective ?_ rw [map_filter' _ Subtype.val_injective] diff --git a/Mathlib/Data/Multiset/Bind.lean b/Mathlib/Data/Multiset/Bind.lean index 3fe645c8e220ed..89ddc4a81c8f68 100644 --- a/Mathlib/Data/Multiset/Bind.lean +++ b/Mathlib/Data/Multiset/Bind.lean @@ -267,7 +267,7 @@ theorem add_product (s t : Multiset α) (u : Multiset β) : (s + t) ×ˢ u = s @[simp] theorem product_add (s : Multiset α) : ∀ t u : Multiset β, s ×ˢ (t + u) = s ×ˢ t + s ×ˢ u := - Multiset.induction_on s (fun t u => rfl) fun a s IH t u => by + Multiset.induction_on s (fun _ _ => rfl) fun a s IH t u => by rw [cons_product, IH] simp [add_comm, add_left_comm, add_assoc] @@ -322,7 +322,7 @@ theorem add_sigma (s t : Multiset α) (u : ∀ a, Multiset (σ a)) : @[simp] theorem sigma_add : ∀ t u : ∀ a, Multiset (σ a), (s.sigma fun a => t a + u a) = s.sigma t + s.sigma u := - Multiset.induction_on s (fun t u => rfl) fun a s IH t u => by + Multiset.induction_on s (fun _ _ => rfl) fun a s IH t u => by rw [cons_sigma, IH] simp [add_comm, add_left_comm, add_assoc] diff --git a/Mathlib/Data/Multiset/FinsetOps.lean b/Mathlib/Data/Multiset/FinsetOps.lean index 8cec332c637a55..1df7e981bed4b2 100644 --- a/Mathlib/Data/Multiset/FinsetOps.lean +++ b/Mathlib/Data/Multiset/FinsetOps.lean @@ -92,7 +92,7 @@ theorem attach_ndinsert (a : α) (s : Multiset α) : have eq : ∀ h : ∀ p : { x // x ∈ s }, p.1 ∈ s, (fun p : { x // x ∈ s } => ⟨p.val, h p⟩ : { x // x ∈ s } → { x // x ∈ s }) = id := - fun h => funext fun p => Subtype.eq rfl + fun _ => funext fun _ => Subtype.eq rfl have : ∀ (t) (eq : s.ndinsert a = t), t.attach = ndinsert ⟨a, eq ▸ mem_ndinsert_self a s⟩ (s.attach.map fun p => ⟨p.1, eq ▸ mem_ndinsert_of_mem p.2⟩) := by intro t ht diff --git a/Mathlib/Data/Multiset/Nodup.lean b/Mathlib/Data/Multiset/Nodup.lean index 2ea7505ae7caad..6dc1fd10b0a00d 100644 --- a/Mathlib/Data/Multiset/Nodup.lean +++ b/Mathlib/Data/Multiset/Nodup.lean @@ -60,7 +60,7 @@ theorem nodup_iff_le {s : Multiset α} : Nodup s ↔ ∀ a : α, ¬a ::ₘ a :: theorem nodup_iff_ne_cons_cons {s : Multiset α} : s.Nodup ↔ ∀ a t, s ≠ a ::ₘ a ::ₘ t := nodup_iff_le.trans - ⟨fun h a t s_eq => h a (s_eq.symm ▸ cons_le_cons a (cons_le_cons a (zero_le _))), fun h a le => + ⟨fun h a _ s_eq => h a (s_eq.symm ▸ cons_le_cons a (cons_le_cons a (zero_le _))), fun h a le => let ⟨t, s_eq⟩ := le_iff_exists_add.mp le h a t (by rwa [cons_add, cons_add, zero_add] at s_eq)⟩ diff --git a/Mathlib/Data/NNReal/Basic.lean b/Mathlib/Data/NNReal/Basic.lean index bf80f11181f55d..f0ef943d2ea06b 100644 --- a/Mathlib/Data/NNReal/Basic.lean +++ b/Mathlib/Data/NNReal/Basic.lean @@ -514,7 +514,7 @@ theorem lt_iff_exists_rat_btwn (a b : ℝ≥0) : have : 0 ≤ (q : ℝ) := le_trans a.2 <| le_of_lt haq ⟨q, Rat.cast_nonneg.1 this, by simp [Real.coe_toNNReal _ this, NNReal.coe_lt_coe.symm, haq, hqb]⟩) - fun ⟨q, _, haq, hqb⟩ => lt_trans haq hqb + fun ⟨_, _, haq, hqb⟩ => lt_trans haq hqb theorem bot_eq_zero : (⊥ : ℝ≥0) = 0 := rfl @@ -550,7 +550,7 @@ theorem zero_le_coe {q : ℝ≥0} : 0 ≤ (q : ℝ) := instance instOrderedSMul {M : Type*} [OrderedAddCommMonoid M] [Module ℝ M] [OrderedSMul ℝ M] : OrderedSMul ℝ≥0 M where smul_lt_smul_of_pos hab hc := (smul_lt_smul_of_pos_left hab (NNReal.coe_pos.2 hc) : _) - lt_of_smul_lt_smul_of_pos {a b c} hab _ := + lt_of_smul_lt_smul_of_pos {_ _ c} hab _ := lt_of_smul_lt_smul_of_nonneg_left (by exact hab) (NNReal.coe_nonneg c) end NNReal diff --git a/Mathlib/Data/Nat/Bits.lean b/Mathlib/Data/Nat/Bits.lean index 753381e7318d10..58bfa8b7cbb479 100644 --- a/Mathlib/Data/Nat/Bits.lean +++ b/Mathlib/Data/Nat/Bits.lean @@ -219,7 +219,7 @@ lemma shiftLeft'_add (b m n) : ∀ k, shiftLeft' b m (n + k) = shiftLeft' b (shi | k + 1 => congr_arg (bit b) (shiftLeft'_add b m n k) lemma shiftLeft'_sub (b m) : ∀ {n k}, k ≤ n → shiftLeft' b m (n - k) = (shiftLeft' b m n) >>> k - | n, 0, _ => rfl + | _, 0, _ => rfl | n + 1, k + 1, h => by rw [succ_sub_succ_eq_sub, shiftLeft', Nat.add_comm, shiftRight_add] simp only [shiftLeft'_sub, Nat.le_of_succ_le_succ h, shiftRight_succ, shiftRight_zero] diff --git a/Mathlib/Data/Nat/Cast/Order/Basic.lean b/Mathlib/Data/Nat/Cast/Order/Basic.lean index 0bd91bdef4a52d..392df917a8a697 100644 --- a/Mathlib/Data/Nat/Cast/Order/Basic.lean +++ b/Mathlib/Data/Nat/Cast/Order/Basic.lean @@ -176,7 +176,7 @@ section RingHomClass variable {R S F : Type*} [NonAssocSemiring R] [NonAssocSemiring S] [FunLike F R S] -theorem NeZero.nat_of_injective {n : ℕ} [h : NeZero (n : R)] [RingHomClass F R S] {f : F} +theorem NeZero.nat_of_injective {n : ℕ} [NeZero (n : R)] [RingHomClass F R S] {f : F} (hf : Function.Injective f) : NeZero (n : S) := ⟨fun h ↦ NeZero.natCast_ne n R <| hf <| by simpa only [map_natCast, map_zero f]⟩ diff --git a/Mathlib/Data/Nat/Choose/Basic.lean b/Mathlib/Data/Nat/Choose/Basic.lean index 08947b2993cb94..d50601dc0a59d9 100644 --- a/Mathlib/Data/Nat/Choose/Basic.lean +++ b/Mathlib/Data/Nat/Choose/Basic.lean @@ -77,7 +77,7 @@ theorem choose_eq_choose_pred_add {n k : ℕ} (hn : 0 < n) (hk : 0 < k) : theorem choose_eq_zero_of_lt : ∀ {n k}, n < k → choose n k = 0 | _, 0, hk => absurd hk (Nat.not_lt_zero _) - | 0, k + 1, _ => choose_zero_succ _ + | 0, _ + 1, _ => choose_zero_succ _ | n + 1, k + 1, hk => by have hnk : n < k := lt_of_succ_lt_succ hk have hnk1 : n < k + 1 := lt_of_succ_lt hk @@ -109,7 +109,7 @@ theorem choose_two_right (n : ℕ) : choose n 2 = n * (n - 1) / 2 := by theorem choose_pos : ∀ {n k}, k ≤ n → 0 < choose n k | 0, _, hk => by rw [Nat.eq_zero_of_le_zero hk]; decide | n + 1, 0, _ => by simp - | n + 1, k + 1, hk => Nat.add_pos_left (choose_pos (le_of_succ_le_succ hk)) _ + | _ + 1, _ + 1, hk => Nat.add_pos_left (choose_pos (le_of_succ_le_succ hk)) _ theorem choose_eq_zero_iff {n k : ℕ} : n.choose k = 0 ↔ n < k := ⟨fun h => lt_of_not_ge (mt Nat.choose_pos h.symm.not_lt), Nat.choose_eq_zero_of_lt⟩ diff --git a/Mathlib/Data/Nat/Choose/Multinomial.lean b/Mathlib/Data/Nat/Choose/Multinomial.lean index 62485e17c0efa2..19e15e9bc63ee0 100644 --- a/Mathlib/Data/Nat/Choose/Multinomial.lean +++ b/Mathlib/Data/Nat/Choose/Multinomial.lean @@ -212,7 +212,7 @@ variable [Semiring R] lemma sum_pow_eq_sum_piAntidiag_of_commute (s : Finset α) (f : α → R) (hc : (s : Set α).Pairwise fun i j ↦ Commute (f i) (f j)) (n : ℕ) : (∑ i in s, f i) ^ n = ∑ k in piAntidiag s n, multinomial s k * - s.noncommProd (fun i ↦ f i ^ k i) (hc.mono' fun i j h ↦ h.pow_pow ..) := by + s.noncommProd (fun i ↦ f i ^ k i) (hc.mono' fun _ _ h ↦ h.pow_pow ..) := by classical induction' s using Finset.cons_induction with a s has ih generalizing n · cases n <;> simp diff --git a/Mathlib/Data/Nat/Choose/Sum.lean b/Mathlib/Data/Nat/Choose/Sum.lean index d15893af1129d3..04851939e63360 100644 --- a/Mathlib/Data/Nat/Choose/Sum.lean +++ b/Mathlib/Data/Nat/Choose/Sum.lean @@ -124,7 +124,7 @@ theorem four_pow_le_two_mul_add_one_mul_central_binom (n : ℕ) : calc 4 ^ n = (1 + 1) ^ (2 * n) := by norm_num [pow_mul] _ = ∑ m ∈ range (2 * n + 1), (2 * n).choose m := by set_option simprocs false in simp [add_pow] - _ ≤ ∑ m ∈ range (2 * n + 1), (2 * n).choose (2 * n / 2) := by gcongr; apply choose_le_middle + _ ≤ ∑ _ ∈ range (2 * n + 1), (2 * n).choose (2 * n / 2) := by gcongr; apply choose_le_middle _ = (2 * n + 1) * choose (2 * n) n := by simp /-- **Zhu Shijie's identity** aka hockey-stick identity, version with `Icc`. -/ diff --git a/Mathlib/Data/Nat/Defs.lean b/Mathlib/Data/Nat/Defs.lean index 3bff75138a170c..4c0204101ae2e1 100644 --- a/Mathlib/Data/Nat/Defs.lean +++ b/Mathlib/Data/Nat/Defs.lean @@ -745,7 +745,7 @@ lemma leRec_trans {n m k} {motive : (m : ℕ) → n ≤ m → Sort*} (refl le_su lemma leRec_succ_left {motive : (m : ℕ) → n ≤ m → Sort*} (refl le_succ_of_le) {m} (h1 : n ≤ m) (h2 : n + 1 ≤ m) : -- the `@` is needed for this to elaborate, even though we only provide explicit arguments! - @leRec _ _ (le_succ_of_le le_rfl refl) (fun k h ih => le_succ_of_le (le_of_succ_le h) ih) _ h2 = + @leRec _ _ (le_succ_of_le le_rfl refl) (fun _ h ih => le_succ_of_le (le_of_succ_le h) ih) _ h2 = leRec (motive := motive) refl le_succ_of_le h1 := by rw [leRec_trans _ _ (le_succ n) h2, leRec_succ'] @@ -875,7 +875,7 @@ lemma decreasingInduction_succ {n} {motive : (m : ℕ) → m ≤ n + 1 → Sort* (mn : m ≤ n) (msn : m ≤ n + 1) : (decreasingInduction (motive := motive) of_succ self msn : motive m msn) = decreasingInduction (motive := fun m h => motive m (le_succ_of_le h)) - (fun i hi => of_succ _ _) (of_succ _ _ self) mn := by + (fun _ _ => of_succ _ _) (of_succ _ _ self) mn := by dsimp only [decreasingInduction]; rw [leRec_succ] @[simp] @@ -886,7 +886,7 @@ lemma decreasingInduction_succ' {n} {motive : (m : ℕ) → m ≤ n + 1 → Sort lemma decreasingInduction_trans {motive : (m : ℕ) → m ≤ k → Sort*} (hmn : m ≤ n) (hnk : n ≤ k) (of_succ self) : (decreasingInduction (motive := motive) of_succ self (Nat.le_trans hmn hnk) : motive m _) = - decreasingInduction (fun n ih => of_succ _ _) (decreasingInduction of_succ self hnk) hmn := by + decreasingInduction (fun _ _ => of_succ _ _) (decreasingInduction of_succ self hnk) hmn := by induction hnk with | refl => rw [decreasingInduction_self] | step hnk ih => @@ -919,7 +919,7 @@ def pincerRecursion {P : ℕ → ℕ → Sort*} (Ha0 : ∀ m : ℕ, P m 0) (H0b (H : ∀ x y : ℕ, P x y.succ → P x.succ y → P x.succ y.succ) : ∀ n m : ℕ, P n m | m, 0 => Ha0 m | 0, n => H0b n - | Nat.succ m, Nat.succ n => H _ _ (pincerRecursion Ha0 H0b H _ _) (pincerRecursion Ha0 H0b H _ _) + | Nat.succ _, Nat.succ _ => H _ _ (pincerRecursion Ha0 H0b H _ _) (pincerRecursion Ha0 H0b H _ _) /-- Decreasing induction: if `P (k+1)` implies `P k` for all `m ≤ k < n`, then `P n` implies `P m`. Also works for functions to `Sort*`. @@ -939,7 +939,7 @@ def decreasingInduction' {P : ℕ → Sort*} (h : ∀ k < n, m ≤ k → P (k + @[elab_as_elim] theorem diag_induction (P : ℕ → ℕ → Prop) (ha : ∀ a, P (a + 1) (a + 1)) (hb : ∀ b, P 0 (b + 1)) (hd : ∀ a b, a < b → P (a + 1) b → P a (b + 1) → P (a + 1) (b + 1)) : ∀ a b, a < b → P a b - | 0, b + 1, _ => hb _ + | 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 omega @@ -1305,7 +1305,7 @@ lemma div_lt_div_of_lt_of_dvd {a b d : ℕ} (hdb : d ∣ b) (h : a < b) : a / d /-! ### Decidability of predicates -/ -instance decidableLoHi (lo hi : ℕ) (P : ℕ → Prop) [H : DecidablePred P] : +instance decidableLoHi (lo hi : ℕ) (P : ℕ → Prop) [DecidablePred P] : Decidable (∀ x, lo ≤ x → x < hi → P x) := decidable_of_iff (∀ x < hi - lo, P (lo + x)) <| by refine ⟨fun al x hl hh ↦ ?_, diff --git a/Mathlib/Data/Nat/Fib/Zeckendorf.lean b/Mathlib/Data/Nat/Fib/Zeckendorf.lean index 81a5fa9e141306..9d1209d75fc3e1 100644 --- a/Mathlib/Data/Nat/Fib/Zeckendorf.lean +++ b/Mathlib/Data/Nat/Fib/Zeckendorf.lean @@ -52,7 +52,7 @@ lemma IsZeckendorfRep_nil : IsZeckendorfRep [] := by simp [IsZeckendorfRep] lemma IsZeckendorfRep.sum_fib_lt : ∀ {n l}, IsZeckendorfRep l → (∀ a ∈ (l ++ [0]).head?, a < n) → (l.map fib).sum < fib n - | n, [], _, hn => fib_pos.2 <| hn _ rfl + | _, [], _, hn => fib_pos.2 <| hn _ rfl | n, a :: l, hl, hn => by simp only [IsZeckendorfRep, cons_append, chain'_iff_pairwise, pairwise_cons] at hl have : ∀ b, b ∈ head? (l ++ [0]) → b < a - 1 := diff --git a/Mathlib/Data/Nat/Find.lean b/Mathlib/Data/Nat/Find.lean index 84ee3406a3e5a7..b26536ee0f5172 100644 --- a/Mathlib/Data/Nat/Find.lean +++ b/Mathlib/Data/Nat/Find.lean @@ -26,10 +26,10 @@ variable [DecidablePred p] (H : ∃ n, p n) private def wf_lbp : WellFounded (@lbp p) := ⟨let ⟨n, pn⟩ := H - suffices ∀ m k, n ≤ k + m → Acc lbp k from fun a => this _ _ (Nat.le_add_left _ _) + suffices ∀ m k, n ≤ k + m → Acc lbp k from fun _ => this _ _ (Nat.le_add_left _ _) fun m => Nat.recOn m - (fun k kn => + (fun _ kn => ⟨_, fun y r => match y, r with | _, ⟨rfl, a⟩ => absurd pn (a _ kn)⟩) @@ -46,7 +46,7 @@ protected def findX : { n // p n ∧ ∀ m < n, ¬p m } := have : ∀ n ≤ m, ¬p n := fun n h => Or.elim (Nat.lt_or_eq_of_le h) (al n) fun e => by rw [e]; exact pm IH _ ⟨rfl, this⟩ fun n h => this n <| Nat.le_of_succ_le_succ h) - 0 fun n h => absurd h (Nat.not_lt_zero _) + 0 fun _ h => absurd h (Nat.not_lt_zero _) /-- If `p` is a (decidable) predicate on `ℕ` and `hp : ∃ (n : ℕ), p n` is a proof that there exists some natural number satisfying `p`, then `Nat.find hp` is the diff --git a/Mathlib/Data/Nat/Lattice.lean b/Mathlib/Data/Nat/Lattice.lean index 46be67ef9f99d6..cd3c50fdd53c6e 100644 --- a/Mathlib/Data/Nat/Lattice.lean +++ b/Mathlib/Data/Nat/Lattice.lean @@ -61,7 +61,7 @@ theorem iInf_of_empty {ι : Sort*} [IsEmpty ι] (f : ι → ℕ) : iInf f = 0 := /-- This combines `Nat.iInf_of_empty` with `ciInf_const`. -/ @[simp] -lemma iInf_const_zero {ι : Sort*} : ⨅ i : ι, 0 = 0 := +lemma iInf_const_zero {ι : Sort*} : ⨅ _ : ι, 0 = 0 := (isEmpty_or_nonempty ι).elim (fun h ↦ by simp) fun h ↦ sInf_eq_zero.2 <| by simp theorem sInf_mem {s : Set ℕ} (h : s.Nonempty) : sInf s ∈ s := by diff --git a/Mathlib/Data/Nat/Log.lean b/Mathlib/Data/Nat/Log.lean index f2cf3df6eca07a..84480adb295c4e 100644 --- a/Mathlib/Data/Nat/Log.lean +++ b/Mathlib/Data/Nat/Log.lean @@ -21,6 +21,14 @@ left adjoints of `Nat.pow b`. See `pow_le_iff_le_log` and `le_pow_iff_clog_le`. namespace Nat +#adaptation_note +/-- +After leanprover/lean4#5338 we just unused argument warnings, +but these are used in the decreasing by blocks. +If instead we inline the `have` blocks, the unusedHavesSuffices linter triggers. +-/ +set_option linter.unusedVariables false + /-! ### Floor logarithm -/ diff --git a/Mathlib/Data/Nat/Pairing.lean b/Mathlib/Data/Nat/Pairing.lean index 6265833d77e174..bda4acd194b8d8 100644 --- a/Mathlib/Data/Nat/Pairing.lean +++ b/Mathlib/Data/Nat/Pairing.lean @@ -93,7 +93,7 @@ theorem unpair_zero : unpair 0 = 0 := by theorem unpair_left_le : ∀ n : ℕ, (unpair n).1 ≤ n | 0 => by simp - | n + 1 => le_of_lt (unpair_lt (Nat.succ_pos _)) + | _ + 1 => le_of_lt (unpair_lt (Nat.succ_pos _)) theorem left_le_pair (a b : ℕ) : a ≤ pair a b := by simpa using unpair_left_le (pair a b) diff --git a/Mathlib/Data/Nat/PartENat.lean b/Mathlib/Data/Nat/PartENat.lean index cc13db102cac56..83ed1864a30f6f 100644 --- a/Mathlib/Data/Nat/PartENat.lean +++ b/Mathlib/Data/Nat/PartENat.lean @@ -87,10 +87,10 @@ theorem dom_some (x : ℕ) : (some x).Dom := instance addCommMonoid : AddCommMonoid PartENat where add := (· + ·) zero := 0 - add_comm x y := Part.ext' and_comm fun _ _ => add_comm _ _ - zero_add x := Part.ext' (iff_of_eq (true_and _)) fun _ _ => zero_add _ - add_zero x := Part.ext' (iff_of_eq (and_true _)) fun _ _ => add_zero _ - add_assoc x y z := Part.ext' and_assoc fun _ _ => add_assoc _ _ _ + add_comm _ _ := Part.ext' and_comm fun _ _ => add_comm _ _ + zero_add _ := Part.ext' (iff_of_eq (true_and _)) fun _ _ => zero_add _ + add_zero _ := Part.ext' (iff_of_eq (and_true _)) fun _ _ => add_zero _ + add_assoc _ _ _ := Part.ext' and_assoc fun _ _ => add_assoc _ _ _ nsmul := nsmulRec instance : AddCommMonoidWithOne PartENat := @@ -415,8 +415,8 @@ noncomputable instance : CanonicallyOrderedAddCommMonoid PartENat := { PartENat.semilatticeSup, PartENat.orderBot, PartENat.orderedAddCommMonoid with le_self_add := fun a b => - PartENat.casesOn b (le_top.trans_eq (add_top _).symm) fun b => - PartENat.casesOn a (top_add _).ge fun a => + PartENat.casesOn b (le_top.trans_eq (add_top _).symm) fun _ => + PartENat.casesOn a (top_add _).ge fun _ => (coe_le_coe.2 le_self_add).trans_eq (Nat.cast_add _ _) exists_add_of_le := fun {a b} => PartENat.casesOn b (fun _ => ⟨⊤, (add_top _).symm⟩) fun b => diff --git a/Mathlib/Data/Nat/Prime/Basic.lean b/Mathlib/Data/Nat/Prime/Basic.lean index 06a9ca4221721a..d1a2155b074aed 100644 --- a/Mathlib/Data/Nat/Prime/Basic.lean +++ b/Mathlib/Data/Nat/Prime/Basic.lean @@ -197,7 +197,7 @@ theorem Prime.mul_eq_prime_sq_iff {x y p : ℕ} (hp : p.Prime) (hx : x ≠ 1) (h exact h theorem Prime.dvd_factorial : ∀ {n p : ℕ} (_ : Prime p), p ∣ n ! ↔ p ≤ n - | 0, p, hp => iff_of_false hp.not_dvd_one (not_le_of_lt hp.pos) + | 0, _, hp => iff_of_false hp.not_dvd_one (not_le_of_lt hp.pos) | n + 1, p, hp => by rw [factorial_succ, hp.dvd_mul, Prime.dvd_factorial hp] exact diff --git a/Mathlib/Data/Nat/Prime/Defs.lean b/Mathlib/Data/Nat/Prime/Defs.lean index a7b24cb865b8fe..67e72199f933ab 100644 --- a/Mathlib/Data/Nat/Prime/Defs.lean +++ b/Mathlib/Data/Nat/Prime/Defs.lean @@ -404,7 +404,7 @@ theorem coprime_of_dvd {m n : ℕ} (H : ∀ k, Prime k → k ∣ m → ¬k ∣ n theorem Prime.coprime_iff_not_dvd {p n : ℕ} (pp : Prime p) : Coprime p n ↔ ¬p ∣ n := ⟨fun co d => pp.not_dvd_one <| co.dvd_of_dvd_mul_left (by simp [d]), fun nd => - coprime_of_dvd fun m m2 mp => ((prime_dvd_prime_iff_eq m2 pp).1 mp).symm ▸ nd⟩ + coprime_of_dvd fun _ m2 mp => ((prime_dvd_prime_iff_eq m2 pp).1 mp).symm ▸ nd⟩ theorem Prime.dvd_mul {p m n : ℕ} (pp : Prime p) : p ∣ m * n ↔ p ∣ m ∨ p ∣ n := ⟨fun H => or_iff_not_imp_left.2 fun h => (pp.coprime_iff_not_dvd.2 h).dvd_of_dvd_mul_left H, diff --git a/Mathlib/Data/Num/Lemmas.lean b/Mathlib/Data/Num/Lemmas.lean index c95ab439e4cf47..2808a6ef83358d 100644 --- a/Mathlib/Data/Num/Lemmas.lean +++ b/Mathlib/Data/Num/Lemmas.lean @@ -55,7 +55,7 @@ theorem cast_to_int [AddGroupWithOne α] (n : PosNum) : ((n : ℤ) : α) = n := theorem succ_to_nat : ∀ n, (succ n : ℕ) = n + 1 | 1 => rfl - | bit0 p => rfl + | bit0 _ => rfl | bit1 p => (congr_arg (fun n ↦ n + n) (succ_to_nat p)).trans <| show ↑p + 1 + ↑p + 1 = ↑p + ↑p + 1 + 1 by simp [add_left_comm] @@ -83,9 +83,9 @@ theorem add_succ : ∀ m n : PosNum, m + succ n = succ (m + n) | 1, b => by simp [one_add] | bit0 a, 1 => congr_arg bit0 (add_one a) | bit1 a, 1 => congr_arg bit1 (add_one a) - | bit0 a, bit0 b => rfl + | bit0 _, bit0 _ => rfl | bit0 a, bit1 b => congr_arg bit0 (add_succ a b) - | bit1 a, bit0 b => rfl + | bit1 _, bit0 _ => rfl | bit1 a, bit1 b => congr_arg bit1 (add_succ a b) theorem bit0_of_bit0 : ∀ n, n + n = bit0 n @@ -187,7 +187,7 @@ theorem add_one : ∀ n : Num, n + 1 = succ n theorem add_succ : ∀ m n : Num, m + succ n = succ (m + n) | 0, n => by simp [zero_add] | pos p, 0 => show pos (p + 1) = succ (pos p + 0) by rw [PosNum.add_one, add_zero, succ, succ'] - | pos p, pos q => congr_arg pos (PosNum.add_succ _ _) + | pos _, pos _ => congr_arg pos (PosNum.add_succ _ _) theorem bit0_of_bit0 : ∀ n : Num, n + n = n.bit0 | 0 => rfl @@ -269,8 +269,8 @@ theorem mul_to_nat : ∀ m n, ((m * n : Num) : ℕ) = m * n theorem cmp_to_nat : ∀ m n, (Ordering.casesOn (cmp m n) ((m : ℕ) < n) (m = n) ((n : ℕ) < m) : Prop) | 0, 0 => rfl - | 0, pos b => to_nat_pos _ - | pos a, 0 => to_nat_pos _ + | 0, pos _ => to_nat_pos _ + | pos _, 0 => to_nat_pos _ | pos a, pos b => by have := PosNum.cmp_to_nat a b; revert this; dsimp [cmp]; cases PosNum.cmp a b exacts [id, congr_arg pos, id] @@ -462,7 +462,7 @@ theorem pred'_to_nat : ∀ n, (pred' n : ℕ) = Nat.pred n pred' n, this with | 0, (h : ((1 : Num) : ℕ) = n) => by rw [← to_nat_inj.1 h]; rfl | Num.pos p, (h : Nat.succ ↑p = n) => by rw [← h]; exact (Nat.succ_add p p).symm - | bit1 n => rfl + | bit1 _ => rfl @[simp] theorem pred'_succ' (n) : pred' (succ' n) = n := @@ -1095,7 +1095,7 @@ theorem ofInt'_toZNum : ∀ n : ℕ, toZNum n = ZNum.ofInt' n theorem mem_ofZNum' : ∀ {m : Num} {n : ZNum}, m ∈ ofZNum' n ↔ n = toZNum m | 0, 0 => ⟨fun _ => rfl, fun _ => rfl⟩ - | pos m, 0 => ⟨nofun, nofun⟩ + | pos _, 0 => ⟨nofun, nofun⟩ | m, ZNum.pos p => Option.some_inj.trans <| by cases m <;> constructor <;> intro h <;> try cases h <;> rfl | m, ZNum.neg p => ⟨nofun, fun h => by cases m <;> cases h⟩ @@ -1134,7 +1134,7 @@ variable {α : Type*} theorem cast_add [AddGroupWithOne α] : ∀ m n, ((m + n : ZNum) : α) = m + n | 0, a => by cases a <;> exact (_root_.zero_add _).symm | b, 0 => by cases b <;> exact (_root_.add_zero _).symm - | pos a, pos b => PosNum.cast_add _ _ + | pos _, pos _ => PosNum.cast_add _ _ | pos a, neg b => by simpa only [sub_eq_add_neg] using PosNum.cast_sub' (α := α) _ _ | neg a, pos b => have : (↑b + -↑a : α) = -↑a + ↑b := by @@ -1185,12 +1185,12 @@ theorem cmp_to_int : ∀ m n, (Ordering.casesOn (cmp m n) ((m : ℤ) < n) (m = n | neg a, neg b => by have := PosNum.cmp_to_nat b a; revert this; dsimp [cmp] cases PosNum.cmp b a <;> dsimp <;> [simp; simp (config := { contextual := true }); simp [GT.gt]] - | pos a, 0 => PosNum.cast_pos _ - | pos a, neg b => lt_trans (neg_lt_zero.2 <| PosNum.cast_pos _) (PosNum.cast_pos _) - | 0, neg b => neg_lt_zero.2 <| PosNum.cast_pos _ - | neg a, 0 => neg_lt_zero.2 <| PosNum.cast_pos _ - | neg a, pos b => lt_trans (neg_lt_zero.2 <| PosNum.cast_pos _) (PosNum.cast_pos _) - | 0, pos b => PosNum.cast_pos _ + | pos _, 0 => PosNum.cast_pos _ + | pos _, neg _ => lt_trans (neg_lt_zero.2 <| PosNum.cast_pos _) (PosNum.cast_pos _) + | 0, neg _ => neg_lt_zero.2 <| PosNum.cast_pos _ + | neg _, 0 => neg_lt_zero.2 <| PosNum.cast_pos _ + | neg _, pos _ => lt_trans (neg_lt_zero.2 <| PosNum.cast_pos _) (PosNum.cast_pos _) + | 0, pos _ => PosNum.cast_pos _ @[norm_cast] theorem lt_to_int {m n : ZNum} : (m : ℤ) < n ↔ m < n := @@ -1326,9 +1326,9 @@ theorem cast_sub [Ring α] (m n) : ((m - n : ZNum) : α) = m - n := by simp [sub @[norm_cast] -- @[simp] -- Porting note (#10618): simp can prove this theorem neg_of_int : ∀ n, ((-n : ℤ) : ZNum) = -n - | (n + 1 : ℕ) => rfl + | (_ + 1 : ℕ) => rfl | 0 => by rw [Int.cast_neg] - | -[n+1] => (zneg_zneg _).symm + | -[_+1] => (zneg_zneg _).symm @[simp] theorem ofInt'_eq : ∀ n : ℤ, ZNum.ofInt' n = n @@ -1440,9 +1440,9 @@ protected theorem div_zero (n : Num) : n / 0 = 0 := @[simp, norm_cast] theorem div_to_nat : ∀ n d, ((n / d : Num) : ℕ) = n / d | 0, 0 => by simp - | 0, pos d => (Nat.zero_div _).symm - | pos n, 0 => (Nat.div_zero _).symm - | pos n, pos d => PosNum.div'_to_nat _ _ + | 0, pos _ => (Nat.zero_div _).symm + | pos _, 0 => (Nat.div_zero _).symm + | pos _, pos _ => PosNum.div'_to_nat _ _ @[simp] protected theorem mod_zero (n : Num) : n % 0 = n := @@ -1454,16 +1454,16 @@ protected theorem mod_zero (n : Num) : n % 0 = n := @[simp, norm_cast] theorem mod_to_nat : ∀ n d, ((n % d : Num) : ℕ) = n % d | 0, 0 => by simp - | 0, pos d => (Nat.zero_mod _).symm - | pos n, 0 => (Nat.mod_zero _).symm - | pos n, pos d => PosNum.mod'_to_nat _ _ + | 0, pos _ => (Nat.zero_mod _).symm + | pos _, 0 => (Nat.mod_zero _).symm + | pos _, pos _ => PosNum.mod'_to_nat _ _ theorem gcd_to_nat_aux : ∀ {n} {a b : Num}, a ≤ b → (a * b).natSize ≤ n → (gcdAux n a b : ℕ) = Nat.gcd a b - | 0, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm - | 0, pos a, 0, ab, _h => (not_lt_of_ge ab).elim rfl - | 0, pos a, pos b, _ab, h => (not_lt_of_le h).elim <| PosNum.natSize_pos _ - | Nat.succ n, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm + | 0, 0, _, _ab, _h => (Nat.gcd_zero_left _).symm + | 0, pos _, 0, ab, _h => (not_lt_of_ge ab).elim rfl + | 0, pos _, pos _, _ab, h => (not_lt_of_le h).elim <| PosNum.natSize_pos _ + | Nat.succ _, 0, _, _ab, _h => (Nat.gcd_zero_left _).symm | Nat.succ n, pos a, b, ab, h => by simp only [gcdAux, cast_pos] rw [Nat.gcd_rec, gcd_to_nat_aux, mod_to_nat] @@ -1516,10 +1516,10 @@ protected theorem div_zero (n : ZNum) : n / 0 = 0 := @[simp, norm_cast] theorem div_to_int : ∀ n d, ((n / d : ZNum) : ℤ) = n / d | 0, 0 => by simp [Int.ediv_zero] - | 0, pos d => (Int.zero_ediv _).symm - | 0, neg d => (Int.zero_ediv _).symm - | pos n, 0 => (Int.ediv_zero _).symm - | neg n, 0 => (Int.ediv_zero _).symm + | 0, pos _ => (Int.zero_ediv _).symm + | 0, neg _ => (Int.zero_ediv _).symm + | pos _, 0 => (Int.ediv_zero _).symm + | neg _, 0 => (Int.ediv_zero _).symm | pos n, pos d => (Num.cast_toZNum _).trans <| by rw [← Num.to_nat_to_int]; simp | pos n, neg d => (Num.cast_toZNumNeg _).trans <| by rw [← Num.to_nat_to_int]; simp | neg n, pos d => @@ -1537,7 +1537,7 @@ theorem div_to_int : ∀ n d, ((n / d : ZNum) : ℤ) = n / d @[simp, norm_cast] theorem mod_to_int : ∀ n d, ((n % d : ZNum) : ℤ) = n % d - | 0, d => (Int.zero_emod _).symm + | 0, _ => (Int.zero_emod _).symm | pos n, d => (Num.cast_toZNum _).trans <| by rw [← Num.to_nat_to_int, cast_pos, Num.mod_to_nat, ← PosNum.to_nat_to_int, abs_to_nat] diff --git a/Mathlib/Data/Option/Basic.lean b/Mathlib/Data/Option/Basic.lean index b0bab527487d94..ba871ac9136bad 100644 --- a/Mathlib/Data/Option/Basic.lean +++ b/Mathlib/Data/Option/Basic.lean @@ -149,7 +149,7 @@ theorem mem_pmem {a : α} (h : ∀ a ∈ x, p a) (ha : a ∈ x) : f a (h a ha) rfl theorem pmap_map (g : γ → α) (x : Option γ) (H) : - pmap f (x.map g) H = pmap (fun a h ↦ f (g a) h) x fun a h ↦ H _ (mem_map_of_mem _ h) := by + pmap f (x.map g) H = pmap (fun a h ↦ f (g a) h) x fun _ h ↦ H _ (mem_map_of_mem _ h) := by cases x <;> simp only [map_none', map_some', pmap] theorem map_pmap (g : β → γ) (f : ∀ a, p a → β) (x H) : @@ -164,7 +164,7 @@ theorem pmap_eq_map (p : α → Prop) (f : α → β) (x H) : theorem pmap_bind {α β γ} {x : Option α} {g : α → Option β} {p : β → Prop} {f : ∀ b, p b → γ} (H) (H' : ∀ (a : α), ∀ b ∈ g a, b ∈ x >>= g) : - pmap f (x >>= g) H = x >>= fun a ↦ pmap f (g a) fun b h ↦ H _ (H' a _ h) := by + pmap f (x >>= g) H = x >>= fun a ↦ pmap f (g a) fun _ h ↦ H _ (H' a _ h) := by cases x <;> simp only [pmap, bind_eq_bind, none_bind, some_bind] theorem bind_pmap {α β γ} {p : α → Prop} (f : ∀ a, p a → β) (x : Option α) (g : β → Option γ) (H) : @@ -233,8 +233,8 @@ theorem guard_eq_some' {p : Prop} [Decidable p] (u) : _root_.guard p = some u theorem liftOrGet_choice {f : α → α → α} (h : ∀ a b, f a b = a ∨ f a b = b) : ∀ o₁ o₂, liftOrGet f o₁ o₂ = o₁ ∨ liftOrGet f o₁ o₂ = o₂ | none, none => Or.inl rfl - | some a, none => Or.inl rfl - | none, some b => Or.inr rfl + | some _, none => Or.inl rfl + | none, some _ => Or.inr rfl | some a, some b => by simpa [liftOrGet] using h a b /-- Given an element of `a : Option α`, a default element `b : β` and a function `α → β`, apply this diff --git a/Mathlib/Data/Option/Defs.lean b/Mathlib/Data/Option/Defs.lean index c15bedf8531353..d4e660aac7a682 100644 --- a/Mathlib/Data/Option/Defs.lean +++ b/Mathlib/Data/Option/Defs.lean @@ -59,7 +59,7 @@ instance decidableForallMem {p : α → Prop} [DecidablePred p] : ∀ o : Option α, Decidable (∀ a ∈ o, p a) | none => isTrue (by simp [false_imp_iff]) | some a => - if h : p a then isTrue fun o e ↦ some_inj.1 e ▸ h + if h : p a then isTrue fun _ e ↦ some_inj.1 e ▸ h else isFalse <| mt (fun H ↦ H _ rfl) h instance decidableExistsMem {p : α → Prop} [DecidablePred p] : diff --git a/Mathlib/Data/Ordmap/Ordset.lean b/Mathlib/Data/Ordmap/Ordset.lean index ca4d7b8c2efab7..290b42a70f8e6e 100644 --- a/Mathlib/Data/Ordmap/Ordset.lean +++ b/Mathlib/Data/Ordmap/Ordset.lean @@ -459,7 +459,7 @@ theorem all_balance' {P l x r} : @All α P (balance' l x r) ↔ All P l ∧ P x theorem foldr_cons_eq_toList : ∀ (t : Ordnode α) (r : List α), t.foldr List.cons r = toList t ++ r - | nil, r => rfl + | nil, _ => rfl | node _ l x r, r' => by rw [foldr, foldr_cons_eq_toList l, foldr_cons_eq_toList r, ← List.cons_append, ← List.append_assoc, ← foldr_cons_eq_toList l]; rfl @@ -513,7 +513,7 @@ theorem findMax_dual (t : Ordnode α) : findMax (dual t) = findMin t := by theorem dual_eraseMin : ∀ t : Ordnode α, dual (eraseMin t) = eraseMax (dual t) | nil => rfl - | node _ nil x r => rfl + | node _ nil _ _ => rfl | node _ (node sz l' y r') x r => by rw [eraseMin, dual_balanceR, dual_eraseMin (node sz l' y r'), dual, dual, dual, eraseMax] @@ -522,12 +522,12 @@ theorem dual_eraseMax (t : Ordnode α) : dual (eraseMax t) = eraseMin (dual t) : theorem splitMin_eq : ∀ (s l) (x : α) (r), splitMin' l x r = (findMin' l x, eraseMin (node s l x r)) - | _, nil, x, r => rfl + | _, nil, _, _ => rfl | _, node ls ll lx lr, x, r => by rw [splitMin', splitMin_eq ls ll lx lr, findMin', eraseMin] theorem splitMax_eq : ∀ (s l) (x : α) (r), splitMax' l x r = (eraseMax (node s l x r), findMax' x r) - | _, l, x, nil => rfl + | _, _, _, nil => rfl | _, l, x, node ls ll lx lr => by rw [splitMax', splitMax_eq ls ll lx lr, findMax', eraseMax] @[elab_as_elim] @@ -793,7 +793,7 @@ def Bounded : Ordnode α → WithBot α → WithTop α → Prop theorem Bounded.dual : ∀ {t : Ordnode α} {o₁ o₂}, Bounded t o₁ o₂ → @Bounded αᵒᵈ _ (dual t) o₂ o₁ | nil, o₁, o₂, h => by cases o₁ <;> cases o₂ <;> trivial - | node _ l x r, _, _, ⟨ol, Or⟩ => ⟨Or.dual, ol.dual⟩ + | node _ _ _ _, _, _, ⟨ol, Or⟩ => ⟨Or.dual, ol.dual⟩ theorem Bounded.dual_iff {t : Ordnode α} {o₁ o₂} : Bounded t o₁ o₂ ↔ @Bounded αᵒᵈ _ (.dual t) o₂ o₁ := @@ -802,11 +802,11 @@ theorem Bounded.dual_iff {t : Ordnode α} {o₁ o₂} : theorem Bounded.weak_left : ∀ {t : Ordnode α} {o₁ o₂}, Bounded t o₁ o₂ → Bounded t ⊥ o₂ | nil, o₁, o₂, h => by cases o₂ <;> trivial - | node _ l x r, _, _, ⟨ol, Or⟩ => ⟨ol.weak_left, Or⟩ + | node _ _ _ _, _, _, ⟨ol, Or⟩ => ⟨ol.weak_left, Or⟩ theorem Bounded.weak_right : ∀ {t : Ordnode α} {o₁ o₂}, Bounded t o₁ o₂ → Bounded t o₁ ⊤ | nil, o₁, o₂, h => by cases o₁ <;> trivial - | node _ l x r, _, _, ⟨ol, Or⟩ => ⟨ol, Or.weak_right⟩ + | node _ _ _ _, _, _, ⟨ol, Or⟩ => ⟨ol, Or.weak_right⟩ theorem Bounded.weak {t : Ordnode α} {o₁ o₂} (h : Bounded t o₁ o₂) : Bounded t ⊥ ⊤ := h.weak_left.weak_right @@ -929,8 +929,8 @@ theorem Valid'.node {s l} {x : α} {r o₁ o₂} (hl : Valid' o₁ l x) (hr : Va ⟨⟨hl.1, hr.1⟩, ⟨hs, hl.2, hr.2⟩, ⟨H, hl.3, hr.3⟩⟩ theorem Valid'.dual : ∀ {t : Ordnode α} {o₁ o₂}, Valid' o₁ t o₂ → @Valid' αᵒᵈ _ o₂ (dual t) o₁ - | .nil, o₁, o₂, h => valid'_nil h.1.dual - | .node _ l x r, o₁, o₂, ⟨⟨ol, Or⟩, ⟨rfl, sl, sr⟩, ⟨b, bl, br⟩⟩ => + | .nil, _, _, h => valid'_nil h.1.dual + | .node _ l _ r, _, _, ⟨⟨ol, Or⟩, ⟨rfl, sl, sr⟩, ⟨b, bl, br⟩⟩ => let ⟨ol', sl', bl'⟩ := Valid'.dual ⟨ol, sl, bl⟩ let ⟨or', sr', br'⟩ := Valid'.dual ⟨Or, sr, br⟩ ⟨⟨or', ol'⟩, ⟨by simp [size_dual, add_comm], sr', sl'⟩, @@ -1324,7 +1324,7 @@ theorem insertWith.valid_aux [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ Bounded nil o₁ x → Bounded nil x o₂ → Valid' o₁ (insertWith f x t) o₂ ∧ Raised (size t) (size (insertWith f x t)) - | nil, o₁, o₂, _, bl, br => ⟨valid'_singleton bl br, Or.inr rfl⟩ + | nil, _, _, _, bl, br => ⟨valid'_singleton bl br, Or.inr rfl⟩ | node sz l y r, o₁, o₂, h, bl, br => by rw [insertWith, cmpLE] split_ifs with h_1 h_2 <;> dsimp only diff --git a/Mathlib/Data/PEquiv.lean b/Mathlib/Data/PEquiv.lean index 920084d283b41b..3228b351dff8f7 100644 --- a/Mathlib/Data/PEquiv.lean +++ b/Mathlib/Data/PEquiv.lean @@ -362,7 +362,7 @@ section Order instance instPartialOrderPEquiv : PartialOrder (α ≃. β) where le f g := ∀ (a : α) (b : β), b ∈ f a → b ∈ g a le_refl _ _ _ := id - le_trans f g h fg gh a b := gh a b ∘ fg a b + le_trans _ _ _ fg gh a b := gh a b ∘ fg a b le_antisymm f g fg gf := ext (by diff --git a/Mathlib/Data/PFun.lean b/Mathlib/Data/PFun.lean index 376018c747f3e2..3c24f0c13cc701 100644 --- a/Mathlib/Data/PFun.lean +++ b/Mathlib/Data/PFun.lean @@ -109,8 +109,8 @@ def asSubtype (f : α →. β) (s : f.Dom) : β := /-- The type of partial functions `α →. β` is equivalent to the type of pairs `(p : α → Prop, f : Subtype p → β)`. -/ def equivSubtype : (α →. β) ≃ Σp : α → Prop, Subtype p → β := - ⟨fun f => ⟨fun a => (f a).Dom, asSubtype f⟩, fun f x => ⟨f.1 x, fun h => f.2 ⟨x, h⟩⟩, fun f => - funext fun a => Part.eta _, fun ⟨p, f⟩ => by dsimp; congr⟩ + ⟨fun f => ⟨fun a => (f a).Dom, asSubtype f⟩, fun f x => ⟨f.1 x, fun h => f.2 ⟨x, h⟩⟩, fun _ => + funext fun _ => Part.eta _, fun ⟨p, f⟩ => by dsimp; congr⟩ theorem asSubtype_eq_of_mem {f : α →. β} {x : α} {y : β} (fxy : y ∈ f x) (domx : x ∈ f.Dom) : f.asSubtype ⟨x, domx⟩ = y := @@ -191,9 +191,9 @@ instance monad : Monad (PFun α) where map := PFun.map instance lawfulMonad : LawfulMonad (PFun α) := LawfulMonad.mk' - (bind_pure_comp := fun f x => funext fun a => Part.bind_some_eq_map _ _) + (bind_pure_comp := fun _ _ => funext fun _ => Part.bind_some_eq_map _ _) (id_map := fun f => by funext a; dsimp [Functor.map, PFun.map]; cases f a; rfl) - (pure_bind := fun x f => funext fun a => Part.bind_some _ (f x)) + (pure_bind := fun x f => funext fun _ => Part.bind_some _ (f x)) (bind_assoc := fun f g k => funext fun a => (f a).bind_assoc (fun b => g b a) fun b => k b a) theorem pure_defined (p : Set α) (x : β) : p ⊆ (@PFun.pure α _ x).Dom := @@ -292,7 +292,7 @@ def fixInduction {C : α → Sort*} {f : α →. β ⊕ α} {b : β} {a : α} (h theorem fixInduction_spec {C : α → Sort*} {f : α →. β ⊕ α} {b : β} {a : α} (h : b ∈ f.fix a) (H : ∀ a', b ∈ f.fix a' → (∀ a'', Sum.inr a'' ∈ f a' → C a'') → C a') : - @fixInduction _ _ C _ _ _ h H = H a h fun a' h' => fixInduction (fix_fwd h h') H := by + @fixInduction _ _ C _ _ _ h H = H a h fun _ h' => fixInduction (fix_fwd h h') H := by unfold fixInduction generalize_proofs induction ‹Acc _ _› diff --git a/Mathlib/Data/PNat/Basic.lean b/Mathlib/Data/PNat/Basic.lean index d1fcce241c69f9..4f8bb3bc6f0fc0 100644 --- a/Mathlib/Data/PNat/Basic.lean +++ b/Mathlib/Data/PNat/Basic.lean @@ -273,11 +273,11 @@ theorem exists_eq_succ_of_ne_one : ∀ {n : ℕ+} (_ : n ≠ 1), ∃ k : ℕ+, n theorem modDivAux_spec : ∀ (k : ℕ+) (r q : ℕ) (_ : ¬(r = 0 ∧ q = 0)), ((modDivAux k r q).1 : ℕ) + k * (modDivAux k r q).2 = r + k * q - | k, 0, 0, h => (h ⟨rfl, rfl⟩).elim + | _, 0, 0, h => (h ⟨rfl, rfl⟩).elim | k, 0, q + 1, _ => by change (k : ℕ) + (k : ℕ) * (q + 1).pred = 0 + (k : ℕ) * (q + 1) rw [Nat.pred_succ, Nat.mul_succ, zero_add, add_comm] - | k, r + 1, q, _ => rfl + | _, _ + 1, _, _ => rfl theorem mod_add_div (m k : ℕ+) : (mod m k + k * div m k : ℕ) = m := by let h₀ := Nat.mod_add_div (m : ℕ) (k : ℕ) diff --git a/Mathlib/Data/PSigma/Order.lean b/Mathlib/Data/PSigma/Order.lean index fe0d6b8051e5bc..c4337051e8a85f 100644 --- a/Mathlib/Data/PSigma/Order.lean +++ b/Mathlib/Data/PSigma/Order.lean @@ -51,7 +51,7 @@ instance lt [LT ι] [∀ i, LT (α i)] : LT (Σₗ' i, α i) := instance preorder [Preorder ι] [∀ i, Preorder (α i)] : Preorder (Σₗ' i, α i) := { Lex.le, Lex.lt with - le_refl := fun ⟨i, a⟩ => Lex.right _ le_rfl, + le_refl := fun ⟨_, _⟩ => Lex.right _ le_rfl, le_trans := by rintro ⟨a₁, b₁⟩ ⟨a₂, b₂⟩ ⟨a₃, b₃⟩ ⟨h₁r⟩ ⟨h₂r⟩ · left diff --git a/Mathlib/Data/Part.lean b/Mathlib/Data/Part.lean index c4903f9bf5b4a5..58395794466e5e 100644 --- a/Mathlib/Data/Part.lean +++ b/Mathlib/Data/Part.lean @@ -330,9 +330,9 @@ noncomputable def equivOption : Part α ≃ Option α := instance : PartialOrder (Part α) where le x y := ∀ i, i ∈ x → i ∈ y - le_refl x y := id - le_trans x y z f g i := g _ ∘ f _ - le_antisymm x y f g := Part.ext fun z => ⟨f _, g _⟩ + le_refl _ _ := id + le_trans _ _ _ f g _ := g _ ∘ f _ + le_antisymm _ _ f g := Part.ext fun _ => ⟨f _, g _⟩ instance : OrderBot (Part α) where bot := none diff --git a/Mathlib/Data/QPF/Multivariate/Constructions/Comp.lean b/Mathlib/Data/QPF/Multivariate/Constructions/Comp.lean index 59234b2be7b7e7..c8681c4243c48d 100644 --- a/Mathlib/Data/QPF/Multivariate/Constructions/Comp.lean +++ b/Mathlib/Data/QPF/Multivariate/Constructions/Comp.lean @@ -69,7 +69,7 @@ end 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 i ↦ abs) ∘ abs ∘ MvPFunctor.comp.get + abs := Comp.mk ∘ (map fun _ ↦ abs) ∘ abs ∘ MvPFunctor.comp.get repr {α} := MvPFunctor.comp.mk ∘ repr ∘ (map fun i ↦ (repr : G i α → (fun i : Fin2 n ↦ Obj (P (G i)) α) i)) ∘ Comp.get abs_repr := by diff --git a/Mathlib/Data/QPF/Univariate/Basic.lean b/Mathlib/Data/QPF/Univariate/Basic.lean index b767d995bd81b8..0111a3ccaf83ea 100644 --- a/Mathlib/Data/QPF/Univariate/Basic.lean +++ b/Mathlib/Data/QPF/Univariate/Basic.lean @@ -512,8 +512,8 @@ elements `x y : F α` are in the same equivalence class if 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 - abs {α} p := FG_abs (abs p) - repr {α} x := repr (FG_repr x) + abs {_} p := FG_abs (abs p) + repr {_} x := repr (FG_repr x) abs_repr {α} x := by simp only; rw [abs_repr, FG_abs_repr] abs_map {α β} f x := by simp only; rw [abs_map, FG_abs_map] diff --git a/Mathlib/Data/Quot.lean b/Mathlib/Data/Quot.lean index 05fbfe253206f8..a6769d8795ab8e 100644 --- a/Mathlib/Data/Quot.lean +++ b/Mathlib/Data/Quot.lean @@ -66,7 +66,7 @@ protected def hrecOn₂ (qa : Quot ra) (qb : Quot rb) (f : ∀ a b, φ ⟦a⟧ (cb : ∀ {a b₁ b₂}, rb b₁ b₂ → HEq (f a b₁) (f a b₂)) : φ qa qb := Quot.hrecOn (motive := fun qa ↦ φ qa qb) qa - (fun a ↦ Quot.hrecOn qb (f a) (fun b₁ b₂ pb ↦ cb pb)) + (fun a ↦ Quot.hrecOn qb (f a) (fun _ _ pb ↦ cb pb)) fun a₁ a₂ pa ↦ Quot.induction_on qb fun b ↦ have h₁ : HEq (@Quot.hrecOn _ _ (φ _) ⟦b⟧ (f a₁) (@cb _)) (f a₁ b) := by diff --git a/Mathlib/Data/Rat/Floor.lean b/Mathlib/Data/Rat/Floor.lean index 9c7accdfc0acb1..98b0835e7c8081 100644 --- a/Mathlib/Data/Rat/Floor.lean +++ b/Mathlib/Data/Rat/Floor.lean @@ -103,14 +103,14 @@ def evalIntFloor : NormNumExt where eval {u αZ} e := do | 0, ~q(ℤ), ~q(@Int.floor $α $instR $instF $x) => match ← derive x with | .isBool .. => failure - | .isNat sα nb pb => do + | .isNat _ _ pb => do assertInstancesCommute return .isNat q(inferInstance) _ q(isNat_intFloor $x _ $pb) - | .isNegNat sα nb pb => do + | .isNegNat _ _ pb => do assertInstancesCommute -- floor always keeps naturals negative, so we can shortcut `.isInt` return .isNegNat q(inferInstance) _ q(isInt_intFloor _ _ $pb) - | .isRat dα q n d h => do + | .isRat _ q n d h => do let _i ← synthInstanceQ q(LinearOrderedField $α) assertInstancesCommute have z : Q(ℤ) := mkRawIntLit ⌊q⌋ diff --git a/Mathlib/Data/Rat/Lemmas.lean b/Mathlib/Data/Rat/Lemmas.lean index 0aa562b90bce1b..2423ed18b9d604 100644 --- a/Mathlib/Data/Rat/Lemmas.lean +++ b/Mathlib/Data/Rat/Lemmas.lean @@ -302,7 +302,7 @@ protected theorem «forall» {p : ℚ → Prop} : (∀ r, p r) ↔ ∀ a b : ℤ rwa [Int.cast_natCast, num_div_den q] at this⟩ protected theorem «exists» {p : ℚ → Prop} : (∃ r, p r) ↔ ∃ a b : ℤ, p (a / b) := - ⟨fun ⟨r, hr⟩ => ⟨r.num, r.den, by convert hr; convert num_div_den r⟩, fun ⟨a, b, h⟩ => ⟨_, h⟩⟩ + ⟨fun ⟨r, hr⟩ => ⟨r.num, r.den, by convert hr; convert num_div_den r⟩, fun ⟨_, _, h⟩ => ⟨_, h⟩⟩ /-! ### Denominator as `ℕ+` diff --git a/Mathlib/Data/Real/Basic.lean b/Mathlib/Data/Real/Basic.lean index 7cec019cb7dbe9..9efe0fb5d9ae33 100644 --- a/Mathlib/Data/Real/Basic.lean +++ b/Mathlib/Data/Real/Basic.lean @@ -520,9 +520,9 @@ noncomputable instance instLinearOrderedField : LinearOrderedField ℝ where exact CauSeq.Completion.inv_mul_cancel h inv_zero := by simp [← ofCauchy_zero, ← ofCauchy_inv] nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl qsmul := _ - qsmul_def := fun q a => rfl + qsmul_def := fun _ _ => rfl nnratCast_def q := by rw [← ofCauchy_nnratCast, NNRat.cast_def, ofCauchy_div, ofCauchy_natCast, ofCauchy_natCast] ratCast_def q := by diff --git a/Mathlib/Data/Real/EReal.lean b/Mathlib/Data/Real/EReal.lean index 4ff49b8b9459bf..884f58c535ef5f 100644 --- a/Mathlib/Data/Real/EReal.lean +++ b/Mathlib/Data/Real/EReal.lean @@ -673,7 +673,7 @@ theorem natCast_mul (m n : ℕ) : theorem exists_rat_btwn_of_lt : ∀ {a b : EReal}, a < b → ∃ x : ℚ, a < (x : ℝ) ∧ ((x : ℝ) : EReal) < b - | ⊤, b, h => (not_top_lt h).elim + | ⊤, _, h => (not_top_lt h).elim | (a : ℝ), ⊥, h => (lt_irrefl _ ((bot_lt_coe a).trans h)).elim | (a : ℝ), (b : ℝ), h => by simp [exists_rat_btwn (EReal.coe_lt_coe_iff.1 h)] | (a : ℝ), ⊤, _ => diff --git a/Mathlib/Data/Rel.lean b/Mathlib/Data/Rel.lean index 27adb8a69b26dc..9717d93d288df0 100644 --- a/Mathlib/Data/Rel.lean +++ b/Mathlib/Data/Rel.lean @@ -194,7 +194,7 @@ theorem image_bot (s : Set α) : (⊥ : Rel α β).image s = ∅ := by @[simp] theorem image_top {s : Set α} (h : Set.Nonempty s) : (⊤ : Rel α β).image s = Set.univ := - Set.eq_univ_of_forall fun x ↦ ⟨h.some, by simp [h.some_mem, Top.top]⟩ + Set.eq_univ_of_forall fun _ ↦ ⟨h.some, by simp [h.some_mem, Top.top]⟩ /-- Preimage of a set under a relation `r`. Same as the image of `s` under `r.inv` -/ def preimage (s : Set β) : Set α := diff --git a/Mathlib/Data/Semiquot.lean b/Mathlib/Data/Semiquot.lean index fb1f34b2cb8c30..326ba455059c61 100644 --- a/Mathlib/Data/Semiquot.lean +++ b/Mathlib/Data/Semiquot.lean @@ -153,9 +153,9 @@ instance : LE (Semiquot α) := instance partialOrder : PartialOrder (Semiquot α) where le s t := ∀ ⦃x⦄, x ∈ s → x ∈ t - le_refl s := Set.Subset.refl _ - le_trans s t u := Set.Subset.trans - le_antisymm s t h₁ h₂ := ext_s.2 (Set.Subset.antisymm h₁ h₂) + le_refl _ := Set.Subset.refl _ + le_trans _ _ _ := Set.Subset.trans + le_antisymm _ _ h₁ h₂ := ext_s.2 (Set.Subset.antisymm h₁ h₂) instance : SemilatticeSup (Semiquot α) := { Semiquot.partialOrder with diff --git a/Mathlib/Data/Seq/Computation.lean b/Mathlib/Data/Seq/Computation.lean index 9ff96e3dd47ef9..0cb816198ffd80 100644 --- a/Mathlib/Data/Seq/Computation.lean +++ b/Mathlib/Data/Seq/Computation.lean @@ -960,10 +960,10 @@ theorem liftRel_def {R : α → β → Prop} {ca cb} : let ⟨b', mb', ab⟩ := h.left ma rwa [mem_unique mb mb']⟩, fun ⟨l, r⟩ => - ⟨fun {a} ma => + ⟨fun {_} ma => let ⟨⟨b, mb⟩⟩ := l.1 ⟨⟨_, ma⟩⟩ ⟨b, mb, r ma mb⟩, - fun {b} mb => + fun {_} mb => let ⟨⟨a, ma⟩⟩ := l.2 ⟨⟨_, mb⟩⟩ ⟨a, ma, r ma mb⟩⟩⟩ diff --git a/Mathlib/Data/Seq/Seq.lean b/Mathlib/Data/Seq/Seq.lean index d8dfa6e7ed0374..b005e06bce8fbb 100644 --- a/Mathlib/Data/Seq/Seq.lean +++ b/Mathlib/Data/Seq/Seq.lean @@ -159,7 +159,7 @@ theorem mem_cons_of_mem (y : α) {a : α} : ∀ {s : Seq α}, a ∈ s → a ∈ | ⟨_, _⟩ => Stream'.mem_cons_of_mem (some y) theorem eq_or_mem_of_mem_cons {a b : α} : ∀ {s : Seq α}, a ∈ cons b s → a = b ∨ a ∈ s - | ⟨f, al⟩, h => (Stream'.eq_or_mem_of_mem_cons h).imp_left fun h => by injection h + | ⟨_, _⟩, h => (Stream'.eq_or_mem_of_mem_cons h).imp_left fun h => by injection h @[simp] theorem mem_cons_iff {a b : α} {s : Seq α} : a ∈ cons b s ↔ a = b ∨ a ∈ s := diff --git a/Mathlib/Data/Seq/WSeq.lean b/Mathlib/Data/Seq/WSeq.lean index 4817d9024ec51a..750b2d1d1eda16 100644 --- a/Mathlib/Data/Seq/WSeq.lean +++ b/Mathlib/Data/Seq/WSeq.lean @@ -708,7 +708,7 @@ theorem drop.aux_none : ∀ n, @drop.aux α n none = Computation.pure none rw [ret_bind, drop.aux_none n] theorem destruct_dropn : ∀ (s : WSeq α) (n), destruct (drop s n) = destruct s >>= drop.aux n - | s, 0 => (bind_pure' _).symm + | _, 0 => (bind_pure' _).symm | s, n + 1 => by rw [← dropn_tail, destruct_dropn _ n, destruct_tail, LawfulMonad.bind_assoc] rfl diff --git a/Mathlib/Data/Set/Enumerate.lean b/Mathlib/Data/Set/Enumerate.lean index fd4f8dbb791b13..f5c71a78aa47e6 100644 --- a/Mathlib/Data/Set/Enumerate.lean +++ b/Mathlib/Data/Set/Enumerate.lean @@ -42,7 +42,7 @@ theorem enumerate_eq_none_of_sel {s : Set α} (h : sel s = none) : ∀ {n}, enum theorem enumerate_eq_none : ∀ {s n₁ n₂}, enumerate sel s n₁ = none → n₁ ≤ n₂ → enumerate sel s n₂ = none - | s, 0, m => fun h _ ↦ enumerate_eq_none_of_sel sel h + | _, 0, _ => fun h _ ↦ enumerate_eq_none_of_sel sel h | s, n + 1, m => fun h hm ↦ by cases hs : sel s · exact enumerate_eq_none_of_sel sel hs diff --git a/Mathlib/Data/Set/Finite.lean b/Mathlib/Data/Set/Finite.lean index cf7a2bfbb02d2b..32b8fcd009e0f1 100644 --- a/Mathlib/Data/Set/Finite.lean +++ b/Mathlib/Data/Set/Finite.lean @@ -1009,7 +1009,7 @@ theorem eq_finite_iUnion_of_finite_subset_iUnion {ι} {s : ι → Set α} {t : S I.Finite ∧ ∃ σ : { i | i ∈ I } → Set α, (∀ i, (σ i).Finite) ∧ (∀ i, σ i ⊆ s i) ∧ t = ⋃ i, σ i := let ⟨I, Ifin, hI⟩ := finite_subset_iUnion tfin h - ⟨I, Ifin, fun x => s x ∩ t, fun i => tfin.subset inter_subset_right, fun i => + ⟨I, Ifin, fun x => s x ∩ t, fun _ => tfin.subset inter_subset_right, fun _ => inter_subset_left, by ext x rw [mem_iUnion] @@ -1111,7 +1111,7 @@ theorem card_image_of_inj_on {s : Set α} [Fintype s] {f : α → β} [Fintype ( _ = s.toFinset.card := Finset.card_image_of_injOn fun x hx y hy hxy => H x (mem_toFinset.1 hx) y (mem_toFinset.1 hy) hxy - _ = Fintype.card s := (Fintype.card_of_finset' _ fun a => mem_toFinset).symm + _ = Fintype.card s := (Fintype.card_of_finset' _ fun _ => mem_toFinset).symm theorem card_image_of_injective (s : Set α) [Fintype s] {f : α → β} [Fintype (f '' s)] (H : Function.Injective f) : Fintype.card (f '' s) = Fintype.card s := diff --git a/Mathlib/Data/Set/Function.lean b/Mathlib/Data/Set/Function.lean index 0ae9780c502d9c..4943372c57ca00 100644 --- a/Mathlib/Data/Set/Function.lean +++ b/Mathlib/Data/Set/Function.lean @@ -544,7 +544,7 @@ theorem MapsTo.restrict_inj (h : MapsTo f s t) : Injective (h.restrict f s t) theorem exists_injOn_iff_injective [Nonempty β] : (∃ f : α → β, InjOn f s) ↔ ∃ f : s → β, Injective f := - ⟨fun ⟨f, hf⟩ => ⟨_, hf.injective⟩, + ⟨fun ⟨_, hf⟩ => ⟨_, hf.injective⟩, fun ⟨f, hf⟩ => by lift f to α → β using trivial exact ⟨f, injOn_iff_injective.2 hf⟩⟩ @@ -891,7 +891,7 @@ theorem BijOn.image_eq (h : BijOn f s t) : f '' s = t := h.surjOn.image_eq_of_mapsTo h.mapsTo lemma BijOn.forall {p : β → Prop} (hf : BijOn f s t) : (∀ b ∈ t, p b) ↔ ∀ a ∈ s, p (f a) where - mp h a ha := h _ <| hf.mapsTo ha + mp h _ ha := h _ <| hf.mapsTo ha mpr h b hb := by obtain ⟨a, ha, rfl⟩ := hf.surjOn hb; exact h _ ha lemma BijOn.exists {p : β → Prop} (hf : BijOn f s t) : (∃ b ∈ t, p b) ↔ ∃ a ∈ s, p (f a) where @@ -1609,7 +1609,7 @@ lemma bijOn' (h₁ : MapsTo e s t) (h₂ : MapsTo e.symm t s) : BijOn e s t := ⟨h₁, e.injective.injOn, fun b hb ↦ ⟨e.symm b, h₂ hb, apply_symm_apply _ _⟩⟩ protected lemma bijOn (h : ∀ a, e a ∈ t ↔ a ∈ s) : BijOn e s t := - e.bijOn' (fun a ↦ (h _).2) fun b hb ↦ (h _).1 <| by rwa [apply_symm_apply] + e.bijOn' (fun _ ↦ (h _).2) fun b hb ↦ (h _).1 <| by rwa [apply_symm_apply] lemma invOn : InvOn e e.symm t s := ⟨e.rightInverse_symm.leftInvOn _, e.leftInverse_symm.leftInvOn _⟩ diff --git a/Mathlib/Data/Set/Image.lean b/Mathlib/Data/Set/Image.lean index 83a5f73df751de..e70bfdc19f8d57 100644 --- a/Mathlib/Data/Set/Image.lean +++ b/Mathlib/Data/Set/Image.lean @@ -570,7 +570,7 @@ theorem forall_mem_range {p : α → Prop} : (∀ a ∈ range f, p a) ↔ ∀ i, theorem forall_subtype_range_iff {p : range f → Prop} : (∀ a : range f, p a) ↔ ∀ i, p ⟨f i, mem_range_self _⟩ := - ⟨fun H i => H _, fun H ⟨y, i, hi⟩ => by + ⟨fun H _ => H _, fun H ⟨y, i, hi⟩ => by subst hi apply H⟩ @@ -584,7 +584,7 @@ theorem exists_subtype_range_iff {p : range f → Prop} : ⟨fun ⟨⟨a, i, hi⟩, ha⟩ => by subst a exact ⟨i, ha⟩, - fun ⟨i, hi⟩ => ⟨_, hi⟩⟩ + fun ⟨_, hi⟩ => ⟨_, hi⟩⟩ theorem range_iff_surjective : range f = univ ↔ Surjective f := eq_univ_iff_forall @@ -663,7 +663,7 @@ theorem insert_image_compl_eq_range (f : α → β) (x : α) : insert (f x) (f ' theorem image_preimage_eq_range_inter {f : α → β} {t : Set β} : f '' (f ⁻¹' t) = range f ∩ t := ext fun x => - ⟨fun ⟨x, hx, HEq⟩ => HEq ▸ ⟨mem_range_self _, hx⟩, fun ⟨⟨y, h_eq⟩, hx⟩ => + ⟨fun ⟨_, hx, HEq⟩ => HEq ▸ ⟨mem_range_self _, hx⟩, fun ⟨⟨y, h_eq⟩, hx⟩ => h_eq ▸ mem_image_of_mem f <| show y ∈ f ⁻¹' t by rw [preimage, mem_setOf, h_eq]; exact hx⟩ theorem image_preimage_eq_inter_range {f : α → β} {t : Set β} : f '' (f ⁻¹' t) = t ∩ range f := by diff --git a/Mathlib/Data/Set/Lattice.lean b/Mathlib/Data/Set/Lattice.lean index b6f29fa406fdf6..4892bed5f539c7 100644 --- a/Mathlib/Data/Set/Lattice.lean +++ b/Mathlib/Data/Set/Lattice.lean @@ -87,10 +87,10 @@ theorem mem_iInter₂_of_mem {s : ∀ i, κ i → Set α} {a : α} (h : ∀ i j, instance completeAtomicBooleanAlgebra : CompleteAtomicBooleanAlgebra (Set α) := { instBooleanAlgebraSet with - le_sSup := fun s t t_in a a_in => ⟨t, t_in, a_in⟩ - sSup_le := fun s t h a ⟨t', ⟨t'_in, a_in⟩⟩ => h t' t'_in a_in - le_sInf := fun s t h a a_in t' t'_in => h t' t'_in a_in - sInf_le := fun s t t_in a h => h _ t_in + le_sSup := fun _ t t_in _ a_in => ⟨t, t_in, a_in⟩ + sSup_le := fun _ _ h _ ⟨t', ⟨t'_in, a_in⟩⟩ => h t' t'_in a_in + le_sInf := fun _ _ h _ a_in t' t'_in => h t' t'_in a_in + sInf_le := fun _ _ t_in _ h => h _ t_in iInf_iSup_eq := by intros; ext; simp [Classical.skolem] } section GaloisConnection diff --git a/Mathlib/Data/Set/Prod.lean b/Mathlib/Data/Set/Prod.lean index d147798baa0d9c..7b460fdb9cb955 100644 --- a/Mathlib/Data/Set/Prod.lean +++ b/Mathlib/Data/Set/Prod.lean @@ -839,12 +839,12 @@ theorem univ_pi_subset_univ_pi_iff : pi univ t₁ ⊆ pi univ t₂ ↔ (∀ i, t₁ i ⊆ t₂ i) ∨ ∃ i, t₁ i = ∅ := by simp [pi_subset_pi_iff] theorem eval_preimage [DecidableEq ι] {s : Set (α i)} : - eval i ⁻¹' s = pi univ (update (fun i => univ) i s) := by + eval i ⁻¹' s = pi univ (update (fun _ => univ) i s) := by ext x simp [@forall_update_iff _ (fun i => Set (α i)) _ _ _ _ fun i' y => x i' ∈ y] theorem eval_preimage' [DecidableEq ι] {s : Set (α i)} : - eval i ⁻¹' s = pi {i} (update (fun i => univ) i s) := by + eval i ⁻¹' s = pi {i} (update (fun _ => univ) i s) := by ext simp diff --git a/Mathlib/Data/Setoid/Basic.lean b/Mathlib/Data/Setoid/Basic.lean index 8734d5bf5b8d2d..63241cbb3689de 100644 --- a/Mathlib/Data/Setoid/Basic.lean +++ b/Mathlib/Data/Setoid/Basic.lean @@ -325,8 +325,8 @@ theorem ker_iff_mem_preimage {f : α → β} {x y} : (ker f).Rel x y ↔ x ∈ f def liftEquiv (r : Setoid α) : { f : α → β // r ≤ ker f } ≃ (Quotient r → β) where toFun f := Quotient.lift (f : α → β) f.2 invFun f := ⟨f ∘ Quotient.mk'', fun x y h => by simp [ker_def, Quotient.sound' h]⟩ - left_inv := fun ⟨f, hf⟩ => Subtype.eq <| funext fun x => rfl - right_inv f := funext fun x => Quotient.inductionOn' x fun x => rfl + left_inv := fun ⟨_, _⟩ => Subtype.eq <| funext fun _ => rfl + right_inv _ := funext fun x => Quotient.inductionOn' x fun _ => rfl /-- The uniqueness part of the universal property for quotients of an arbitrary type. -/ theorem lift_unique {r : Setoid α} {f : α → β} (H : r ≤ ker f) (g : Quotient r → β) @@ -358,7 +358,7 @@ noncomputable def quotientKerEquivRange : Quotient (ker f) ≃ Set.range f := ((@Quotient.lift _ (Set.range f) (ker f) fun x => ⟨f x, Set.mem_range_self x⟩) fun _ _ h => Subtype.ext_val h) ⟨fun x y h => ker_lift_injective f <| by rcases x with ⟨⟩; rcases y with ⟨⟩; injections, - fun ⟨w, z, hz⟩ => + fun ⟨_, z, hz⟩ => ⟨@Quotient.mk'' _ (ker f) z, Subtype.ext_iff_val.2 hz⟩⟩ /-- If `f` has a computable right-inverse, then the quotient by its kernel is equivalent to its @@ -430,11 +430,11 @@ def quotientQuotientEquivQuotient (s : Setoid α) (h : r ≤ s) : Quotient (ker (Quot.mapRight h)) ≃ Quotient s where toFun x := (Quotient.liftOn' x fun w => - (Quotient.liftOn' w (@Quotient.mk'' _ s)) fun x y H => Quotient.sound <| h H) - fun x y => Quotient.inductionOn₂' x y fun w z H => show @Quot.mk _ _ _ = @Quot.mk _ _ _ from H + (Quotient.liftOn' w (@Quotient.mk'' _ s)) fun _ _ H => Quotient.sound <| h H) + fun x y => Quotient.inductionOn₂' x y fun _ _ H => show @Quot.mk _ _ _ = @Quot.mk _ _ _ from H invFun x := (Quotient.liftOn' x fun w => @Quotient.mk'' _ (ker <| Quot.mapRight h) <| @Quotient.mk'' _ r w) - fun x y H => Quotient.sound' <| show @Quot.mk _ _ _ = @Quot.mk _ _ _ from Quotient.sound H + fun _ _ H => Quotient.sound' <| show @Quot.mk _ _ _ = @Quot.mk _ _ _ from Quotient.sound H left_inv x := Quotient.inductionOn' x fun y => Quotient.inductionOn' y fun w => by show ⟦_⟧ = _; rfl right_inv x := Quotient.inductionOn' x fun y => by show ⟦_⟧ = _; rfl @@ -452,8 +452,8 @@ def correspondence (r : Setoid α) : { s // r ≤ s } ≃o Setoid (Quotient r) w ⟨Quotient.ind s.1.2.1, @fun x y ↦ Quotient.inductionOn₂ x y fun _ _ ↦ s.1.2.2, @fun x y z ↦ Quotient.inductionOn₃ x y z fun _ _ _ ↦ s.1.2.3⟩⟩ invFun s := ⟨comap Quotient.mk' s, fun x y h => by rw [comap_rel, eq_rel.2 h]⟩ - left_inv s := rfl - right_inv s := ext fun x y ↦ Quotient.inductionOn₂ x y fun _ _ ↦ Iff.rfl + left_inv _ := rfl + right_inv _ := ext fun x y ↦ Quotient.inductionOn₂ x y fun _ _ ↦ Iff.rfl map_rel_iff' := ⟨fun h x y hs ↦ @h ⟦x⟧ ⟦y⟧ hs, fun h x y ↦ Quotient.inductionOn₂ x y fun _ _ hs ↦ h hs⟩ diff --git a/Mathlib/Data/Setoid/Partition.lean b/Mathlib/Data/Setoid/Partition.lean index 7813b2de0bebee..b44853cfa153b7 100644 --- a/Mathlib/Data/Setoid/Partition.lean +++ b/Mathlib/Data/Setoid/Partition.lean @@ -49,7 +49,7 @@ def mkClasses (c : Set (Set α)) (H : ∀ a, ∃! b ∈ c, a ∈ b) : Setoid α iseqv.symm := fun {x _y} h s hs hy => by obtain ⟨t, ⟨ht, hx⟩, _⟩ := H x rwa [eq_of_mem_eqv_class H hs hy ht (h t ht hx)] - iseqv.trans := fun {_x y z} h1 h2 s hs hx => h2 s hs (h1 s hs hx) + iseqv.trans := fun {_x _ _} h1 h2 s hs hx => h2 s hs (h1 s hs hx) /-- Makes the equivalence classes of an equivalence relation. -/ def classes (r : Setoid α) : Set (Set α) := @@ -135,7 +135,7 @@ theorem eqv_classes_disjoint {c : Set (Set α)} (H : ∀ a, ∃! b ∈ c, a ∈ theorem eqv_classes_of_disjoint_union {c : Set (Set α)} (hu : Set.sUnion c = @Set.univ α) (H : c.PairwiseDisjoint id) (a) : ∃! b ∈ c, a ∈ b := let ⟨b, hc, ha⟩ := Set.mem_sUnion.1 <| show a ∈ _ by rw [hu]; exact Set.mem_univ a - ExistsUnique.intro b ⟨hc, ha⟩ fun b' hc' => H.elim_set hc'.1 hc _ hc'.2 ha + 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 α. -/ def setoidOfDisjointUnion {c : Set (Set α)} (hu : Set.sUnion c = @Set.univ α) diff --git a/Mathlib/Data/Sigma/Order.lean b/Mathlib/Data/Sigma/Order.lean index f7d007a46e857e..3afb990febe690 100644 --- a/Mathlib/Data/Sigma/Order.lean +++ b/Mathlib/Data/Sigma/Order.lean @@ -140,7 +140,7 @@ theorem lt_def [LT ι] [∀ i, LT (α i)] {a b : Σₗ i, α i} : /-- The lexicographical preorder on a sigma type. -/ instance preorder [Preorder ι] [∀ i, Preorder (α i)] : Preorder (Σₗ i, α i) := { Sigma.Lex.LE, Sigma.Lex.LT with - le_refl := fun ⟨i, a⟩ => Lex.right a a le_rfl, + le_refl := fun ⟨_, a⟩ => Lex.right a a le_rfl, le_trans := fun _ _ _ => trans_of ((Lex (· < ·)) fun _ => (· ≤ ·)), lt_iff_le_not_le := by refine fun a b => ⟨fun hab => ⟨hab.mono_right fun i a b => le_of_lt, ?_⟩, ?_⟩ diff --git a/Mathlib/Data/Stream/Init.lean b/Mathlib/Data/Stream/Init.lean index c90ad62ac925db..b893cc61acf480 100644 --- a/Mathlib/Data/Stream/Init.lean +++ b/Mathlib/Data/Stream/Init.lean @@ -356,7 +356,7 @@ theorem interleave_tail_tail (s₁ s₂ : Stream' α) : tail s₁ ⋈ tail s₂ theorem get_interleave_left : ∀ (n : ℕ) (s₁ s₂ : Stream' α), get (s₁ ⋈ s₂) (2 * n) = get s₁ n - | 0, s₁, s₂ => rfl + | 0, _, _ => rfl | n + 1, s₁, s₂ => by change get (s₁ ⋈ s₂) (succ (succ (2 * n))) = get s₁ (succ n) rw [get_succ, get_succ, interleave_eq, tail_cons, tail_cons] @@ -365,7 +365,7 @@ theorem get_interleave_left : ∀ (n : ℕ) (s₁ s₂ : Stream' α), theorem get_interleave_right : ∀ (n : ℕ) (s₁ s₂ : Stream' α), get (s₁ ⋈ s₂) (2 * n + 1) = get s₂ n - | 0, s₁, s₂ => rfl + | 0, _, _ => rfl | n + 1, s₁, s₂ => by change get (s₁ ⋈ s₂) (succ (succ (2 * n + 1))) = get s₂ (succ n) rw [get_succ, get_succ, interleave_eq, tail_cons, tail_cons, @@ -415,7 +415,7 @@ theorem interleave_even_odd (s₁ : Stream' α) : even s₁ ⋈ odd s₁ = s₁ rfl theorem get_even : ∀ (n : ℕ) (s : Stream' α), get (even s) n = get s (2 * n) - | 0, s => rfl + | 0, _ => rfl | succ n, s => by change get (even s) (succ n) = get s (succ (succ (2 * n))) rw [get_succ, get_succ, tail_even, get_even n]; rfl @@ -438,13 +438,13 @@ theorem cons_append_stream (a : α) (l : List α) (s : Stream' α) : theorem append_append_stream : ∀ (l₁ l₂ : List α) (s : Stream' α), l₁ ++ l₂ ++ₛ s = l₁ ++ₛ (l₂ ++ₛ s) - | [], l₂, s => rfl + | [], _, _ => rfl | List.cons a l₁, l₂, s => by rw [List.cons_append, cons_append_stream, cons_append_stream, append_append_stream l₁] theorem map_append_stream (f : α → β) : ∀ (l : List α) (s : Stream' α), map f (l ++ₛ s) = List.map f l ++ₛ map f s - | [], s => rfl + | [], _ => rfl | List.cons a l, s => by rw [cons_append_stream, List.map_cons, map_cons, cons_append_stream, map_append_stream f l] @@ -499,7 +499,7 @@ theorem take_take {s : Stream' α} : ∀ {m n}, (s.take n).take m = s.take (min (take_succ' n).symm theorem get?_take {s : Stream' α} : ∀ {k n}, k < n → (s.take n).get? k = s.get k - | 0, n+1, _ => rfl + | 0, _+1, _ => rfl | k+1, n+1, h => by rw [take_succ, List.get?, get?_take (Nat.lt_of_succ_lt_succ h), get_succ] theorem get?_take_succ (n : ℕ) (s : Stream' α) : diff --git a/Mathlib/Data/String/Basic.lean b/Mathlib/Data/String/Basic.lean index d30479b15e6111..6d86ef5ed7a826 100644 --- a/Mathlib/Data/String/Basic.lean +++ b/Mathlib/Data/String/Basic.lean @@ -139,7 +139,7 @@ theorem head_empty : "".data.head! = default := rfl instance : LinearOrder String where - le_refl a := le_iff_toList_le.mpr le_rfl + le_refl _ := le_iff_toList_le.mpr le_rfl le_trans a b c := by simp only [le_iff_toList_le] apply le_trans diff --git a/Mathlib/Data/Sum/Order.lean b/Mathlib/Data/Sum/Order.lean index 7eef753b32d1a3..6d1cf4426180c9 100644 --- a/Mathlib/Data/Sum/Order.lean +++ b/Mathlib/Data/Sum/Order.lean @@ -157,7 +157,7 @@ variable [Preorder α] [Preorder β] instance instPreorderSum : Preorder (α ⊕ β) := { instLESum, instLTSum with - le_refl := fun x => LiftRel.refl _ _ _, + le_refl := fun _ => LiftRel.refl _ _ _, le_trans := fun _ _ _ => LiftRel.trans _ _, lt_iff_le_not_le := fun a b => by refine ⟨fun hab => ⟨hab.mono (fun _ _ => le_of_lt) fun _ _ => le_of_lt, ?_⟩, ?_⟩ diff --git a/Mathlib/Data/Sym/Basic.lean b/Mathlib/Data/Sym/Basic.lean index 4378b439653ed3..6c89905364aa0f 100644 --- a/Mathlib/Data/Sym/Basic.lean +++ b/Mathlib/Data/Sym/Basic.lean @@ -468,7 +468,7 @@ theorem mem_append_iff {s' : Sym α m} : a ∈ s.append s' ↔ a ∈ s ∨ a ∈ def oneEquiv : α ≃ Sym α 1 where toFun a := ⟨{a}, by simp⟩ invFun s := (Equiv.subtypeQuotientEquivQuotientSubtype - (·.length = 1) _ (fun l ↦ Iff.rfl) (fun l l' ↦ by rfl) s).liftOn + (·.length = 1) _ (fun _ ↦ Iff.rfl) (fun l l' ↦ by rfl) s).liftOn (fun l ↦ l.1.head <| List.length_pos.mp <| by simp) fun ⟨_, _⟩ ⟨_, h⟩ ↦ fun perm ↦ by obtain ⟨a, rfl⟩ := List.length_eq_one.mp h diff --git a/Mathlib/Data/Sym/Sym2.lean b/Mathlib/Data/Sym/Sym2.lean index 945179cd192f3f..c3366dd172bb1c 100644 --- a/Mathlib/Data/Sym/Sym2.lean +++ b/Mathlib/Data/Sym/Sym2.lean @@ -182,9 +182,9 @@ def lift : { f : α → α → β // ∀ a₁ a₂, f a₁ a₂ = f a₂ a₁ } Quot.lift (uncurry ↑f) <| by rintro _ _ ⟨⟩ exacts [rfl, f.prop _ _] - invFun F := ⟨curry (F ∘ Sym2.mk), fun a₁ a₂ => congr_arg F eq_swap⟩ - left_inv f := Subtype.ext rfl - right_inv F := funext <| Sym2.ind fun x y => rfl + invFun F := ⟨curry (F ∘ Sym2.mk), fun _ _ => congr_arg F eq_swap⟩ + left_inv _ := Subtype.ext rfl + right_inv _ := funext <| Sym2.ind fun _ _ => rfl @[simp] theorem lift_mk (f : { f : α → α → β // ∀ a₁ a₂, f a₁ a₂ = f a₂ a₁ }) (a₁ a₂ : α) : @@ -211,8 +211,8 @@ def lift₂ : ⟨fun a₁ a₂ b₁ b₂ => F s(a₁, a₂) s(b₁, b₂), fun a₁ a₂ b₁ b₂ => by constructor exacts [congr_arg₂ F eq_swap rfl, congr_arg₂ F rfl eq_swap]⟩ - left_inv f := Subtype.ext rfl - right_inv F := funext₂ fun a b => Sym2.inductionOn₂ a b fun _ _ _ _ => rfl + left_inv _ := Subtype.ext rfl + right_inv _ := funext₂ fun a b => Sym2.inductionOn₂ a b fun _ _ _ _ => rfl @[simp] theorem lift₂_mk @@ -456,23 +456,23 @@ theorem fromRel_proj_prop {sym : Symmetric r} {z : α × α} : Sym2.mk z ∈ fro theorem fromRel_prop {sym : Symmetric r} {a b : α} : s(a, b) ∈ fromRel sym ↔ r a b := Iff.rfl -theorem fromRel_bot : fromRel (fun (x y : α) z => z : Symmetric ⊥) = ∅ := by +theorem fromRel_bot : fromRel (fun (_ _ : α) z => z : Symmetric ⊥) = ∅ := by apply Set.eq_empty_of_forall_not_mem fun e => _ apply Sym2.ind simp [-Set.bot_eq_empty, Prop.bot_eq_false] -theorem fromRel_top : fromRel (fun (x y : α) z => z : Symmetric ⊤) = Set.univ := by +theorem fromRel_top : fromRel (fun (_ _ : α) z => z : Symmetric ⊤) = Set.univ := by apply Set.eq_univ_of_forall fun e => _ apply Sym2.ind simp [-Set.top_eq_univ, Prop.top_eq_true] -theorem fromRel_ne : fromRel (fun (x y : α) z => z.symm : Symmetric Ne) = {z | ¬IsDiag z} := by +theorem fromRel_ne : fromRel (fun (_ _ : α) z => z.symm : Symmetric Ne) = {z | ¬IsDiag z} := by ext z; exact z.ind (by simp) theorem fromRel_irreflexive {sym : Symmetric r} : Irreflexive r ↔ ∀ {z}, z ∈ fromRel sym → ¬IsDiag z := { mp := by intro h; apply Sym2.ind; aesop - mpr := fun h x hr => h (fromRel_prop.mpr hr) rfl } + mpr := fun h _ hr => h (fromRel_prop.mpr hr) rfl } theorem mem_fromRel_irrefl_other_ne {sym : Symmetric r} (irrefl : Irreflexive r) {a : α} {z : Sym2 α} (hz : z ∈ fromRel sym) (h : a ∈ z) : Mem.other h ≠ a := diff --git a/Mathlib/Data/Tree/Basic.lean b/Mathlib/Data/Tree/Basic.lean index 2b1d95d767b681..4628f0ce38b536 100644 --- a/Mathlib/Data/Tree/Basic.lean +++ b/Mathlib/Data/Tree/Basic.lean @@ -117,6 +117,6 @@ def unitRecOn {motive : Tree Unit → Sort*} (t : Tree Unit) (base : motive nil) theorem left_node_right_eq_self : ∀ {x : Tree Unit} (_hx : x ≠ nil), x.left △ x.right = x | nil, h => by trivial - | node a l r, _ => rfl -- Porting note: `a △ b` no longer works in pattern matching + | node _ _ _, _ => rfl -- Porting note: `a △ b` no longer works in pattern matching end Tree diff --git a/Mathlib/Data/Vector/Basic.lean b/Mathlib/Data/Vector/Basic.lean index 5db96436f76b05..14362f975a7191 100644 --- a/Mathlib/Data/Vector/Basic.lean +++ b/Mathlib/Data/Vector/Basic.lean @@ -348,7 +348,7 @@ def mOfFn {m} [Monad m] {α : Type u} : ∀ {n}, (Fin n → m α) → m (Vector theorem mOfFn_pure {m} [Monad m] [LawfulMonad m] {α} : ∀ {n} (f : Fin n → α), (@mOfFn m _ _ _ fun i => pure (f i)) = pure (ofFn f) - | 0, f => rfl + | 0, _ => rfl | n + 1, f => by rw [mOfFn, @mOfFn_pure m _ _ _ n _, ofFn] simp diff --git a/Mathlib/Data/Vector/Defs.lean b/Mathlib/Data/Vector/Defs.lean index 8c08c0254b5026..24273d810fe4fd 100644 --- a/Mathlib/Data/Vector/Defs.lean +++ b/Mathlib/Data/Vector/Defs.lean @@ -65,7 +65,7 @@ theorem tail_cons (a : α) : ∀ v : Vector α n, tail (cons a v) = v @[simp] theorem cons_head_tail : ∀ v : Vector α (succ n), cons (head v) (tail v) = v | ⟨[], h⟩ => by contradiction - | ⟨a :: v, h⟩ => rfl + | ⟨_ :: _, _⟩ => rfl /-- The list obtained from a vector. -/ def toList (v : Vector α n) : List α := diff --git a/Mathlib/Data/Vector3.lean b/Mathlib/Data/Vector3.lean index 9ec3dea9345291..d1c8061307db87 100644 --- a/Mathlib/Data/Vector3.lean +++ b/Mathlib/Data/Vector3.lean @@ -146,13 +146,13 @@ theorem append_cons (a : α) (v : Vector3 α m) (w : Vector3 α n) : (a :: v) +- @[simp] theorem append_left : ∀ {m} (i : Fin2 m) (v : Vector3 α m) {n} (w : Vector3 α n), (v +-+ w) (left n i) = v i - | _, @fz m, v, n, w => v.consElim fun a _t => by simp [*, left] + | _, @fz m, v, _, _ => v.consElim fun a _t => by simp [*, left] | _, @fs m i, v, n, w => v.consElim fun _a t => by simp [append_left, left] @[simp] theorem append_add : ∀ {m} (v : Vector3 α m) {n} (w : Vector3 α n) (i : Fin2 n), (v +-+ w) (add i m) = w i - | 0, v, n, w, i => rfl + | 0, _, _, _, _ => rfl | m + 1, v, n, w, i => v.consElim fun _a t => by simp [append_add, add] /-- Insert `a` into `v` at index `i`. -/ @@ -205,7 +205,7 @@ theorem exists_vector_zero (f : Vector3 α 0 → Prop) : Exists f ↔ f [] := ⟨fun ⟨v, fv⟩ => by rw [← eq_nil v]; exact fv, fun f0 => ⟨[], f0⟩⟩ theorem exists_vector_succ (f : Vector3 α (succ n) → Prop) : Exists f ↔ ∃ x v, f (x :: v) := - ⟨fun ⟨v, fv⟩ => ⟨_, _, by rw [cons_head_tail v]; exact fv⟩, fun ⟨x, v, fxv⟩ => ⟨_, fxv⟩⟩ + ⟨fun ⟨v, fv⟩ => ⟨_, _, by rw [cons_head_tail v]; exact fv⟩, fun ⟨_, _, fxv⟩ => ⟨_, fxv⟩⟩ theorem vectorEx_iff_exists : ∀ {n} (f : Vector3 α n → Prop), VectorEx n f ↔ Exists f | 0, f => (exists_vector_zero f).symm diff --git a/Mathlib/Data/W/Basic.lean b/Mathlib/Data/W/Basic.lean index aec104886a43b6..a2b73e07e8871d 100644 --- a/Mathlib/Data/W/Basic.lean +++ b/Mathlib/Data/W/Basic.lean @@ -133,11 +133,11 @@ private abbrev WType' {α : Type*} (β : α → Type*) [∀ a : α, Fintype (β variable [∀ a : α, Encodable (β a)] private def encodable_zero : Encodable (WType' β 0) := - let f : WType' β 0 → Empty := fun ⟨x, h⟩ => False.elim <| not_lt_of_ge h (WType.depth_pos _) + let f : WType' β 0 → Empty := fun ⟨_, h⟩ => False.elim <| not_lt_of_ge h (WType.depth_pos _) let finv : Empty → WType' β 0 := by intro x cases x - have : ∀ x, finv (f x) = x := fun ⟨x, h⟩ => False.elim <| not_lt_of_ge h (WType.depth_pos _) + have : ∀ x, finv (f x) = x := fun ⟨_, h⟩ => False.elim <| not_lt_of_ge h (WType.depth_pos _) Encodable.ofLeftInverse f finv this private def f (n : ℕ) : WType' β (n + 1) → Σa : α, β a → WType' β n @@ -155,7 +155,7 @@ private def finv (n : ℕ) : (Σa : α, β a → WType' β n) → WType' β (n + variable [Encodable α] -private def encodable_succ (n : Nat) (h : Encodable (WType' β n)) : Encodable (WType' β (n + 1)) := +private def encodable_succ (n : Nat) (_ : Encodable (WType' β n)) : Encodable (WType' β (n + 1)) := Encodable.ofLeftInverse (f n) (finv n) (by rintro ⟨⟨_, _⟩, _⟩ diff --git a/Mathlib/Data/W/Cardinal.lean b/Mathlib/Data/W/Cardinal.lean index 5841bc9d66bd18..62545bd0184ae1 100644 --- a/Mathlib/Data/W/Cardinal.lean +++ b/Mathlib/Data/W/Cardinal.lean @@ -67,7 +67,7 @@ theorem cardinal_mk_le_max_aleph0_of_finite' [∀ a, Finite (β a)] : _ ≤ m * ⨆ a, m ^ lift.{u} #(β a) := mul_le_mul' (le_max_left _ _) le_rfl _ = m := mul_eq_left (le_max_right _ _) - (ciSup_le' fun i => pow_le (le_max_right _ _) (lt_aleph0_of_finite _)) <| + (ciSup_le' fun _ => pow_le (le_max_right _ _) (lt_aleph0_of_finite _)) <| pos_iff_ne_zero.1 <| Order.succ_le_iff.1 (by diff --git a/Mathlib/Data/ZMod/Basic.lean b/Mathlib/Data/ZMod/Basic.lean index ba4a441a9fdfef..d7eb347c8deeed 100644 --- a/Mathlib/Data/ZMod/Basic.lean +++ b/Mathlib/Data/ZMod/Basic.lean @@ -519,7 +519,7 @@ variable {m n : ℕ} @[simp] theorem val_eq_zero : ∀ {n : ℕ} (a : ZMod n), a.val = 0 ↔ a = 0 - | 0, a => Int.natAbs_eq_zero + | 0, _ => Int.natAbs_eq_zero | n + 1, a => by rw [Fin.ext_iff] exact Iff.rfl @@ -1139,7 +1139,7 @@ theorem valMinAbs_def_pos {n : ℕ} [NeZero n] (x : ZMod n) : @[simp, norm_cast] theorem coe_valMinAbs : ∀ {n : ℕ} (x : ZMod n), (x.valMinAbs : ZMod n) = x - | 0, x => Int.cast_id + | 0, _ => Int.cast_id | k@(n + 1), x => by rw [valMinAbs_def_pos] split_ifs @@ -1331,9 +1331,9 @@ instance instField : Field (ZMod p) where mul_inv_cancel := mul_inv_cancel_aux p inv_zero := inv_zero p nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl qsmul := _ - qsmul_def := fun a x => rfl + qsmul_def := fun _ _ => rfl /-- `ZMod p` is an integral domain when `p` is prime. -/ instance (p : ℕ) [hp : Fact p.Prime] : IsDomain (ZMod p) := by diff --git a/Mathlib/Data/ZMod/Defs.lean b/Mathlib/Data/ZMod/Defs.lean index 76e27012548a54..40ebde64104eed 100644 --- a/Mathlib/Data/ZMod/Defs.lean +++ b/Mathlib/Data/ZMod/Defs.lean @@ -45,7 +45,7 @@ open Nat.ModEq Int /-- Multiplicative commutative semigroup structure on `Fin n`. -/ instance instCommSemigroup (n : ℕ) : CommSemigroup (Fin n) := { inferInstanceAs (Mul (Fin n)) with - mul_assoc := fun ⟨a, ha⟩ ⟨b, hb⟩ ⟨c, hc⟩ => + 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 _ @@ -54,7 +54,7 @@ instance instCommSemigroup (n : ℕ) : CommSemigroup (Fin n) := mul_comm := Fin.mul_comm } private theorem left_distrib_aux (n : ℕ) : ∀ a b c : Fin n, a * (b + c) = a * b + a * c := - fun ⟨a, ha⟩ ⟨b, hb⟩ ⟨c, hc⟩ => + fun ⟨a, _⟩ ⟨b, _⟩ ⟨c, _⟩ => Fin.eq_of_val_eq <| calc a * ((b + c) % n) ≡ a * (b + c) [MOD n] := (Nat.mod_modEq _ _).mul_left _ diff --git a/Mathlib/Data/ZMod/IntUnitsPower.lean b/Mathlib/Data/ZMod/IntUnitsPower.lean index 4d6bd6c1d8b3d8..c627c6cd17d155 100644 --- a/Mathlib/Data/ZMod/IntUnitsPower.lean +++ b/Mathlib/Data/ZMod/IntUnitsPower.lean @@ -35,12 +35,12 @@ lemma ZMod.natCast_smul_units (n : ℕ) (au : Additive ℤˣ) : (n : ZMod 2) • /-- This is an indirect way of saying that `ℤˣ` has a power operation by `ZMod 2`. -/ instance : Module (ZMod 2) (Additive ℤˣ) where smul z au := .ofMul <| Additive.toMul au ^ z.val - one_smul au := Additive.toMul.injective <| pow_one _ + one_smul _ := Additive.toMul.injective <| pow_one _ mul_smul z₁ z₂ au := Additive.toMul.injective <| by dsimp only [ZMod.smul_units_def, toMul_nsmul] rw [← pow_mul, ZMod.val_mul, ← Int.units_pow_eq_pow_mod_two, mul_comm] - smul_zero z := Additive.toMul.injective <| one_pow _ - smul_add z au₁ au₂ := Additive.toMul.injective <| mul_pow _ _ _ + smul_zero _ := Additive.toMul.injective <| one_pow _ + smul_add _ _ _ := Additive.toMul.injective <| mul_pow _ _ _ add_smul z₁ z₂ au := Additive.toMul.injective <| by dsimp only [ZMod.smul_units_def, toMul_nsmul, toMul_add] rw [← pow_add, ZMod.val_add, ← Int.units_pow_eq_pow_mod_two] diff --git a/Mathlib/Deprecated/Subgroup.lean b/Mathlib/Deprecated/Subgroup.lean index f30ed0f0e3ca39..40cdc4a7f736df 100644 --- a/Mathlib/Deprecated/Subgroup.lean +++ b/Mathlib/Deprecated/Subgroup.lean @@ -456,8 +456,8 @@ theorem exists_list_of_mem_closure {s : Set G} {a : G} (h : a ∈ closure s) : InClosure.recOn h (fun {x} hxs => ⟨[x], List.forall_mem_singleton.2 <| Or.inl hxs, List.prod_singleton⟩) ⟨[], List.forall_mem_nil _, rfl⟩ - (fun {x} _ ⟨L, HL1, HL2⟩ => - ⟨L.reverse.map Inv.inv, fun x hx => + (fun {_} _ ⟨L, HL1, HL2⟩ => + ⟨L.reverse.map Inv.inv, fun _ hx => let ⟨y, hy1, hy2⟩ := List.exists_of_mem_map hx hy2 ▸ Or.imp id (by rw [inv_inv]; exact id) (HL1 _ <| List.mem_reverse.1 hy1).symm, HL2 ▸ diff --git a/Mathlib/Deprecated/Submonoid.lean b/Mathlib/Deprecated/Submonoid.lean index ef7d983287a9d7..e7fa4e7c6f2682 100644 --- a/Mathlib/Deprecated/Submonoid.lean +++ b/Mathlib/Deprecated/Submonoid.lean @@ -347,7 +347,7 @@ theorem mem_closure_union_iff {M : Type*} [CommMonoid M] {s t : Set M} {x : M} : ⟨y, hy, z * hd, (closure.isSubmonoid _).mul_mem hz (subset_closure ht), by rw [← mul_assoc, List.prod_cons, ← hyzx, mul_comm hd]⟩) HL1, - fun ⟨y, hy, z, hz, hyzx⟩ => + fun ⟨_, hy, _, hz, hyzx⟩ => hyzx ▸ (closure.isSubmonoid _).mul_mem (closure_mono Set.subset_union_left hy) (closure_mono Set.subset_union_right hz)⟩ diff --git a/Mathlib/Dynamics/Circle/RotationNumber/TranslationNumber.lean b/Mathlib/Dynamics/Circle/RotationNumber/TranslationNumber.lean index bf93db2355a6df..745facc0985ce4 100644 --- a/Mathlib/Dynamics/Circle/RotationNumber/TranslationNumber.lean +++ b/Mathlib/Dynamics/Circle/RotationNumber/TranslationNumber.lean @@ -164,9 +164,9 @@ instance : Monoid CircleDeg1Lift where { toOrderHom := f.1.comp g.1 map_add_one' := fun x => by simp [map_add_one] } one := ⟨.id, fun _ => rfl⟩ - mul_one f := rfl - one_mul f := rfl - mul_assoc f₁ f₂ f₃ := DFunLike.coe_injective rfl + mul_one _ := rfl + one_mul _ := rfl + mul_assoc _ _ _ := DFunLike.coe_injective rfl instance : Inhabited CircleDeg1Lift := ⟨1⟩ @@ -201,7 +201,7 @@ def toOrderIso : CircleDeg1Liftˣ →* ℝ ≃o ℝ where right_inv := units_apply_inv_apply f map_rel_iff' := ⟨fun h => by simpa using mono (↑f⁻¹) h, mono f⟩ } map_one' := rfl - map_mul' f g := rfl + map_mul' _ _ := rfl @[simp] theorem coe_toOrderIso (f : CircleDeg1Liftˣ) : ⇑(toOrderIso f) = f := @@ -350,23 +350,23 @@ theorem map_fract_sub_fract_eq (x : ℝ) : f (fract x) - fract x = f x - x := by noncomputable instance : Lattice CircleDeg1Lift where sup f g := { toFun := fun x => max (f x) (g x) - monotone' := fun x y h => max_le_max (f.mono h) (g.mono h) + monotone' := fun _ _ h => max_le_max (f.mono h) (g.mono h) -- TODO: generalize to `Monotone.max` map_add_one' := fun x => by simp [max_add_add_right] } le f g := ∀ x, f x ≤ g x le_refl f x := le_refl (f x) - le_trans f₁ f₂ f₃ h₁₂ h₂₃ x := le_trans (h₁₂ x) (h₂₃ x) - le_antisymm f₁ f₂ h₁₂ h₂₁ := ext fun x => le_antisymm (h₁₂ x) (h₂₁ x) + le_trans _ _ _ h₁₂ h₂₃ x := le_trans (h₁₂ x) (h₂₃ x) + le_antisymm _ _ h₁₂ h₂₁ := ext fun x => le_antisymm (h₁₂ x) (h₂₁ x) le_sup_left f g x := le_max_left (f x) (g x) le_sup_right f g x := le_max_right (f x) (g x) - sup_le f₁ f₂ f₃ h₁ h₂ x := max_le (h₁ x) (h₂ x) + sup_le _ _ _ h₁ h₂ x := max_le (h₁ x) (h₂ x) inf f g := { toFun := fun x => min (f x) (g x) - monotone' := fun x y h => min_le_min (f.mono h) (g.mono h) + monotone' := fun _ _ h => min_le_min (f.mono h) (g.mono h) map_add_one' := fun x => by simp [min_add_add_right] } inf_le_left f g x := min_le_left (f x) (g x) inf_le_right f g x := min_le_right (f x) (g x) - le_inf f₁ f₂ f₃ h₂ h₃ x := le_min (h₂ x) (h₃ x) + le_inf _ _ _ h₂ h₃ x := le_min (h₂ x) (h₃ x) @[simp] theorem sup_apply (x : ℝ) : (f ⊔ g) x = max (f x) (g x) := diff --git a/Mathlib/Dynamics/PeriodicPts.lean b/Mathlib/Dynamics/PeriodicPts.lean index 160a6606f5e0fa..948033b25c274c 100644 --- a/Mathlib/Dynamics/PeriodicPts.lean +++ b/Mathlib/Dynamics/PeriodicPts.lean @@ -181,7 +181,7 @@ theorem Semiconj.mapsTo_ptsOfPeriod {g : α → β} (h : Semiconj g fa fb) (n : theorem bijOn_ptsOfPeriod (f : α → α) {n : ℕ} (hn : 0 < n) : BijOn f (ptsOfPeriod f n) (ptsOfPeriod f n) := - ⟨(Commute.refl f).mapsTo_ptsOfPeriod n, fun x hx y hy hxy => hx.eq_of_apply_eq_same hy hn hxy, + ⟨(Commute.refl f).mapsTo_ptsOfPeriod n, fun _ hx _ hy hxy => hx.eq_of_apply_eq_same hy hn hxy, fun x hx => ⟨f^[n.pred] x, hx.apply_iterate _, by rw [← comp_apply (f := f), comp_iterate_pred_of_pos f hn, hx.eq]⟩⟩ diff --git a/Mathlib/FieldTheory/Adjoin.lean b/Mathlib/FieldTheory/Adjoin.lean index c83073349810a3..204fdd29bf1e46 100644 --- a/Mathlib/FieldTheory/Adjoin.lean +++ b/Mathlib/FieldTheory/Adjoin.lean @@ -1182,7 +1182,7 @@ open Module AdjoinRoot in in `K⟮α⟯` with `α` a root of `f`, then `f(g(x))` is irreducible. -/ theorem _root_.Polynomial.irreducible_comp {f g : K[X]} (hfm : f.Monic) (hgm : g.Monic) (hf : Irreducible f) - (hg : ∀ (E : Type u) [Field E] [Algebra K E] (x : E) (hx : minpoly K x = f), + (hg : ∀ (E : Type u) [Field E] [Algebra K E] (x : E) (_ : minpoly K x = f), Irreducible (g.map (algebraMap _ _) - C (AdjoinSimple.gen K x))) : Irreducible (f.comp g) := by have hf' : natDegree f ≠ 0 := diff --git a/Mathlib/FieldTheory/Finite/Polynomial.lean b/Mathlib/FieldTheory/Finite/Polynomial.lean index 00e92545eba5b2..a5a76e1726feb4 100644 --- a/Mathlib/FieldTheory/Finite/Polynomial.lean +++ b/Mathlib/FieldTheory/Finite/Polynomial.lean @@ -200,7 +200,7 @@ theorem rank_R [Fintype σ] : Module.rank K (R σ K) = Fintype.card (σ → K) : refine forall_congr' fun n => le_tsub_iff_right ?_ exact Fintype.card_pos_iff.2 ⟨0⟩ _ = #(σ → { n // n < Fintype.card K }) := - (@Equiv.subtypePiEquivPi σ (fun _ => ℕ) fun s n => n < Fintype.card K).cardinal_eq + (@Equiv.subtypePiEquivPi σ (fun _ => ℕ) fun _ n => n < Fintype.card K).cardinal_eq _ = #(σ → Fin (Fintype.card K)) := (Equiv.arrowCongr (Equiv.refl σ) Fin.equivSubtype.symm).cardinal_eq _ = #(σ → K) := (Equiv.arrowCongr (Equiv.refl σ) (Fintype.equivFin K).symm).cardinal_eq diff --git a/Mathlib/FieldTheory/IntermediateField/Basic.lean b/Mathlib/FieldTheory/IntermediateField/Basic.lean index 27a9fb8cd57cdd..31cc6116137552 100644 --- a/Mathlib/FieldTheory/IntermediateField/Basic.lean +++ b/Mathlib/FieldTheory/IntermediateField/Basic.lean @@ -252,7 +252,7 @@ theorem toSubalgebra_toIntermediateField (S : Subalgebra K L) (inv_mem : ∀ x @[simp] theorem toIntermediateField_toSubalgebra (S : IntermediateField K L) : - (S.toSubalgebra.toIntermediateField fun x => S.inv_mem) = S := by + (S.toSubalgebra.toIntermediateField fun _ => S.inv_mem) = S := by ext rfl @@ -650,8 +650,8 @@ def extendScalars.orderIso : { E : Subfield L // F ≤ E } ≃o IntermediateField F L where toFun E := extendScalars E.2 invFun E := ⟨E.toSubfield, fun x hx ↦ E.algebraMap_mem ⟨x, hx⟩⟩ - left_inv E := rfl - right_inv E := rfl + left_inv _ := rfl + right_inv _ := rfl map_rel_iff' {E E'} := by simp only [Equiv.coe_fn_mk] exact extendScalars_le_extendScalars_iff _ _ @@ -702,8 +702,8 @@ into an order isomorphism from def extendScalars.orderIso : { E : IntermediateField K L // F ≤ E } ≃o IntermediateField F L where toFun E := extendScalars E.2 invFun E := ⟨E.restrictScalars K, fun x hx ↦ E.algebraMap_mem ⟨x, hx⟩⟩ - left_inv E := rfl - right_inv E := rfl + left_inv _ := rfl + right_inv _ := rfl map_rel_iff' {E E'} := by simp only [Equiv.coe_fn_mk] exact extendScalars_le_extendScalars_iff _ _ diff --git a/Mathlib/FieldTheory/IsAlgClosed/Classification.lean b/Mathlib/FieldTheory/IsAlgClosed/Classification.lean index f617fc7a73aec1..5d028a07e9d414 100644 --- a/Mathlib/FieldTheory/IsAlgClosed/Classification.lean +++ b/Mathlib/FieldTheory/IsAlgClosed/Classification.lean @@ -65,7 +65,7 @@ theorem cardinal_mk_le_max : #L ≤ max #R ℵ₀ := _ = Cardinal.sum fun p : R[X] => #{x : L | x ∈ p.aroots L} := by rw [← mk_sigma]; rfl _ ≤ Cardinal.sum.{u, u} fun _ : R[X] => ℵ₀ := - (sum_le_sum _ _ fun p => (Multiset.finite_toSet _).lt_aleph0.le) + (sum_le_sum _ _ fun _ => (Multiset.finite_toSet _).lt_aleph0.le) _ = #(R[X]) * ℵ₀ := sum_const' _ _ _ ≤ max (max #(R[X]) ℵ₀) ℵ₀ := mul_le_max _ _ _ ≤ max (max (max #R ℵ₀) ℵ₀) ℵ₀ := diff --git a/Mathlib/FieldTheory/KummerExtension.lean b/Mathlib/FieldTheory/KummerExtension.lean index 671a4b1bb374a7..bb7dbd753c5b85 100644 --- a/Mathlib/FieldTheory/KummerExtension.lean +++ b/Mathlib/FieldTheory/KummerExtension.lean @@ -182,7 +182,7 @@ theorem X_pow_sub_C_irreducible_iff_of_prime {p : ℕ} (hp : p.Prime) {a : K} : theorem X_pow_mul_sub_C_irreducible {n m : ℕ} {a : K} (hm : Irreducible (X ^ m - C a)) - (hn : ∀ (E : Type u) [Field E] [Algebra K E] (x : E) (hx : minpoly K x = X ^ m - C a), + (hn : ∀ (E : Type u) [Field E] [Algebra K E] (x : E) (_ : minpoly K x = X ^ m - C a), Irreducible (X ^ n - C (AdjoinSimple.gen K x))) : Irreducible (X ^ (n * m) - C a) := by have hm' : m ≠ 0 := by diff --git a/Mathlib/FieldTheory/PerfectClosure.lean b/Mathlib/FieldTheory/PerfectClosure.lean index 50b237cb61ab01..39f00a20954662 100644 --- a/Mathlib/FieldTheory/PerfectClosure.lean +++ b/Mathlib/FieldTheory/PerfectClosure.lean @@ -271,7 +271,7 @@ instance instAddCommGroup : AddCommGroup (PerfectClosure K p) := Quot.inductionOn e fun ⟨n, x⟩ => congr_arg (Quot.mk _) <| by simp only [iterate_map_zero, iterate_zero_apply, add_zero] - sub_eq_add_neg := fun a b => rfl + sub_eq_add_neg := fun _ _ => rfl neg_add_cancel := fun e => Quot.inductionOn e fun ⟨n, x⟩ => by simp only [quot_mk_eq_mk, neg_mk, mk_add_mk, iterate_map_neg, neg_add_cancel, mk_zero_right] @@ -495,9 +495,9 @@ instance instDivisionRing : DivisionRing (PerfectClosure K p) where rw [mul_inv_cancel₀ this, iterate_map_one] inv_zero := congr_arg (Quot.mk (R K p)) (by rw [inv_zero]) nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl qsmul := _ - qsmul_def := fun q a => rfl + qsmul_def := fun _ _ => rfl instance instField : Field (PerfectClosure K p) := { (inferInstance : DivisionRing (PerfectClosure K p)), diff --git a/Mathlib/FieldTheory/RatFunc/Basic.lean b/Mathlib/FieldTheory/RatFunc/Basic.lean index 66d5c87abee7c8..4e0129beb6355d 100644 --- a/Mathlib/FieldTheory/RatFunc/Basic.lean +++ b/Mathlib/FieldTheory/RatFunc/Basic.lean @@ -522,9 +522,9 @@ instance instField [IsDomain K] : Field (RatFunc K) where mul_inv_cancel _ := mul_inv_cancel zpow := zpowRec nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl qsmul := _ - qsmul_def := fun q a => rfl + qsmul_def := fun _ _ => rfl section IsFractionRing @@ -547,7 +547,7 @@ instance (R : Type*) [CommSemiring R] [Algebra R K[X]] : Algebra R (RatFunc K) w rw [RingHom.coe_mk, MonoidHom.coe_mk, OneHom.coe_mk] rw [mk_one', ← mk_smul, mk_def_of_ne (c • p) hq, mk_def_of_ne p hq, ← ofFractionRing_mul, IsLocalization.mul_mk'_eq_mk'_of_mul, Algebra.smul_def] - commutes' c x := mul_comm _ _ + commutes' _ _ := mul_comm _ _ variable {K} @@ -717,7 +717,7 @@ theorem algebraMap_ne_zero {x : K[X]} (hx : x ≠ 0) : algebraMap K[X] (RatFunc theorem liftOn_div {P : Sort v} (p q : K[X]) (f : K[X] → K[X] → P) (f0 : ∀ p, f p 0 = f 0 1) (H' : ∀ {p q p' q'} (_hq : q ≠ 0) (_hq' : q' ≠ 0), q' * p = q * p' → f p q = f p' q') (H : ∀ {p q p' q'} (_hq : q ∈ K[X]⁰) (_hq' : q' ∈ K[X]⁰), q' * p = q * p' → f p q = f p' q' := - fun {p q p' q'} hq hq' h => H' (nonZeroDivisors.ne_zero hq) (nonZeroDivisors.ne_zero hq') h) : + fun {_ _ _ _} hq hq' h => H' (nonZeroDivisors.ne_zero hq) (nonZeroDivisors.ne_zero hq') h) : (RatFunc.liftOn (algebraMap _ (RatFunc K) p / algebraMap _ _ q)) f @H = f p q := by rw [← mk_eq_div, liftOn_mk _ _ f f0 @H'] @@ -735,7 +735,7 @@ then `P` holds on all elements of `RatFunc K`. See also `induction_on'`, which is a recursion principle defined in terms of `RatFunc.mk`. -/ protected theorem induction_on {P : RatFunc K → Prop} (x : RatFunc K) - (f : ∀ (p q : K[X]) (hq : q ≠ 0), P (algebraMap _ (RatFunc K) p / algebraMap _ _ q)) : P x := + (f : ∀ (p q : K[X]) (_ : q ≠ 0), P (algebraMap _ (RatFunc K) p / algebraMap _ _ q)) : P x := x.induction_on' fun p q hq => by simpa using f p q hq theorem ofFractionRing_mk' (x : K[X]) (y : K[X]⁰) : diff --git a/Mathlib/FieldTheory/RatFunc/Defs.lean b/Mathlib/FieldTheory/RatFunc/Defs.lean index b45d1838b3eb79..da34170f5b492d 100644 --- a/Mathlib/FieldTheory/RatFunc/Defs.lean +++ b/Mathlib/FieldTheory/RatFunc/Defs.lean @@ -119,7 +119,7 @@ theorem liftOn_ofFractionRing_mk {P : Sort v} (n : K[X]) (d : K[X]⁰) (f : K[X] exact Localization.liftOn_mk _ _ _ _ theorem liftOn_condition_of_liftOn'_condition {P : Sort v} {f : K[X] → K[X] → P} - (H : ∀ {p q a} (hq : q ≠ 0) (_ha : a ≠ 0), f (a * p) (a * q) = f p q) ⦃p q p' q' : K[X]⦄ + (H : ∀ {p q a} (_ : q ≠ 0) (_ha : a ≠ 0), f (a * p) (a * q) = f p q) ⦃p q p' q' : K[X]⦄ (hq : q ≠ 0) (hq' : q' ≠ 0) (h : q' * p = q * p') : f p q = f p' q' := calc f p q = f (q' * p) (q' * q) := (H hq hq').symm @@ -183,7 +183,7 @@ theorem mk_eq_mk {p q p' q' : K[X]} (hq : q ≠ 0) (hq' : q' ≠ 0) : theorem liftOn_mk {P : Sort v} (p q : K[X]) (f : K[X] → K[X] → P) (f0 : ∀ p, f p 0 = f 0 1) (H' : ∀ {p q p' q'} (_hq : q ≠ 0) (_hq' : q' ≠ 0), q' * p = q * p' → f p q = f p' q') (H : ∀ {p q p' q'} (_hq : q ∈ K[X]⁰) (_hq' : q' ∈ K[X]⁰), q' * p = q * p' → f p q = f p' q' := - fun {p q p' q'} hq hq' h => H' (nonZeroDivisors.ne_zero hq) (nonZeroDivisors.ne_zero hq') h) : + fun {_ _ _ _} hq hq' h => H' (nonZeroDivisors.ne_zero hq) (nonZeroDivisors.ne_zero hq') h) : (RatFunc.mk p q).liftOn f @H = f p q := by by_cases hq : q = 0 · subst hq diff --git a/Mathlib/FieldTheory/Separable.lean b/Mathlib/FieldTheory/Separable.lean index 11f14b5edd03f3..8060298a804950 100644 --- a/Mathlib/FieldTheory/Separable.lean +++ b/Mathlib/FieldTheory/Separable.lean @@ -307,7 +307,7 @@ theorem separable_map {S} [CommRing S] [Nontrivial S] (f : F →+* S) {p : F[X]} theorem separable_prod_X_sub_C_iff' {ι : Sort _} {f : ι → F} {s : Finset ι} : (∏ i ∈ s, (X - C (f i))).Separable ↔ ∀ x ∈ s, ∀ y ∈ s, f x = f y → x = y := - ⟨fun hfs x hx y hy hfxy => hfs.inj_of_prod_X_sub_C hx hy hfxy, fun H => by + ⟨fun hfs _ hx _ hy hfxy => hfs.inj_of_prod_X_sub_C hx hy hfxy, fun H => by rw [← prod_attach] exact separable_prod' diff --git a/Mathlib/FieldTheory/SplittingField/Construction.lean b/Mathlib/FieldTheory/SplittingField/Construction.lean index fb0572b56c8b97..8f9e3daadffc72 100644 --- a/Mathlib/FieldTheory/SplittingField/Construction.lean +++ b/Mathlib/FieldTheory/SplittingField/Construction.lean @@ -165,7 +165,7 @@ protected theorem splits (n : ℕ) : ∀ (f : K[X]) (_hfn : f.natDegree = n), Splits (algebraMap K <| SplittingFieldAux n f) f := Nat.recOn (motive := fun n => ∀ {K : Type u} [Field K], ∀ (f : K[X]) (_hfn : f.natDegree = n), Splits (algebraMap K <| SplittingFieldAux n f) f) n - (fun {K} _ _ hf => + (fun {_} _ _ hf => splits_of_degree_le_one _ (le_trans degree_le_natDegree <| hf.symm ▸ WithBot.coe_le_coe.2 zero_le_one)) fun n ih {K} _ f hf => by @@ -181,7 +181,7 @@ theorem adjoin_rootSet (n : ℕ) : ∀ {K : Type u} [Field K], ∀ (f : K[X]) (_hfn : f.natDegree = n), Algebra.adjoin K (f.rootSet (SplittingFieldAux n f)) = ⊤) - n (fun {K} _ f _hf => Algebra.eq_top_iff.2 fun x => Subalgebra.range_le _ ⟨x, rfl⟩) + n (fun {_} _ _ _hf => Algebra.eq_top_iff.2 fun x => Subalgebra.range_le _ ⟨x, rfl⟩) fun n ih {K} _ f hfn => by have hndf : f.natDegree ≠ 0 := by intro h; rw [h] at hfn; cases hfn have hfn0 : f ≠ 0 := by intro h; rw [h] at hndf; exact hndf rfl diff --git a/Mathlib/Geometry/Euclidean/Sphere/Basic.lean b/Mathlib/Geometry/Euclidean/Sphere/Basic.lean index 6c5067aad4c235..c4e42b8477423a 100644 --- a/Mathlib/Geometry/Euclidean/Sphere/Basic.lean +++ b/Mathlib/Geometry/Euclidean/Sphere/Basic.lean @@ -157,7 +157,7 @@ theorem Cospherical.subset {ps₁ ps₂ : Set P} (hs : ps₁ ⊆ ps₂) (hc : Co /-- The empty set is cospherical. -/ theorem cospherical_empty [Nonempty P] : Cospherical (∅ : Set P) := let ⟨p⟩ := ‹Nonempty P› - ⟨p, 0, fun p => False.elim⟩ + ⟨p, 0, fun _ => False.elim⟩ /-- A single point is cospherical. -/ theorem cospherical_singleton (p : P) : Cospherical ({p} : Set P) := by diff --git a/Mathlib/Geometry/Manifold/ChartedSpace.lean b/Mathlib/Geometry/Manifold/ChartedSpace.lean index d62d89afae12c6..6a69ac58da981f 100644 --- a/Mathlib/Geometry/Manifold/ChartedSpace.lean +++ b/Mathlib/Geometry/Manifold/ChartedSpace.lean @@ -366,7 +366,7 @@ def Pregroupoid.groupoid (PG : Pregroupoid H) : StructureGroupoid H where apply e.continuousOn_toFun.isOpen_inter_preimage e.open_source e'.open_source · apply PG.comp he'.2 he.2 e'.open_target e.open_target apply e'.continuousOn_invFun.isOpen_inter_preimage e'.open_target e.open_target - symm' e he := ⟨he.2, he.1⟩ + symm' _ he := ⟨he.2, he.1⟩ id_mem' := ⟨PG.id_mem, PG.id_mem⟩ locality' e he := by constructor @@ -445,7 +445,7 @@ instance : CompleteLattice (StructureGroupoid H) := top := instStructureGroupoidOrderTop.top le_top := instStructureGroupoidOrderTop.le_top inf := (· ⊓ ·) - le_inf := fun N₁ N₂ N₃ h₁₂ h₁₃ m hm ↦ ⟨h₁₂ hm, h₁₃ hm⟩ + le_inf := fun _ _ _ h₁₂ h₁₃ _ hm ↦ ⟨h₁₂ hm, h₁₃ hm⟩ inf_le_left := fun _ _ _ ↦ And.left inf_le_right := fun _ _ _ ↦ And.right } diff --git a/Mathlib/Geometry/Manifold/DerivationBundle.lean b/Mathlib/Geometry/Manifold/DerivationBundle.lean index fad0b9a9bd14e7..7c3df6e865fc13 100644 --- a/Mathlib/Geometry/Manifold/DerivationBundle.lean +++ b/Mathlib/Geometry/Manifold/DerivationBundle.lean @@ -135,8 +135,8 @@ def hfdifferential {f : C^∞⟮I, M; I', M'⟯} {x : M} {y : M'} (h : f x = y) PointedSmoothMap.smul_def, ContMDiffMap.comp_apply, PointedSmoothMap.smul_def, ContMDiffMap.comp_apply, h] norm_cast - map_smul' k v := rfl - map_add' v w := rfl + map_smul' _ _ := rfl + map_add' _ _ := rfl /-- The homogeneous differential as a linear map. -/ def fdifferential (f : C^∞⟮I, M; I', M'⟯) (x : M) : diff --git a/Mathlib/Geometry/Manifold/Instances/Real.lean b/Mathlib/Geometry/Manifold/Instances/Real.lean index 43cbf79926a58d..f3df629fd809bf 100644 --- a/Mathlib/Geometry/Manifold/Instances/Real.lean +++ b/Mathlib/Geometry/Manifold/Instances/Real.lean @@ -134,7 +134,7 @@ def modelWithCornersEuclideanHalfSpace (n : ℕ) [NeZero n] : left_inv' := fun ⟨xval, xprop⟩ _ => by rw [Subtype.mk_eq_mk, update_eq_iff] exact ⟨max_eq_left xprop, fun i _ => rfl⟩ - right_inv' x hx := update_eq_iff.2 ⟨max_eq_left hx, fun i _ => rfl⟩ + right_inv' _ hx := update_eq_iff.2 ⟨max_eq_left hx, fun _ _ => rfl⟩ source_eq := rfl uniqueDiffOn' := by have : UniqueDiffOn ℝ _ := @@ -155,7 +155,7 @@ def modelWithCornersEuclideanQuadrant (n : ℕ) : source := univ target := { x | ∀ i, 0 ≤ x i } map_source' x _ := x.property - map_target' x _ := mem_univ _ + map_target' _ _ := mem_univ _ left_inv' x _ := by ext i; simp only [Subtype.coe_mk, x.2 i, max_eq_left] right_inv' x hx := by ext1 i; simp only [hx i, max_eq_left] source_eq := rfl diff --git a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean index 30d7e6eaa301e0..0f98d08e805815 100644 --- a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean +++ b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean @@ -115,7 +115,7 @@ def comp {X Y Z : LocallyRingedSpace.{u}} (f : Hom X Y) (g : Hom Y Z) : Hom X Z instance : Category LocallyRingedSpace.{u} where Hom := Hom id := id - comp {X Y Z} f g := comp f g + comp {_ _ _} f g := comp f g comp_id {X Y} f := Hom.ext <| by simp [comp] id_comp {X Y} f := Hom.ext <| by simp [comp] assoc {_ _ _ _} f g h := Hom.ext <| by simp [comp] @@ -124,7 +124,7 @@ instance : Category LocallyRingedSpace.{u} where @[simps] def forgetToSheafedSpace : LocallyRingedSpace.{u} ⥤ SheafedSpace CommRingCat.{u} where obj X := X.toSheafedSpace - map {X Y} f := f.1 + map {_ _} f := f.1 instance : forgetToSheafedSpace.Faithful where map_injective {_ _} _ _ h := Hom.ext h diff --git a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean index 60b7cb47198e4b..fac6ae0294b93b 100644 --- a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean +++ b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean @@ -106,7 +106,7 @@ noncomputable def coproductCofanIsColimit : IsColimit (coproductCofan F) where (((forgetToSheafedSpace.mapCocone s).ι.app i).stalkMap y) := (s.ι.app i).2 y infer_instance⟩ - fac s j := LocallyRingedSpace.Hom.ext + fac _ _ := LocallyRingedSpace.Hom.ext (colimit.ι_desc (C := SheafedSpace.{u+1, u, u} CommRingCatMax.{u, u}) _ _) uniq s f h := LocallyRingedSpace.Hom.ext diff --git a/Mathlib/Geometry/RingedSpace/SheafedSpace.lean b/Mathlib/Geometry/RingedSpace/SheafedSpace.lean index b77aabfada5a7f..7b65ebaffd7eb6 100644 --- a/Mathlib/Geometry/RingedSpace/SheafedSpace.lean +++ b/Mathlib/Geometry/RingedSpace/SheafedSpace.lean @@ -149,7 +149,7 @@ variable (C) /-- The forgetful functor from `SheafedSpace` to `Top`. -/ def forget : SheafedSpace C ⥤ TopCat where obj X := (X : TopCat) - map {X Y} f := f.base + map {_ _} f := f.base end diff --git a/Mathlib/GroupTheory/Abelianization.lean b/Mathlib/GroupTheory/Abelianization.lean index 5ee8a835a60c49..46351f703f1ebd 100644 --- a/Mathlib/GroupTheory/Abelianization.lean +++ b/Mathlib/GroupTheory/Abelianization.lean @@ -231,7 +231,7 @@ def Abelianization.equivOfComm {H : Type*} [CommGroup H] : H ≃* Abelianization { Abelianization.of with toFun := Abelianization.of invFun := Abelianization.lift (MonoidHom.id H) - left_inv := fun a => rfl + left_inv := fun _ => rfl right_inv := by rintro ⟨a⟩ rfl } diff --git a/Mathlib/GroupTheory/Archimedean.lean b/Mathlib/GroupTheory/Archimedean.lean index 4105f66700e0c7..a84d8e30532170 100644 --- a/Mathlib/GroupTheory/Archimedean.lean +++ b/Mathlib/GroupTheory/Archimedean.lean @@ -103,6 +103,6 @@ theorem Subgroup.cyclic_of_isolated_one {H : Subgroup G} {a : G} (h₀ : 1 < a) /-- Every subgroup of `ℤ` is cyclic. -/ theorem Int.subgroup_cyclic (H : AddSubgroup ℤ) : ∃ a, H = AddSubgroup.closure {a} := - have : Ioo (0 : ℤ) 1 = ∅ := eq_empty_of_forall_not_mem fun m hm => + have : Ioo (0 : ℤ) 1 = ∅ := eq_empty_of_forall_not_mem fun _ hm => hm.1.not_le (lt_add_one_iff.1 hm.2) AddSubgroup.cyclic_of_isolated_zero one_pos <| by simp [this] diff --git a/Mathlib/GroupTheory/CommutingProbability.lean b/Mathlib/GroupTheory/CommutingProbability.lean index dc3739fd84c363..3f168c3c283058 100644 --- a/Mathlib/GroupTheory/CommutingProbability.lean +++ b/Mathlib/GroupTheory/CommutingProbability.lean @@ -142,8 +142,8 @@ private lemma div_four_lt : {n : ℕ} → (h0 : n ≠ 0) → (h1 : n ≠ 1) → /-- A list of Dihedral groups whose product will have commuting probability `1 / n`. -/ def reciprocalFactors (n : ℕ) : List ℕ := - if h0 : n = 0 then [0] - else if h1 : n = 1 then [] + if _ : n = 0 then [0] + else if _ : n = 1 then [] else if Even n then 3 :: reciprocalFactors (n / 2) else diff --git a/Mathlib/GroupTheory/Congruence/Basic.lean b/Mathlib/GroupTheory/Congruence/Basic.lean index fe6cfe5261d0ad..a6e6e72b5404f9 100644 --- a/Mathlib/GroupTheory/Congruence/Basic.lean +++ b/Mathlib/GroupTheory/Congruence/Basic.lean @@ -389,7 +389,7 @@ instance : PartialOrder (Con M) where an addition."] instance : CompleteLattice (Con M) where __ := completeLatticeOfInf (Con M) fun s => - ⟨fun r hr x y h => (h : ∀ r ∈ s, (r : Con M) x y) r hr, fun r hr x y h r' hr' => + ⟨fun r hr x y h => (h : ∀ r ∈ s, (r : Con M) x y) r hr, fun _ hr _ _ h _ hr' => hr hr' h⟩ inf c d := ⟨c.toSetoid ⊓ d.toSetoid, fun h1 h2 => ⟨c.mul h1.1 h2.1, d.mul h1.2 h2.2⟩⟩ @@ -399,7 +399,7 @@ instance : CompleteLattice (Con M) where top := { Setoid.completeLattice.top with mul' := by tauto } le_top _ := fun _ _ _ => trivial bot := { Setoid.completeLattice.bot with mul' := fun h1 h2 => h1 ▸ h2 ▸ rfl } - bot_le c := fun x y h => h ▸ c.refl x + bot_le c := fun x _ h => h ▸ c.refl x /-- The infimum of two congruence relations equals the infimum of the underlying binary operations. -/ @@ -572,10 +572,10 @@ the order-preserving bijection between the set of additive congruence relations the additive congruence relations on the quotient of `M` by `c`."] def correspondence : { d // c ≤ d } ≃o Con c.Quotient where toFun d := - d.1.mapOfSurjective (↑) (fun x y => rfl) (by rw [mul_ker_mk_eq]; exact d.2) <| + d.1.mapOfSurjective (↑) (fun _ _ => rfl) (by rw [mul_ker_mk_eq]; exact d.2) <| @Quotient.exists_rep _ c.toSetoid invFun d := - ⟨comap ((↑) : M → c.Quotient) (fun x y => rfl) d, fun x y h => + ⟨comap ((↑) : M → c.Quotient) (fun _ _ => rfl) d, fun x y h => show d x y by rw [c.eq.2 h]; exact d.refl _⟩ left_inv d := -- Porting note: by exact needed for unknown reason diff --git a/Mathlib/GroupTheory/CoprodI.lean b/Mathlib/GroupTheory/CoprodI.lean index 67d5fdc6738bd6..eb0bad0e811e85 100644 --- a/Mathlib/GroupTheory/CoprodI.lean +++ b/Mathlib/GroupTheory/CoprodI.lean @@ -151,7 +151,7 @@ def lift : (∀ i, M i →* N) ≃ (CoprodI M →* N) where FreeMonoid.lift _ (FreeMonoid.of _ * FreeMonoid.of _) = FreeMonoid.lift _ (FreeMonoid.of _) simp only [MonoidHom.map_mul, FreeMonoid.lift_eval_of] - invFun f i := f.comp of + invFun f _ := f.comp of left_inv := by intro fi ext i x diff --git a/Mathlib/GroupTheory/Coset/Basic.lean b/Mathlib/GroupTheory/Coset/Basic.lean index 44bb4b0f21528d..d9ede0a36ed677 100644 --- a/Mathlib/GroupTheory/Coset/Basic.lean +++ b/Mathlib/GroupTheory/Coset/Basic.lean @@ -470,13 +470,13 @@ variable [Group α] {s : Subgroup α} @[to_additive "The natural bijection between the cosets `g + s` and `s`."] def leftCosetEquivSubgroup (g : α) : (g • s : Set α) ≃ s := ⟨fun x => ⟨g⁻¹ * x.1, (mem_leftCoset_iff _).1 x.2⟩, fun x => ⟨g * x.1, x.1, x.2, rfl⟩, - fun ⟨x, hx⟩ => Subtype.eq <| by simp, fun ⟨g, hg⟩ => Subtype.eq <| by simp⟩ + fun ⟨x, _⟩ => Subtype.eq <| by simp, fun ⟨g, _⟩ => Subtype.eq <| by simp⟩ /-- The natural bijection between a right coset `s * g` and `s`. -/ @[to_additive "The natural bijection between the cosets `s + g` and `s`."] def rightCosetEquivSubgroup (g : α) : (op g • s : Set α) ≃ s := ⟨fun x => ⟨x.1 * g⁻¹, (mem_rightCoset_iff _).1 x.2⟩, fun x => ⟨x.1 * g, x.1, x.2, rfl⟩, - fun ⟨x, hx⟩ => Subtype.eq <| by simp, fun ⟨g, hg⟩ => Subtype.eq <| by simp⟩ + fun ⟨x, _⟩ => Subtype.eq <| by simp, fun ⟨g, _⟩ => Subtype.eq <| by simp⟩ /-- A (non-canonical) bijection between a group `α` and the product `(α/s) × s` -/ @[to_additive addGroupEquivQuotientProdAddSubgroup @@ -492,7 +492,7 @@ noncomputable def groupEquivQuotientProdSubgroup : α ≃ (α ⧸ s) × s := _root_.Subtype fun x : α => Quotient.mk'' x = Quotient.mk'' _ simp [-Quotient.eq''] rfl - _ ≃ Σ _L : α ⧸ s, s := Equiv.sigmaCongrRight fun L => leftCosetEquivSubgroup _ + _ ≃ Σ _L : α ⧸ s, s := Equiv.sigmaCongrRight fun _ => leftCosetEquivSubgroup _ _ ≃ (α ⧸ s) × s := Equiv.sigmaEquivProd _ _ variable {t : Subgroup α} @@ -517,7 +517,7 @@ of the quotient map `G → G/K`. The classical version is `Subgroup.quotientEqui def quotientEquivProdOfLE' (h_le : s ≤ t) (f : α ⧸ t → α) (hf : Function.RightInverse f QuotientGroup.mk) : α ⧸ s ≃ (α ⧸ t) × t ⧸ s.subgroupOf t where toFun a := - ⟨a.map' id fun b c h => leftRel_apply.mpr (h_le (leftRel_apply.mp h)), + ⟨a.map' id fun _ _ h => leftRel_apply.mpr (h_le (leftRel_apply.mp h)), a.map' (fun g : α => ⟨(f (Quotient.mk'' g))⁻¹ * g, leftRel_apply.mp (Quotient.exact' (hf g))⟩) fun b c h => by rw [leftRel_apply] @@ -703,7 +703,7 @@ noncomputable def preimageMkEquivSubgroupProdSet (s : Subgroup α) (t : Set (α show QuotientGroup.mk _ ∈ t by rw [mk_mul_of_mem _ a.1.2, out_eq'] exact a.2.2⟩ - left_inv := fun ⟨a, ha⟩ => Subtype.eq <| show _ * _ = a by simp + left_inv := fun ⟨a, _⟩ => Subtype.eq <| show _ * _ = a by simp right_inv := fun ⟨⟨a, ha⟩, ⟨x, hx⟩⟩ => by ext <;> simp [ha] end QuotientGroup diff --git a/Mathlib/GroupTheory/Divisible.lean b/Mathlib/GroupTheory/Divisible.lean index 4276c6c3fd8b1f..e34a6a788ad697 100644 --- a/Mathlib/GroupTheory/Divisible.lean +++ b/Mathlib/GroupTheory/Divisible.lean @@ -173,7 +173,7 @@ 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 a := dif_pos rfl + div_zero _ := dif_pos rfl div_cancel a hn := by simp_rw [dif_neg hn] generalize_proofs h1 diff --git a/Mathlib/GroupTheory/FreeAbelianGroup.lean b/Mathlib/GroupTheory/FreeAbelianGroup.lean index 475386ea7d3dfb..2bbbd09ab5770a 100644 --- a/Mathlib/GroupTheory/FreeAbelianGroup.lean +++ b/Mathlib/GroupTheory/FreeAbelianGroup.lean @@ -375,7 +375,7 @@ theorem of_mul (x y : α) : of (x * y) = of x * of y := instance distrib : Distrib (FreeAbelianGroup α) := { FreeAbelianGroup.mul α, FreeAbelianGroup.addCommGroup α with - left_distrib := fun x y z ↦ (lift _).map_add _ _ + left_distrib := fun _ _ _ ↦ (lift _).map_add _ _ right_distrib := fun x y z ↦ by simp only [(· * ·), Mul.mul, map_add, ← Pi.add_def, lift.add'] } instance nonUnitalNonAssocRing : NonUnitalNonAssocRing (FreeAbelianGroup α) := diff --git a/Mathlib/GroupTheory/FreeGroup/Basic.lean b/Mathlib/GroupTheory/FreeGroup/Basic.lean index 4dfea2fbf13f63..390e31eeb995b3 100644 --- a/Mathlib/GroupTheory/FreeGroup/Basic.lean +++ b/Mathlib/GroupTheory/FreeGroup/Basic.lean @@ -195,10 +195,10 @@ respectively. This is also known as Newman's diamond lemma. -/ to `w2` and `w3` respectively, then there is a word `w4` such that `w2` and `w3` reduce to `w4` respectively. This is also known as Newman's diamond lemma."] theorem church_rosser : Red L₁ L₂ → Red L₁ L₃ → Join Red L₂ L₃ := - Relation.church_rosser fun a b c hab hac => + Relation.church_rosser fun _ b c hab hac => match b, c, Red.Step.diamond hab hac rfl with | b, _, Or.inl rfl => ⟨b, by rfl, by rfl⟩ - | b, c, Or.inr ⟨d, hbd, hcd⟩ => ⟨d, ReflGen.single hbd, hcd.to_red⟩ + | _, _, Or.inr ⟨d, hbd, hcd⟩ => ⟨d, ReflGen.single hbd, hcd.to_red⟩ @[to_additive] theorem cons_cons {p} : Red L₁ L₂ → Red (p :: L₁) (p :: L₂) := @@ -252,7 +252,7 @@ theorem to_append_iff : Red L (L₁ ++ L₂) ↔ ∃ L₃ L₄, L = L₃ ++ L₄ by simp rcases ih this with ⟨w₁, w₂, rfl, h₁, h₂⟩ exact ⟨w₁, w₂, rfl, h₁.tail Step.not, h₂⟩) - fun ⟨L₃, L₄, Eq, h₃, h₄⟩ => Eq.symm ▸ append_append h₃ h₄ + fun ⟨_, _, Eq, h₃, h₄⟩ => Eq.symm ▸ append_append h₃ h₄ /-- The empty word `[]` only reduces to itself. -/ @[to_additive "The empty word `[]` only reduces to itself."] @@ -369,10 +369,10 @@ end Red @[to_additive FreeAddGroup.equivalence_join_red] theorem equivalence_join_red : Equivalence (Join (@Red α)) := - equivalence_join_reflTransGen fun a b c hab hac => + equivalence_join_reflTransGen fun _ b c hab hac => match b, c, Red.Step.diamond hab hac rfl with | b, _, Or.inl rfl => ⟨b, by rfl, by rfl⟩ - | b, c, Or.inr ⟨d, hbd, hcd⟩ => ⟨d, ReflGen.single hbd, ReflTransGen.single hcd⟩ + | _, _, Or.inr ⟨d, hbd, hcd⟩ => ⟨d, ReflGen.single hbd, ReflTransGen.single hcd⟩ @[to_additive FreeAddGroup.join_red_of_step] theorem join_red_of_step (h : Red.Step L₁ L₂) : Join Red L₁ L₂ := @@ -569,7 +569,7 @@ from the free group over `α` to `β` -/ additive group homomorphism from the free additive group over `α` to `β`"] def lift : (α → β) ≃ (FreeGroup α →* β) where toFun f := - MonoidHom.mk' (Quot.lift (Lift.aux f) fun L₁ L₂ => Red.Step.lift) <| by + MonoidHom.mk' (Quot.lift (Lift.aux f) fun _ _ => Red.Step.lift) <| by rintro ⟨L₁⟩ ⟨L₂⟩; simp [Lift.aux] invFun g := g ∘ of left_inv f := List.prod_singleton diff --git a/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean b/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean index 9ce47f7942f612..6669bfc8d8d210 100644 --- a/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean +++ b/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean @@ -96,6 +96,13 @@ 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 +#adaptation_note +/-- +The new unused variable linter in +https://github.com/leanprover/lean4/pull/5338 +flags `{ e // _ }`. +-/ +set_option linter.unusedVariables 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. @@ -106,7 +113,7 @@ instance actionGroupoidIsFree {G A : Type u} [Group G] [IsFreeGroup G] [MulActio IsFreeGroupoid (ActionCategory G A) where quiverGenerators := ⟨fun a b => { e : IsFreeGroup.Generators G // IsFreeGroup.of e • a.back = b.back }⟩ - of := fun (e : { e // _}) => ⟨IsFreeGroup.of e, e.property⟩ + of := fun (e : { e // _ }) => ⟨IsFreeGroup.of e, e.property⟩ unique_lift := by intro X _ f let f' : IsFreeGroup.Generators G → (A → X) ⋊[mulAutArrow] G := fun e => diff --git a/Mathlib/GroupTheory/GroupAction/Blocks.lean b/Mathlib/GroupTheory/GroupAction/Blocks.lean index 9fbae888310e9b..dddd660c93991f 100644 --- a/Mathlib/GroupTheory/GroupAction/Blocks.lean +++ b/Mathlib/GroupTheory/GroupAction/Blocks.lean @@ -451,9 +451,9 @@ def block_stabilizerOrderIso [htGX : IsPretransitive G X] (a : X) : toFun := fun ⟨B, ha, hB⟩ => ⟨stabilizer G B, hB.stabilizer_le ha⟩ invFun := fun ⟨H, hH⟩ => ⟨MulAction.orbit H a, MulAction.mem_orbit_self a, IsBlock.of_orbit hH⟩ - left_inv := fun ⟨B, ha, hB⟩ => + left_inv := fun ⟨_, ha, hB⟩ => (id (propext Subtype.mk_eq_mk)).mpr (hB.orbit_stabilizer_eq ha) - right_inv := fun ⟨H, hH⟩ => + right_inv := fun ⟨_, hH⟩ => (id (propext Subtype.mk_eq_mk)).mpr (stabilizer_orbit_eq hH) map_rel_iff' := by rintro ⟨B, ha, hB⟩; rintro ⟨B', ha', hB'⟩ diff --git a/Mathlib/GroupTheory/GroupAction/ConjAct.lean b/Mathlib/GroupTheory/GroupAction/ConjAct.lean index b16c6ce0f2902c..c1d499828409fb 100644 --- a/Mathlib/GroupTheory/GroupAction/ConjAct.lean +++ b/Mathlib/GroupTheory/GroupAction/ConjAct.lean @@ -352,7 +352,7 @@ def unitsCentralizerEquiv (x : Mˣ) : have : (u : ConjAct Mˣ) • x = x := u.2 rwa [ConjAct.smul_def, mul_inv_eq_iff_eq_mul, Units.ext_iff, eq_comm] at this⟩, map_one' := rfl, - map_mul' := fun a b ↦ rfl } + map_mul' := fun _ _ ↦ rfl } invFun := fun u ↦ ⟨ConjAct.toConjAct (Units.map (Submonoid.centralizer ({↑x} : Set M)).subtype u), by change _ • _ = _ diff --git a/Mathlib/GroupTheory/GroupAction/Quotient.lean b/Mathlib/GroupTheory/GroupAction/Quotient.lean index 3cd5bab40dafdb..8d5f1ebb80f808 100644 --- a/Mathlib/GroupTheory/GroupAction/Quotient.lean +++ b/Mathlib/GroupTheory/GroupAction/Quotient.lean @@ -157,7 +157,7 @@ noncomputable def orbitEquivQuotientStabilizer (b : β) : orbit α 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), - fun ⟨b, ⟨g, hgb⟩⟩ => ⟨g, Subtype.eq hgb⟩⟩ + fun ⟨_, ⟨g, hgb⟩⟩ => ⟨g, Subtype.eq hgb⟩⟩ /-- Orbit-stabilizer theorem. -/ @[to_additive AddAction.orbitProdStabilizerEquivAddGroup "Orbit-stabilizer theorem."] diff --git a/Mathlib/GroupTheory/HNNExtension.lean b/Mathlib/GroupTheory/HNNExtension.lean index 2ba02b333a4265..551403b5170c4e 100644 --- a/Mathlib/GroupTheory/HNNExtension.lean +++ b/Mathlib/GroupTheory/HNNExtension.lean @@ -356,7 +356,7 @@ def Cancels (u : ℤˣ) (w : NormalWord d) : Prop := def unitsSMulWithCancel (u : ℤˣ) (w : NormalWord d) : Cancels u w → NormalWord d := consRecOn w (by simp [Cancels, ofGroup]; tauto) - (fun g u' w h1 h2 _ can => + (fun g _ w _ _ _ can => (toSubgroupEquiv φ u ⟨g, can.1⟩ : G) • w) /-- Multiplying `t^u` by a `NormalWord`, `w` and putting the result in normal form. -/ diff --git a/Mathlib/GroupTheory/MonoidLocalization/Order.lean b/Mathlib/GroupTheory/MonoidLocalization/Order.lean index ccdd1707f6e4d4..9dbdafbb9a75a8 100644 --- a/Mathlib/GroupTheory/MonoidLocalization/Order.lean +++ b/Mathlib/GroupTheory/MonoidLocalization/Order.lean @@ -60,7 +60,7 @@ theorem mk_lt_mk : mk a₁ a₂ < mk b₁ b₂ ↔ ↑b₂ * a₁ < a₂ * b₁ instance partialOrder : PartialOrder (Localization s) where le := (· ≤ ·) lt := (· < ·) - le_refl a := Localization.induction_on a fun a => le_rfl + le_refl a := Localization.induction_on a fun _ => le_rfl le_trans a b c := Localization.induction_on₃ a b c fun a b c hab hbc => by simp only [mk_le_mk] at hab hbc ⊢ @@ -76,7 +76,7 @@ instance partialOrder : PartialOrder (Localization s) where · simp_rw [mk_le_mk, mk_eq_mk_iff, r_iff_exists] exact fun hab hba => ⟨1, by rw [hab.antisymm hba]⟩ all_goals rfl - lt_iff_le_not_le a b := Localization.induction_on₂ a b fun a b => lt_iff_le_not_le + lt_iff_le_not_le a b := Localization.induction_on₂ a b fun _ _ => lt_iff_le_not_le @[to_additive] instance orderedCancelCommMonoid : OrderedCancelCommMonoid (Localization s) where diff --git a/Mathlib/GroupTheory/NoncommPiCoprod.lean b/Mathlib/GroupTheory/NoncommPiCoprod.lean index 52503c3b5a08ca..70be3543599dfc 100644 --- a/Mathlib/GroupTheory/NoncommPiCoprod.lean +++ b/Mathlib/GroupTheory/NoncommPiCoprod.lean @@ -99,7 +99,7 @@ namespace MonoidHom @[to_additive "The canonical homomorphism from a family of additive monoids. See also `LinearMap.lsum` for a linear version without the commutativity assumption."] def noncommPiCoprod : (∀ i : ι, N i) →* M where - toFun f := Finset.univ.noncommProd (fun i => ϕ i (f i)) fun i _ j _ h => hcomm h _ _ + toFun f := Finset.univ.noncommProd (fun i => ϕ i (f i)) fun _ _ _ _ h => hcomm h _ _ map_one' := by apply (Finset.noncommProd_eq_pow_card _ _ _ _ _).trans (one_pow _) simp @@ -135,7 +135,7 @@ def noncommPiCoprodEquiv [DecidableEq ι] : ((∀ i, N i) →* M) where toFun ϕ := noncommPiCoprod ϕ.1 ϕ.2 invFun f := - ⟨fun i => f.comp (MonoidHom.mulSingle N i), fun i j hij x y => + ⟨fun i => f.comp (MonoidHom.mulSingle N i), fun _ _ hij x y => Commute.map (Pi.mulSingle_commute hij x y) f⟩ left_inv ϕ := by ext diff --git a/Mathlib/GroupTheory/PGroup.lean b/Mathlib/GroupTheory/PGroup.lean index 52fcaf2fb7a602..d882d7e22ca40c 100644 --- a/Mathlib/GroupTheory/PGroup.lean +++ b/Mathlib/GroupTheory/PGroup.lean @@ -28,7 +28,7 @@ namespace IsPGroup theorem iff_orderOf [hp : Fact p.Prime] : IsPGroup p G ↔ ∀ g : G, ∃ k : ℕ, orderOf g = p ^ k := forall_congr' fun g => - ⟨fun ⟨k, hk⟩ => + ⟨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]⟩ @@ -134,7 +134,7 @@ theorem nontrivial_iff_card [Finite G] : Nontrivial G ↔ ∃ n > 0, Nat.card G Nat.pos_of_ne_zero fun hk0 => by rw [hk0, pow_zero] at hk; exact Finite.one_lt_card.ne' hk, hk⟩, - fun ⟨k, hk0, hk⟩ => + fun ⟨_, hk0, hk⟩ => Finite.one_lt_card_iff_nontrivial.1 <| hk.symm ▸ one_lt_pow₀ (Fact.out (p := p.Prime)).one_lt (ne_of_gt hk0)⟩ diff --git a/Mathlib/GroupTheory/Perm/Basic.lean b/Mathlib/GroupTheory/Perm/Basic.lean index 5dc3ff87f4586b..70e6c423d6dfde 100644 --- a/Mathlib/GroupTheory/Perm/Basic.lean +++ b/Mathlib/GroupTheory/Perm/Basic.lean @@ -31,14 +31,14 @@ instance instPowNat : Pow (Perm α) ℕ where pow f n := ⟨f^[n], f.symm^[n], f.left_inv.iterate _, f.right_inv.iterate _⟩ instance permGroup : Group (Perm α) where - mul_assoc f g h := (trans_assoc _ _ _).symm + mul_assoc _ _ _ := (trans_assoc _ _ _).symm one_mul := trans_refl mul_one := refl_trans inv_mul_cancel := self_trans_symm npow n f := f ^ n - npow_succ n f := coe_fn_injective <| Function.iterate_succ _ _ + npow_succ _ _ := coe_fn_injective <| Function.iterate_succ _ _ zpow := zpowRec fun n f ↦ f ^ n - zpow_succ' n f := coe_fn_injective <| Function.iterate_succ _ _ + zpow_succ' _ _ := coe_fn_injective <| Function.iterate_succ _ _ @[simp] theorem default_eq : (default : Perm α) = 1 := @@ -351,7 +351,7 @@ theorem subtypePerm_pow (f : Perm α) (n : ℕ) (hf) : | succ n ih => simp_rw [pow_succ', ih, subtypePerm_mul] private theorem zpow_aux (hf : ∀ x, p x ↔ p (f x)) : ∀ {n : ℤ} (x), p x ↔ p ((f ^ n) x) - | Int.ofNat n => pow_aux hf + | Int.ofNat _ => pow_aux hf | Int.negSucc n => by rw [zpow_negSucc] exact inv_aux.1 (pow_aux hf) diff --git a/Mathlib/GroupTheory/Perm/Cycle/Basic.lean b/Mathlib/GroupTheory/Perm/Cycle/Basic.lean index a13b28ec141ca5..0fc24ba0a1006a 100644 --- a/Mathlib/GroupTheory/Perm/Cycle/Basic.lean +++ b/Mathlib/GroupTheory/Perm/Cycle/Basic.lean @@ -278,7 +278,7 @@ theorem isCycle_iff_sameCycle (hx : f x ≠ x) : IsCycle f ↔ ∀ {y}, SameCycl rw [← zpow_apply_eq_self_of_apply_eq_self hy i, (f ^ i).injective.eq_iff] at hi rw [hi, hy], hf.exists_zpow_eq hx⟩, - fun h => ⟨x, hx, fun y hy => h.2 hy⟩⟩ + fun h => ⟨x, hx, fun _ hy => h.2 hy⟩⟩ section Finite @@ -790,7 +790,7 @@ theorem IsCycleOn.pow_apply_eq {s : Finset α} (hf : f.IsCycleOn s) (ha : a ∈ theorem IsCycleOn.zpow_apply_eq {s : Finset α} (hf : f.IsCycleOn s) (ha : a ∈ s) : ∀ {n : ℤ}, (f ^ n) a = a ↔ (s.card : ℤ) ∣ n - | Int.ofNat n => (hf.pow_apply_eq ha).trans Int.natCast_dvd_natCast.symm + | Int.ofNat _ => (hf.pow_apply_eq ha).trans Int.natCast_dvd_natCast.symm | Int.negSucc n => by rw [zpow_negSucc, ← inv_pow] exact (hf.inv.pow_apply_eq ha).trans (dvd_neg.trans Int.natCast_dvd_natCast).symm @@ -932,7 +932,7 @@ variable {f : Perm α} {s : Finset α} theorem product_self_eq_disjiUnion_perm_aux (hf : f.IsCycleOn s) : (range s.card : Set ℕ).PairwiseDisjoint fun k => - s.map ⟨fun i => (i, (f ^ k) i), fun i j => congr_arg Prod.fst⟩ := by + s.map ⟨fun i => (i, (f ^ k) i), fun _ _ => congr_arg Prod.fst⟩ := by obtain hs | _ := (s : Set α).subsingleton_or_nontrivial · refine Set.Subsingleton.pairwise ?_ _ simp_rw [Set.Subsingleton, mem_coe, ← card_le_one] at hs ⊢ @@ -960,7 +960,7 @@ The diagonals are given by the cycle `f`. theorem product_self_eq_disjiUnion_perm (hf : f.IsCycleOn s) : s ×ˢ s = (range s.card).disjiUnion - (fun k => s.map ⟨fun i => (i, (f ^ k) i), fun i j => congr_arg Prod.fst⟩) + (fun k => s.map ⟨fun i => (i, (f ^ k) i), fun _ _ => congr_arg Prod.fst⟩) (product_self_eq_disjiUnion_perm_aux hf) := by ext ⟨a, b⟩ simp only [mem_product, Equiv.Perm.coe_pow, mem_disjiUnion, mem_range, mem_map, diff --git a/Mathlib/GroupTheory/Perm/Cycle/Type.lean b/Mathlib/GroupTheory/Perm/Cycle/Type.lean index 5a823f43577e4b..c690004e7f5419 100644 --- a/Mathlib/GroupTheory/Perm/Cycle/Type.lean +++ b/Mathlib/GroupTheory/Perm/Cycle/Type.lean @@ -461,7 +461,7 @@ theorem _root_.exists_prime_orderOf_dvd_card {G : Type*} [Group G] [Fintype G] ( /-- 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_addOrderOf_dvd_card {G : Type*} [AddGroup G] [Fintype G] (p : ℕ) - [hp : Fact p.Prime] (hdvd : p ∣ Fintype.card G) : ∃ x : G, addOrderOf x = p := + [Fact p.Prime] (hdvd : p ∣ Fintype.card G) : ∃ x : G, addOrderOf x = p := @exists_prime_orderOf_dvd_card (Multiplicative G) _ _ _ _ (by convert hdvd) attribute [to_additive existing] exists_prime_orderOf_dvd_card diff --git a/Mathlib/GroupTheory/Perm/DomMulAct.lean b/Mathlib/GroupTheory/Perm/DomMulAct.lean index 4bfd4c758ab0d8..5d730372bcddfa 100644 --- a/Mathlib/GroupTheory/Perm/DomMulAct.lean +++ b/Mathlib/GroupTheory/Perm/DomMulAct.lean @@ -77,9 +77,9 @@ def stabilizerMulEquiv : (stabilizer (Perm α)ᵈᵐᵃ f)ᵐᵒᵖ ≃* (∀ i, ext a rw [smul_apply, symm_apply_apply, Perm.smul_def] apply comp_stabilizerEquiv_invFun⟩ - left_inv g := rfl + left_inv _ := rfl right_inv g := by ext i a; apply stabilizerEquiv_invFun_eq - map_mul' g h := rfl + map_mul' _ _ := rfl variable {f} diff --git a/Mathlib/GroupTheory/Perm/List.lean b/Mathlib/GroupTheory/Perm/List.lean index 1cdc01f35e5cd2..8e9416970a1b34 100644 --- a/Mathlib/GroupTheory/Perm/List.lean +++ b/Mathlib/GroupTheory/Perm/List.lean @@ -257,7 +257,7 @@ theorem formPerm_eq_of_isRotated {l l' : List α} (hd : Nodup l) (h : l ~r l') : theorem formPerm_append_pair : ∀ (l : List α) (a b : α), formPerm (l ++ [a, b]) = formPerm (l ++ [a]) * swap a b | [], _, _ => rfl - | [x], _, _ => rfl + | [_], _, _ => rfl | x::y::l, a, b => by simpa [mul_assoc] using formPerm_append_pair (y::l) a b diff --git a/Mathlib/GroupTheory/Perm/Sign.lean b/Mathlib/GroupTheory/Perm/Sign.lean index 269920ef0aab37..f40786fe4064c9 100644 --- a/Mathlib/GroupTheory/Perm/Sign.lean +++ b/Mathlib/GroupTheory/Perm/Sign.lean @@ -72,7 +72,7 @@ def swapFactorsAux : ⟨swap x (f x)::m.1, by rw [List.prod_cons, m.2.1, ← mul_assoc, mul_def (swap x (f x)), swap_swap, ← one_def, one_mul], - fun {g} hg => ((List.mem_cons).1 hg).elim (fun h => ⟨x, f x, hfx, h⟩) (m.2.2 _)⟩ + fun {_} hg => ((List.mem_cons).1 hg).elim (fun h => ⟨x, f x, hfx, h⟩) (m.2.2 _)⟩ /-- `swapFactors` represents a permutation as a product of a list of transpositions. The representation is non unique and depends on the linear order structure. @@ -245,7 +245,7 @@ theorem signAux_mul {n : ℕ} (f g : Perm (Fin n)) : signAux (f * g) = signAux f rfl private theorem signAux_swap_zero_one' (n : ℕ) : signAux (swap (0 : Fin (n + 2)) 1) = -1 := - show _ = ∏ x ∈ {(⟨1, 0⟩ : Σ a : Fin (n + 2), Fin (n + 2))}, + show _ = ∏ x ∈ {(⟨1, 0⟩ : Σ _ : Fin (n + 2), Fin (n + 2))}, if (Equiv.swap 0 1) x.1 ≤ swap 0 1 x.2 then (-1 : ℤˣ) else 1 by refine Eq.symm (prod_subset (fun ⟨x₁, x₂⟩ => by simp (config := { contextual := true }) [mem_finPairsLT, Fin.one_pos]) fun a ha₁ ha₂ => ?_) @@ -495,7 +495,7 @@ theorem sign_bij [DecidableEq β] [Fintype β] {f : Perm α} {g : Perm β} (i : rw [← h _ x.2 this] exact mt (hi _ _ this x.2) x.2⟩ : { y // g y ≠ y })) - ⟨fun ⟨x, hx⟩ ⟨y, hy⟩ h => Subtype.eq (hi _ _ _ _ (Subtype.mk.inj h)), fun ⟨y, hy⟩ => + ⟨fun ⟨_, _⟩ ⟨_, _⟩ h => Subtype.eq (hi _ _ _ _ (Subtype.mk.inj h)), fun ⟨y, hy⟩ => let ⟨x, hfx, hx⟩ := hg y hy ⟨⟨x, hfx⟩, Subtype.eq hx⟩⟩) fun ⟨x, _⟩ => Subtype.eq (h x _ _) diff --git a/Mathlib/GroupTheory/Perm/Support.lean b/Mathlib/GroupTheory/Perm/Support.lean index f95ba42476e2a0..ea8f7d275ba904 100644 --- a/Mathlib/GroupTheory/Perm/Support.lean +++ b/Mathlib/GroupTheory/Perm/Support.lean @@ -562,7 +562,7 @@ theorem two_le_card_support_of_ne_one {f : Perm α} (h : f ≠ 1) : 2 ≤ f.supp theorem card_support_swap_mul {f : Perm α} {x : α} (hx : f x ≠ x) : (swap x (f x) * f).support.card < f.support.card := Finset.card_lt_card - ⟨fun z hz => (mem_support_swap_mul_imp_mem_support_ne hz).left, fun h => + ⟨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))⟩ theorem card_support_swap {x y : α} (hxy : x ≠ y) : (swap x y).support.card = 2 := diff --git a/Mathlib/GroupTheory/PushoutI.lean b/Mathlib/GroupTheory/PushoutI.lean index ab561721ed4f6b..47fa6da660134a 100644 --- a/Mathlib/GroupTheory/PushoutI.lean +++ b/Mathlib/GroupTheory/PushoutI.lean @@ -454,7 +454,7 @@ theorem summand_smul_def' {i : ι} (g : G i) (w : NormalWord d) : noncomputable instance mulAction : MulAction (PushoutI φ) (NormalWord d) := MulAction.ofEndHom <| lift - (fun i => MulAction.toEndHom) + (fun _ => MulAction.toEndHom) MulAction.toEndHom <| by intro i simp only [MulAction.toEndHom, DFunLike.ext_iff, MonoidHom.coe_comp, MonoidHom.coe_mk, diff --git a/Mathlib/GroupTheory/QuotientGroup/Basic.lean b/Mathlib/GroupTheory/QuotientGroup/Basic.lean index 2172f44a0ecee6..c29572983166b8 100644 --- a/Mathlib/GroupTheory/QuotientGroup/Basic.lean +++ b/Mathlib/GroupTheory/QuotientGroup/Basic.lean @@ -106,7 +106,7 @@ theorem monoidHom_ext ⦃f g : G ⧸ N →* M⦄ (h : f.comp (mk' N) = g.comp (m MonoidHom.ext fun x => QuotientGroup.induction_on x <| (DFunLike.congr_fun h : _) @[to_additive (attr := simp)] -theorem eq_one_iff {N : Subgroup G} [nN : N.Normal] (x : G) : (x : G ⧸ N) = 1 ↔ x ∈ N := by +theorem eq_one_iff {N : Subgroup G} [N.Normal] (x : G) : (x : G ⧸ N) = 1 ↔ x ∈ N := by refine QuotientGroup.eq.trans ?_ rw [mul_one, Subgroup.inv_mem_iff] diff --git a/Mathlib/GroupTheory/SchurZassenhaus.lean b/Mathlib/GroupTheory/SchurZassenhaus.lean index a143963c7cc26d..ed1bc6f16be044 100644 --- a/Mathlib/GroupTheory/SchurZassenhaus.lean +++ b/Mathlib/GroupTheory/SchurZassenhaus.lean @@ -98,7 +98,7 @@ theorem exists_smul_eq (hH : Nat.Coprime (Nat.card H) H.index) (α β : H.Quotie ∃ h : H, h • α = β := Quotient.inductionOn' α (Quotient.inductionOn' β fun β α => - Exists.imp (fun n => Quotient.sound') + Exists.imp (fun _ => Quotient.sound') ⟨(powCoprime hH).symm (diff (MonoidHom.id H) β α), (diff_inv _ _ _).symm.trans (inv_eq_one.mpr diff --git a/Mathlib/GroupTheory/SpecificGroups/Alternating.lean b/Mathlib/GroupTheory/SpecificGroups/Alternating.lean index 200e6d06c39ac1..60f59d2000a12a 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Alternating.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Alternating.lean @@ -137,7 +137,7 @@ open alternatingGroup @[simp] theorem closure_three_cycles_eq_alternating : closure { σ : Perm α | IsThreeCycle σ } = alternatingGroup α := - closure_eq_of_le _ (fun σ hσ => mem_alternatingGroup.2 hσ.sign) fun σ hσ => by + closure_eq_of_le _ (fun _ hσ => mem_alternatingGroup.2 hσ.sign) fun σ hσ => by suffices hind : ∀ (n : ℕ) (l : List (Perm α)) (_ : ∀ g, g ∈ l → IsSwap g) (_ : l.length = 2 * n), l.prod ∈ closure { σ : Perm α | IsThreeCycle σ } by diff --git a/Mathlib/GroupTheory/SpecificGroups/Dihedral.lean b/Mathlib/GroupTheory/SpecificGroups/Dihedral.lean index 53949cd3a109b2..843bcfd6e14855 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Dihedral.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Dihedral.lean @@ -200,7 +200,7 @@ $n + n + n + n*n$) of commuting elements. -/ def OddCommuteEquiv (hn : Odd n) : { p : DihedralGroup n × DihedralGroup n // Commute p.1 p.2 } ≃ ZMod n ⊕ ZMod n ⊕ ZMod n ⊕ ZMod n × ZMod n := let u := ZMod.unitOfCoprime 2 (Nat.prime_two.coprime_iff_not_dvd.mpr hn.not_two_dvd_nat) - have hu : ∀ a : ZMod n, a + a = 0 ↔ a = 0 := fun a => ZMod.add_self_eq_zero_iff_eq_zero hn + have hu : ∀ a : ZMod n, a + a = 0 ↔ a = 0 := fun _ => ZMod.add_self_eq_zero_iff_eq_zero hn { toFun := fun | ⟨⟨sr i, r _⟩, _⟩ => Sum.inl i | ⟨⟨r _, sr j⟩, _⟩ => Sum.inr (Sum.inl j) @@ -212,7 +212,7 @@ def OddCommuteEquiv (hn : Odd n) : { p : DihedralGroup n × DihedralGroup n // C | .inr (.inr (.inl k)) => ⟨⟨sr (u⁻¹ * k), sr (u⁻¹ * k)⟩, rfl⟩ | .inr (.inr (.inr ⟨i, j⟩)) => ⟨⟨r i, r j⟩, congrArg r (add_comm i j)⟩ left_inv := fun - | ⟨⟨r i, r j⟩, h⟩ => rfl + | ⟨⟨r _, r _⟩, _⟩ => rfl | ⟨⟨r i, sr j⟩, h⟩ => by simpa [sub_eq_add_neg, neg_eq_iff_add_eq_zero, hu, eq_comm (a := i) (b := 0)] using h.eq | ⟨⟨sr i, r j⟩, h⟩ => by @@ -223,11 +223,11 @@ def OddCommuteEquiv (hn : Odd n) : { p : DihedralGroup n × DihedralGroup n // C rw [Subtype.ext_iff, Prod.ext_iff, sr.injEq, sr.injEq, h, and_self, ← two_mul] exact u.inv_mul_cancel_left j right_inv := fun - | .inl i => rfl - | .inr (.inl j) => rfl + | .inl _ => rfl + | .inr (.inl _) => rfl | .inr (.inr (.inl k)) => congrArg (Sum.inr ∘ Sum.inr ∘ Sum.inl) <| two_mul (u⁻¹ * k) ▸ u.mul_inv_cancel_left k - | .inr (.inr (.inr ⟨i, j⟩)) => rfl } + | .inr (.inr (.inr ⟨_, _⟩)) => rfl } /-- If n is odd, then the Dihedral group of order $2n$ has $n(n+3)$ pairs of commuting elements. -/ lemma card_commute_odd (hn : Odd n) : diff --git a/Mathlib/GroupTheory/Sylow.lean b/Mathlib/GroupTheory/Sylow.lean index a534e244575fe1..7792a01f89afb3 100644 --- a/Mathlib/GroupTheory/Sylow.lean +++ b/Mathlib/GroupTheory/Sylow.lean @@ -130,13 +130,13 @@ theorem IsPGroup.exists_le_sylow {P : Subgroup G} (hP : IsPGroup p P) : ∃ Q : (fun c hc1 hc2 Q hQ => ⟨{ carrier := ⋃ R : c, R one_mem' := ⟨Q, ⟨⟨Q, hQ⟩, rfl⟩, Q.one_mem⟩ - inv_mem' := fun {g} ⟨_, ⟨R, rfl⟩, hg⟩ => ⟨R, ⟨R, rfl⟩, R.1.inv_mem hg⟩ - mul_mem' := fun {g} h ⟨_, ⟨R, rfl⟩, hg⟩ ⟨_, ⟨S, rfl⟩, hh⟩ => + inv_mem' := fun {_} ⟨_, ⟨R, rfl⟩, hg⟩ => ⟨R, ⟨R, rfl⟩, R.1.inv_mem hg⟩ + mul_mem' := fun {_} _ ⟨_, ⟨R, rfl⟩, hg⟩ ⟨_, ⟨S, rfl⟩, hh⟩ => (hc2.total R.2 S.2).elim (fun T => ⟨S, ⟨S, rfl⟩, S.1.mul_mem (T hg) hh⟩) fun T => ⟨R, ⟨R, rfl⟩, R.1.mul_mem hg (T hh)⟩ }, fun ⟨g, _, ⟨S, rfl⟩, hg⟩ => by refine Exists.imp (fun k hk => ?_) (hc1 S.2 ⟨g, hg⟩) - rwa [Subtype.ext_iff, coe_pow] at hk ⊢, fun M hM g hg => ⟨M, ⟨⟨M, hM⟩, rfl⟩, hg⟩⟩) + rwa [Subtype.ext_iff, coe_pow] at hk ⊢, fun M hM _ hg => ⟨M, ⟨⟨M, hM⟩, rfl⟩, hg⟩⟩) P hP) fun {Q} h => ⟨⟨Q, h.2.prop, h.2.eq_of_ge⟩, h.1⟩ @@ -451,7 +451,7 @@ def fixedPointsMulLeftCosetsEquivQuotient (H : Subgroup G) [Finite (H : Set G)] normalizer H ⧸ Subgroup.comap ((normalizer H).subtype : normalizer H →* G) H := @subtypeQuotientEquivQuotientSubtype G (normalizer H : Set G) (_) (_) (MulAction.fixedPoints H (G ⧸ H)) - (fun a => (@mem_fixedPoints_mul_left_cosets_iff_mem_normalizer _ _ _ ‹_› _).symm) + (fun _ => (@mem_fixedPoints_mul_left_cosets_iff_mem_normalizer _ _ _ ‹_› _).symm) (by intros unfold_projs @@ -479,7 +479,7 @@ theorem card_normalizer_modEq_card [Finite G] {p : ℕ} {n : ℕ} [hp : Fact p.P /-- If `H` is a `p`-subgroup but not a Sylow `p`-subgroup, then `p` divides the index of `H` inside its normalizer. -/ -theorem prime_dvd_card_quotient_normalizer [Finite G] {p : ℕ} {n : ℕ} [hp : Fact p.Prime] +theorem prime_dvd_card_quotient_normalizer [Finite G] {p : ℕ} {n : ℕ} [Fact p.Prime] (hdvd : p ^ (n + 1) ∣ Nat.card G) {H : Subgroup G} (hH : Nat.card H = p ^ n) : p ∣ Nat.card (normalizer H ⧸ Subgroup.comap ((normalizer H).subtype : normalizer H →* G) H) := let ⟨s, hs⟩ := exists_eq_mul_left_of_dvd hdvd diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean index 86b064cb61eace..0849ae203d5a83 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean @@ -323,7 +323,7 @@ instance group : Group (P₁ ≃ᵃ[k] P₁) where one := refl k P₁ mul e e' := e'.trans e inv := symm - mul_assoc e₁ e₂ e₃ := trans_assoc _ _ _ + mul_assoc _ _ _ := trans_assoc _ _ _ one_mul := trans_refl mul_one := refl_trans inv_mul_cancel := self_trans_symm diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean index 7f6518bb77f2e9..ef82d9e40a82ce 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean @@ -213,8 +213,8 @@ variable {R : Type*} [Monoid R] [DistribMulAction R V2] [SMulCommClass k R V2] instance mulAction : MulAction R (P1 →ᵃ[k] V2) where -- Porting note: `map_vadd` is `simp`, but we still have to pass it explicitly smul c f := ⟨c • ⇑f, c • f.linear, fun p v => by simp [smul_add, map_vadd f]⟩ - one_smul f := ext fun p => one_smul _ _ - mul_smul c₁ c₂ f := ext fun p => mul_smul _ _ _ + one_smul _ := ext fun _ => one_smul _ _ + mul_smul _ _ _ := ext fun _ => mul_smul _ _ _ @[simp, norm_cast] theorem coe_smul (c : R) (f : P1 →ᵃ[k] V2) : ⇑(c • f) = c • ⇑f := diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace.lean index ab4b6063b2c231..70ea2fa9472291 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace.lean @@ -522,13 +522,13 @@ instance : CompleteLattice (AffineSubspace k P) := PartialOrder.lift ((↑) : AffineSubspace k P → Set P) coe_injective with sup := fun s1 s2 => affineSpan k (s1 ∪ s2) - le_sup_left := fun s1 s2 => + le_sup_left := fun _ _ => Set.Subset.trans Set.subset_union_left (subset_spanPoints k _) - le_sup_right := fun s1 s2 => + le_sup_right := fun _ _ => Set.Subset.trans Set.subset_union_right (subset_spanPoints k _) - sup_le := fun s1 s2 s3 hs1 hs2 => spanPoints_subset_coe_of_subset_coe (Set.union_subset hs1 hs2) + sup_le := fun _ _ _ hs1 hs2 => spanPoints_subset_coe_of_subset_coe (Set.union_subset hs1 hs2) inf := fun s1 s2 => - mk (s1 ∩ s2) fun c p1 p2 p3 hp1 hp2 hp3 => + mk (s1 ∩ s2) fun c _ _ _ hp1 hp2 hp3 => ⟨s1.smul_vsub_vadd_mem c hp1.1 hp2.1 hp3.1, s2.smul_vsub_vadd_mem c hp1.2 hp2.2 hp3.2⟩ inf_le_left := fun _ _ => Set.inter_subset_left inf_le_right := fun _ _ => Set.inter_subset_right diff --git a/Mathlib/LinearAlgebra/Alternating/Basic.lean b/Mathlib/LinearAlgebra/Alternating/Basic.lean index 007a27d3573682..69536a10962b01 100644 --- a/Mathlib/LinearAlgebra/Alternating/Basic.lean +++ b/Mathlib/LinearAlgebra/Alternating/Basic.lean @@ -286,7 +286,7 @@ theorem coe_add : (↑(f + f') : MultilinearMap R (fun _ : ι => M) N) = f + f' instance zero : Zero (M [⋀^ι]→ₗ[R] N) := ⟨{ (0 : MultilinearMap R (fun _ : ι => M) N) with - map_eq_zero_of_eq' := fun v i j _ _ => by simp }⟩ + map_eq_zero_of_eq' := fun _ _ _ _ _ => by simp }⟩ @[simp] theorem zero_apply : (0 : M [⋀^ι]→ₗ[R] N) v = 0 := @@ -873,8 +873,8 @@ def curryLeft {n : ℕ} (f : M'' [⋀^Fin n.succ]→ₗ[R'] N'') : map_eq_zero_of_eq' := fun v i j hv hij => f.map_eq_zero_of_eq _ (by rwa [Matrix.cons_val_succ, Matrix.cons_val_succ]) ((Fin.succ_injective _).ne hij) } - map_add' m₁ m₂ := ext fun v => f.map_vecCons_add _ _ _ - map_smul' r m := ext fun v => f.map_vecCons_smul _ _ _ + map_add' _ _ := ext fun _ => f.map_vecCons_add _ _ _ + map_smul' _ _ := ext fun _ => f.map_vecCons_smul _ _ _ @[simp] theorem curryLeft_zero {n : ℕ} : curryLeft (0 : M'' [⋀^Fin n.succ]→ₗ[R'] N'') = 0 := @@ -903,7 +903,7 @@ def curryLeftLinearMap {n : ℕ} : @[simp] theorem curryLeft_same {n : ℕ} (f : M'' [⋀^Fin n.succ.succ]→ₗ[R'] N'') (m : M'') : (f.curryLeft m).curryLeft m = 0 := - ext fun x => f.map_eq_zero_of_eq _ (by simp) Fin.zero_ne_one + ext fun _ => f.map_eq_zero_of_eq _ (by simp) Fin.zero_ne_one @[simp] theorem curryLeft_compAlternatingMap {n : ℕ} (g : N'' →ₗ[R'] N₂'') diff --git a/Mathlib/LinearAlgebra/BilinearForm/Hom.lean b/Mathlib/LinearAlgebra/BilinearForm/Hom.lean index f32f28e8aea318..98d0c01aeaba56 100644 --- a/Mathlib/LinearAlgebra/BilinearForm/Hom.lean +++ b/Mathlib/LinearAlgebra/BilinearForm/Hom.lean @@ -268,8 +268,8 @@ def congr (e : M ≃ₗ[R] M') : BilinForm R M ≃ₗ[R] BilinForm R M' where simp only [comp_apply, LinearEquiv.coe_coe, LinearEquiv.symm_apply_apply, forall_const] right_inv B := ext₂ fun x => by simp only [comp_apply, LinearEquiv.coe_coe, LinearEquiv.apply_symm_apply, forall_const] - map_add' B B' := ext₂ fun x y => rfl - map_smul' B B' := ext₂ fun x y => rfl + map_add' _ _ := ext₂ fun _ _ => rfl + map_smul' _ _ := ext₂ fun _ _ => rfl @[simp] theorem congr_apply (e : M ≃ₗ[R] M') (B : BilinForm R M) (x y : M') : diff --git a/Mathlib/LinearAlgebra/BilinearMap.lean b/Mathlib/LinearAlgebra/BilinearMap.lean index 10c008423626ee..0430d8a20645b6 100644 --- a/Mathlib/LinearAlgebra/BilinearMap.lean +++ b/Mathlib/LinearAlgebra/BilinearMap.lean @@ -102,8 +102,8 @@ attribute [local instance] SMulCommClass.symm /-- Given a linear map from `M` to linear maps from `N` to `P`, i.e., a bilinear map from `M × N` to `P`, change the order of variables and get a linear map from `N` to linear maps from `M` to `P`. -/ def flip (f : M →ₛₗ[ρ₁₂] N →ₛₗ[σ₁₂] P) : N →ₛₗ[σ₁₂] M →ₛₗ[ρ₁₂] P := - mk₂'ₛₗ σ₁₂ ρ₁₂ (fun n m => f m n) (fun n₁ n₂ m => (f m).map_add _ _) - (fun c n m => (f m).map_smulₛₗ _ _) + mk₂'ₛₗ σ₁₂ ρ₁₂ (fun n m => f m n) (fun _ _ m => (f m).map_add _ _) + (fun _ _ m => (f m).map_smulₛₗ _ _) (fun n m₁ m₂ => by simp only [map_add, add_apply]) -- Note: #8386 changed `map_smulₛₗ` into `map_smulₛₗ _`. -- It looks like we now run out of assignable metavariables. diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean index 30687d5b355943..156e71925668fc 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean @@ -105,7 +105,7 @@ theorem involute_eq_id : protected def equiv : CliffordAlgebra (0 : QuadraticForm R Unit) ≃ₐ[R] R := AlgEquiv.ofAlgHom (CliffordAlgebra.lift (0 : QuadraticForm R Unit) <| - ⟨0, fun m : Unit => (zero_mul (0 : R)).trans (algebraMap R _).map_zero.symm⟩) + ⟨0, fun _ : Unit => (zero_mul (0 : R)).trans (algebraMap R _).map_zero.symm⟩) (Algebra.ofId R _) (by ext) (by ext : 1; rw [ι_eq_zero, LinearMap.comp_zero, LinearMap.comp_zero]) diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/Even.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/Even.lean index 76bff36c9a4d14..a94392b30fc066 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/Even.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/Even.lean @@ -157,8 +157,8 @@ private def fFold : M →ₗ[R] A × S f →ₗ[R] A × S f := LinearMap.ext fun m₃ => show f.bilin m₃ (c • m) * a.1 = c • (f.bilin m₃ m * a.1) by rw [LinearMap.map_smul, smul_mul_assoc])) - (fun m a₁ a₂ => Prod.ext rfl (Subtype.ext <| LinearMap.ext fun m₃ => mul_add _ _ _)) - fun c m a => Prod.ext rfl (Subtype.ext <| LinearMap.ext fun m₃ => mul_smul_comm _ _ _) + (fun _ _ _ => Prod.ext rfl (Subtype.ext <| LinearMap.ext fun _ => mul_add _ _ _)) + fun _ _ _ => Prod.ext rfl (Subtype.ext <| LinearMap.ext fun _ => mul_smul_comm _ _ _) @[simp] private theorem fst_fFold_fFold (m₁ m₂ : M) (x : A × S f) : diff --git a/Mathlib/LinearAlgebra/DFinsupp.lean b/Mathlib/LinearAlgebra/DFinsupp.lean index 7f631f041c8c39..2313a713d4ae5c 100644 --- a/Mathlib/LinearAlgebra/DFinsupp.lean +++ b/Mathlib/LinearAlgebra/DFinsupp.lean @@ -319,7 +319,7 @@ theorem mem_iSup_iff_exists_dfinsupp (p : ι → Submodule R N) (x : N) : See also `Submodule.mem_iSup_iff_exists_finsupp`. -/ theorem mem_iSup_iff_exists_dfinsupp' (p : ι → Submodule R N) [∀ (i) (x : p i), Decidable (x ≠ 0)] - (x : N) : x ∈ iSup p ↔ ∃ f : Π₀ i, p i, (f.sum fun i xi => ↑xi) = x := by + (x : N) : x ∈ iSup p ↔ ∃ f : Π₀ i, p i, (f.sum fun _ xi => ↑xi) = x := by rw [mem_iSup_iff_exists_dfinsupp] simp_rw [DFinsupp.lsum_apply_apply, DFinsupp.sumAddHom_apply, LinearMap.toAddMonoidHom_coe, coe_subtype] diff --git a/Mathlib/LinearAlgebra/DirectSum/TensorProduct.lean b/Mathlib/LinearAlgebra/DirectSum/TensorProduct.lean index 58b0cd735d196d..1a6c8831e3b9d0 100644 --- a/Mathlib/LinearAlgebra/DirectSum/TensorProduct.lean +++ b/Mathlib/LinearAlgebra/DirectSum/TensorProduct.lean @@ -117,9 +117,9 @@ protected def directSum : def directSumLeft : (⨁ i₁, M₁ i₁) ⊗[R] M₂' ≃ₗ[R] ⨁ i, M₁ i ⊗[R] M₂' := LinearEquiv.ofLinear (lift <| - DirectSum.toModule R _ _ fun i => + DirectSum.toModule R _ _ fun _ => (mk R _ _).compr₂ <| DirectSum.lof R ι₁ (fun i => M₁ i ⊗[R] M₂') _) - (DirectSum.toModule R _ _ fun i => rTensor _ (DirectSum.lof R ι₁ _ _)) + (DirectSum.toModule R _ _ fun _ => rTensor _ (DirectSum.lof R ι₁ _ _)) (DirectSum.linearMap_ext R fun i => TensorProduct.ext <| LinearMap.ext₂ fun m₁ m₂ => by diff --git a/Mathlib/LinearAlgebra/ExteriorAlgebra/OfAlternating.lean b/Mathlib/LinearAlgebra/ExteriorAlgebra/OfAlternating.lean index 0aaaa15bab98c4..ebefb027f8c14a 100644 --- a/Mathlib/LinearAlgebra/ExteriorAlgebra/OfAlternating.lean +++ b/Mathlib/LinearAlgebra/ExteriorAlgebra/OfAlternating.lean @@ -141,7 +141,7 @@ def liftAlternatingEquiv : (∀ i, M [⋀^Fin i]→ₗ[R] N) ≃ₗ[R] ExteriorA map_add' := map_add _ map_smul' := map_smul _ invFun F i := F.compAlternatingMap (ιMulti R i) - left_inv f := funext fun i => liftAlternating_comp_ιMulti _ + left_inv _ := funext fun _ => liftAlternating_comp_ιMulti _ right_inv F := (liftAlternating_comp _ _).trans <| by rw [liftAlternating_ιMulti, LinearMap.comp_id] diff --git a/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean b/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean index f7ab907b35f9c0..6d30b7aa5aa3a8 100644 --- a/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean +++ b/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean @@ -674,9 +674,9 @@ noncomputable def divisionRingOfFiniteDimensional (F K : Type*) [Field F] [Ring exact (Classical.choose_spec (FiniteDimensional.exists_mul_eq_one F hx):) inv_zero := dif_pos rfl nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl qsmul := _ - qsmul_def := fun q a => rfl + qsmul_def := fun _ _ => rfl /-- An integral domain that is module-finite as an algebra over a field is a field. -/ noncomputable def fieldOfFiniteDimensional (F K : Type*) [Field F] [h : CommRing K] [IsDomain K] diff --git a/Mathlib/LinearAlgebra/Finsupp.lean b/Mathlib/LinearAlgebra/Finsupp.lean index 810b8a01afebdd..91e9feb4155da7 100644 --- a/Mathlib/LinearAlgebra/Finsupp.lean +++ b/Mathlib/LinearAlgebra/Finsupp.lean @@ -276,7 +276,7 @@ def supported (s : Set α) : Submodule R (α →₀ M) where simp only [subset_def, Finset.mem_coe, Set.mem_setOf_eq, mem_support_iff, zero_apply] intro h ha exact (ha rfl).elim - smul_mem' a p hp := Subset.trans (Finset.coe_subset.2 support_smul) hp + smul_mem' _ _ hp := Subset.trans (Finset.coe_subset.2 support_smul) hp variable {M} @@ -1266,7 +1266,7 @@ theorem mem_span_finset {s : Finset M} {x : M} : (Finsupp.mem_span_image_iff_linearCombination _).1 (show x ∈ span R (_root_.id '' (↑s : Set M)) by rwa [Set.image_id]) ⟨v, hvx ▸ (linearCombination_apply_of_mem_supported _ hvs).symm⟩, - fun ⟨f, hf⟩ => hf ▸ sum_mem fun i hi => smul_mem _ _ <| subset_span hi⟩ + fun ⟨_, hf⟩ => hf ▸ sum_mem fun _ hi => smul_mem _ _ <| subset_span hi⟩ /-- An element `m ∈ M` is contained in the `R`-submodule spanned by a set `s ⊆ M`, if and only if `m` can be written as a finite `R`-linear combination of elements of `s`. diff --git a/Mathlib/LinearAlgebra/Lagrange.lean b/Mathlib/LinearAlgebra/Lagrange.lean index ab7d725e812774..9b87bad3dd5faa 100644 --- a/Mathlib/LinearAlgebra/Lagrange.lean +++ b/Mathlib/LinearAlgebra/Lagrange.lean @@ -376,7 +376,7 @@ theorem eq_interpolate_iff {f : F[X]} (hvs : Set.InjOn v s) : and polynomials of degree less than `Fintype.card ι`. -/ def funEquivDegreeLT (hvs : Set.InjOn v s) : degreeLT F s.card ≃ₗ[F] s → F where toFun f i := f.1.eval (v i) - map_add' f g := funext fun v => eval_add + map_add' _ _ := funext fun _ => eval_add map_smul' c f := funext <| by simp invFun r := ⟨interpolate s v fun x => if hx : x ∈ s then r ⟨x, hx⟩ else 0, diff --git a/Mathlib/LinearAlgebra/LinearIndependent.lean b/Mathlib/LinearAlgebra/LinearIndependent.lean index 9ce4ca2f473b7a..4b279b9b0bd229 100644 --- a/Mathlib/LinearAlgebra/LinearIndependent.lean +++ b/Mathlib/LinearAlgebra/LinearIndependent.lean @@ -144,8 +144,8 @@ theorem linearIndependent_iff' : fun hnis => hnis.elim his _ = (∑ j ∈ s, Finsupp.single j (g j)) i := (map_sum ..).symm _ = 0 := DFunLike.ext_iff.1 h i, - fun hf l hl => - Finsupp.ext fun i => + fun hf _ hl => + Finsupp.ext fun _ => _root_.by_contradiction fun hni => hni <| hf _ _ hl _ <| Finsupp.mem_support_iff.2 hni⟩ theorem linearIndependent_iff'' : diff --git a/Mathlib/LinearAlgebra/LinearPMap.lean b/Mathlib/LinearAlgebra/LinearPMap.lean index bae8ae629f0f73..ff0ddc27cc274a 100644 --- a/Mathlib/LinearAlgebra/LinearPMap.lean +++ b/Mathlib/LinearAlgebra/LinearPMap.lean @@ -223,12 +223,12 @@ instance inhabited : Inhabited (E →ₗ.[R] F) := instance semilatticeInf : SemilatticeInf (E →ₗ.[R] F) where le := (· ≤ ·) - le_refl f := ⟨le_refl f.domain, fun x y h => Subtype.eq h ▸ rfl⟩ - le_trans := fun f g h ⟨fg_le, fg_eq⟩ ⟨gh_le, gh_eq⟩ => - ⟨le_trans fg_le gh_le, fun x z hxz => + le_refl f := ⟨le_refl f.domain, fun _ _ h => Subtype.eq h ▸ rfl⟩ + le_trans := fun _ _ _ ⟨fg_le, fg_eq⟩ ⟨gh_le, gh_eq⟩ => + ⟨le_trans fg_le gh_le, fun x _ hxz => have hxy : (x : E) = inclusion fg_le x := rfl (fg_eq hxy).trans (gh_eq <| hxy.symm.trans hxz)⟩ - le_antisymm f g fg gf := eq_of_le_of_domain_eq fg (le_antisymm fg.1 gf.1) + le_antisymm _ _ fg gf := eq_of_le_of_domain_eq fg (le_antisymm fg.1 gf.1) inf := (· ⊓ ·) -- Porting note: `by rintro` is required, or error of a metavariable happens. le_inf := by @@ -240,9 +240,9 @@ instance semilatticeInf : SemilatticeInf (E →ₗ.[R] F) where fun x ⟨y, yg, hy⟩ h => by apply fg_eq exact h⟩ - inf_le_left f g := ⟨fun x hx => hx.fst, fun x y h => congr_arg f <| Subtype.eq <| h⟩ - inf_le_right f g := - ⟨fun x hx => hx.snd.fst, fun ⟨x, xf, xg, hx⟩ y h => hx.trans <| congr_arg g <| Subtype.eq <| h⟩ + inf_le_left f _ := ⟨fun _ hx => hx.fst, fun _ _ h => congr_arg f <| Subtype.eq <| h⟩ + inf_le_right _ g := + ⟨fun _ hx => hx.snd.fst, fun ⟨_, _, _, hx⟩ _ h => hx.trans <| congr_arg g <| Subtype.eq <| h⟩ instance orderBot : OrderBot (E →ₗ.[R] F) where bot := ⊥ @@ -676,7 +676,7 @@ theorem domRestrict_apply {f : E →ₗ.[R] F} {S : Submodule R E} ⦃x : ↥(S exact LinearPMap.mk_apply _ _ _ theorem domRestrict_le {f : E →ₗ.[R] F} {S : Submodule R E} : f.domRestrict S ≤ f := - ⟨by simp, fun x y hxy => domRestrict_apply hxy⟩ + ⟨by simp, fun _ _ hxy => domRestrict_apply hxy⟩ /-! ### Graph -/ diff --git a/Mathlib/LinearAlgebra/Matrix/Charpoly/LinearMap.lean b/Mathlib/LinearAlgebra/Matrix/Charpoly/LinearMap.lean index 73a35fa98fa856..e7d285c6ad0d2d 100644 --- a/Mathlib/LinearAlgebra/Matrix/Charpoly/LinearMap.lean +++ b/Mathlib/LinearAlgebra/Matrix/Charpoly/LinearMap.lean @@ -229,4 +229,4 @@ theorem LinearMap.exists_monic_and_coeff_mem_pow_and_aeval_eq_zero_of_range_le_s theorem LinearMap.exists_monic_and_aeval_eq_zero [Module.Finite R M] (f : Module.End R M) : ∃ p : R[X], p.Monic ∧ Polynomial.aeval f p = 0 := (LinearMap.exists_monic_and_coeff_mem_pow_and_aeval_eq_zero_of_range_le_smul R f ⊤ (by simp)).imp - fun p h => h.imp_right And.right + fun _ h => h.imp_right And.right diff --git a/Mathlib/LinearAlgebra/Matrix/Circulant.lean b/Mathlib/LinearAlgebra/Matrix/Circulant.lean index 769780c3325b5a..c81affc3515054 100644 --- a/Mathlib/LinearAlgebra/Matrix/Circulant.lean +++ b/Mathlib/LinearAlgebra/Matrix/Circulant.lean @@ -60,7 +60,7 @@ theorem circulant_injective [AddGroup n] : Injective (circulant : (n → α) → theorem Fin.circulant_injective : ∀ n, Injective fun v : Fin n → α => circulant v | 0 => by simp [Injective] - | n + 1 => Matrix.circulant_injective + | _ + 1 => Matrix.circulant_injective @[simp] theorem circulant_inj [AddGroup n] {v w : n → α} : circulant v = circulant w ↔ v = w := @@ -78,12 +78,12 @@ theorem conjTranspose_circulant [Star α] [AddGroup n] (v : n → α) : theorem Fin.transpose_circulant : ∀ {n} (v : Fin n → α), (circulant v)ᵀ = circulant fun i => v (-i) | 0 => by simp [Injective, eq_iff_true_of_subsingleton] - | n + 1 => Matrix.transpose_circulant + | _ + 1 => Matrix.transpose_circulant theorem Fin.conjTranspose_circulant [Star α] : ∀ {n} (v : Fin n → α), (circulant v)ᴴ = circulant (star fun i => v (-i)) | 0 => by simp [Injective, eq_iff_true_of_subsingleton] - | n + 1 => Matrix.conjTranspose_circulant + | _ + 1 => Matrix.conjTranspose_circulant theorem map_circulant [Sub n] (v : n → α) (f : α → β) : (circulant v).map f = circulant fun i => f (v i) := @@ -117,7 +117,7 @@ theorem circulant_mul [Semiring α] [Fintype n] [AddGroup n] (v w : n → α) : theorem Fin.circulant_mul [Semiring α] : ∀ {n} (v w : Fin n → α), circulant v * circulant w = circulant (circulant v *ᵥ w) | 0 => by simp [Injective, eq_iff_true_of_subsingleton] - | n + 1 => Matrix.circulant_mul + | _ + 1 => Matrix.circulant_mul /-- Multiplication of circulant matrices commutes when the elements do. -/ theorem circulant_mul_comm [CommSemigroup α] [AddCommMonoid α] [Fintype n] [AddCommGroup n] @@ -134,7 +134,7 @@ theorem circulant_mul_comm [CommSemigroup α] [AddCommMonoid α] [Fintype n] [Ad theorem Fin.circulant_mul_comm [CommSemigroup α] [AddCommMonoid α] : ∀ {n} (v w : Fin n → α), circulant v * circulant w = circulant w * circulant v | 0 => by simp [Injective] - | n + 1 => Matrix.circulant_mul_comm + | _ + 1 => Matrix.circulant_mul_comm /-- `k • circulant v` is another circulant matrix `circulant (k • v)`. -/ theorem circulant_smul [Sub n] [SMul R α] (k : R) (v : n → α) : @@ -169,7 +169,7 @@ theorem circulant_isSymm_iff [AddGroup n] {v : n → α} : theorem Fin.circulant_isSymm_iff : ∀ {n} {v : Fin n → α}, (circulant v).IsSymm ↔ ∀ i, v (-i) = v i | 0 => by simp [IsSymm.ext_iff, IsEmpty.forall_iff] - | n + 1 => Matrix.circulant_isSymm_iff + | _ + 1 => Matrix.circulant_isSymm_iff /-- If `circulant v` is symmetric, `∀ i j : I, v (- i) = v i`. -/ theorem circulant_isSymm_apply [AddGroup n] {v : n → α} (h : (circulant v).IsSymm) (i : n) : diff --git a/Mathlib/LinearAlgebra/Matrix/DotProduct.lean b/Mathlib/LinearAlgebra/Matrix/DotProduct.lean index d943a52a816859..3a313af6368d57 100644 --- a/Mathlib/LinearAlgebra/Matrix/DotProduct.lean +++ b/Mathlib/LinearAlgebra/Matrix/DotProduct.lean @@ -109,13 +109,13 @@ variable [NoZeroDivisors R] /-- Note that this applies to `ℂ` via `RCLike.toStarOrderedRing`. -/ @[simp] theorem dotProduct_star_self_eq_zero {v : n → R} : dotProduct (star v) v = 0 ↔ v = 0 := - (Fintype.sum_eq_zero_iff_of_nonneg fun i => star_mul_self_nonneg _).trans <| + (Fintype.sum_eq_zero_iff_of_nonneg fun _ => star_mul_self_nonneg _).trans <| by simp [Function.funext_iff, mul_eq_zero] /-- Note that this applies to `ℂ` via `RCLike.toStarOrderedRing`. -/ @[simp] theorem dotProduct_self_star_eq_zero {v : n → R} : dotProduct v (star v) = 0 ↔ v = 0 := - (Fintype.sum_eq_zero_iff_of_nonneg fun i => mul_star_self_nonneg _).trans <| + (Fintype.sum_eq_zero_iff_of_nonneg fun _ => mul_star_self_nonneg _).trans <| by simp [Function.funext_iff, mul_eq_zero] @[simp] diff --git a/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Card.lean b/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Card.lean index d7867798bc310f..413a3c806128d0 100644 --- a/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Card.lean +++ b/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Card.lean @@ -77,7 +77,7 @@ noncomputable def equiv_GL_linearindependent (hn : 0 < n) : rw [← Basis.coePiBasisFun.toMatrix_eq_transpose, ← coe_basisOfLinearIndependentOfCardEqFinrank M.2] exact isUnit_det_of_invertible _ - left_inv := fun x ↦ Units.ext (ext fun i j ↦ rfl) + left_inv := fun _ ↦ Units.ext (ext fun _ _ ↦ rfl) right_inv := by exact congrFun rfl /-- The cardinal of the general linear group over a finite field. -/ diff --git a/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Defs.lean b/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Defs.lean index 5ae49bf1b77c90..da7f4ec7321657 100644 --- a/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Defs.lean +++ b/Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Defs.lean @@ -67,7 +67,7 @@ def det : GL n R →* Rˣ where val_inv := by rw [← det_mul, A.mul_inv, det_one] inv_val := by rw [← det_mul, A.inv_mul, det_one] } map_one' := Units.ext det_one - map_mul' A B := Units.ext <| det_mul _ _ + map_mul' _ _ := Units.ext <| det_mul _ _ /-- The `GL n R` and `Matrix.GeneralLinearGroup R n` groups are multiplicatively equivalent -/ def toLin : GL n R ≃* LinearMap.GeneralLinearGroup R (n → R) := diff --git a/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean b/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean index 261b976d62a387..608958eb28df1a 100644 --- a/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean +++ b/Mathlib/LinearAlgebra/Matrix/SpecialLinearGroup.lean @@ -302,7 +302,7 @@ noncomputable def center_equiv_rootsOfUnity : (fun hn ↦ by rw [center_eq_bot_of_subsingleton, Fintype.card_eq_zero, Nat.toPNat'_zero, rootsOfUnity_one] exact MulEquiv.mulEquivOfUnique) - (fun hn ↦ center_equiv_rootsOfUnity' (Classical.arbitrary n)) + (fun _ ↦ center_equiv_rootsOfUnity' (Classical.arbitrary n)) end center diff --git a/Mathlib/LinearAlgebra/Multilinear/Basic.lean b/Mathlib/LinearAlgebra/Multilinear/Basic.lean index 25022902c14a56..21a0244972b27d 100644 --- a/Mathlib/LinearAlgebra/Multilinear/Basic.lean +++ b/Mathlib/LinearAlgebra/Multilinear/Basic.lean @@ -176,7 +176,7 @@ theorem add_apply (m : ∀ i, M₁ i) : (f + f') m = f m + f' m := rfl instance : Zero (MultilinearMap R M₁ M₂) := - ⟨⟨fun _ => 0, fun _ i _ _ => by simp, fun _ i c _ => by simp⟩⟩ + ⟨⟨fun _ => 0, fun _ _ _ _ => by simp, fun _ _ c _ => by simp⟩⟩ instance : Inhabited (MultilinearMap R M₁ M₂) := ⟨0⟩ @@ -260,7 +260,7 @@ def ofSubsingleton [Subsingleton ι] (i : ι) : { toFun := fun x ↦ f fun _ ↦ x map_add' := fun x y ↦ by simpa [update_eq_const_of_subsingleton] using f.map_add 0 i x y map_smul' := fun c x ↦ by simpa [update_eq_const_of_subsingleton] using f.map_smul 0 i c x } - left_inv f := rfl + left_inv _ := rfl right_inv f := by ext x; refine congr_arg f ?_; exact (eq_const_of_subsingleton _ _).symm variable (M₁) {M₂} @@ -1004,7 +1004,7 @@ sending a multilinear map `g` to `g (f₁ ⬝ , ..., fₙ ⬝ )` is linear in `g @[simps] def compLinearMapMultilinear : @MultilinearMap R ι (fun i ↦ M₁ i →ₗ[R] M₁' i) ((MultilinearMap R M₁' M₂) →ₗ[R] MultilinearMap R M₁ M₂) _ _ _ - (fun i ↦ LinearMap.module) _ where + (fun _ ↦ LinearMap.module) _ where toFun := MultilinearMap.compLinearMapₗ map_add' := by intro _ f i f₁ f₂ @@ -1208,16 +1208,16 @@ theorem sub_apply (m : ∀ i, M₁ i) : (f - g) m = f m - g m := instance : AddCommGroup (MultilinearMap R M₁ M₂) := { MultilinearMap.addCommMonoid with - neg_add_cancel := fun a => MultilinearMap.ext fun v => neg_add_cancel _ - sub_eq_add_neg := fun a b => MultilinearMap.ext fun v => sub_eq_add_neg _ _ + neg_add_cancel := fun _ => MultilinearMap.ext fun _ => neg_add_cancel _ + sub_eq_add_neg := fun _ _ => MultilinearMap.ext fun _ => sub_eq_add_neg _ _ zsmul := fun n f => { toFun := fun m => n • f m map_add' := fun m i x y => by simp [smul_add] map_smul' := fun l i x d => by simp [← smul_comm x n (_ : M₂)] } -- Porting note: changed from `AddCommGroup` to `SubNegMonoid` - zsmul_zero' := fun a => MultilinearMap.ext fun v => SubNegMonoid.zsmul_zero' _ - zsmul_succ' := fun z a => MultilinearMap.ext fun v => SubNegMonoid.zsmul_succ' _ _ - zsmul_neg' := fun z a => MultilinearMap.ext fun v => SubNegMonoid.zsmul_neg' _ _ } + zsmul_zero' := fun _ => MultilinearMap.ext fun _ => SubNegMonoid.zsmul_zero' _ + zsmul_succ' := fun _ _ => MultilinearMap.ext fun _ => SubNegMonoid.zsmul_succ' _ _ + zsmul_neg' := fun _ _ => MultilinearMap.ext fun _ => SubNegMonoid.zsmul_neg' _ _ } end RangeAddCommGroup diff --git a/Mathlib/LinearAlgebra/Pi.lean b/Mathlib/LinearAlgebra/Pi.lean index 18abf808fda35b..89740b2d0a89e1 100644 --- a/Mathlib/LinearAlgebra/Pi.lean +++ b/Mathlib/LinearAlgebra/Pi.lean @@ -63,7 +63,7 @@ theorem pi_eq_zero (f : (i : ι) → M₂ →ₗ[R] φ i) : pi f = 0 ↔ ∀ i, simp only [LinearMap.ext_iff, pi_apply, funext_iff] exact ⟨fun h a b => h b a, fun h a b => h b a⟩ -theorem pi_zero : pi (fun i => 0 : (i : ι) → M₂ →ₗ[R] φ i) = 0 := by ext; rfl +theorem pi_zero : pi (fun _ => 0 : (i : ι) → M₂ →ₗ[R] φ i) = 0 := by ext; rfl theorem pi_comp (f : (i : ι) → M₂ →ₗ[R] φ i) (g : M₃ →ₗ[R] M₂) : (pi f).comp g = pi fun i => (f i).comp g := diff --git a/Mathlib/LinearAlgebra/PiTensorProduct.lean b/Mathlib/LinearAlgebra/PiTensorProduct.lean index 79f7de870e7fd2..051109b80bec88 100644 --- a/Mathlib/LinearAlgebra/PiTensorProduct.lean +++ b/Mathlib/LinearAlgebra/PiTensorProduct.lean @@ -226,14 +226,14 @@ protected theorem smul_add (r : R₁) (x y : ⨂[R] i, s i) : r • (x + y) = r instance distribMulAction' : DistribMulAction R₁ (⨂[R] i, s i) where smul := (· • ·) - smul_add r x y := AddMonoidHom.map_add _ _ _ + smul_add _ _ _ := AddMonoidHom.map_add _ _ _ mul_smul r r' x := PiTensorProduct.induction_on' x (fun {r'' f} ↦ by simp [smul_tprodCoeff', smul_smul]) fun {x y} ihx ihy ↦ by simp_rw [PiTensorProduct.smul_add, ihx, ihy] one_smul x := PiTensorProduct.induction_on' x (fun {r f} ↦ by rw [smul_tprodCoeff', one_smul]) fun {z y} ihz ihy ↦ by simp_rw [PiTensorProduct.smul_add, ihz, ihy] - smul_zero r := AddMonoidHom.map_zero _ + smul_zero _ := AddMonoidHom.map_zero _ instance smulCommClass' [SMulCommClass R₁ R₂ R] : SMulCommClass R₁ R₂ (⨂[R] i, s i) := ⟨fun {r' r''} x ↦ diff --git a/Mathlib/LinearAlgebra/Prod.lean b/Mathlib/LinearAlgebra/Prod.lean index 5c0e7970a23624..c81e4d17cb82ea 100644 --- a/Mathlib/LinearAlgebra/Prod.lean +++ b/Mathlib/LinearAlgebra/Prod.lean @@ -113,8 +113,8 @@ def prodEquiv [Module S M₂] [Module S M₃] [SMulCommClass R S M₂] [SMulComm invFun f := ((fst _ _ _).comp f, (snd _ _ _).comp f) left_inv f := by ext <;> rfl right_inv f := by ext <;> rfl - map_add' a b := rfl - map_smul' r a := rfl + map_add' _ _ := rfl + map_smul' _ _ := rfl section diff --git a/Mathlib/LinearAlgebra/Projectivization/Subspace.lean b/Mathlib/LinearAlgebra/Projectivization/Subspace.lean index c915615a57a835..6bb52dbaf5aa23 100644 --- a/Mathlib/LinearAlgebra/Projectivization/Subspace.lean +++ b/Mathlib/LinearAlgebra/Projectivization/Subspace.lean @@ -96,7 +96,7 @@ def gi : GaloisInsertion (span : Set (ℙ K V) → Subspace K V) SetLike.coe whe assumption · apply B.mem_add assumption'⟩ - le_l_u S := subset_span _ + le_l_u _ := subset_span _ choice_eq _ _ := rfl /-- The span of a subspace is the subspace. -/ @@ -128,7 +128,7 @@ instance : CompleteLattice (Subspace K V) := exact ha hE hx) inf_le_left := fun A B _ hx => (@inf_le_left _ _ A B) hx inf_le_right := fun A B _ hx => (@inf_le_right _ _ A B) hx - le_inf := fun A B _ h1 h2 _ hx => (le_inf h1 h2) hx } + le_inf := fun _ _ _ h1 h2 _ hx => (le_inf h1 h2) hx } instance subspaceInhabited : Inhabited (Subspace K V) where default := ⊤ diff --git a/Mathlib/LinearAlgebra/QuadraticForm/QuadraticModuleCat.lean b/Mathlib/LinearAlgebra/QuadraticForm/QuadraticModuleCat.lean index c0d2eb6ac8a7a3..7e6c8fa28492ed 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/QuadraticModuleCat.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/QuadraticModuleCat.lean @@ -84,7 +84,7 @@ instance concreteCategory : ConcreteCategory.{v} (QuadraticModuleCat.{v} R) wher { obj := fun M => M map := fun f => f.toIsometry } forget_faithful := - { map_injective := fun {M N} => DFunLike.coe_injective.comp <| Hom.toIsometry_injective _ _ } + { map_injective := fun {_ _} => DFunLike.coe_injective.comp <| Hom.toIsometry_injective _ _ } instance hasForgetToModule : HasForget₂ (QuadraticModuleCat R) (ModuleCat R) where forget₂ := diff --git a/Mathlib/LinearAlgebra/QuadraticForm/QuadraticModuleCat/Monoidal.lean b/Mathlib/LinearAlgebra/QuadraticForm/QuadraticModuleCat/Monoidal.lean index f7b52334b71674..d7c1d70ea2269c 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/QuadraticModuleCat/Monoidal.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/QuadraticModuleCat/Monoidal.lean @@ -82,7 +82,7 @@ theorem forget₂_map_associator_inv (X Y Z : QuadraticModuleCat.{u} R) : noncomputable instance instMonoidalCategory : MonoidalCategory (QuadraticModuleCat.{u} R) := Monoidal.induced (forget₂ (QuadraticModuleCat R) (ModuleCat R)) - { μIso := fun X Y => Iso.refl _ + { μIso := fun _ _ => Iso.refl _ εIso := Iso.refl _ leftUnitor_eq := fun X => by simp only [forget₂_obj, forget₂_map, Iso.refl_symm, Iso.trans_assoc, Iso.trans_hom, diff --git a/Mathlib/LinearAlgebra/Quotient.lean b/Mathlib/LinearAlgebra/Quotient.lean index ece10805d55059..9f3e755dd20ebd 100644 --- a/Mathlib/LinearAlgebra/Quotient.lean +++ b/Mathlib/LinearAlgebra/Quotient.lean @@ -470,8 +470,8 @@ and `f : M ≃ₗ N` maps `P` to `Q`, then `M ⧸ P` is equivalent to `N ⧸ Q`. @[simps] 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 = Q) : (M ⧸ P) ≃ₗ[R] N ⧸ Q := - { P.mapQ Q (f : M →ₗ[R] N) fun x hx => hf ▸ Submodule.mem_map_of_mem hx with - toFun := P.mapQ Q (f : M →ₗ[R] N) fun x hx => hf ▸ Submodule.mem_map_of_mem hx + { 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 diff --git a/Mathlib/LinearAlgebra/Ray.lean b/Mathlib/LinearAlgebra/Ray.lean index 547a7c8540f4b8..680c02e7722d3b 100644 --- a/Mathlib/LinearAlgebra/Ray.lean +++ b/Mathlib/LinearAlgebra/Ray.lean @@ -200,7 +200,7 @@ variable (R M) instance RayVector.Setoid : Setoid (RayVector R M) where r x y := SameRay R (x : M) y iseqv := - ⟨fun x => SameRay.refl _, fun h => h.symm, by + ⟨fun _ => SameRay.refl _, fun h => h.symm, by intros x y z hxy hyz exact hxy.trans hyz fun hy => (y.2 hy).elim⟩ diff --git a/Mathlib/LinearAlgebra/Span.lean b/Mathlib/LinearAlgebra/Span.lean index 460f7003ad94ba..eff580c8d6d6d5 100644 --- a/Mathlib/LinearAlgebra/Span.lean +++ b/Mathlib/LinearAlgebra/Span.lean @@ -254,8 +254,8 @@ theorem span_nat_eq (s : AddSubmonoid M) : (span ℕ (s : Set M)).toAddSubmonoid theorem span_int_eq_addSubgroup_closure {M : Type*} [AddCommGroup M] (s : Set M) : (span ℤ s).toAddSubgroup = AddSubgroup.closure s := Eq.symm <| - AddSubgroup.closure_eq_of_le _ subset_span fun x hx => - span_induction hx (fun x hx => AddSubgroup.subset_closure hx) (AddSubgroup.zero_mem _) + AddSubgroup.closure_eq_of_le _ subset_span fun _ hx => + span_induction hx (fun _ hx => AddSubgroup.subset_closure hx) (AddSubgroup.zero_mem _) (fun _ _ => AddSubgroup.add_mem _) fun _ _ _ => AddSubgroup.zsmul_mem _ ‹_› _ @[simp] diff --git a/Mathlib/LinearAlgebra/TensorAlgebra/Basis.lean b/Mathlib/LinearAlgebra/TensorAlgebra/Basis.lean index 24e2067ed86e60..dc1cb2176c8832 100644 --- a/Mathlib/LinearAlgebra/TensorAlgebra/Basis.lean +++ b/Mathlib/LinearAlgebra/TensorAlgebra/Basis.lean @@ -65,7 +65,7 @@ instance instModuleFree [Module.Free R M] : Module.Free R (TensorAlgebra R M) := no zero-divisors. -/ instance instNoZeroDivisors [NoZeroDivisors R] [Module.Free R M] : NoZeroDivisors (TensorAlgebra R M) := - have ⟨⟨κ, b⟩⟩ := ‹Module.Free R M› + have ⟨⟨_, b⟩⟩ := ‹Module.Free R M› (equivFreeAlgebra b).toMulEquiv.noZeroDivisors end CommSemiring diff --git a/Mathlib/LinearAlgebra/TensorPower.lean b/Mathlib/LinearAlgebra/TensorPower.lean index b05bd64ae042db..cf2823fc1606a5 100644 --- a/Mathlib/LinearAlgebra/TensorPower.lean +++ b/Mathlib/LinearAlgebra/TensorPower.lean @@ -197,9 +197,9 @@ theorem mul_assoc {na nb nc} (a : (⨂[R]^na) M) (b : (⨂[R]^nb) M) (c : (⨂[R -- for now we just use the default for the `gnpow` field as it's easier. instance gmonoid : GradedMonoid.GMonoid fun i => ⨂[R]^i M := { TensorPower.gMul, TensorPower.gOne with - one_mul := fun a => gradedMonoid_eq_of_cast (zero_add _) (one_mul _) - mul_one := fun a => gradedMonoid_eq_of_cast (add_zero _) (mul_one _) - mul_assoc := fun a b c => gradedMonoid_eq_of_cast (add_assoc _ _ _) (mul_assoc _ _ _) } + one_mul := fun _ => gradedMonoid_eq_of_cast (zero_add _) (one_mul _) + mul_one := fun _ => gradedMonoid_eq_of_cast (add_zero _) (mul_one _) + mul_assoc := fun _ _ _ => gradedMonoid_eq_of_cast (add_assoc _ _ _) (mul_assoc _ _ _) } /-- The canonical map from `R` to `⨂[R]^0 M` corresponding to the `algebraMap` of the tensor algebra. -/ @@ -229,10 +229,10 @@ theorem algebraMap₀_mul_algebraMap₀ (r s : R) : instance gsemiring : DirectSum.GSemiring fun i => ⨂[R]^i M := { TensorPower.gmonoid with - mul_zero := fun a => LinearMap.map_zero _ - zero_mul := fun b => LinearMap.map_zero₂ _ _ - mul_add := fun a b₁ b₂ => LinearMap.map_add _ _ _ - add_mul := fun a₁ a₂ b => LinearMap.map_add₂ _ _ _ _ + mul_zero := fun _ => LinearMap.map_zero _ + zero_mul := fun _ => LinearMap.map_zero₂ _ _ + mul_add := fun _ _ _ => LinearMap.map_add _ _ _ + add_mul := fun _ _ _ => LinearMap.map_add₂ _ _ _ _ natCast := fun n => algebraMap₀ (n : R) natCast_zero := by simp only [Nat.cast_zero, map_zero] natCast_succ := fun n => by simp only [Nat.cast_succ, map_add, algebraMap₀_one] } diff --git a/Mathlib/LinearAlgebra/TensorProduct/DirectLimit.lean b/Mathlib/LinearAlgebra/TensorProduct/DirectLimit.lean index 76b533c78ac5c2..90eb34ab76c15b 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/DirectLimit.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/DirectLimit.lean @@ -96,7 +96,7 @@ noncomputable def directLimitLeft : noncomputable def directLimitRight : M ⊗[R] DirectLimit G f ≃ₗ[R] DirectLimit (M ⊗[R] G ·) (M ◁ f) := TensorProduct.comm _ _ _ ≪≫ₗ directLimitLeft f M ≪≫ₗ - Module.DirectLimit.congr (fun i ↦ TensorProduct.comm _ _ _) + Module.DirectLimit.congr (fun _ ↦ TensorProduct.comm _ _ _) (fun i j h ↦ TensorProduct.ext <| DFunLike.ext _ _ <| by aesop) @[simp] lemma directLimitRight_tmul_of {i : ι} (m : M) (g : G i) : diff --git a/Mathlib/LinearAlgebra/TensorProduct/Pi.lean b/Mathlib/LinearAlgebra/TensorProduct/Pi.lean index 96a279919c16cc..06c4f31969cbf7 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Pi.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Pi.lean @@ -64,7 +64,7 @@ def piScalarRightInv : (ι → N) →ₗ[S] N ⊗[R] (ι → R) := LinearMap.lsum S (fun _ ↦ N) S <| fun i ↦ { toFun := fun n ↦ n ⊗ₜ Pi.single i 1 map_add' := fun x y ↦ by simp [add_tmul] - map_smul' := fun s x ↦ rfl + map_smul' := fun _ _ ↦ rfl } @[simp] diff --git a/Mathlib/Logic/Equiv/Basic.lean b/Mathlib/Logic/Equiv/Basic.lean index 198c48db494a9a..2176dc8c6d48a0 100644 --- a/Mathlib/Logic/Equiv/Basic.lean +++ b/Mathlib/Logic/Equiv/Basic.lean @@ -484,7 +484,7 @@ def sigmaEquivOptionOfInhabited (α : Type u) [Inhabited α] [DecidableEq α] : snd.left_inv a := by dsimp only; split_ifs <;> simp [*] snd.right_inv | none => by simp - | some ⟨a, ha⟩ => dif_neg ha + | some ⟨_, ha⟩ => dif_neg ha end @@ -600,7 +600,7 @@ 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 ⟨a, h⟩ => dif_pos h⟩ + invFun x := ⟨fun a => if h : p a then x₀ ⟨a, h⟩ else x ⟨a, h⟩, funext fun ⟨_, h⟩ => dif_pos h⟩ left_inv := fun ⟨x, hx⟩ => Subtype.val_injective <| funext fun a => by @@ -817,7 +817,7 @@ section def arrowProdEquivProdArrow (α β γ : Type*) : (γ → α × β) ≃ (γ → α) × (γ → β) where toFun := fun f => (fun c => (f c).1, fun c => (f c).2) invFun := fun p c => (p.1 c, p.2 c) - left_inv := fun f => rfl + left_inv := fun _ => rfl right_inv := fun p => by cases p; rfl open Sum @@ -830,7 +830,7 @@ def sumPiEquivProdPi {ι ι'} (π : ι ⊕ ι' → Type*) : toFun f := ⟨fun i => f (inl i), fun i' => f (inr i')⟩ invFun g := Sum.rec g.1 g.2 left_inv f := by ext (i | i) <;> rfl - right_inv g := Prod.ext rfl rfl + right_inv _ := Prod.ext rfl rfl /-- The equivalence between a product of two dependent functions types and a single dependent function type. Basically a symmetric version of `Equiv.sumPiEquivProdPi`. -/ @@ -1028,7 +1028,7 @@ lemma coe_subtypeEquiv_eq_map {X Y} {p : X → Prop} {q : Y → Prop} (e : X ≃ rfl @[simp] -theorem subtypeEquiv_refl {p : α → Prop} (h : ∀ a, p a ↔ p (Equiv.refl _ a) := fun a => Iff.rfl) : +theorem subtypeEquiv_refl {p : α → Prop} (h : ∀ a, p a ↔ p (Equiv.refl _ a) := fun _ => Iff.rfl) : (Equiv.refl α).subtypeEquiv h = Equiv.refl { a : α // p a } := by ext rfl @@ -1090,7 +1090,7 @@ def subtypeSubtypeEquivSubtypeExists (p : α → Prop) (q : Subtype p → Prop) ⟨a.1, a.1.2, by rcases a with ⟨⟨a, hap⟩, haq⟩ exact haq⟩, - fun a => ⟨⟨a, a.2.fst⟩, a.2.snd⟩, fun ⟨⟨a, ha⟩, h⟩ => rfl, fun ⟨a, h₁, h₂⟩ => rfl⟩ + fun a => ⟨⟨a, a.2.fst⟩, a.2.snd⟩, fun ⟨⟨_, _⟩, _⟩ => rfl, fun ⟨_, _, _⟩ => rfl⟩ /-- A subtype of a subtype is equivalent to the subtype of elements satisfying both predicates. -/ @[simps!] @@ -1166,9 +1166,9 @@ def sigmaOptionEquivOfSome {α} (p : Option α → Type v) (h : p none → False `Sigma` type such that for all `i` we have `(f i).fst = i`. -/ def piEquivSubtypeSigma (ι) (π : ι → Type*) : (∀ i, π i) ≃ { f : ι → Σ i, π i // ∀ i, (f i).1 = i } where - toFun := fun f => ⟨fun i => ⟨i, f i⟩, fun i => rfl⟩ + toFun := fun f => ⟨fun i => ⟨i, f i⟩, fun _ => rfl⟩ invFun := fun f i => by rw [← f.2 i]; exact (f.1 i).2 - left_inv := fun f => funext fun i => rfl + left_inv := fun _ => funext fun _ => rfl right_inv := fun ⟨f, hf⟩ => Subtype.eq <| funext fun i => Sigma.eq (hf i).symm <| eq_of_heq <| rec_heq_of_heq _ <| by simp @@ -1211,7 +1211,7 @@ def subtypeProdEquivSigmaSubtype {α β} (p : α → β → Prop) : toFun x := ⟨x.1.1, x.1.2, x.property⟩ invFun x := ⟨⟨x.1, x.2⟩, x.2.property⟩ left_inv x := by ext <;> rfl - right_inv := fun ⟨a, b, pab⟩ => rfl + right_inv := fun ⟨_, _, _⟩ => rfl /-- The type `∀ (i : α), β i` can be split as a product by separating the indices in `α` depending on whether they satisfy a predicate `p` or not. -/ @@ -1360,11 +1360,11 @@ def subtypeQuotientEquivQuotientSubtype (p₁ : α → Prop) {s₁ : Setoid α} (h : ∀ x y : Subtype p₁, s₂.r x y ↔ s₁.r x y) : {x // p₂ x} ≃ Quotient s₂ where toFun a := Quotient.hrecOn a.1 (fun a h => ⟦⟨a, (hp₂ _).2 h⟩⟧) - (fun a b hab => hfunext (by rw [Quotient.sound hab]) fun h₁ h₂ _ => + (fun a b hab => hfunext (by rw [Quotient.sound hab]) fun _ _ _ => heq_of_eq (Quotient.sound ((h _ _).2 hab))) a.2 invFun a := - Quotient.liftOn a (fun a => (⟨⟦a.1⟧, (hp₂ _).1 a.2⟩ : { x // p₂ x })) fun a b hab => + Quotient.liftOn a (fun a => (⟨⟦a.1⟧, (hp₂ _).1 a.2⟩ : { x // p₂ x })) fun _ _ hab => Subtype.ext_val (Quotient.sound ((h _ _).1 hab)) left_inv := by exact fun ⟨a, ha⟩ => Quotient.inductionOn a (fun b hb => rfl) ha right_inv a := by exact Quotient.inductionOn a fun ⟨a, ha⟩ => rfl diff --git a/Mathlib/Logic/Equiv/Defs.lean b/Mathlib/Logic/Equiv/Defs.lean index 79b92f29b0e1b0..a8fbb1a0ed801f 100644 --- a/Mathlib/Logic/Equiv/Defs.lean +++ b/Mathlib/Logic/Equiv/Defs.lean @@ -534,7 +534,7 @@ def piUnique [Unique α] (β : α → Sort*) : (∀ i, β i) ≃ β default wher toFun f := f default invFun := uniqueElim left_inv f := by ext i; cases Unique.eq_default i; rfl - right_inv x := rfl + right_inv _ := rfl /-- If `α` has a unique term, then the type of function `α → β` is equivalent to `β`. -/ @[simps! (config := .asFn) apply symm_apply] @@ -716,7 +716,7 @@ end variable {p : α → Prop} {q : β → Prop} (e : α ≃ β) protected lemma forall_congr_right : (∀ a, q (e a)) ↔ ∀ b, q b := - ⟨fun h a ↦ by simpa using h (e.symm a), fun h b ↦ h _⟩ + ⟨fun h a ↦ by simpa using h (e.symm a), fun h _ ↦ h _⟩ protected lemma forall_congr_left : (∀ a, p a) ↔ ∀ b, p (e.symm b) := e.symm.forall_congr_right.symm @@ -730,7 +730,7 @@ protected lemma forall_congr' (h : ∀ b, p (e.symm b) ↔ q b) : (∀ a, p a) e.forall_congr_left.trans (by simp [h]) protected lemma exists_congr_right : (∃ a, q (e a)) ↔ ∃ b, q b := - ⟨fun ⟨b, h⟩ ↦ ⟨_, h⟩, fun ⟨a, h⟩ ↦ ⟨e.symm a, by simpa using h⟩⟩ + ⟨fun ⟨_, h⟩ ↦ ⟨_, h⟩, fun ⟨a, h⟩ ↦ ⟨e.symm a, by simpa using h⟩⟩ protected lemma exists_congr_left : (∃ a, p a) ↔ ∃ b, p (e.symm b) := e.symm.exists_congr_right.symm diff --git a/Mathlib/Logic/Equiv/Fin.lean b/Mathlib/Logic/Equiv/Fin.lean index 3453d19eac0205..9a84638f263960 100644 --- a/Mathlib/Logic/Equiv/Fin.lean +++ b/Mathlib/Logic/Equiv/Fin.lean @@ -63,7 +63,7 @@ given by separating out the last element of the tuple. This is `Fin.snoc` as an `Equiv`. -/ @[simps] def snocEquiv (α : Fin (n + 1) → Type*) : α (last n) × (∀ i, α (castSucc i)) ≃ ∀ i, α i where - toFun f i := Fin.snoc f.2 f.1 _ + toFun f _ := Fin.snoc f.2 f.1 _ invFun f := ⟨f _, Fin.init f⟩ left_inv f := by simp right_inv f := by simp @@ -444,7 +444,7 @@ def finProdFinEquiv : Fin m × Fin n ≃ Fin (m * n) where (y.1 + n * x.1) % n = y.1 % n := Nat.add_mul_mod_self_left _ _ _ _ = y.1 := Nat.mod_eq_of_lt y.2 ) - right_inv x := Fin.eq_of_val_eq <| Nat.mod_add_div _ _ + right_inv _ := Fin.eq_of_val_eq <| Nat.mod_add_div _ _ /-- The equivalence induced by `a ↦ (a / n, a % n)` for nonzero `n`. This is like `finProdFinEquiv.symm` but with `m` infinite. @@ -454,7 +454,7 @@ def Nat.divModEquiv (n : ℕ) [NeZero n] : ℕ ≃ ℕ × Fin n where toFun a := (a / n, ↑a) invFun p := p.1 * n + ↑p.2 -- TODO: is there a canonical order of `*` and `+` here? - left_inv a := Nat.div_add_mod' _ _ + left_inv _ := Nat.div_add_mod' _ _ right_inv p := by refine Prod.ext ?_ (Fin.ext <| Nat.mul_add_mod_of_lt p.2.is_lt) dsimp only diff --git a/Mathlib/Logic/Equiv/List.lean b/Mathlib/Logic/Equiv/List.lean index 7a050c68661b55..bf14924bbdaac0 100644 --- a/Mathlib/Logic/Equiv/List.lean +++ b/Mathlib/Logic/Equiv/List.lean @@ -259,11 +259,11 @@ def raise : List ℕ → ℕ → List ℕ | m :: l, n => (m + n) :: raise l (m + n) theorem lower_raise : ∀ l n, lower (raise l n) n = l - | [], n => rfl + | [], _ => rfl | m :: l, n => by rw [raise, lower, Nat.add_sub_cancel_right, lower_raise l] theorem raise_lower : ∀ {l n}, List.Sorted (· ≤ ·) (n :: l) → raise (lower l n) n = l - | [], n, _ => rfl + | [], _, _ => rfl | m :: l, n, h => by have : n ≤ m := List.rel_of_sorted_cons h _ (l.mem_cons_self _) simp [raise, lower, Nat.sub_add_cancel this, raise_lower h.of_cons] @@ -309,11 +309,11 @@ def raise' : List ℕ → ℕ → List ℕ | m :: l, n => (m + n) :: raise' l (m + n + 1) theorem lower_raise' : ∀ l n, lower' (raise' l n) n = l - | [], n => rfl + | [], _ => rfl | m :: l, n => by simp [raise', lower', add_tsub_cancel_right, lower_raise'] theorem raise_lower' : ∀ {l n}, (∀ m ∈ l, n ≤ m) → List.Sorted (· < ·) l → raise' (lower' l n) n = l - | [], n, _, _ => rfl + | [], _, _, _ => rfl | m :: l, n, h₁, h₂ => by have : n ≤ m := h₁ _ (l.mem_cons_self _) simp [raise', lower', Nat.sub_add_cancel this, diff --git a/Mathlib/Logic/Equiv/PartialEquiv.lean b/Mathlib/Logic/Equiv/PartialEquiv.lean index 9dd50be972f0cb..0a231722f6cfac 100644 --- a/Mathlib/Logic/Equiv/PartialEquiv.lean +++ b/Mathlib/Logic/Equiv/PartialEquiv.lean @@ -236,7 +236,7 @@ def _root_.Equiv.toPartialEquivOfImageEq (e : α ≃ β) (s : Set α) (t : Set invFun := e.symm source := s target := t - map_source' x hx := h ▸ mem_image_of_mem _ hx + map_source' _ hx := h ▸ mem_image_of_mem _ hx map_target' x hx := by subst t rcases hx with ⟨x, hx, rfl⟩ @@ -622,32 +622,32 @@ theorem inv_image_trans_target : e'.symm '' (e.trans e').target = e'.source ∩ image_trans_source e'.symm e.symm theorem trans_assoc (e'' : PartialEquiv γ δ) : (e.trans e').trans e'' = e.trans (e'.trans e'') := - PartialEquiv.ext (fun x => rfl) (fun x => rfl) + PartialEquiv.ext (fun _ => rfl) (fun _ => rfl) (by simp [trans_source, @preimage_comp α β γ, inter_assoc]) @[simp, mfld_simps] theorem trans_refl : e.trans (PartialEquiv.refl β) = e := - PartialEquiv.ext (fun x => rfl) (fun x => rfl) (by simp [trans_source]) + PartialEquiv.ext (fun _ => rfl) (fun _ => rfl) (by simp [trans_source]) @[simp, mfld_simps] theorem refl_trans : (PartialEquiv.refl α).trans e = e := - PartialEquiv.ext (fun x => rfl) (fun x => rfl) (by simp [trans_source, preimage_id]) + PartialEquiv.ext (fun _ => rfl) (fun _ => rfl) (by simp [trans_source, preimage_id]) theorem trans_ofSet (s : Set β) : e.trans (ofSet s) = e.restr (e ⁻¹' s) := PartialEquiv.ext (fun _ => rfl) (fun _ => rfl) rfl theorem trans_refl_restr (s : Set β) : e.trans ((PartialEquiv.refl β).restr s) = e.restr (e ⁻¹' s) := - PartialEquiv.ext (fun x => rfl) (fun x => rfl) (by simp [trans_source]) + PartialEquiv.ext (fun _ => rfl) (fun _ => rfl) (by simp [trans_source]) theorem trans_refl_restr' (s : Set β) : e.trans ((PartialEquiv.refl β).restr s) = e.restr (e.source ∩ e ⁻¹' s) := - PartialEquiv.ext (fun x => rfl) (fun x => rfl) <| by + PartialEquiv.ext (fun _ => rfl) (fun _ => rfl) <| by simp only [trans_source, restr_source, refl_source, univ_inter] rw [← inter_assoc, inter_self] theorem restr_trans (s : Set α) : (e.restr s).trans e' = (e.trans e').restr s := - PartialEquiv.ext (fun x => rfl) (fun x => rfl) <| by + PartialEquiv.ext (fun _ => rfl) (fun _ => rfl) <| by simp [trans_source, inter_comm, inter_assoc] /-- A lemma commonly useful when `e` and `e'` are charts of a manifold. -/ @@ -916,7 +916,7 @@ theorem symm_toPartialEquiv : e.symm.toPartialEquiv = e.toPartialEquiv.symm := @[simp, mfld_simps] theorem trans_toPartialEquiv : (e.trans e').toPartialEquiv = e.toPartialEquiv.trans e'.toPartialEquiv := - PartialEquiv.ext (fun x => rfl) (fun x => rfl) + PartialEquiv.ext (fun _ => rfl) (fun _ => rfl) (by simp [PartialEquiv.trans_source, Equiv.toPartialEquiv]) /-- Precompose a partial equivalence with an equivalence. diff --git a/Mathlib/Logic/Equiv/Set.lean b/Mathlib/Logic/Equiv/Set.lean index 660731bfc4b8ab..fb24c904db0686 100644 --- a/Mathlib/Logic/Equiv/Set.lean +++ b/Mathlib/Logic/Equiv/Set.lean @@ -149,8 +149,8 @@ def setProdEquivSigma {α β : Type*} (s : Set (α × β)) : s ≃ Σx : α, { y : β | (x, y) ∈ s } where toFun x := ⟨x.1.1, x.1.2, by simp⟩ invFun x := ⟨(x.1, x.2.1), x.2.2⟩ - left_inv := fun ⟨⟨x, y⟩, h⟩ => rfl - right_inv := fun ⟨x, y, h⟩ => rfl + left_inv := fun ⟨⟨_, _⟩, _⟩ => rfl + right_inv := fun ⟨_, _, _⟩ => rfl /-- The subtypes corresponding to equal sets are equivalent. -/ @[simps! apply] @@ -364,7 +364,7 @@ protected def compl {α : Type u} {β : Type v} {s : Set α} {t : Set β} [Decid [DecidablePred (· ∈ t)] (e₀ : s ≃ t) : { e : α ≃ β // ∀ x : s, e x = e₀ x } ≃ ((sᶜ : Set α) ≃ (tᶜ : Set β)) where toFun e := - subtypeEquiv e fun a => + subtypeEquiv e fun _ => not_congr <| Iff.symm <| MapsTo.mem_iff (mapsTo_iff_exists_map_subtype.2 ⟨e₀, e.2⟩) @@ -478,7 +478,7 @@ def rangeInl (α β : Type*) : Set.range (Sum.inl : α → α ⊕ β) ≃ α whe | ⟨.inr _, h⟩ => False.elim <| by rcases h with ⟨x, h'⟩; cases h' invFun x := ⟨.inl x, mem_range_self _⟩ left_inv := fun ⟨_, _, rfl⟩ => rfl - right_inv x := rfl + right_inv _ := rfl @[simp] lemma rangeInl_apply_inl {α : Type*} (β : Type*) (x : α) : (rangeInl α β) ⟨.inl x, mem_range_self _⟩ = x := @@ -492,7 +492,7 @@ def rangeInr (α β : Type*) : Set.range (Sum.inr : β → α ⊕ β) ≃ β whe | ⟨.inr x, _⟩ => x invFun x := ⟨.inr x, mem_range_self _⟩ left_inv := fun ⟨_, _, rfl⟩ => rfl - right_inv x := rfl + right_inv _ := rfl @[simp] lemma rangeInr_apply_inr (α : Type*) {β : Type*} (x : β) : (rangeInr α β) ⟨.inr x, mem_range_self _⟩ = x := @@ -554,7 +554,7 @@ theorem self_comp_ofInjective_symm {α β} {f : α → β} (hf : Injective f) : theorem ofLeftInverse_eq_ofInjective {α β : Type*} (f : α → β) (f_inv : Nonempty α → β → α) (hf : ∀ h : Nonempty α, LeftInverse (f_inv h) f) : ofLeftInverse f f_inv hf = - ofInjective f ((isEmpty_or_nonempty α).elim (fun h _ _ _ => Subsingleton.elim _ _) + ofInjective f ((isEmpty_or_nonempty α).elim (fun _ _ _ _ => Subsingleton.elim _ _) (fun h => (hf h).injective)) := by ext simp diff --git a/Mathlib/Logic/Equiv/TransferInstance.lean b/Mathlib/Logic/Equiv/TransferInstance.lean index f4afabe33c38e8..e1e5ce7366f083 100644 --- a/Mathlib/Logic/Equiv/TransferInstance.lean +++ b/Mathlib/Logic/Equiv/TransferInstance.lean @@ -133,7 +133,7 @@ on `β` back along `e`. -/ the additive structure on `α` is the one obtained by transporting an additive structure on `β` back along `e`."] def mulEquiv (e : α ≃ β) [Mul β] : - let mul := Equiv.mul e + let _ := Equiv.mul e α ≃* β := by intros exact @@ -343,7 +343,7 @@ protected abbrev addGroupWithOne [AddGroupWithOne β] : AddGroupWithOne α := e.addGroup with intCast := fun n => e.symm n intCast_ofNat := fun n => by simp only [Int.cast_natCast]; rfl - intCast_negSucc := fun n => + intCast_negSucc := fun _ => congr_arg e.symm <| (Int.cast_negSucc _).trans <| congr_arg _ (e.apply_symm_apply _).symm } noncomputable instance [Small.{v} α] [AddGroupWithOne α] : AddGroupWithOne (Shrink.{v} α) := @@ -565,7 +565,7 @@ variable [Semiring R] /-- Transfer `Module` across an `Equiv` -/ protected abbrev module (e : α ≃ β) [AddCommMonoid β] : - let addCommMonoid := Equiv.addCommMonoid e + let _ := Equiv.addCommMonoid e ∀ [Module R β], Module R α := by intros exact @@ -608,7 +608,7 @@ variable [CommSemiring R] /-- Transfer `Algebra` across an `Equiv` -/ protected abbrev algebra (e : α ≃ β) [Semiring β] : - let semiring := Equiv.semiring e + let _ := Equiv.semiring e ∀ [Algebra R β], Algebra R α := by intros letI : Module R α := e.module R @@ -621,8 +621,8 @@ protected abbrev algebra (e : α ≃ β) [Semiring β] : simp only [apply_symm_apply, Algebra.mul_smul_comm] lemma algebraMap_def (e : α ≃ β) [Semiring β] [Algebra R β] (r : R) : - let semiring := Equiv.semiring e - let algebra := Equiv.algebra R e + let _ := Equiv.semiring e + let _ := Equiv.algebra R e (algebraMap R α) r = e.symm ((algebraMap R β) r) := by intros simp only [Algebra.algebraMap_eq_smul_one] diff --git a/Mathlib/Logic/Function/Basic.lean b/Mathlib/Logic/Function/Basic.lean index 1af46bf00e7fa6..131ecb1c0731d4 100644 --- a/Mathlib/Logic/Function/Basic.lean +++ b/Mathlib/Logic/Function/Basic.lean @@ -33,7 +33,7 @@ theorem eval_apply {β : α → Sort*} (x : α) (f : ∀ x, β x) : eval x f = f theorem const_def {y : β} : (fun _ : α ↦ y) = const α y := rfl -theorem const_injective [Nonempty α] : Injective (const α : β → α → β) := fun y₁ y₂ h ↦ +theorem const_injective [Nonempty α] : Injective (const α : β → α → β) := fun _ _ h ↦ let ⟨x⟩ := ‹Nonempty α› congr_fun h x @@ -839,13 +839,13 @@ protected theorem uncurry {α β γ : Type*} {f : α → β → γ} (hf : Inject fun ⟨_, _⟩ ⟨_, _⟩ h ↦ (hf h).elim (congr_arg₂ _) /-- As a map from the left argument to a unary function, `f` is injective. -/ -theorem left' (hf : Injective2 f) [Nonempty β] : Function.Injective f := fun a₁ a₂ h ↦ +theorem left' (hf : Injective2 f) [Nonempty β] : Function.Injective f := fun _ _ h ↦ let ⟨b⟩ := ‹Nonempty β› hf.left b <| (congr_fun h b : _) /-- As a map from the right argument to a unary function, `f` is injective. -/ theorem right' (hf : Injective2 f) [Nonempty α] : Function.Injective fun b a ↦ f a b := - fun b₁ b₂ h ↦ + fun _ _ h ↦ let ⟨a⟩ := ‹Nonempty α› hf.right a <| (congr_fun h a : _) diff --git a/Mathlib/Logic/Relation.lean b/Mathlib/Logic/Relation.lean index 2a90c042f467f9..93afac58af7093 100644 --- a/Mathlib/Logic/Relation.lean +++ b/Mathlib/Logic/Relation.lean @@ -245,7 +245,7 @@ namespace ReflGen theorem to_reflTransGen : ∀ {a b}, ReflGen r a b → ReflTransGen r a b | a, _, refl => by rfl - | a, b, single h => ReflTransGen.tail ReflTransGen.refl h + | _, _, single h => ReflTransGen.tail ReflTransGen.refl h theorem mono {p : α → α → Prop} (hp : ∀ a b, r a b → p a b) : ∀ {a b}, ReflGen r a b → ReflGen p a b | a, _, ReflGen.refl => by rfl diff --git a/Mathlib/MeasureTheory/Category/MeasCat.lean b/Mathlib/MeasureTheory/Category/MeasCat.lean index 02453ff552ced9..0ea23b5368bf10 100644 --- a/Mathlib/MeasureTheory/Category/MeasCat.lean +++ b/Mathlib/MeasureTheory/Category/MeasCat.lean @@ -106,7 +106,7 @@ nicely under the monad operations. -/ def Integral : Giry.Algebra where A := MeasCat.of ℝ≥0∞ a := ⟨fun m : MeasureTheory.Measure ℝ≥0∞ ↦ ∫⁻ x, x ∂m, Measure.measurable_lintegral measurable_id⟩ - unit := Subtype.eq <| funext fun r : ℝ≥0∞ => lintegral_dirac' _ measurable_id + unit := Subtype.eq <| funext fun _ : ℝ≥0∞ => lintegral_dirac' _ measurable_id assoc := Subtype.eq <| funext fun μ : MeasureTheory.Measure (MeasureTheory.Measure ℝ≥0∞) => show ∫⁻ x, x ∂μ.join = ∫⁻ x, x ∂Measure.map (fun m => ∫⁻ x, x ∂m) μ by rw [Measure.lintegral_join, lintegral_map] <;> diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean index b7ac515ab27d02..a09f3bc5eb9bde 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean @@ -266,7 +266,7 @@ theorem IsCompact.nullMeasurableSet [T2Space α] {μ} (h : IsCompact s) : NullMe then they can't be separated by a Borel measurable set. -/ theorem Inseparable.mem_measurableSet_iff {x y : γ} (h : Inseparable x y) {s : Set γ} (hs : MeasurableSet s) : x ∈ s ↔ y ∈ s := - hs.induction_on_open (C := fun s ↦ (x ∈ s ↔ y ∈ s)) (fun _ ↦ h.mem_open_iff) (fun s _ ↦ Iff.not) + hs.induction_on_open (C := fun s ↦ (x ∈ s ↔ y ∈ s)) (fun _ ↦ h.mem_open_iff) (fun _ _ ↦ Iff.not) fun _ _ _ h ↦ by simp [h] /-- If `K` is a compact set in an R₁ space and `s ⊇ K` is a Borel measurable superset, diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Metric.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Metric.lean index 2a7e7bc08abc6e..5e50607338e9b6 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Metric.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Metric.lean @@ -193,7 +193,7 @@ theorem tendsto_measure_cthickening_of_isCompact [MetricSpace α] [MeasurableSpa the borel sets of some second countable t4 topology (i.e. a separable metrizable one). -/ theorem exists_borelSpace_of_countablyGenerated_of_separatesPoints (α : Type*) [m : MeasurableSpace α] [CountablyGenerated α] [SeparatesPoints α] : - ∃ τ : TopologicalSpace α, SecondCountableTopology α ∧ T4Space α ∧ BorelSpace α := by + ∃ _ : TopologicalSpace α, SecondCountableTopology α ∧ T4Space α ∧ BorelSpace α := by rcases measurableEquiv_nat_bool_of_countablyGenerated α with ⟨s, ⟨f⟩⟩ letI := induced f inferInstance let F := f.toEquiv.toHomeomorphOfInducing <| inducing_induced _ @@ -205,7 +205,7 @@ second countable t4 topology on `α` (i.e. a separable metrizable one) for which open set is measurable. -/ theorem exists_opensMeasurableSpace_of_countablySeparated (α : Type*) [m : MeasurableSpace α] [CountablySeparated α] : - ∃ τ : TopologicalSpace α, SecondCountableTopology α ∧ T4Space α ∧ OpensMeasurableSpace α := by + ∃ _ : TopologicalSpace α, SecondCountableTopology α ∧ T4Space α ∧ OpensMeasurableSpace α := by rcases exists_countablyGenerated_le_of_countablySeparated α with ⟨m', _, _, m'le⟩ rcases exists_borelSpace_of_countablyGenerated_of_separatesPoints (m := m') with ⟨τ, _, _, τm'⟩ exact ⟨τ, ‹_›, ‹_›, @OpensMeasurableSpace.mk _ _ m (τm'.measurable_eq.symm.le.trans m'le)⟩ diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean index 4bd14a8a98d53a..1014d372633329 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean @@ -299,7 +299,7 @@ theorem Dense.borel_eq_generateFrom_Ico_mem {α : Type*} [TopologicalSpace α] [ [OrderTopology α] [SecondCountableTopology α] [DenselyOrdered α] [NoMinOrder α] {s : Set α} (hd : Dense s) : borel α = .generateFrom { S : Set α | ∃ l ∈ s, ∃ u ∈ s, l < u ∧ Ico l u = S } := - hd.borel_eq_generateFrom_Ico_mem_aux (by simp) fun x y hxy H => + hd.borel_eq_generateFrom_Ico_mem_aux (by simp) fun _ _ hxy H => ((nonempty_Ioo.2 hxy).ne_empty H).elim theorem borel_eq_generateFrom_Ico (α : Type*) [TopologicalSpace α] [SecondCountableTopology α] @@ -325,7 +325,7 @@ theorem Dense.borel_eq_generateFrom_Ioc_mem {α : Type*} [TopologicalSpace α] [ [OrderTopology α] [SecondCountableTopology α] [DenselyOrdered α] [NoMaxOrder α] {s : Set α} (hd : Dense s) : borel α = .generateFrom { S : Set α | ∃ l ∈ s, ∃ u ∈ s, l < u ∧ Ioc l u = S } := - hd.borel_eq_generateFrom_Ioc_mem_aux (by simp) fun x y hxy H => + hd.borel_eq_generateFrom_Ioc_mem_aux (by simp) fun _ _ hxy H => ((nonempty_Ioo.2 hxy).ne_empty H).elim theorem borel_eq_generateFrom_Ioc (α : Type*) [TopologicalSpace α] [SecondCountableTopology α] @@ -430,7 +430,7 @@ theorem ext_of_Iic {α : Type*} [TopologicalSpace α] {m : MeasurableSpace α} /-- Two finite measures on a Borel space are equal if they agree on all left-closed right-infinite intervals. -/ -theorem ext_of_Ici {α : Type*} [TopologicalSpace α] {m : MeasurableSpace α} +theorem ext_of_Ici {α : Type*} [TopologicalSpace α] {_ : MeasurableSpace α} [SecondCountableTopology α] [LinearOrder α] [OrderTopology α] [BorelSpace α] (μ ν : Measure α) [IsFiniteMeasure μ] (h : ∀ a, μ (Ici a) = ν (Ici a)) : μ = ν := @ext_of_Iic αᵒᵈ _ _ _ _ _ ‹_› _ _ _ h diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean index f15add556e5f0a..c5fadec87d50e1 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean @@ -115,7 +115,7 @@ def finiteSpanningSetsInIooRat (μ : Measure ℝ) [IsLocallyFiniteMeasure μ] : -- TODO: norm_cast fails here? push_cast exact neg_lt_self n.cast_add_one_pos - finite n := measure_Ioo_lt_top + finite _ := measure_Ioo_lt_top spanning := iUnion_eq_univ_iff.2 fun x => ⟨⌊|x|⌋₊, neg_lt.1 ((neg_le_abs x).trans_lt (Nat.lt_floor_add_one _)), diff --git a/Mathlib/MeasureTheory/Constructions/EventuallyMeasurable.lean b/Mathlib/MeasureTheory/Constructions/EventuallyMeasurable.lean index c26b40b3beb7dd..a82d9ab57e4519 100644 --- a/Mathlib/MeasureTheory/Constructions/EventuallyMeasurable.lean +++ b/Mathlib/MeasureTheory/Constructions/EventuallyMeasurable.lean @@ -40,7 +40,7 @@ on `α`, modulo a given σ-filter `l` on `α`. -/ def EventuallyMeasurableSpace (l : Filter α) [CountableInterFilter l] : MeasurableSpace α where MeasurableSet' s := ∃ t, MeasurableSet t ∧ s =ᶠ[l] t measurableSet_empty := ⟨∅, MeasurableSet.empty, EventuallyEq.refl _ _ ⟩ - measurableSet_compl := fun s ⟨t, ht, hts⟩ => ⟨tᶜ, ht.compl, hts.compl⟩ + measurableSet_compl := fun _ ⟨t, ht, hts⟩ => ⟨tᶜ, ht.compl, hts.compl⟩ measurableSet_iUnion s hs := by choose t ht hts using hs exact ⟨⋃ i, t i, MeasurableSet.iUnion ht, EventuallyEq.countable_iUnion hts⟩ diff --git a/Mathlib/MeasureTheory/Constructions/HaarToSphere.lean b/Mathlib/MeasureTheory/Constructions/HaarToSphere.lean index 01b32e29b00eec..c236710f3f0faa 100644 --- a/Mathlib/MeasureTheory/Constructions/HaarToSphere.lean +++ b/Mathlib/MeasureTheory/Constructions/HaarToSphere.lean @@ -97,7 +97,7 @@ and cover the whole open ray `(0, +∞)`. -/ def finiteSpanningSetsIn_volumeIoiPow_range_Iio (n : ℕ) : FiniteSpanningSetsIn (volumeIoiPow n) (range Iio) where set k := Iio ⟨k + 1, mem_Ioi.2 k.cast_add_one_pos⟩ - set_mem k := mem_range_self _ + set_mem _ := mem_range_self _ finite k := by simp [volumeIoiPow_apply_Iio] spanning := iUnion_eq_univ_iff.2 fun x ↦ ⟨⌊x.1⌋₊, Nat.lt_floor_add_one x.1⟩ diff --git a/Mathlib/MeasureTheory/Constructions/Pi.lean b/Mathlib/MeasureTheory/Constructions/Pi.lean index 300e10ce1b53a3..40341ab6df349e 100644 --- a/Mathlib/MeasureTheory/Constructions/Pi.lean +++ b/Mathlib/MeasureTheory/Constructions/Pi.lean @@ -836,7 +836,7 @@ theorem volume_preserving_piFinTwo (α : Fin 2 → Type u) [∀ i, MeasureSpace MeasurePreserving (MeasurableEquiv.piFinTwo α) volume volume := measurePreserving_piFinTwo _ -theorem measurePreserving_finTwoArrow_vec {α : Type u} {m : MeasurableSpace α} (μ ν : Measure α) +theorem measurePreserving_finTwoArrow_vec {α : Type u} {_ : MeasurableSpace α} (μ ν : Measure α) [SigmaFinite μ] [SigmaFinite ν] : MeasurePreserving MeasurableEquiv.finTwoArrow (Measure.pi ![μ, ν]) (μ.prod ν) := haveI : ∀ i, SigmaFinite (![μ, ν] i) := Fin.forall_fin_two.2 ⟨‹_›, ‹_›⟩ diff --git a/Mathlib/MeasureTheory/Covering/Besicovitch.lean b/Mathlib/MeasureTheory/Covering/Besicovitch.lean index 91cc3db5e2be07..1e7a76eadda2d3 100644 --- a/Mathlib/MeasureTheory/Covering/Besicovitch.lean +++ b/Mathlib/MeasureTheory/Covering/Besicovitch.lean @@ -1016,7 +1016,7 @@ forms a Vitali family. This is essentially a restatement of the measurable Besic protected def vitaliFamily (μ : Measure α) [SFinite μ] : VitaliFamily μ where setsAt x := (fun r : ℝ => closedBall x r) '' Ioi (0 : ℝ) measurableSet _ := forall_mem_image.2 fun _ _ ↦ isClosed_ball.measurableSet - nonempty_interior _ := forall_mem_image.2 fun r rpos ↦ + nonempty_interior _ := forall_mem_image.2 fun _ rpos ↦ (nonempty_ball.2 rpos).mono ball_subset_interior_closedBall nontrivial x ε εpos := ⟨closedBall x ε, mem_image_of_mem _ εpos, Subset.rfl⟩ covering := by diff --git a/Mathlib/MeasureTheory/Covering/DensityTheorem.lean b/Mathlib/MeasureTheory/Covering/DensityTheorem.lean index 146d0ba6eff075..d48e5568554620 100644 --- a/Mathlib/MeasureTheory/Covering/DensityTheorem.lean +++ b/Mathlib/MeasureTheory/Covering/DensityTheorem.lean @@ -139,8 +139,8 @@ not required to be fixed. See also `Besicovitch.ae_tendsto_measure_inter_div`. -/ theorem ae_tendsto_measure_inter_div (S : Set α) (K : ℝ) : ∀ᵐ x ∂μ.restrict S, - ∀ {ι : Type*} {l : Filter ι} (w : ι → α) (δ : ι → ℝ) (δlim : Tendsto δ l (𝓝[>] 0)) - (xmem : ∀ᶠ j in l, x ∈ closedBall (w j) (K * δ j)), + ∀ {ι : Type*} {l : Filter ι} (w : ι → α) (δ : ι → ℝ) (_ : Tendsto δ l (𝓝[>] 0)) + (_ : ∀ᶠ j in l, x ∈ closedBall (w j) (K * δ j)), Tendsto (fun j => μ (S ∩ closedBall (w j) (δ j)) / μ (closedBall (w j) (δ j))) l (𝓝 1) := by filter_upwards [(vitaliFamily μ K).ae_tendsto_measure_inter_div S] with x hx ι l w δ δlim xmem using hx.comp (tendsto_closedBall_filterAt μ _ _ δlim xmem) @@ -148,8 +148,8 @@ theorem ae_tendsto_measure_inter_div (S : Set α) (K : ℝ) : ∀ᵐ x ∂μ.res /-- A version of **Lebesgue differentiation theorem** for a sequence of closed balls whose centers are not required to be fixed. -/ theorem ae_tendsto_average_norm_sub {f : α → E} (hf : LocallyIntegrable f μ) (K : ℝ) : ∀ᵐ x ∂μ, - ∀ {ι : Type*} {l : Filter ι} (w : ι → α) (δ : ι → ℝ) (δlim : Tendsto δ l (𝓝[>] 0)) - (xmem : ∀ᶠ j in l, x ∈ closedBall (w j) (K * δ j)), + ∀ {ι : Type*} {l : Filter ι} (w : ι → α) (δ : ι → ℝ) (_ : Tendsto δ l (𝓝[>] 0)) + (_ : ∀ᶠ j in l, x ∈ closedBall (w j) (K * δ j)), Tendsto (fun j => ⨍ y in closedBall (w j) (δ j), ‖f y - f x‖ ∂μ) l (𝓝 0) := by filter_upwards [(vitaliFamily μ K).ae_tendsto_average_norm_sub hf] with x hx ι l w δ δlim xmem using hx.comp (tendsto_closedBall_filterAt μ _ _ δlim xmem) @@ -158,8 +158,8 @@ theorem ae_tendsto_average_norm_sub {f : α → E} (hf : LocallyIntegrable f μ) centers are not required to be fixed. -/ theorem ae_tendsto_average [NormedSpace ℝ E] [CompleteSpace E] {f : α → E} (hf : LocallyIntegrable f μ) (K : ℝ) : ∀ᵐ x ∂μ, - ∀ {ι : Type*} {l : Filter ι} (w : ι → α) (δ : ι → ℝ) (δlim : Tendsto δ l (𝓝[>] 0)) - (xmem : ∀ᶠ j in l, x ∈ closedBall (w j) (K * δ j)), + ∀ {ι : Type*} {l : Filter ι} (w : ι → α) (δ : ι → ℝ) (_ : Tendsto δ l (𝓝[>] 0)) + (_ : ∀ᶠ j in l, x ∈ closedBall (w j) (K * δ j)), Tendsto (fun j => ⨍ y in closedBall (w j) (δ j), f y ∂μ) l (𝓝 (f x)) := by filter_upwards [(vitaliFamily μ K).ae_tendsto_average hf] with x hx ι l w δ δlim xmem using hx.comp (tendsto_closedBall_filterAt μ _ _ δlim xmem) diff --git a/Mathlib/MeasureTheory/Covering/Vitali.lean b/Mathlib/MeasureTheory/Covering/Vitali.lean index fb944ea1501163..817189a085c43e 100644 --- a/Mathlib/MeasureTheory/Covering/Vitali.lean +++ b/Mathlib/MeasureTheory/Covering/Vitali.lean @@ -398,8 +398,8 @@ protected def vitaliFamily [PseudoMetricSpace α] [MeasurableSpace α] [OpensMea VitaliFamily μ where setsAt x := { a | IsClosed a ∧ (interior a).Nonempty ∧ ∃ r, a ⊆ closedBall x r ∧ μ (closedBall x (3 * r)) ≤ C * μ a } - measurableSet x a ha := ha.1.measurableSet - nonempty_interior x a ha := ha.2.1 + measurableSet _ _ ha := ha.1.measurableSet + nonempty_interior _ _ ha := ha.2.1 nontrivial x ε εpos := by obtain ⟨r, μr, rpos, rε⟩ : ∃ r, μ (closedBall x (3 * r)) ≤ C * μ (closedBall x r) ∧ r ∈ Ioc (0 : ℝ) ε := diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean index fd79dc7a0b7771..577dc56ee22e50 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean @@ -457,7 +457,7 @@ theorem setIntegral_condexpIndSMul (hs : MeasurableSet[m] s) (ht : MeasurableSet ∫ a in s, (condexpIndSMul hm ht hμt x) a ∂μ = ∫ a in s, (condexpL2 ℝ ℝ hm (indicatorConstLp 2 ht hμt 1) : α → ℝ) a • x ∂μ := setIntegral_congr_ae (hm s hs) - ((condexpIndSMul_ae_eq_smul hm ht hμt x).mono fun x hx _ => hx) + ((condexpIndSMul_ae_eq_smul hm ht hμt x).mono fun _ hx _ => hx) _ = (∫ a in s, (condexpL2 ℝ ℝ hm (indicatorConstLp 2 ht hμt 1) : α → ℝ) a ∂μ) • x := (integral_smul_const _ x) _ = (μ (t ∩ s)).toReal • x := by rw [setIntegral_condexpL2_indicator hs ht hμs hμt] diff --git a/Mathlib/MeasureTheory/Function/LpOrder.lean b/Mathlib/MeasureTheory/Function/LpOrder.lean index 86290745da5ecc..5a7e13be9a62b3 100644 --- a/Mathlib/MeasureTheory/Function/LpOrder.lean +++ b/Mathlib/MeasureTheory/Function/LpOrder.lean @@ -90,7 +90,7 @@ theorem coeFn_abs (f : Lp E p μ) : ⇑|f| =ᵐ[μ] fun x => |f x| := noncomputable instance instNormedLatticeAddCommGroup [Fact (1 ≤ p)] : NormedLatticeAddCommGroup (Lp E p μ) := { Lp.instLattice, Lp.instNormedAddCommGroup with - add_le_add_left := fun f g => add_le_add_left + add_le_add_left := fun _ _ => add_le_add_left solid := fun f g hfg => by rw [← coeFn_le] at hfg simp_rw [Lp.norm_def, ENNReal.toReal_le_toReal (Lp.eLpNorm_ne_top f) (Lp.eLpNorm_ne_top g)] diff --git a/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean b/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean index fdf5f19ca96be9..883a202727ea9e 100644 --- a/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean +++ b/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean @@ -1113,7 +1113,7 @@ theorem eLpNormEssSup_le_nnreal_smul_eLpNormEssSup_of_ae_le_mul {f : α → F} { (h : ∀ᵐ x ∂μ, ‖f x‖₊ ≤ c * ‖g x‖₊) : eLpNormEssSup f μ ≤ c • eLpNormEssSup g μ := calc essSup (fun x => (‖f x‖₊ : ℝ≥0∞)) μ ≤ essSup (fun x => (↑(c * ‖g x‖₊) : ℝ≥0∞)) μ := - essSup_mono_ae <| h.mono fun x hx => ENNReal.coe_le_coe.mpr hx + essSup_mono_ae <| h.mono fun _ hx => ENNReal.coe_le_coe.mpr hx _ = essSup (fun x => (c * ‖g x‖₊ : ℝ≥0∞)) μ := by simp_rw [ENNReal.coe_mul] _ = c • essSup (fun x => (‖g x‖₊ : ℝ≥0∞)) μ := ENNReal.essSup_const_mul diff --git a/Mathlib/MeasureTheory/Function/LpSpace.lean b/Mathlib/MeasureTheory/Function/LpSpace.lean index 22f250535cb264..12414c825abe8b 100644 --- a/Mathlib/MeasureTheory/Function/LpSpace.lean +++ b/Mathlib/MeasureTheory/Function/LpSpace.lean @@ -406,7 +406,7 @@ instance instNormedAddCommGroup [hp : Fact (1 ≤ p)] : NormedAddCommGroup (Lp E simp only [Lp.nnnorm_coe_ennreal] exact (eLpNorm_congr_ae (AEEqFun.coeFn_add _ _)).trans_le (eLpNorm_add_le (Lp.aestronglyMeasurable _) (Lp.aestronglyMeasurable _) hp.out) - eq_zero_of_map_eq_zero' := fun f => + eq_zero_of_map_eq_zero' := fun _ => (norm_eq_zero_iff <| zero_lt_one.trans_le hp.1).1 } with edist := edist edist_dist := Lp.edist_dist } @@ -1435,8 +1435,8 @@ theorem cauchySeq_Lp_iff_cauchySeq_ℒp {ι} [Nonempty ι] [SemilatticeSup ι] [ theorem completeSpace_lp_of_cauchy_complete_ℒp [hp : Fact (1 ≤ p)] (H : - ∀ (f : ℕ → α → E) (hf : ∀ n, Memℒp (f n) p μ) (B : ℕ → ℝ≥0∞) (hB : ∑' i, B i < ∞) - (h_cau : ∀ N n m : ℕ, N ≤ n → N ≤ m → eLpNorm (f n - f m) p μ < B N), + ∀ (f : ℕ → α → E) (_ : ∀ n, Memℒp (f n) p μ) (B : ℕ → ℝ≥0∞) (_ : ∑' i, B i < ∞) + (_ : ∀ N n m : ℕ, N ≤ n → N ≤ m → eLpNorm (f n - f m) p μ < B N), ∃ (f_lim : α → E), Memℒp f_lim p μ ∧ atTop.Tendsto (fun n => eLpNorm (f n - f_lim) p μ) (𝓝 0)) : CompleteSpace (Lp E p μ) := by diff --git a/Mathlib/MeasureTheory/Function/SimpleFunc.lean b/Mathlib/MeasureTheory/Function/SimpleFunc.lean index ea3760f408df59..267c67d35ba52d 100644 --- a/Mathlib/MeasureTheory/Function/SimpleFunc.lean +++ b/Mathlib/MeasureTheory/Function/SimpleFunc.lean @@ -553,8 +553,8 @@ theorem smul_eq_map [SMul K β] (k : K) (f : α →ₛ β) : k • f = f.map (k instance instPreorder [Preorder β] : Preorder (α →ₛ β) := { SimpleFunc.instLE with - le_refl := fun f a => le_rfl - le_trans := fun f g h hfg hgh a => le_trans (hfg _) (hgh a) } + le_refl := fun _ _ => le_rfl + le_trans := fun _ _ _ hfg hgh a => le_trans (hfg _) (hgh a) } instance instPartialOrder [PartialOrder β] : PartialOrder (α →ₛ β) := { SimpleFunc.instPreorder with @@ -855,8 +855,8 @@ def lintegralₗ {m : MeasurableSpace α} : (α →ₛ ℝ≥0∞) →ₗ[ℝ≥ map_add' := by simp [lintegral, mul_add, Finset.sum_add_distrib] map_smul' := fun c μ => by simp [lintegral, mul_left_comm _ c, Finset.mul_sum, Measure.smul_apply c] } - map_add' f g := LinearMap.ext fun μ => add_lintegral f g - map_smul' c f := LinearMap.ext fun μ => const_mul_lintegral f c + map_add' f g := LinearMap.ext fun _ => add_lintegral f g + map_smul' c f := LinearMap.ext fun _ => const_mul_lintegral f c @[simp] theorem zero_lintegral : (0 : α →ₛ ℝ≥0∞).lintegral μ = 0 := diff --git a/Mathlib/MeasureTheory/Function/UniformIntegrable.lean b/Mathlib/MeasureTheory/Function/UniformIntegrable.lean index 52d0280c4dbba0..cd1ec970e05817 100644 --- a/Mathlib/MeasureTheory/Function/UniformIntegrable.lean +++ b/Mathlib/MeasureTheory/Function/UniformIntegrable.lean @@ -327,7 +327,7 @@ end theorem eLpNorm_indicator_le_of_bound {f : α → β} (hp_top : p ≠ ∞) {ε : ℝ} (hε : 0 < ε) {M : ℝ} (hf : ∀ x, ‖f x‖ < M) : - ∃ (δ : ℝ) (hδ : 0 < δ), ∀ s, MeasurableSet s → + ∃ (δ : ℝ) (_ : 0 < δ), ∀ s, MeasurableSet s → μ s ≤ ENNReal.ofReal δ → eLpNorm (s.indicator f) p μ ≤ ENNReal.ofReal ε := by by_cases hM : M ≤ 0 · refine ⟨1, zero_lt_one, fun s _ _ => ?_⟩ @@ -363,7 +363,7 @@ variable {f : α → β} /-- Auxiliary lemma for `MeasureTheory.Memℒp.eLpNorm_indicator_le`. -/ theorem Memℒp.eLpNorm_indicator_le' (hp_one : 1 ≤ p) (hp_top : p ≠ ∞) (hf : Memℒp f p μ) (hmeas : StronglyMeasurable f) {ε : ℝ} (hε : 0 < ε) : - ∃ (δ : ℝ) (hδ : 0 < δ), ∀ s, MeasurableSet s → μ s ≤ ENNReal.ofReal δ → + ∃ (δ : ℝ) (_ : 0 < δ), ∀ s, MeasurableSet s → μ s ≤ ENNReal.ofReal δ → eLpNorm (s.indicator f) p μ ≤ 2 * ENNReal.ofReal ε := by obtain ⟨M, hMpos, hM⟩ := hf.eLpNorm_indicator_norm_ge_pos_le hmeas hε obtain ⟨δ, hδpos, hδ⟩ := @@ -397,7 +397,7 @@ alias Memℒp.snorm_indicator_le' := Memℒp.eLpNorm_indicator_le' measurability on `f`. -/ theorem Memℒp.eLpNorm_indicator_le_of_meas (hp_one : 1 ≤ p) (hp_top : p ≠ ∞) (hf : Memℒp f p μ) (hmeas : StronglyMeasurable f) {ε : ℝ} (hε : 0 < ε) : - ∃ (δ : ℝ) (hδ : 0 < δ), ∀ s, MeasurableSet s → μ s ≤ ENNReal.ofReal δ → + ∃ (δ : ℝ) (_ : 0 < δ), ∀ s, MeasurableSet s → μ s ≤ ENNReal.ofReal δ → eLpNorm (s.indicator f) p μ ≤ ENNReal.ofReal ε := by obtain ⟨δ, hδpos, hδ⟩ := hf.eLpNorm_indicator_le' hp_one hp_top hmeas (half_pos hε) refine ⟨δ, hδpos, fun s hs hμs => le_trans (hδ s hs hμs) ?_⟩ @@ -410,7 +410,7 @@ alias Memℒp.snorm_indicator_le_of_meas := Memℒp.eLpNorm_indicator_le_of_meas theorem Memℒp.eLpNorm_indicator_le (hp_one : 1 ≤ p) (hp_top : p ≠ ∞) (hf : Memℒp f p μ) {ε : ℝ} (hε : 0 < ε) : - ∃ (δ : ℝ) (hδ : 0 < δ), ∀ s, MeasurableSet s → μ s ≤ ENNReal.ofReal δ → + ∃ (δ : ℝ) (_ : 0 < δ), ∀ s, MeasurableSet s → μ s ≤ ENNReal.ofReal δ → eLpNorm (s.indicator f) p μ ≤ ENNReal.ofReal ε := by have hℒp := hf obtain ⟨⟨f', hf', heq⟩, _⟩ := hf diff --git a/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean b/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean index 10441a23710fa5..2defb3e6bfd2fd 100644 --- a/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean +++ b/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean @@ -344,7 +344,7 @@ theorem AECover.biInter_Ici_aecover [Preorder ι] {φ : ι → Set α} (hφ : AECover μ atTop φ) : AECover μ atTop fun n : ι => ⋂ (k) (_h : k ∈ Ici n), φ k where ae_eventually_mem := hφ.ae_eventually_mem.mono fun x h ↦ by simpa only [mem_iInter, mem_Ici, eventually_forall_ge_atTop] - measurableSet i := .biInter (to_countable _) fun n _ => hφ.measurableSet n + measurableSet _ := .biInter (to_countable _) fun n _ => hφ.measurableSet n end AECoverUnionInterCountable @@ -475,7 +475,7 @@ theorem AECover.integral_tendsto_of_countably_generated [l.IsCountablyGenerated] convert h using 2; rw [integral_indicator (hφ.measurableSet _)] tendsto_integral_filter_of_dominated_convergence (fun x => ‖f x‖) (Eventually.of_forall fun i => hfi.aestronglyMeasurable.indicator <| hφ.measurableSet i) - (Eventually.of_forall fun i => ae_of_all _ fun x => norm_indicator_le_norm_self _ _) hfi.norm + (Eventually.of_forall fun _ => ae_of_all _ fun _ => norm_indicator_le_norm_self _ _) hfi.norm (hφ.ae_tendsto_indicator f) /-- Slight reformulation of diff --git a/Mathlib/MeasureTheory/Integral/Lebesgue.lean b/Mathlib/MeasureTheory/Integral/Lebesgue.lean index e00c2da2c5ee91..ea728df43b1407 100644 --- a/Mathlib/MeasureTheory/Integral/Lebesgue.lean +++ b/Mathlib/MeasureTheory/Integral/Lebesgue.lean @@ -1028,19 +1028,19 @@ theorem lintegral_iInf_ae {f : ℕ → α → ℝ≥0∞} (h_meas : ∀ n, Measu (h_mono : ∀ n : ℕ, f n.succ ≤ᵐ[μ] f n) (h_fin : ∫⁻ a, f 0 a ∂μ ≠ ∞) : ∫⁻ a, ⨅ n, f n a ∂μ = ⨅ n, ∫⁻ a, f n a ∂μ := have fn_le_f0 : ∫⁻ a, ⨅ n, f n a ∂μ ≤ ∫⁻ a, f 0 a ∂μ := - lintegral_mono fun a => iInf_le_of_le 0 le_rfl + lintegral_mono fun _ => iInf_le_of_le 0 le_rfl have fn_le_f0' : ⨅ n, ∫⁻ a, f n a ∂μ ≤ ∫⁻ a, f 0 a ∂μ := iInf_le_of_le 0 le_rfl (ENNReal.sub_right_inj h_fin fn_le_f0 fn_le_f0').1 <| show ∫⁻ a, f 0 a ∂μ - ∫⁻ a, ⨅ n, f n a ∂μ = ∫⁻ a, f 0 a ∂μ - ⨅ n, ∫⁻ a, f n a ∂μ from calc ∫⁻ a, f 0 a ∂μ - ∫⁻ a, ⨅ n, f n a ∂μ = ∫⁻ a, f 0 a - ⨅ n, f n a ∂μ := (lintegral_sub (measurable_iInf h_meas) - (ne_top_of_le_ne_top h_fin <| lintegral_mono fun a => iInf_le _ _) - (ae_of_all _ fun a => iInf_le _ _)).symm - _ = ∫⁻ a, ⨆ n, f 0 a - f n a ∂μ := congr rfl (funext fun a => ENNReal.sub_iInf) + (ne_top_of_le_ne_top h_fin <| lintegral_mono fun _ => iInf_le _ _) + (ae_of_all _ fun _ => iInf_le _ _)).symm + _ = ∫⁻ a, ⨆ n, f 0 a - f n a ∂μ := congr rfl (funext fun _ => ENNReal.sub_iInf) _ = ⨆ n, ∫⁻ a, f 0 a - f n a ∂μ := (lintegral_iSup_ae (fun n => (h_meas 0).sub (h_meas n)) fun n => - (h_mono n).mono fun a ha => tsub_le_tsub le_rfl ha) + (h_mono n).mono fun _ ha => tsub_le_tsub le_rfl ha) _ = ⨆ n, ∫⁻ a, f 0 a ∂μ - ∫⁻ a, f n a ∂μ := (have h_mono : ∀ᵐ a ∂μ, ∀ n : ℕ, f n.succ a ≤ f n a := ae_all_iff.2 h_mono have h_mono : ∀ n, ∀ᵐ a ∂μ, f n a ≤ f 0 a := fun n => @@ -1113,9 +1113,9 @@ theorem lintegral_liminf_le' {f : ℕ → α → ℝ≥0∞} (h_meas : ∀ n, AE ∫⁻ a, liminf (fun n => f n a) atTop ∂μ = ∫⁻ a, ⨆ n : ℕ, ⨅ i ≥ n, f i a ∂μ := by simp only [liminf_eq_iSup_iInf_of_nat] _ = ⨆ n : ℕ, ∫⁻ a, ⨅ i ≥ n, f i a ∂μ := - (lintegral_iSup' (fun n => aemeasurable_biInf _ (to_countable _) (fun i _ ↦ h_meas i)) - (ae_of_all μ fun a n m hnm => iInf_le_iInf_of_subset fun i hi => le_trans hnm hi)) - _ ≤ ⨆ n : ℕ, ⨅ i ≥ n, ∫⁻ a, f i a ∂μ := iSup_mono fun n => le_iInf₂_lintegral _ + (lintegral_iSup' (fun _ => aemeasurable_biInf _ (to_countable _) (fun i _ ↦ h_meas i)) + (ae_of_all μ fun _ _ _ hnm => iInf_le_iInf_of_subset fun _ hi => le_trans hnm hi)) + _ ≤ ⨆ n : ℕ, ⨅ i ≥ n, ∫⁻ a, f i a ∂μ := iSup_mono fun _ => le_iInf₂_lintegral _ _ = atTop.liminf fun n => ∫⁻ a, f n a ∂μ := Filter.liminf_eq_iSup_iInf_of_nat.symm /-- Known as Fatou's lemma -/ @@ -1129,7 +1129,7 @@ theorem limsup_lintegral_le {f : ℕ → α → ℝ≥0∞} (g : α → ℝ≥0 calc limsup (fun n => ∫⁻ a, f n a ∂μ) atTop = ⨅ n : ℕ, ⨆ i ≥ n, ∫⁻ a, f i a ∂μ := limsup_eq_iInf_iSup_of_nat - _ ≤ ⨅ n : ℕ, ∫⁻ a, ⨆ i ≥ n, f i a ∂μ := iInf_mono fun n => iSup₂_lintegral_le _ + _ ≤ ⨅ n : ℕ, ∫⁻ a, ⨆ i ≥ n, f i a ∂μ := iInf_mono fun _ => iSup₂_lintegral_le _ _ = ∫⁻ a, ⨅ n : ℕ, ⨆ i ≥ n, f i a ∂μ := by refine (lintegral_iInf ?_ ?_ ?_).symm · intro n @@ -1149,13 +1149,13 @@ theorem tendsto_lintegral_of_dominated_convergence {F : ℕ → α → ℝ≥0 tendsto_of_le_liminf_of_limsup_le (calc ∫⁻ a, f a ∂μ = ∫⁻ a, liminf (fun n : ℕ => F n a) atTop ∂μ := - lintegral_congr_ae <| h_lim.mono fun a h => h.liminf_eq.symm + lintegral_congr_ae <| h_lim.mono fun _ h => h.liminf_eq.symm _ ≤ liminf (fun n => ∫⁻ a, F n a ∂μ) atTop := lintegral_liminf_le hF_meas ) (calc limsup (fun n : ℕ => ∫⁻ a, F n a ∂μ) atTop ≤ ∫⁻ a, limsup (fun n => F n a) atTop ∂μ := limsup_lintegral_le _ hF_meas h_bound h_fin - _ = ∫⁻ a, f a ∂μ := lintegral_congr_ae <| h_lim.mono fun a h => h.limsup_eq + _ = ∫⁻ a, f a ∂μ := lintegral_congr_ae <| h_lim.mono fun _ h => h.limsup_eq ) /-- Dominated convergence theorem for nonnegative functions which are just almost everywhere diff --git a/Mathlib/MeasureTheory/Integral/SetToL1.lean b/Mathlib/MeasureTheory/Integral/SetToL1.lean index b1c2e325add446..e4fe8a61b787a9 100644 --- a/Mathlib/MeasureTheory/Integral/SetToL1.lean +++ b/Mathlib/MeasureTheory/Integral/SetToL1.lean @@ -96,7 +96,7 @@ namespace FinMeasAdditive variable {β : Type*} [AddCommMonoid β] {T T' : Set α → β} -theorem zero : FinMeasAdditive μ (0 : Set α → β) := fun s t _ _ _ _ _ => by simp +theorem zero : FinMeasAdditive μ (0 : Set α → β) := fun _ _ _ _ _ _ _ => by simp theorem add (hT : FinMeasAdditive μ T) (hT' : FinMeasAdditive μ T') : FinMeasAdditive μ (T + T') := by @@ -192,7 +192,7 @@ theorem eq_zero_of_measure_zero {β : Type*} [NormedAddCommGroup β] {T : Set α refine ((hT.2 s hs (by simp [hs_zero])).trans (le_of_eq ?_)).antisymm (norm_nonneg _) rw [hs_zero, ENNReal.zero_toReal, mul_zero] -theorem eq_zero {β : Type*} [NormedAddCommGroup β] {T : Set α → β} {C : ℝ} {m : MeasurableSpace α} +theorem eq_zero {β : Type*} [NormedAddCommGroup β] {T : Set α → β} {C : ℝ} {_ : MeasurableSpace α} (hT : DominatedFinMeasAdditive (0 : Measure α) T C) {s : Set α} (hs : MeasurableSet s) : T s = 0 := eq_zero_of_measure_zero hT hs (by simp only [Measure.coe_zero, Pi.zero_apply]) @@ -421,7 +421,7 @@ theorem setToSimpleFunc_add (T : Set α → E →L[ℝ] F) (h_add : FinMeasAddit setToSimpleFunc T (f + g) = ∑ x ∈ (pair f g).range, T (pair f g ⁻¹' {x}) (x.fst + x.snd) := by rw [add_eq_map₂, map_setToSimpleFunc T h_add hp_pair]; simp _ = ∑ x ∈ (pair f g).range, (T (pair f g ⁻¹' {x}) x.fst + T (pair f g ⁻¹' {x}) x.snd) := - (Finset.sum_congr rfl fun a _ => ContinuousLinearMap.map_add _ _ _) + (Finset.sum_congr rfl fun _ _ => ContinuousLinearMap.map_add _ _ _) _ = (∑ x ∈ (pair f g).range, T (pair f g ⁻¹' {x}) x.fst) + ∑ x ∈ (pair f g).range, T (pair f g ⁻¹' {x}) x.snd := by rw [Finset.sum_add_distrib] @@ -1637,7 +1637,7 @@ theorem continuous_setToFun_of_dominated (hT : DominatedFinMeasAdditive μ T C) {bound : α → ℝ} (hfs_meas : ∀ x, AEStronglyMeasurable (fs x) μ) (h_bound : ∀ x, ∀ᵐ a ∂μ, ‖fs x a‖ ≤ bound a) (bound_integrable : Integrable bound μ) (h_cont : ∀ᵐ a ∂μ, Continuous fun x => fs x a) : Continuous fun x => setToFun μ T hT (fs x) := - continuous_iff_continuousAt.mpr fun x₀ => + continuous_iff_continuousAt.mpr fun _ => continuousAt_setToFun_of_dominated hT (Eventually.of_forall hfs_meas) (Eventually.of_forall h_bound) ‹_› <| h_cont.mono fun _ => Continuous.continuousAt diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean b/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean index 61c55dee0d6485..573857eeaad279 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean @@ -67,7 +67,7 @@ variable {m m₁ m₂ : MeasurableSpace α} {m' : MeasurableSpace β} {f : α protected def map (f : α → β) (m : MeasurableSpace α) : MeasurableSpace β where MeasurableSet' s := MeasurableSet[m] <| f ⁻¹' s measurableSet_empty := m.measurableSet_empty - measurableSet_compl s hs := m.measurableSet_compl _ hs + measurableSet_compl _ hs := m.measurableSet_compl _ hs measurableSet_iUnion f hf := by simpa only [preimage_iUnion] using m.measurableSet_iUnion _ hf lemma map_def {s : Set β} : MeasurableSet[m.map f] s ↔ MeasurableSet[m] (f ⁻¹' s) := Iff.rfl @@ -85,7 +85,7 @@ theorem map_comp {f : α → β} {g : β → γ} : (m.map f).map g = m.map (g protected def comap (f : α → β) (m : MeasurableSpace β) : MeasurableSpace α where MeasurableSet' s := ∃ s', MeasurableSet[m] s' ∧ f ⁻¹' s' = s measurableSet_empty := ⟨∅, m.measurableSet_empty, rfl⟩ - measurableSet_compl := fun s ⟨s', h₁, h₂⟩ => ⟨s'ᶜ, m.measurableSet_compl _ h₁, h₂ ▸ rfl⟩ + measurableSet_compl := fun _ ⟨s', h₁, h₂⟩ => ⟨s'ᶜ, m.measurableSet_compl _ h₁, h₂ ▸ rfl⟩ measurableSet_iUnion s hs := let ⟨s', hs'⟩ := Classical.axiom_of_choice hs ⟨⋃ i, s' i, m.measurableSet_iUnion _ fun i => (hs' i).left, by simp [hs']⟩ diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean b/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean index 5c9f7d9d195dc8..0a5c5306735ce3 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Defs.lean @@ -418,9 +418,9 @@ theorem measurableSet_bot_iff {s : Set α} : MeasurableSet[⊥] s ↔ s = ∅ { MeasurableSet' := fun s => s = ∅ ∨ s = univ measurableSet_empty := Or.inl rfl measurableSet_compl := by simp (config := { contextual := true }) [or_imp] - measurableSet_iUnion := fun f hf => sUnion_mem_empty_univ (forall_mem_range.2 hf) } + measurableSet_iUnion := fun _ hf => sUnion_mem_empty_univ (forall_mem_range.2 hf) } have : b = ⊥ := - bot_unique fun s hs => + bot_unique fun _ hs => hs.elim (fun s => s.symm ▸ @measurableSet_empty _ ⊥) fun s => s.symm ▸ @MeasurableSet.univ _ ⊥ this ▸ Iff.rfl diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean b/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean index 295f11d4408f21..67ab6dc3c5625b 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean @@ -509,7 +509,7 @@ Measurable version of `Fin.insertNthEquiv`. -/ def piFinSuccAbove {n : ℕ} (α : Fin (n + 1) → Type*) [∀ i, MeasurableSpace (α i)] (i : Fin (n + 1)) : (∀ j, α j) ≃ᵐ α i × ∀ j, α (i.succAbove j) where toEquiv := (Fin.insertNthEquiv α i).symm - measurable_toFun := (measurable_pi_apply i).prod_mk <| measurable_pi_iff.2 fun j => + measurable_toFun := (measurable_pi_apply i).prod_mk <| measurable_pi_iff.2 fun _ => measurable_pi_apply _ measurable_invFun := measurable_pi_iff.2 <| i.forall_iff_succAbove.2 ⟨by simp [measurable_fst], fun j => by simpa using (measurable_pi_apply _).comp measurable_snd⟩ diff --git a/Mathlib/MeasureTheory/Measure/Complex.lean b/Mathlib/MeasureTheory/Measure/Complex.lean index 7ce4fcfe8f6992..35a76272bc537d 100644 --- a/Mathlib/MeasureTheory/Measure/Complex.lean +++ b/Mathlib/MeasureTheory/Measure/Complex.lean @@ -63,7 +63,7 @@ def _root_.MeasureTheory.SignedMeasure.toComplexMeasure (s t : SignedMeasure α) measureOf' i := ⟨s i, t i⟩ empty' := by dsimp only; rw [s.empty, t.empty]; rfl not_measurable' i hi := by dsimp only; rw [s.not_measurable hi, t.not_measurable hi]; rfl - m_iUnion' f hf hfdisj := (Complex.hasSum_iff _ _).2 ⟨s.m_iUnion hf hfdisj, t.m_iUnion hf hfdisj⟩ + m_iUnion' _ hf hfdisj := (Complex.hasSum_iff _ _).2 ⟨s.m_iUnion hf hfdisj, t.m_iUnion hf hfdisj⟩ theorem _root_.MeasureTheory.SignedMeasure.toComplexMeasure_apply {s t : SignedMeasure α} {i : Set α} : s.toComplexMeasure t i = ⟨s i, t i⟩ := rfl diff --git a/Mathlib/MeasureTheory/Measure/Count.lean b/Mathlib/MeasureTheory/Measure/Count.lean index 0383da666916ab..75eef1a163c72e 100644 --- a/Mathlib/MeasureTheory/Measure/Count.lean +++ b/Mathlib/MeasureTheory/Measure/Count.lean @@ -34,7 +34,7 @@ theorem le_count_apply : ∑' _ : s, (1 : ℝ≥0∞) ≤ count s := _ ≤ ∑' i, dirac i s := ENNReal.tsum_le_tsum fun _ => le_dirac_apply _ ≤ count s := le_sum_apply _ _ -theorem count_apply (hs : MeasurableSet s) : count s = ∑' i : s, 1 := by +theorem count_apply (hs : MeasurableSet s) : count s = ∑' _ : s, 1 := by simp only [count, sum_apply, hs, dirac_apply', ← tsum_subtype s (1 : α → ℝ≥0∞), Pi.one_apply] -- @[simp] -- Porting note (#10618): simp can prove this @@ -44,8 +44,8 @@ theorem count_empty : count (∅ : Set α) = 0 := by rw [count_apply MeasurableS theorem count_apply_finset' {s : Finset α} (s_mble : MeasurableSet (s : Set α)) : count (↑s : Set α) = s.card := calc - count (↑s : Set α) = ∑' i : (↑s : Set α), 1 := count_apply s_mble - _ = ∑ i ∈ s, 1 := s.tsum_subtype 1 + count (↑s : Set α) = ∑' _ : (↑s : Set α), 1 := count_apply s_mble + _ = ∑ _ ∈ s, 1 := s.tsum_subtype 1 _ = s.card := by simp @[simp] diff --git a/Mathlib/MeasureTheory/Measure/Hausdorff.lean b/Mathlib/MeasureTheory/Measure/Hausdorff.lean index 2558bd6c6aa54a..fc55f1955171d1 100644 --- a/Mathlib/MeasureTheory/Measure/Hausdorff.lean +++ b/Mathlib/MeasureTheory/Measure/Hausdorff.lean @@ -268,7 +268,7 @@ theorem mono_pre (m : Set X → ℝ≥0∞) {r r' : ℝ≥0∞} (h : r ≤ r') : le_pre.2 fun _ hs => pre_le (hs.trans h) theorem mono_pre_nat (m : Set X → ℝ≥0∞) : Monotone fun k : ℕ => pre m k⁻¹ := - fun k l h => le_pre.2 fun s hs => pre_le (hs.trans <| by simpa) + fun k l h => le_pre.2 fun _ hs => pre_le (hs.trans <| by simpa) theorem tendsto_pre (m : Set X → ℝ≥0∞) (s : Set X) : Tendsto (fun r => pre m r s) (𝓝[>] 0) (𝓝 <| mkMetric' m s) := by diff --git a/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean b/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean index fd684e18cafc6b..1a99901e0a12a5 100644 --- a/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean +++ b/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean @@ -213,9 +213,9 @@ space. The instance is recorded on the type synonym noncomputable instance levyProkhorovDist_pseudoMetricSpace_finiteMeasure : PseudoMetricSpace (LevyProkhorov (FiniteMeasure Ω)) where dist μ ν := levyProkhorovDist μ.toMeasure ν.toMeasure - dist_self μ := levyProkhorovDist_self _ - dist_comm μ ν := levyProkhorovDist_comm _ _ - dist_triangle μ ν κ := levyProkhorovDist_triangle _ _ _ + dist_self _ := levyProkhorovDist_self _ + dist_comm _ _ := levyProkhorovDist_comm _ _ + dist_triangle _ _ _ := levyProkhorovDist_triangle _ _ _ edist_dist μ ν := by simp [← ENNReal.ofReal_coe_nnreal] lemma measure_le_measure_closure_of_levyProkhorovEDist_eq_zero {μ ν : Measure Ω} @@ -258,9 +258,9 @@ furthermore assume that `Ω` is separable. -/ noncomputable instance levyProkhorovDist_pseudoMetricSpace_probabilityMeasure : PseudoMetricSpace (LevyProkhorov (ProbabilityMeasure Ω)) where dist μ ν := levyProkhorovDist μ.toMeasure ν.toMeasure - dist_self μ := levyProkhorovDist_self _ - dist_comm μ ν := levyProkhorovDist_comm _ _ - dist_triangle μ ν κ := levyProkhorovDist_triangle _ _ _ + dist_self _ := levyProkhorovDist_self _ + dist_comm _ _ := levyProkhorovDist_comm _ _ + dist_triangle _ _ _ := levyProkhorovDist_triangle _ _ _ edist_dist μ ν := by simp [← ENNReal.ofReal_coe_nnreal] lemma LevyProkhorov.dist_def (μ ν : LevyProkhorov (ProbabilityMeasure Ω)) : diff --git a/Mathlib/MeasureTheory/Measure/MeasureSpace.lean b/Mathlib/MeasureTheory/Measure/MeasureSpace.lean index 2c1821c1225d6a..2bbeba47597478 100644 --- a/Mathlib/MeasureTheory/Measure/MeasureSpace.lean +++ b/Mathlib/MeasureTheory/Measure/MeasureSpace.lean @@ -904,9 +904,9 @@ theorem measure_toMeasurable_add_inter_right {s t : Set α} (hs : MeasurableSet /-- Measures are partially ordered. -/ instance instPartialOrder [MeasurableSpace α] : PartialOrder (Measure α) where le m₁ m₂ := ∀ s, m₁ s ≤ m₂ s - le_refl m s := le_rfl - le_trans m₁ m₂ m₃ h₁ h₂ s := le_trans (h₁ s) (h₂ s) - le_antisymm m₁ m₂ h₁ h₂ := ext fun s _ => le_antisymm (h₁ s) (h₂ s) + le_refl _ _ := le_rfl + le_trans _ _ _ h₁ h₂ s := le_trans (h₁ s) (h₂ s) + le_antisymm _ _ h₁ h₂ := ext fun s _ => le_antisymm (h₁ s) (h₂ s) theorem toOuterMeasure_le : μ₁.toOuterMeasure ≤ μ₂.toOuterMeasure ↔ μ₁ ≤ μ₂ := .rfl @@ -962,7 +962,7 @@ private theorem measure_sInf_le (h : μ ∈ m) : sInf m ≤ μ := private theorem measure_le_sInf (h : ∀ μ' ∈ m, μ ≤ μ') : μ ≤ sInf m := have : μ.toOuterMeasure ≤ sInf (toOuterMeasure '' m) := - le_sInf <| forall_mem_image.2 fun μ hμ ↦ toOuterMeasure_le.2 <| h _ hμ + le_sInf <| forall_mem_image.2 fun _ hμ ↦ toOuterMeasure_le.2 <| h _ hμ le_iff.2 fun s hs => by rw [sInf_apply hs]; exact this s instance instCompleteSemilatticeInf [MeasurableSpace α] : CompleteSemilatticeInf (Measure α) := @@ -984,7 +984,7 @@ instance instCompleteLattice [MeasurableSpace α] : CompleteLattice (Measure α) else simp_all [Set.not_nonempty_iff_eq_empty] trim_le := le_top }, - le_top := fun μ => toOuterMeasure_le.mp le_top + le_top := fun _ => toOuterMeasure_le.mp le_top bot := 0 bot_le := fun _a _s => bot_le } @@ -1483,7 +1483,7 @@ instance instIsRefl [MeasurableSpace α] : IsRefl (Measure α) (· ≪ ·) := ⟨fun _ => AbsolutelyContinuous.rfl⟩ @[simp] -protected lemma zero (μ : Measure α) : 0 ≪ μ := fun s _ ↦ by simp +protected lemma zero (μ : Measure α) : 0 ≪ μ := fun _ _ ↦ by simp @[trans] protected theorem trans (h1 : μ₁ ≪ μ₂) (h2 : μ₂ ≪ μ₃) : μ₁ ≪ μ₃ := fun _s hs => h1 <| h2 hs @@ -1549,7 +1549,7 @@ lemma absolutelyContinuous_smul {c : ℝ≥0∞} (hc : c ≠ 0) : μ ≪ c • theorem ae_le_iff_absolutelyContinuous : ae μ ≤ ae ν ↔ μ ≪ ν := ⟨fun h s => by rw [measure_zero_iff_ae_nmem, measure_zero_iff_ae_nmem] - exact fun hs => h hs, fun h s hs => h hs⟩ + exact fun hs => h hs, fun h _ hs => h hs⟩ alias ⟨_root_.LE.le.absolutelyContinuous_of_ae, AbsolutelyContinuous.ae_le⟩ := ae_le_iff_absolutelyContinuous @@ -1737,7 +1737,7 @@ end Pointwise /-- The filter of sets `s` such that `sᶜ` has finite measure. -/ def cofinite {m0 : MeasurableSpace α} (μ : Measure α) : Filter α := - comk (μ · < ∞) (by simp) (fun t ht s hs ↦ (measure_mono hs).trans_lt ht) fun s hs t ht ↦ + comk (μ · < ∞) (by simp) (fun _ ht _ hs ↦ (measure_mono hs).trans_lt ht) fun s hs t ht ↦ (measure_union_le s t).trans_lt <| ENNReal.add_lt_top.2 ⟨hs, ht⟩ theorem mem_cofinite : s ∈ μ.cofinite ↔ μ sᶜ < ∞ := diff --git a/Mathlib/MeasureTheory/Measure/NullMeasurable.lean b/Mathlib/MeasureTheory/Measure/NullMeasurable.lean index 3f2767ff07960a..6e3eb67afb0196 100644 --- a/Mathlib/MeasureTheory/Measure/NullMeasurable.lean +++ b/Mathlib/MeasureTheory/Measure/NullMeasurable.lean @@ -401,7 +401,7 @@ namespace Measure def completion {_ : MeasurableSpace α} (μ : Measure α) : MeasureTheory.Measure (NullMeasurableSpace α μ) where toOuterMeasure := μ.toOuterMeasure - m_iUnion s hs hd := measure_iUnion₀ (hd.mono fun i j h => h.aedisjoint) hs + m_iUnion _ hs hd := measure_iUnion₀ (hd.mono fun _ _ h => h.aedisjoint) hs trim_le := by nth_rewrite 2 [← μ.trimmed] exact OuterMeasure.trim_anti_measurableSpace _ fun _ ↦ MeasurableSet.nullMeasurableSet diff --git a/Mathlib/MeasureTheory/Measure/Stieltjes.lean b/Mathlib/MeasureTheory/Measure/Stieltjes.lean index 841b773d2cd9d0..1e25364777f6e7 100644 --- a/Mathlib/MeasureTheory/Measure/Stieltjes.lean +++ b/Mathlib/MeasureTheory/Measure/Stieltjes.lean @@ -136,7 +136,7 @@ at `x` is a Stieltjes function, i.e., it is monotone and right-continuous. -/ noncomputable def _root_.Monotone.stieltjesFunction {f : ℝ → ℝ} (hf : Monotone f) : StieltjesFunction where toFun := rightLim f - mono' x y hxy := hf.rightLim hxy + mono' _ _ hxy := hf.rightLim hxy right_continuous' := by intro x s hs obtain ⟨l, u, hlu, lus⟩ : ∃ l u : ℝ, rightLim f x ∈ Ioo l u ∧ Ioo l u ⊆ s := diff --git a/Mathlib/MeasureTheory/Measure/Typeclasses.lean b/Mathlib/MeasureTheory/Measure/Typeclasses.lean index df7f1022fa796c..fb5f43b48b9f27 100644 --- a/Mathlib/MeasureTheory/Measure/Typeclasses.lean +++ b/Mathlib/MeasureTheory/Measure/Typeclasses.lean @@ -642,11 +642,11 @@ theorem SigmaFinite.out (h : SigmaFinite μ) : Nonempty (μ.FiniteSpanningSetsIn def Measure.toFiniteSpanningSetsIn (μ : Measure α) [h : SigmaFinite μ] : μ.FiniteSpanningSetsIn { s | MeasurableSet s } where set n := toMeasurable μ (h.out.some.set n) - set_mem n := measurableSet_toMeasurable _ _ + set_mem _ := measurableSet_toMeasurable _ _ finite n := by rw [measure_toMeasurable] exact h.out.some.finite n - spanning := eq_univ_of_subset (iUnion_mono fun n => subset_toMeasurable _ _) h.out.some.spanning + spanning := eq_univ_of_subset (iUnion_mono fun _ => subset_toMeasurable _ _) h.out.some.spanning /-- 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 @@ -1445,7 +1445,7 @@ theorem exists_open_superset_measure_lt_top (h : IsCompact s) (μ : Measure α) theorem measure_lt_top_of_nhdsWithin (h : IsCompact s) (hμ : ∀ x ∈ s, μ.FiniteAtFilter (𝓝[s] x)) : μ s < ∞ := - IsCompact.induction_on h (by simp) (fun s t hst ht => (measure_mono hst).trans_lt ht) + IsCompact.induction_on h (by simp) (fun _ _ hst ht => (measure_mono hst).trans_lt ht) (fun s t hs ht => (measure_union_le s t).trans_lt (ENNReal.add_lt_top.2 ⟨hs, ht⟩)) hμ theorem measure_zero_of_nhdsWithin (hs : IsCompact s) : diff --git a/Mathlib/MeasureTheory/Measure/VectorMeasure.lean b/Mathlib/MeasureTheory/Measure/VectorMeasure.lean index 50bf902e8d3cff..7a254f9b3708c4 100644 --- a/Mathlib/MeasureTheory/Measure/VectorMeasure.lean +++ b/Mathlib/MeasureTheory/Measure/VectorMeasure.lean @@ -237,7 +237,7 @@ def add (v w : VectorMeasure α M) : VectorMeasure α M where measureOf' := v + w empty' := by simp not_measurable' _ hi := by rw [Pi.add_apply, v.not_measurable hi, w.not_measurable hi, add_zero] - m_iUnion' f hf₁ hf₂ := HasSum.add (v.m_iUnion hf₁ hf₂) (w.m_iUnion hf₁ hf₂) + m_iUnion' _ hf₁ hf₂ := HasSum.add (v.m_iUnion hf₁ hf₂) (w.m_iUnion hf₁ hf₂) instance instAdd : Add (VectorMeasure α M) := ⟨add⟩ @@ -268,7 +268,7 @@ def neg (v : VectorMeasure α M) : VectorMeasure α M where measureOf' := -v empty' := by simp not_measurable' _ hi := by rw [Pi.neg_apply, neg_eq_zero, v.not_measurable hi] - m_iUnion' f hf₁ hf₂ := HasSum.neg <| v.m_iUnion hf₁ hf₂ + m_iUnion' _ hf₁ hf₂ := HasSum.neg <| v.m_iUnion hf₁ hf₂ instance instNeg : Neg (VectorMeasure α M) := ⟨neg⟩ @@ -283,7 +283,7 @@ def sub (v w : VectorMeasure α M) : VectorMeasure α M where measureOf' := v - w empty' := by simp not_measurable' _ hi := by rw [Pi.sub_apply, v.not_measurable hi, w.not_measurable hi, sub_zero] - m_iUnion' f hf₁ hf₂ := HasSum.sub (v.m_iUnion hf₁ hf₂) (w.m_iUnion hf₁ hf₂) + m_iUnion' _ hf₁ hf₂ := HasSum.sub (v.m_iUnion hf₁ hf₂) (w.m_iUnion hf₁ hf₂) instance instSub : Sub (VectorMeasure α M) := ⟨sub⟩ @@ -462,7 +462,7 @@ 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 i hi => if_neg hi + not_measurable' := fun _ hi => if_neg hi m_iUnion' := by intro g hg₁ hg₂ simp only @@ -500,7 +500,7 @@ def mapRange (v : VectorMeasure α M) (f : M →+ N) (hf : Continuous f) : Vecto measureOf' s := f (v s) empty' := by simp only; rw [empty, AddMonoidHom.map_zero] not_measurable' i hi := by simp only; rw [not_measurable v hi, AddMonoidHom.map_zero] - m_iUnion' g hg₁ hg₂ := HasSum.map (v.m_iUnion hg₁ hg₂) f hf + m_iUnion' _ hg₁ hg₂ := HasSum.map (v.m_iUnion hg₁ hg₂) f hf @[simp] theorem mapRange_apply {f : M →+ N} (hf : Continuous f) {s : Set α} : v.mapRange f hf s = f (v s) := @@ -561,7 +561,7 @@ def restrict (v : VectorMeasure α M) (i : Set α) : VectorMeasure α M := if hi : MeasurableSet i then { measureOf' := fun s => if MeasurableSet s then v (s ∩ i) else 0 empty' := by simp - not_measurable' := fun i hi => if_neg hi + not_measurable' := fun _ hi => if_neg hi m_iUnion' := by intro f hf₁ hf₂ simp only @@ -694,9 +694,9 @@ variable {M : Type*} [TopologicalSpace M] [AddCommMonoid M] [PartialOrder M] This definition is consistent with `Measure.instPartialOrder`. -/ instance instPartialOrder : PartialOrder (VectorMeasure α M) where le v w := ∀ i, MeasurableSet i → v i ≤ w i - le_refl v i _ := le_rfl - le_trans u v w h₁ h₂ i hi := le_trans (h₁ i hi) (h₂ i hi) - le_antisymm v w h₁ h₂ := ext fun i hi => le_antisymm (h₁ i hi) (h₂ i hi) + le_refl _ _ _ := le_rfl + le_trans _ _ _ h₁ h₂ i hi := le_trans (h₁ i hi) (h₂ i hi) + le_antisymm _ _ h₁ h₂ := ext fun i hi => le_antisymm (h₁ i hi) (h₂ i hi) variable {u v w : VectorMeasure α M} diff --git a/Mathlib/MeasureTheory/Measure/WithDensity.lean b/Mathlib/MeasureTheory/Measure/WithDensity.lean index c6f8473cff0f9c..f7b67208ce3065 100644 --- a/Mathlib/MeasureTheory/Measure/WithDensity.lean +++ b/Mathlib/MeasureTheory/Measure/WithDensity.lean @@ -32,7 +32,7 @@ variable {α : Type*} {m0 : MeasurableSpace α} {μ : Measure α} measure such that for a measurable set `s` we have `μ.withDensity f s = ∫⁻ a in s, f a ∂μ`. -/ noncomputable def Measure.withDensity {m : MeasurableSpace α} (μ : Measure α) (f : α → ℝ≥0∞) : Measure α := - Measure.ofMeasurable (fun s _ => ∫⁻ a in s, f a ∂μ) (by simp) fun s hs hd => + Measure.ofMeasurable (fun s _ => ∫⁻ a in s, f a ∂μ) (by simp) fun _ hs hd => lintegral_iUnion hs hd _ @[simp] diff --git a/Mathlib/MeasureTheory/Measure/WithDensityVectorMeasure.lean b/Mathlib/MeasureTheory/Measure/WithDensityVectorMeasure.lean index 91e480a646863b..674e34c9ca6f39 100644 --- a/Mathlib/MeasureTheory/Measure/WithDensityVectorMeasure.lean +++ b/Mathlib/MeasureTheory/Measure/WithDensityVectorMeasure.lean @@ -42,7 +42,7 @@ 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 s hs => if_neg hs + not_measurable' := fun _ hs => if_neg hs m_iUnion' := fun s hs₁ hs₂ => by dsimp only convert hasSum_integral_iUnion hs₁ hs₂ hf.integrableOn with n diff --git a/Mathlib/MeasureTheory/OuterMeasure/OfFunction.lean b/Mathlib/MeasureTheory/OuterMeasure/OfFunction.lean index 7e859de1147fce..ac7e4d2a1aacab 100644 --- a/Mathlib/MeasureTheory/OuterMeasure/OfFunction.lean +++ b/Mathlib/MeasureTheory/OuterMeasure/OfFunction.lean @@ -57,7 +57,7 @@ protected def ofFunction (m : Set α → ℝ≥0∞) (m_empty : m ∅ = 0) : Out le_antisymm ((iInf_le_of_le fun _ => ∅) <| iInf_le_of_le (empty_subset _) <| by simp [m_empty]) (zero_le _) - mono := fun {s₁ s₂} hs => iInf_mono fun f => iInf_mono' fun hb => ⟨hs.trans hb, le_rfl⟩ + mono := fun {_ _} hs => iInf_mono fun _ => iInf_mono' fun hb => ⟨hs.trans hb, le_rfl⟩ iUnion_nat := fun s _ => ENNReal.le_of_forall_pos_le_add <| by intro ε hε (hb : (∑' i, μ (s i)) < ∞) diff --git a/Mathlib/MeasureTheory/OuterMeasure/Operations.lean b/Mathlib/MeasureTheory/OuterMeasure/Operations.lean index 7dba544ed01e37..5362183b1260a5 100644 --- a/Mathlib/MeasureTheory/OuterMeasure/Operations.lean +++ b/Mathlib/MeasureTheory/OuterMeasure/Operations.lean @@ -38,7 +38,7 @@ instance instZero : Zero (OuterMeasure α) := ⟨{ measureOf := fun _ => 0 empty := rfl mono := by intro _ _ _; exact le_refl 0 - iUnion_nat := fun s _ => zero_le _ }⟩ + iUnion_nat := fun _ _ => zero_le _ }⟩ @[simp] theorem coe_zero : ⇑(0 : OuterMeasure α) = 0 := @@ -51,7 +51,7 @@ instance instAdd : Add (OuterMeasure α) := ⟨fun m₁ m₂ => { measureOf := fun s => m₁ s + m₂ s empty := show m₁ ∅ + m₂ ∅ = 0 by simp [OuterMeasure.empty] - mono := fun {s₁ s₂} h => add_le_add (m₁.mono h) (m₂.mono h) + mono := fun {_ _} h => add_le_add (m₁.mono h) (m₂.mono h) iUnion_nat := fun s _ => calc m₁ (⋃ i, s i) + m₂ (⋃ i, s i) ≤ (∑' i, m₁ (s i)) + ∑' i, m₂ (s i) := @@ -135,9 +135,9 @@ theorem coe_bot : (⊥ : OuterMeasure α) = 0 := instance instPartialOrder : PartialOrder (OuterMeasure α) where le m₁ m₂ := ∀ s, m₁ s ≤ m₂ s - le_refl a s := le_rfl - le_trans a b c hab hbc s := le_trans (hab s) (hbc s) - le_antisymm a b hab hba := ext fun s => le_antisymm (hab s) (hba s) + le_refl _ _ := le_rfl + le_trans _ _ _ hab hbc s := le_trans (hab s) (hbc s) + le_antisymm _ _ hab hba := ext fun s => le_antisymm (hab s) (hba s) instance orderBot : OrderBot (OuterMeasure α) := { bot := 0, @@ -152,7 +152,7 @@ instance instSupSet : SupSet (OuterMeasure α) := ⟨fun ms => { measureOf := fun s => ⨆ m ∈ ms, (m : OuterMeasure α) s empty := nonpos_iff_eq_zero.1 <| iSup₂_le fun m _ => le_of_eq m.empty - mono := fun {s₁ s₂} hs => iSup₂_mono fun m _ => m.mono hs + mono := fun {_ _} hs => iSup₂_mono fun m _ => m.mono hs iUnion_nat := fun f _ => iSup₂_le fun m hm => calc @@ -164,7 +164,7 @@ instance instSupSet : SupSet (OuterMeasure α) := instance instCompleteLattice : CompleteLattice (OuterMeasure α) := { OuterMeasure.orderBot, completeLatticeOfSup (OuterMeasure α) fun ms => - ⟨fun m hm s => by apply le_iSup₂ m hm, fun m hm s => iSup₂_le fun m' hm' => hm hm' s⟩ with } + ⟨fun m hm s => by apply le_iSup₂ m hm, fun _ hm s => iSup₂_le fun _ hm' => hm hm' s⟩ with } @[simp] theorem sSup_apply (ms : Set (OuterMeasure α)) (s : Set α) : @@ -200,10 +200,10 @@ def map {β} (f : α → β) : OuterMeasure α →ₗ[ℝ≥0∞] OuterMeasure toFun m := { measureOf := fun s => m (f ⁻¹' s) empty := m.empty - mono := fun {s t} h => m.mono (preimage_mono h) + mono := fun {_ _} h => m.mono (preimage_mono h) iUnion_nat := fun s _ => by simpa using measure_iUnion_le fun i => f ⁻¹' s i } - map_add' m₁ m₂ := coe_fn_injective rfl - map_smul' c m := coe_fn_injective rfl + map_add' _ _ := coe_fn_injective rfl + map_smul' _ _ := coe_fn_injective rfl @[simp] theorem map_apply {β} (f : α → β) (m : OuterMeasure α) (s : Set β) : map f m s = m (f ⁻¹' s) := @@ -237,7 +237,7 @@ instance instLawfulFunctor : LawfulFunctor OuterMeasure := by constructor <;> in def dirac (a : α) : OuterMeasure α where measureOf s := indicator s (fun _ => 1) a empty := by simp - mono {s t} h := indicator_le_indicator_of_subset h (fun _ => zero_le _) a + mono {_ _} h := indicator_le_indicator_of_subset h (fun _ => zero_le _) a iUnion_nat s _ := calc indicator (⋃ n, s n) 1 a = ⨆ n, indicator (s n) 1 a := indicator_iUnion_apply (M := ℝ≥0∞) rfl _ _ _ @@ -251,7 +251,7 @@ theorem dirac_apply (a : α) (s : Set α) : dirac a s = indicator s (fun _ => 1) def sum {ι} (f : ι → OuterMeasure α) : OuterMeasure α where measureOf s := ∑' i, f i s empty := by simp - mono {s t} h := ENNReal.tsum_le_tsum fun i => measure_mono h + mono {_ _} h := ENNReal.tsum_le_tsum fun _ => measure_mono h iUnion_nat s _ := by rw [ENNReal.tsum_comm]; exact ENNReal.tsum_le_tsum fun i => measure_iUnion_le _ @@ -268,10 +268,10 @@ def comap {β} (f : α → β) : OuterMeasure β →ₗ[ℝ≥0∞] OuterMeasure toFun m := { measureOf := fun s => m (f '' s) empty := by simp - mono := fun {s t} h => m.mono <| image_subset f h + mono := fun {_ _} h => m.mono <| image_subset f h iUnion_nat := fun s _ => by simpa only [image_iUnion] using measure_iUnion_le _ } - map_add' m₁ m₂ := rfl - map_smul' c m := rfl + map_add' _ _ := rfl + map_smul' _ _ := rfl @[simp] theorem comap_apply {β} (f : α → β) (m : OuterMeasure β) (s : Set α) : comap f m s = m (f '' s) := @@ -341,7 +341,7 @@ 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) -theorem top_apply' (s : Set α) : (⊤ : OuterMeasure α) s = ⨅ h : s = ∅, 0 := +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] @[simp] diff --git a/Mathlib/MeasureTheory/PiSystem.lean b/Mathlib/MeasureTheory/PiSystem.lean index aed108095fc155..fdcbf376f1d779 100644 --- a/Mathlib/MeasureTheory/PiSystem.lean +++ b/Mathlib/MeasureTheory/PiSystem.lean @@ -540,9 +540,9 @@ theorem le_def {α} {a b : DynkinSystem α} : a ≤ b ↔ a.Has ≤ b.Has := instance : PartialOrder (DynkinSystem α) := { DynkinSystem.instLEDynkinSystem with - le_refl := fun a b => le_rfl - le_trans := fun a b c hab hbc => le_def.mpr (le_trans hab hbc) - le_antisymm := fun a b h₁ h₂ => ext fun s => ⟨h₁ s, h₂ s⟩ } + le_refl := fun _ _ => le_rfl + le_trans := fun _ _ _ hab hbc => le_def.mpr (le_trans hab hbc) + le_antisymm := fun _ _ h₁ h₂ => ext fun s => ⟨h₁ s, h₂ s⟩ } /-- Every measurable space (σ-algebra) forms a Dynkin system -/ def ofMeasurableSpace (m : MeasurableSpace α) : DynkinSystem α where @@ -588,7 +588,7 @@ def toMeasurableSpace (h_inter : ∀ s₁ s₂, d.Has s₁ → d.Has s₂ → d. MeasurableSpace α where MeasurableSet' := d.Has measurableSet_empty := d.has_empty - measurableSet_compl s h := d.has_compl h + measurableSet_compl _ h := d.has_compl h measurableSet_iUnion f hf := by rw [← iUnion_disjointed] exact @@ -647,7 +647,7 @@ theorem generate_inter {s : Set (Set α)} (hs : IsPiSystem s) {t₁ t₂ : Set additionally that it is non-empty, but we drop this condition in the formalization). -/ theorem generateFrom_eq {s : Set (Set α)} (hs : IsPiSystem s) : - generateFrom s = (generate s).toMeasurableSpace fun t₁ t₂ => generate_inter hs := + generateFrom s = (generate s).toMeasurableSpace fun _ _ => generate_inter hs := le_antisymm (generateFrom_le fun t ht => GenerateHas.basic t ht) (ofMeasurableSpace_le_ofMeasurableSpace_iff.mp <| by rw [ofMeasurableSpace_toMeasurableSpace] diff --git a/Mathlib/MeasureTheory/SetSemiring.lean b/Mathlib/MeasureTheory/SetSemiring.lean index 0727d10d8f8f52..9df3fa00df0489 100644 --- a/Mathlib/MeasureTheory/SetSemiring.lean +++ b/Mathlib/MeasureTheory/SetSemiring.lean @@ -291,7 +291,7 @@ lemma inter_mem (hC : IsSetRing C) (hs : s ∈ C) (ht : t ∈ C) : s ∩ t ∈ C lemma isSetSemiring (hC : IsSetRing C) : IsSetSemiring C where empty_mem := hC.empty_mem - inter_mem := fun s hs t ht => hC.inter_mem hs ht + inter_mem := fun _ hs _ ht => hC.inter_mem hs ht diff_eq_sUnion' := by refine fun s hs t ht => ⟨{s \ t}, ?_, ?_, ?_⟩ · simp only [coe_singleton, Set.singleton_subset_iff] diff --git a/Mathlib/ModelTheory/DirectLimit.lean b/Mathlib/ModelTheory/DirectLimit.lean index 3a743588786600..496585e0014ae5 100644 --- a/Mathlib/ModelTheory/DirectLimit.lean +++ b/Mathlib/ModelTheory/DirectLimit.lean @@ -72,7 +72,7 @@ theorem coe_natLERec (m n : ℕ) (h : m ≤ n) : Embedding.comp_apply, ih] instance natLERec.directedSystem : DirectedSystem G' fun i j h => natLERec f' i j h := - ⟨fun i x _ => congr (congr rfl (Nat.leRecOn_self _)) rfl, + ⟨fun _ _ _ => congr (congr rfl (Nat.leRecOn_self _)) rfl, fun hij hjk => by simp [Nat.leRecOn_trans hij hjk]⟩ end DirectedSystem @@ -104,7 +104,7 @@ variable [DirectedSystem G fun i j h => f i j h] @[simp] theorem unify_sigma_mk_self {α : Type*} {i : ι} {x : α → G i} : - (unify f (fun a => .mk f i (x a)) i fun j ⟨a, hj⟩ => + (unify f (fun a => .mk f i (x a)) i fun _ ⟨_, hj⟩ => _root_.trans (le_of_eq hj.symm) (refl _)) = x := by ext a rw [unify] @@ -127,7 +127,7 @@ namespace DirectLimit def setoid [DirectedSystem G fun i j h => f i j h] [IsDirected ι (· ≤ ·)] : Setoid (Σˣ f) where r := fun ⟨i, x⟩ ⟨j, y⟩ => ∃ (k : ι) (ik : i ≤ k) (jk : j ≤ k), f i k ik x = f j k jk y iseqv := - ⟨fun ⟨i, x⟩ => ⟨i, refl i, refl i, rfl⟩, @fun ⟨i, x⟩ ⟨j, y⟩ ⟨k, ik, jk, h⟩ => + ⟨fun ⟨i, _⟩ => ⟨i, refl i, refl i, rfl⟩, @fun ⟨_, _⟩ ⟨_, _⟩ ⟨k, ik, jk, h⟩ => ⟨k, jk, ik, h.symm⟩, @fun ⟨i, x⟩ ⟨j, y⟩ ⟨k, z⟩ ⟨ij, hiij, hjij, hij⟩ ⟨jk, hjjk, hkjk, hjk⟩ => by obtain ⟨ijk, hijijk, hjkijk⟩ := directed_of (· ≤ ·) ij jk diff --git a/Mathlib/ModelTheory/Order.lean b/Mathlib/ModelTheory/Order.lean index af11c905aa569e..775c86094849ce 100644 --- a/Mathlib/ModelTheory/Order.lean +++ b/Mathlib/ModelTheory/Order.lean @@ -312,7 +312,7 @@ theorem realize_denselyOrdered [h : DenselyOrdered M] : variable (L) (M) -theorem denselyOrdered_of_dlo [h: M ⊨ L.dlo] : DenselyOrdered M := +theorem denselyOrdered_of_dlo [M ⊨ L.dlo] : DenselyOrdered M := realize_denselyOrdered_iff.1 (L.dlo.realize_sentence_of_mem (by simp only [dlo, Set.union_insert, Set.union_singleton, Set.mem_insert_iff, true_or, or_true])) @@ -533,7 +533,7 @@ theorem dlo_isComplete : Language.order.dlo.IsComplete := ⟨by letI : Language.order.Structure ℚ := orderStructure ℚ exact Theory.ModelType.of _ ℚ⟩ - fun M => inferInstance + fun _ => inferInstance end Fraisse diff --git a/Mathlib/ModelTheory/Semantics.lean b/Mathlib/ModelTheory/Semantics.lean index 3da6c40283d182..f180eb567f05df 100644 --- a/Mathlib/ModelTheory/Semantics.lean +++ b/Mathlib/ModelTheory/Semantics.lean @@ -339,7 +339,7 @@ theorem realize_mapTermRel_add_castLe [L'.Structure M] {k : ℕ} (ft n t).realize (Sum.elim v' xs') = t.realize (Sum.elim (v xs') (xs' ∘ Fin.natAdd _))) (h2 : ∀ (n) (R : L.Relations n) (x : Fin n → M), RelMap (fr n R) x = RelMap R x) (hv : ∀ (n) (xs : Fin (k + n) → M) (x : M), @v (n + 1) (snoc xs x : Fin _ → M) = v xs) : - (φ.mapTermRel ft fr fun n => castLE (add_assoc _ _ _).symm.le).Realize v' xs ↔ + (φ.mapTermRel ft fr fun _ => castLE (add_assoc _ _ _).symm.le).Realize v' xs ↔ φ.Realize (v xs) (xs ∘ Fin.natAdd _) := by induction φ with | falsum => rfl diff --git a/Mathlib/ModelTheory/Substructures.lean b/Mathlib/ModelTheory/Substructures.lean index 0fc09939992950..8c088e86751077 100644 --- a/Mathlib/ModelTheory/Substructures.lean +++ b/Mathlib/ModelTheory/Substructures.lean @@ -635,7 +635,7 @@ def topEquiv : (⊤ : L.Substructure M) ≃[L] M where toFun := subtype ⊤ invFun m := ⟨m, mem_top m⟩ left_inv m := by simp - right_inv m := rfl + right_inv _ := rfl @[simp] theorem coe_topEquiv : @@ -684,7 +684,7 @@ def substructureReduct (φ : L →ᴸ L') [φ.IsExpansionOn M] : inj' S T h := by simp only [SetLike.coe_set_eq, Substructure.mk.injEq] at h exact h - map_rel_iff' {S T} := Iff.rfl + map_rel_iff' {_ _} := Iff.rfl variable (φ : L →ᴸ L') [φ.IsExpansionOn M] @@ -757,7 +757,7 @@ hom `M → p`. -/ def codRestrict (p : L.Substructure N) (f : M →[L] N) (h : ∀ c, f c ∈ p) : M →[L] p where toFun c := ⟨f c, h c⟩ map_fun' {n} f x := by aesop - map_rel' {n} R x h := f.map_rel R x h + map_rel' {_} R x h := f.map_rel R x h @[simp] theorem comp_codRestrict (f : M →[L] N) (g : N →[L] P) (p : L.Substructure P) (h : ∀ b, g b ∈ p) : @@ -847,8 +847,8 @@ theorem domRestrict_apply (f : M ↪[L] N) (p : L.Substructure M) (x : p) : f.do to an embedding `M → p`. -/ def codRestrict (p : L.Substructure N) (f : M ↪[L] N) (h : ∀ c, f c ∈ p) : M ↪[L] p where toFun := f.toHom.codRestrict p h - inj' a b ab := f.injective (Subtype.mk_eq_mk.1 ab) - map_fun' {n} F x := (f.toHom.codRestrict p h).map_fun' F x + inj' _ _ ab := f.injective (Subtype.mk_eq_mk.1 ab) + map_fun' {_} F x := (f.toHom.codRestrict p h).map_fun' F x map_rel' {n} r x := by simp only rw [← p.subtype.map_rel] @@ -888,7 +888,7 @@ noncomputable def substructureEquivMap (f : M ↪[L] N) (s : L.Substructure M) : (Classical.choose_spec (codRestrict (s.map f.toHom) (f.domRestrict s) (fun ⟨m, hm⟩ => ⟨m, hm, rfl⟩) ⟨m, hm⟩).2).2) - right_inv := fun ⟨n, hn⟩ => Subtype.mk_eq_mk.2 (Classical.choose_spec hn).2 + right_inv := fun ⟨_, hn⟩ => Subtype.mk_eq_mk.2 (Classical.choose_spec hn).2 map_fun' {n} f x := by aesop map_rel' {n} R x := by aesop @@ -908,7 +908,7 @@ theorem subtype_substructureEquivMap (f : M ↪[L] N) (s : L.Substructure M) : invFun n := Classical.choose n.2 left_inv m := f.injective (Classical.choose_spec (codRestrict f.toHom.range f f.toHom.mem_range_self m).2) - right_inv := fun ⟨n, hn⟩ => Subtype.mk_eq_mk.2 (Classical.choose_spec hn) + right_inv := fun ⟨_, hn⟩ => Subtype.mk_eq_mk.2 (Classical.choose_spec hn) map_fun' {n} f x := by aesop map_rel' {n} R x := by aesop diff --git a/Mathlib/ModelTheory/Syntax.lean b/Mathlib/ModelTheory/Syntax.lean index 7fa52ce76edb5b..1c3ec68f882e69 100644 --- a/Mathlib/ModelTheory/Syntax.lean +++ b/Mathlib/ModelTheory/Syntax.lean @@ -472,8 +472,8 @@ def mapTermRel {g : ℕ → ℕ} (ft : ∀ n, L.Term (α ⊕ (Fin n)) → L'.Ter /-- Raises all of the `Fin`-indexed variables of a formula greater than or equal to `m` by `n'`. -/ def liftAt : ∀ {n : ℕ} (n' _m : ℕ), L.BoundedFormula α n → L.BoundedFormula α (n + n') := - fun {n} n' m φ => - φ.mapTermRel (fun k t => t.liftAt n' m) (fun _ => id) fun _ => + fun {_} n' m φ => + φ.mapTermRel (fun _ t => t.liftAt n' m) (fun _ => id) fun _ => castLE (by rw [add_assoc, add_comm 1, add_assoc]) @[simp] diff --git a/Mathlib/ModelTheory/Ultraproducts.lean b/Mathlib/ModelTheory/Ultraproducts.lean index 63dbaa42f715dc..dbe1d5d34724fe 100644 --- a/Mathlib/ModelTheory/Ultraproducts.lean +++ b/Mathlib/ModelTheory/Ultraproducts.lean @@ -46,8 +46,8 @@ namespace Ultraproduct instance setoidPrestructure : L.Prestructure ((u : Filter α).productSetoid M) := { (u : Filter α).productSetoid M with toStructure := - { funMap := fun {n} f x a => funMap f fun i => x i a - RelMap := fun {n} r x => ∀ᶠ a : α in u, RelMap r fun i => x i a } + { funMap := fun {_} f x a => funMap f fun i => x i a + 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 diff --git a/Mathlib/NumberTheory/Cyclotomic/PrimitiveRoots.lean b/Mathlib/NumberTheory/Cyclotomic/PrimitiveRoots.lean index e4a82b6a04edb2..0d5dc764a96e23 100644 --- a/Mathlib/NumberTheory/Cyclotomic/PrimitiveRoots.lean +++ b/Mathlib/NumberTheory/Cyclotomic/PrimitiveRoots.lean @@ -153,8 +153,8 @@ noncomputable def embeddingsEquivPrimitiveRoots (C : Type*) [CommRing C] [IsDoma rwa [aeval_def, eval₂_eq_eval_map, hζ.powerBasis_gen K, ← hζ.minpoly_eq_cyclotomic_of_irreducible hirr, map_cyclotomic, ← IsRoot.def, isRoot_cyclotomic_iff, ← mem_primitiveRoots n.pos] - left_inv := fun x => Subtype.ext rfl - right_inv := fun x => Subtype.ext rfl } + left_inv := fun _ => Subtype.ext rfl + right_inv := fun _ => Subtype.ext rfl } -- Porting note: renamed argument `φ`: "expected '_' or identifier" @[simp] diff --git a/Mathlib/NumberTheory/Cyclotomic/Rat.lean b/Mathlib/NumberTheory/Cyclotomic/Rat.lean index 39cdf61a389356..eae82d89db9ff8 100644 --- a/Mathlib/NumberTheory/Cyclotomic/Rat.lean +++ b/Mathlib/NumberTheory/Cyclotomic/Rat.lean @@ -214,6 +214,13 @@ theorem integralPowerBasis_gen [hcycl : IsCyclotomicExtension {p ^ k} ℚ K] simp only [adjoinEquivRingOfIntegers_apply, IsIntegralClosure.algebraMap_lift] rfl +#adaptation_note +/-- +We name `hcycl` so it can be used as a named argument, +but since https://github.com/leanprover/lean4/pull/5338, this is considered unused, +so we need to disable the linter. +-/ +set_option linter.unusedVariables false in @[simp] theorem integralPowerBasis_dim [hcycl : IsCyclotomicExtension {p ^ k} ℚ K] (hζ : IsPrimitiveRoot ζ ↑(p ^ k)) : hζ.integralPowerBasis.dim = φ (p ^ k) := by diff --git a/Mathlib/NumberTheory/Divisors.lean b/Mathlib/NumberTheory/Divisors.lean index 0c98cefad6ecd4..3fb893b14cd82b 100644 --- a/Mathlib/NumberTheory/Divisors.lean +++ b/Mathlib/NumberTheory/Divisors.lean @@ -281,7 +281,7 @@ theorem image_snd_divisorsAntidiagonal : (divisorsAntidiagonal n).image Prod.snd exact image_fst_divisorsAntidiagonal theorem map_div_right_divisors : - n.divisors.map ⟨fun d => (d, n / d), fun p₁ p₂ => congr_arg Prod.fst⟩ = + n.divisors.map ⟨fun d => (d, n / d), fun _ _ => congr_arg Prod.fst⟩ = n.divisorsAntidiagonal := by ext ⟨d, nd⟩ simp only [mem_map, mem_divisorsAntidiagonal, Function.Embedding.coeFn_mk, mem_divisors, @@ -294,7 +294,7 @@ theorem map_div_right_divisors : exact ⟨⟨dvd_mul_right _ _, hn⟩, Nat.mul_div_cancel_left _ (left_ne_zero_of_mul hn).bot_lt⟩ theorem map_div_left_divisors : - n.divisors.map ⟨fun d => (n / d, d), fun p₁ p₂ => congr_arg Prod.snd⟩ = + n.divisors.map ⟨fun d => (n / d, d), fun _ _ => congr_arg Prod.snd⟩ = n.divisorsAntidiagonal := by apply Finset.map_injective (Equiv.prodComm _ _).toEmbedding ext diff --git a/Mathlib/NumberTheory/EllipticDivisibilitySequence.lean b/Mathlib/NumberTheory/EllipticDivisibilitySequence.lean index b48aa4e66e2453..541332309d477e 100644 --- a/Mathlib/NumberTheory/EllipticDivisibilitySequence.lean +++ b/Mathlib/NumberTheory/EllipticDivisibilitySequence.lean @@ -113,12 +113,12 @@ def preNormEDS' (b c d : R) : ℕ → R have h4 : m + 4 < n + 5 := Nat.lt_succ.mpr <| add_le_add_right (n.div_le_self 2) 4 have h3 : m + 3 < n + 5 := (lt_add_one _).trans h4 have h2 : m + 2 < n + 5 := (lt_add_one _).trans h3 - have h1 : m + 1 < n + 5 := (lt_add_one _).trans h2 + have _ : m + 1 < n + 5 := (lt_add_one _).trans h2 if hn : Even n then 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) else - have h5 : m + 5 < n + 5 := add_lt_add_right + have _ : m + 5 < n + 5 := add_lt_add_right (Nat.div_lt_self (Nat.not_even_iff_odd.1 hn).pos <| Nat.lt_succ_self 1) 5 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 diff --git a/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean b/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean index c4b313daf7c59d..a331c2298bfd9a 100644 --- a/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean +++ b/Mathlib/NumberTheory/LegendreSymbol/JacobiSymbol.lean @@ -558,7 +558,7 @@ private theorem fastJacobiSymAux.eq_jacobiSym {a b : ℕ} {flip : Bool} {ha0 : a private def fastJacobiSym (a : ℤ) (b : ℕ) : ℤ := if hb0 : b = 0 then 1 - else if hb2 : b % 2 = 0 then + else if _ : b % 2 = 0 then if a % 2 = 0 then 0 else diff --git a/Mathlib/NumberTheory/Liouville/LiouvilleNumber.lean b/Mathlib/NumberTheory/Liouville/LiouvilleNumber.lean index 49a8325713112e..093de3c6112944 100644 --- a/Mathlib/NumberTheory/Liouville/LiouvilleNumber.lean +++ b/Mathlib/NumberTheory/Liouville/LiouvilleNumber.lean @@ -114,7 +114,7 @@ theorem remainder_lt' (n : ℕ) {m : ℝ} (m1 : 1 < m) : -- 3. the first series is summable (remainder_summable m1 n) -- 4. the second series is summable, since its terms grow quickly - (summable_one_div_pow_of_le m1 fun j => le_self_add) + (summable_one_div_pow_of_le m1 fun _ => le_self_add) -- split the sum in the exponent and massage _ = ∑' i : ℕ, (1 / m) ^ i * (1 / m ^ (n + 1)!) := by simp only [pow_add, one_div, mul_inv, inv_pow] diff --git a/Mathlib/NumberTheory/Liouville/Measure.lean b/Mathlib/NumberTheory/Liouville/Measure.lean index 618b456b255055..55c85ab7d9a3dc 100644 --- a/Mathlib/NumberTheory/Liouville/Measure.lean +++ b/Mathlib/NumberTheory/Liouville/Measure.lean @@ -107,7 +107,7 @@ theorem ae_not_liouvilleWith : ∀ᵐ x, ∀ p > (2 : ℝ), ¬LiouvilleWith p x volume_iUnion_setOf_liouvilleWith theorem ae_not_liouville : ∀ᵐ x, ¬Liouville x := - ae_not_liouvilleWith.mono fun x h₁ h₂ => h₁ 3 (by norm_num) (h₂.liouvilleWith 3) + 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] diff --git a/Mathlib/NumberTheory/Liouville/Residual.lean b/Mathlib/NumberTheory/Liouville/Residual.lean index 38feb5335e9274..151dd1af3c8f88 100644 --- a/Mathlib/NumberTheory/Liouville/Residual.lean +++ b/Mathlib/NumberTheory/Liouville/Residual.lean @@ -38,7 +38,7 @@ theorem IsGδ.setOf_liouville : IsGδ { x | Liouville x } := by theorem setOf_liouville_eq_irrational_inter_iInter_iUnion : { x | Liouville x } = - { x | Irrational x } ∩ ⋂ n : ℕ, ⋃ (a : ℤ) (b : ℤ) (hb : 1 < b), + { 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) ?_ diff --git a/Mathlib/NumberTheory/LucasLehmer.lean b/Mathlib/NumberTheory/LucasLehmer.lean index fd4fbbd8441a48..91ce335ec08651 100644 --- a/Mathlib/NumberTheory/LucasLehmer.lean +++ b/Mathlib/NumberTheory/LucasLehmer.lean @@ -554,7 +554,7 @@ theorem isNat_not_lucasLehmerTest : {p np : ℕ} → /-- Calculate `LucasLehmer.LucasLehmerTest p` for `2 ≤ p` by using kernel reduction for the `sMod'` function. -/ @[norm_num LucasLehmer.LucasLehmerTest (_ : ℕ)] -def evalLucasLehmerTest : NormNumExt where eval {u α} e := do +def evalLucasLehmerTest : NormNumExt where eval {_ _} e := do let .app _ (p : Q(ℕ)) ← Meta.whnfR e | failure let ⟨ep, hp⟩ ← deriveNat p _ let np := ep.natLit! diff --git a/Mathlib/NumberTheory/ModularForms/Basic.lean b/Mathlib/NumberTheory/ModularForms/Basic.lean index 77d18bd72f9993..aca96ca3623865 100644 --- a/Mathlib/NumberTheory/ModularForms/Basic.lean +++ b/Mathlib/NumberTheory/ModularForms/Basic.lean @@ -245,7 +245,7 @@ theorem mul_coe {k_1 k_2 : ℤ} {Γ : Subgroup SL(2, ℤ)} (f : ModularForm Γ k @[simps! (config := .asFn) toFun toSlashInvariantForm] def const (x : ℂ) : ModularForm Γ 0 where toSlashInvariantForm := .const x - holo' x := mdifferentiableAt_const 𝓘(ℂ, ℂ) 𝓘(ℂ, ℂ) + holo' _ := mdifferentiableAt_const 𝓘(ℂ, ℂ) 𝓘(ℂ, ℂ) bdd_at_infty' A := by simpa only [SlashInvariantForm.const_toFun, ModularForm.is_invariant_const] using atImInfty.const_boundedAtFilter x @@ -407,20 +407,20 @@ instance (Γ : Subgroup SL(2, ℤ)) : GradedMonoid.GMul (ModularForm Γ) where mul f g := f.mul g instance instGCommRing (Γ : Subgroup SL(2, ℤ)) : DirectSum.GCommRing (ModularForm Γ) where - one_mul a := gradedMonoid_eq_of_cast (zero_add _) (ext fun _ => one_mul _) - mul_one a := gradedMonoid_eq_of_cast (add_zero _) (ext fun _ => mul_one _) - mul_assoc a b c := gradedMonoid_eq_of_cast (add_assoc _ _ _) (ext fun _ => mul_assoc _ _ _) - mul_zero {i j} f := ext fun _ => mul_zero _ - zero_mul {i j} f := ext fun _ => zero_mul _ - mul_add {i j} f g h := ext fun _ => mul_add _ _ _ - add_mul {i j} f g h := ext fun _ => add_mul _ _ _ - mul_comm a b := gradedMonoid_eq_of_cast (add_comm _ _) (ext fun _ => mul_comm _ _) + one_mul _ := gradedMonoid_eq_of_cast (zero_add _) (ext fun _ => one_mul _) + mul_one _ := gradedMonoid_eq_of_cast (add_zero _) (ext fun _ => mul_one _) + mul_assoc _ _ _ := gradedMonoid_eq_of_cast (add_assoc _ _ _) (ext fun _ => mul_assoc _ _ _) + mul_zero {_ _} _ := ext fun _ => mul_zero _ + zero_mul {_ _} _ := ext fun _ => zero_mul _ + mul_add {_ _} _ _ _ := ext fun _ => mul_add _ _ _ + add_mul {_ _} _ _ _ := ext fun _ => add_mul _ _ _ + mul_comm _ _ := gradedMonoid_eq_of_cast (add_comm _ _) (ext fun _ => mul_comm _ _) natCast := Nat.cast natCast_zero := ext fun _ => Nat.cast_zero - natCast_succ n := ext fun _ => Nat.cast_succ _ + natCast_succ _ := ext fun _ => Nat.cast_succ _ intCast := Int.cast - intCast_ofNat n := ext fun _ => AddGroupWithOne.intCast_ofNat _ - intCast_negSucc_ofNat n := ext fun _ => AddGroupWithOne.intCast_negSucc _ + intCast_ofNat _ := ext fun _ => AddGroupWithOne.intCast_ofNat _ + intCast_negSucc_ofNat _ := ext fun _ => AddGroupWithOne.intCast_negSucc _ instance instGAlgebra (Γ : Subgroup SL(2, ℤ)) : DirectSum.GAlgebra ℂ (ModularForm Γ) where toFun := { toFun := const, map_zero' := rfl, map_add' := fun _ _ => rfl } diff --git a/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean b/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean index 12b15e1ddd7d77..4970ba0001a5ad 100644 --- a/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean +++ b/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean @@ -423,7 +423,7 @@ set_option maxSynthPendingDepth 2 -- Note this is active for the remainder of th def logEmbeddingEquiv : Additive ((𝓞 K)ˣ ⧸ (torsion K)) ≃ₗ[ℤ] (unitLattice K) := LinearEquiv.ofBijective ((logEmbeddingQuot K).codRestrict (unitLattice K) - (Quotient.ind fun x ↦ logEmbeddingQuot_apply K _ ▸ + (Quotient.ind fun _ ↦ logEmbeddingQuot_apply K _ ▸ Submodule.mem_map_of_mem trivial)).toIntLinearMap ⟨fun _ _ ↦ by rw [AddMonoidHom.coe_toIntLinearMap, AddMonoidHom.codRestrict_apply, diff --git a/Mathlib/NumberTheory/Ostrowski.lean b/Mathlib/NumberTheory/Ostrowski.lean index de32a03798da56..31a0b280f41f19 100644 --- a/Mathlib/NumberTheory/Ostrowski.lean +++ b/Mathlib/NumberTheory/Ostrowski.lean @@ -190,7 +190,7 @@ lemma exists_pos_mulRingNorm_eq_pow_neg : ∃ t : ℝ, 0 < t ∧ f p = p ^ (-t) include hf_nontriv bdd in /-- If `f` is bounded and not trivial, then it is equivalent to a p-adic absolute value. -/ theorem mulRingNorm_equiv_padic_of_bounded : - ∃! p, ∃ (hp : Fact (p.Prime)), MulRingNorm.equiv f (mulRingNorm_padic p) := by + ∃! p, ∃ (_ : Fact (p.Prime)), MulRingNorm.equiv f (mulRingNorm_padic p) := by obtain ⟨p, hfp, hmin⟩ := exists_minimal_nat_zero_lt_mulRingNorm_lt_one hf_nontriv bdd have hprime := is_prime_of_minimal_nat_zero_lt_mulRingNorm_lt_one hfp.1 hfp.2 hmin have hprime_fact : Fact (p.Prime) := ⟨hprime⟩ diff --git a/Mathlib/NumberTheory/Padics/Hensel.lean b/Mathlib/NumberTheory/Padics/Hensel.lean index 05f97027ce268e..614c690370a02e 100644 --- a/Mathlib/NumberTheory/Padics/Hensel.lean +++ b/Mathlib/NumberTheory/Padics/Hensel.lean @@ -227,7 +227,7 @@ private def ih_n {n : ℕ} {z : ℤ_[p]} (hz : ih n z) : { z' : ℤ_[p] // ih (n rw [sub_eq_add_neg, ← hz.1, ← norm_neg (F.derivative.eval z)] at hdist have := PadicInt.norm_eq_of_norm_add_lt_right hdist rwa [norm_neg, hz.1] at this - let ⟨q, heq⟩ := calc_eval_z' hnorm rfl hz h1 rfl + let ⟨_, heq⟩ := calc_eval_z' hnorm rfl hz h1 rfl have hnle : ‖F.eval z'‖ ≤ ‖F.derivative.eval a‖ ^ 2 * T ^ 2 ^ (n + 1) := calc_eval_z'_norm hz heq h1 rfl ⟨hfeq, hnle⟩⟩ diff --git a/Mathlib/NumberTheory/PellMatiyasevic.lean b/Mathlib/NumberTheory/PellMatiyasevic.lean index d53d6039949dba..d2cef3a69a1f76 100644 --- a/Mathlib/NumberTheory/PellMatiyasevic.lean +++ b/Mathlib/NumberTheory/PellMatiyasevic.lean @@ -249,7 +249,7 @@ theorem x_pos (n) : 0 < xn a1 n := theorem eq_pell_lem : ∀ (n) (b : ℤ√(d a1)), 1 ≤ b → IsPell b → b ≤ pellZd a1 n → ∃ n, b = pellZd a1 n - | 0, b => fun h1 _ hl => ⟨0, @Zsqrtd.le_antisymm _ (dnsq a1) _ _ hl h1⟩ + | 0, _ => fun h1 _ hl => ⟨0, @Zsqrtd.le_antisymm _ (dnsq a1) _ _ hl h1⟩ | n + 1, b => fun h1 hp h => have a1p : (0 : ℤ√(d a1)) ≤ ⟨a, 1⟩ := trivial have am1p : (0 : ℤ√(d a1)) ≤ ⟨a, -1⟩ := show (_ : Nat) ≤ _ by simp; exact Nat.pred_le _ @@ -353,7 +353,7 @@ theorem xy_coprime (n) : (xn a1 n).Coprime (yn a1 n) := exact Nat.dvd_sub (le_of_lt <| Nat.lt_of_sub_eq_succ p) (kx.mul_left _) (ky.mul_left _) theorem strictMono_y : StrictMono (yn a1) - | m, 0, h => absurd h <| Nat.not_lt_zero _ + | _, 0, h => absurd h <| Nat.not_lt_zero _ | m, n + 1, h => by have : yn a1 m ≤ yn a1 n := Or.elim (lt_or_eq_of_le <| Nat.le_of_succ_le_succ h) (fun hl => le_of_lt <| strictMono_y hl) @@ -363,7 +363,7 @@ theorem strictMono_y : StrictMono (yn a1) exact mul_le_mul this (le_of_lt a1) (Nat.zero_le _) (Nat.zero_le _) theorem strictMono_x : StrictMono (xn a1) - | m, 0, h => absurd h <| Nat.not_lt_zero _ + | _, 0, h => absurd h <| Nat.not_lt_zero _ | m, n + 1, h => by have : xn a1 m ≤ xn a1 n := Or.elim (lt_or_eq_of_le <| Nat.le_of_succ_le_succ h) (fun hl => le_of_lt <| strictMono_x hl) @@ -657,7 +657,7 @@ theorem eq_of_xn_modEq_lem3 {i n} (npos : 0 < n) : (fun h => lt_trans (eq_of_xn_modEq_lem3 npos h (le_of_lt (Nat.lt_of_succ_le j2n)) jn - fun ⟨a1, n1, i0, j2⟩ => by + fun ⟨_, n1, _, j2⟩ => by rw [n1, j2] at j2n; exact absurd j2n (by decide)) s) fun h => by rw [h]; exact s @@ -703,8 +703,8 @@ theorem eq_of_xn_modEq' {i j n} (ipos : 0 < i) (hin : i ≤ n) (j4n : j ≤ 4 * have i2n : i ≤ 2 * n := by apply le_trans hin; rw [two_mul]; apply Nat.le_add_left (le_or_gt j (2 * n)).imp (fun j2n : j ≤ 2 * n => - eq_of_xn_modEq a1 j2n i2n h fun a2 n1 => - ⟨fun j0 i2 => by rw [n1, i2] at hin; exact absurd hin (by decide), fun _ i0 => + eq_of_xn_modEq a1 j2n i2n h fun _ n1 => + ⟨fun _ i2 => by rw [n1, i2] at hin; exact absurd hin (by decide), fun _ i0 => _root_.ne_of_gt ipos i0⟩) fun j2n : 2 * n < j => suffices i = 4 * n - j by rw [this, add_tsub_cancel_of_le j4n] @@ -713,7 +713,7 @@ theorem eq_of_xn_modEq' {i j n} (ipos : 0 < i) (hin : i ≤ n) (j4n : j ≤ 4 * (h.symm.trans <| by let t := xn_modEq_x4n_sub a1 j42n rwa [tsub_tsub_cancel_of_le j4n] at t) - fun a2 n1 => + fun _ n1 => ⟨fun i0 => absurd i0 (_root_.ne_of_gt ipos), fun i2 => by rw [n1, i2] at hin exact absurd hin (by decide)⟩ diff --git a/Mathlib/NumberTheory/Primorial.lean b/Mathlib/NumberTheory/Primorial.lean index 8bc67a5f611f7d..886f7183cfa38b 100644 --- a/Mathlib/NumberTheory/Primorial.lean +++ b/Mathlib/NumberTheory/Primorial.lean @@ -55,7 +55,7 @@ theorem primorial_add_dvd {m n : ℕ} (h : n ≤ m) : (m + n)# ∣ m# * choose ( (m + n)# = m# * ∏ p ∈ filter Nat.Prime (Ico (m + 1) (m + n + 1)), p := primorial_add _ _ _ ∣ m# * choose (m + n) m := mul_dvd_mul_left _ <| - prod_primes_dvd _ (fun k hk ↦ (mem_filter.1 hk).2.prime) fun p hp ↦ by + prod_primes_dvd _ (fun _ hk ↦ (mem_filter.1 hk).2.prime) fun p hp ↦ by rw [mem_filter, mem_Ico] at hp exact hp.2.dvd_choose_add hp.1.1 (h.trans_lt (m.lt_succ_self.trans_le hp.1.1)) (Nat.lt_succ_iff.1 hp.1.2) diff --git a/Mathlib/NumberTheory/Zsqrtd/Basic.lean b/Mathlib/NumberTheory/Zsqrtd/Basic.lean index c73a74bb7a6b6f..58b19978fb5b9c 100644 --- a/Mathlib/NumberTheory/Zsqrtd/Basic.lean +++ b/Mathlib/NumberTheory/Zsqrtd/Basic.lean @@ -217,9 +217,9 @@ theorem star_im (z : ℤ√d) : (star z).im = -z.im := rfl instance : StarRing (ℤ√d) where - star_involutive x := Zsqrtd.ext rfl (neg_neg _) + star_involutive _ := Zsqrtd.ext rfl (neg_neg _) star_mul a b := by ext <;> simp <;> ring - star_add a b := Zsqrtd.ext rfl (neg_add _ _) + star_add _ _ := Zsqrtd.ext rfl (neg_add _ _) -- Porting note: proof was `by decide` instance nontrivial : Nontrivial (ℤ√d) := @@ -654,7 +654,7 @@ instance preorder : Preorder (ℤ√d) where le_refl a := show Nonneg (a - a) by simp only [sub_self]; trivial le_trans a b c hab hbc := by simpa [sub_add_sub_cancel'] using hab.add hbc lt := (· < ·) - lt_iff_le_not_le a b := (and_iff_right_of_imp (Zsqrtd.le_total _ _).resolve_left).symm + lt_iff_le_not_le _ _ := (and_iff_right_of_imp (Zsqrtd.le_total _ _).resolve_left).symm open Int in theorem le_arch (a : ℤ√d) : ∃ n : ℕ, a ≤ n := by @@ -805,12 +805,12 @@ theorem not_divides_sq (x y) : (x + 1) * (x + 1) ≠ d * (y + 1) * (y + 1) := fu open Int in theorem nonneg_antisymm : ∀ {a : ℤ√d}, Nonneg a → Nonneg (-a) → a = 0 | ⟨0, 0⟩, _, _ => rfl - | ⟨-[x+1], -[y+1]⟩, xy, _ => False.elim xy - | ⟨(x + 1 : Nat), (y + 1 : Nat)⟩, _, yx => False.elim yx - | ⟨-[x+1], 0⟩, xy, _ => absurd xy (not_sqLe_succ _ _ _ (by decide)) - | ⟨(x + 1 : Nat), 0⟩, _, yx => absurd yx (not_sqLe_succ _ _ _ (by decide)) - | ⟨0, -[y+1]⟩, xy, _ => absurd xy (not_sqLe_succ _ _ _ d_pos) - | ⟨0, (y + 1 : Nat)⟩, _, yx => absurd yx (not_sqLe_succ _ _ _ d_pos) + | ⟨-[_+1], -[_+1]⟩, xy, _ => False.elim xy + | ⟨(_ + 1 : Nat), (_ + 1 : Nat)⟩, _, yx => False.elim yx + | ⟨-[_+1], 0⟩, xy, _ => absurd xy (not_sqLe_succ _ _ _ (by decide)) + | ⟨(_ + 1 : Nat), 0⟩, _, yx => absurd yx (not_sqLe_succ _ _ _ (by decide)) + | ⟨0, -[_+1]⟩, xy, _ => absurd xy (not_sqLe_succ _ _ _ d_pos) + | ⟨0, (_ + 1 : Nat)⟩, _, yx => absurd yx (not_sqLe_succ _ _ _ d_pos) | ⟨(x + 1 : Nat), -[y+1]⟩, (xy : SqLe _ _ _ _), (yx : SqLe _ _ _ _) => by let t := le_antisymm yx xy rw [one_mul] at t diff --git a/Mathlib/NumberTheory/Zsqrtd/GaussianInt.lean b/Mathlib/NumberTheory/Zsqrtd/GaussianInt.lean index 6ade04820260dd..c0a2b23beb7937 100644 --- a/Mathlib/NumberTheory/Zsqrtd/GaussianInt.lean +++ b/Mathlib/NumberTheory/Zsqrtd/GaussianInt.lean @@ -250,7 +250,7 @@ instance : EuclideanDomain ℤ[i] := r := _ r_wellFounded := (measure (Int.natAbs ∘ norm)).wf remainder_lt := natAbs_norm_mod_lt - mul_left_not_lt := fun a b hb0 => not_lt_of_ge <| norm_le_norm_mul_left a hb0 } + mul_left_not_lt := fun a _ hb0 => not_lt_of_ge <| norm_le_norm_mul_left a hb0 } open PrincipalIdealRing diff --git a/Mathlib/NumberTheory/Zsqrtd/QuadraticReciprocity.lean b/Mathlib/NumberTheory/Zsqrtd/QuadraticReciprocity.lean index 4847518e1ce0e1..e77bb9da4988ff 100644 --- a/Mathlib/NumberTheory/Zsqrtd/QuadraticReciprocity.lean +++ b/Mathlib/NumberTheory/Zsqrtd/QuadraticReciprocity.lean @@ -80,7 +80,7 @@ theorem mod_four_eq_three_of_nat_prime_of_prime (p : ℕ) [hp : Fact p.Prime] clear_aux_decl tauto -theorem prime_of_nat_prime_of_mod_four_eq_three (p : ℕ) [hp : Fact p.Prime] (hp3 : p % 4 = 3) : +theorem prime_of_nat_prime_of_mod_four_eq_three (p : ℕ) [Fact p.Prime] (hp3 : p % 4 = 3) : Prime (p : ℤ[i]) := irreducible_iff_prime.1 <| by_contradiction fun hpi => diff --git a/Mathlib/Order/Antichain.lean b/Mathlib/Order/Antichain.lean index cdfcbf4009f477..3361bfcc25257c 100644 --- a/Mathlib/Order/Antichain.lean +++ b/Mathlib/Order/Antichain.lean @@ -180,12 +180,12 @@ theorem IsAntichain.not_lt (hs : IsAntichain (· ≤ ·) s) (ha : a ∈ s) (hb : fun h => hs ha hb h.ne h.le theorem isAntichain_and_least_iff : IsAntichain (· ≤ ·) s ∧ IsLeast s a ↔ s = {a} := - ⟨fun h => eq_singleton_iff_unique_mem.2 ⟨h.2.1, fun b hb => h.1.eq' hb h.2.1 (h.2.2 hb)⟩, by + ⟨fun h => eq_singleton_iff_unique_mem.2 ⟨h.2.1, fun _ hb => h.1.eq' hb h.2.1 (h.2.2 hb)⟩, by rintro rfl exact ⟨isAntichain_singleton _ _, isLeast_singleton⟩⟩ theorem isAntichain_and_greatest_iff : IsAntichain (· ≤ ·) s ∧ IsGreatest s a ↔ s = {a} := - ⟨fun h => eq_singleton_iff_unique_mem.2 ⟨h.2.1, fun b hb => h.1.eq hb h.2.1 (h.2.2 hb)⟩, by + ⟨fun h => eq_singleton_iff_unique_mem.2 ⟨h.2.1, fun _ hb => h.1.eq hb h.2.1 (h.2.2 hb)⟩, by rintro rfl exact ⟨isAntichain_singleton _ _, isGreatest_singleton⟩⟩ diff --git a/Mathlib/Order/Antisymmetrization.lean b/Mathlib/Order/Antisymmetrization.lean index 8dae92170d4dd4..685d82061d1d58 100644 --- a/Mathlib/Order/Antisymmetrization.lean +++ b/Mathlib/Order/Antisymmetrization.lean @@ -218,7 +218,7 @@ def OrderIso.dualAntisymmetrization : invFun := (Quotient.map' id) fun _ _ => And.symm left_inv a := Quotient.inductionOn' a fun a => by simp_rw [Quotient.map'_mk'', id] right_inv a := Quotient.inductionOn' a fun a => by simp_rw [Quotient.map'_mk'', id] - map_rel_iff' := @fun a b => Quotient.inductionOn₂' a b fun a b => Iff.rfl + map_rel_iff' := @fun a b => Quotient.inductionOn₂' a b fun _ _ => Iff.rfl @[simp] theorem OrderIso.dualAntisymmetrization_apply (a : α) : diff --git a/Mathlib/Order/Atoms.lean b/Mathlib/Order/Atoms.lean index bcafc0ff307469..d7d36b09473b61 100644 --- a/Mathlib/Order/Atoms.lean +++ b/Mathlib/Order/Atoms.lean @@ -512,7 +512,7 @@ theorem sSup_atoms_eq_top : sSup { a : α | IsAtom a } = ⊤ := by exact (and_iff_left le_top).symm theorem le_iff_atom_le_imp {a b : α} : a ≤ b ↔ ∀ c : α, IsAtom c → c ≤ a → c ≤ b := - ⟨fun ab c _ ca => le_trans ca ab, fun h => by + ⟨fun ab _ _ ca => le_trans ca ab, fun h => by rw [← sSup_atoms_le_eq a, ← sSup_atoms_le_eq b] exact sSup_le_sSup fun c hc => ⟨hc.1, h c hc.1 hc.2⟩⟩ @@ -1090,7 +1090,7 @@ theorem isAtom_iff {f : ∀ i, π i} [∀ i, PartialOrder (π i)] [∀ i, OrderB theorem isAtom_single {i : ι} [DecidableEq ι] [∀ i, PartialOrder (π i)] [∀ i, OrderBot (π i)] {a : π i} (h : IsAtom a) : IsAtom (Function.update (⊥ : ∀ i, π i) i a) := - isAtom_iff.2 ⟨i, by simpa, fun j hji => Function.update_noteq hji _ _⟩ + isAtom_iff.2 ⟨i, by simpa, fun _ hji => Function.update_noteq hji _ _⟩ theorem isAtom_iff_eq_single [DecidableEq ι] [∀ i, PartialOrder (π i)] [∀ i, OrderBot (π i)] {f : ∀ i, π i} : diff --git a/Mathlib/Order/Basic.lean b/Mathlib/Order/Basic.lean index 08b21b2de49869..f7a234670ae36b 100644 --- a/Mathlib/Order/Basic.lean +++ b/Mathlib/Order/Basic.lean @@ -767,7 +767,7 @@ theorem Pi.le_def [∀ i, LE (π i)] {x y : ∀ i, π i} : instance Pi.preorder [∀ i, Preorder (π i)] : Preorder (∀ i, π i) where __ := inferInstanceAs (LE (∀ i, π i)) le_refl := fun a i ↦ le_refl (a i) - le_trans := fun a b c h₁ h₂ i ↦ le_trans (h₁ i) (h₂ i) + le_trans := fun _ _ _ h₁ h₂ i ↦ le_trans (h₁ i) (h₂ i) theorem Pi.lt_def [∀ i, Preorder (π i)] {x y : ∀ i, π i} : x < y ↔ x ≤ y ∧ ∃ i, x i < y i := by @@ -1126,7 +1126,7 @@ variable [Preorder α] [Preorder β] {a a₁ a₂ : α} {b b₁ b₂ : β} {x y instance (α β : Type*) [Preorder α] [Preorder β] : Preorder (α × β) where __ := inferInstanceAs (LE (α × β)) le_refl := fun ⟨a, b⟩ ↦ ⟨le_refl a, le_refl b⟩ - le_trans := fun ⟨a, b⟩ ⟨c, d⟩ ⟨e, f⟩ ⟨hac, hbd⟩ ⟨hce, hdf⟩ ↦ ⟨le_trans hac hce, le_trans hbd hdf⟩ + le_trans := fun ⟨_, _⟩ ⟨_, _⟩ ⟨_, _⟩ ⟨hac, hbd⟩ ⟨hce, hdf⟩ ↦ ⟨le_trans hac hce, le_trans hbd hdf⟩ @[simp] theorem swap_lt_swap : x.swap < y.swap ↔ x < y := diff --git a/Mathlib/Order/Birkhoff.lean b/Mathlib/Order/Birkhoff.lean index 03f815acdee3cc..efa0574e446658 100644 --- a/Mathlib/Order/Birkhoff.lean +++ b/Mathlib/Order/Birkhoff.lean @@ -185,7 +185,7 @@ open Classical in lattice is isomorphic to the lattice of lower sets of its sup-irreducible elements. -/ noncomputable def OrderIso.lowerSetSupIrred [OrderBot α] : α ≃o LowerSet {a : α // SupIrred a} := Equiv.toOrderIso - { toFun := fun a ↦ ⟨{b | ↑b ≤ a}, fun b c hcb hba ↦ hba.trans' hcb⟩ + { toFun := fun a ↦ ⟨{b | ↑b ≤ a}, fun _ _ hcb hba ↦ hba.trans' hcb⟩ invFun := fun s ↦ (s : Set {a : α // SupIrred a}).toFinset.sup (↑) left_inv := fun a ↦ by refine le_antisymm (Finset.sup_le fun b ↦ Set.mem_toFinset.1) ?_ @@ -200,7 +200,7 @@ noncomputable def OrderIso.lowerSetSupIrred [OrderBot α] : α ≃o LowerSet {a exact s.lower ha (Set.mem_toFinset.1 hi) · dsimp exact le_sup (Set.mem_toFinset.2 ha) } - (fun b c hbc d ↦ le_trans' hbc) fun s t hst ↦ Finset.sup_mono <| Set.toFinset_mono hst + (fun _ _ hbc _ ↦ le_trans' hbc) fun _ _ hst ↦ Finset.sup_mono <| Set.toFinset_mono hst namespace OrderEmbedding diff --git a/Mathlib/Order/BooleanAlgebra.lean b/Mathlib/Order/BooleanAlgebra.lean index 24e867d0ac3540..3d8e0ff5b03f0d 100644 --- a/Mathlib/Order/BooleanAlgebra.lean +++ b/Mathlib/Order/BooleanAlgebra.lean @@ -692,8 +692,8 @@ instance Prop.instBooleanAlgebra : BooleanAlgebra Prop where __ := Prop.instHeytingAlgebra __ := GeneralizedHeytingAlgebra.toDistribLattice compl := Not - himp_eq p q := propext imp_iff_or_not - inf_compl_le_bot p H := H.2 H.1 + himp_eq _ _ := propext imp_iff_or_not + inf_compl_le_bot _ H := H.2 H.1 top_le_sup_compl p _ := Classical.em p instance Prod.instBooleanAlgebra [BooleanAlgebra α] [BooleanAlgebra β] : @@ -760,8 +760,8 @@ protected abbrev Function.Injective.booleanAlgebra [Sup α] [Inf α] [Top α] [B compl := compl himp := himp top := ⊤ - le_top a := (@le_top β _ _ _).trans map_top.ge - bot_le a := map_bot.le.trans bot_le + le_top _ := (@le_top β _ _ _).trans map_top.ge + bot_le _ := map_bot.le.trans bot_le inf_compl_le_bot a := ((map_inf _ _).trans <| by rw [map_compl, inf_compl_eq_bot, map_bot]).le top_le_sup_compl a := ((map_sup _ _).trans <| by rw [map_compl, sup_compl_eq_top, map_top]).ge sdiff_eq a b := by diff --git a/Mathlib/Order/Booleanisation.lean b/Mathlib/Order/Booleanisation.lean index aa7f7370581b45..1b2c1d9c34ad89 100644 --- a/Mathlib/Order/Booleanisation.lean +++ b/Mathlib/Order/Booleanisation.lean @@ -168,13 +168,13 @@ instance instPreorder : Preorder (Booleanisation α) where | comp a, lift b => by simp | comp a, comp b => by simp [lt_iff_le_not_le] le_refl x := match x with - | lift a => LE.lift le_rfl - | comp a => LE.comp le_rfl + | lift _ => LE.lift le_rfl + | comp _ => LE.comp le_rfl le_trans x y z hxy hyz := match x, y, z, hxy, hyz with - | lift a, lift b, lift c, LE.lift hab, LE.lift hbc => LE.lift <| hab.trans hbc - | lift a, lift b, comp c, LE.lift hab, LE.sep hbc => LE.sep <| hbc.mono_left hab - | lift a, comp b, comp c, LE.sep hab, LE.comp hcb => LE.sep <| hab.mono_right hcb - | comp a, comp b, comp c, LE.comp hba, LE.comp hcb => LE.comp <| hcb.trans hba + | lift _, lift _, lift _, LE.lift hab, LE.lift hbc => LE.lift <| hab.trans hbc + | lift _, lift _, comp _, LE.lift hab, LE.sep hbc => LE.sep <| hbc.mono_left hab + | lift _, comp _, comp _, LE.sep hab, LE.comp hcb => LE.sep <| hab.mono_right hcb + | comp _, comp _, comp _, LE.comp hba, LE.comp hcb => LE.comp <| hcb.trans hba instance instPartialOrder : PartialOrder (Booleanisation α) where le_antisymm x y hxy hyx := match x, y, hxy, hyx with @@ -226,7 +226,7 @@ instance instDistribLattice : DistribLattice (Booleanisation α) where inf_le_right _ _ := inf_le_right le_inf _ _ _ := le_inf le_sup_inf x y z := match x, y, z with - | lift a, lift b, lift c => LE.lift le_sup_inf + | lift _, lift _, lift _ => LE.lift le_sup_inf | lift a, lift b, comp c => LE.lift <| by simp [sup_left_comm, sup_comm] | lift a, comp b, lift c => LE.lift <| by simp [sup_left_comm (a := b \ a), sup_comm (a := b \ a)] @@ -234,7 +234,7 @@ instance instDistribLattice : DistribLattice (Booleanisation α) where | comp a, lift b, lift c => LE.comp <| by rw [sdiff_inf] | comp a, lift b, comp c => LE.comp <| by rw [sdiff_sdiff_right'] | comp a, comp b, lift c => LE.comp <| by rw [sdiff_sdiff_right', sup_comm] - | comp a, comp b, comp c => LE.comp (inf_sup_left _ _ _).le + | comp _, comp _, comp _ => LE.comp (inf_sup_left _ _ _).le -- The linter significantly hinders readability here. set_option linter.unusedVariables false in diff --git a/Mathlib/Order/Bounds/Basic.lean b/Mathlib/Order/Bounds/Basic.lean index ad3019a2ea838f..eaee5e41d13306 100644 --- a/Mathlib/Order/Bounds/Basic.lean +++ b/Mathlib/Order/Bounds/Basic.lean @@ -564,7 +564,7 @@ section variable [SemilatticeSup γ] [DenselyOrdered γ] theorem isGLB_Ioo {a b : γ} (h : a < b) : IsGLB (Ioo a b) a := - ⟨fun x hx => hx.1.le, fun x hx => by + ⟨fun _ hx => hx.1.le, fun x hx => by rcases eq_or_lt_of_le (le_sup_right : a ≤ x ⊔ a) with h₁ | h₂ · exact h₁.symm ▸ le_sup_left obtain ⟨y, lty, ylt⟩ := exists_between h₂ diff --git a/Mathlib/Order/Category/BddDistLat.lean b/Mathlib/Order/Category/BddDistLat.lean index 55bd9eb0547379..3ead1db99b5ecf 100644 --- a/Mathlib/Order/Category/BddDistLat.lean +++ b/Mathlib/Order/Category/BddDistLat.lean @@ -68,7 +68,7 @@ instance hasForgetToDistLat : HasForget₂ BddDistLat DistLat where -- Porting note: was `⟨X⟩` -- see https://github.com/leanprover-community/mathlib4/issues/4998 { obj := fun X => { α := X } - map := fun {X Y} => BoundedLatticeHom.toLatticeHom } + map := fun {_ _} => BoundedLatticeHom.toLatticeHom } instance hasForgetToBddLat : HasForget₂ BddDistLat BddLat := InducedCategory.hasForget₂ toBddLat @@ -91,7 +91,7 @@ def Iso.mk {α β : BddDistLat.{u}} (e : α ≃o β) : α ≅ β where @[simps] def dual : BddDistLat ⥤ BddDistLat where obj X := of Xᵒᵈ - map {X Y} := BoundedLatticeHom.dual + map {_ _} := BoundedLatticeHom.dual /-- The equivalence between `BddDistLat` and itself induced by `OrderDual` both ways. -/ @[simps functor inverse] diff --git a/Mathlib/Order/Category/BddLat.lean b/Mathlib/Order/Category/BddLat.lean index 45b49280d263e3..b1f4e2931ddcb5 100644 --- a/Mathlib/Order/Category/BddLat.lean +++ b/Mathlib/Order/Category/BddLat.lean @@ -71,23 +71,23 @@ instance : ConcreteCategory BddLat where instance hasForgetToBddOrd : HasForget₂ BddLat BddOrd where forget₂ := { obj := fun X => BddOrd.of X - map := fun {X Y} => BoundedLatticeHom.toBoundedOrderHom } + map := fun {_ _} => BoundedLatticeHom.toBoundedOrderHom } instance hasForgetToLat : HasForget₂ BddLat Lat where forget₂ := -- Porting note: was `⟨X⟩`, see https://github.com/leanprover-community/mathlib4/issues/4998 { obj := fun X => {α := X} - map := fun {X Y} => BoundedLatticeHom.toLatticeHom } + map := fun {_ _} => BoundedLatticeHom.toLatticeHom } instance hasForgetToSemilatSup : HasForget₂ BddLat SemilatSupCat where forget₂ := { obj := fun X => ⟨X⟩ - map := fun {X Y} => BoundedLatticeHom.toSupBotHom } + map := fun {_ _} => BoundedLatticeHom.toSupBotHom } instance hasForgetToSemilatInf : HasForget₂ BddLat SemilatInfCat where forget₂ := { obj := fun X => ⟨X⟩ - map := fun {X Y} => BoundedLatticeHom.toInfTopHom } + map := fun {_ _} => BoundedLatticeHom.toInfTopHom } @[simp] theorem coe_forget_to_bddOrd (X : BddLat) : ↥((forget₂ BddLat BddOrd).obj X) = ↥X := @@ -135,7 +135,7 @@ def Iso.mk {α β : BddLat.{u}} (e : α ≃o β) : α ≅ β where @[simps] def dual : BddLat ⥤ BddLat where obj X := of Xᵒᵈ - map {X Y} := BoundedLatticeHom.dual + map {_ _} := BoundedLatticeHom.dual /-- The equivalence between `BddLat` and itself induced by `OrderDual` both ways. -/ @[simps functor inverse] @@ -177,7 +177,7 @@ def latToBddLat : Lat.{u} ⥤ BddLat where functor from `Lat` to `BddLat`. -/ def latToBddLatForgetAdjunction : latToBddLat.{u} ⊣ forget₂ BddLat Lat := Adjunction.mkOfHomEquiv - { homEquiv := fun X Y => + { homEquiv := fun X _ => { toFun := fun f => { toFun := f ∘ some ∘ some map_sup' := fun a b => (congr_arg f <| by rfl).trans (f.map_sup' _ _) @@ -188,15 +188,15 @@ def latToBddLatForgetAdjunction : latToBddLat.{u} ⊣ forget₂ BddLat Lat := match a with | none => f.map_top'.symm | some none => f.map_bot'.symm - | some (some a) => rfl - right_inv := fun f => LatticeHom.ext fun a => rfl } - homEquiv_naturality_left_symm := fun f g => + | some (some _) => rfl + right_inv := fun _ => LatticeHom.ext fun _ => rfl } + homEquiv_naturality_left_symm := fun _ _ => BoundedLatticeHom.ext fun a => match a with | none => rfl | some none => rfl - | some (some a) => rfl - homEquiv_naturality_right := fun f g => LatticeHom.ext fun a => rfl } + | some (some _) => rfl + homEquiv_naturality_right := fun _ _ => LatticeHom.ext fun _ => rfl } /-- `latToBddLat` and `OrderDual` commute. -/ -- Porting note: the `simpNF` linter is not happy as it simplifies something that does not diff --git a/Mathlib/Order/Category/BddOrd.lean b/Mathlib/Order/Category/BddOrd.lean index 2bab27e9532350..89e1c988b0e68d 100644 --- a/Mathlib/Order/Category/BddOrd.lean +++ b/Mathlib/Order/Category/BddOrd.lean @@ -68,7 +68,7 @@ instance concreteCategory : ConcreteCategory BddOrd where instance hasForgetToPartOrd : HasForget₂ BddOrd PartOrd where forget₂ := { obj := fun X => X.toPartOrd - map := fun {X Y} => BoundedOrderHom.toOrderHom } + map := fun {_ _} => BoundedOrderHom.toOrderHom } instance hasForgetToBipointed : HasForget₂ BddOrd Bipointed where forget₂ := @@ -80,7 +80,7 @@ instance hasForgetToBipointed : HasForget₂ BddOrd Bipointed where @[simps] def dual : BddOrd ⥤ BddOrd where obj X := of Xᵒᵈ - map {X Y} := BoundedOrderHom.dual + map {_ _} := BoundedOrderHom.dual /-- Constructs an equivalence between bounded orders from an order isomorphism between them. -/ @[simps] diff --git a/Mathlib/Order/Category/BoolAlg.lean b/Mathlib/Order/Category/BoolAlg.lean index e90e6e55aed901..42c66fcc0c103d 100644 --- a/Mathlib/Order/Category/BoolAlg.lean +++ b/Mathlib/Order/Category/BoolAlg.lean @@ -86,7 +86,7 @@ def Iso.mk {α β : BoolAlg.{u}} (e : α ≃o β) : α ≅ β where @[simps] def dual : BoolAlg ⥤ BoolAlg where obj X := of Xᵒᵈ - map {X Y} := BoundedLatticeHom.dual + map {_ _} := BoundedLatticeHom.dual /-- The equivalence between `BoolAlg` and itself induced by `OrderDual` both ways. -/ @[simps functor inverse] diff --git a/Mathlib/Order/Category/CompleteLat.lean b/Mathlib/Order/Category/CompleteLat.lean index 801b4f828293cb..f888d4a94b0f5d 100644 --- a/Mathlib/Order/Category/CompleteLat.lean +++ b/Mathlib/Order/Category/CompleteLat.lean @@ -54,7 +54,7 @@ instance : ConcreteCategory CompleteLat := by instance hasForgetToBddLat : HasForget₂ CompleteLat BddLat where forget₂ := { obj := fun X => BddLat.of X - map := fun {X Y} => CompleteLatticeHom.toBoundedLatticeHom } + map := fun {_ _} => CompleteLatticeHom.toBoundedLatticeHom } forget_comp := rfl /-- Constructs an isomorphism of complete lattices from an order isomorphism between them. -/ @@ -69,7 +69,7 @@ def Iso.mk {α β : CompleteLat.{u}} (e : α ≃o β) : α ≅ β where @[simps] def dual : CompleteLat ⥤ CompleteLat where obj X := of Xᵒᵈ - map {X Y} := CompleteLatticeHom.dual + map {_ _} := CompleteLatticeHom.dual /-- The equivalence between `CompleteLat` and itself induced by `OrderDual` both ways. -/ @[simps functor inverse] diff --git a/Mathlib/Order/Category/FinBddDistLat.lean b/Mathlib/Order/Category/FinBddDistLat.lean index b3dab1d7a23b9f..0747d3df364a15 100644 --- a/Mathlib/Order/Category/FinBddDistLat.lean +++ b/Mathlib/Order/Category/FinBddDistLat.lean @@ -82,7 +82,7 @@ example {X Y : FinBddDistLat} : (X ⟶ Y) = BoundedLatticeHom X Y := @[simps] def dual : FinBddDistLat ⥤ FinBddDistLat where obj X := of Xᵒᵈ - map {X Y} := BoundedLatticeHom.dual + map {_ _} := BoundedLatticeHom.dual /-- The equivalence between `FinBddDistLat` and itself induced by `OrderDual` both ways. -/ @[simps functor inverse] diff --git a/Mathlib/Order/Category/FinBoolAlg.lean b/Mathlib/Order/Category/FinBoolAlg.lean index 174cc8c0a1c03e..58791b31ec741e 100644 --- a/Mathlib/Order/Category/FinBoolAlg.lean +++ b/Mathlib/Order/Category/FinBoolAlg.lean @@ -126,7 +126,7 @@ def Iso.mk {α β : FinBoolAlg.{u}} (e : α ≃o β) : α ≅ β where @[simps] def dual : FinBoolAlg ⥤ FinBoolAlg where obj X := of Xᵒᵈ - map {X Y} := BoundedLatticeHom.dual + map {_ _} := BoundedLatticeHom.dual /-- The equivalence between `FinBoolAlg` and itself induced by `OrderDual` both ways. -/ @[simps functor inverse] diff --git a/Mathlib/Order/Category/FinPartOrd.lean b/Mathlib/Order/Category/FinPartOrd.lean index 5b90c8fa7d59da..e520e1b7399277 100644 --- a/Mathlib/Order/Category/FinPartOrd.lean +++ b/Mathlib/Order/Category/FinPartOrd.lean @@ -83,7 +83,7 @@ def Iso.mk {α β : FinPartOrd.{u}} (e : α ≃o β) : α ≅ β where @[simps] def dual : FinPartOrd ⥤ FinPartOrd where obj X := of Xᵒᵈ - map {X Y} := OrderHom.dual + map {_ _} := OrderHom.dual /-- The equivalence between `FinPartOrd` and itself induced by `OrderDual` both ways. -/ @[simps] diff --git a/Mathlib/Order/Category/Frm.lean b/Mathlib/Order/Category/Frm.lean index 4ece7379317182..f09b81f241c544 100644 --- a/Mathlib/Order/Category/Frm.lean +++ b/Mathlib/Order/Category/Frm.lean @@ -68,7 +68,7 @@ instance : ConcreteCategory Frm := by instance hasForgetToLat : HasForget₂ Frm Lat where forget₂ := { obj := fun X => ⟨X, _⟩ - map := fun {X Y} => FrameHom.toLatticeHom } + map := fun {_ _} => FrameHom.toLatticeHom } /-- Constructs an isomorphism of frames from an order isomorphism between them. -/ @[simps] @@ -89,7 +89,7 @@ end Frm def topCatOpToFrm : TopCatᵒᵖ ⥤ Frm where obj X := Frm.of (Opens (unop X : TopCat)) map f := Opens.comap <| Quiver.Hom.unop f - map_id X := Opens.comap_id + map_id _ := Opens.comap_id -- Note, `CompHaus` is too strong. We only need `T0Space`. instance CompHausOpToFrame.faithful : (compHausToTop.op ⋙ topCatOpToFrm.{u}).Faithful := diff --git a/Mathlib/Order/Category/NonemptyFinLinOrd.lean b/Mathlib/Order/Category/NonemptyFinLinOrd.lean index 3c6d13dec2f735..cfa1dab4252005 100644 --- a/Mathlib/Order/Category/NonemptyFinLinOrd.lean +++ b/Mathlib/Order/Category/NonemptyFinLinOrd.lean @@ -86,7 +86,7 @@ instance hasForgetToLinOrd : HasForget₂ NonemptyFinLinOrd LinOrd := instance hasForgetToFinPartOrd : HasForget₂ NonemptyFinLinOrd FinPartOrd where forget₂ := { obj := fun X => FinPartOrd.of X - map := @fun X Y => id } + map := @fun _ _ => id } /-- Constructs an equivalence between nonempty finite linear orders from an order isomorphism between them. -/ diff --git a/Mathlib/Order/Category/OmegaCompletePartialOrder.lean b/Mathlib/Order/Category/OmegaCompletePartialOrder.lean index c92cacfbb73aef..7a02ed603f9c1d 100644 --- a/Mathlib/Order/Category/OmegaCompletePartialOrder.lean +++ b/Mathlib/Order/Category/OmegaCompletePartialOrder.lean @@ -78,14 +78,14 @@ def product {J : Type v} (f : J → ωCPO.{v}) : Fan f := def isProduct (J : Type v) (f : J → ωCPO) : IsLimit (product f) where lift s := -- Porting note: Original proof didn't have `.toFun` - ⟨⟨fun t j => (s.π.app ⟨j⟩).toFun t, fun x y h j => (s.π.app ⟨j⟩).monotone h⟩, + ⟨⟨fun t j => (s.π.app ⟨j⟩).toFun t, fun _ _ h j => (s.π.app ⟨j⟩).monotone h⟩, fun x => funext fun j => (s.π.app ⟨j⟩).continuous x⟩ uniq s m w := by ext t; funext j -- Porting note: Originally `ext t j` change m.toFun t j = (s.π.app ⟨j⟩).toFun t rw [← w ⟨j⟩] rfl - fac s j := rfl + fac _ _ := rfl instance (J : Type v) (f : J → ωCPO.{v}) : HasProduct f := HasLimit.mk ⟨_, isProduct _ f⟩ @@ -119,7 +119,7 @@ def isEqualizer {X Y : ωCPO.{v}} (f g : X ⟶ Y) : IsLimit (equalizer f g) := Fork.IsLimit.mk' _ fun s => -- Porting note: Changed `s.ι x` to `s.ι.toFun x` ⟨{ toFun := fun x => ⟨s.ι.toFun x, by apply ContinuousHom.congr_fun s.condition⟩ - monotone' := fun x y h => s.ι.monotone h + monotone' := fun _ _ h => s.ι.monotone h map_ωSup' := fun x => Subtype.ext (s.ι.continuous x) }, by ext; rfl, fun hm => by apply ContinuousHom.ext _ _ fun x => Subtype.ext ?_ -- Porting note: Originally `ext` diff --git a/Mathlib/Order/Category/Semilat.lean b/Mathlib/Order/Category/Semilat.lean index 1d896ad622d2d3..94562309402376 100644 --- a/Mathlib/Order/Category/Semilat.lean +++ b/Mathlib/Order/Category/Semilat.lean @@ -152,7 +152,7 @@ def Iso.mk {α β : SemilatSupCat.{u}} (e : α ≃o β) : α ≅ β where @[simps] def dual : SemilatSupCat ⥤ SemilatInfCat where obj X := SemilatInfCat.of Xᵒᵈ - map {X Y} := SupBotHom.dual + map {_ _} := SupBotHom.dual end SemilatSupCat @@ -170,7 +170,7 @@ def Iso.mk {α β : SemilatInfCat.{u}} (e : α ≃o β) : α ≅ β where @[simps] def dual : SemilatInfCat ⥤ SemilatSupCat where obj X := SemilatSupCat.of Xᵒᵈ - map {X Y} := InfTopHom.dual + map {_ _} := InfTopHom.dual end SemilatInfCat diff --git a/Mathlib/Order/Circular.lean b/Mathlib/Order/Circular.lean index 3757b6709e94bd..cf1950b1cf1c70 100644 --- a/Mathlib/Order/Circular.lean +++ b/Mathlib/Order/Circular.lean @@ -346,7 +346,7 @@ See note [reducible non-instances]. -/ abbrev Preorder.toCircularPreorder (α : Type*) [Preorder α] : CircularPreorder α where btw a b c := a ≤ b ∧ b ≤ c ∨ b ≤ c ∧ c ≤ a ∨ c ≤ a ∧ a ≤ b sbtw a b c := a < b ∧ b < c ∨ b < c ∧ c < a ∨ c < a ∧ a < b - btw_refl a := Or.inl ⟨le_rfl, le_rfl⟩ + btw_refl _ := Or.inl ⟨le_rfl, le_rfl⟩ btw_cyclic_left {a b c} h := by dsimp rwa [← or_assoc, or_comm] diff --git a/Mathlib/Order/Closure.lean b/Mathlib/Order/Closure.lean index 53f361b143e1e8..ab229a68e246f2 100644 --- a/Mathlib/Order/Closure.lean +++ b/Mathlib/Order/Closure.lean @@ -202,7 +202,7 @@ theorem ext_isClosed (c₁ c₂ : ClosureOperator α) /-- A closure operator is equal to the closure operator obtained by feeding `c.closed` into the `ofPred` constructor. -/ theorem eq_ofPred_closed (c : ClosureOperator α) : - c = ofPred c c.IsClosed c.le_closure c.isClosed_closure fun x y ↦ closure_min := by + c = ofPred c c.IsClosed c.le_closure c.isClosed_closure fun _ _ ↦ closure_min := by ext rfl @@ -255,8 +255,8 @@ variable [CompleteLattice α] (c : ClosureOperator α) def ofCompletePred (p : α → Prop) (hsinf : ∀ s, (∀ a ∈ s, p a) → p (sInf s)) : ClosureOperator α := ofPred (fun a ↦ ⨅ b : {b // a ≤ b ∧ p b}, b) p (fun a ↦ by set_option tactic.skipAssignedInstances false in simp [forall_swap]) - (fun a ↦ hsinf _ <| forall_mem_range.2 fun b ↦ b.2.2) - (fun a b hab hb ↦ iInf_le_of_le ⟨b, hab, hb⟩ le_rfl) + (fun _ ↦ hsinf _ <| forall_mem_range.2 fun b ↦ b.2.2) + (fun _ b hab hb ↦ iInf_le_of_le ⟨b, hab, hb⟩ le_rfl) theorem sInf_isClosed {c : ClosureOperator α} {S : Set α} (H : ∀ x ∈ S, c.IsClosed x) : c.IsClosed (sInf S) := diff --git a/Mathlib/Order/CompactlyGenerated/Basic.lean b/Mathlib/Order/CompactlyGenerated/Basic.lean index 4fb6ec86d8fa8c..f3bc338a1d2ea6 100644 --- a/Mathlib/Order/CompactlyGenerated/Basic.lean +++ b/Mathlib/Order/CompactlyGenerated/Basic.lean @@ -350,7 +350,7 @@ theorem sSup_compact_eq_top : sSup { a : α | CompleteLattice.IsCompactElement a theorem le_iff_compact_le_imp {a b : α} : a ≤ b ↔ ∀ c : α, CompleteLattice.IsCompactElement c → c ≤ a → c ≤ b := - ⟨fun ab c _ ca => le_trans ca ab, fun h => by + ⟨fun ab _ _ ca => le_trans ca ab, fun h => by rw [← sSup_compact_le_eq a, ← sSup_compact_le_eq b] exact sSup_le_sSup fun c hc => ⟨hc.1, h c hc.1 hc.2⟩⟩ @@ -416,7 +416,7 @@ theorem inf_sSup_eq_iSup_inf_sup_finset : theorem CompleteLattice.setIndependent_iff_finite {s : Set α} : CompleteLattice.SetIndependent s ↔ ∀ t : Finset α, ↑t ⊆ s → CompleteLattice.SetIndependent (↑t : Set α) := - ⟨fun hs t ht => hs.mono ht, fun h a ha => by + ⟨fun hs _ ht => hs.mono ht, fun h a ha => by rw [disjoint_iff, inf_sSup_eq_iSup_inf_sup_finset, iSup_eq_bot] intro t rw [iSup_eq_bot, Finset.sup_id_eq_sSup] diff --git a/Mathlib/Order/Compare.lean b/Mathlib/Order/Compare.lean index 0fc1605e23a0dd..9fd8b1100315ff 100644 --- a/Mathlib/Order/Compare.lean +++ b/Mathlib/Order/Compare.lean @@ -52,18 +52,18 @@ theorem swap_eq_iff_eq_swap {o o' : Ordering} : o.swap = o' ↔ o = o'.swap := b rw [← swap_inj, swap_swap] theorem Compares.eq_lt [Preorder α] : ∀ {o} {a b : α}, Compares o a b → (o = lt ↔ a < b) - | lt, a, b, h => ⟨fun _ => h, fun _ => rfl⟩ + | lt, _, _, h => ⟨fun _ => h, fun _ => rfl⟩ | eq, a, b, h => ⟨fun h => by injection h, fun h' => (ne_of_lt h' h).elim⟩ | gt, a, b, h => ⟨fun h => by injection h, fun h' => (lt_asymm h h').elim⟩ theorem Compares.ne_lt [Preorder α] : ∀ {o} {a b : α}, Compares o a b → (o ≠ lt ↔ b ≤ a) - | lt, a, b, h => ⟨absurd rfl, fun h' => (not_le_of_lt h h').elim⟩ - | eq, a, b, h => ⟨fun _ => ge_of_eq h, fun _ h => by injection h⟩ - | gt, a, b, h => ⟨fun _ => le_of_lt h, fun _ h => by injection h⟩ + | lt, _, _, h => ⟨absurd rfl, fun h' => (not_le_of_lt h h').elim⟩ + | eq, _, _, h => ⟨fun _ => ge_of_eq h, fun _ h => by injection h⟩ + | gt, _, _, h => ⟨fun _ => le_of_lt h, fun _ h => by injection h⟩ theorem Compares.eq_eq [Preorder α] : ∀ {o} {a b : α}, Compares o a b → (o = eq ↔ a = b) | lt, a, b, h => ⟨fun h => by injection h, fun h' => (ne_of_lt h h').elim⟩ - | eq, a, b, h => ⟨fun _ => h, fun _ => rfl⟩ + | eq, _, _, h => ⟨fun _ => h, fun _ => rfl⟩ | gt, a, b, h => ⟨fun h => by injection h, fun h' => (ne_of_gt h h').elim⟩ theorem Compares.eq_gt [Preorder α] {o} {a b : α} (h : Compares o a b) : o = gt ↔ b < a := diff --git a/Mathlib/Order/CompleteBooleanAlgebra.lean b/Mathlib/Order/CompleteBooleanAlgebra.lean index 38fc91ba706394..8cec133540ae24 100644 --- a/Mathlib/Order/CompleteBooleanAlgebra.lean +++ b/Mathlib/Order/CompleteBooleanAlgebra.lean @@ -157,7 +157,7 @@ This sets `a ⇨ b := sSup {c | c ⊓ a ≤ b}` and `aᶜ := a ⇨ ⊥`. -/ abbrev ofMinimalAxioms (minAx : MinimalAxioms α) : Frame α where __ := minAx himp a b := sSup {c | c ⊓ a ≤ b} - le_himp_iff a b c := + le_himp_iff _ b c := ⟨fun h ↦ (inf_le_inf_right _ h).trans (by simp [minAx.sSup_inf_eq]), fun h ↦ le_sSup h⟩ himp_bot _ := rfl @@ -193,7 +193,7 @@ This sets `a \ b := sInf {c | a ≤ b ⊔ c}` and `¬a := ⊤ \ a`. -/ abbrev ofMinimalAxioms (minAx : MinimalAxioms α) : Coframe α where __ := minAx sdiff a b := sInf {c | a ≤ b ⊔ c} - sdiff_le_iff a b c := + sdiff_le_iff a b _ := ⟨fun h ↦ (sup_le_sup_left h _).trans' (by simp [minAx.sup_sInf_eq]), fun h ↦ sInf_le h⟩ top_sdiff _ := rfl diff --git a/Mathlib/Order/CompleteLattice.lean b/Mathlib/Order/CompleteLattice.lean index 87517a17d75440..ae7c9a34e17c82 100644 --- a/Mathlib/Order/CompleteLattice.lean +++ b/Mathlib/Order/CompleteLattice.lean @@ -204,7 +204,7 @@ def completeLatticeOfInf (α : Type*) [H1 : PartialOrder α] [H2 : InfSet α] (isGLB_sInf : ∀ s : Set α, IsGLB s (sInf s)) : CompleteLattice α where __ := H1; __ := H2 bot := sInf univ - bot_le x := (isGLB_sInf univ).1 trivial + bot_le _ := (isGLB_sInf univ).1 trivial top := sInf ∅ le_top a := (isGLB_sInf ∅).2 <| by simp sup a b := sInf { x : α | a ≤ x ∧ b ≤ x } @@ -212,16 +212,16 @@ def completeLatticeOfInf (α : Type*) [H1 : PartialOrder α] [H2 : InfSet α] le_inf a b c hab hac := by apply (isGLB_sInf _).2 simp [*] - inf_le_right a b := (isGLB_sInf _).1 <| mem_insert_of_mem _ <| mem_singleton _ - inf_le_left a b := (isGLB_sInf _).1 <| mem_insert _ _ + inf_le_right _ _ := (isGLB_sInf _).1 <| mem_insert_of_mem _ <| mem_singleton _ + inf_le_left _ _ := (isGLB_sInf _).1 <| mem_insert _ _ sup_le a b c hac hbc := (isGLB_sInf _).1 <| by simp [*] - le_sup_left a b := (isGLB_sInf _).2 fun x => And.left - le_sup_right a b := (isGLB_sInf _).2 fun x => And.right - le_sInf s a ha := (isGLB_sInf s).2 ha - sInf_le s a ha := (isGLB_sInf s).1 ha + le_sup_left _ _ := (isGLB_sInf _).2 fun _ => And.left + le_sup_right _ _ := (isGLB_sInf _).2 fun _ => And.right + le_sInf s _ ha := (isGLB_sInf s).2 ha + sInf_le s _ ha := (isGLB_sInf s).1 ha sSup s := sInf (upperBounds s) - le_sSup s a ha := (isGLB_sInf (upperBounds s)).2 fun b hb => hb ha - sSup_le s a ha := (isGLB_sInf (upperBounds s)).1 ha + le_sSup s _ ha := (isGLB_sInf (upperBounds s)).2 fun _ hb => hb ha + sSup_le s _ ha := (isGLB_sInf (upperBounds s)).1 ha /-- Any `CompleteSemilatticeInf` is in fact a `CompleteLattice`. @@ -251,22 +251,22 @@ def completeLatticeOfSup (α : Type*) [H1 : PartialOrder α] [H2 : SupSet α] (isLUB_sSup : ∀ s : Set α, IsLUB s (sSup s)) : CompleteLattice α where __ := H1; __ := H2 top := sSup univ - le_top x := (isLUB_sSup univ).1 trivial + le_top _ := (isLUB_sSup univ).1 trivial bot := sSup ∅ bot_le x := (isLUB_sSup ∅).2 <| by simp sup a b := sSup {a, b} sup_le a b c hac hbc := (isLUB_sSup _).2 (by simp [*]) - le_sup_left a b := (isLUB_sSup _).1 <| mem_insert _ _ - le_sup_right a b := (isLUB_sSup _).1 <| mem_insert_of_mem _ <| mem_singleton _ + le_sup_left _ _ := (isLUB_sSup _).1 <| mem_insert _ _ + le_sup_right _ _ := (isLUB_sSup _).1 <| mem_insert_of_mem _ <| mem_singleton _ inf a b := sSup { x | x ≤ a ∧ x ≤ b } le_inf a b c hab hac := (isLUB_sSup _).1 <| by simp [*] - inf_le_left a b := (isLUB_sSup _).2 fun x => And.left - inf_le_right a b := (isLUB_sSup _).2 fun x => And.right + inf_le_left _ _ := (isLUB_sSup _).2 fun _ => And.left + inf_le_right _ _ := (isLUB_sSup _).2 fun _ => And.right sInf s := sSup (lowerBounds s) - sSup_le s a ha := (isLUB_sSup s).2 ha - le_sSup s a ha := (isLUB_sSup s).1 ha - sInf_le s a ha := (isLUB_sSup (lowerBounds s)).2 fun b hb => hb ha - le_sInf s a ha := (isLUB_sSup (lowerBounds s)).1 ha + sSup_le s _ ha := (isLUB_sSup s).2 ha + le_sSup s _ ha := (isLUB_sSup s).1 ha + sInf_le s _ ha := (isLUB_sSup (lowerBounds s)).2 fun _ hb => hb ha + le_sInf s _ ha := (isLUB_sSup (lowerBounds s)).1 ha /-- Any `CompleteSemilatticeSup` is in fact a `CompleteLattice`. diff --git a/Mathlib/Order/CompleteLatticeIntervals.lean b/Mathlib/Order/CompleteLatticeIntervals.lean index 149df0ed5225da..814ddc87ae3d51 100644 --- a/Mathlib/Order/CompleteLatticeIntervals.lean +++ b/Mathlib/Order/CompleteLatticeIntervals.lean @@ -241,10 +241,10 @@ variable [CompleteLattice α] {a : α} instance instCompleteLattice : CompleteLattice (Iic a) where sSup S := ⟨sSup ((↑) '' S), by simpa using fun b hb _ ↦ hb⟩ sInf S := ⟨a ⊓ sInf ((↑) '' S), by simp⟩ - le_sSup S b hb := le_sSup <| mem_image_of_mem Subtype.val hb - sSup_le S b hb := sSup_le <| fun c' ⟨c, hc, hc'⟩ ↦ hc' ▸ hb c hc - sInf_le S b hb := inf_le_of_right_le <| sInf_le <| mem_image_of_mem Subtype.val hb - le_sInf S b hb := le_inf_iff.mpr ⟨b.property, le_sInf fun d' ⟨d, hd, hd'⟩ ↦ hd' ▸ hb d hd⟩ + le_sSup _ _ hb := le_sSup <| mem_image_of_mem Subtype.val hb + sSup_le _ _ hb := sSup_le <| fun _ ⟨c, hc, hc'⟩ ↦ hc' ▸ hb c hc + sInf_le _ _ hb := inf_le_of_right_le <| sInf_le <| mem_image_of_mem Subtype.val hb + le_sInf _ b hb := le_inf_iff.mpr ⟨b.property, le_sInf fun _ ⟨d, hd, hd'⟩ ↦ hd' ▸ hb d hd⟩ le_top := by simp bot_le := by simp diff --git a/Mathlib/Order/Concept.lean b/Mathlib/Order/Concept.lean index ea202e9b33def4..59acc56d37fcc9 100644 --- a/Mathlib/Order/Concept.lean +++ b/Mathlib/Order/Concept.lean @@ -222,8 +222,8 @@ theorem strictAnti_snd : StrictAnti (Prod.snd ∘ toProd : Concept α β r → S instance instLatticeConcept : Lattice (Concept α β r) := { Concept.instSemilatticeInfConcept with sup := (· ⊔ ·) - le_sup_left := fun c d => snd_subset_snd_iff.1 inter_subset_left - le_sup_right := fun c d => snd_subset_snd_iff.1 inter_subset_right + le_sup_left := fun _ _ => snd_subset_snd_iff.1 inter_subset_left + le_sup_right := fun _ _ => snd_subset_snd_iff.1 inter_subset_right sup_le := fun c d e => by simp_rw [← snd_subset_snd_iff] exact subset_inter } diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean b/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean index 7910ab0ffc59a3..f14480f908ed03 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean @@ -958,15 +958,15 @@ end ConditionallyCompleteLattice instance Pi.conditionallyCompleteLattice {ι : Type*} {α : ι → Type*} [∀ i, ConditionallyCompleteLattice (α i)] : ConditionallyCompleteLattice (∀ i, α i) := { Pi.instLattice, Pi.supSet, Pi.infSet with - le_csSup := fun s f ⟨g, hg⟩ hf i => - le_csSup ⟨g i, Set.forall_mem_range.2 fun ⟨f', hf'⟩ => hg hf' i⟩ ⟨⟨f, hf⟩, rfl⟩ - csSup_le := fun s f hs hf i => - (csSup_le (by haveI := hs.to_subtype; apply range_nonempty)) fun b ⟨⟨g, hg⟩, hb⟩ => + le_csSup := fun _ f ⟨g, hg⟩ hf i => + le_csSup ⟨g i, Set.forall_mem_range.2 fun ⟨_, hf'⟩ => hg hf' i⟩ ⟨⟨f, hf⟩, rfl⟩ + csSup_le := fun s _ hs hf i => + (csSup_le (by haveI := hs.to_subtype; apply range_nonempty)) fun _ ⟨⟨_, hg⟩, hb⟩ => hb ▸ hf hg i - csInf_le := fun s f ⟨g, hg⟩ hf i => - csInf_le ⟨g i, Set.forall_mem_range.2 fun ⟨f', hf'⟩ => hg hf' i⟩ ⟨⟨f, hf⟩, rfl⟩ - le_csInf := fun s f hs hf i => - (le_csInf (by haveI := hs.to_subtype; apply range_nonempty)) fun b ⟨⟨g, hg⟩, hb⟩ => + csInf_le := fun _ f ⟨g, hg⟩ hf i => + csInf_le ⟨g i, Set.forall_mem_range.2 fun ⟨_, hf'⟩ => hg hf' i⟩ ⟨⟨f, hf⟩, rfl⟩ + le_csInf := fun s _ hs hf i => + (le_csInf (by haveI := hs.to_subtype; apply range_nonempty)) fun _ ⟨⟨_, hg⟩, hb⟩ => hb ▸ hf hg i } section ConditionallyCompleteLinearOrder @@ -1578,7 +1578,7 @@ open Classical in noncomputable instance WithTop.WithBot.completeLattice {α : Type*} [ConditionallyCompleteLattice α] : CompleteLattice (WithTop (WithBot α)) := { instInfSet, instSupSet, boundedOrder, lattice with - le_sSup := fun S a haS => (WithTop.isLUB_sSup' ⟨a, haS⟩).1 haS + le_sSup := fun _ a haS => (WithTop.isLUB_sSup' ⟨a, haS⟩).1 haS sSup_le := fun S a ha => by rcases S.eq_empty_or_nonempty with h | h · show ite _ _ _ ≤ a @@ -1610,7 +1610,7 @@ noncomputable instance WithTop.WithBot.completeLattice {α : Type*} use ⊥ intro b _ exact bot_le - le_sInf := fun S a haS => (WithTop.isGLB_sInf' ⟨a, haS⟩).2 haS } + le_sInf := fun _ a haS => (WithTop.isGLB_sInf' ⟨a, haS⟩).2 haS } noncomputable instance WithTop.WithBot.completeLinearOrder {α : Type*} [ConditionallyCompleteLinearOrder α] : CompleteLinearOrder (WithTop (WithBot α)) := diff --git a/Mathlib/Order/Filter/AtTopBot.lean b/Mathlib/Order/Filter/AtTopBot.lean index 18b4a5cf5790c1..131acf974c0aca 100644 --- a/Mathlib/Order/Filter/AtTopBot.lean +++ b/Mathlib/Order/Filter/AtTopBot.lean @@ -978,12 +978,12 @@ theorem tendsto_comp_val_Iic_atBot [Preorder α] [IsDirected α (· ≥ ·)] tendsto_comp_val_Ici_atTop (α := αᵒᵈ) theorem map_add_atTop_eq_nat (k : ℕ) : map (fun a => a + k) atTop = atTop := - map_atTop_eq_of_gc (· - k) k (fun a b h => Nat.add_le_add_right h k) - (fun a b h => (Nat.le_sub_iff_add_le h).symm) fun a h => by rw [Nat.sub_add_cancel h] + map_atTop_eq_of_gc (· - k) k (fun _ _ h => Nat.add_le_add_right h k) + (fun _ _ h => (Nat.le_sub_iff_add_le h).symm) fun a h => by rw [Nat.sub_add_cancel h] theorem map_sub_atTop_eq_nat (k : ℕ) : map (fun a => a - k) atTop = atTop := - map_atTop_eq_of_gc (· + k) 0 (fun a b h => Nat.sub_le_sub_right h _) - (fun a b _ => Nat.sub_le_iff_le_add) fun b _ => by rw [Nat.add_sub_cancel_right] + map_atTop_eq_of_gc (· + k) 0 (fun _ _ h => Nat.sub_le_sub_right h _) + (fun _ _ _ => Nat.sub_le_iff_le_add) fun b _ => by rw [Nat.add_sub_cancel_right] theorem tendsto_add_atTop_nat (k : ℕ) : Tendsto (fun a => a + k) atTop atTop := le_of_eq (map_add_atTop_eq_nat k) @@ -997,7 +997,7 @@ theorem tendsto_add_atTop_iff_nat {f : ℕ → α} {l : Filter α} (k : ℕ) : rw [← tendsto_map'_iff, map_add_atTop_eq_nat] theorem map_div_atTop_eq_nat (k : ℕ) (hk : 0 < k) : map (fun a => a / k) atTop = atTop := - map_atTop_eq_of_gc (fun b => k * b + (k - 1)) 1 (fun a b h => Nat.div_le_div_right h) + map_atTop_eq_of_gc (fun b => k * b + (k - 1)) 1 (fun _ _ h => Nat.div_le_div_right h) -- Porting note: there was a parse error in `calc`, use `simp` instead (fun a b _ => by rw [Nat.div_le_iff_le_mul_add_pred hk]) fun b _ => by rw [Nat.mul_add_div hk, Nat.div_eq_of_lt, add_zero]; omega diff --git a/Mathlib/Order/Filter/Basic.lean b/Mathlib/Order/Filter/Basic.lean index 85fed348f70354..c0377331e71f58 100644 --- a/Mathlib/Order/Filter/Basic.lean +++ b/Mathlib/Order/Filter/Basic.lean @@ -954,7 +954,7 @@ lemma frequently_mem_iff_neBot {l : Filter α} {s : Set α} : (∃ᶠ x in l, x theorem frequently_iff_forall_eventually_exists_and {p : α → Prop} {f : Filter α} : (∃ᶠ x in f, p x) ↔ ∀ {q : α → Prop}, (∀ᶠ x in f, q x) → ∃ x, p x ∧ q x := - ⟨fun hp q hq => (hp.and_eventually hq).exists, fun H hp => by + ⟨fun hp _ hq => (hp.and_eventually hq).exists, fun H hp => by simpa only [and_not_self_iff, exists_false] using H hp⟩ theorem frequently_iff {f : Filter α} {P : α → Prop} : @@ -1498,7 +1498,7 @@ variable {f : α → β} {l : Filter β} {p : α → Prop} {s : Set α} theorem mem_comap' : s ∈ comap f l ↔ { y | ∀ ⦃x⦄, f x = y → x ∈ s } ∈ l := ⟨fun ⟨t, ht, hts⟩ => mem_of_superset ht fun y hy x hx => hts <| mem_preimage.2 <| by rwa [hx], - fun h => ⟨_, h, fun x hx => hx rfl⟩⟩ + fun h => ⟨_, h, fun _ hx => hx rfl⟩⟩ -- TODO: it would be nice to use `kernImage` much more to take advantage of common name and API, -- and then this would become `mem_comap'` diff --git a/Mathlib/Order/Filter/EventuallyConst.lean b/Mathlib/Order/Filter/EventuallyConst.lean index be981a5e721425..3ec97fbbb55012 100644 --- a/Mathlib/Order/Filter/EventuallyConst.lean +++ b/Mathlib/Order/Filter/EventuallyConst.lean @@ -155,7 +155,7 @@ end EventuallyConst lemma eventuallyConst_atTop [SemilatticeSup α] [Nonempty α] : EventuallyConst f atTop ↔ (∃ i, ∀ j, i ≤ j → f j = f i) := - (atTop_basis.eventuallyConst_iff' fun i _ ↦ left_mem_Ici).trans <| by + (atTop_basis.eventuallyConst_iff' fun _ _ ↦ left_mem_Ici).trans <| by simp only [true_and, mem_Ici] lemma eventuallyConst_atTop_nat {f : ℕ → α} : diff --git a/Mathlib/Order/Filter/FilterProduct.lean b/Mathlib/Order/Filter/FilterProduct.lean index 4e69166e08aea5..c36a347ed094fd 100644 --- a/Mathlib/Order/Filter/FilterProduct.lean +++ b/Mathlib/Order/Filter/FilterProduct.lean @@ -39,20 +39,20 @@ instance instGroupWithZero [GroupWithZero β] : GroupWithZero β* where __ := instDivInvMonoid __ := instMonoidWithZero mul_inv_cancel f := inductionOn f fun f hf ↦ coe_eq.2 <| (φ.em fun y ↦ f y = 0).elim - (fun H ↦ (hf <| coe_eq.2 H).elim) fun H ↦ H.mono fun x ↦ mul_inv_cancel₀ + (fun H ↦ (hf <| coe_eq.2 H).elim) fun H ↦ H.mono fun _ ↦ mul_inv_cancel₀ inv_zero := coe_eq.2 <| by simp only [Function.comp_def, inv_zero, EventuallyEq.rfl] instance instDivisionSemiring [DivisionSemiring β] : DivisionSemiring β* where toSemiring := instSemiring __ := instGroupWithZero nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl instance instDivisionRing [DivisionRing β] : DivisionRing β* where __ := instRing __ := instDivisionSemiring qsmul := _ - qsmul_def := fun q a => rfl + qsmul_def := fun _ _ => rfl instance instSemifield [Semifield β] : Semifield β* where __ := instCommSemiring diff --git a/Mathlib/Order/Filter/Germ/Basic.lean b/Mathlib/Order/Filter/Germ/Basic.lean index ec0c18e57cedf3..30542abc2fd0bb 100644 --- a/Mathlib/Order/Filter/Germ/Basic.lean +++ b/Mathlib/Order/Filter/Germ/Basic.lean @@ -690,7 +690,7 @@ theorem const_le_iff [LE β] [NeBot l] {x y : β} : (↑x : Germ l β) ≤ ↑y instance instPreorder [Preorder β] : Preorder (Germ l β) where le := (· ≤ ·) le_refl f := inductionOn f <| EventuallyLE.refl l - le_trans f₁ f₂ f₃ := inductionOn₃ f₁ f₂ f₃ fun f₁ f₂ f₃ => EventuallyLE.trans + le_trans f₁ f₂ f₃ := inductionOn₃ f₁ f₂ f₃ fun _ _ _ => EventuallyLE.trans instance instPartialOrder [PartialOrder β] : PartialOrder (Germ l β) where le_antisymm f g := inductionOn₂ f g fun _ _ h₁ h₂ ↦ (EventuallyLE.antisymm h₁ h₂).germ_eq diff --git a/Mathlib/Order/Filter/Pi.lean b/Mathlib/Order/Filter/Pi.lean index 147840d30d0260..50cf2341b3b4ec 100644 --- a/Mathlib/Order/Filter/Pi.lean +++ b/Mathlib/Order/Filter/Pi.lean @@ -152,7 +152,7 @@ theorem pi_inf_principal_pi_neBot [∀ i, NeBot (f i)] {I : Set ι} : instance PiInfPrincipalPi.neBot [h : ∀ i, NeBot (f i ⊓ 𝓟 (s i))] {I : Set ι} : NeBot (pi f ⊓ 𝓟 (I.pi s)) := (pi_inf_principal_univ_pi_neBot.2 ‹_›).mono <| - inf_le_inf_left _ <| principal_mono.2 fun x hx i _ => hx i trivial + inf_le_inf_left _ <| principal_mono.2 fun _ hx i _ => hx i trivial @[simp] theorem pi_eq_bot : pi f = ⊥ ↔ ∃ i, f i = ⊥ := by diff --git a/Mathlib/Order/Filter/Pointwise.lean b/Mathlib/Order/Filter/Pointwise.lean index a1c46ad3a9f3f1..478f544d72b32e 100644 --- a/Mathlib/Order/Filter/Pointwise.lean +++ b/Mathlib/Order/Filter/Pointwise.lean @@ -612,11 +612,11 @@ protected theorem mul_eq_one_iff : f * g = 1 ↔ ∃ a b, f = pure a ∧ g = pur `α` is."] protected def divisionMonoid : DivisionMonoid (Filter α) := { Filter.monoid, Filter.instInvolutiveInv, Filter.instDiv, Filter.instZPow (α := α) with - mul_inv_rev := fun s t => map_map₂_antidistrib mul_inv_rev + mul_inv_rev := fun _ _ => map_map₂_antidistrib mul_inv_rev inv_eq_of_mul := fun s t h => by obtain ⟨a, b, rfl, rfl, hab⟩ := Filter.mul_eq_one_iff.1 h rw [inv_pure, inv_eq_of_mul_eq_one_right hab] - div_eq_mul_inv := fun f g => map_map₂_distrib_right div_eq_mul_inv } + div_eq_mul_inv := fun _ _ => map_map₂_distrib_right div_eq_mul_inv } @[to_additive] theorem isUnit_iff : IsUnit f ↔ ∃ a, f = pure a ∧ IsUnit a := by @@ -1043,7 +1043,7 @@ instance isCentralScalar [SMul α β] [SMul αᵐᵒᵖ β] [IsCentralScalar α of `Filter α` on `Filter β`"] protected def mulAction [Monoid α] [MulAction α β] : MulAction (Filter α) (Filter β) where one_smul f := map₂_pure_left.trans <| by simp_rw [one_smul, map_id'] - mul_smul f g h := map₂_assoc mul_smul + mul_smul _ _ _ := map₂_assoc mul_smul /-- A multiplicative action of a monoid on a type `β` gives a multiplicative action on `Filter β`. -/ diff --git a/Mathlib/Order/Filter/SmallSets.lean b/Mathlib/Order/Filter/SmallSets.lean index fe284b82bd719a..1e40a2da092eb3 100644 --- a/Mathlib/Order/Filter/SmallSets.lean +++ b/Mathlib/Order/Filter/SmallSets.lean @@ -150,7 +150,7 @@ theorem eventually_smallSets_eventually {p : α → Prop} : (∀ᶠ s in l.smallSets, ∀ᶠ x in l', x ∈ s → p x) ↔ ∀ᶠ x in l ⊓ l', p x := calc _ ↔ ∃ s ∈ l, ∀ᶠ x in l', x ∈ s → p x := - eventually_smallSets' fun s t hst ht => ht.mono fun x hx hs => hx (hst hs) + eventually_smallSets' fun _ _ hst ht => ht.mono fun _ hx hs => hx (hst hs) _ ↔ ∃ s ∈ l, ∃ t ∈ l', ∀ x, x ∈ t → x ∈ s → p x := by simp only [eventually_iff_exists_mem] _ ↔ ∀ᶠ x in l ⊓ l', p x := by simp only [eventually_inf, and_comm, mem_inter_iff, ← and_imp] diff --git a/Mathlib/Order/Filter/Ultrafilter.lean b/Mathlib/Order/Filter/Ultrafilter.lean index 6f238409f1d35a..e480d43fb294ca 100644 --- a/Mathlib/Order/Filter/Ultrafilter.lean +++ b/Mathlib/Order/Filter/Ultrafilter.lean @@ -119,7 +119,7 @@ theorem diff_mem_iff (f : Ultrafilter α) : s \ t ∈ f ↔ s ∈ f ∧ t ∉ f def ofComplNotMemIff (f : Filter α) (h : ∀ s, sᶜ ∉ f ↔ s ∈ f) : Ultrafilter α where toFilter := f neBot' := ⟨fun hf => by simp [hf] at h⟩ - le_of_le g hg hgf s hs := (h s).1 fun hsc => compl_not_mem hs (hgf hsc) + le_of_le _ _ hgf s hs := (h s).1 fun hsc => compl_not_mem hs (hgf hsc) /-- If `f : Filter α` is an atom, then it is an ultrafilter. -/ def ofAtom (f : Filter α) (hf : IsAtom f) : Ultrafilter α where diff --git a/Mathlib/Order/GaloisConnection.lean b/Mathlib/Order/GaloisConnection.lean index 95ba690deb3fb4..d4ea55c673a62a 100644 --- a/Mathlib/Order/GaloisConnection.lean +++ b/Mathlib/Order/GaloisConnection.lean @@ -551,7 +551,7 @@ abbrev liftSemilatticeSup [SemilatticeSup α] (gi : GaloisInsertion l u) : Semil sup := fun a b => l (u a ⊔ u b) le_sup_left := fun a _ => (gi.le_l_u a).trans <| gi.gc.monotone_l <| le_sup_left le_sup_right := fun _ b => (gi.le_l_u b).trans <| gi.gc.monotone_l <| le_sup_right - sup_le := fun a b c hac hbc => + sup_le := fun _ _ _ hac hbc => gi.gc.l_le <| sup_le (gi.gc.monotone_u hac) (gi.gc.monotone_u hbc) } -- See note [reducible non instances] @@ -593,8 +593,8 @@ abbrev liftBoundedOrder [Preorder α] [BoundedOrder α] (gi : GaloisInsertion l abbrev liftCompleteLattice [CompleteLattice α] (gi : GaloisInsertion l u) : CompleteLattice β := { gi.liftBoundedOrder, gi.liftLattice with sSup := fun s => l (sSup (u '' s)) - sSup_le := fun s => (gi.isLUB_of_u_image (isLUB_sSup _)).2 - le_sSup := fun s => (gi.isLUB_of_u_image (isLUB_sSup _)).1 + sSup_le := fun _ => (gi.isLUB_of_u_image (isLUB_sSup _)).2 + le_sSup := fun _ => (gi.isLUB_of_u_image (isLUB_sSup _)).1 sInf := fun s => gi.choice (sInf (u '' s)) <| (isGLB_sInf _).2 <| diff --git a/Mathlib/Order/Heyting/Basic.lean b/Mathlib/Order/Heyting/Basic.lean index 199354c730cffd..392c6569e8911a 100644 --- a/Mathlib/Order/Heyting/Basic.lean +++ b/Mathlib/Order/Heyting/Basic.lean @@ -183,7 +183,7 @@ abbrev HeytingAlgebra.ofHImp [DistribLattice α] [BoundedOrder α] (himp : α himp, compl := fun a => himp a ⊥, le_himp_iff, - himp_bot := fun a => rfl } + himp_bot := fun _ => rfl } -- See note [reducible non-instances] /-- Construct a Heyting algebra from the lattice structure and complement operator alone. -/ @@ -202,7 +202,7 @@ abbrev CoheytingAlgebra.ofSDiff [DistribLattice α] [BoundedOrder α] (sdiff : sdiff, hnot := fun a => sdiff ⊤ a, sdiff_le_iff, - top_sdiff := fun a => rfl } + top_sdiff := fun _ => rfl } -- See note [reducible non-instances] /-- Construct a co-Heyting algebra from the difference and Heyting negation alone. -/ @@ -943,14 +943,14 @@ abbrev LinearOrder.toBiheytingAlgebra [LinearOrder α] [BoundedOrder α] : Bihey split_ifs with h · exact iff_of_true le_top (inf_le_of_right_le h) · rw [inf_le_iff, or_iff_left h], - himp_bot := fun a => if_congr le_bot_iff rfl rfl, sdiff := fun a b => if a ≤ b then ⊥ else a, + himp_bot := fun _ => if_congr le_bot_iff rfl rfl, sdiff := fun a b => if a ≤ b then ⊥ else a, hnot := fun a => if a = ⊤ then ⊥ else ⊤, sdiff_le_iff := fun a b c => by change ite _ _ _ ≤ _ ↔ _ split_ifs with h · exact iff_of_true bot_le (le_sup_of_le_left h) · rw [le_sup_iff, or_iff_right h], - top_sdiff := fun a => if_congr top_le_iff rfl rfl } + top_sdiff := fun _ => if_congr top_le_iff rfl rfl } instance OrderDual.instBiheytingAlgebra [BiheytingAlgebra α] : BiheytingAlgebra αᵒᵈ where __ := instHeytingAlgebra diff --git a/Mathlib/Order/Heyting/Regular.lean b/Mathlib/Order/Heyting/Regular.lean index 98043e41c3ecfa..6b8a0c8a59808b 100644 --- a/Mathlib/Order/Heyting/Regular.lean +++ b/Mathlib/Order/Heyting/Regular.lean @@ -79,10 +79,10 @@ abbrev _root_.BooleanAlgebra.ofRegular (h : ∀ a : α, IsRegular (a ⊔ aᶜ)) codisjoint_iff.2 <| by rw [← (h a), compl_sup, inf_compl_eq_bot, compl_bot]⟩ { ‹HeytingAlgebra α›, GeneralizedHeytingAlgebra.toDistribLattice with - himp_eq := fun a b => + himp_eq := fun _ _ => eq_of_forall_le_iff fun _ => le_himp_iff.trans (this _).le_sup_right_iff_inf_left_le.symm - inf_compl_le_bot := fun a => (this _).1.le_bot - top_le_sup_compl := fun a => (this _).2.top_le } + inf_compl_le_bot := fun _ => (this _).1.le_bot + top_le_sup_compl := fun _ => (this _).2.top_le } variable (α) @@ -198,7 +198,7 @@ instance : BooleanAlgebra (Regular α) := coe_le_coe.1 <| by dsimp rw [sup_inf_left, compl_compl_inf_distrib] - inf_compl_le_bot := fun a => coe_le_coe.1 <| disjoint_iff_inf_le.1 disjoint_compl_right + inf_compl_le_bot := fun _ => coe_le_coe.1 <| disjoint_iff_inf_le.1 disjoint_compl_right top_le_sup_compl := fun a => coe_le_coe.1 <| by dsimp diff --git a/Mathlib/Order/Hom/Order.lean b/Mathlib/Order/Hom/Order.lean index c2db9e632bb029..a1bc51bc10dd59 100644 --- a/Mathlib/Order/Hom/Order.lean +++ b/Mathlib/Order/Hom/Order.lean @@ -116,10 +116,10 @@ instance [CompleteLattice β] : CompleteLattice (α →o β) := -- sSup := SupSet.sSup -- Porting note: removed, unnecessary? -- Porting note: Added `by apply`, was `fun s f hf x => le_iSup_of_le f (le_iSup _ hf)` le_sSup := fun s f hf x => le_iSup_of_le f (by apply le_iSup _ hf) - sSup_le := fun s f hf x => iSup₂_le fun g hg => hf g hg x + sSup_le := fun _ _ hf x => iSup₂_le fun g hg => hf g hg x --inf := sInf -- Porting note: removed, unnecessary? - le_sInf := fun s f hf x => le_iInf₂ fun g hg => hf g hg x - sInf_le := fun s f hf x => iInf_le_of_le f (iInf_le _ hf) + le_sInf := fun _ _ hf x => le_iInf₂ fun g hg => hf g hg x + sInf_le := fun _ f hf _ => iInf_le_of_le f (iInf_le _ hf) } theorem iterate_sup_le_sup_iff {α : Type*} [SemilatticeSup α] (f : α →o α) : diff --git a/Mathlib/Order/Ideal.lean b/Mathlib/Order/Ideal.lean index 3e6b195981b8fb..9fe09de57fd26b 100644 --- a/Mathlib/Order/Ideal.lean +++ b/Mathlib/Order/Ideal.lean @@ -345,7 +345,7 @@ instance : Sup (Ideal P) := y ≤ yi ⊔ yj := ‹_› _ ≤ xi ⊔ yi ⊔ (xj ⊔ yj) := sup_le_sup le_sup_right le_sup_right)⟩, le_sup_left, le_sup_right⟩ - lower' := fun x y h ⟨yi, hi, yj, hj, hxy⟩ ↦ ⟨yi, hi, yj, hj, h.trans hxy⟩ }⟩ + lower' := fun _ _ h ⟨yi, hi, yj, hj, hxy⟩ ↦ ⟨yi, hi, yj, hj, h.trans hxy⟩ }⟩ instance : Lattice (Ideal P) := { Ideal.instPartialOrderIdeal with diff --git a/Mathlib/Order/InitialSeg.lean b/Mathlib/Order/InitialSeg.lean index cfc294fcbe01cf..513501c25072e6 100644 --- a/Mathlib/Order/InitialSeg.lean +++ b/Mathlib/Order/InitialSeg.lean @@ -119,7 +119,7 @@ theorem exists_eq_iff_rel (f : r ≼i s) {a : α} {b : β} : s b (f a) ↔ ∃ a ⟨fun h => by rcases f.mem_range_of_rel h with ⟨a', rfl⟩ exact ⟨a', rfl, f.map_rel_iff.1 h⟩, - fun ⟨a', e, h⟩ => e ▸ f.map_rel_iff.2 h⟩ + fun ⟨_, e, h⟩ => e ▸ f.map_rel_iff.2 h⟩ @[deprecated exists_eq_iff_rel (since := "2024-09-21")] alias init_iff := exists_eq_iff_rel @@ -547,7 +547,7 @@ theorem collapseF.not_lt [IsWellOrder β s] (f : r ↪r s) (a : α) {b} to fill the gaps. -/ noncomputable def collapse [IsWellOrder β s] (f : r ↪r s) : r ≼i s := haveI := RelEmbedding.isWellOrder f - ⟨RelEmbedding.ofMonotone (fun a => (collapseF f a).1) fun a b => collapseF.lt f, fun a b => + ⟨RelEmbedding.ofMonotone (fun a => (collapseF f a).1) fun _ _ => collapseF.lt f, fun a b => Acc.recOn (IsWellFounded.wf.apply b : Acc s b) (fun b _ _ a h => by rcases (@IsWellFounded.wf _ r).has_min { a | ¬s (collapseF f a).1 b } diff --git a/Mathlib/Order/Interval/Basic.lean b/Mathlib/Order/Interval/Basic.lean index b2c3ac1ca1c31b..83018f19646dc8 100644 --- a/Mathlib/Order/Interval/Basic.lean +++ b/Mathlib/Order/Interval/Basic.lean @@ -470,7 +470,7 @@ instance lattice : Lattice (Interval α) := match s, t with | ⊥, ⊥ => bot_le | ⊥, some _ => bot_le - | some s, ⊥ => bot_le + | some _, ⊥ => bot_le | some s, some t => by change dite _ _ _ ≤ _ split_ifs @@ -479,7 +479,7 @@ instance lattice : Lattice (Interval α) := inf_le_right := fun s t => match s, t with | ⊥, ⊥ => bot_le - | ⊥, some t => bot_le + | ⊥, some _ => bot_le | some _, ⊥ => bot_le | some s, some t => by change dite _ _ _ ≤ _ @@ -488,7 +488,7 @@ instance lattice : Lattice (Interval α) := · exact bot_le le_inf := fun s t c => match s, t, c with - | ⊥, t, c => fun _ _ => bot_le + | ⊥, _, _ => fun _ _ => bot_le | (s : NonemptyInterval α), t, c => fun hb hc => by lift t to NonemptyInterval α using ne_bot_of_le_ne_bot WithBot.coe_ne_bot hb lift c to NonemptyInterval α using ne_bot_of_le_ne_bot WithBot.coe_ne_bot hc diff --git a/Mathlib/Order/Interval/Finset/Defs.lean b/Mathlib/Order/Interval/Finset/Defs.lean index d81c2dec0066ca..4957140ea58934 100644 --- a/Mathlib/Order/Interval/Finset/Defs.lean +++ b/Mathlib/Order/Interval/Finset/Defs.lean @@ -875,8 +875,8 @@ instance locallyFiniteOrder : LocallyFiniteOrder (WithTop α) where -- Porting note: the proofs below got much worse finset_mem_Icc a b x := match a, b, x with - | ⊤, ⊤, x => mem_singleton.trans (le_antisymm_iff.trans and_comm) - | ⊤, (b : α), x => + | ⊤, ⊤, _ => mem_singleton.trans (le_antisymm_iff.trans and_comm) + | ⊤, (b : α), _ => iff_of_false (not_mem_empty _) fun h => (h.1.trans h.2).not_lt <| coe_lt_top _ | (a : α), ⊤, ⊤ => by simp [WithTop.some, WithTop.top, insertNone] | (a : α), ⊤, (x : α) => by @@ -891,7 +891,7 @@ instance locallyFiniteOrder : LocallyFiniteOrder (WithTop α) where erw [aux] finset_mem_Ico a b x := match a, b, x with - | ⊤, b, x => iff_of_false (not_mem_empty _) fun h => not_top_lt <| h.1.trans_lt h.2 + | ⊤, _, _ => iff_of_false (not_mem_empty _) fun h => not_top_lt <| h.1.trans_lt h.2 | (a : α), ⊤, ⊤ => by simp [some, Embedding.some] | (a : α), ⊤, (x : α) => by simp only [Embedding.some, mem_map, mem_Ici, Embedding.coeFn_mk, coe_le_coe, aux, @@ -905,7 +905,7 @@ instance locallyFiniteOrder : LocallyFiniteOrder (WithTop α) where erw [aux] finset_mem_Ioc a b x := match a, b, x with - | ⊤, b, x => iff_of_false (not_mem_empty _) fun h => not_top_lt <| h.1.trans_le h.2 + | ⊤, _, _ => iff_of_false (not_mem_empty _) fun h => not_top_lt <| h.1.trans_le h.2 | (a : α), ⊤, ⊤ => by simp [some, insertNone, top] | (a : α), ⊤, (x : α) => by simp [some, Embedding.some, insertNone, aux] -- This used to be in the above `simp` before @@ -918,7 +918,7 @@ instance locallyFiniteOrder : LocallyFiniteOrder (WithTop α) where erw [aux] finset_mem_Ioo a b x := match a, b, x with - | ⊤, b, x => iff_of_false (not_mem_empty _) fun h => not_top_lt <| h.1.trans h.2 + | ⊤, _, _ => iff_of_false (not_mem_empty _) fun h => not_top_lt <| h.1.trans h.2 | (a : α), ⊤, ⊤ => by simp [some, Embedding.some, insertNone] | (a : α), ⊤, (x : α) => by simp [some, Embedding.some, insertNone, aux, top] -- This used to be in the above `simp` before diff --git a/Mathlib/Order/Interval/Set/Basic.lean b/Mathlib/Order/Interval/Set/Basic.lean index 0be1e96eff231d..aa5fb56defb3c1 100644 --- a/Mathlib/Order/Interval/Set/Basic.lean +++ b/Mathlib/Order/Interval/Set/Basic.lean @@ -753,7 +753,7 @@ theorem mem_Ici_Ioi_of_subset_of_subset {s : Set α} (ho : Ioi a ⊆ s) (hc : s (fun h : a ∈ s => Or.inl <| Subset.antisymm hc <| by rw [← Ioi_union_left, union_subset_iff]; simp [*]) fun h => - Or.inr <| Subset.antisymm (fun x hx => lt_of_le_of_ne (hc hx) fun heq => h <| heq.symm ▸ hx) ho + Or.inr <| Subset.antisymm (fun _ hx => lt_of_le_of_ne (hc hx) fun heq => h <| heq.symm ▸ hx) ho theorem mem_Iic_Iio_of_subset_of_subset {s : Set α} (ho : Iio a ⊆ s) (hc : s ⊆ Iic a) : s ∈ ({Iic a, Iio a} : Set (Set α)) := diff --git a/Mathlib/Order/Interval/Set/OrderIso.lean b/Mathlib/Order/Interval/Set/OrderIso.lean index e125b788f0d480..b23c2799a05f45 100644 --- a/Mathlib/Order/Interval/Set/OrderIso.lean +++ b/Mathlib/Order/Interval/Set/OrderIso.lean @@ -90,12 +90,12 @@ end Preorder /-- Order isomorphism between `Iic (⊤ : α)` and `α` when `α` has a top element -/ def IicTop {α : Type*} [Preorder α] [OrderTop α] : Iic (⊤ : α) ≃o α := - { @Equiv.subtypeUnivEquiv α (Iic (⊤ : α)) fun x => le_top with + { @Equiv.subtypeUnivEquiv α (Iic (⊤ : α)) fun _ => le_top with map_rel_iff' := @fun x y => by rfl } /-- Order isomorphism between `Ici (⊥ : α)` and `α` when `α` has a bottom element -/ def IciBot {α : Type*} [Preorder α] [OrderBot α] : Ici (⊥ : α) ≃o α := - { @Equiv.subtypeUnivEquiv α (Ici (⊥ : α)) fun x => bot_le with + { @Equiv.subtypeUnivEquiv α (Ici (⊥ : α)) fun _ => bot_le with map_rel_iff' := @fun x y => by rfl } end OrderIso diff --git a/Mathlib/Order/Interval/Set/Pi.lean b/Mathlib/Order/Interval/Set/Pi.lean index 524744496cce61..3d63a7437ca290 100644 --- a/Mathlib/Order/Interval/Set/Pi.lean +++ b/Mathlib/Order/Interval/Set/Pi.lean @@ -51,7 +51,7 @@ theorem piecewise_mem_Icc' {s : Set ι} [∀ j, Decidable (j ∈ s)] {f₁ f₂ section Nonempty -theorem pi_univ_Ioi_subset [Nonempty ι]: (pi univ fun i ↦ Ioi (x i)) ⊆ Ioi x := fun z hz ↦ +theorem pi_univ_Ioi_subset [Nonempty ι]: (pi univ fun i ↦ Ioi (x i)) ⊆ Ioi x := fun _ hz ↦ ⟨fun i ↦ le_of_lt <| hz i trivial, fun h ↦ (‹Nonempty ι›.elim) fun i ↦ not_lt_of_le (h i) (hz i trivial)⟩ diff --git a/Mathlib/Order/OmegaCompletePartialOrder.lean b/Mathlib/Order/OmegaCompletePartialOrder.lean index 911cd139607e1a..0d7b0cf6a38043 100644 --- a/Mathlib/Order/OmegaCompletePartialOrder.lean +++ b/Mathlib/Order/OmegaCompletePartialOrder.lean @@ -462,11 +462,11 @@ open OmegaCompletePartialOrder OmegaCompletePartialOrder.Chain instance [∀ a, OmegaCompletePartialOrder (β a)] : OmegaCompletePartialOrder (∀ a, β a) where ωSup c a := ωSup (c.map (Pi.evalOrderHom a)) - ωSup_le c f hf a := + ωSup_le _ _ hf a := ωSup_le _ _ <| by rintro i apply hf - le_ωSup c i x := le_ωSup_of_le _ <| le_rfl + le_ωSup _ _ _ := le_ωSup_of_le _ <| le_rfl namespace OmegaCompletePartialOrder @@ -480,7 +480,7 @@ lemma ωScottContinuous.apply₂ (hf : ωScottContinuous f) (a : α) : ωScottCo lemma ωScottContinuous.of_apply₂ (hf : ∀ a, ωScottContinuous (f · a)) : ωScottContinuous f := ωScottContinuous.of_monotone_map_ωSup - ⟨fun x y h a ↦ (hf a).monotone h, fun c ↦ by ext a; apply (hf a).map_ωSup c⟩ + ⟨fun _ _ h a ↦ (hf a).monotone h, fun c ↦ by ext a; apply (hf a).map_ωSup c⟩ lemma ωScottContinuous_iff_apply₂ : ωScottContinuous f ↔ ∀ a, ωScottContinuous (f · a) := ⟨ωScottContinuous.apply₂, ωScottContinuous.of_apply₂⟩ @@ -495,7 +495,7 @@ theorem flip₁_continuous' (f : ∀ x : α, γ → β x) (a : α) (hf : Continu @[deprecated ωScottContinuous.of_apply₂ (since := "2024-05-29")] theorem flip₂_continuous' (f : γ → ∀ x, β x) (hf : ∀ x, Continuous' fun g => f g x) : Continuous' f := - Continuous.of_bundled _ (fun x y h a => (hf a).to_monotone h) + Continuous.of_bundled _ (fun _ _ h a => (hf a).to_monotone h) (by intro c; ext a; apply (hf a).to_bundled _ c) end OmegaCompletePartialOrder @@ -936,7 +936,7 @@ theorem ωSup_apply_ωSup (c₀ : Chain (α →𝒄 β)) (c₁ : Chain α) : @[simps] def flip {α : Type*} (f : α → β →𝒄 γ) : β →𝒄 α → γ where toFun x y := f y x - monotone' x y h a := (f a).monotone h + monotone' _ _ h a := (f a).monotone h map_ωSup' _ := by ext x; change f _ _ = _; rw [(f _).continuous]; rfl /-- `Part.bind` as a continuous function. -/ diff --git a/Mathlib/Order/Partition/Finpartition.lean b/Mathlib/Order/Partition/Finpartition.lean index 91dbd15b3b57bb..2392533c815c4b 100644 --- a/Mathlib/Order/Partition/Finpartition.lean +++ b/Mathlib/Order/Partition/Finpartition.lean @@ -221,8 +221,8 @@ instance : LE (Finpartition a) := instance : PartialOrder (Finpartition a) := { (inferInstance : LE (Finpartition a)) with - le_refl := fun P b hb ↦ ⟨b, hb, le_rfl⟩ - le_trans := fun P Q R hPQ hQR b hb ↦ by + le_refl := fun _ b hb ↦ ⟨b, hb, le_rfl⟩ + le_trans := fun _ Q R hPQ hQR b hb ↦ by obtain ⟨c, hc, hbc⟩ := hPQ hb obtain ⟨d, hd, hcd⟩ := hQR hc exact ⟨d, hd, hbc.trans hcd⟩ @@ -428,7 +428,7 @@ variable [GeneralizedBooleanAlgebra α] [DecidableEq α] {a b c : α} (P : Finpa def avoid (b : α) : Finpartition (a \ b) := ofErase (P.parts.image (· \ b)) - (P.disjoint.image_finset_of_le fun a ↦ sdiff_le).supIndep + (P.disjoint.image_finset_of_le fun _ ↦ sdiff_le).supIndep (by rw [sup_image, id_comp, Finset.sup_sdiff_right, ← Function.id_def, P.sup_parts]) @[simp] diff --git a/Mathlib/Order/PiLex.lean b/Mathlib/Order/PiLex.lean index b9228f4db92e07..bcad74a66ca1db 100644 --- a/Mathlib/Order/PiLex.lean +++ b/Mathlib/Order/PiLex.lean @@ -57,7 +57,7 @@ theorem lex_lt_of_lt_of_preorder [∀ i, Preorder (β i)] {r} (hwf : WellFounded ⟨i, fun j hj => ⟨h'.1 j, not_not.1 fun h => hl j (lt_of_le_not_le (h'.1 j) h) hj⟩, hi⟩ theorem lex_lt_of_lt [∀ i, PartialOrder (β i)] {r} (hwf : WellFounded r) {x y : ∀ i, β i} - (hlt : x < y) : Pi.Lex r (@fun i => (· < ·)) x y := by + (hlt : x < y) : Pi.Lex r (@fun _ => (· < ·)) x y := by simp_rw [Pi.Lex, le_antisymm_iff] exact lex_lt_of_lt_of_preorder hwf hlt @@ -205,7 +205,7 @@ instance [LinearOrder ι] [IsWellOrder ι (· < ·)] [Nonempty ι] [∀ i, Parti smaller than the original function. -/ theorem lex_desc {α} [Preorder ι] [DecidableEq ι] [Preorder α] {f : ι → α} {i j : ι} (h₁ : i ≤ j) (h₂ : f j < f i) : toLex (f ∘ Equiv.swap i j) < toLex f := - ⟨i, fun k hik => congr_arg f (Equiv.swap_apply_of_ne_of_ne hik.ne (hik.trans_le h₁).ne), by + ⟨i, fun _ hik => congr_arg f (Equiv.swap_apply_of_ne_of_ne hik.ne (hik.trans_le h₁).ne), by simpa only [Pi.toLex_apply, Function.comp_apply, Equiv.swap_apply_left] using h₂⟩ end Pi diff --git a/Mathlib/Order/Rel/GaloisConnection.lean b/Mathlib/Order/Rel/GaloisConnection.lean index 0edf015bf74663..9666eb999ee6bb 100644 --- a/Mathlib/Order/Rel/GaloisConnection.lean +++ b/Mathlib/Order/Rel/GaloisConnection.lean @@ -51,7 +51,7 @@ def rightDual (I : Set β) : Set α := {a : α | ∀ ⦃b⦄, b ∈ I → R a b} /-- The pair of functions `toDual ∘ leftDual` and `rightDual ∘ ofDual` forms a Galois connection. -/ theorem gc_leftDual_rightDual : GaloisConnection (toDual ∘ R.leftDual) (R.rightDual ∘ ofDual) := - fun J I ↦ ⟨fun h a ha b hb ↦ h (by simpa) ha, fun h b hb a ha ↦ h (by simpa) hb⟩ + fun _ _ ↦ ⟨fun h _ ha _ hb ↦ h (by simpa) ha, fun h _ hb _ ha ↦ h (by simpa) hb⟩ /-! ### Induced equivalences between fixed points -/ diff --git a/Mathlib/Order/RelClasses.lean b/Mathlib/Order/RelClasses.lean index be726cd3e66f40..1f6bd1a3387583 100644 --- a/Mathlib/Order/RelClasses.lean +++ b/Mathlib/Order/RelClasses.lean @@ -159,7 +159,7 @@ See note [reducible non-instances]. -/ abbrev partialOrderOfSO (r) [IsStrictOrder α r] : PartialOrder α where le x y := x = y ∨ r x y lt := r - le_refl x := Or.inl rfl + le_refl _ := Or.inl rfl le_trans x y z h₁ h₂ := match y, z, h₁, h₂ with | _, _, Or.inl rfl, h₂ => h₂ @@ -185,7 +185,7 @@ abbrev linearOrderOfSTO (r) [IsStrictTotalOrder α r] [∀ x y, Decidable ¬r x { __ := partialOrderOfSO r le_total := fun x y => match y, trichotomous_of r x y with - | y, Or.inl h => Or.inl (Or.inr h) + | _, Or.inl h => Or.inl (Or.inr h) | _, Or.inr (Or.inl rfl) => Or.inl (Or.inl rfl) | _, Or.inr (Or.inr h) => Or.inr (Or.inr h), toMin := minOfLe, diff --git a/Mathlib/Order/RelIso/Group.lean b/Mathlib/Order/RelIso/Group.lean index 352ac47981f5ad..73cd157bc3f541 100644 --- a/Mathlib/Order/RelIso/Group.lean +++ b/Mathlib/Order/RelIso/Group.lean @@ -19,9 +19,9 @@ instance : Group (r ≃r r) where one := RelIso.refl r mul f₁ f₂ := f₂.trans f₁ inv := RelIso.symm - mul_assoc f₁ f₂ f₃ := rfl - one_mul f := ext fun _ => rfl - mul_one f := ext fun _ => rfl + mul_assoc _ _ _ := rfl + one_mul _ := ext fun _ => rfl + mul_one _ := ext fun _ => rfl inv_mul_cancel f := ext f.symm_apply_apply @[simp] diff --git a/Mathlib/Order/SuccPred/Basic.lean b/Mathlib/Order/SuccPred/Basic.lean index 5620dbe15bbf18..55b6157d4a5db5 100644 --- a/Mathlib/Order/SuccPred/Basic.lean +++ b/Mathlib/Order/SuccPred/Basic.lean @@ -143,7 +143,7 @@ noncomputable def SuccOrder.ofLinearWellFoundedLT [WellFoundedLT α] : SuccOrder rw [not_isMax_iff] at ha simp_rw [Set.Nonempty, mem_Ioi, dif_pos ha] exact ⟨(wellFounded_lt.min_le · ha), lt_of_lt_of_le (wellFounded_lt.min_mem _ ha)⟩) - fun a ha ↦ dif_neg (not_not_intro ha <| not_isMax_iff.mpr ·) + fun _ ha ↦ dif_neg (not_not_intro ha <| not_isMax_iff.mpr ·) /-- A linear order with well-founded greater-than relation is a `PredOrder`. -/ noncomputable def PredOrder.ofLinearWellFoundedGT (α) [LinearOrder α] [WellFoundedGT α] : diff --git a/Mathlib/Order/SupClosed.lean b/Mathlib/Order/SupClosed.lean index 998929ca5eab35..f1940a4250ed13 100644 --- a/Mathlib/Order/SupClosed.lean +++ b/Mathlib/Order/SupClosed.lean @@ -469,7 +469,7 @@ end DistribLattice def SemilatticeSup.toCompleteSemilatticeSup [SemilatticeSup α] (sSup : Set α → α) (h : ∀ s, SupClosed s → IsLUB s (sSup s)) : CompleteSemilatticeSup α where sSup := fun s => sSup (supClosure s) - le_sSup s a ha := (h _ supClosed_supClosure).1 <| subset_supClosure ha + le_sSup _ _ ha := (h _ supClosed_supClosure).1 <| subset_supClosure ha sSup_le s a ha := (isLUB_le_iff <| h _ supClosed_supClosure).2 <| by rwa [upperBounds_supClosure] /-- A meet-semilattice where every inf-closed set has a greatest lower bound is automatically @@ -477,5 +477,5 @@ complete. -/ def SemilatticeInf.toCompleteSemilatticeInf [SemilatticeInf α] (sInf : Set α → α) (h : ∀ s, InfClosed s → IsGLB s (sInf s)) : CompleteSemilatticeInf α where sInf := fun s => sInf (infClosure s) - sInf_le s a ha := (h _ infClosed_infClosure).1 <| subset_infClosure ha + sInf_le _ _ ha := (h _ infClosed_infClosure).1 <| subset_infClosure ha le_sInf s a ha := (le_isGLB_iff <| h _ infClosed_infClosure).2 <| by rwa [lowerBounds_infClosure] diff --git a/Mathlib/Order/WellFoundedSet.lean b/Mathlib/Order/WellFoundedSet.lean index 5c7e684d6af00d..e6c840cc1936df 100644 --- a/Mathlib/Order/WellFoundedSet.lean +++ b/Mathlib/Order/WellFoundedSet.lean @@ -838,7 +838,7 @@ theorem Set.WellFoundedOn.prod_lex_of_wellFoundedOn_fiber (hα : s.WellFoundedOn (hβ : ∀ a, (s ∩ f ⁻¹' {a}).WellFoundedOn (rβ on g)) : s.WellFoundedOn (Prod.Lex rα rβ on fun c => (f c, g c)) := WellFounded.prod_lex_of_wellFoundedOn_fiber hα - fun a ↦ ((hβ a).onFun (f := fun x => ⟨x, x.1.2, x.2⟩)).mono (fun b c h ↦ ‹_›) + fun a ↦ ((hβ a).onFun (f := fun x => ⟨x, x.1.2, x.2⟩)).mono (fun _ _ h ↦ ‹_›) end ProdLex diff --git a/Mathlib/Order/WithBot.lean b/Mathlib/Order/WithBot.lean index c0f4154f4b6471..b78132bdc9a954 100644 --- a/Mathlib/Order/WithBot.lean +++ b/Mathlib/Order/WithBot.lean @@ -293,8 +293,8 @@ instance preorder [Preorder α] : Preorder (WithBot α) where lt_iff_le_not_le := by intros a b cases a <;> cases b <;> simp [lt_iff_le_not_le] - le_refl o a ha := ⟨a, ha, le_rfl⟩ - le_trans o₁ o₂ o₃ h₁ h₂ a ha := + le_refl _ a ha := ⟨a, ha, le_rfl⟩ + le_trans _ _ _ h₁ h₂ a ha := let ⟨b, hb, ab⟩ := h₁ a ha let ⟨c, hc, bc⟩ := h₂ b hb ⟨c, hc, le_trans ab bc⟩ @@ -434,7 +434,7 @@ instance decidableEq [DecidableEq α] : DecidableEq (WithBot α) := inferInstanceAs <| DecidableEq (Option α) instance decidableLE [LE α] [@DecidableRel α (· ≤ ·)] : @DecidableRel (WithBot α) (· ≤ ·) - | none, x => isTrue fun a h => Option.noConfusion h + | none, _ => isTrue fun _ h => Option.noConfusion h | Option.some x, Option.some y => if h : x ≤ y then isTrue (coe_le_coe.2 h) else isFalse <| by simp [*] | Option.some x, none => isFalse fun h => by rcases h x rfl with ⟨y, ⟨_⟩, _⟩ @@ -469,7 +469,7 @@ instance instWellFoundedLT [LT α] [WellFoundedLT α] : WellFoundedLT (WithBot have acc_bot := ⟨_, by simp [not_lt_bot]⟩ .intro fun | ⊥ => acc_bot - | (a : α) => (wellFounded_lt.1 a).rec fun a _ ih => + | (a : α) => (wellFounded_lt.1 a).rec fun _ _ ih => .intro _ fun | ⊥, _ => acc_bot | (b : α), hlt => ih _ (coe_lt_coe.1 hlt) diff --git a/Mathlib/Order/Zorn.lean b/Mathlib/Order/Zorn.lean index 8c519e1bbaec18..b0418fa34a94b7 100644 --- a/Mathlib/Order/Zorn.lean +++ b/Mathlib/Order/Zorn.lean @@ -112,7 +112,7 @@ theorem zorn_le₀ (s : Set α) (ih : ∀ c ⊆ s, IsChain (· ≤ ·) c → ∃ (by rintro _ ⟨p, hpc, rfl⟩ _ ⟨q, hqc, rfl⟩ hpq exact hc hpc hqc fun t => hpq (Subtype.ext_iff.1 t)) - ⟨⟨ub, hubs⟩, fun ⟨y, hy⟩ hc => hub _ ⟨_, hc, rfl⟩⟩ + ⟨⟨ub, hubs⟩, fun ⟨_, _⟩ hc => hub _ ⟨_, hc, rfl⟩⟩ ⟨m, hms, fun z hzs hmz => @h ⟨z, hzs⟩ hmz⟩ theorem zorn_le_nonempty₀ (s : Set α) diff --git a/Mathlib/Probability/Distributions/Uniform.lean b/Mathlib/Probability/Distributions/Uniform.lean index c639f53703f5bb..fca2b2cafde427 100644 --- a/Mathlib/Probability/Distributions/Uniform.lean +++ b/Mathlib/Probability/Distributions/Uniform.lean @@ -257,7 +257,7 @@ theorem toOuterMeasure_uniformOfFinset_apply : _ = ∑' x, if x ∈ s ∧ x ∈ t then (s.card : ℝ≥0∞)⁻¹ else 0 := (tsum_congr fun x => by simp_rw [uniformOfFinset_apply, ← ite_and, and_comm]) _ = ∑ x ∈ s.filter (· ∈ t), if x ∈ s ∧ x ∈ t then (s.card : ℝ≥0∞)⁻¹ else 0 := - (tsum_eq_sum fun x hx => if_neg fun h => hx (Finset.mem_filter.2 h)) + (tsum_eq_sum fun _ hx => if_neg fun h => hx (Finset.mem_filter.2 h)) _ = ∑ _x ∈ s.filter (· ∈ t), (s.card : ℝ≥0∞)⁻¹ := (Finset.sum_congr rfl fun x hx => by let this : x ∈ s ∧ x ∈ t := by simpa using hx diff --git a/Mathlib/Probability/Independence/Kernel.lean b/Mathlib/Probability/Independence/Kernel.lean index 146667d5bfbdbf..6986bae0a89f3e 100644 --- a/Mathlib/Probability/Independence/Kernel.lean +++ b/Mathlib/Probability/Independence/Kernel.lean @@ -827,7 +827,7 @@ theorem IndepSets.indepSet_of_mem {_m0 : MeasurableSpace Ω} (hs : s ∈ S) (ht IndepSet s t κ μ := (indepSet_iff_measure_inter_eq_mul hs_meas ht_meas κ μ).mpr (h_indep s t hs ht) -theorem Indep.indepSet_of_measurableSet {m₁ m₂ m0 : MeasurableSpace Ω} {κ : Kernel α Ω} +theorem Indep.indepSet_of_measurableSet {m₁ m₂ _ : MeasurableSpace Ω} {κ : Kernel α Ω} {μ : Measure α} (h_indep : Indep m₁ m₂ κ μ) {s t : Set Ω} (hs : MeasurableSet[m₁] s) (ht : MeasurableSet[m₂] t) : diff --git a/Mathlib/Probability/Kernel/Defs.lean b/Mathlib/Probability/Kernel/Defs.lean index 707e45278f5bc2..df3b0dacc3a32f 100644 --- a/Mathlib/Probability/Kernel/Defs.lean +++ b/Mathlib/Probability/Kernel/Defs.lean @@ -165,7 +165,7 @@ theorem Kernel.measure_le_bound (κ : Kernel α β) [h : IsFiniteKernel κ] (a : κ a s ≤ IsFiniteKernel.bound κ := (measure_mono (Set.subset_univ s)).trans (h.exists_univ_le.choose_spec.2 a) -instance isFiniteKernel_zero (α β : Type*) {mα : MeasurableSpace α} {mβ : MeasurableSpace β} : +instance isFiniteKernel_zero (α β : Type*) {_ : MeasurableSpace α} {_ : MeasurableSpace β} : IsFiniteKernel (0 : Kernel α β) := ⟨⟨0, ENNReal.coe_lt_top, fun _ => by simp only [Kernel.zero_apply, Measure.coe_zero, Pi.zero_apply, le_zero_iff]⟩⟩ diff --git a/Mathlib/Probability/Kernel/Disintegration/StandardBorel.lean b/Mathlib/Probability/Kernel/Disintegration/StandardBorel.lean index c9a1f8966a14ea..db4a4a141b4576 100644 --- a/Mathlib/Probability/Kernel/Disintegration/StandardBorel.lean +++ b/Mathlib/Probability/Kernel/Disintegration/StandardBorel.lean @@ -81,8 +81,8 @@ lemma isRatCondKernelCDFAux_density_Iic (κ : Kernel α (γ × ℝ)) [IsFiniteKe measurable := measurable_pi_iff.mpr fun _ ↦ measurable_density κ (fst κ) measurableSet_Iic mono' a q r hqr := ae_of_all _ fun c ↦ density_mono_set le_rfl a c (Iic_subset_Iic.mpr (by exact_mod_cast hqr)) - nonneg' a q := ae_of_all _ fun c ↦ density_nonneg le_rfl _ _ _ - le_one' a q := ae_of_all _ fun c ↦ density_le_one le_rfl _ _ _ + nonneg' _ _ := ae_of_all _ fun _ ↦ density_nonneg le_rfl _ _ _ + le_one' _ _ := ae_of_all _ fun _ ↦ density_le_one le_rfl _ _ _ tendsto_integral_of_antitone a s hs_anti hs_tendsto := by let s' : ℕ → Set ℝ := fun n ↦ Iic (s n) refine tendsto_integral_density_of_antitone le_rfl a s' ?_ ?_ (fun _ ↦ measurableSet_Iic) @@ -108,8 +108,8 @@ lemma isRatCondKernelCDFAux_density_Iic (κ : Kernel α (γ × ℝ)) [IsFiniteKe obtain ⟨i, hi⟩ := hs_tendsto q refine ⟨i, hq.le.trans ?_⟩ exact mod_cast hi i le_rfl - integrable a q := integrable_density le_rfl a measurableSet_Iic - setIntegral a A hA q := setIntegral_density le_rfl a measurableSet_Iic hA + integrable a _ := integrable_density le_rfl a measurableSet_Iic + setIntegral a _ hA _ := setIntegral_density le_rfl a measurableSet_Iic hA /-- Taking the kernel density of intervals `Iic q` for `q : ℚ` gives a function with the property `isRatCondKernelCDF`. -/ diff --git a/Mathlib/Probability/Martingale/Convergence.lean b/Mathlib/Probability/Martingale/Convergence.lean index 42764ff3c943d5..cd3dced4e06728 100644 --- a/Mathlib/Probability/Martingale/Convergence.lean +++ b/Mathlib/Probability/Martingale/Convergence.lean @@ -191,7 +191,7 @@ theorem Submartingale.exists_ae_tendsto_of_bdd [IsFiniteMeasure μ] (hf : Submar theorem Submartingale.exists_ae_trim_tendsto_of_bdd [IsFiniteMeasure μ] (hf : Submartingale f ℱ μ) (hbdd : ∀ n, eLpNorm (f n) 1 μ ≤ R) : - ∀ᵐ ω ∂μ.trim (sSup_le fun m ⟨n, hn⟩ => hn ▸ ℱ.le _ : ⨆ n, ℱ n ≤ m0), + ∀ᵐ ω ∂μ.trim (sSup_le fun _ ⟨_, hn⟩ => hn ▸ ℱ.le _ : ⨆ n, ℱ n ≤ m0), ∃ c, Tendsto (fun n => f n ω) atTop (𝓝 c) := by letI := (⨆ n, ℱ n) rw [ae_iff, trim_measurableSet_eq] diff --git a/Mathlib/Probability/Moments.lean b/Mathlib/Probability/Moments.lean index 3ad21345e302fb..1433dc8119e430 100644 --- a/Mathlib/Probability/Moments.lean +++ b/Mathlib/Probability/Moments.lean @@ -244,7 +244,7 @@ theorem IndepFun.integrable_exp_mul_add {X Y : Ω → ℝ} (h_indep : IndepFun X exact (h_indep.exp_mul t t).integrable_mul h_int_X h_int_Y theorem iIndepFun.integrable_exp_mul_sum [IsFiniteMeasure μ] {X : ι → Ω → ℝ} - (h_indep : iIndepFun (fun i => inferInstance) X μ) (h_meas : ∀ i, Measurable (X i)) + (h_indep : iIndepFun (fun _ => inferInstance) X μ) (h_meas : ∀ i, Measurable (X i)) {s : Finset ι} (h_int : ∀ i ∈ s, Integrable (fun ω => exp (t * X i ω)) μ) : Integrable (fun ω => exp (t * (∑ i ∈ s, X i) ω)) μ := by classical @@ -259,7 +259,7 @@ theorem iIndepFun.integrable_exp_mul_sum [IsFiniteMeasure μ] {X : ι → Ω → exact (h_indep.indepFun_finset_sum_of_not_mem h_meas hi_notin_s).symm theorem iIndepFun.mgf_sum {X : ι → Ω → ℝ} - (h_indep : iIndepFun (fun i => inferInstance) X μ) (h_meas : ∀ i, Measurable (X i)) + (h_indep : iIndepFun (fun _ => inferInstance) X μ) (h_meas : ∀ i, Measurable (X i)) (s : Finset ι) : mgf (∑ i ∈ s, X i) μ t = ∏ i ∈ s, mgf (X i) μ t := by have : IsProbabilityMeasure μ := h_indep.isProbabilityMeasure classical @@ -273,7 +273,7 @@ theorem iIndepFun.mgf_sum {X : ι → Ω → ℝ} h_rec, prod_insert hi_notin_s] theorem iIndepFun.cgf_sum {X : ι → Ω → ℝ} - (h_indep : iIndepFun (fun i => inferInstance) X μ) (h_meas : ∀ i, Measurable (X i)) + (h_indep : iIndepFun (fun _ => inferInstance) X μ) (h_meas : ∀ i, Measurable (X i)) {s : Finset ι} (h_int : ∀ i ∈ s, Integrable (fun ω => exp (t * X i ω)) μ) : cgf (∑ i ∈ s, X i) μ t = ∑ i ∈ s, cgf (X i) μ t := by have : IsProbabilityMeasure μ := h_indep.isProbabilityMeasure diff --git a/Mathlib/Probability/ProbabilityMassFunction/Constructions.lean b/Mathlib/Probability/ProbabilityMassFunction/Constructions.lean index 503b97db3cdf22..71cc19f51f1b7d 100644 --- a/Mathlib/Probability/ProbabilityMassFunction/Constructions.lean +++ b/Mathlib/Probability/ProbabilityMassFunction/Constructions.lean @@ -129,7 +129,7 @@ instance : LawfulFunctor PMF where comp_map _ _ _ := (map_comp _ _ _).symm instance : LawfulMonad PMF := LawfulMonad.mk' - (bind_pure_comp := fun f x => rfl) + (bind_pure_comp := fun _ _ => rfl) (id_map := id_map) (pure_bind := pure_bind) (bind_assoc := bind_bind) diff --git a/Mathlib/Probability/ProbabilityMassFunction/Monad.lean b/Mathlib/Probability/ProbabilityMassFunction/Monad.lean index 31a9cbfa903d10..3e0a147acaecac 100644 --- a/Mathlib/Probability/ProbabilityMassFunction/Monad.lean +++ b/Mathlib/Probability/ProbabilityMassFunction/Monad.lean @@ -156,7 +156,7 @@ theorem toOuterMeasure_bind_apply : _ = ∑' (b) (a), p a * if b ∈ s then f a b else 0 := tsum_congr fun b => by split_ifs <;> simp _ = ∑' (a) (b), p a * if b ∈ s then f a b else 0 := (tsum_comm' ENNReal.summable (fun _ => ENNReal.summable) fun _ => ENNReal.summable) - _ = ∑' a, p a * ∑' b, if b ∈ s then f a b else 0 := tsum_congr fun a => ENNReal.tsum_mul_left + _ = ∑' a, p a * ∑' b, if b ∈ s then f a b else 0 := tsum_congr fun _ => ENNReal.tsum_mul_left _ = ∑' a, p a * ∑' b, if b ∈ s then f a b else 0 := (tsum_congr fun a => (congr_arg fun x => p a * x) <| tsum_congr fun b => by split_ifs <;> rfl) _ = ∑' a, p a * (f a).toOuterMeasure s := diff --git a/Mathlib/Probability/Process/Filtration.lean b/Mathlib/Probability/Process/Filtration.lean index eaa870240f64e1..cc95366031c1b5 100644 --- a/Mathlib/Probability/Process/Filtration.lean +++ b/Mathlib/Probability/Process/Filtration.lean @@ -156,19 +156,19 @@ theorem sInf_def (s : Set (Filtration ι m)) (i : ι) : noncomputable instance instCompleteLattice : CompleteLattice (Filtration ι m) where le := (· ≤ ·) - le_refl f i := le_rfl - le_trans f g h h_fg h_gh i := (h_fg i).trans (h_gh i) - le_antisymm f g h_fg h_gf := Filtration.ext <| funext fun i => (h_fg i).antisymm (h_gf i) + le_refl _ _ := le_rfl + le_trans _ _ _ h_fg h_gh i := (h_fg i).trans (h_gh i) + le_antisymm _ _ h_fg h_gf := Filtration.ext <| funext fun i => (h_fg i).antisymm (h_gf i) sup := (· ⊔ ·) - le_sup_left f g i := le_sup_left - le_sup_right f g i := le_sup_right - sup_le f g h h_fh h_gh i := sup_le (h_fh i) (h_gh _) + le_sup_left _ _ _ := le_sup_left + le_sup_right _ _ _ := le_sup_right + sup_le _ _ _ h_fh h_gh i := sup_le (h_fh i) (h_gh _) inf := (· ⊓ ·) - inf_le_left f g i := inf_le_left - inf_le_right f g i := inf_le_right - le_inf f g h h_fg h_fh i := le_inf (h_fg i) (h_fh i) + inf_le_left _ _ _ := inf_le_left + inf_le_right _ _ _ := inf_le_right + le_inf _ _ _ h_fg h_fh i := le_inf (h_fg i) (h_fh i) sSup := sSup - le_sSup s f hf_mem i := le_sSup ⟨f, hf_mem, rfl⟩ + le_sSup _ f hf_mem _ := le_sSup ⟨f, hf_mem, rfl⟩ sSup_le s f h_forall i := sSup_le fun m' hm' => by obtain ⟨g, hg_mem, hfm'⟩ := hm' @@ -188,7 +188,7 @@ noncomputable instance instCompleteLattice : CompleteLattice (Filtration ι m) w top := ⊤ bot := ⊥ le_top f i := f.le' i - bot_le f i := bot_le + bot_le _ _ := bot_le end Filtration @@ -247,7 +247,7 @@ of σ-algebras such that that sequence of functions is measurable with respect t the filtration. -/ def natural (u : ι → Ω → β) (hum : ∀ i, StronglyMeasurable (u i)) : Filtration ι m where seq i := ⨆ j ≤ i, MeasurableSpace.comap (u j) mβ - mono' i j hij := biSup_mono fun k => ge_trans hij + mono' _ _ hij := biSup_mono fun _ => ge_trans hij le' i := by refine iSup₂_le ?_ rintro j _ s ⟨t, ht, rfl⟩ diff --git a/Mathlib/RepresentationTheory/Action/Basic.lean b/Mathlib/RepresentationTheory/Action/Basic.lean index e09c00af54f4ed..9097a7d47988b2 100644 --- a/Mathlib/RepresentationTheory/Action/Basic.lean +++ b/Mathlib/RepresentationTheory/Action/Basic.lean @@ -196,7 +196,7 @@ def unitIso : 𝟭 (Action V G) ≅ functor ⋙ inverse := /-- Auxiliary definition for `functorCategoryEquivalence`. -/ @[simps!] def counitIso : inverse ⋙ functor ≅ 𝟭 (SingleObj G ⥤ V) := - NatIso.ofComponents fun M => NatIso.ofComponents fun X => Iso.refl _ + NatIso.ofComponents fun M => NatIso.ofComponents fun _ => Iso.refl _ end FunctorCategoryEquivalence @@ -284,7 +284,7 @@ def actionPunitEquivalence : Action V (MonCat.of PUnit) ≌ V where simp only [MonCat.oneHom_apply, MonCat.one_of, End.one_def, id_eq, Functor.comp_obj, forget_obj, Iso.refl_hom, Category.comp_id] exact ρ_one X - counitIso := NatIso.ofComponents fun X => Iso.refl _ + counitIso := NatIso.ofComponents fun _ => Iso.refl _ variable (V) diff --git a/Mathlib/RepresentationTheory/Action/Concrete.lean b/Mathlib/RepresentationTheory/Action/Concrete.lean index e2ebc3a42dff79..61d62003c4f3d6 100644 --- a/Mathlib/RepresentationTheory/Action/Concrete.lean +++ b/Mathlib/RepresentationTheory/Action/Concrete.lean @@ -38,7 +38,7 @@ def ofMulActionLimitCone {ι : Type v} (G : Type max v u) [Monoid G] (F : ι → LimitCone (Discrete.functor fun i : ι => Action.ofMulAction G (F i)) where cone := { pt := Action.ofMulAction G (∀ i : ι, F i) - π := Discrete.natTrans (fun i => ⟨fun x => x i.as, fun g => rfl⟩) } + π := Discrete.natTrans (fun i => ⟨fun x => x i.as, fun _ => rfl⟩) } isLimit := { lift := fun s => { hom := fun x i => (s.π.app ⟨i⟩).hom x @@ -46,7 +46,7 @@ def ofMulActionLimitCone {ι : Type v} (G : Type max v u) [Monoid G] (F : ι → ext x funext j exact congr_fun ((s.π.app ⟨j⟩).comm g) x } - fac := fun s j => rfl + fac := fun _ _ => rfl uniq := fun s f h => by ext x funext j @@ -149,7 +149,7 @@ lemma quotientToEndHom_mk [N.Normal] (x : H) (g : G) : /-- If `N` and `H` are subgroups of a group `G` with `N ≤ H`, this is the canonical `G`-morphism `G ⧸ N ⟶ G ⧸ H`. -/ def quotientToQuotientOfLE [Fintype (G ⧸ H)] (h : N ≤ H) : (G ⧸ₐ N) ⟶ (G ⧸ₐ H) where - hom := Quotient.lift _ <| fun a b hab ↦ Quotient.sound <| + hom := Quotient.lift _ <| fun _ _ hab ↦ Quotient.sound <| (QuotientGroup.leftRel_apply).mpr (h <| (QuotientGroup.leftRel_apply).mp hab) comm g := by ext (x : G ⧸ N) diff --git a/Mathlib/RepresentationTheory/Action/Monoidal.lean b/Mathlib/RepresentationTheory/Action/Monoidal.lean index a31d4f9f7196fc..3eecdddcbe9090 100644 --- a/Mathlib/RepresentationTheory/Action/Monoidal.lean +++ b/Mathlib/RepresentationTheory/Action/Monoidal.lean @@ -71,7 +71,7 @@ variable (V G) def forgetMonoidal : MonoidalFunctor (Action V G) V := { toFunctor := Action.forget _ _ ε := 𝟙 _ - μ := fun X Y => 𝟙 _ } + μ := fun _ _ => 𝟙 _ } instance forgetMonoidal_faithful : (forgetMonoidal V G).Faithful := by change (forget V G).Faithful; infer_instance diff --git a/Mathlib/RepresentationTheory/GroupCohomology/LowDegree.lean b/Mathlib/RepresentationTheory/GroupCohomology/LowDegree.lean index f8101f22d3a293..c2cc073aa0dca2 100644 --- a/Mathlib/RepresentationTheory/GroupCohomology/LowDegree.lean +++ b/Mathlib/RepresentationTheory/GroupCohomology/LowDegree.lean @@ -263,8 +263,8 @@ group homs `G → A`. -/ { toFun := f.1 ∘ Additive.toMul map_zero' := oneCocycles_map_one f map_add' := oneCocycles_map_mul_of_isTrivial f } - map_add' x y := rfl - map_smul' r x := rfl + map_add' _ _ := rfl + map_smul' _ _ := rfl invFun f := { val := f property := mem_oneCocycles_of_addMonoidHom f } diff --git a/Mathlib/RepresentationTheory/GroupCohomology/Resolution.lean b/Mathlib/RepresentationTheory/GroupCohomology/Resolution.lean index 9d4c8627a8198a..acca90f2bc60f9 100644 --- a/Mathlib/RepresentationTheory/GroupCohomology/Resolution.lean +++ b/Mathlib/RepresentationTheory/GroupCohomology/Resolution.lean @@ -405,7 +405,7 @@ variable [Monoid G] isomorphic to `EG`, the universal cover of the classifying space of `G` as a simplicial `G`-set. -/ def cechNerveTerminalFromIso : cechNerveTerminalFrom (Action.ofMulAction G G) ≅ classifyingSpaceUniversalCover G := - NatIso.ofComponents (fun n => limit.isoLimitCone (Action.ofMulActionLimitCone _ _)) fun f => by + NatIso.ofComponents (fun _ => limit.isoLimitCone (Action.ofMulActionLimitCone _ _)) fun f => by refine IsLimit.hom_ext (Action.ofMulActionLimitCone.{u, 0} G fun _ => G).2 fun j => ?_ dsimp only [cechNerveTerminalFrom, Pi.lift] rw [Category.assoc, limit.isoLimitCone_hom_π, limit.lift_π, Category.assoc] diff --git a/Mathlib/RepresentationTheory/Rep.lean b/Mathlib/RepresentationTheory/Rep.lean index 0c233f3d57f276..8ebf69973568b4 100644 --- a/Mathlib/RepresentationTheory/Rep.lean +++ b/Mathlib/RepresentationTheory/Rep.lean @@ -293,8 +293,8 @@ representation morphisms `Hom(k[G], A)` and `A`. -/ @[simps] noncomputable def leftRegularHomEquiv (A : Rep k G) : (Rep.ofMulAction k G G ⟶ A) ≃ₗ[k] A where toFun f := f.hom (Finsupp.single 1 1) - map_add' x y := rfl - map_smul' r x := rfl + map_add' _ _ := rfl + map_smul' _ _ := rfl invFun x := leftRegularHom A x left_inv f := by refine Action.Hom.ext (Finsupp.lhom_ext' fun x : G => LinearMap.ext_ring ?_) @@ -373,7 +373,7 @@ def homEquiv (A B C : Rep k G) : (A ⊗ B ⟶ C) ≃ (B ⟶ (Rep.ihom A).obj C) dsimp rw [ρ_inv_self_apply] rfl} - left_inv f := Action.Hom.ext (TensorProduct.ext' fun _ _ => rfl) + left_inv _ := Action.Hom.ext (TensorProduct.ext' fun _ _ => rfl) right_inv f := by ext; rfl variable {A B C} diff --git a/Mathlib/RingTheory/Adjoin/FG.lean b/Mathlib/RingTheory/Adjoin/FG.lean index 1256cc4e9a973d..fdbe2c43cbbaad 100644 --- a/Mathlib/RingTheory/Adjoin/FG.lean +++ b/Mathlib/RingTheory/Adjoin/FG.lean @@ -103,7 +103,7 @@ theorem fg_of_fg_toSubmodule {S : Subalgebra R A} : S.toSubmodule.FG → S.FG := fun ⟨t, ht⟩ ↦ ⟨t, le_antisymm (Algebra.adjoin_le fun x hx ↦ show x ∈ Subalgebra.toSubmodule S from ht ▸ subset_span hx) <| show Subalgebra.toSubmodule S ≤ Subalgebra.toSubmodule (Algebra.adjoin R ↑t) from fun x hx ↦ - span_le.mpr (fun x hx ↦ Algebra.subset_adjoin hx) + span_le.mpr (fun _ hx ↦ Algebra.subset_adjoin hx) (show x ∈ span R ↑t by rw [ht] exact hx)⟩ diff --git a/Mathlib/RingTheory/Bialgebra/Hom.lean b/Mathlib/RingTheory/Bialgebra/Hom.lean index f1b2923cd334c9..bbb6a66995f90c 100644 --- a/Mathlib/RingTheory/Bialgebra/Hom.lean +++ b/Mathlib/RingTheory/Bialgebra/Hom.lean @@ -275,10 +275,10 @@ theorem map_smul_of_tower {R'} [SMul R' A] [SMul R' B] [LinearMap.CompatibleSMul @[simps (config := .lemmasOnly) toSemigroup_toMul_mul toOne_one] instance End : Monoid (A →ₐc[R] A) where mul := comp - mul_assoc ϕ ψ χ := rfl + mul_assoc _ _ _ := rfl one := BialgHom.id R A - one_mul ϕ := ext fun x => rfl - mul_one ϕ := ext fun x => rfl + one_mul _ := ext fun _ => rfl + mul_one _ := ext fun _ => rfl @[simp] theorem one_apply (x : A) : (1 : A →ₐc[R] A) x = x := diff --git a/Mathlib/RingTheory/Binomial.lean b/Mathlib/RingTheory/Binomial.lean index 659a95f8fb2267..ad5a0893a9a041 100644 --- a/Mathlib/RingTheory/Binomial.lean +++ b/Mathlib/RingTheory/Binomial.lean @@ -225,7 +225,7 @@ section Basic_Instances open Polynomial instance Nat.instBinomialRing : BinomialRing ℕ where - nsmul_right_injective n hn r s hrs := Nat.eq_of_mul_eq_mul_left (Nat.pos_of_ne_zero hn) hrs + nsmul_right_injective _ hn _ _ hrs := Nat.eq_of_mul_eq_mul_left (Nat.pos_of_ne_zero hn) hrs multichoose n k := Nat.choose (n + k - 1) k factorial_nsmul_multichoose r n := by rw [smul_eq_mul, ← Nat.descFactorial_eq_factorial_mul_choose, @@ -238,7 +238,7 @@ def Int.multichoose (n : ℤ) (k : ℕ) : ℤ := | negSucc n => (-1) ^ k * Nat.choose (n + 1) k instance Int.instBinomialRing : BinomialRing ℤ where - nsmul_right_injective n hn r s hrs := Int.eq_of_mul_eq_mul_left (Int.ofNat_ne_zero.mpr hn) hrs + nsmul_right_injective _ hn _ _ hrs := Int.eq_of_mul_eq_mul_left (Int.ofNat_ne_zero.mpr hn) hrs multichoose := Int.multichoose factorial_nsmul_multichoose r k := by rw [Int.multichoose.eq_def, nsmul_eq_mul] diff --git a/Mathlib/RingTheory/Coalgebra/Hom.lean b/Mathlib/RingTheory/Coalgebra/Hom.lean index c6c26e0bf65b9b..2c15ce54d3b1aa 100644 --- a/Mathlib/RingTheory/Coalgebra/Hom.lean +++ b/Mathlib/RingTheory/Coalgebra/Hom.lean @@ -241,10 +241,10 @@ theorem map_smul_of_tower {R'} [SMul R' A] [SMul R' B] [LinearMap.CompatibleSMul @[simps (config := .lemmasOnly) toSemigroup_toMul_mul toOne_one] instance End : Monoid (A →ₗc[R] A) where mul := comp - mul_assoc ϕ ψ χ := rfl + mul_assoc _ _ _ := rfl one := CoalgHom.id R A - one_mul ϕ := ext fun x => rfl - mul_one ϕ := ext fun x => rfl + one_mul _ := ext fun _ => rfl + mul_one _ := ext fun _ => rfl @[simp] theorem one_apply (x : A) : (1 : A →ₗc[R] A) x = x := diff --git a/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean b/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean index 088395622dc68e..5ad19cc5ca6aef 100644 --- a/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean +++ b/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean @@ -355,7 +355,7 @@ instance : Algebra (R_hat R K) (FiniteAdeleRing R K) where map_zero' := by ext; rfl map_add' _ _ := by ext; rfl commutes' _ _ := mul_comm _ _ - smul_def' r x := rfl + smul_def' _ _ := rfl instance : CoeFun (FiniteAdeleRing R K) (fun _ ↦ ∀ (v : HeightOneSpectrum R), adicCompletion K v) where diff --git a/Mathlib/RingTheory/DedekindDomain/Ideal.lean b/Mathlib/RingTheory/DedekindDomain/Ideal.lean index 426d9396129871..c730c6a9168db2 100644 --- a/Mathlib/RingTheory/DedekindDomain/Ideal.lean +++ b/Mathlib/RingTheory/DedekindDomain/Ideal.lean @@ -562,7 +562,7 @@ noncomputable instance FractionalIdeal.semifield : Semifield (FractionalIdeal A div_eq_mul_inv := FractionalIdeal.div_eq_mul_inv mul_inv_cancel _ := FractionalIdeal.mul_inv_cancel nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl /-- Fractional ideals have cancellative multiplication in a Dedekind domain. @@ -1245,7 +1245,7 @@ noncomputable def IsDedekindDomain.quotientEquivPiFactors {I : Ideal R} (hI : I R ⧸ I ≃+* ∀ P : (factors I).toFinset, R ⧸ (P : Ideal R) ^ (Multiset.count ↑P (factors I)) := IsDedekindDomain.quotientEquivPiOfProdEq _ _ _ (fun P : (factors I).toFinset => prime_of_factor _ (Multiset.mem_toFinset.mp P.prop)) - (fun i j hij => Subtype.coe_injective.ne hij) + (fun _ _ hij => Subtype.coe_injective.ne hij) (calc (∏ P : (factors I).toFinset, (P : Ideal R) ^ (factors I).count (P : Ideal R)) = ∏ P ∈ (factors I).toFinset, P ^ (factors I).count P := diff --git a/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean b/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean index 3ac49f7143a12a..964dfa3fb3639c 100644 --- a/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean +++ b/Mathlib/RingTheory/DedekindDomain/SelmerGroup.lean @@ -172,7 +172,7 @@ theorem monotone (hS : S ≤ S') : K⟮S,n⟯ ≤ K⟮S',n⟯ := fun _ hx v => h /-- The multiplicative `v`-adic valuations on `K⟮S, n⟯` for all `v ∈ S`. -/ def valuation : K⟮S,n⟯ →* S → Multiplicative (ZMod n) where toFun x v := (v : HeightOneSpectrum R).valuationOfNeZeroMod n (x : K/n) - map_one' := funext fun v => map_one _ + map_one' := funext fun _ => map_one _ map_mul' x y := by simp only [Subgroup.coe_mul, map_mul]; rfl theorem valuation_ker_eq : diff --git a/Mathlib/RingTheory/Derivation/Basic.lean b/Mathlib/RingTheory/Derivation/Basic.lean index 6a979034730827..51dccf2f460eaa 100644 --- a/Mathlib/RingTheory/Derivation/Basic.lean +++ b/Mathlib/RingTheory/Derivation/Basic.lean @@ -151,7 +151,7 @@ theorem map_aeval (P : R[X]) (x : A) : · simp [add_smul, *] · simp [mul_smul, ← Nat.cast_smul_eq_nsmul A] -theorem eqOn_adjoin {s : Set A} (h : Set.EqOn D1 D2 s) : Set.EqOn D1 D2 (adjoin R s) := fun x hx => +theorem eqOn_adjoin {s : Set A} (h : Set.EqOn D1 D2 s) : Set.EqOn D1 D2 (adjoin R s) := fun _ hx => Algebra.adjoin_induction hx h (fun r => (D1.map_algebraMap r).trans (D2.map_algebraMap r).symm) (fun x y hx hy => by simp only [map_add, *]) fun x y hx hy => by simp only [leibniz, *] diff --git a/Mathlib/RingTheory/Filtration.lean b/Mathlib/RingTheory/Filtration.lean index 8ce8b760670a3f..8b38d3cb2ddca3 100644 --- a/Mathlib/RingTheory/Filtration.lean +++ b/Mathlib/RingTheory/Filtration.lean @@ -238,7 +238,7 @@ variable (F F') protected def submodule : Submodule (reesAlgebra I) (PolynomialModule R M) where carrier := { f | ∀ i, f i ∈ F.N i } add_mem' hf hg i := Submodule.add_mem _ (hf i) (hg i) - zero_mem' i := Submodule.zero_mem _ + zero_mem' _ := Submodule.zero_mem _ smul_mem' r f hf i := by rw [Subalgebra.smul_def, PolynomialModule.smul_apply] apply Submodule.sum_mem diff --git a/Mathlib/RingTheory/Finiteness.lean b/Mathlib/RingTheory/Finiteness.lean index 0039e1437e417e..9b6993825be281 100644 --- a/Mathlib/RingTheory/Finiteness.lean +++ b/Mathlib/RingTheory/Finiteness.lean @@ -194,7 +194,7 @@ variable {f} theorem fg_of_fg_map_injective (f : M →ₗ[R] P) (hf : Function.Injective f) {N : Submodule R M} (hfn : (N.map f).FG) : N.FG := let ⟨t, ht⟩ := hfn - ⟨t.preimage f fun x _ y _ h => hf h, + ⟨t.preimage f fun _ _ _ _ h => hf h, Submodule.map_injective_of_injective hf <| by rw [map_span, Finset.coe_preimage, Set.image_preimage_eq_inter_range, Set.inter_eq_self_of_subset_left, ht] diff --git a/Mathlib/RingTheory/FractionalIdeal/Operations.lean b/Mathlib/RingTheory/FractionalIdeal/Operations.lean index d6ab280bcde60e..5f88258c9e20ac 100644 --- a/Mathlib/RingTheory/FractionalIdeal/Operations.lean +++ b/Mathlib/RingTheory/FractionalIdeal/Operations.lean @@ -154,7 +154,7 @@ theorem mapEquiv_refl : mapEquiv AlgEquiv.refl = RingEquiv.refl (FractionalIdeal theorem isFractional_span_iff {s : Set P} : IsFractional S (span R s) ↔ ∃ a ∈ S, ∀ b : P, b ∈ s → IsInteger R (a • b) := ⟨fun ⟨a, a_mem, h⟩ => ⟨a, a_mem, fun b hb => h b (subset_span hb)⟩, fun ⟨a, a_mem, h⟩ => - ⟨a, a_mem, fun b hb => + ⟨a, a_mem, fun _ hb => span_induction hb h (by rw [smul_zero] @@ -206,7 +206,7 @@ noncomputable irreducible_def canonicalEquiv : FractionalIdeal S P ≃+* Fractio mapEquiv { ringEquivOfRingEquiv P P' (RingEquiv.refl R) (show S.map _ = S by rw [RingEquiv.toMonoidHom_refl, Submonoid.map_id]) with - commutes' := fun r => ringEquivOfRingEquiv_eq _ _ } + commutes' := fun _ => ringEquivOfRingEquiv_eq _ _ } @[simp] theorem mem_canonicalEquiv_apply {I : FractionalIdeal S P} {x : P'} : @@ -793,7 +793,7 @@ instance isPrincipal {R} [CommRing R] [IsDomain R] [IsPrincipalIdealRing R] [Alg theorem le_spanSingleton_mul_iff {x : P} {I J : FractionalIdeal S P} : I ≤ spanSingleton S x * J ↔ ∀ zI ∈ I, ∃ zJ ∈ J, x * zJ = zI := - show (∀ {zI} (hzI : zI ∈ I), zI ∈ spanSingleton _ x * J) ↔ ∀ zI ∈ I, ∃ zJ ∈ J, x * zJ = zI by + show (∀ {zI} (_ : zI ∈ I), zI ∈ spanSingleton _ x * J) ↔ ∀ zI ∈ I, ∃ zJ ∈ J, x * zJ = zI by simp only [mem_singleton_mul, eq_comm] theorem spanSingleton_mul_le_iff {x : P} {I J : FractionalIdeal S P} : diff --git a/Mathlib/RingTheory/FreeCommRing.lean b/Mathlib/RingTheory/FreeCommRing.lean index eeaec370fa7432..766f2d735f1e4a 100644 --- a/Mathlib/RingTheory/FreeCommRing.lean +++ b/Mathlib/RingTheory/FreeCommRing.lean @@ -98,7 +98,7 @@ protected theorem induction_on {C : FreeCommRing α → Prop} (z : FreeCommRing (fun m => Multiset.induction_on m h1 fun a m ih => by convert hm (of a) _ (hb a) ih apply of_cons) - (fun m ih => hn _ ih) ha + (fun _ ih => hn _ ih) ha section lift diff --git a/Mathlib/RingTheory/FreeRing.lean b/Mathlib/RingTheory/FreeRing.lean index 1ec0166f4f5312..507361f9d6e891 100644 --- a/Mathlib/RingTheory/FreeRing.lean +++ b/Mathlib/RingTheory/FreeRing.lean @@ -63,7 +63,7 @@ protected theorem induction_on {C : FreeRing α → Prop} (z : FreeRing α) (hn1 convert hm _ _ (hb a) ih rw [of, ← FreeAbelianGroup.of_mul] rfl) - (fun m ih => hn _ ih) ha + (fun _ ih => hn _ ih) ha section lift diff --git a/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean b/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean index ace75dcb78fce3..762d89039a33b4 100644 --- a/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean +++ b/Mathlib/RingTheory/GradedAlgebra/HomogeneousLocalization.lean @@ -228,10 +228,10 @@ theorem den_add (c1 c2 : NumDenSameDeg 𝒜 x) : ((c1 + c2).den : A) = c1.den * instance : CommMonoid (NumDenSameDeg 𝒜 x) where one := 1 mul := (· * ·) - mul_assoc c1 c2 c3 := ext _ (add_assoc _ _ _) (mul_assoc _ _ _) (mul_assoc _ _ _) - one_mul c := ext _ (zero_add _) (one_mul _) (one_mul _) - mul_one c := ext _ (add_zero _) (mul_one _) (mul_one _) - mul_comm c1 c2 := ext _ (add_comm _ _) (mul_comm _ _) (mul_comm _ _) + mul_assoc _ _ _ := ext _ (add_assoc _ _ _) (mul_assoc _ _ _) (mul_assoc _ _ _) + one_mul _ := ext _ (zero_add _) (one_mul _) (one_mul _) + mul_one _ := ext _ (add_zero _) (mul_one _) (mul_one _) + mul_comm _ _ := ext _ (add_comm _ _) (mul_comm _ _) (mul_comm _ _) instance : Pow (NumDenSameDeg 𝒜 x) ℕ where pow c n := diff --git a/Mathlib/RingTheory/HahnSeries/Summable.lean b/Mathlib/RingTheory/HahnSeries/Summable.lean index 871e001eae93b3..4405c005d34e1e 100644 --- a/Mathlib/RingTheory/HahnSeries/Summable.lean +++ b/Mathlib/RingTheory/HahnSeries/Summable.lean @@ -512,9 +512,9 @@ instance instField [Field R] : Field (HahnSeries Γ R) where rw [sub_sub_cancel] at h rw [← mul_assoc, mul_comm x, h] nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl qsmul := _ - qsmul_def := fun q a => rfl + qsmul_def := fun _ _ => rfl end Inversion diff --git a/Mathlib/RingTheory/HahnSeries/Valuation.lean b/Mathlib/RingTheory/HahnSeries/Valuation.lean index 95c72f7dfe144a..c1aec5076a7f11 100644 --- a/Mathlib/RingTheory/HahnSeries/Valuation.lean +++ b/Mathlib/RingTheory/HahnSeries/Valuation.lean @@ -37,7 +37,7 @@ variable (Γ R) [LinearOrderedCancelAddCommMonoid Γ] [Ring R] [IsDomain R] /-- The additive valuation on `HahnSeries Γ R`, returning the smallest index at which a Hahn Series has a nonzero coefficient, or `⊤` for the 0 series. -/ def addVal : AddValuation (HahnSeries Γ R) (WithTop Γ) := - AddValuation.of orderTop orderTop_zero (orderTop_one) (fun x y => min_orderTop_le_orderTop_add) + AddValuation.of orderTop orderTop_zero (orderTop_one) (fun _ _ => min_orderTop_le_orderTop_add) fun x y => by by_cases hx : x = 0; · simp [hx] by_cases hy : y = 0; · simp [hy] diff --git a/Mathlib/RingTheory/Ideal/Maps.lean b/Mathlib/RingTheory/Ideal/Maps.lean index 5a46dd702e1324..6a3982baf6a298 100644 --- a/Mathlib/RingTheory/Ideal/Maps.lean +++ b/Mathlib/RingTheory/Ideal/Maps.lean @@ -483,8 +483,8 @@ theorem map_mul : map f (I * J) = map f I * map f J := show (f (r * s)) ∈ map f I * map f J by rw [_root_.map_mul]; exact mul_mem_mul (mem_map_of_mem f hri) (mem_map_of_mem f hsj)) (span_mul_span (↑f '' ↑I) (↑f '' ↑J) ▸ (span_le.2 <| - Set.iUnion₂_subset fun i ⟨r, hri, hfri⟩ => - Set.iUnion₂_subset fun j ⟨s, hsj, hfsj⟩ => + Set.iUnion₂_subset fun _ ⟨r, hri, hfri⟩ => + Set.iUnion₂_subset fun _ ⟨s, hsj, hfsj⟩ => Set.singleton_subset_iff.2 <| hfri ▸ hfsj ▸ by rw [← _root_.map_mul]; exact mem_map_of_mem f (mul_mem_mul hri hsj))) diff --git a/Mathlib/RingTheory/Ideal/Operations.lean b/Mathlib/RingTheory/Ideal/Operations.lean index 50211d46f660e8..fcedd7484f3131 100644 --- a/Mathlib/RingTheory/Ideal/Operations.lean +++ b/Mathlib/RingTheory/Ideal/Operations.lean @@ -148,12 +148,12 @@ theorem mem_smul_span_singleton {I : Ideal R} {m : M} {x : M} : x ∈ I • span R ({m} : Set M) ↔ ∃ y ∈ I, y • m = x := ⟨fun hx => smul_induction_on hx - (fun r hri n hnm => + (fun r hri _ hnm => let ⟨s, hs⟩ := mem_span_singleton.1 hnm ⟨r * s, I.mul_mem_right _ hri, hs ▸ mul_smul r s m⟩) fun m1 m2 ⟨y1, hyi1, hy1⟩ ⟨y2, hyi2, hy2⟩ => ⟨y1 + y2, I.add_mem hyi1 hyi2, by rw [add_smul, hy1, hy2]⟩, - fun ⟨y, hyi, hy⟩ => hy ▸ smul_mem_smul hyi (subset_span <| Set.mem_singleton m)⟩ + fun ⟨_, hyi, hy⟩ => hy ▸ smul_mem_smul hyi (subset_span <| Set.mem_singleton m)⟩ theorem smul_le_right : I • N ≤ N := smul_le.2 fun r _ _ => N.smul_mem r @@ -605,7 +605,7 @@ theorem mul_sup_eq_of_coprime_right (h : K ⊔ J = ⊤) : I * K ⊔ J = I ⊔ J theorem sup_prod_eq_top {s : Finset ι} {J : ι → Ideal R} (h : ∀ i, i ∈ s → I ⊔ J i = ⊤) : (I ⊔ ∏ i ∈ s, J i) = ⊤ := Finset.prod_induction _ (fun J => I ⊔ J = ⊤) - (fun J K hJ hK => (sup_mul_eq_of_coprime_left hJ).trans hK) + (fun _ _ hJ hK => (sup_mul_eq_of_coprime_left hJ).trans hK) (by simp_rw [one_eq_top, sup_top_eq]) h theorem sup_multiset_prod_eq_top {s : Multiset (Ideal R)} (h : ∀ p ∈ s, I ⊔ p = ⊤) : @@ -694,8 +694,8 @@ theorem mul_eq_bot {R : Type*} [CommSemiring R] [NoZeroDivisors R] {I J : Ideal I * J = ⊥ ↔ I = ⊥ ∨ J = ⊥ := ⟨fun hij => or_iff_not_imp_left.mpr fun I_ne_bot => - J.eq_bot_iff.mpr fun j hj => - let ⟨i, hi, ne0⟩ := I.ne_bot_iff.mp I_ne_bot + J.eq_bot_iff.mpr fun _ hj => + let ⟨_, hi, ne0⟩ := I.ne_bot_iff.mp I_ne_bot Or.resolve_left (mul_eq_zero.mp ((I * J).eq_bot_iff.mp hij _ (mul_mem_mul hi hj))) ne0, fun h => by cases' h with h h <;> rw [← Ideal.mul_bot, h, Ideal.mul_comm]⟩ @@ -903,15 +903,15 @@ theorem IsPrime.radical_le_iff (hJ : IsPrime J) : I.radical ≤ J ↔ I ≤ J := IsRadical.radical_le_iff hJ.isRadical theorem radical_eq_sInf (I : Ideal R) : radical I = sInf { J : Ideal R | I ≤ J ∧ IsPrime J } := - le_antisymm (le_sInf fun J hJ ↦ hJ.2.radical_le_iff.2 hJ.1) fun r hr ↦ + le_antisymm (le_sInf fun _ hJ ↦ hJ.2.radical_le_iff.2 hJ.1) fun r hr ↦ by_contradiction fun hri ↦ let ⟨m, hIm, hm⟩ := zorn_le_nonempty₀ { K : Ideal R | r ∉ radical K } (fun c hc hcc y hyc => ⟨sSup c, fun ⟨n, hrnc⟩ => - let ⟨y, hyc, hrny⟩ := (Submodule.mem_sSup_of_directed ⟨y, hyc⟩ hcc.directedOn).1 hrnc + let ⟨_, hyc, hrny⟩ := (Submodule.mem_sSup_of_directed ⟨y, hyc⟩ hcc.directedOn).1 hrnc hc hyc ⟨n, hrny⟩, - fun z => le_sSup⟩) + fun _ => le_sSup⟩) I hri have hrm : r ∉ radical m := hm.prop have : ∀ x ∉ m, r ∈ radical (m ⊔ span {x}) := fun x hxm => diff --git a/Mathlib/RingTheory/Ideal/Pointwise.lean b/Mathlib/RingTheory/Ideal/Pointwise.lean index aca8181312f7ad..dad3393be00883 100644 --- a/Mathlib/RingTheory/Ideal/Pointwise.lean +++ b/Mathlib/RingTheory/Ideal/Pointwise.lean @@ -37,12 +37,12 @@ protected def pointwiseMulSemiringAction : MulSemiringAction M (Ideal R) where smul a := Ideal.map (MulSemiringAction.toRingHom _ _ a) one_smul I := congr_arg (I.map ·) (RingHom.ext <| one_smul M) |>.trans I.map_id - mul_smul a₁ a₂ I := + mul_smul _ _ I := congr_arg (I.map ·) (RingHom.ext <| mul_smul _ _) |>.trans (I.map_map _ _).symm smul_one a := by simp only [Ideal.one_eq_top]; exact Ideal.map_top _ smul_mul a I J := Ideal.map_mul (MulSemiringAction.toRingHom _ _ a) I J - smul_add a I J := Ideal.map_sup _ I J - smul_zero a := Ideal.map_bot + smul_add _ I J := Ideal.map_sup _ I J + smul_zero _ := Ideal.map_bot scoped[Pointwise] attribute [instance] Ideal.pointwiseMulSemiringAction diff --git a/Mathlib/RingTheory/Ideal/Quotient.lean b/Mathlib/RingTheory/Ideal/Quotient.lean index 5a9cc0195360c9..3889f7377adb06 100644 --- a/Mathlib/RingTheory/Ideal/Quotient.lean +++ b/Mathlib/RingTheory/Ideal/Quotient.lean @@ -197,13 +197,13 @@ protected noncomputable abbrev groupWithZero (I : Ideal R) [hI : I.IsMaximal] : will have computable inverses (and `qsmul`, `ratCast`) in some applications. See note [reducible non-instances]. -/ -protected noncomputable abbrev field (I : Ideal R) [hI : I.IsMaximal] : Field (R ⧸ I) where +protected noncomputable abbrev field (I : Ideal R) [I.IsMaximal] : Field (R ⧸ I) where __ := commRing _ __ := Quotient.groupWithZero _ nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl qsmul := _ - qsmul_def := fun q x => rfl + qsmul_def := fun _ _ => rfl /-- If the quotient by an ideal is a field, then the ideal is maximal. -/ theorem maximal_of_isField (I : Ideal R) (hqf : IsField (R ⧸ I)) : I.IsMaximal := by @@ -322,7 +322,7 @@ instance modulePi : Module (R ⧸ I) ((ι → R) ⧸ I.pi ι) where /-- `R^n/I^n` is isomorphic to `(R/I)^n` as an `R/I`-module. -/ noncomputable def piQuotEquiv : ((ι → R) ⧸ I.pi ι) ≃ₗ[R ⧸ I] ι → (R ⧸ I) where toFun := fun x ↦ - Quotient.liftOn' x (fun f i => Ideal.Quotient.mk I (f i)) fun a b hab => + Quotient.liftOn' x (fun f i => Ideal.Quotient.mk I (f i)) fun _ _ hab => funext fun i => (Submodule.Quotient.eq' _).2 (QuotientAddGroup.leftRel_apply.mp hab i) map_add' := by rintro ⟨_⟩ ⟨_⟩; rfl map_smul' := by rintro ⟨_⟩ ⟨_⟩; rfl diff --git a/Mathlib/RingTheory/IntegralDomain.lean b/Mathlib/RingTheory/IntegralDomain.lean index 2d5e9ee2a2c510..7126ac0db11453 100644 --- a/Mathlib/RingTheory/IntegralDomain.lean +++ b/Mathlib/RingTheory/IntegralDomain.lean @@ -92,9 +92,9 @@ def Fintype.divisionRingOfIsDomain (R : Type*) [Ring R] [IsDomain R] [DecidableE __ := Fintype.groupWithZeroOfCancel R __ := ‹Ring R› nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl qsmul := _ - qsmul_def := fun q a => rfl + qsmul_def := fun _ _ => rfl /-- Every finite commutative domain is a field. More generally, commutativity is not required: this can be found in `Mathlib.RingTheory.LittleWedderburn`. -/ diff --git a/Mathlib/RingTheory/JacobsonIdeal.lean b/Mathlib/RingTheory/JacobsonIdeal.lean index 5f513287fa395b..adf95dc2bcc16b 100644 --- a/Mathlib/RingTheory/JacobsonIdeal.lean +++ b/Mathlib/RingTheory/JacobsonIdeal.lean @@ -414,7 +414,7 @@ end IsLocal theorem isPrimary_of_isMaximal_radical [CommRing R] {I : Ideal R} (hi : IsMaximal (radical I)) : IsPrimary I := have : radical I = jacobson I := - le_antisymm (le_sInf fun M ⟨him, hm⟩ => hm.isPrime.radical_le_iff.2 him) + le_antisymm (le_sInf fun _ ⟨him, hm⟩ => hm.isPrime.radical_le_iff.2 him) (sInf_le ⟨le_radical, hi⟩) ⟨ne_top_of_lt <| lt_of_le_of_lt le_radical (lt_top_iff_ne_top.2 hi.1.1), fun {x y} hxy => ((isLocal_of_isMaximal_radical hi).mem_jacobson_or_exists_inv y).symm.imp diff --git a/Mathlib/RingTheory/Kaehler/Basic.lean b/Mathlib/RingTheory/Kaehler/Basic.lean index 09bc7c6dc0c453..daf09320aeba75 100644 --- a/Mathlib/RingTheory/Kaehler/Basic.lean +++ b/Mathlib/RingTheory/Kaehler/Basic.lean @@ -545,8 +545,8 @@ theorem KaehlerDifferential.kerTotal_mkQ_single_smul (r : R) (x y) : (y𝖣r • noncomputable def KaehlerDifferential.derivationQuotKerTotal : Derivation R S ((S →₀ S) ⧸ KaehlerDifferential.kerTotal R S) where toFun x := 1𝖣x - map_add' x y := KaehlerDifferential.kerTotal_mkQ_single_add _ _ _ _ _ - map_smul' r s := KaehlerDifferential.kerTotal_mkQ_single_smul _ _ _ _ _ + map_add' _ _ := KaehlerDifferential.kerTotal_mkQ_single_add _ _ _ _ _ + map_smul' _ _ := KaehlerDifferential.kerTotal_mkQ_single_smul _ _ _ _ _ map_one_eq_zero' := KaehlerDifferential.kerTotal_mkQ_single_algebraMap_one _ _ _ leibniz' a b := (KaehlerDifferential.kerTotal_mkQ_single_mul _ _ _ _ _).trans diff --git a/Mathlib/RingTheory/LocalProperties/Basic.lean b/Mathlib/RingTheory/LocalProperties/Basic.lean index a3ece3c9a9726d..966f297fe56568 100644 --- a/Mathlib/RingTheory/LocalProperties/Basic.lean +++ b/Mathlib/RingTheory/LocalProperties/Basic.lean @@ -268,7 +268,7 @@ open scoped nonZeroDivisors /-- Let `I J : Ideal R`. If the localization of `I` at each maximal ideal `P` is included in the localization of `J` at `P`, then `I ≤ J`. -/ theorem Ideal.le_of_localization_maximal {I J : Ideal R} - (h : ∀ (P : Ideal R) (hP : P.IsMaximal), + (h : ∀ (P : Ideal R) (_ : P.IsMaximal), Ideal.map (algebraMap R (Localization.AtPrime P)) I ≤ Ideal.map (algebraMap R (Localization.AtPrime P)) J) : I ≤ J := by @@ -300,7 +300,7 @@ theorem Ideal.eq_of_localization_maximal {I J : Ideal R} /-- An ideal is trivial if its localization at every maximal ideal is trivial. -/ theorem ideal_eq_bot_of_localization' (I : Ideal R) - (h : ∀ (J : Ideal R) (hJ : J.IsMaximal), + (h : ∀ (J : Ideal R) (_ : J.IsMaximal), Ideal.map (algebraMap R (Localization.AtPrime J)) I = ⊥) : I = ⊥ := Ideal.eq_of_localization_maximal fun P hP => by simpa using h P hP @@ -309,7 +309,7 @@ theorem ideal_eq_bot_of_localization' (I : Ideal R) -- localized modules. /-- An ideal is trivial if its localization at every maximal ideal is trivial. -/ theorem ideal_eq_bot_of_localization (I : Ideal R) - (h : ∀ (J : Ideal R) (hJ : J.IsMaximal), + (h : ∀ (J : Ideal R) (_ : J.IsMaximal), IsLocalization.coeSubmodule (Localization.AtPrime J) I = ⊥) : I = ⊥ := ideal_eq_bot_of_localization' _ fun P hP => @@ -318,7 +318,7 @@ theorem ideal_eq_bot_of_localization (I : Ideal R) exact ⟨x, hx, rfl⟩ theorem eq_zero_of_localization (r : R) - (h : ∀ (J : Ideal R) (hJ : J.IsMaximal), algebraMap R (Localization.AtPrime J) r = 0) : + (h : ∀ (J : Ideal R) (_ : J.IsMaximal), algebraMap R (Localization.AtPrime J) r = 0) : r = 0 := by rw [← Ideal.span_singleton_eq_bot] apply ideal_eq_bot_of_localization diff --git a/Mathlib/RingTheory/LocalProperties/Reduced.lean b/Mathlib/RingTheory/LocalProperties/Reduced.lean index 65df1788488871..5a7cb0ef69937c 100644 --- a/Mathlib/RingTheory/LocalProperties/Reduced.lean +++ b/Mathlib/RingTheory/LocalProperties/Reduced.lean @@ -20,7 +20,7 @@ Let `R` be a commutative ring, `M` be a submonoid of `R`. -/ /-- `M⁻¹R` is reduced if `R` is reduced. -/ -theorem isReduced_localizationPreserves : LocalizationPreserves fun R hR => IsReduced R := by +theorem isReduced_localizationPreserves : LocalizationPreserves fun R _ => IsReduced R := by introv R _ _ constructor rintro x ⟨_ | n, e⟩ @@ -43,7 +43,7 @@ instance {R : Type*} [CommRing R] (M : Submonoid R) [IsReduced R] : IsReduced (L isReduced_localizationPreserves M _ inferInstance /-- `R` is reduced if `Rₘ` is reduced for all maximal ideal `m`. -/ -theorem isReduced_ofLocalizationMaximal : OfLocalizationMaximal fun R hR => IsReduced R := by +theorem isReduced_ofLocalizationMaximal : OfLocalizationMaximal fun R _ => IsReduced R := by introv R h constructor intro x hx diff --git a/Mathlib/RingTheory/Localization/AtPrime.lean b/Mathlib/RingTheory/Localization/AtPrime.lean index 5b122fb2d696c5..cec0198c34a92a 100644 --- a/Mathlib/RingTheory/Localization/AtPrime.lean +++ b/Mathlib/RingTheory/Localization/AtPrime.lean @@ -44,7 +44,7 @@ namespace Ideal def primeCompl : Submonoid R where carrier := (Pᶜ : Set R) one_mem' := by convert P.ne_top_iff_one.1 hp.1 - mul_mem' {x y} hnx hny hxy := Or.casesOn (hp.mem_or_mem hxy) hnx hny + mul_mem' {_ _} hnx hny hxy := Or.casesOn (hp.mem_or_mem hxy) hnx hny theorem primeCompl_le_nonZeroDivisors [NoZeroDivisors R] : P.primeCompl ≤ nonZeroDivisors R := le_nonZeroDivisors_of_noZeroDivisors <| not_not_intro P.zero_mem @@ -188,12 +188,12 @@ theorem AtPrime.map_eq_maximalIdeal : -- Porting note: can not find `hI` rw [map_comap I.primeCompl] -theorem le_comap_primeCompl_iff {J : Ideal P} [hJ : J.IsPrime] {f : R →+* P} : +theorem le_comap_primeCompl_iff {J : Ideal P} [J.IsPrime] {f : R →+* P} : I.primeCompl ≤ J.primeCompl.comap f ↔ J.comap f ≤ I := ⟨fun h x hx => by contrapose! hx exact h hx, - fun h x hx hfxJ => hx (h hfxJ)⟩ + fun h _ hx hfxJ => hx (h hfxJ)⟩ variable (I) diff --git a/Mathlib/RingTheory/Localization/Basic.lean b/Mathlib/RingTheory/Localization/Basic.lean index 71f588f1472167..60472d72cb4017 100644 --- a/Mathlib/RingTheory/Localization/Basic.lean +++ b/Mathlib/RingTheory/Localization/Basic.lean @@ -600,7 +600,7 @@ theorem map_comp_map {A : Type*} [CommSemiring A] {U : Submonoid A} {W} [CommSem of the induced maps equals the map of localizations induced by `l ∘ g`. -/ theorem map_map {A : Type*} [CommSemiring A] {U : Submonoid A} {W} [CommSemiring W] [Algebra A W] [IsLocalization U W] {l : P →+* A} (hl : T ≤ U.comap l) (x : S) : - map W l hl (map Q g hy x) = map W (l.comp g) (fun x hx => hl (hy hx)) x := by + map W l hl (map Q g hy x) = map W (l.comp g) (fun _ hx => hl (hy hx)) x := by rw [← map_comp_map (Q := Q) hy hl]; rfl theorem map_smul (x : S) (z : R) : map Q g hy (z • x : S) = g z • map Q g hy x := by diff --git a/Mathlib/RingTheory/Localization/FractionRing.lean b/Mathlib/RingTheory/Localization/FractionRing.lean index f4b231a725789d..e4e325d226ed21 100644 --- a/Mathlib/RingTheory/Localization/FractionRing.lean +++ b/Mathlib/RingTheory/Localization/FractionRing.lean @@ -126,9 +126,9 @@ noncomputable abbrev toField : Field K where 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 nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl qsmul := _ - qsmul_def := fun a x => rfl + qsmul_def := fun _ _ => rfl lemma surjective_iff_isField [IsDomain R] : Function.Surjective (algebraMap R K) ↔ IsField R where mp h := (RingEquiv.ofBijective (algebraMap R K) diff --git a/Mathlib/RingTheory/Multiplicity.lean b/Mathlib/RingTheory/Multiplicity.lean index 457a6e35fcef74..1ae9ede282f648 100644 --- a/Mathlib/RingTheory/Multiplicity.lean +++ b/Mathlib/RingTheory/Multiplicity.lean @@ -199,7 +199,7 @@ theorem exists_eq_pow_mul_and_not_dvd {a b : α} (hfin : Finite a b) : theorem multiplicity_le_multiplicity_iff {a b : α} {c d : β} : multiplicity a b ≤ multiplicity c d ↔ ∀ n : ℕ, a ^ n ∣ b → c ^ n ∣ d := - ⟨fun h n hab => pow_dvd_of_le_multiplicity (le_trans (le_multiplicity_of_pow_dvd hab) h), fun h => + ⟨fun h _ hab => pow_dvd_of_le_multiplicity (le_trans (le_multiplicity_of_pow_dvd hab) h), fun h => letI := Classical.dec (Finite a b) if hab : Finite a b then by rw [← PartENat.natCast_get (finite_iff_dom.1 hab)] diff --git a/Mathlib/RingTheory/MvPolynomial/Homogeneous.lean b/Mathlib/RingTheory/MvPolynomial/Homogeneous.lean index 4772bb3e6107bd..a5847ddf565cd7 100644 --- a/Mathlib/RingTheory/MvPolynomial/Homogeneous.lean +++ b/Mathlib/RingTheory/MvPolynomial/Homogeneous.lean @@ -64,7 +64,7 @@ def homogeneousSubmodule (n : ℕ) : Submodule R (MvPolynomial σ R) where apply hc rw [h] exact smul_zero r - zero_mem' d hd := False.elim (hd <| coeff_zero _) + 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 diff --git a/Mathlib/RingTheory/MvPolynomial/Symmetric/FundamentalTheorem.lean b/Mathlib/RingTheory/MvPolynomial/Symmetric/FundamentalTheorem.lean index 717b6f8ac0bf23..8a1f28577910ec 100644 --- a/Mathlib/RingTheory/MvPolynomial/Symmetric/FundamentalTheorem.lean +++ b/Mathlib/RingTheory/MvPolynomial/Symmetric/FundamentalTheorem.lean @@ -61,7 +61,7 @@ section accumulate /-- The `j`th entry of `accumulate n m t` is the sum of `t i` over all `i ≥ j`. -/ @[simps] def accumulate (n m : ℕ) : (Fin n → ℕ) →+ (Fin m → ℕ) where toFun t j := ∑ i in univ.filter (fun i : Fin n ↦ (j : ℕ) ≤ i), t i - map_zero' := funext <| fun j ↦ sum_eq_zero <| fun h _ ↦ rfl + map_zero' := funext <| fun _ ↦ sum_eq_zero <| fun _ _ ↦ rfl map_add' t₁ t₂ := funext <| fun j ↦ by dsimp only; exact sum_add_distrib /-- The `i`th entry of `invAccumulate n m s` is `s i - s (i+1)`, where `s j = 0` if `j ≥ m`. -/ diff --git a/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean b/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean index a5d6459f7d56f0..d580a2fd428fcd 100644 --- a/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean +++ b/Mathlib/RingTheory/MvPolynomial/WeightedHomogeneous.lean @@ -130,7 +130,7 @@ def weightedHomogeneousSubmodule (w : σ → M) (m : M) : Submodule R (MvPolynom smul_mem' r a ha c hc := by rw [coeff_smul] at hc exact ha (right_ne_zero_of_mul hc) - zero_mem' d hd := False.elim (hd <| coeff_zero _) + 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 diff --git a/Mathlib/RingTheory/NonUnitalSubring/Basic.lean b/Mathlib/RingTheory/NonUnitalSubring/Basic.lean index f71dbda3f4e858..e1b12c0376adc2 100644 --- a/Mathlib/RingTheory/NonUnitalSubring/Basic.lean +++ b/Mathlib/RingTheory/NonUnitalSubring/Basic.lean @@ -713,13 +713,13 @@ theorem closure_induction₂ {s : Set R} {p : R → R → Prop} {a b : R} (ha : theorem mem_closure_iff {s : Set R} {x} : x ∈ closure s ↔ x ∈ AddSubgroup.closure (Subsemigroup.closure s : Set R) := ⟨fun h => - closure_induction h (fun x hx => AddSubgroup.subset_closure <| Subsemigroup.subset_closure hx) - (AddSubgroup.zero_mem _) (fun x y hx hy => AddSubgroup.add_mem _ hx hy) - (fun x hx => AddSubgroup.neg_mem _ hx) fun x y hx hy => + closure_induction h (fun _ hx => AddSubgroup.subset_closure <| Subsemigroup.subset_closure hx) + (AddSubgroup.zero_mem _) (fun _ _ hx hy => AddSubgroup.add_mem _ hx hy) + (fun _ hx => AddSubgroup.neg_mem _ hx) fun x _ hx hy => AddSubgroup.closure_induction hy (fun q hq => AddSubgroup.closure_induction hx - (fun p hp => AddSubgroup.subset_closure ((Subsemigroup.closure s).mul_mem hp hq)) + (fun _ hp => AddSubgroup.subset_closure ((Subsemigroup.closure s).mul_mem hp hq)) (by rw [zero_mul q]; apply AddSubgroup.zero_mem _) (fun p₁ p₂ ihp₁ ihp₂ => by rw [add_mul p₁ p₂ q]; apply AddSubgroup.add_mem _ ihp₁ ihp₂) fun x hx => by @@ -732,10 +732,10 @@ theorem mem_closure_iff {s : Set R} {x} : rw [f]; apply AddSubgroup.neg_mem _ hz, fun h => AddSubgroup.closure_induction h - (fun x hx => - Subsemigroup.closure_induction hx (fun x hx => subset_closure hx) fun x y hx hy => + (fun _ hx => + Subsemigroup.closure_induction hx (fun _ hx => subset_closure hx) fun _ _ hx hy => mul_mem hx hy) - (zero_mem _) (fun x y hx hy => add_mem hx hy) fun x hx => neg_mem hx⟩ + (zero_mem _) (fun _ _ hx hy => add_mem hx hy) fun _ hx => neg_mem hx⟩ /-- If all elements of `s : Set A` commute pairwise, then `closure s` is a commutative ring. -/ def closureNonUnitalCommRingOfComm {R : Type u} [NonUnitalRing R] {s : Set R} diff --git a/Mathlib/RingTheory/Nullstellensatz.lean b/Mathlib/RingTheory/Nullstellensatz.lean index 2e6928088762cd..4b18643ff516f0 100644 --- a/Mathlib/RingTheory/Nullstellensatz.lean +++ b/Mathlib/RingTheory/Nullstellensatz.lean @@ -57,7 +57,7 @@ theorem zeroLocus_top : zeroLocus (⊤ : Ideal (MvPolynomial σ k)) = ⊥ := /-- Ideal of polynomials with common zeroes at all elements of a set -/ def vanishingIdeal (V : Set (σ → k)) : Ideal (MvPolynomial σ k) where carrier := {p | ∀ x ∈ V, eval x p = 0} - zero_mem' x _ := RingHom.map_zero _ + zero_mem' _ _ := RingHom.map_zero _ add_mem' {p q} hp hq x hx := by simp only [hq x hx, hp x hx, add_zero, RingHom.map_add] smul_mem' p q hq x hx := by simp only [hq x hx, Algebra.id.smul_eq_mul, mul_zero, RingHom.map_mul] @@ -131,14 +131,14 @@ def pointToPoint (x : σ → k) : PrimeSpectrum (MvPolynomial σ k) := theorem vanishingIdeal_pointToPoint (V : Set (σ → k)) : PrimeSpectrum.vanishingIdeal (pointToPoint '' V) = MvPolynomial.vanishingIdeal V := le_antisymm - (fun p hp x hx => + (fun _ hp x hx => (((PrimeSpectrum.mem_vanishingIdeal _ _).1 hp) ⟨vanishingIdeal {x}, by infer_instance⟩ <| by exact ⟨x, ⟨hx, rfl⟩⟩) -- Porting note: tactic mode code compiles but term mode does not x rfl) - fun p hp => - (PrimeSpectrum.mem_vanishingIdeal _ _).2 fun I hI => + fun _ hp => + (PrimeSpectrum.mem_vanishingIdeal _ _).2 fun _ hI => let ⟨x, hx⟩ := hI - hx.2 ▸ fun x' hx' => (Set.mem_singleton_iff.1 hx').symm ▸ hp x hx.1 + hx.2 ▸ fun _ hx' => (Set.mem_singleton_iff.1 hx').symm ▸ hp x hx.1 theorem pointToPoint_zeroLocus_le (I : Ideal (MvPolynomial σ k)) : pointToPoint '' MvPolynomial.zeroLocus I ≤ PrimeSpectrum.zeroLocus ↑I := fun J hJ => diff --git a/Mathlib/RingTheory/OreLocalization/Ring.lean b/Mathlib/RingTheory/OreLocalization/Ring.lean index 2a911ebd370177..73dca39178779d 100644 --- a/Mathlib/RingTheory/OreLocalization/Ring.lean +++ b/Mathlib/RingTheory/OreLocalization/Ring.lean @@ -275,9 +275,9 @@ instance : DivisionRing R[R⁰⁻¹] where mul_inv_cancel := OreLocalization.mul_inv_cancel inv_zero := OreLocalization.inv_zero nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl qsmul := _ - qsmul_def := fun q a => rfl + qsmul_def := fun _ _ => rfl end DivisionRing diff --git a/Mathlib/RingTheory/Perfection.lean b/Mathlib/RingTheory/Perfection.lean index 341d08d64c1150..38d57045aa3ebc 100644 --- a/Mathlib/RingTheory/Perfection.lean +++ b/Mathlib/RingTheory/Perfection.lean @@ -165,14 +165,14 @@ noncomputable def lift (R : Type u₁) [CommSemiring R] [CharP R p] [PerfectRing toFun f := { toFun := fun r => ⟨fun n => f (((frobeniusEquiv R p).symm : R →+* R)^[n] r), fun n => by erw [← f.map_pow, Function.iterate_succ_apply', frobeniusEquiv_symm_pow_p]⟩ - map_one' := ext fun n => (congr_arg f <| iterate_map_one _ _).trans f.map_one - map_mul' := fun x y => - ext fun n => (congr_arg f <| iterate_map_mul _ _ _ _).trans <| f.map_mul _ _ - map_zero' := ext fun n => (congr_arg f <| iterate_map_zero _ _).trans f.map_zero - map_add' := fun x y => - ext fun n => (congr_arg f <| iterate_map_add _ _ _ _).trans <| f.map_add _ _ } + map_one' := ext fun _ => (congr_arg f <| iterate_map_one _ _).trans f.map_one + map_mul' := fun _ _ => + ext fun _ => (congr_arg f <| iterate_map_mul _ _ _ _).trans <| f.map_mul _ _ + map_zero' := ext fun _ => (congr_arg f <| iterate_map_zero _ _).trans f.map_zero + map_add' := fun _ _ => + ext fun _ => (congr_arg f <| iterate_map_add _ _ _ _).trans <| f.map_add _ _ } invFun := RingHom.comp <| coeff S p 0 - left_inv f := RingHom.ext fun r => rfl + left_inv _ := RingHom.ext fun _ => rfl right_inv f := RingHom.ext fun r => ext fun n => show coeff S p 0 (f (((frobeniusEquiv R p).symm)^[n] r)) = coeff S p n (f r) by rw [← coeff_iterate_frobenius _ 0 n, zero_add, ← RingHom.map_iterate_frobenius, @@ -190,9 +190,9 @@ variable {R} {S : Type u₂} [CommSemiring S] [CharP S p] def map (φ : R →+* S) : Ring.Perfection R p →+* Ring.Perfection S p where toFun f := ⟨fun n => φ (coeff R p n f), fun n => by rw [← φ.map_pow, coeff_pow_p']⟩ map_one' := Subtype.eq <| funext fun _ => φ.map_one - map_mul' f g := Subtype.eq <| funext fun n => φ.map_mul _ _ + map_mul' _ _ := Subtype.eq <| funext fun _ => φ.map_mul _ _ map_zero' := Subtype.eq <| funext fun _ => φ.map_zero - map_add' f g := Subtype.eq <| funext fun n => φ.map_add _ _ + map_add' _ _ := Subtype.eq <| funext fun _ => φ.map_add _ _ theorem coeff_map (φ : R →+* S) (f : Ring.Perfection R p) (n : ℕ) : coeff S p n (map p φ f) = φ (coeff R p n f) := rfl @@ -237,7 +237,7 @@ theorem of : PerfectionMap p (Perfection.coeff R p 0) := /-- For a perfect ring, it itself is the perfection. -/ theorem id [PerfectRing R p] : PerfectionMap p (RingHom.id R) := - { injective := fun x y hxy => hxy 0 + { injective := fun _ _ hxy => hxy 0 surjective := fun f hf => ⟨f 0, fun n => show ((frobeniusEquiv R p).symm)^[n] (f 0) = f n from diff --git a/Mathlib/RingTheory/Polynomial/Basic.lean b/Mathlib/RingTheory/Polynomial/Basic.lean index ab6d03ba20af21..2c47e070c61a3e 100644 --- a/Mathlib/RingTheory/Polynomial/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Basic.lean @@ -788,7 +788,7 @@ variable (σ) {r : R} namespace Polynomial theorem prime_C_iff : Prime (C r) ↔ Prime r := - ⟨comap_prime C (evalRingHom (0 : R)) fun r => eval_C, fun hr => by + ⟨comap_prime C (evalRingHom (0 : R)) fun _ => eval_C, fun hr => by have := hr.1 rw [← Ideal.span_singleton_prime] at hr ⊢ · rw [← Set.image_singleton, ← Ideal.map_span] @@ -912,7 +912,7 @@ protected theorem Polynomial.isNoetherianRing [inst : IsNoetherianRing R] : IsNo let ⟨N, HN⟩ := hm let ⟨s, hs⟩ := I.is_fg_degreeLE N have hm2 : ∀ k, I.leadingCoeffNth k ≤ M := fun k => - Or.casesOn (le_or_lt k N) (fun h => HN ▸ I.leadingCoeffNth_mono h) fun h x hx => + Or.casesOn (le_or_lt 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 diff --git a/Mathlib/RingTheory/Polynomial/Cyclotomic/Eval.lean b/Mathlib/RingTheory/Polynomial/Cyclotomic/Eval.lean index 4a1ad15664ee85..a0b678d3d5f3f4 100644 --- a/Mathlib/RingTheory/Polynomial/Cyclotomic/Eval.lean +++ b/Mathlib/RingTheory/Polynomial/Cyclotomic/Eval.lean @@ -212,7 +212,7 @@ theorem sub_one_pow_totient_le_cyclotomic_eval {q : ℝ} (hq' : 1 < q) : ∀ n, (q - 1) ^ totient n ≤ (cyclotomic n ℝ).eval q | 0 => by simp only [totient_zero, _root_.pow_zero, cyclotomic_zero, eval_one, le_refl] | 1 => by simp only [totient_one, pow_one, cyclotomic_one, eval_sub, eval_X, eval_one, le_refl] - | n + 2 => (sub_one_pow_totient_lt_cyclotomic_eval le_add_self hq').le + | _ + 2 => (sub_one_pow_totient_lt_cyclotomic_eval le_add_self hq').le theorem cyclotomic_eval_lt_add_one_pow_totient {n : ℕ} {q : ℝ} (hn' : 3 ≤ n) (hq' : 1 < q) : (cyclotomic n ℝ).eval q < (q + 1) ^ totient n := by @@ -285,7 +285,7 @@ theorem cyclotomic_eval_le_add_one_pow_totient {q : ℝ} (hq' : 1 < q) : | 0 => by simp | 1 => by simp [add_assoc, add_nonneg, zero_le_one] | 2 => by simp - | n + 3 => (cyclotomic_eval_lt_add_one_pow_totient le_add_self hq').le + | _ + 3 => (cyclotomic_eval_lt_add_one_pow_totient le_add_self hq').le theorem sub_one_pow_totient_lt_natAbs_cyclotomic_eval {n : ℕ} {q : ℕ} (hn' : 1 < n) (hq : q ≠ 1) : (q - 1) ^ totient n < ((cyclotomic n ℤ).eval ↑q).natAbs := by diff --git a/Mathlib/RingTheory/Polynomial/Quotient.lean b/Mathlib/RingTheory/Polynomial/Quotient.lean index 6d9f4b7aa653f9..6e259934716705 100644 --- a/Mathlib/RingTheory/Polynomial/Quotient.lean +++ b/Mathlib/RingTheory/Polynomial/Quotient.lean @@ -211,10 +211,10 @@ lemma quotientEquivQuotientMvPolynomial_rightInverse (I : Ideal R) : Function.RightInverse (eval₂ (Ideal.Quotient.lift I ((Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R))).comp C) - fun i hi => quotient_map_C_eq_zero hi) + fun _ hi => quotient_map_C_eq_zero hi) fun i => Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R)) (X i)) (Ideal.Quotient.lift (Ideal.map C I : Ideal (MvPolynomial σ R)) - (eval₂Hom (C.comp (Ideal.Quotient.mk I)) X) fun a ha => eval₂_C_mk_eq_zero ha) := by + (eval₂Hom (C.comp (Ideal.Quotient.mk I)) X) fun _ ha => eval₂_C_mk_eq_zero ha) := by intro f apply induction_on f · intro r @@ -233,10 +233,10 @@ lemma quotientEquivQuotientMvPolynomial_leftInverse (I : Ideal R) : Function.LeftInverse (eval₂ (Ideal.Quotient.lift I ((Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R))).comp C) - fun i hi => quotient_map_C_eq_zero hi) + fun _ hi => quotient_map_C_eq_zero hi) fun i => Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R)) (X i)) (Ideal.Quotient.lift (Ideal.map C I : Ideal (MvPolynomial σ R)) - (eval₂Hom (C.comp (Ideal.Quotient.mk I)) X) fun a ha => eval₂_C_mk_eq_zero ha) := by + (eval₂Hom (C.comp (Ideal.Quotient.mk I)) X) fun _ ha => eval₂_C_mk_eq_zero ha) := by intro f obtain ⟨f, rfl⟩ := Ideal.Quotient.mk_surjective f apply induction_on f diff --git a/Mathlib/RingTheory/PowerBasis.lean b/Mathlib/RingTheory/PowerBasis.lean index a9cf86b0049c16..3800d1cc290331 100644 --- a/Mathlib/RingTheory/PowerBasis.lean +++ b/Mathlib/RingTheory/PowerBasis.lean @@ -308,7 +308,7 @@ noncomputable def liftEquiv (pb : PowerBasis A S) : (S →ₐ[A] S') ≃ { y : S' // aeval y (minpoly A pb.gen) = 0 } where toFun f := ⟨f pb.gen, by rw [aeval_algHom_apply, minpoly.aeval, map_zero]⟩ invFun y := pb.lift y y.2 - left_inv f := pb.algHom_ext <| lift_gen _ _ _ + left_inv _ := pb.algHom_ext <| lift_gen _ _ _ right_inv y := Subtype.ext <| lift_gen _ _ y.prop /-- `pb.liftEquiv'` states that elements of the root set of the minimal diff --git a/Mathlib/RingTheory/ReesAlgebra.lean b/Mathlib/RingTheory/ReesAlgebra.lean index 8aaec4c3b41b3a..6fe710e881b772 100644 --- a/Mathlib/RingTheory/ReesAlgebra.lean +++ b/Mathlib/RingTheory/ReesAlgebra.lean @@ -50,7 +50,7 @@ def reesAlgebra : Subalgebra R R[X] where add_mem' hf hg i := by rw [coeff_add] exact Ideal.add_mem _ (hf i) (hg i) - zero_mem' i := Ideal.zero_mem _ + zero_mem' _ := Ideal.zero_mem _ algebraMap_mem' r i := by rw [algebraMap_apply, coeff_C] split_ifs with h diff --git a/Mathlib/RingTheory/Regular/RegularSequence.lean b/Mathlib/RingTheory/Regular/RegularSequence.lean index a1e81fdf08b75e..5477dd102ec5b3 100644 --- a/Mathlib/RingTheory/Regular/RegularSequence.lean +++ b/Mathlib/RingTheory/Regular/RegularSequence.lean @@ -333,7 +333,7 @@ def recIterModByRegularWithRing {R : Type u} → [CommRing R] → {M : Type v} → [AddCommGroup M] → [Module R M] → {rs : List R} → (h : IsWeaklyRegular M rs) → motive R M rs h | R, _, M, _, _, [], _ => nil R M - | R, _, M, _, _, r :: rs, h => + | _, _, M, _, _, r :: rs, h => let ⟨h1, h2⟩ := (isWeaklyRegular_cons_iff' M r rs).mp h cons r rs h1 h2 (recIterModByRegularWithRing nil cons h2) termination_by _ _ _ _ _ rs => List.length rs diff --git a/Mathlib/RingTheory/SimpleModule.lean b/Mathlib/RingTheory/SimpleModule.lean index 9a27c4b72d3044..ca9632f9632b52 100644 --- a/Mathlib/RingTheory/SimpleModule.lean +++ b/Mathlib/RingTheory/SimpleModule.lean @@ -398,9 +398,9 @@ noncomputable instance _root_.Module.End.divisionRing exact (LinearEquiv.ofBijective _ <| bijective_of_ne_zero a0).right_inv _ inv_zero := dif_pos rfl nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl qsmul := _ - qsmul_def := fun q a => rfl + qsmul_def := fun _ _ => rfl end LinearMap diff --git a/Mathlib/RingTheory/TensorProduct/Basic.lean b/Mathlib/RingTheory/TensorProduct/Basic.lean index 3bddb995b0910c..cbcde91fc95fdb 100644 --- a/Mathlib/RingTheory/TensorProduct/Basic.lean +++ b/Mathlib/RingTheory/TensorProduct/Basic.lean @@ -692,8 +692,8 @@ def lift (f : A →ₐ[S] C) (g : B →ₐ[R] C) (hfg : ∀ x y, Commute (f x) ( (AlgebraTensorModule.lift <| letI restr : (C →ₗ[S] C) →ₗ[S] _ := { toFun := (·.restrictScalars R) - map_add' := fun f g => LinearMap.ext fun x => rfl - map_smul' := fun c g => LinearMap.ext fun x => rfl } + map_add' := fun _ _ => LinearMap.ext fun _ => rfl + map_smul' := fun _ _ => LinearMap.ext fun _ => rfl } LinearMap.flip <| (restr ∘ₗ LinearMap.mul S C ∘ₗ f.toLinearMap).flip ∘ₗ g) (fun a₁ a₂ b₁ b₂ => show f (a₁ * a₂) * g (b₁ * b₂) = f a₁ * g b₁ * (f a₂ * g b₂) by rw [map_mul, map_mul, (hfg a₂ b₁).mul_mul_mul_comm]) @@ -707,7 +707,7 @@ theorem lift_tmul (f : A →ₐ[S] C) (g : B →ₐ[R] C) (hfg : ∀ x y, Commut @[simp] theorem lift_includeLeft_includeRight : - lift includeLeft includeRight (fun a b => (Commute.one_right _).tmul (Commute.one_left _)) = + lift includeLeft includeRight (fun _ _ => (Commute.one_right _).tmul (Commute.one_left _)) = .id S (A ⊗[R] B) := by ext <;> simp @@ -733,7 +733,7 @@ algebra. -/ def liftEquiv : {fg : (A →ₐ[S] C) × (B →ₐ[R] C) // ∀ x y, Commute (fg.1 x) (fg.2 y)} ≃ ((A ⊗[R] B) →ₐ[S] C) where toFun fg := lift fg.val.1 fg.val.2 fg.prop - invFun f' := ⟨(f'.comp includeLeft, (f'.restrictScalars R).comp includeRight), fun x y => + invFun f' := ⟨(f'.comp includeLeft, (f'.restrictScalars R).comp includeRight), fun _ _ => ((Commute.one_right _).tmul (Commute.one_left _)).map f'⟩ left_inv fg := by ext <;> simp right_inv f' := by ext <;> simp diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain.lean b/Mathlib/RingTheory/UniqueFactorizationDomain.lean index ab4db15117b064..a439e8e8833c89 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain.lean @@ -101,7 +101,7 @@ theorem induction_on_irreducible {P : α → Prop} (a : α) (h0 : P 0) (hu : ∀ theorem exists_factors (a : α) : a ≠ 0 → ∃ f : Multiset α, (∀ b ∈ f, Irreducible b) ∧ Associated f.prod a := induction_on_irreducible a (fun h => (h rfl).elim) - (fun u hu _ => ⟨0, fun _ h => False.elim (Multiset.not_mem_zero _ h), hu.unit, one_mul _⟩) + (fun _ hu _ => ⟨0, fun _ h => False.elim (Multiset.not_mem_zero _ h), hu.unit, one_mul _⟩) fun a i ha0 hi ih _ => let ⟨s, hs⟩ := ih ha0 ⟨i ::ₘ s, fun b H => (Multiset.mem_cons.1 H).elim (fun h => h.symm ▸ hi) (hs.1 b), by @@ -118,7 +118,7 @@ theorem not_unit_iff_exists_factors_eq (a : α) (hn0 : a ≠ 0) : · obtain rfl | ha := Multiset.mem_cons.1 ha exacts [Associated.irreducible ⟨u, rfl⟩ (hi b h), hi a (Multiset.mem_of_mem_erase ha)] · rw [Multiset.prod_cons, mul_comm b, mul_assoc, Multiset.prod_erase h, mul_comm], - fun ⟨f, hi, he, hne⟩ => + fun ⟨_, hi, he, hne⟩ => let ⟨b, h⟩ := Multiset.exists_mem_of_ne_zero hne not_isUnit_of_not_isUnit_dvd (hi b h).not_unit <| he ▸ Multiset.dvd_prod h⟩ @@ -494,7 +494,7 @@ theorem exists_mem_factors_of_dvd {a p : α} (ha0 : a ≠ 0) (hp : Irreducible p have hb0 : b ≠ 0 := fun hb0 => by simp_all have : Multiset.Rel Associated (p ::ₘ factors b) (factors a) := factors_unique - (fun x hx => (Multiset.mem_cons.1 hx).elim (fun h => h.symm ▸ hp) (irreducible_of_factor _)) + (fun _ hx => (Multiset.mem_cons.1 hx).elim (fun h => h.symm ▸ hp) (irreducible_of_factor _)) irreducible_of_factor (Associated.symm <| calc @@ -627,7 +627,7 @@ theorem exists_mem_normalizedFactors_of_dvd {a p : α} (ha0 : a ≠ 0) (hp : Irr have hb0 : b ≠ 0 := fun hb0 => by simp_all have : Multiset.Rel Associated (p ::ₘ normalizedFactors b) (normalizedFactors a) := factors_unique - (fun x hx => + (fun _ hx => (Multiset.mem_cons.1 hx).elim (fun h => h.symm ▸ hp) (irreducible_of_normalized_factor _)) irreducible_of_normalized_factor (Associated.symm <| @@ -1201,7 +1201,7 @@ theorem prod_mono : ∀ {a b : FactorSet α}, a ≤ b → a.prod ≤ b.prod have : b = ⊤ := top_unique h rw [this, prod_top] | a, ⊤, _ => show a.prod ≤ (⊤ : FactorSet α).prod by simp - | WithTop.some a, WithTop.some b, h => + | WithTop.some _, WithTop.some _, h => prod_le_prod <| Multiset.map_le_map <| WithTop.coe_le_coe.1 <| h theorem FactorSet.prod_eq_zero_iff [Nontrivial α] (p : FactorSet α) : p.prod = 0 ↔ p = ⊤ := by diff --git a/Mathlib/RingTheory/Valuation/ValuationSubring.lean b/Mathlib/RingTheory/Valuation/ValuationSubring.lean index a62a8375a1d0ae..48d6df21160fae 100644 --- a/Mathlib/RingTheory/Valuation/ValuationSubring.lean +++ b/Mathlib/RingTheory/Valuation/ValuationSubring.lean @@ -227,7 +227,7 @@ def subtype (R : ValuationSubring K) : R →+* K := /-- The canonical map on value groups induced by a coarsening of valuation rings. -/ def mapOfLE (R S : ValuationSubring K) (h : R ≤ S) : R.ValueGroup →*₀ S.ValueGroup where - toFun := Quotient.map' id fun x y ⟨u, hu⟩ => ⟨Units.map (R.inclusion S h).toMonoidHom u, hu⟩ + toFun := Quotient.map' id fun _ _ ⟨u, hu⟩ => ⟨Units.map (R.inclusion S h).toMonoidHom u, hu⟩ map_zero' := rfl map_one' := rfl map_mul' := by rintro ⟨⟩ ⟨⟩; rfl @@ -349,7 +349,7 @@ def primeSpectrumOrderEquiv : (PrimeSpectrum A)ᵒᵈ ≃o {S // A ≤ S} := instance linearOrderOverring : LinearOrder {S // A ≤ S} := { (inferInstance : PartialOrder _) with le_total := - let i : IsTotal (PrimeSpectrum A) (· ≤ ·) := ⟨fun ⟨x, _⟩ ⟨y, _⟩ => LE.isTotal.total x y⟩ + let _ : IsTotal (PrimeSpectrum A) (· ≤ ·) := ⟨fun ⟨x, _⟩ ⟨y, _⟩ => LE.isTotal.total x y⟩ (primeSpectrumOrderEquiv A).symm.toRelEmbedding.isTotal.total decidableLE := inferInstance } @@ -613,7 +613,7 @@ def principalUnitGroupEquiv : rw [A.coe_mem_principalUnitGroup_iff]; simp⟩ left_inv x := by simp right_inv x := by simp - map_mul' x y := rfl + map_mul' _ _ := rfl theorem principalUnitGroupEquiv_apply (a : A.principalUnitGroup) : (((principalUnitGroupEquiv A a : Aˣ) : A) : K) = (a : Kˣ) := diff --git a/Mathlib/RingTheory/WittVector/IsPoly.lean b/Mathlib/RingTheory/WittVector/IsPoly.lean index 2e6c8619172e2d..da0cac3cda9426 100644 --- a/Mathlib/RingTheory/WittVector/IsPoly.lean +++ b/Mathlib/RingTheory/WittVector/IsPoly.lean @@ -220,7 +220,7 @@ variable {p} /-- The composition of polynomial functions is polynomial. -/ -- Porting note (#10754): made this an instance instance IsPoly₂.comp {h f g} [hh : IsPoly₂ p h] [hf : IsPoly p f] [hg : IsPoly p g] : - IsPoly₂ p fun R _Rcr x y => h (f x) (g y) := by + IsPoly₂ p fun _ _Rcr x y => h (f x) (g y) := by obtain ⟨φ, hf⟩ := hf obtain ⟨ψ, hg⟩ := hg obtain ⟨χ, hh⟩ := hh @@ -238,7 +238,7 @@ instance IsPoly₂.comp {h f g} [hh : IsPoly₂ p h] [hf : IsPoly p f] [hg : IsP /-- The composition of a polynomial function with a binary polynomial function is polynomial. -/ -- Porting note (#10754): made this an instance instance IsPoly.comp₂ {g f} [hg : IsPoly p g] [hf : IsPoly₂ p f] : - IsPoly₂ p fun R _Rcr x y => g (f x y) := by + IsPoly₂ p fun _ _Rcr x y => g (f x y) := by obtain ⟨φ, hf⟩ := hf obtain ⟨ψ, hg⟩ := hg use fun n => bind₁ φ (ψ n) @@ -247,7 +247,7 @@ instance IsPoly.comp₂ {g f} [hg : IsPoly p g] [hf : IsPoly₂ p f] : /-- The diagonal `fun x ↦ f x x` of a polynomial function `f` is polynomial. -/ -- Porting note (#10754): made this an instance -instance IsPoly₂.diag {f} [hf : IsPoly₂ p f] : IsPoly p fun R _Rcr x => f x x := by +instance IsPoly₂.diag {f} [hf : IsPoly₂ p f] : IsPoly p fun _ _Rcr x => f x x := by obtain ⟨φ, hf⟩ := hf refine ⟨⟨fun n => bind₁ (uncurry ![X, X]) (φ n), ?_⟩⟩ intros; funext n diff --git a/Mathlib/RingTheory/WittVector/MulP.lean b/Mathlib/RingTheory/WittVector/MulP.lean index 6cdf37a89f03d6..099970cef0ee62 100644 --- a/Mathlib/RingTheory/WittVector/MulP.lean +++ b/Mathlib/RingTheory/WittVector/MulP.lean @@ -59,7 +59,7 @@ variable (p) /-- Multiplication by `n` is a polynomial function. -/ @[is_poly] -theorem mulN_isPoly (n : ℕ) : IsPoly p fun R _Rcr x => x * n := +theorem mulN_isPoly (n : ℕ) : IsPoly p fun _ _Rcr x => x * n := ⟨⟨wittMulN p n, fun R _Rcr x => by funext k; exact mulN_coeff n x k⟩⟩ @[simp] diff --git a/Mathlib/RingTheory/WittVector/Truncated.lean b/Mathlib/RingTheory/WittVector/Truncated.lean index ad0dab556c7aed..4fa06dc3e127b6 100644 --- a/Mathlib/RingTheory/WittVector/Truncated.lean +++ b/Mathlib/RingTheory/WittVector/Truncated.lean @@ -482,7 +482,7 @@ def liftEquiv : { f : ∀ k, S →+* TruncatedWittVector p k R // ∀ (k₁ k₂ intro _ _ h simp only [← RingHom.comp_assoc, truncate_comp_wittVector_truncate]⟩ left_inv := by rintro ⟨f, hf⟩; simp only [truncate_comp_lift] - right_inv g := lift_unique _ _ fun _ => rfl + right_inv _ := lift_unique _ _ fun _ => rfl theorem hom_ext (g₁ g₂ : S →+* 𝕎 R) (h : ∀ k, (truncate k).comp g₁ = (truncate k).comp g₂) : g₁ = g₂ := diff --git a/Mathlib/SetTheory/Cardinal/Basic.lean b/Mathlib/SetTheory/Cardinal/Basic.lean index e6a0f29565545d..cf4dfeb391b9ee 100644 --- a/Mathlib/SetTheory/Cardinal/Basic.lean +++ b/Mathlib/SetTheory/Cardinal/Basic.lean @@ -520,8 +520,8 @@ instance commSemiring : CommSemiring Cardinal.{u} where add_zero a := inductionOn a fun α => mk_congr <| Equiv.sumEmpty α _ add_assoc a b c := inductionOn₃ a b c fun α β γ => mk_congr <| Equiv.sumAssoc α β γ add_comm a b := inductionOn₂ a b fun α β => mk_congr <| Equiv.sumComm α β - zero_mul a := inductionOn a fun α => mk_eq_zero _ - mul_zero a := inductionOn a fun α => mk_eq_zero _ + zero_mul a := inductionOn a fun _ => mk_eq_zero _ + mul_zero a := inductionOn a fun _ => mk_eq_zero _ one_mul a := inductionOn a fun α => mk_congr <| Equiv.uniqueProd α _ mul_one a := inductionOn a fun α => mk_congr <| Equiv.prodUnique α _ mul_assoc a b c := inductionOn₃ a b c fun α β γ => mk_congr <| Equiv.prodAssoc α β γ @@ -623,7 +623,7 @@ instance canonicallyOrderedCommSemiring : CanonicallyOrderedCommSemiring Cardina Cardinal.partialOrder with bot := 0 bot_le := Cardinal.zero_le - add_le_add_left := fun a b => add_le_add_left + add_le_add_left := fun _ _ => add_le_add_left exists_add_of_le := fun {a b} => inductionOn₂ a b fun α β ⟨⟨f, hf⟩⟩ => have : α ⊕ ((range f)ᶜ : Set β) ≃ β := by @@ -631,7 +631,7 @@ instance canonicallyOrderedCommSemiring : CanonicallyOrderedCommSemiring Cardina exact (Equiv.sumCongr (Equiv.ofInjective f hf) (Equiv.refl _)).trans <| Equiv.Set.sumCompl (range f) ⟨#(↥(range f)ᶜ), mk_congr this.symm⟩ - le_self_add := fun a b => (add_zero a).ge.trans <| add_le_add_left (Cardinal.zero_le _) _ + le_self_add := fun a _ => (add_zero a).ge.trans <| add_le_add_left (Cardinal.zero_le _) _ eq_zero_or_eq_zero_of_mul_eq_zero := fun {a b} => inductionOn₂ a b fun α β => by simpa only [mul_def, mk_eq_zero_iff, isEmpty_prod] using id } @@ -998,7 +998,7 @@ instance small_Ioo (a b : Cardinal.{u}) : Small.{u} (Ioo a b) := small_subset Io /-- A set of cardinals is bounded above iff it's small, i.e. it corresponds to a usual ZFC set. -/ theorem bddAbove_iff_small {s : Set Cardinal.{u}} : BddAbove s ↔ Small.{u} s := - ⟨fun ⟨a, ha⟩ => @small_subset _ (Iic a) s (fun x h => ha h) _, by + ⟨fun ⟨a, ha⟩ => @small_subset _ (Iic a) s (fun _ h => ha h) _, by rintro ⟨ι, ⟨e⟩⟩ suffices (range fun x : ι => (e.symm x).1) = s by rw [← this] @@ -1485,14 +1485,14 @@ theorem lt_aleph0 {c : Cardinal} : c < ℵ₀ ↔ ∃ n : ℕ, c = n := simp contrapose! h' haveI := Infinite.to_subtype h' - exact ⟨Infinite.natEmbedding S⟩, fun ⟨n, e⟩ => e.symm ▸ nat_lt_aleph0 _⟩ + exact ⟨Infinite.natEmbedding S⟩, fun ⟨_, e⟩ => e.symm ▸ nat_lt_aleph0 _⟩ lemma succ_eq_of_lt_aleph0 {c : Cardinal} (h : c < ℵ₀) : Order.succ c = c + 1 := by obtain ⟨n, hn⟩ := Cardinal.lt_aleph0.mp h rw [hn, succ_natCast] theorem aleph0_le {c : Cardinal} : ℵ₀ ≤ c ↔ ∀ n : ℕ, ↑n ≤ c := - ⟨fun h n => (nat_lt_aleph0 _).le.trans h, fun h => + ⟨fun h _ => (nat_lt_aleph0 _).le.trans h, fun h => le_of_not_lt fun hn => by rcases lt_aleph0.1 hn with ⟨n, rfl⟩ exact (Nat.lt_succ_self _).not_le (natCast_le.1 (h (n + 1)))⟩ diff --git a/Mathlib/SetTheory/Cardinal/Cofinality.lean b/Mathlib/SetTheory/Cardinal/Cofinality.lean index ded9fbf59464d1..5f1d484af9be79 100644 --- a/Mathlib/SetTheory/Cardinal/Cofinality.lean +++ b/Mathlib/SetTheory/Cardinal/Cofinality.lean @@ -381,7 +381,7 @@ theorem nfpFamily_lt_ord {ι} {f : ι → Ordinal → Ordinal} {c} (hc : ℵ₀ theorem nfpBFamily_lt_ord_lift {o : Ordinal} {f : ∀ a < o, Ordinal → Ordinal} {c} (hc : ℵ₀ < cof c) (hc' : Cardinal.lift.{v, u} o.card < cof c) (hf : ∀ (i hi), ∀ b < c, f i hi b < c) {a} : a < c → nfpBFamily.{u, v} o f a < c := - nfpFamily_lt_ord_lift hc (by rwa [mk_toType]) fun i => hf _ _ + nfpFamily_lt_ord_lift hc (by rwa [mk_toType]) fun _ => hf _ _ theorem nfpBFamily_lt_ord {o : Ordinal} {f : ∀ a < o, Ordinal → Ordinal} {c} (hc : ℵ₀ < cof c) (hc' : o.card < cof c) (hf : ∀ (i hi), ∀ b < c, f i hi b < c) {a} : @@ -456,11 +456,11 @@ theorem cof_zero : cof 0 = 0 := by @[simp] theorem cof_eq_zero {o} : cof o = 0 ↔ o = 0 := - ⟨inductionOn o fun α r _ z => - let ⟨S, hl, e⟩ := cof_eq r + ⟨inductionOn o fun _ r _ z => + let ⟨_, hl, e⟩ := cof_eq r type_eq_zero_iff_isEmpty.2 <| ⟨fun a => - let ⟨b, h, _⟩ := hl a + let ⟨_, h, _⟩ := hl a (mk_eq_zero_iff.1 (e.trans z)).elim' ⟨_, h⟩⟩, fun e => by simp [e]⟩ @@ -541,7 +541,7 @@ theorem id_of_le_cof (h : o ≤ o.cof.ord) : IsFundamentalSequence o o fun a _ = ⟨h, @fun _ _ _ _ => id, blsub_id o⟩ protected theorem zero {f : ∀ b < (0 : Ordinal), Ordinal} : IsFundamentalSequence 0 0 f := - ⟨by rw [cof_zero, ord_zero], @fun i j hi => (Ordinal.not_lt_zero i hi).elim, blsub_zero f⟩ + ⟨by rw [cof_zero, ord_zero], @fun i _ hi => (Ordinal.not_lt_zero i hi).elim, blsub_zero f⟩ protected theorem succ : IsFundamentalSequence (succ o) 1 fun _ _ => o := by refine ⟨?_, @fun i j hi hj h => ?_, blsub_const Ordinal.one_ne_zero o⟩ @@ -1091,7 +1091,7 @@ theorem nfpBFamily_lt_ord_lift_of_isRegular {o : Ordinal} {f : ∀ a < o, Ordina (hc : IsRegular c) (ho : Cardinal.lift.{v, u} o.card < c) (hc' : c ≠ ℵ₀) (hf : ∀ (i hi), ∀ b < c.ord, f i hi b < c.ord) {a} : a < c.ord → nfpBFamily.{u, v} o f a < c.ord := - nfpFamily_lt_ord_lift_of_isRegular hc (by rwa [mk_toType]) hc' fun i => hf _ _ + nfpFamily_lt_ord_lift_of_isRegular hc (by rwa [mk_toType]) hc' fun _ => hf _ _ theorem nfpBFamily_lt_ord_of_isRegular {o : Ordinal} {f : ∀ a < o, Ordinal → Ordinal} {c} (hc : IsRegular c) (ho : o.card < c) (hc' : c ≠ ℵ₀) @@ -1140,7 +1140,7 @@ theorem derivBFamily_lt_ord_lift {o : Ordinal} {f : ∀ a < o, Ordinal → Ordin (hc : IsRegular c) (hι : Cardinal.lift.{v, u} o.card < c) (hc' : c ≠ ℵ₀) (hf : ∀ (i hi), ∀ b < c.ord, f i hi b < c.ord) {a} : a < c.ord → derivBFamily.{u, v} o f a < c.ord := - derivFamily_lt_ord_lift hc (by rwa [mk_toType]) hc' fun i => hf _ _ + derivFamily_lt_ord_lift hc (by rwa [mk_toType]) hc' fun _ => hf _ _ theorem derivBFamily_lt_ord {o : Ordinal} {f : ∀ a < o, Ordinal → Ordinal} {c} (hc : IsRegular c) (hι : o.card < c) (hc' : c ≠ ℵ₀) (hf : ∀ (i hi), ∀ b < c.ord, f i hi b < c.ord) {a} : diff --git a/Mathlib/SetTheory/Game/Basic.lean b/Mathlib/SetTheory/Game/Basic.lean index 8c72765907e523..13900670705bd0 100644 --- a/Mathlib/SetTheory/Game/Basic.lean +++ b/Mathlib/SetTheory/Game/Basic.lean @@ -82,7 +82,7 @@ theorem zero_def : (0 : Game) = ⟦0⟧ := rfl instance instPartialOrderGame : PartialOrder Game where - le := Quotient.lift₂ (· ≤ ·) fun x₁ y₁ x₂ y₂ hx hy => propext (le_congr hx hy) + le := Quotient.lift₂ (· ≤ ·) fun _ _ _ _ hx hy => propext (le_congr hx hy) le_refl := by rintro ⟨x⟩ exact le_refl x @@ -93,7 +93,7 @@ instance instPartialOrderGame : PartialOrder Game where rintro ⟨x⟩ ⟨y⟩ h₁ h₂ apply Quot.sound exact ⟨h₁, h₂⟩ - lt := Quotient.lift₂ (· < ·) fun x₁ y₁ x₂ y₂ hx hy => propext (lt_congr hx hy) + lt := Quotient.lift₂ (· < ·) fun _ _ _ _ hx hy => propext (lt_congr hx hy) lt_iff_le_not_le := by rintro ⟨x⟩ ⟨y⟩ exact @lt_iff_le_not_le _ _ x y diff --git a/Mathlib/SetTheory/Game/PGame.lean b/Mathlib/SetTheory/Game/PGame.lean index 55a01998f3b98c..afa7e0b2209179 100644 --- a/Mathlib/SetTheory/Game/PGame.lean +++ b/Mathlib/SetTheory/Game/PGame.lean @@ -997,7 +997,7 @@ def moveRightSymm : /-- The identity relabelling. -/ @[refl] def refl (x : PGame) : x ≡r x := - ⟨Equiv.refl _, Equiv.refl _, fun i => refl _, fun j => refl _⟩ + ⟨Equiv.refl _, Equiv.refl _, fun _ => refl _, fun _ => refl _⟩ termination_by x instance (x : PGame) : Inhabited (x ≡r x) := diff --git a/Mathlib/SetTheory/Game/State.lean b/Mathlib/SetTheory/Game/State.lean index d7871744adc589..01df81444246be 100644 --- a/Mathlib/SetTheory/Game/State.lean +++ b/Mathlib/SetTheory/Game/State.lean @@ -206,7 +206,7 @@ instance shortOfStateAux : ∀ (n : ℕ) {s : S} (h : turnBound s ≤ n), Short have j := (rightMovesOfStateAux _ _).toFun j exfalso exact turnBound_ne_zero_of_right_move j.2 (nonpos_iff_eq_zero.mp h) - | n + 1, s, h => + | n + 1, _, h => Short.mk' (fun i => shortOfRelabelling (relabellingMoveLeftAux (n + 1) h i).symm (shortOfStateAux n _)) diff --git a/Mathlib/SetTheory/Lists.lean b/Mathlib/SetTheory/Lists.lean index cd2aeac9c77220..46a43296569198 100644 --- a/Mathlib/SetTheory/Lists.lean +++ b/Mathlib/SetTheory/Lists.lean @@ -174,7 +174,7 @@ theorem mem_of_subset' {a} : ∀ {l₁ l₂ : Lists' α true} (_ : l₁ ⊆ l₂ · exact mem_of_subset' s h theorem subset_def {l₁ l₂ : Lists' α true} : l₁ ⊆ l₂ ↔ ∀ a ∈ l₁.toList, a ∈ l₂ := - ⟨fun H a => mem_of_subset' H, fun H => by + ⟨fun H _ => mem_of_subset' H, fun H => by rw [← of_toList l₁] revert H; induction' toList l₁ with h t t_ih <;> intro H · exact Subset.nil @@ -336,7 +336,7 @@ mutual exact decidable_of_iff' _ Equiv.antisymm_iff termination_by x y => sizeOf x + sizeOf y instance Subset.decidable : ∀ l₁ l₂ : Lists' α true, Decidable (l₁ ⊆ l₂) - | Lists'.nil, l₂ => isTrue Lists'.Subset.nil + | Lists'.nil, _ => isTrue Lists'.Subset.nil | @Lists'.cons' _ b a l₁, l₂ => by haveI := have : sizeOf (⟨b, a⟩ : Lists α) < 1 + 1 + sizeOf a + sizeOf l₁ := by simp [sizeof_pos] diff --git a/Mathlib/SetTheory/Ordinal/Arithmetic.lean b/Mathlib/SetTheory/Ordinal/Arithmetic.lean index 967798e7995f7d..85687f4ba62929 100644 --- a/Mathlib/SetTheory/Ordinal/Arithmetic.lean +++ b/Mathlib/SetTheory/Ordinal/Arithmetic.lean @@ -420,7 +420,7 @@ theorem IsNormal.le_iff_eq {f} (H : IsNormal f) {a} : f a ≤ a ↔ f a = a := theorem IsNormal.le_set {f o} (H : 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 := - ⟨fun h a pa => (H.le_iff.2 ((H₂ _).1 le_rfl _ pa)).trans h, fun h => by + ⟨fun h _ pa => (H.le_iff.2 ((H₂ _).1 le_rfl _ pa)).trans h, fun h => by -- Porting note: `refine'` didn't work well so `induction` is used induction b using limitRecOn with | H₁ => @@ -453,7 +453,7 @@ theorem IsNormal.isLimit {f} (H : IsNormal f) {o} (l : IsLimit o) : IsLimit (f o (succ_le_of_lt h₂).trans_lt (H.lt_iff.2 h₁)⟩ theorem add_le_of_limit {a b c : Ordinal} (h : IsLimit b) : a + b ≤ c ↔ ∀ b' < b, a + b' ≤ c := - ⟨fun h b' l => (add_le_add_left l.le _).trans h, fun H => + ⟨fun h _ l => (add_le_add_left l.le _).trans h, fun H => le_of_not_lt <| by -- Porting note: `induction` tactics are required because of the parser bug. induction a using inductionOn with @@ -597,10 +597,9 @@ alias one_add_of_omega_le := one_add_of_omega0_le instance monoid : Monoid Ordinal.{u} where mul a b := Quotient.liftOn₂ a b - (fun ⟨α, r, wo⟩ ⟨β, s, wo'⟩ => ⟦⟨β × α, Prod.Lex s r, inferInstance⟩⟧ : + (fun ⟨α, r, _⟩ ⟨β, s, _⟩ => ⟦⟨β × α, Prod.Lex s r, inferInstance⟩⟧ : WellOrder → WellOrder → Ordinal) - fun ⟨α₁, r₁, o₁⟩ ⟨α₂, r₂, o₂⟩ ⟨β₁, s₁, p₁⟩ ⟨β₂, s₂, p₂⟩ ⟨f⟩ ⟨g⟩ => - Quot.sound ⟨RelIso.prodLexCongr g f⟩ + fun ⟨_, _, _⟩ _ _ _ ⟨f⟩ ⟨g⟩ => Quot.sound ⟨RelIso.prodLexCongr g f⟩ one := 1 mul_assoc a b c := Quotient.inductionOn₃ a b c fun ⟨α, r, _⟩ ⟨β, s, _⟩ ⟨γ, t, _⟩ => @@ -739,7 +738,7 @@ private theorem mul_le_of_limit_aux {α β r s} [IsWellOrder α r] [IsWellOrder Sum.lex_inl_inl] using h theorem mul_le_of_limit {a b c : Ordinal} (h : IsLimit b) : a * b ≤ c ↔ ∀ b' < b, a * b' ≤ c := - ⟨fun h b' l => (mul_le_mul_left' l.le _).trans h, fun H => + ⟨fun h _ l => (mul_le_mul_left' l.le _).trans h, fun H => -- Porting note: `induction` tactics are required because of the parser bug. le_of_not_lt <| by induction a using inductionOn with @@ -754,7 +753,7 @@ theorem isNormal_mul_right {a : Ordinal} (h : 0 < a) : IsNormal (a * ·) := beta_reduce rw [mul_succ] simpa only [add_zero] using (add_lt_add_iff_left (a * b)).2 h, - fun b l c => mul_le_of_limit l⟩ + fun _ l _ => mul_le_of_limit l⟩ @[deprecated isNormal_mul_right (since := "2024-10-11")] alias mul_isNormal := isNormal_mul_right @@ -1475,7 +1474,7 @@ theorem bsup_le_iff {o f a} : bsup.{u, v} o f ≤ a ↔ ∀ i h, f i h ≤ a := sup_le_iff.trans ⟨fun h i hi => by rw [← familyOfBFamily_enum o f] - exact h _, fun h i => h _ _⟩ + exact h _, fun h _ => h _ _⟩ theorem bsup_le {o : Ordinal} {f : ∀ b < o, Ordinal} {a} : (∀ i h, f i h ≤ a) → bsup.{u, v} o f ≤ a := diff --git a/Mathlib/SetTheory/Ordinal/Basic.lean b/Mathlib/SetTheory/Ordinal/Basic.lean index 633dfc776c196d..f6526c9ba0f286 100644 --- a/Mathlib/SetTheory/Ordinal/Basic.lean +++ b/Mathlib/SetTheory/Ordinal/Basic.lean @@ -297,7 +297,7 @@ instance partialOrder : PartialOrder Ordinal where instance linearOrder : LinearOrder Ordinal := {inferInstanceAs (PartialOrder Ordinal) with - le_total := fun a b => Quotient.inductionOn₂ a b fun ⟨α, r, _⟩ ⟨β, s, _⟩ => + le_total := fun a b => Quotient.inductionOn₂ a b fun ⟨_, r, _⟩ ⟨_, s, _⟩ => (InitialSeg.total r s).recOn (fun f => Or.inl ⟨f⟩) fun f => Or.inr ⟨f⟩ decidableLE := Classical.decRel _ } @@ -761,10 +761,10 @@ instance addMonoidWithOne : AddMonoidWithOne Ordinal.{u} where zero := 0 one := 1 zero_add o := - inductionOn o fun α r _ => + inductionOn o fun α _ _ => Eq.symm <| Quotient.sound ⟨⟨(emptySum PEmpty α).symm, Sum.lex_inr_inr⟩⟩ add_zero o := - inductionOn o fun α r _ => + inductionOn o fun α _ _ => Eq.symm <| Quotient.sound ⟨⟨(sumEmpty α PEmpty).symm, Sum.lex_inl_inl⟩⟩ add_assoc o₁ o₂ o₃ := Quotient.inductionOn₃ o₁ o₂ o₃ fun ⟨α, r, _⟩ ⟨β, s, _⟩ ⟨γ, t, _⟩ => @@ -967,8 +967,8 @@ noncomputable def enumIsoToType (o : Ordinal) : Set.Iio o ≃o o.toType where rw [type_lt] exact x.2⟩ invFun x := ⟨typein (α := o.toType) (· < ·) x, typein_lt_self x⟩ - left_inv := fun ⟨o', h⟩ => Subtype.ext_val (typein_enum _ _) - right_inv h := enum_typein _ _ + left_inv := fun ⟨_, _⟩ => Subtype.ext_val (typein_enum _ _) + right_inv _ := enum_typein _ _ map_rel_iff' := by rintro ⟨a, _⟩ ⟨b, _⟩ apply enum_le_enum' @@ -997,7 +997,7 @@ noncomputable alias outOrderBotOfPos := toTypeOrderBotOfPos theorem enum_zero_eq_bot {o : Ordinal} (ho : 0 < o) : enum (α := o.toType) (· < ·) ⟨0, by rwa [type_lt]⟩ = - have H := toTypeOrderBotOfPos ho + have _ := toTypeOrderBotOfPos ho (⊥ : o.toType) := rfl @@ -1314,14 +1314,14 @@ theorem lt_univ {c} : c < univ.{u, u + 1} ↔ ∃ c', c = lift.{u + 1, u} c' := cases' liftPrincipalSeg.mem_range_of_rel_top (by simpa only [liftPrincipalSeg_top]) with o e have := card_ord c rw [← e, liftPrincipalSeg_coe, ← lift_card] at this - exact ⟨_, this.symm⟩, fun ⟨c', e⟩ => e.symm ▸ lift_lt_univ _⟩ + exact ⟨_, this.symm⟩, fun ⟨_, e⟩ => e.symm ▸ lift_lt_univ _⟩ theorem lt_univ' {c} : c < univ.{u, v} ↔ ∃ c', c = lift.{max (u + 1) v, u} c' := ⟨fun h => by let ⟨a, h', e⟩ := lt_lift_iff.1 h rw [← univ_id] at h' rcases lt_univ.{u}.1 h' with ⟨c', rfl⟩ - exact ⟨c', by simp only [e.symm, lift_lift]⟩, fun ⟨c', e⟩ => e.symm ▸ lift_lt_univ' _⟩ + exact ⟨c', by simp only [e.symm, lift_lift]⟩, fun ⟨_, e⟩ => e.symm ▸ lift_lt_univ' _⟩ theorem small_iff_lift_mk_lt_univ {α : Type u} : Small.{v} α ↔ Cardinal.lift.{v+1,_} #α < univ.{v, max u (v + 1)} := by diff --git a/Mathlib/SetTheory/Ordinal/Exponential.lean b/Mathlib/SetTheory/Ordinal/Exponential.lean index 6fb276eb864d63..cfc85d758a4995 100644 --- a/Mathlib/SetTheory/Ordinal/Exponential.lean +++ b/Mathlib/SetTheory/Ordinal/Exponential.lean @@ -103,7 +103,7 @@ theorem opow_natCast (a : Ordinal) (n : ℕ) : a ^ (n : Ordinal) = a ^ n := by theorem isNormal_opow {a : Ordinal} (h : 1 < a) : IsNormal (a ^ ·) := have a0 : 0 < a := zero_lt_one.trans h ⟨fun b => by simpa only [mul_one, opow_succ] using (mul_lt_mul_iff_left (opow_pos b a0)).2 h, - fun b l c => opow_le_of_limit (ne_of_gt a0) l⟩ + fun _ l _ => opow_le_of_limit (ne_of_gt a0) l⟩ @[deprecated isNormal_opow (since := "2024-10-11")] alias opow_isNormal := isNormal_opow diff --git a/Mathlib/SetTheory/Ordinal/FixedPoint.lean b/Mathlib/SetTheory/Ordinal/FixedPoint.lean index 40cae6c0b82996..4af5b1ee190ea9 100644 --- a/Mathlib/SetTheory/Ordinal/FixedPoint.lean +++ b/Mathlib/SetTheory/Ordinal/FixedPoint.lean @@ -208,7 +208,7 @@ theorem le_iff_derivFamily (H : ∀ i, IsNormal (f i)) {a} : exact let ⟨o', h, hl⟩ := h IH o' h (le_of_not_le hl), - fun ⟨o, e⟩ i => e ▸ (derivFamily_fp (H i) _).le⟩ + fun ⟨_, e⟩ i => e ▸ (derivFamily_fp (H i) _).le⟩ theorem fp_iff_derivFamily (H : ∀ i, IsNormal (f i)) {a} : (∀ i, f i a = a) ↔ ∃ o, derivFamily.{u, v} f o = a := diff --git a/Mathlib/SetTheory/Ordinal/NaturalOps.lean b/Mathlib/SetTheory/Ordinal/NaturalOps.lean index 3c72aeb23d13a9..3de7f421c950a6 100644 --- a/Mathlib/SetTheory/Ordinal/NaturalOps.lean +++ b/Mathlib/SetTheory/Ordinal/NaturalOps.lean @@ -335,8 +335,8 @@ instance orderedCancelAddCommMonoid : OrderedCancelAddCommMonoid NatOrdinal := { NatOrdinal.linearOrder with add := (· + ·) add_assoc := nadd_assoc - add_le_add_left := fun a b => add_le_add_left - le_of_add_le_add_left := fun a b c => le_of_add_le_add_left + add_le_add_left := fun _ _ => add_le_add_left + le_of_add_le_add_left := fun _ _ _ => le_of_add_le_add_left zero := 0 zero_add := zero_nadd add_zero := nadd_zero @@ -688,8 +688,8 @@ instance : OrderedCommSemiring NatOrdinal.{u} := mul_one := nmul_one mul_comm := nmul_comm zero_le_one := @zero_le_one Ordinal _ _ _ _ - mul_le_mul_of_nonneg_left := fun a b c h _ => nmul_le_nmul_left h c - mul_le_mul_of_nonneg_right := fun a b c h _ => nmul_le_nmul_right h c } + mul_le_mul_of_nonneg_left := fun _ _ c h _ => nmul_le_nmul_left h c + mul_le_mul_of_nonneg_right := fun _ _ c h _ => nmul_le_nmul_right h c } namespace Ordinal diff --git a/Mathlib/SetTheory/Ordinal/Notation.lean b/Mathlib/SetTheory/Ordinal/Notation.lean index 0d443138f41f48..c9d5e0211b86c3 100644 --- a/Mathlib/SetTheory/Ordinal/Notation.lean +++ b/Mathlib/SetTheory/Ordinal/Notation.lean @@ -284,8 +284,8 @@ theorem oadd_lt_oadd_3 {e n a₁ a₂} (h : a₁ < a₂) : oadd e n a₁ < oadd theorem cmp_compares : ∀ (a b : ONote) [NF a] [NF b], (cmp a b).Compares a b | 0, 0, _, _ => rfl - | oadd e n a, 0, _, _ => oadd_pos _ _ _ - | 0, oadd e n a, _, _ => oadd_pos _ _ _ + | oadd _ _ _, 0, _, _ => oadd_pos _ _ _ + | 0, oadd _ _ _, _, _ => oadd_pos _ _ _ | o₁@(oadd e₁ n₁ a₁), o₂@(oadd e₂ n₂ a₂), h₁, h₂ => by -- TODO: golf rw [cmp] have IHe := @cmp_compares _ _ h₁.fst h₂.fst @@ -481,7 +481,7 @@ instance sub_nf (o₁ o₂) : ∀ [NF o₁] [NF o₂], NF (o₁ - o₂) @[simp] theorem repr_sub : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ - o₂) = repr o₁ - repr o₂ | 0, o, _, h₂ => by cases o <;> exact (Ordinal.zero_sub _).symm - | oadd e n a, 0, _, _ => (Ordinal.sub_zero _).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₂ conv_lhs at h' => dsimp [HSub.hSub, Sub.sub, sub] @@ -537,7 +537,7 @@ theorem oadd_mul (e₁ n₁ a₁ e₂ n₂ a₂) : theorem oadd_mul_nfBelow {e₁ n₁ a₁ b₁} (h₁ : NFBelow (oadd e₁ n₁ a₁) b₁) : ∀ {o₂ b₂}, NFBelow o₂ b₂ → NFBelow (oadd e₁ n₁ a₁ * o₂) (repr e₁ + b₂) - | 0, b₂, _ => NFBelow.zero + | 0, _, _ => NFBelow.zero | oadd e₂ n₂ a₂, b₂, h₂ => by have IH := oadd_mul_nfBelow h₁ h₂.snd by_cases e0 : e₂ = 0 <;> simp only [e0, oadd_mul, ↓reduceIte] @@ -553,12 +553,12 @@ theorem oadd_mul_nfBelow {e₁ n₁ a₁ b₁} (h₁ : NFBelow (oadd e₁ n₁ a instance mul_nf : ∀ (o₁ o₂) [NF o₁] [NF o₂], NF (o₁ * o₂) | 0, o, _, h₂ => by cases o <;> exact NF.zero - | oadd e n a, o, ⟨⟨b₁, hb₁⟩⟩, ⟨⟨b₂, hb₂⟩⟩ => ⟨⟨_, oadd_mul_nfBelow hb₁ hb₂⟩⟩ + | oadd _ _ _, _, ⟨⟨_, hb₁⟩⟩, ⟨⟨_, hb₂⟩⟩ => ⟨⟨_, oadd_mul_nfBelow hb₁ hb₂⟩⟩ @[simp] theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = repr o₁ * repr o₂ | 0, o, _, h₂ => by cases o <;> exact (zero_mul _).symm - | oadd e₁ n₁ a₁, 0, _, _ => (mul_zero _).symm + | oadd _ _ _, 0, _, _ => (mul_zero _).symm | oadd e₁ n₁ a₁, oadd e₂ n₂ a₂, h₁, h₂ => by have IH : repr (mul _ _) = _ := @repr_mul _ _ h₁ h₂.snd conv => diff --git a/Mathlib/SetTheory/Ordinal/Principal.lean b/Mathlib/SetTheory/Ordinal/Principal.lean index 1f7d12231c7428..c20573c3505921 100644 --- a/Mathlib/SetTheory/Ordinal/Principal.lean +++ b/Mathlib/SetTheory/Ordinal/Principal.lean @@ -158,7 +158,7 @@ theorem exists_lt_add_of_not_principal_add {a} (ha : ¬Principal (· + ·) a) : theorem principal_add_iff_add_lt_ne_self {a} : Principal (· + ·) a ↔ ∀ b < a, ∀ c < a, b + c ≠ a := - ⟨fun ha b hb c hc => (ha hb hc).ne, fun H => by + ⟨fun ha _ hb _ hc => (ha hb hc).ne, fun H => by by_contra! ha rcases exists_lt_add_of_not_principal_add ha with ⟨b, hb, c, hc, rfl⟩ exact (H b hb c hc).irrefl⟩ diff --git a/Mathlib/SetTheory/ZFC/Basic.lean b/Mathlib/SetTheory/ZFC/Basic.lean index bc21fd9e20d726..bbfd6ee8f1eac5 100644 --- a/Mathlib/SetTheory/ZFC/Basic.lean +++ b/Mathlib/SetTheory/ZFC/Basic.lean @@ -1564,7 +1564,7 @@ private lemma toSet_equiv_aux {s : Set ZFSet.{u}} (hs : Small.{u} s) : @[simps apply_coe] noncomputable def toSet_equiv : ZFSet.{u} ≃ {s : Set ZFSet.{u} // Small.{u, u+1} s} where toFun x := ⟨x.toSet, x.small_toSet⟩ - invFun := fun ⟨s, h⟩ ↦ mk <| PSet.mk (Shrink s) fun x ↦ ((equivShrink.{u, u+1} s).symm x).1.out + invFun := fun ⟨s, _⟩ ↦ mk <| PSet.mk (Shrink s) fun x ↦ ((equivShrink.{u, u+1} s).symm x).1.out left_inv := Function.rightInverse_of_injective_of_leftInverse (by intros x y; simp) fun s ↦ Subtype.coe_injective <| toSet_equiv_aux s.2 right_inv s := Subtype.coe_injective <| toSet_equiv_aux s.2 diff --git a/Mathlib/SetTheory/ZFC/Ordinal.lean b/Mathlib/SetTheory/ZFC/Ordinal.lean index fc7b53d80cedda..56dbcfb274d7a0 100644 --- a/Mathlib/SetTheory/ZFC/Ordinal.lean +++ b/Mathlib/SetTheory/ZFC/Ordinal.lean @@ -80,7 +80,7 @@ protected theorem IsTransitive.powerset (h : x.IsTransitive) : (powerset x).IsTr theorem isTransitive_iff_sUnion_subset : x.IsTransitive ↔ (⋃₀ x : ZFSet) ⊆ x := ⟨fun h y hy => by rcases mem_sUnion.1 hy with ⟨z, hz, hz'⟩ - exact h.mem_trans hz' hz, fun H y hy z hz => H <| mem_sUnion_of_mem hz hy⟩ + exact h.mem_trans hz' hz, fun H _ hy _ hz => H <| mem_sUnion_of_mem hz hy⟩ alias ⟨IsTransitive.sUnion_subset, _⟩ := isTransitive_iff_sUnion_subset diff --git a/Mathlib/Tactic/NormNum/Basic.lean b/Mathlib/Tactic/NormNum/Basic.lean index f2921c511d2d30..f22cd76b3016bc 100644 --- a/Mathlib/Tactic/NormNum/Basic.lean +++ b/Mathlib/Tactic/NormNum/Basic.lean @@ -25,6 +25,14 @@ See other files in this directory for many more plugins. universe u +#adaptation_note +/-- +Since https://github.com/leanprover/lean4/pull/5338, +the unused variable linter can not see usages of variables in +`haveI' : ⋯ =Q ⋯ := ⟨⟩` clauses, so generates many false positives. +-/ +set_option linter.unusedVariables false + namespace Mathlib open Lean hiding Rat mkRat open Meta diff --git a/Mathlib/Tactic/NormNum/DivMod.lean b/Mathlib/Tactic/NormNum/DivMod.lean index 821532050c5495..2ad7e4703023d2 100644 --- a/Mathlib/Tactic/NormNum/DivMod.lean +++ b/Mathlib/Tactic/NormNum/DivMod.lean @@ -13,6 +13,14 @@ This file adds support for the `%`, `/`, and `∣` (divisibility) operators on ` to the `norm_num` tactic. -/ +#adaptation_note +/-- +Since https://github.com/leanprover/lean4/pull/5338, +the unused variable linter can not see usages of variables in +`haveI' : ⋯ =Q ⋯ := ⟨⟩` clauses, so generates many false positives. +-/ +set_option linter.unusedVariables false + namespace Mathlib open Lean hiding Rat mkRat open Meta diff --git a/Mathlib/Tactic/NormNum/Eq.lean b/Mathlib/Tactic/NormNum/Eq.lean index 3c0cdec603d270..a97a3fd671669d 100644 --- a/Mathlib/Tactic/NormNum/Eq.lean +++ b/Mathlib/Tactic/NormNum/Eq.lean @@ -11,6 +11,14 @@ import Mathlib.Tactic.NormNum.Inv variable {α : Type*} +#adaptation_note +/-- +Since https://github.com/leanprover/lean4/pull/5338, +the unused variable linter can not see usages of variables in +`haveI' : ⋯ =Q ⋯ := ⟨⟩` clauses, so generates many false positives. +-/ +set_option linter.unusedVariables false + open Lean Meta Qq namespace Mathlib.Meta.NormNum diff --git a/Mathlib/Tactic/NormNum/GCD.lean b/Mathlib/Tactic/NormNum/GCD.lean index 55f86434e67e54..1e3b522bdd15a0 100644 --- a/Mathlib/Tactic/NormNum/GCD.lean +++ b/Mathlib/Tactic/NormNum/GCD.lean @@ -15,6 +15,14 @@ Note that `Nat.coprime` is reducible and defined in terms of `Nat.gcd`, so the ` also indirectly provides a `Nat.coprime` extension. -/ +#adaptation_note +/-- +Since https://github.com/leanprover/lean4/pull/5338, +the unused variable linter can not see usages of variables in +`haveI' : ⋯ =Q ⋯ := ⟨⟩` clauses, so generates many false positives. +-/ +set_option linter.unusedVariables false + namespace Tactic namespace NormNum diff --git a/Mathlib/Tactic/NormNum/Ineq.lean b/Mathlib/Tactic/NormNum/Ineq.lean index 9c5a20797bcc25..b19927601b352b 100644 --- a/Mathlib/Tactic/NormNum/Ineq.lean +++ b/Mathlib/Tactic/NormNum/Ineq.lean @@ -13,6 +13,14 @@ import Mathlib.Algebra.Order.Ring.Cast # `norm_num` extensions for inequalities. -/ +#adaptation_note +/-- +Since https://github.com/leanprover/lean4/pull/5338, +the unused variable linter can not see usages of variables in +`haveI' : ⋯ =Q ⋯ := ⟨⟩` clauses, so generates many false positives. +-/ +set_option linter.unusedVariables false + open Lean Meta Qq namespace Mathlib.Meta.NormNum diff --git a/Mathlib/Tactic/NormNum/Inv.lean b/Mathlib/Tactic/NormNum/Inv.lean index 5b30fb59f8e8ba..b153337b226958 100644 --- a/Mathlib/Tactic/NormNum/Inv.lean +++ b/Mathlib/Tactic/NormNum/Inv.lean @@ -13,6 +13,14 @@ import Mathlib.Algebra.Field.Basic variable {u : Lean.Level} +#adaptation_note +/-- +Since https://github.com/leanprover/lean4/pull/5338, +the unused variable linter can not see usages of variables in +`haveI' : ⋯ =Q ⋯ := ⟨⟩` clauses, so generates many false positives. +-/ +set_option linter.unusedVariables false + namespace Mathlib.Meta.NormNum open Lean.Meta Qq diff --git a/Mathlib/Tactic/NormNum/IsCoprime.lean b/Mathlib/Tactic/NormNum/IsCoprime.lean index 1b69efa7dc001e..abb193758c7a47 100644 --- a/Mathlib/Tactic/NormNum/IsCoprime.lean +++ b/Mathlib/Tactic/NormNum/IsCoprime.lean @@ -46,7 +46,7 @@ def proveIntIsCoprime (ex ey : Q(ℤ)) : Q(IsCoprime $ex $ey) ⊕ Q(¬ IsCoprime /-- Evaluates the `IsCoprime` predicate over `ℤ`. -/ @[norm_num IsCoprime (_ : ℤ) (_ : ℤ)] -def evalIntIsCoprime : NormNumExt where eval {u α} e := do +def evalIntIsCoprime : NormNumExt where eval {_ _} e := do let .app (.app _ (x : Q(ℤ))) (y : Q(ℤ)) ← Meta.whnfR e | failure let ⟨ex, p⟩ ← deriveInt x _ let ⟨ey, q⟩ ← deriveInt y _ diff --git a/Mathlib/Tactic/NormNum/LegendreSymbol.lean b/Mathlib/Tactic/NormNum/LegendreSymbol.lean index dfb3def6ba7c4e..166fc060cfcdca 100644 --- a/Mathlib/Tactic/NormNum/LegendreSymbol.lean +++ b/Mathlib/Tactic/NormNum/LegendreSymbol.lean @@ -356,6 +356,14 @@ namespace NormNum open Lean Elab Tactic Qq Mathlib.Meta.NormNum +#adaptation_note +/-- +Since https://github.com/leanprover/lean4/pull/5338, +the unused variable linter can not see usages of variables in +`haveI' : ⋯ =Q ⋯ := ⟨⟩` clauses, so generates many false positives. +-/ +set_option linter.unusedVariables false + /-- This is the `norm_num` plug-in that evaluates Jacobi symbols. -/ @[norm_num jacobiSym _ _] def evalJacobiSym : NormNumExt where eval {u α} e := do diff --git a/Mathlib/Tactic/NormNum/NatFib.lean b/Mathlib/Tactic/NormNum/NatFib.lean index c1d41a19439751..4ac286c3557e7a 100644 --- a/Mathlib/Tactic/NormNum/NatFib.lean +++ b/Mathlib/Tactic/NormNum/NatFib.lean @@ -103,7 +103,7 @@ theorem isNat_fib : {x nx z : ℕ} → IsNat x nx → Nat.fib nx = z → IsNat ( /-- Evaluates the `Nat.fib` function. -/ @[norm_num Nat.fib _] -def evalNatFib : NormNumExt where eval {u α} e := do +def evalNatFib : NormNumExt where eval {_ _} e := do let .app _ (x : Q(ℕ)) ← Meta.whnfR e | failure let sℕ : Q(AddMonoidWithOne ℕ) := q(instAddMonoidWithOneNat) let ⟨ex, p⟩ ← deriveNat x sℕ diff --git a/Mathlib/Tactic/NormNum/NatSqrt.lean b/Mathlib/Tactic/NormNum/NatSqrt.lean index bcdc436d884958..bda1f991d15c4f 100644 --- a/Mathlib/Tactic/NormNum/NatSqrt.lean +++ b/Mathlib/Tactic/NormNum/NatSqrt.lean @@ -42,7 +42,7 @@ def proveNatSqrt (ex : Q(ℕ)) : (ey : Q(ℕ)) × Q(Nat.sqrt $ex = $ey) := /-- Evaluates the `Nat.sqrt` function. -/ @[norm_num Nat.sqrt _] -def evalNatSqrt : NormNumExt where eval {u α} e := do +def evalNatSqrt : NormNumExt where eval {_ _} e := do let .app _ (x : Q(ℕ)) ← Meta.whnfR e | failure let sℕ : Q(AddMonoidWithOne ℕ) := q(instAddMonoidWithOneNat) let ⟨ex, p⟩ ← deriveNat x sℕ diff --git a/Mathlib/Tactic/NormNum/Pow.lean b/Mathlib/Tactic/NormNum/Pow.lean index 0744f331ef6921..6f238a046d0577 100644 --- a/Mathlib/Tactic/NormNum/Pow.lean +++ b/Mathlib/Tactic/NormNum/Pow.lean @@ -10,6 +10,14 @@ import Mathlib.Tactic.NormNum.Basic ## `norm_num` plugin for `^`. -/ +#adaptation_note +/-- +Since https://github.com/leanprover/lean4/pull/5338, +the unused variable linter can not see usages of variables in +`haveI' : ⋯ =Q ⋯ := ⟨⟩` clauses, so generates many false positives. +-/ +set_option linter.unusedVariables false + namespace Mathlib open Lean hiding Rat mkRat open Meta diff --git a/Mathlib/Tactic/NormNum/Prime.lean b/Mathlib/Tactic/NormNum/Prime.lean index 4f9a95a5d7158e..f1e5dc961f2b41 100644 --- a/Mathlib/Tactic/NormNum/Prime.lean +++ b/Mathlib/Tactic/NormNum/Prime.lean @@ -118,7 +118,7 @@ theorem isNat_minFac_4 : {n n' k : ℕ} → /-- The `norm_num` extension which identifies expressions of the form `minFac n`. -/ @[norm_num Nat.minFac _] partial def evalMinFac : - NormNumExt where eval {u α} e := do + NormNumExt where eval {_ _} e := do let .app (.const ``Nat.minFac _) (n : Q(ℕ)) ← whnfR e | failure let sℕ : Q(AddMonoidWithOne ℕ) := q(instAddMonoidWithOneNat) let ⟨nn, pn⟩ ← deriveNat n sℕ @@ -175,7 +175,7 @@ theorem isNat_prime_2 : {n n' : ℕ} → theorem isNat_not_prime {n n' : ℕ} (h : IsNat n n') : ¬n'.Prime → ¬n.Prime := isNat.natElim h /-- The `norm_num` extension which identifies expressions of the form `Nat.Prime n`. -/ -@[norm_num Nat.Prime _] def evalNatPrime : NormNumExt where eval {u α} e := do +@[norm_num Nat.Prime _] def evalNatPrime : NormNumExt where eval {_ _} e := do let .app (.const `Nat.Prime _) (n : Q(ℕ)) ← whnfR e | failure let ⟨nn, pn⟩ ← deriveNat n _ let n' := nn.natLit! diff --git a/Mathlib/Testing/SlimCheck/Functions.lean b/Mathlib/Testing/SlimCheck/Functions.lean index 80acb2790dfaf5..51eadae43cdecb 100644 --- a/Mathlib/Testing/SlimCheck/Functions.lean +++ b/Mathlib/Testing/SlimCheck/Functions.lean @@ -423,7 +423,7 @@ one is a permutation of the other. -/ protected def shrink {α : Type} [DecidableEq α] : InjectiveFunction α → List (InjectiveFunction α) - | ⟨xs, h₀, h₁⟩ => do + | ⟨_, h₀, h₁⟩ => do let ⟨xs', ys', h₀, h₁⟩ ← InjectiveFunction.shrinkPerm ⟨_, _, h₀, h₁⟩ have h₃ : xs'.length ≤ ys'.length := le_of_eq (List.Perm.length_eq h₀) have h₄ : ys'.length ≤ xs'.length := le_of_eq (List.Perm.length_eq h₀.symm) diff --git a/Mathlib/Topology/Algebra/Group/Basic.lean b/Mathlib/Topology/Algebra/Group/Basic.lean index 49c268a901a0cf..6ea401ab9a9493 100644 --- a/Mathlib/Topology/Algebra/Group/Basic.lean +++ b/Mathlib/Topology/Algebra/Group/Basic.lean @@ -1911,7 +1911,7 @@ topologies contained in the intersection of `s` and `t`. -/ instance : CompleteSemilatticeInf (GroupTopology α) := { inferInstanceAs (InfSet (GroupTopology α)), inferInstanceAs (PartialOrder (GroupTopology α)) with - sInf_le := fun S a haS => toTopologicalSpace_le.1 <| sInf_le ⟨a, haS, rfl⟩ + sInf_le := fun _ a haS => toTopologicalSpace_le.1 <| sInf_le ⟨a, haS, rfl⟩ le_sInf := by intro S a hab apply (inferInstanceAs (CompleteLattice (TopologicalSpace α))).le_sInf diff --git a/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean b/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean index bc17c8afdc3222..cf601094c68339 100644 --- a/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean +++ b/Mathlib/Topology/Algebra/InfiniteSum/Basic.lean @@ -572,7 +572,7 @@ theorem tprod_eq_mul_tprod_ite' [DecidableEq β] {f : β → α} (b : β) ∏' x, f x = ∏' x, (ite (x = b) (f x) 1 * update f b 1 x) := tprod_congr fun n ↦ by split_ifs with h <;> simp [update_apply, h] _ = (∏' x, ite (x = b) (f x) 1) * ∏' x, update f b 1 x := - tprod_mul ⟨ite (b = b) (f b) 1, hasProd_single b fun b hb ↦ if_neg hb⟩ hf + tprod_mul ⟨ite (b = b) (f b) 1, hasProd_single b fun _ hb ↦ if_neg hb⟩ hf _ = ite (b = b) (f b) 1 * ∏' x, update f b 1 x := by congr exact tprod_eq_mulSingle b fun b' hb' ↦ if_neg hb' diff --git a/Mathlib/Topology/Algebra/Module/Alternating/Basic.lean b/Mathlib/Topology/Algebra/Module/Alternating/Basic.lean index 1b43517bdbae16..93a4d39bc7ed42 100644 --- a/Mathlib/Topology/Algebra/Module/Alternating/Basic.lean +++ b/Mathlib/Topology/Algebra/Module/Alternating/Basic.lean @@ -590,8 +590,8 @@ variable (R M N N') /-- `ContinuousLinearMap.compContinuousAlternatingMap` as a bundled bilinear map. -/ def _root_.ContinuousLinearMap.compContinuousAlternatingMapₗ : (N →L[R] N') →ₗ[R] (M [⋀^ι]→L[R] N) →ₗ[R] (M [⋀^ι]→L[R] N') := - LinearMap.mk₂ R ContinuousLinearMap.compContinuousAlternatingMap (fun f₁ f₂ g => rfl) - (fun c f g => rfl) (fun f g₁ g₂ => by ext1; apply f.map_add) fun c f g => by ext1; simp + LinearMap.mk₂ R ContinuousLinearMap.compContinuousAlternatingMap (fun _ _ _ => rfl) + (fun _ _ _ => rfl) (fun f g₁ g₂ => by ext1; apply f.map_add) fun c f g => by ext1; simp end Semiring diff --git a/Mathlib/Topology/Algebra/Nonarchimedean/Basic.lean b/Mathlib/Topology/Algebra/Nonarchimedean/Basic.lean index 227a2f3aaef682..56b953c25c2717 100644 --- a/Mathlib/Topology/Algebra/Nonarchimedean/Basic.lean +++ b/Mathlib/Topology/Algebra/Nonarchimedean/Basic.lean @@ -97,7 +97,7 @@ theorem prod_self_subset {U} (hU : U ∈ 𝓝 (1 : G × G)) : /-- The cartesian product of two nonarchimedean groups is nonarchimedean. -/ @[to_additive "The cartesian product of two nonarchimedean groups is nonarchimedean."] instance : NonarchimedeanGroup (G × K) where - is_nonarchimedean U hU := + is_nonarchimedean _ hU := let ⟨V, W, h⟩ := prod_subset hU ⟨V.prod W, ‹_›⟩ diff --git a/Mathlib/Topology/Algebra/Order/LiminfLimsup.lean b/Mathlib/Topology/Algebra/Order/LiminfLimsup.lean index 2514169662c245..72c9ec5be2a80e 100644 --- a/Mathlib/Topology/Algebra/Order/LiminfLimsup.lean +++ b/Mathlib/Topology/Algebra/Order/LiminfLimsup.lean @@ -271,7 +271,7 @@ variable [CompleteLinearOrder α] [TopologicalSpace α] [FirstCountableTopology @[simp] theorem limsup_eq_bot : f.limsup u = ⊥ ↔ u =ᶠ[f] ⊥ := ⟨fun h => - (EventuallyLE.trans eventually_le_limsup <| Eventually.of_forall fun _ => h.le).mono fun x hx => + (EventuallyLE.trans eventually_le_limsup <| Eventually.of_forall fun _ => h.le).mono fun _ hx => le_antisymm hx bot_le, fun h => by rw [limsup_congr h] diff --git a/Mathlib/Topology/Algebra/UniformField.lean b/Mathlib/Topology/Algebra/UniformField.lean index da3fb454151fa4..9542b3674ce5be 100644 --- a/Mathlib/Topology/Algebra/UniformField.lean +++ b/Mathlib/Topology/Algebra/UniformField.lean @@ -150,9 +150,9 @@ instance instField : Field (hat K) where inv_zero := by simp only [Inv.inv, ite_true] -- TODO: use a better defeq nnqsmul := _ - nnqsmul_def := fun q a => rfl + nnqsmul_def := fun _ _ => rfl qsmul := _ - qsmul_def := fun a x => rfl + qsmul_def := fun _ _ => rfl instance : TopologicalDivisionRing (hat K) := { Completion.topologicalRing with diff --git a/Mathlib/Topology/Bases.lean b/Mathlib/Topology/Bases.lean index bc50dd33b1af80..46d7a2dd5d1df1 100644 --- a/Mathlib/Topology/Bases.lean +++ b/Mathlib/Topology/Bases.lean @@ -142,7 +142,7 @@ theorem isTopologicalBasis_of_isOpen_of_nhds {s : Set (Set α)} (h_open : ∀ u IsTopologicalBasis s := .of_hasBasis_nhds <| fun a ↦ (nhds_basis_opens a).to_hasBasis' (by simpa [and_assoc] using h_nhds a) - fun t ⟨hts, hat⟩ ↦ (h_open _ hts).mem_nhds hat + fun _ ⟨hts, hat⟩ ↦ (h_open _ hts).mem_nhds hat /-- A set `s` is in the neighbourhood of `a` iff there is some basis set `t`, which contains `a` and is itself contained in `s`. -/ diff --git a/Mathlib/Topology/Basic.lean b/Mathlib/Topology/Basic.lean index 55a8aa4aec4ec3..1c5fc5ac20a5c9 100644 --- a/Mathlib/Topology/Basic.lean +++ b/Mathlib/Topology/Basic.lean @@ -90,7 +90,7 @@ end protected theorem TopologicalSpace.ext_iff {t t' : TopologicalSpace X} : t = t' ↔ ∀ s, IsOpen[t] s ↔ IsOpen[t'] s := - ⟨fun h s => h ▸ Iff.rfl, fun h => by ext; exact h _⟩ + ⟨fun h _ => h ▸ Iff.rfl, fun h => by ext; exact h _⟩ theorem isOpen_fold {t : TopologicalSpace X} : t.IsOpen s = IsOpen[t] s := rfl @@ -309,7 +309,7 @@ theorem interior_union_isClosed_of_interior_empty (h₁ : IsClosed s) (h₂ : interior t = ∅) : interior (s ∪ t) = interior s := have : interior (s ∪ t) ⊆ s := fun x ⟨u, ⟨(hu₁ : IsOpen u), (hu₂ : u ⊆ s ∪ t)⟩, (hx₁ : x ∈ u)⟩ => by_contradiction fun hx₂ : x ∉ s => - have : u \ s ⊆ t := fun x ⟨h₁, h₂⟩ => Or.resolve_left (hu₂ h₁) h₂ + have : u \ s ⊆ t := fun _ ⟨h₁, h₂⟩ => Or.resolve_left (hu₂ h₁) h₂ have : u \ s ⊆ interior t := by rwa [(IsOpen.sdiff hu₁ h₁).subset_interior_iff] have : u \ s ⊆ ∅ := by rwa [h₂] at this this ⟨hx₁, hx₂⟩ @@ -1062,7 +1062,7 @@ theorem isOpen_iff_nhds : IsOpen s ↔ ∀ x ∈ s, 𝓝 x ≤ 𝓟 s := theorem TopologicalSpace.ext_iff_nhds {X} {t t' : TopologicalSpace X} : t = t' ↔ ∀ x, @nhds _ t x = @nhds _ t' x := - ⟨fun H x ↦ congrFun (congrArg _ H) _, fun H ↦ by ext; simp_rw [@isOpen_iff_nhds _ _ _, H]⟩ + ⟨fun H _ ↦ congrFun (congrArg _ H) _, fun H ↦ by ext; simp_rw [@isOpen_iff_nhds _ _ _, H]⟩ alias ⟨_, TopologicalSpace.ext_nhds⟩ := TopologicalSpace.ext_iff_nhds diff --git a/Mathlib/Topology/Category/Compactum.lean b/Mathlib/Topology/Category/Compactum.lean index 1bb55e129ab03c..d8ccb28743f15d 100644 --- a/Mathlib/Topology/Category/Compactum.lean +++ b/Mathlib/Topology/Category/Compactum.lean @@ -457,7 +457,7 @@ end compactumToCompHaus `compactumToCompHaus`. -/ def compactumToCompHausCompForget : compactumToCompHaus ⋙ CategoryTheory.forget CompHaus ≅ Compactum.forget := - NatIso.ofComponents fun X => eqToIso rfl + NatIso.ofComponents fun _ => eqToIso rfl /- TODO: `forget CompHaus` is monadic, as it is isomorphic to the composition diff --git a/Mathlib/Topology/Category/LightProfinite/Basic.lean b/Mathlib/Topology/Category/LightProfinite/Basic.lean index 56a5871cbcd22f..73dbb2fa55ef62 100644 --- a/Mathlib/Topology/Category/LightProfinite/Basic.lean +++ b/Mathlib/Topology/Category/LightProfinite/Basic.lean @@ -160,7 +160,7 @@ def limitConeIsLimit {J : Type v} [SmallCategory J] [CountableCategory J] lift S := (CompHaus.limitConeIsLimit.{v, u} (F ⋙ lightProfiniteToCompHaus)).lift (lightProfiniteToCompHaus.mapCone S) - uniq S m h := (CompHaus.limitConeIsLimit.{v, u} _).uniq (lightProfiniteToCompHaus.mapCone S) _ h + uniq S _ h := (CompHaus.limitConeIsLimit.{v, u} _).uniq (lightProfiniteToCompHaus.mapCone S) _ h noncomputable instance createsCountableLimits {J : Type v} [SmallCategory J] [CountableCategory J] : CreatesLimitsOfShape J lightToProfinite.{max v u} where @@ -338,7 +338,7 @@ noncomputable def LightProfinite.equivDiagram : LightProfinite.{u} ≌ LightDiag inverse := lightDiagramToLightProfinite unitIso := Iso.refl _ counitIso := NatIso.ofComponents - (fun X ↦ lightDiagramToProfinite.preimageIso (Iso.refl _)) (by + (fun _ ↦ lightDiagramToProfinite.preimageIso (Iso.refl _)) (by intro _ _ f simp only [Functor.comp_obj, lightDiagramToLightProfinite_obj, lightProfiniteToLightDiagram_obj, Functor.id_obj, Functor.comp_map, diff --git a/Mathlib/Topology/Category/Profinite/Basic.lean b/Mathlib/Topology/Category/Profinite/Basic.lean index fdde9e65b27a89..1faa3653c9a741 100644 --- a/Mathlib/Topology/Category/Profinite/Basic.lean +++ b/Mathlib/Topology/Category/Profinite/Basic.lean @@ -189,7 +189,7 @@ def limitConeIsLimit {J : Type v} [SmallCategory J] (F : J ⥤ Profinite.{max u lift S := (CompHaus.limitConeIsLimit.{v, u} (F ⋙ profiniteToCompHaus)).lift (profiniteToCompHaus.mapCone S) - uniq S m h := (CompHaus.limitConeIsLimit.{v, u} _).uniq (profiniteToCompHaus.mapCone S) _ h + uniq S _ h := (CompHaus.limitConeIsLimit.{v, u} _).uniq (profiniteToCompHaus.mapCone S) _ h /-- The adjunction between CompHaus.to_Profinite and Profinite.to_CompHaus -/ def toProfiniteAdjToCompHaus : CompHaus.toProfinite ⊣ profiniteToCompHaus := diff --git a/Mathlib/Topology/Category/TopCat/Adjunctions.lean b/Mathlib/Topology/Category/TopCat/Adjunctions.lean index e42823dc49ca54..52f1591638bd4a 100644 --- a/Mathlib/Topology/Category/TopCat/Adjunctions.lean +++ b/Mathlib/Topology/Category/TopCat/Adjunctions.lean @@ -27,15 +27,15 @@ namespace TopCat `Top ⥤ Type`. -/ @[simps! unit counit] def adj₁ : discrete ⊣ forget TopCat.{u} where - unit := { app := fun X => id } - counit := { app := fun X => ⟨id, continuous_bot⟩ } + unit := { app := fun _ => id } + counit := { app := fun _ => ⟨id, continuous_bot⟩ } /-- Equipping a type with the trivial topology is right adjoint to the forgetful functor `Top ⥤ Type`. -/ @[simps! unit counit] def adj₂ : forget TopCat.{u} ⊣ trivial where - unit := { app := fun X => ⟨id, continuous_top⟩ } - counit := { app := fun X => id } + unit := { app := fun _ => ⟨id, continuous_top⟩ } + counit := { app := fun _ => id } instance : (forget TopCat.{u}).IsRightAdjoint := ⟨_, ⟨adj₁⟩⟩ diff --git a/Mathlib/Topology/Category/TopCat/Limits/Basic.lean b/Mathlib/Topology/Category/TopCat/Limits/Basic.lean index b476fb65fb907a..e7833bab71d89f 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Basic.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Basic.lean @@ -68,7 +68,7 @@ Generally you should just use `limit.isLimit F`, unless you need the actual defi def limitConeIsLimit (F : J ⥤ TopCat.{max v u}) : IsLimit (limitCone.{v,u} F) where lift S := { toFun := fun x => - ⟨fun j => S.π.app _ x, fun f => by + ⟨fun _ => S.π.app _ x, fun f => by dsimp rw [← S.w f] rfl⟩ diff --git a/Mathlib/Topology/Category/TopCat/Limits/Products.lean b/Mathlib/Topology/Category/TopCat/Limits/Products.lean index bd879c98c4ab4c..4a6576bc290e8e 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Products.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Products.lean @@ -51,7 +51,7 @@ def piFanIsLimit {ι : Type v} (α : ι → TopCat.{max v u}) : IsLimit (piFan dsimp rw [ContinuousMap.coe_mk, ← h ⟨i⟩] rfl - fac s j := rfl + fac _ _ := rfl /-- The product is homeomorphic to the product of the underlying spaces, equipped with the product topology. diff --git a/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean b/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean index f60d2f02b49187..7427588e292b72 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean @@ -171,7 +171,7 @@ def pullbackHomeoPreimage apply hg.inj convert x.prop exact Exists.choose_spec (p := fun y ↦ g y = f (↑x : X × Y).1) _ - right_inv := fun x ↦ rfl + right_inv := fun _ ↦ rfl continuous_toFun := by apply Continuous.subtype_mk exact continuous_fst.comp continuous_subtype_val diff --git a/Mathlib/Topology/Category/TopCat/OpenNhds.lean b/Mathlib/Topology/Category/TopCat/OpenNhds.lean index d9325ee6922be3..863d3a8c4d612f 100644 --- a/Mathlib/Topology/Category/TopCat/OpenNhds.lean +++ b/Mathlib/Topology/Category/TopCat/OpenNhds.lean @@ -145,7 +145,7 @@ def functorNhds (h : IsOpenMap f) (x : X) : OpenNhds x ⥤ OpenNhds (f x) where /-- An open map `f : X ⟶ Y` induces an adjunction between `OpenNhds x` and `OpenNhds (f x)`. -/ def adjunctionNhds (h : IsOpenMap f) (x : X) : IsOpenMap.functorNhds h x ⊣ OpenNhds.map f x where - unit := { app := fun U => homOfLE fun x hxU => ⟨x, hxU, rfl⟩ } - counit := { app := fun V => homOfLE fun y ⟨_, hfxV, hxy⟩ => hxy ▸ hfxV } + unit := { app := fun _ => homOfLE fun x hxU => ⟨x, hxU, rfl⟩ } + counit := { app := fun _ => homOfLE fun _ ⟨_, hfxV, hxy⟩ => hxy ▸ hfxV } end IsOpenMap diff --git a/Mathlib/Topology/Category/TopCat/Opens.lean b/Mathlib/Topology/Category/TopCat/Opens.lean index 988c19dba4faa4..41c2df48911b05 100644 --- a/Mathlib/Topology/Category/TopCat/Opens.lean +++ b/Mathlib/Topology/Category/TopCat/Opens.lean @@ -126,13 +126,13 @@ theorem openEmbedding {X : TopCat.{u}} (U : Opens X) : OpenEmbedding (inclusion' -/ def inclusionTopIso (X : TopCat.{u}) : (toTopCat X).obj ⊤ ≅ X where hom := inclusion' ⊤ - inv := ⟨fun x => ⟨x, trivial⟩, continuous_def.2 fun U ⟨_, hS, hSU⟩ => hSU ▸ hS⟩ + inv := ⟨fun x => ⟨x, trivial⟩, continuous_def.2 fun _ ⟨_, hS, hSU⟩ => hSU ▸ hS⟩ /-- `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.continuous⟩ - map i := ⟨⟨fun x h => i.le h⟩⟩ + map i := ⟨⟨fun _ h => i.le h⟩⟩ @[simp] theorem map_coe (f : X ⟶ Y) (U : Opens Y) : ((map f).obj U : Set X) = f ⁻¹' (U : Set Y) := @@ -281,8 +281,8 @@ def IsOpenMap.functor {X Y : TopCat} {f : X ⟶ Y} (hf : IsOpenMap f) : Opens X -/ def IsOpenMap.adjunction {X Y : TopCat} {f : X ⟶ Y} (hf : IsOpenMap f) : Adjunction hf.functor (TopologicalSpace.Opens.map f) where - unit := { app := fun U => homOfLE fun x hxU => ⟨x, hxU, rfl⟩ } - counit := { app := fun V => homOfLE fun y ⟨_, hfxV, hxy⟩ => hxy ▸ hfxV } + unit := { app := fun _ => homOfLE fun x hxU => ⟨x, hxU, rfl⟩ } + counit := { app := fun _ => homOfLE fun _ ⟨_, hfxV, hxy⟩ => hxy ▸ hfxV } instance IsOpenMap.functorFullOfMono {X Y : TopCat} {f : X ⟶ Y} (hf : IsOpenMap f) [H : Mono f] : hf.functor.Full where diff --git a/Mathlib/Topology/Category/TopCat/Yoneda.lean b/Mathlib/Topology/Category/TopCat/Yoneda.lean index 65ed0d1e00d832..d898269d9ac23d 100644 --- a/Mathlib/Topology/Category/TopCat/Yoneda.lean +++ b/Mathlib/Topology/Category/TopCat/Yoneda.lean @@ -59,7 +59,7 @@ theorem piComparison_fac {α : Type} (X : α → TopCat) : /-- The universe polymorphic Yoneda presheaf on `TopCat` preserves finite products. -/ noncomputable instance : PreservesFiniteProducts (yonedaPresheaf'.{w, w'} Y) where - preserves J _ := + preserves _ _ := { preservesLimit := fun {K} => have : ∀ {α : Type} (X : α → TopCat), PreservesLimit (Discrete.functor (fun x ↦ op (X x))) (yonedaPresheaf'.{w, w'} Y) := fun X => @PreservesProduct.ofIsoComparison _ _ _ _ diff --git a/Mathlib/Topology/Category/TopCommRingCat.lean b/Mathlib/Topology/Category/TopCommRingCat.lean index b6734c03f35c71..d8e2fce858d9a7 100644 --- a/Mathlib/Topology/Category/TopCommRingCat.lean +++ b/Mathlib/Topology/Category/TopCommRingCat.lean @@ -54,7 +54,7 @@ instance : ConcreteCategory TopCommRingCat.{u} where map := fun f => f.val } -- Porting note: Old proof was `forget_faithful := { }` forget_faithful := - { map_injective := fun {_ _ a b} h => Subtype.ext <| RingHom.coe_inj h } + { map_injective := fun {_ _ _ _} h => Subtype.ext <| RingHom.coe_inj h } /-- Construct a bundled `TopCommRingCat` from the underlying type and the appropriate typeclasses. -/ diff --git a/Mathlib/Topology/CompactOpen.lean b/Mathlib/Topology/CompactOpen.lean index 0338dd8e2d3619..c4e0af021885c1 100644 --- a/Mathlib/Topology/CompactOpen.lean +++ b/Mathlib/Topology/CompactOpen.lean @@ -260,7 +260,7 @@ theorem compactOpen_eq_iInf_induced : alias compactOpen_eq_sInf_induced := compactOpen_eq_iInf_induced theorem nhds_compactOpen_eq_iInf_nhds_induced (f : C(X, Y)) : - 𝓝 f = ⨅ (s) (hs : IsCompact s), (𝓝 (f.restrict s)).comap (ContinuousMap.restrict s) := by + 𝓝 f = ⨅ (s) (_ : IsCompact s), (𝓝 (f.restrict s)).comap (ContinuousMap.restrict s) := by rw [compactOpen_eq_iInf_induced] simp only [nhds_iInf, nhds_induced] diff --git a/Mathlib/Topology/Compactification/OnePoint.lean b/Mathlib/Topology/Compactification/OnePoint.lean index 7552539c3ada1c..622f86227bd241 100644 --- a/Mathlib/Topology/Compactification/OnePoint.lean +++ b/Mathlib/Topology/Compactification/OnePoint.lean @@ -393,7 +393,7 @@ noncomputable def continuousMapDiscreteEquiv (Y : Type*) [DiscreteTopology X] [T ⟨fun x ↦ f x, ⟨f ∞, continuous_iff_from_discrete f |>.mp <| map_continuous f⟩⟩ exact Classical.choose_spec f'.property · simp - right_inv f := rfl + right_inv _ := rfl lemma continuous_iff_from_nat {Y : Type*} [TopologicalSpace Y] (f : OnePoint ℕ → Y) : Continuous f ↔ Tendsto (fun x : ℕ ↦ f x) atTop (𝓝 (f ∞)) := by diff --git a/Mathlib/Topology/Compactness/Compact.lean b/Mathlib/Topology/Compactness/Compact.lean index b83613bdfbf387..0eb3000c7fbcfe 100644 --- a/Mathlib/Topology/Compactness/Compact.lean +++ b/Mathlib/Topology/Compactness/Compact.lean @@ -222,7 +222,7 @@ theorem IsCompact.disjoint_nhdsSet_right {l : Filter X} (hs : IsCompact s) : -- Porting note (#11215): TODO: reformulate using `Disjoint` /-- For every directed family of closed sets whose intersection avoids a compact set, there exists a single element of the family which itself avoids this compact set. -/ -theorem IsCompact.elim_directed_family_closed {ι : Type v} [hι : Nonempty ι] (hs : IsCompact s) +theorem IsCompact.elim_directed_family_closed {ι : Type v} [Nonempty ι] (hs : IsCompact s) (t : ι → Set X) (htc : ∀ i, IsClosed (t i)) (hst : (s ∩ ⋂ i, t i) = ∅) (hdt : Directed (· ⊇ ·) t) : ∃ i : ι, s ∩ t i = ∅ := let ⟨t, ht⟩ := @@ -241,7 +241,7 @@ there exists a finite subfamily whose intersection avoids this compact set. -/ theorem IsCompact.elim_finite_subfamily_closed {ι : Type v} (hs : IsCompact s) (t : ι → Set X) (htc : ∀ i, IsClosed (t i)) (hst : (s ∩ ⋂ i, t i) = ∅) : ∃ u : Finset ι, (s ∩ ⋂ i ∈ u, t i) = ∅ := - hs.elim_directed_family_closed _ (fun t ↦ isClosed_biInter fun _ _ ↦ htc _) + hs.elim_directed_family_closed _ (fun _ ↦ isClosed_biInter fun _ _ ↦ htc _) (by rwa [← iInter_eq_iInter_finset]) (directed_of_isDirected_le fun _ _ h ↦ biInter_subset_biInter_left h) @@ -378,7 +378,7 @@ theorem IsCompact.mem_nhdsSet_prod_of_forall {K : Set X} {Y} {l : Filter Y} {s : theorem IsCompact.nhdsSet_prod_eq_biSup {K : Set X} (hK : IsCompact K) {Y} (l : Filter Y) : (𝓝ˢ K) ×ˢ l = ⨆ x ∈ K, 𝓝 x ×ˢ l := le_antisymm (fun s hs ↦ hK.mem_nhdsSet_prod_of_forall <| by simpa using hs) - (iSup₂_le fun x hx ↦ prod_mono (nhds_le_nhdsSet hx) le_rfl) + (iSup₂_le fun _ hx ↦ prod_mono (nhds_le_nhdsSet hx) le_rfl) theorem IsCompact.prod_nhdsSet_eq_biSup {K : Set Y} (hK : IsCompact K) {X} (l : Filter X) : l ×ˢ (𝓝ˢ K) = ⨆ y ∈ K, l ×ˢ 𝓝 y := by @@ -435,7 +435,7 @@ theorem isCompact_empty : IsCompact (∅ : Set X) := fun _f hnf hsf => Not.elim hnf.ne <| empty_mem_iff_bot.1 <| le_principal_iff.1 hsf @[simp] -theorem isCompact_singleton {x : X} : IsCompact ({x} : Set X) := fun f hf hfa => +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⟩ diff --git a/Mathlib/Topology/Compactness/CompactlyGeneratedSpace.lean b/Mathlib/Topology/Compactness/CompactlyGeneratedSpace.lean index b80b8869deeaba..09080f8e326cda 100644 --- a/Mathlib/Topology/Compactness/CompactlyGeneratedSpace.lean +++ b/Mathlib/Topology/Compactness/CompactlyGeneratedSpace.lean @@ -94,6 +94,13 @@ instance (X : Type v) [t : TopologicalSpace X] [DiscreteTopology X] : rw [DiscreteTopology.eq_bot (t := t)] exact bot_le +#adaptation_note +/-- +The new unused variable linter in +https://github.com/leanprover/lean4/pull/5338 +flags `[tY : TopologicalSpace Y]`, but we want to use this as a named argument. +-/ +set_option linter.unusedVariables false in /-- Let `f : X → Y`. Suppose that to prove that `f` is continuous, it suffices to show that for every compact Hausdorff space `K` and every continuous map `g : K → X`, `f ∘ g` is continuous. Then `X` is compactly generated. -/ diff --git a/Mathlib/Topology/Compactness/Lindelof.lean b/Mathlib/Topology/Compactness/Lindelof.lean index 6cbd814c5efbe5..64c83c6ca1c471 100644 --- a/Mathlib/Topology/Compactness/Lindelof.lean +++ b/Mathlib/Topology/Compactness/Lindelof.lean @@ -306,7 +306,7 @@ theorem isLindelof_empty : IsLindelof (∅ : Set X) := fun _f hnf _ hsf ↦ /-- A singleton set is a Lindelof set. -/ @[simp] -theorem isLindelof_singleton {x : X} : IsLindelof ({x} : Set X) := fun f hf _ hfa ↦ +theorem isLindelof_singleton {x : X} : IsLindelof ({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⟩ diff --git a/Mathlib/Topology/Compactness/SigmaCompact.lean b/Mathlib/Topology/Compactness/SigmaCompact.lean index 7518114ce3802d..ec5a6b0e2279f9 100644 --- a/Mathlib/Topology/Compactness/SigmaCompact.lean +++ b/Mathlib/Topology/Compactness/SigmaCompact.lean @@ -251,7 +251,7 @@ instance [Countable ι] {X : ι → Type*} [∀ i, TopologicalSpace (X i)] protected theorem ClosedEmbedding.sigmaCompactSpace {e : Y → X} (he : ClosedEmbedding e) : SigmaCompactSpace Y := - ⟨⟨fun n => e ⁻¹' compactCovering X n, fun n => + ⟨⟨fun n => e ⁻¹' compactCovering X n, fun _ => he.isCompact_preimage (isCompact_compactCovering _ _), by rw [← preimage_iUnion, iUnion_compactCovering, preimage_univ]⟩⟩ diff --git a/Mathlib/Topology/Connected/Basic.lean b/Mathlib/Topology/Connected/Basic.lean index 54b61ed7b660c3..9cb32af224c6e5 100644 --- a/Mathlib/Topology/Connected/Basic.lean +++ b/Mathlib/Topology/Connected/Basic.lean @@ -207,7 +207,7 @@ variable [LinearOrder β] [SuccOrder β] [IsSuccArchimedean β] such that any two neighboring sets meet is preconnected. -/ theorem IsPreconnected.iUnion_of_chain {s : β → Set α} (H : ∀ n, IsPreconnected (s n)) (K : ∀ n, (s n ∩ s (succ n)).Nonempty) : IsPreconnected (⋃ n, s n) := - IsPreconnected.iUnion_of_reflTransGen H fun i j => + IsPreconnected.iUnion_of_reflTransGen H fun _ _ => reflTransGen_of_succ _ (fun i _ => K i) fun i _ => by rw [inter_comm] exact K i @@ -216,7 +216,7 @@ theorem IsPreconnected.iUnion_of_chain {s : β → Set α} (H : ∀ n, IsPreconn such that any two neighboring sets meet is connected. -/ theorem IsConnected.iUnion_of_chain [Nonempty β] {s : β → Set α} (H : ∀ n, IsConnected (s n)) (K : ∀ n, (s n ∩ s (succ n)).Nonempty) : IsConnected (⋃ n, s n) := - IsConnected.iUnion_of_reflTransGen H fun i j => + IsConnected.iUnion_of_reflTransGen H fun _ _ => reflTransGen_of_succ _ (fun i _ => K i) fun i _ => by rw [inter_comm] exact K i diff --git a/Mathlib/Topology/Constructions.lean b/Mathlib/Topology/Constructions.lean index b4bf95ad2f9e18..646dbbbcf8c5ac 100644 --- a/Mathlib/Topology/Constructions.lean +++ b/Mathlib/Topology/Constructions.lean @@ -628,7 +628,7 @@ theorem prod_generateFrom_generateFrom_eq {X Y : Type*} {s : Set (Set X)} {t : S generateFrom (image2 (· ×ˢ ·) s t) := let G := generateFrom (image2 (· ×ˢ ·) s t) le_antisymm - (le_generateFrom fun g ⟨u, hu, v, hv, g_eq⟩ => + (le_generateFrom fun _ ⟨_, hu, _, hv, g_eq⟩ => g_eq.symm ▸ @IsOpen.prod _ _ (generateFrom s) (generateFrom t) _ _ (GenerateOpen.basic _ hu) (GenerateOpen.basic _ hv)) @@ -656,7 +656,7 @@ theorem prod_generateFrom_generateFrom_eq {X Y : Type*} {s : Set (Set X)} {t : S theorem prod_eq_generateFrom : instTopologicalSpaceProd = generateFrom { g | ∃ (s : Set X) (t : Set Y), IsOpen s ∧ IsOpen t ∧ g = s ×ˢ t } := - le_antisymm (le_generateFrom fun g ⟨s, t, hs, ht, g_eq⟩ => g_eq.symm ▸ hs.prod ht) + le_antisymm (le_generateFrom fun _ ⟨_, _, hs, ht, g_eq⟩ => g_eq.symm ▸ hs.prod ht) (le_inf (forall_mem_image.2 fun t ht => GenerateOpen.basic _ ⟨t, univ, by simpa [Set.prod_eq] using ht⟩) @@ -1436,7 +1436,7 @@ theorem pi_eq_generateFrom : generateFrom { g | ∃ (s : ∀ a, Set (π a)) (i : Finset ι), (∀ a ∈ i, IsOpen (s a)) ∧ g = pi (↑i) s } := calc Pi.topologicalSpace - _ = @Pi.topologicalSpace ι π fun a => generateFrom { s | IsOpen s } := by + _ = @Pi.topologicalSpace ι π fun _ => generateFrom { s | IsOpen s } := by simp only [generateFrom_setOf_isOpen] _ = _ := pi_generateFrom_eq diff --git a/Mathlib/Topology/ContinuousMap/Bounded.lean b/Mathlib/Topology/ContinuousMap/Bounded.lean index 01840e85e6d016..a6d612f35ff680 100644 --- a/Mathlib/Topology/ContinuousMap/Bounded.lean +++ b/Mathlib/Topology/ContinuousMap/Bounded.lean @@ -187,8 +187,8 @@ theorem dist_lt_iff_of_nonempty_compact [Nonempty α] [CompactSpace α] : instance instPseudoMetricSpace : PseudoMetricSpace (α →ᵇ β) where dist_self f := le_antisymm ((dist_le le_rfl).2 fun x => by simp) dist_nonneg' dist_comm f g := by simp [dist_eq, dist_comm] - dist_triangle f g h := (dist_le (add_nonneg dist_nonneg' dist_nonneg')).2 - fun x => le_trans (dist_triangle _ _ _) (add_le_add (dist_coe_le_dist _) (dist_coe_le_dist _)) + dist_triangle _ _ _ := (dist_le (add_nonneg dist_nonneg' dist_nonneg')).2 + fun _ => le_trans (dist_triangle _ _ _) (add_le_add (dist_coe_le_dist _) (dist_coe_le_dist _)) -- Porting note (#10888): added proof for `edist_dist` edist_dist x y := by dsimp; congr; simp [dist_nonneg'] @@ -1065,8 +1065,8 @@ variable (𝕜) /-- The evaluation at a point, as a continuous linear map from `α →ᵇ β` to `β`. -/ def evalCLM (x : α) : (α →ᵇ β) →L[𝕜] β where toFun f := f x - map_add' f g := add_apply _ _ - map_smul' c f := smul_apply _ _ _ + map_add' _ _ := add_apply _ _ + map_smul' _ _ := smul_apply _ _ _ @[simp] theorem evalCLM_apply (x : α) (f : α →ᵇ β) : evalCLM 𝕜 x f = f x := rfl diff --git a/Mathlib/Topology/ContinuousMap/Compact.lean b/Mathlib/Topology/ContinuousMap/Compact.lean index ca3851110e9399..552c3e592bff1c 100644 --- a/Mathlib/Topology/ContinuousMap/Compact.lean +++ b/Mathlib/Topology/ContinuousMap/Compact.lean @@ -295,7 +295,7 @@ def linearIsometryBoundedOfCompact : C(α, E) ≃ₗᵢ[𝕜] α →ᵇ E := map_smul' := fun c f => by ext norm_cast - norm_map' := fun f => rfl } + norm_map' := fun _ => rfl } variable {α E} diff --git a/Mathlib/Topology/ContinuousMap/Ideals.lean b/Mathlib/Topology/ContinuousMap/Ideals.lean index 5edb4350d52746..44324eab0595fb 100644 --- a/Mathlib/Topology/ContinuousMap/Ideals.lean +++ b/Mathlib/Topology/ContinuousMap/Ideals.lean @@ -86,7 +86,7 @@ def idealOfSet (s : Set X) : Ideal C(X, R) where carrier := {f : C(X, R) | ∀ x ∈ sᶜ, f x = 0} add_mem' {f g} hf hg x hx := by simp [hf x hx, hg x hx, coe_add, Pi.add_apply, add_zero] zero_mem' _ _ := rfl - smul_mem' c f hf x hx := mul_zero (c x) ▸ congr_arg (fun y => c x * y) (hf x hx) + smul_mem' c _ hf x hx := mul_zero (c x) ▸ congr_arg (fun y => c x * y) (hf x hx) theorem idealOfSet_closed [T2Space R] (s : Set X) : IsClosed (idealOfSet R s : Set C(X, R)) := by @@ -388,8 +388,8 @@ variable [Nontrivial 𝕜] [NoZeroDivisors 𝕜] def continuousMapEval : C(X, characterSpace 𝕜 C(X, 𝕜)) where toFun x := ⟨{ toFun := fun f => f x - map_add' := fun f g => rfl - map_smul' := fun z f => rfl + map_add' := fun _ _ => rfl + map_smul' := fun _ _ => rfl cont := continuous_eval_const x }, by rw [CharacterSpace.eq_set_map_one_map_mul]; exact ⟨rfl, fun f g => rfl⟩⟩ continuous_toFun := by diff --git a/Mathlib/Topology/ContinuousMap/Units.lean b/Mathlib/Topology/ContinuousMap/Units.lean index 0337bcc434faad..b63040d502d1d5 100644 --- a/Mathlib/Topology/ContinuousMap/Units.lean +++ b/Mathlib/Topology/ContinuousMap/Units.lean @@ -33,8 +33,8 @@ def unitsLift : C(X, Mˣ) ≃ C(X, M)ˣ where toFun f := { val := ⟨fun x => f x, Units.continuous_val.comp f.continuous⟩ inv := ⟨fun x => ↑(f x)⁻¹, Units.continuous_val.comp (continuous_inv.comp f.continuous)⟩ - val_inv := ext fun x => Units.mul_inv _ - inv_val := ext fun x => Units.inv_mul _ } + val_inv := ext fun _ => Units.mul_inv _ + inv_val := ext fun _ => Units.inv_mul _ } invFun f := { toFun := fun x => ⟨(f : C(X, M)) x, (↑f⁻¹ : C(X, M)) x, diff --git a/Mathlib/Topology/ContinuousOn.lean b/Mathlib/Topology/ContinuousOn.lean index 7608fd4158dbb6..a09c8362c391f9 100644 --- a/Mathlib/Topology/ContinuousOn.lean +++ b/Mathlib/Topology/ContinuousOn.lean @@ -720,7 +720,7 @@ theorem continuousWithinAt_update_same [DecidableEq α] {f : α → β} {s : Set { rw [← continuousWithinAt_diff_self, ContinuousWithinAt, update_same] } _ ↔ Tendsto f (𝓝[s \ {x}] x) (𝓝 y) := tendsto_congr' <| eventually_nhdsWithin_iff.2 <| Eventually.of_forall - fun z hz => update_noteq hz.2 _ _ + fun _ hz => update_noteq hz.2 _ _ @[simp] theorem continuousAt_update_same [DecidableEq α] {f : α → β} {x : α} {y : β} : diff --git a/Mathlib/Topology/Defs/Induced.lean b/Mathlib/Topology/Defs/Induced.lean index 2b89c259917e85..c64958ba704431 100644 --- a/Mathlib/Topology/Defs/Induced.lean +++ b/Mathlib/Topology/Defs/Induced.lean @@ -75,7 +75,7 @@ instance _root_.instTopologicalSpaceSubtype {p : X → Prop} [t : TopologicalSpa def coinduced (f : X → Y) (t : TopologicalSpace X) : TopologicalSpace Y where IsOpen s := IsOpen (f ⁻¹' s) isOpen_univ := t.isOpen_univ - isOpen_inter s₁ s₂ h₁ h₂ := h₁.inter h₂ + isOpen_inter _ _ h₁ h₂ := h₁.inter h₂ isOpen_sUnion s h := by simpa only [preimage_sUnion] using isOpen_biUnion h end TopologicalSpace diff --git a/Mathlib/Topology/EMetricSpace/Defs.lean b/Mathlib/Topology/EMetricSpace/Defs.lean index 2b6096cad74f3a..966bb8124ec912 100644 --- a/Mathlib/Topology/EMetricSpace/Defs.lean +++ b/Mathlib/Topology/EMetricSpace/Defs.lean @@ -311,7 +311,7 @@ instance Prod.pseudoEMetricSpaceMax [PseudoEMetricSpace β] : PseudoEMetricSpace edist x y := edist x.1 y.1 ⊔ edist x.2 y.2 edist_self x := by simp edist_comm x y := by simp [edist_comm] - edist_triangle x y z := + edist_triangle _ _ _ := 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 diff --git a/Mathlib/Topology/EMetricSpace/Pi.lean b/Mathlib/Topology/EMetricSpace/Pi.lean index bbf987884575b2..4e1672b11e5fbc 100644 --- a/Mathlib/Topology/EMetricSpace/Pi.lean +++ b/Mathlib/Topology/EMetricSpace/Pi.lean @@ -59,7 +59,7 @@ spaces. -/ instance pseudoEMetricSpacePi [∀ b, PseudoEMetricSpace (π b)] : PseudoEMetricSpace (∀ b, π b) where edist_self f := bot_unique <| Finset.sup_le <| by simp edist_comm f g := by simp [edist_pi_def, edist_comm] - edist_triangle f g h := edist_pi_le_iff.2 fun b => le_trans (edist_triangle _ (g b) _) + edist_triangle _ g _ := edist_pi_le_iff.2 fun b => le_trans (edist_triangle _ (g b) _) (add_le_add (edist_le_pi_edist _ _ _) (edist_le_pi_edist _ _ _)) toUniformSpace := Pi.uniformSpace _ uniformity_edist := by diff --git a/Mathlib/Topology/FiberBundle/Constructions.lean b/Mathlib/Topology/FiberBundle/Constructions.lean index b5cac2629b8cf5..a9ac5e6eb5149d 100644 --- a/Mathlib/Topology/FiberBundle/Constructions.lean +++ b/Mathlib/Topology/FiberBundle/Constructions.lean @@ -189,10 +189,10 @@ noncomputable def prod : Trivialization (F₁ × F₂) (π (F₁ × F₂) (E₁ invFun := Prod.invFun' e₁ e₂ source := π (F₁ × F₂) (E₁ ×ᵇ E₂) ⁻¹' (e₁.baseSet ∩ e₂.baseSet) target := (e₁.baseSet ∩ e₂.baseSet) ×ˢ Set.univ - map_source' x h := ⟨h, Set.mem_univ _⟩ - map_target' x h := h.1 - left_inv' x := Prod.left_inv - right_inv' x := Prod.right_inv + map_source' _ h := ⟨h, Set.mem_univ _⟩ + map_target' _ h := h.1 + left_inv' _ := Prod.left_inv + right_inv' _ := Prod.right_inv open_source := by convert (e₁.open_source.prod e₂.open_source).preimage (FiberBundle.Prod.inducing_diag F₁ E₁ F₂ E₂).continuous @@ -205,7 +205,7 @@ noncomputable def prod : Trivialization (F₁ × F₂) (π (F₁ × F₂) (E₁ open_baseSet := e₁.open_baseSet.inter e₂.open_baseSet source_eq := rfl target_eq := rfl - proj_toFun x _ := rfl + proj_toFun _ _ := rfl @[simp] theorem baseSet_prod : (prod e₁ e₂).baseSet = e₁.baseSet ∩ e₂.baseSet := rfl @@ -339,7 +339,7 @@ noncomputable def Trivialization.pullback (e : Trivialization F (π F E)) (f : K rw [e.source_eq] rfl target_eq := rfl - proj_toFun y _ := rfl + proj_toFun _ _ := rfl noncomputable instance FiberBundle.pullback [∀ x, TopologicalSpace (E x)] [FiberBundle F E] (f : K) : FiberBundle F ((f : B' → B) *ᵖ E) where diff --git a/Mathlib/Topology/Filter.lean b/Mathlib/Topology/Filter.lean index 17a22a272b2385..78b2714743dbe2 100644 --- a/Mathlib/Topology/Filter.lean +++ b/Mathlib/Topology/Filter.lean @@ -57,7 +57,7 @@ theorem isTopologicalBasis_Iic_principal : { exists_subset_inter := by rintro _ ⟨s, rfl⟩ _ ⟨t, rfl⟩ l hl exact ⟨Iic (𝓟 s) ∩ Iic (𝓟 t), ⟨s ∩ t, by simp⟩, hl, Subset.rfl⟩ - sUnion_eq := sUnion_eq_univ_iff.2 fun l => ⟨Iic ⊤, ⟨univ, congr_arg Iic principal_univ⟩, + sUnion_eq := sUnion_eq_univ_iff.2 fun _ => ⟨Iic ⊤, ⟨univ, congr_arg Iic principal_univ⟩, mem_Iic.2 le_top⟩ eq_generateFrom := rfl } diff --git a/Mathlib/Topology/Gluing.lean b/Mathlib/Topology/Gluing.lean index d6fd7281d0b0cc..753550992301e1 100644 --- a/Mathlib/Topology/Gluing.lean +++ b/Mathlib/Topology/Gluing.lean @@ -379,7 +379,7 @@ def mk' (h : MkCore.{u}) : TopCat.GlueData where refine Subtype.ext ?_ exact h.cocycle i j k ⟨x, hx⟩ hx' -- Porting note: was not necessary in mathlib3 - f_mono i j := (TopCat.mono_iff_injective _).mpr fun x y h => Subtype.ext h + f_mono _ _ := (TopCat.mono_iff_injective _).mpr fun _ _ h => Subtype.ext h variable {α : Type u} [TopologicalSpace α] {J : Type u} (U : J → Opens α) @@ -389,7 +389,7 @@ def ofOpenSubsets : TopCat.GlueData.{u} := mk'.{u} { J U := fun i => (Opens.toTopCat <| TopCat.of α).obj (U i) - V := fun i j => (Opens.map <| Opens.inclusion' _).obj (U j) + V := fun _ j => (Opens.map <| Opens.inclusion' _).obj (U j) t := fun i j => ⟨fun x => ⟨⟨x.1.1, x.2⟩, x.1.2⟩, by -- Porting note: was `continuity`, see https://github.com/leanprover-community/mathlib4/issues/5030 refine Continuous.subtype_mk ?_ ?_ @@ -400,15 +400,15 @@ def ofOpenSubsets : TopCat.GlueData.{u} := -- Porting note: no longer needed `cases U i`! simp t_id := fun i => by ext; rfl - t_inter := fun i j k x hx => hx - cocycle := fun i j k x h => rfl } + t_inter := fun _ _ _ _ hx => hx + cocycle := fun _ _ _ _ _ => rfl } /-- The canonical map from the glue of a family of open subsets `α` into `α`. This map is an open embedding (`fromOpenSubsetsGlue_openEmbedding`), and its range is `⋃ i, (U i : Set α)` (`range_fromOpenSubsetsGlue`). -/ def fromOpenSubsetsGlue : (ofOpenSubsets U).toGlueData.glued ⟶ TopCat.of α := - Multicoequalizer.desc _ _ (fun x => Opens.inclusion' _) (by rintro ⟨i, j⟩; ext x; rfl) + Multicoequalizer.desc _ _ (fun _ => Opens.inclusion' _) (by rintro ⟨i, j⟩; ext x; rfl) -- Porting note: `elementwise` here produces a bad lemma, -- where too much has been simplified, despite the `nosimp`. diff --git a/Mathlib/Topology/Homeomorph.lean b/Mathlib/Topology/Homeomorph.lean index 6d33a57317001d..9daf8a9d2be4cc 100644 --- a/Mathlib/Topology/Homeomorph.lean +++ b/Mathlib/Topology/Homeomorph.lean @@ -811,7 +811,7 @@ variable {Z : Type*} [TopologicalSpace X] [TopologicalSpace Y] [TopologicalSpace @[simps toEquiv] def toHomeomorph (e : X ≃ Y) (he : ∀ s, IsOpen (e ⁻¹' s) ↔ IsOpen s) : X ≃ₜ Y where toEquiv := e - continuous_toFun := continuous_def.2 fun s ↦ (he _).2 + continuous_toFun := continuous_def.2 fun _ ↦ (he _).2 continuous_invFun := continuous_def.2 fun s ↦ by convert (he _).1; simp @[simp] lemma coe_toHomeomorph (e : X ≃ Y) (he) : ⇑(e.toHomeomorph he) = e := rfl diff --git a/Mathlib/Topology/Homotopy/HSpaces.lean b/Mathlib/Topology/Homotopy/HSpaces.lean index 15648773fa8227..cf728834e55ae6 100644 --- a/Mathlib/Topology/Homotopy/HSpaces.lean +++ b/Mathlib/Topology/Homotopy/HSpaces.lean @@ -163,7 +163,7 @@ def qRight (p : I × I) : I := theorem continuous_qRight : Continuous qRight := continuous_projIcc.comp <| - Continuous.div (by fun_prop) (by fun_prop) fun x ↦ (add_pos zero_lt_one).ne' + Continuous.div (by fun_prop) (by fun_prop) fun _ ↦ (add_pos zero_lt_one).ne' theorem qRight_zero_left (θ : I) : qRight (0, θ) = 0 := Set.projIcc_of_le_left _ <| by simp only [coe_zero, mul_zero, zero_div, le_refl] diff --git a/Mathlib/Topology/Instances/ENNReal.lean b/Mathlib/Topology/Instances/ENNReal.lean index 5623966b95601a..40974db3f97173 100644 --- a/Mathlib/Topology/Instances/ENNReal.lean +++ b/Mathlib/Topology/Instances/ENNReal.lean @@ -153,7 +153,7 @@ theorem tendsto_nhds_top_iff_nat {m : α → ℝ≥0∞} {f : Filter α} : tendsto_nhds_top_iff_nnreal.trans ⟨fun h n => by simpa only [ENNReal.coe_natCast] using h n, fun h x => let ⟨n, hn⟩ := exists_nat_gt x - (h n).mono fun y => lt_trans <| by rwa [← ENNReal.coe_natCast, coe_lt_coe]⟩ + (h n).mono fun _ => lt_trans <| by rwa [← ENNReal.coe_natCast, coe_lt_coe]⟩ theorem tendsto_nhds_top {m : α → ℝ≥0∞} {f : Filter α} (h : ∀ n : ℕ, ∀ᶠ a in f, ↑n < m a) : Tendsto m f (𝓝 ∞) := diff --git a/Mathlib/Topology/Instances/EReal.lean b/Mathlib/Topology/Instances/EReal.lean index 4d970aa153cb8d..08db54290d7bd0 100644 --- a/Mathlib/Topology/Instances/EReal.lean +++ b/Mathlib/Topology/Instances/EReal.lean @@ -226,14 +226,14 @@ lemma limsup_add_le_add_limsup (h : limsup u f ≠ ⊥ ∨ limsup v f ≠ ⊤) exact (add_lt_add a_x b_x).trans c_ab lemma limsup_add_liminf_le_limsup_add : (limsup u f) + (liminf v f) ≤ limsup (u + v) f := - add_le_of_forall_add_le fun a a_u b b_v ↦ (le_limsup_iff).2 fun c c_ab ↦ + add_le_of_forall_add_le fun _ a_u _ b_v ↦ (le_limsup_iff).2 fun _ c_ab ↦ Frequently.mono (Frequently.and_eventually ((frequently_lt_of_lt_limsup) a_u) ((eventually_lt_of_lt_liminf) b_v)) fun _ ab_x ↦ c_ab.trans (add_lt_add ab_x.1 ab_x.2) lemma liminf_add_le_limsup_add_liminf (h : limsup u f ≠ ⊥ ∨ liminf v f ≠ ⊤) (h' : limsup u f ≠ ⊤ ∨ liminf v f ≠ ⊥) : liminf (u + v) f ≤ (limsup u f) + (liminf v f) := - le_add_of_forall_le_add h h' fun a a_u b b_v ↦ (liminf_le_iff).2 fun c c_ab ↦ + le_add_of_forall_le_add h h' fun _ a_u _ b_v ↦ (liminf_le_iff).2 fun _ c_ab ↦ Frequently.mono (Frequently.and_eventually ((frequently_lt_of_liminf_lt) b_v) ((eventually_lt_of_limsup_lt) a_u)) fun _ ab_x ↦ (add_lt_add ab_x.2 ab_x.1).trans c_ab diff --git a/Mathlib/Topology/Instances/Real.lean b/Mathlib/Topology/Instances/Real.lean index 16325c2f3e0aba..927f93d6bf83a5 100644 --- a/Mathlib/Topology/Instances/Real.lean +++ b/Mathlib/Topology/Instances/Real.lean @@ -61,13 +61,13 @@ instance : SecondCountableTopology ℝ := secondCountable_of_proper theorem Real.isTopologicalBasis_Ioo_rat : @IsTopologicalBasis ℝ _ (⋃ (a : ℚ) (b : ℚ) (_ : a < b), {Ioo (a : ℝ) b}) := isTopologicalBasis_of_isOpen_of_nhds (by simp (config := { contextual := true }) [isOpen_Ioo]) - fun a v hav hv => - let ⟨l, u, ⟨hl, hu⟩, h⟩ := mem_nhds_iff_exists_Ioo_subset.mp (IsOpen.mem_nhds hv hav) + fun a _ hav hv => + let ⟨_, _, ⟨hl, hu⟩, h⟩ := mem_nhds_iff_exists_Ioo_subset.mp (IsOpen.mem_nhds hv hav) let ⟨q, hlq, hqa⟩ := exists_rat_btwn hl let ⟨p, hap, hpu⟩ := exists_rat_btwn hu ⟨Ioo q p, by simp only [mem_iUnion] - exact ⟨q, p, Rat.cast_lt.1 <| hqa.trans hap, rfl⟩, ⟨hqa, hap⟩, fun a' ⟨hqa', ha'p⟩ => + exact ⟨q, p, Rat.cast_lt.1 <| hqa.trans hap, rfl⟩, ⟨hqa, hap⟩, fun _ ⟨hqa', ha'p⟩ => h ⟨hlq.trans hqa', ha'p.trans hpu⟩⟩ @[simp] @@ -142,7 +142,7 @@ theorem closure_of_rat_image_lt {q : ℚ} : Subset.antisymm (isClosed_Ici.closure_subset_iff.2 (image_subset_iff.2 fun p (h : q < p) => by simpa using h.le)) - fun x hx => mem_closure_iff_nhds.2 fun t ht => + fun x hx => mem_closure_iff_nhds.2 fun _ ht => let ⟨ε, ε0, hε⟩ := Metric.mem_nhds_iff.1 ht let ⟨p, h₁, h₂⟩ := exists_rat_btwn ((lt_add_iff_pos_right x).2 ε0) ⟨p, hε <| by rwa [mem_ball, Real.dist_eq, abs_of_pos (sub_pos.2 h₁), sub_lt_iff_lt_add'], diff --git a/Mathlib/Topology/List.lean b/Mathlib/Topology/List.lean index f9e3f9ddbdfc36..ca954e2c62243d 100644 --- a/Mathlib/Topology/List.lean +++ b/Mathlib/Topology/List.lean @@ -118,7 +118,7 @@ theorem continuousAt_length : ∀ l : List α, ContinuousAt List.length l := by theorem tendsto_insertNth' {a : α} : ∀ {n : ℕ} {l : List α}, Tendsto (fun p : α × List α => insertNth n p.1 p.2) (𝓝 a ×ˢ 𝓝 l) (𝓝 (insertNth n a l)) - | 0, l => tendsto_cons + | 0, _ => tendsto_cons | n + 1, [] => by simp | n + 1, a'::l => by have : 𝓝 a ×ˢ 𝓝 (a'::l) = diff --git a/Mathlib/Topology/MetricSpace/Algebra.lean b/Mathlib/Topology/MetricSpace/Algebra.lean index e185b9abdc3bab..c3e28fc646228f 100644 --- a/Mathlib/Topology/MetricSpace/Algebra.lean +++ b/Mathlib/Topology/MetricSpace/Algebra.lean @@ -186,21 +186,21 @@ instance Pi.instBoundedSMul {α : Type*} {β : ι → Type*} [PseudoMetricSpace [∀ i, PseudoMetricSpace (β i)] [Zero α] [∀ i, Zero (β i)] [∀ i, SMul α (β i)] [∀ i, BoundedSMul α (β i)] : BoundedSMul α (∀ i, β i) where dist_smul_pair' x y₁ y₂ := - (dist_pi_le_iff <| by positivity).2 fun i ↦ + (dist_pi_le_iff <| by positivity).2 fun _ ↦ (dist_smul_pair _ _ _).trans <| mul_le_mul_of_nonneg_left (dist_le_pi_dist _ _ _) dist_nonneg dist_pair_smul' x₁ x₂ y := - (dist_pi_le_iff <| by positivity).2 fun i ↦ + (dist_pi_le_iff <| by positivity).2 fun _ ↦ (dist_pair_smul _ _ _).trans <| mul_le_mul_of_nonneg_left (dist_le_pi_dist _ 0 _) dist_nonneg instance Pi.instBoundedSMul' {α β : ι → Type*} [∀ i, PseudoMetricSpace (α i)] [∀ i, PseudoMetricSpace (β i)] [∀ i, Zero (α i)] [∀ i, Zero (β i)] [∀ i, SMul (α i) (β i)] [∀ i, BoundedSMul (α i) (β i)] : BoundedSMul (∀ i, α i) (∀ i, β i) where dist_smul_pair' x y₁ y₂ := - (dist_pi_le_iff <| by positivity).2 fun i ↦ + (dist_pi_le_iff <| by positivity).2 fun _ ↦ (dist_smul_pair _ _ _).trans <| mul_le_mul (dist_le_pi_dist _ 0 _) (dist_le_pi_dist _ _ _) dist_nonneg dist_nonneg dist_pair_smul' x₁ x₂ y := - (dist_pi_le_iff <| by positivity).2 fun i ↦ + (dist_pi_le_iff <| by positivity).2 fun _ ↦ (dist_pair_smul _ _ _).trans <| mul_le_mul (dist_le_pi_dist _ _ _) (dist_le_pi_dist _ 0 _) dist_nonneg dist_nonneg diff --git a/Mathlib/Topology/MetricSpace/Closeds.lean b/Mathlib/Topology/MetricSpace/Closeds.lean index 2dd3375fbcd8e9..8c33b2ec9c2f74 100644 --- a/Mathlib/Topology/MetricSpace/Closeds.lean +++ b/Mathlib/Topology/MetricSpace/Closeds.lean @@ -38,9 +38,9 @@ variable {α : Type u} [EMetricSpace α] {s : Set α} on the type of closed subsets -/ instance Closeds.emetricSpace : EMetricSpace (Closeds α) where edist s t := hausdorffEdist (s : Set α) t - edist_self s := hausdorffEdist_self - edist_comm s t := hausdorffEdist_comm - edist_triangle s t u := hausdorffEdist_triangle + edist_self _ := hausdorffEdist_self + edist_comm _ _ := hausdorffEdist_comm + edist_triangle _ _ _ := hausdorffEdist_triangle eq_of_edist_eq_zero {s t} h := Closeds.ext <| (hausdorffEdist_zero_iff_eq_of_closed s.closed t.closed).1 h @@ -224,9 +224,9 @@ instance Closeds.compactSpace [CompactSpace α] : CompactSpace (Closeds α) := where the edistance is the Hausdorff edistance -/ instance NonemptyCompacts.emetricSpace : EMetricSpace (NonemptyCompacts α) where edist s t := hausdorffEdist (s : Set α) t - edist_self s := hausdorffEdist_self - edist_comm s t := hausdorffEdist_comm - edist_triangle s t u := hausdorffEdist_triangle + edist_self _ := hausdorffEdist_self + edist_comm _ _ := hausdorffEdist_comm + edist_triangle _ _ _ := hausdorffEdist_triangle eq_of_edist_eq_zero {s t} h := NonemptyCompacts.ext <| by have : closure (s : Set α) = closure t := hausdorffEdist_zero_iff_closure_eq_closure.1 h rwa [s.isCompact.isClosed.closure_eq, t.isCompact.isClosed.closure_eq] at this diff --git a/Mathlib/Topology/MetricSpace/Dilation.lean b/Mathlib/Topology/MetricSpace/Dilation.lean index a2b542947d55f6..2622d97a69454c 100644 --- a/Mathlib/Topology/MetricSpace/Dilation.lean +++ b/Mathlib/Topology/MetricSpace/Dilation.lean @@ -326,7 +326,7 @@ instance : Monoid (α →ᵈ α) where mul := comp mul_one := comp_id one_mul := id_comp - mul_assoc f g h := comp_assoc _ _ _ + mul_assoc _ _ _ := comp_assoc _ _ _ theorem one_def : (1 : α →ᵈ α) = Dilation.id α := rfl diff --git a/Mathlib/Topology/MetricSpace/Gluing.lean b/Mathlib/Topology/MetricSpace/Gluing.lean index e3f3f1233ca43f..f11b797b3559ed 100644 --- a/Mathlib/Topology/MetricSpace/Gluing.lean +++ b/Mathlib/Topology/MetricSpace/Gluing.lean @@ -129,8 +129,8 @@ private theorem glueDist_triangle_inl_inr_inl (Φ : Z → X) (Ψ : Z → Y) (ε private theorem glueDist_triangle (Φ : Z → X) (Ψ : Z → Y) (ε : ℝ) (H : ∀ p q, |dist (Φ p) (Φ q) - dist (Ψ p) (Ψ q)| ≤ 2 * ε) : ∀ x y z, glueDist Φ Ψ ε x z ≤ glueDist Φ Ψ ε x y + glueDist Φ Ψ ε y z - | .inl x, .inl y, .inl z => dist_triangle _ _ _ - | .inr x, .inr y, .inr z => dist_triangle _ _ _ + | .inl _, .inl _, .inl _ => dist_triangle _ _ _ + | .inr _, .inr _, .inr _ => dist_triangle _ _ _ | .inr x, .inl y, .inl z => by simp only [← glueDist_swap Φ] apply glueDist_triangle_inl_inr_inr @@ -139,7 +139,7 @@ private theorem glueDist_triangle (Φ : Z → X) (Ψ : Z → Y) (ε : ℝ) | .inl x, .inl y, .inr z => by simpa only [← glueDist_swap Φ, glueDist_comm, add_comm, Sum.swap_inl, Sum.swap_inr] using glueDist_triangle_inl_inr_inr Ψ Φ ε z y x - | .inl x, .inr y, .inr z => glueDist_triangle_inl_inr_inr .. + | .inl _, .inr _, .inr _ => glueDist_triangle_inl_inr_inr .. | .inl x, .inr y, .inl z => glueDist_triangle_inl_inr_inl Φ Ψ ε H x y z | .inr x, .inl y, .inr z => by simp only [← glueDist_swap Φ] diff --git a/Mathlib/Topology/MetricSpace/GromovHausdorffRealized.lean b/Mathlib/Topology/MetricSpace/GromovHausdorffRealized.lean index 9a6979a644bb11..1610895150222b 100644 --- a/Mathlib/Topology/MetricSpace/GromovHausdorffRealized.lean +++ b/Mathlib/Topology/MetricSpace/GromovHausdorffRealized.lean @@ -432,9 +432,9 @@ predistance is given by the candidate. Then, we will identify points at `0` pred to obtain a genuine metric space. -/ def premetricOptimalGHDist : PseudoMetricSpace (X ⊕ Y) where dist p q := optimalGHDist X Y (p, q) - dist_self x := candidates_refl (optimalGHDist_mem_candidatesB X Y) - dist_comm x y := candidates_symm (optimalGHDist_mem_candidatesB X Y) - dist_triangle x y z := candidates_triangle (optimalGHDist_mem_candidatesB X Y) + dist_self _ := candidates_refl (optimalGHDist_mem_candidatesB X Y) + dist_comm _ _ := candidates_symm (optimalGHDist_mem_candidatesB X Y) + dist_triangle _ _ _ := candidates_triangle (optimalGHDist_mem_candidatesB X Y) -- Porting note (#10888): added proof for `edist_dist` edist_dist x y := by simp only diff --git a/Mathlib/Topology/MetricSpace/HausdorffDistance.lean b/Mathlib/Topology/MetricSpace/HausdorffDistance.lean index fc2c6abdca52c4..b898627b74b4ef 100644 --- a/Mathlib/Topology/MetricSpace/HausdorffDistance.lean +++ b/Mathlib/Topology/MetricSpace/HausdorffDistance.lean @@ -114,7 +114,7 @@ the edist from `x` to `y` -/ theorem infEdist_le_infEdist_add_edist : infEdist x s ≤ infEdist y s + edist x y := calc ⨅ z ∈ s, edist x z ≤ ⨅ z ∈ s, edist y z + edist x y := - iInf₂_mono fun z _ => (edist_triangle _ _ _).trans_eq (add_comm _ _) + iInf₂_mono fun _ _ => (edist_triangle _ _ _).trans_eq (add_comm _ _) _ = (⨅ z ∈ s, edist y z) + edist x y := by simp only [ENNReal.iInf_add] theorem infEdist_le_edist_add_infEdist : infEdist x s ≤ edist x y + infEdist y s := by diff --git a/Mathlib/Topology/MetricSpace/Isometry.lean b/Mathlib/Topology/MetricSpace/Isometry.lean index 0640a68f619aa9..34b17ebabb3e41 100644 --- a/Mathlib/Topology/MetricSpace/Isometry.lean +++ b/Mathlib/Topology/MetricSpace/Isometry.lean @@ -458,9 +458,9 @@ instance : Group (α ≃ᵢ α) where one := IsometryEquiv.refl _ mul e₁ e₂ := e₂.trans e₁ inv := IsometryEquiv.symm - mul_assoc e₁ e₂ e₃ := rfl - one_mul e := ext fun _ => rfl - mul_one e := ext fun _ => rfl + mul_assoc _ _ _ := rfl + one_mul _ := ext fun _ => rfl + mul_one _ := ext fun _ => rfl inv_mul_cancel e := ext e.symm_apply_apply @[simp] theorem coe_one : ⇑(1 : α ≃ᵢ α) = id := rfl diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Constructions.lean b/Mathlib/Topology/MetricSpace/Pseudo/Constructions.lean index 764f2c2b7f1f10..1edab114462099 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Constructions.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Constructions.lean @@ -23,11 +23,11 @@ variable {α β : Type*} [PseudoMetricSpace α] abbrev PseudoMetricSpace.induced {α β} (f : α → β) (m : PseudoMetricSpace β) : PseudoMetricSpace α where dist x y := dist (f x) (f y) - dist_self x := dist_self _ - dist_comm x y := dist_comm _ _ - dist_triangle x y z := dist_triangle _ _ _ + dist_self _ := dist_self _ + dist_comm _ _ := dist_comm _ _ + dist_triangle _ _ _ := dist_triangle _ _ _ edist x y := edist (f x) (f y) - edist_dist x y := edist_dist _ _ + edist_dist _ _ := edist_dist _ _ toUniformSpace := UniformSpace.comap f m.toUniformSpace uniformity_dist := (uniformity_basis_dist.comap _).eq_biInf toBornology := Bornology.induced f @@ -147,7 +147,7 @@ variable [PseudoMetricSpace β] instance Prod.pseudoMetricSpaceMax : PseudoMetricSpace (α × β) := let i := PseudoEMetricSpace.toPseudoMetricSpaceOfDist (fun x y : α × β => dist x.1 y.1 ⊔ dist x.2 y.2) - (fun x y => (max_lt (edist_lt_top _ _) (edist_lt_top _ _)).ne) fun x y => by + (fun _ _ => (max_lt (edist_lt_top _ _) (edist_lt_top _ _)).ne) fun x y => by simp only [sup_eq_max, dist_edist, ← ENNReal.toReal_max (edist_ne_top _ _) (edist_ne_top _ _), Prod.edist_eq] i.replaceBornology fun s => by diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean index 89df0d0b39ba35..de82c05c1a3241 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Defs.lean @@ -59,7 +59,7 @@ def UniformSpace.ofDist (dist : α → α → ℝ) (dist_self : ∀ x : α, dist abbrev Bornology.ofDist {α : Type*} (dist : α → α → ℝ) (dist_comm : ∀ x y, dist x y = dist y x) (dist_triangle : ∀ x y z, dist x z ≤ dist x y + dist y z) : Bornology α := Bornology.ofBounded { s : Set α | ∃ C, ∀ ⦃x⦄, x ∈ s → ∀ ⦃y⦄, y ∈ s → dist x y ≤ C } - ⟨0, fun x hx y => hx.elim⟩ (fun s ⟨c, hc⟩ t h => ⟨c, fun x hx y hy => hc (h hx) (h hy)⟩) + ⟨0, fun _ hx _ => hx.elim⟩ (fun _ ⟨c, hc⟩ _ h => ⟨c, fun _ hx _ hy => hc (h hx) (h hy)⟩) (fun s hs t ht => by rcases s.eq_empty_or_nonempty with rfl | ⟨x, hx⟩ · rwa [empty_union] @@ -1013,8 +1013,8 @@ section Real instance Real.pseudoMetricSpace : PseudoMetricSpace ℝ where dist x y := |x - y| dist_self := by simp [abs_zero] - dist_comm x y := abs_sub_comm _ _ - dist_triangle x y z := abs_sub_le _ _ _ + dist_comm _ _ := abs_sub_comm _ _ + dist_triangle _ _ _ := abs_sub_le _ _ _ theorem Real.dist_eq (x y : ℝ) : dist x y = |x - y| := rfl diff --git a/Mathlib/Topology/Metrizable/Uniformity.lean b/Mathlib/Topology/Metrizable/Uniformity.lean index 3dc4176d75c215..3aaa2860dcb661 100644 --- a/Mathlib/Topology/Metrizable/Uniformity.lean +++ b/Mathlib/Topology/Metrizable/Uniformity.lean @@ -79,7 +79,7 @@ noncomputable def ofPreNNDist (d : X → X → ℝ≥0) (dist_self : ∀ x, d x append_assoc, append_assoc] rw [length_cons, length_append, length_singleton] -- Porting note: `edist_dist` is no longer inferred - edist_dist x y := rfl + edist_dist _ _ := rfl theorem dist_ofPreNNDist (d : X → X → ℝ≥0) (dist_self : ∀ x, d x x = 0) (dist_comm : ∀ x y, d x y = d y x) (x y : X) : diff --git a/Mathlib/Topology/Order.lean b/Mathlib/Topology/Order.lean index c1c9b629e85926..05a207e173994a 100644 --- a/Mathlib/Topology/Order.lean +++ b/Mathlib/Topology/Order.lean @@ -269,7 +269,7 @@ theorem continuous_of_discreteTopology [TopologicalSpace β] {f : α → β} : C singleton is open. -/ theorem continuous_discrete_rng {α} [TopologicalSpace α] [TopologicalSpace β] [DiscreteTopology β] {f : α → β} : Continuous f ↔ ∀ b : β, IsOpen (f ⁻¹' {b}) := - ⟨fun h b => (isOpen_discrete _).preimage h, fun h => ⟨fun s _ => by + ⟨fun h _ => (isOpen_discrete _).preimage h, fun h => ⟨fun s _ => by rw [← biUnion_of_singleton s, preimage_iUnion₂] exact isOpen_biUnion fun _ _ => h _⟩⟩ diff --git a/Mathlib/Topology/Order/Basic.lean b/Mathlib/Topology/Order/Basic.lean index 3e2cc3f13ebe98..beee03643d1b35 100644 --- a/Mathlib/Topology/Order/Basic.lean +++ b/Mathlib/Topology/Order/Basic.lean @@ -284,10 +284,10 @@ theorem nhdsWithin_Iic_basis [TopologicalSpace α] [LinearOrder α] [OrderTopolo nhdsWithin_Iic_basis' (exists_lt a) theorem nhds_top_order [TopologicalSpace α] [Preorder α] [OrderTop α] [OrderTopology α] : - 𝓝 (⊤ : α) = ⨅ (l) (h₂ : l < ⊤), 𝓟 (Ioi l) := by simp [nhds_eq_order (⊤ : α)] + 𝓝 (⊤ : α) = ⨅ (l) (_ : l < ⊤), 𝓟 (Ioi l) := by simp [nhds_eq_order (⊤ : α)] theorem nhds_bot_order [TopologicalSpace α] [Preorder α] [OrderBot α] [OrderTopology α] : - 𝓝 (⊥ : α) = ⨅ (l) (h₂ : ⊥ < l), 𝓟 (Iio l) := by simp [nhds_eq_order (⊥ : α)] + 𝓝 (⊥ : α) = ⨅ (l) (_ : ⊥ < l), 𝓟 (Iio l) := by simp [nhds_eq_order (⊥ : α)] theorem nhds_top_basis [TopologicalSpace α] [LinearOrder α] [OrderTop α] [OrderTopology α] [Nontrivial α] : (𝓝 ⊤).HasBasis (fun a : α => a < ⊤) fun a : α => Ioi a := by diff --git a/Mathlib/Topology/Order/Bornology.lean b/Mathlib/Topology/Order/Bornology.lean index e2307a276340e9..93afbf73aa4aee 100644 --- a/Mathlib/Topology/Order/Bornology.lean +++ b/Mathlib/Topology/Order/Bornology.lean @@ -29,8 +29,8 @@ and below. -/ def orderBornology : Bornology α := .ofBounded {s | BddBelow s ∧ BddAbove s} (by simp) - (fun s hs t hst ↦ ⟨hs.1.mono hst, hs.2.mono hst⟩) - (fun s hs t ht ↦ ⟨hs.1.union ht.1, hs.2.union ht.2⟩) + (fun _ hs _ hst ↦ ⟨hs.1.mono hst, hs.2.mono hst⟩) + (fun _ hs _ ht ↦ ⟨hs.1.union ht.1, hs.2.union ht.2⟩) (by simp) @[simp] lemma orderBornology_isBounded : orderBornology.IsBounded s ↔ BddBelow s ∧ BddAbove s := by diff --git a/Mathlib/Topology/Order/Category/FrameAdjunction.lean b/Mathlib/Topology/Order/Category/FrameAdjunction.lean index e44b0f9de90624..9f2055bd85c47e 100644 --- a/Mathlib/Topology/Order/Category/FrameAdjunction.lean +++ b/Mathlib/Topology/Order/Category/FrameAdjunction.lean @@ -97,7 +97,7 @@ a point `x` of the space `X` a point of the locale of opens of `X`. -/ @[simps] def localePointOfSpacePoint (x : X) : PT (Opens X) where toFun := (x ∈ ·) - map_inf' a b := rfl + map_inf' _ _ := rfl map_top' := rfl map_sSup' S := by simp [Prop.exists_iff] diff --git a/Mathlib/Topology/Order/MonotoneContinuity.lean b/Mathlib/Topology/Order/MonotoneContinuity.lean index 9c1a04ed46becc..ac6195f5ca3456 100644 --- a/Mathlib/Topology/Order/MonotoneContinuity.lean +++ b/Mathlib/Topology/Order/MonotoneContinuity.lean @@ -253,7 +253,7 @@ theorem continuousAt_of_monotoneOn_of_image_mem_nhds [DenselyOrdered β] {f : α theorem Monotone.continuous_of_denseRange [DenselyOrdered β] {f : α → β} (h_mono : Monotone f) (h_dense : DenseRange f) : Continuous f := continuous_iff_continuousAt.mpr fun a => - continuousAt_of_monotoneOn_of_closure_image_mem_nhds (fun x _ y _ hxy => h_mono hxy) + continuousAt_of_monotoneOn_of_closure_image_mem_nhds (fun _ _ _ _ hxy => h_mono hxy) univ_mem <| by simp only [image_univ, h_dense.closure_eq, univ_mem] diff --git a/Mathlib/Topology/Partial.lean b/Mathlib/Topology/Partial.lean index 8f7c0957e850a4..5c1301d71d438b 100644 --- a/Mathlib/Topology/Partial.lean +++ b/Mathlib/Topology/Partial.lean @@ -51,7 +51,7 @@ theorem open_dom_of_pcontinuous {f : X →. Y} (h : PContinuous f) : IsOpen f.Do rw [← PFun.preimage_univ]; exact h _ isOpen_univ theorem pcontinuous_iff' {f : X →. Y} : - PContinuous f ↔ ∀ {x y} (h : y ∈ f x), PTendsto' f (𝓝 x) (𝓝 y) := by + PContinuous f ↔ ∀ {x y} (_ : y ∈ f x), PTendsto' f (𝓝 x) (𝓝 y) := by constructor · intro h x y h' simp only [ptendsto'_def, mem_nhds_iff] diff --git a/Mathlib/Topology/PartialHomeomorph.lean b/Mathlib/Topology/PartialHomeomorph.lean index 98e7d2e0d5f74f..3cecb43406b4ef 100644 --- a/Mathlib/Topology/PartialHomeomorph.lean +++ b/Mathlib/Topology/PartialHomeomorph.lean @@ -761,7 +761,7 @@ theorem trans_of_set' {s : Set Y} (hs : IsOpen s) : e.trans (ofSet s hs) = e.restr (e.source ∩ e ⁻¹' s) := by rw [trans_ofSet, restr_source_inter] theorem ofSet_trans {s : Set X} (hs : IsOpen s) : (ofSet s hs).trans e = e.restr s := - PartialHomeomorph.ext _ _ (fun x => rfl) (fun x => rfl) <| by simp [hs.interior_eq, inter_comm] + PartialHomeomorph.ext _ _ (fun _ => rfl) (fun _ => rfl) <| by simp [hs.interior_eq, inter_comm] theorem ofSet_trans' {s : Set X} (hs : IsOpen s) : (ofSet s hs).trans e = e.restr (e.source ∩ s) := by diff --git a/Mathlib/Topology/PartitionOfUnity.lean b/Mathlib/Topology/PartitionOfUnity.lean index 661a124cbc7d45..bee6a23c8a1774 100644 --- a/Mathlib/Topology/PartitionOfUnity.lean +++ b/Mathlib/Topology/PartitionOfUnity.lean @@ -339,7 +339,7 @@ protected def single (i : ι) (s : Set X) : BumpCovering ι X s where contrapose! hx rw [mem_singleton_iff] at hx simp [hx] - nonneg' := le_update_iff.2 ⟨fun x => zero_le_one, fun _ _ => le_rfl⟩ + nonneg' := le_update_iff.2 ⟨fun _ => zero_le_one, fun _ _ => le_rfl⟩ 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]⟩ @@ -506,7 +506,7 @@ def toPartitionOfUnity : PartitionOfUnity ι X s where toFun i := ⟨f.toPOUFun i, f.continuous_toPOUFun i⟩ locallyFinite' := f.locallyFinite.subset f.support_toPOUFun_subset nonneg' i x := - mul_nonneg (f.nonneg i x) (finprod_cond_nonneg fun j hj => sub_nonneg.2 <| f.le_one j x) + mul_nonneg (f.nonneg i x) (finprod_cond_nonneg fun j _ => sub_nonneg.2 <| f.le_one j x) sum_eq_one' x hx := by simp only [ContinuousMap.coe_mk, sum_toPOUFun_eq, sub_eq_self] apply finprod_eq_zero (fun i => 1 - f i x) (f.ind x hx) diff --git a/Mathlib/Topology/SeparatedMap.lean b/Mathlib/Topology/SeparatedMap.lean index 67633a9c6069db..471b35d8086e1d 100644 --- a/Mathlib/Topology/SeparatedMap.lean +++ b/Mathlib/Topology/SeparatedMap.lean @@ -174,11 +174,25 @@ section eqLocus variable {f : X → Y} {g₁ g₂ : A → X} (h₁ : Continuous g₁) (h₂ : Continuous g₂) include h₁ h₂ +#adaptation_note +/-- +After https://github.com/leanprover/lean4/pull/5338, +the unused variable linter flags `g` here, +but it is used in a type ascription to direct `fun_prop`. +-/ +set_option linter.unusedVariables false in theorem IsSeparatedMap.isClosed_eqLocus (sep : IsSeparatedMap f) (he : f ∘ g₁ = f ∘ g₂) : IsClosed {a | g₁ a = g₂ a} := let g : A → f.Pullback f := fun a ↦ ⟨⟨g₁ a, g₂ a⟩, congr_fun he a⟩ (isSeparatedMap_iff_isClosed_diagonal.mp sep).preimage (by fun_prop : Continuous g) +#adaptation_note +/-- +After https://github.com/leanprover/lean4/pull/5338, +the unused variable linter flags `g` here, +but it is used in a type ascription to direct `fun_prop`. +-/ +set_option linter.unusedVariables false in theorem IsLocallyInjective.isOpen_eqLocus (inj : IsLocallyInjective f) (he : f ∘ g₁ = f ∘ g₂) : IsOpen {a | g₁ a = g₂ a} := let g : A → f.Pullback f := fun a ↦ ⟨⟨g₁ a, g₂ a⟩, congr_fun he a⟩ diff --git a/Mathlib/Topology/Separation.lean b/Mathlib/Topology/Separation.lean index 98e4bd5cdac2f9..4d39f3cd21001c 100644 --- a/Mathlib/Topology/Separation.lean +++ b/Mathlib/Topology/Separation.lean @@ -309,7 +309,7 @@ theorem inseparable_eq_eq [T0Space X] : Inseparable = @Eq X := theorem TopologicalSpace.IsTopologicalBasis.inseparable_iff {b : Set (Set X)} (hb : IsTopologicalBasis b) {x y : X} : Inseparable x y ↔ ∀ s ∈ b, (x ∈ s ↔ y ∈ s) := - ⟨fun h s hs ↦ inseparable_iff_forall_open.1 h _ (hb.isOpen hs), + ⟨fun h _ hs ↦ inseparable_iff_forall_open.1 h _ (hb.isOpen hs), fun h ↦ hb.nhds_hasBasis.eq_of_same_basis <| by convert hb.nhds_hasBasis using 2 exact and_congr_right (h _)⟩ @@ -1724,7 +1724,7 @@ theorem eqOn_closure₂' [T2Space Z] {s : Set X} {t : Set Y} {f g : X → Y → (hg₂ : ∀ y, Continuous fun x => g x y) : ∀ x ∈ closure s, ∀ y ∈ closure t, f x y = g x y := suffices closure s ⊆ ⋂ y ∈ closure t, { x | f x y = g x y } by simpa only [subset_def, mem_iInter] (closure_minimal fun x hx => mem_iInter₂.2 <| Set.EqOn.closure (h x hx) (hf₁ _) (hg₁ _)) <| - isClosed_biInter fun y _ => isClosed_eq (hf₂ _) (hg₂ _) + isClosed_biInter fun _ _ => isClosed_eq (hf₂ _) (hg₂ _) theorem eqOn_closure₂ [T2Space Z] {s : Set X} {t : Set Y} {f g : X → Y → Z} (h : ∀ x ∈ s, ∀ y ∈ t, f x y = g x y) (hf : Continuous (uncurry f)) diff --git a/Mathlib/Topology/Sequences.lean b/Mathlib/Topology/Sequences.lean index 2e0e2de87c3658..f19fd89e1847da 100644 --- a/Mathlib/Topology/Sequences.lean +++ b/Mathlib/Topology/Sequences.lean @@ -192,7 +192,7 @@ theorem continuous_iff_seqContinuous [SequentialSpace X] {f : X → Y} : theorem SequentialSpace.coinduced [SequentialSpace X] {Y} (f : X → Y) : @SequentialSpace Y (.coinduced f ‹_›) := letI : TopologicalSpace Y := .coinduced f ‹_› - ⟨fun s hs ↦ isClosed_coinduced.2 (hs.preimage continuous_coinduced_rng.seqContinuous).isClosed⟩ + ⟨fun _ hs ↦ isClosed_coinduced.2 (hs.preimage continuous_coinduced_rng.seqContinuous).isClosed⟩ protected theorem SequentialSpace.iSup {X} {ι : Sort*} {t : ι → TopologicalSpace X} (h : ∀ i, @SequentialSpace X (t i)) : @SequentialSpace X (⨆ i, t i) := by diff --git a/Mathlib/Topology/Sets/Opens.lean b/Mathlib/Topology/Sets/Opens.lean index cf7ecc4c6353c6..1b2ffd4204a29e 100644 --- a/Mathlib/Topology/Sets/Opens.lean +++ b/Mathlib/Topology/Sets/Opens.lean @@ -343,7 +343,7 @@ theorem isCompactElement_iff (s : Opens α) : def comap (f : C(α, β)) : FrameHom (Opens β) (Opens α) where toFun s := ⟨f ⁻¹' s, s.2.preimage f.continuous⟩ map_sSup' s := ext <| by simp only [coe_sSup, preimage_iUnion, biUnion_image, coe_mk] - map_inf' a b := rfl + map_inf' _ _ := rfl map_top' := rfl @[simp] @@ -381,8 +381,8 @@ theorem comap_injective [T0Space β] : Injective (comap : C(α, β) → FrameHom def _root_.Homeomorph.opensCongr (f : α ≃ₜ β) : Opens α ≃o Opens β where toFun := Opens.comap f.symm.toContinuousMap invFun := Opens.comap f.toContinuousMap - left_inv := fun U => ext <| f.toEquiv.preimage_symm_preimage _ - right_inv := fun U => ext <| f.toEquiv.symm_preimage_preimage _ + left_inv := fun _ => ext <| f.toEquiv.preimage_symm_preimage _ + right_inv := fun _ => ext <| f.toEquiv.symm_preimage_preimage _ map_rel_iff' := by simp only [← SetLike.coe_subset_coe]; exact f.symm.surjective.preimage_subset_preimage_iff diff --git a/Mathlib/Topology/Sheaves/LocalPredicate.lean b/Mathlib/Topology/Sheaves/LocalPredicate.lean index c9213520cca769..8d32b5f87a342d 100644 --- a/Mathlib/Topology/Sheaves/LocalPredicate.lean +++ b/Mathlib/Topology/Sheaves/LocalPredicate.lean @@ -148,7 +148,7 @@ theorem PrelocalPredicate.sheafifyOf {T : X → Type v} {P : PrelocalPredicate T @[simps!] def subpresheafToTypes (P : PrelocalPredicate T) : Presheaf (Type v) X where obj U := { f : ∀ x : U.unop , T x // P.pred f } - map {U V} i f := ⟨fun x => f.1 (i.unop x), P.res i.unop f.1 f.2⟩ + map {_ _} i f := ⟨fun x => f.1 (i.unop x), P.res i.unop f.1 f.2⟩ namespace subpresheafToTypes @@ -157,7 +157,7 @@ variable (P : PrelocalPredicate T) /-- The natural transformation including the subpresheaf of functions satisfying a local predicate into the presheaf of all functions. -/ -def subtype : subpresheafToTypes P ⟶ presheafToTypes X T where app U f := f.1 +def subtype : subpresheafToTypes P ⟶ presheafToTypes X T where app _ f := f.1 open TopCat.Presheaf diff --git a/Mathlib/Topology/Sheaves/Operations.lean b/Mathlib/Topology/Sheaves/Operations.lean index c982c9d8e36183..4eec0af579f980 100644 --- a/Mathlib/Topology/Sheaves/Operations.lean +++ b/Mathlib/Topology/Sheaves/Operations.lean @@ -46,7 +46,7 @@ variable {F : X.Presheaf CommRingCat.{w}} (G : F.SubmonoidPresheaf) /-- The localization of a presheaf of `CommRing`s with respect to a `SubmonoidPresheaf`. -/ protected noncomputable def SubmonoidPresheaf.localizationPresheaf : X.Presheaf CommRingCat where obj U := CommRingCat.of <| Localization (G.obj U) - map {U V} i := CommRingCat.ofHom <| IsLocalization.map _ (F.map i) (G.map i) + map {_ _} i := CommRingCat.ofHom <| IsLocalization.map _ (F.map i) (G.map i) map_id U := by simp_rw [F.map_id] ext x diff --git a/Mathlib/Topology/Sheaves/PresheafOfFunctions.lean b/Mathlib/Topology/Sheaves/PresheafOfFunctions.lean index 6049ed866f9d83..ce0908cb259703 100644 --- a/Mathlib/Topology/Sheaves/PresheafOfFunctions.lean +++ b/Mathlib/Topology/Sheaves/PresheafOfFunctions.lean @@ -43,11 +43,11 @@ There is no requirement that the functions are continuous, here. -/ def presheafToTypes (T : X → Type v) : X.Presheaf (Type v) where obj U := ∀ x : U.unop, T x - map {U V} i g := fun x : V.unop => g (i.unop x) + map {_ V} i g := fun x : V.unop => g (i.unop x) map_id U := by ext g rfl - map_comp {U V W} i j := rfl + map_comp {_ _ _} _ _ := rfl @[simp] theorem presheafToTypes_obj {T : X → Type v} {U : (Opens X)ᵒᵖ} : @@ -70,11 +70,11 @@ There is no requirement that the functions are continuous, here. -/ def presheafToType (T : Type v) : X.Presheaf (Type v) where obj U := U.unop → T - map {U V} i g := g ∘ i.unop + map {_ _} i g := g ∘ i.unop map_id U := by ext g rfl - map_comp {U V W} i j := rfl + map_comp {_ _ _} _ _ := rfl @[simp] theorem presheafToType_obj {T : Type v} {U : (Opens X)ᵒᵖ} : @@ -136,18 +136,18 @@ from `X : TopCat` to `R : TopCommRingCat` form a commutative ring, functorial in def commRingYoneda : TopCommRingCat.{u} ⥤ TopCat.{u}ᵒᵖ ⥤ CommRingCat.{u} where obj R := { obj := fun X => continuousFunctions X R - map := fun {X Y} f => continuousFunctions.pullback f R + map := fun {_ _} f => continuousFunctions.pullback f R map_id := fun X => by ext rfl - map_comp := fun {X Y Z} f g => rfl } - map {R S} φ := + map_comp := fun {_ _ _} _ _ => rfl } + map {_ _} φ := { app := fun X => continuousFunctions.map X φ - naturality := fun X Y f => rfl } + naturality := fun _ _ _ => rfl } map_id X := by ext rfl - map_comp {X Y Z} f g := rfl + map_comp {_ _ _} _ _ := rfl /-- The presheaf (of commutative rings), consisting of functions on an open set `U ⊆ X` with values in some topological commutative ring `T`. diff --git a/Mathlib/Topology/Sheaves/SheafCondition/PairwiseIntersections.lean b/Mathlib/Topology/Sheaves/SheafCondition/PairwiseIntersections.lean index 9677da6bdf32ec..890f87cb372760 100644 --- a/Mathlib/Topology/Sheaves/SheafCondition/PairwiseIntersections.lean +++ b/Mathlib/Topology/Sheaves/SheafCondition/PairwiseIntersections.lean @@ -103,7 +103,7 @@ of open sets below some `U i`. @[simps] def pairwiseToOpensLeCover : Pairwise ι ⥤ OpensLeCover U where obj := pairwiseToOpensLeCoverObj U - map {V W} i := pairwiseToOpensLeCoverMap U i + map {_ _} i := pairwiseToOpensLeCoverMap U i instance (V : OpensLeCover U) : Nonempty (StructuredArrow V (pairwiseToOpensLeCover U)) := ⟨@StructuredArrow.mk _ _ _ _ _ (single V.index) _ V.homToIndex⟩ diff --git a/Mathlib/Topology/Sheaves/Skyscraper.lean b/Mathlib/Topology/Sheaves/Skyscraper.lean index a1bfb6d86c2efc..55935827687758 100644 --- a/Mathlib/Topology/Sheaves/Skyscraper.lean +++ b/Mathlib/Topology/Sheaves/Skyscraper.lean @@ -308,7 +308,7 @@ theorem fromStalk_to_skyscraper {𝓕 : Presheaf C X} {c : C} (f : 𝓕.stalk p @[simps] protected def unit : 𝟭 (Presheaf C X) ⟶ Presheaf.stalkFunctor C p₀ ⋙ skyscraperPresheafFunctor p₀ where - app 𝓕 := toSkyscraperPresheaf _ <| 𝟙 _ + app _ := toSkyscraperPresheaf _ <| 𝟙 _ naturality 𝓕 𝓖 f := by ext U; dsimp split_ifs with h @@ -381,7 +381,7 @@ def stalkSkyscraperSheafAdjunction [HasColimits C] : counit := StalkSkyscraperPresheafAdjunctionAuxs.counit p₀ left_triangle_components X := ((skyscraperPresheafStalkAdjunction p₀).left_triangle_components X.val) - right_triangle_components Y := + right_triangle_components _ := Sheaf.Hom.ext ((skyscraperPresheafStalkAdjunction p₀).right_triangle_components _) instance [HasColimits C] : (skyscraperSheafFunctor p₀ : C ⥤ Sheaf C X).IsRightAdjoint := diff --git a/Mathlib/Topology/ShrinkingLemma.lean b/Mathlib/Topology/ShrinkingLemma.lean index 49f989797cbfcb..b88d57ecb32332 100644 --- a/Mathlib/Topology/ShrinkingLemma.lean +++ b/Mathlib/Topology/ShrinkingLemma.lean @@ -74,8 +74,8 @@ protected theorem subset (v : PartialRefinement u s) (i : ι) : v i ⊆ u i := b open Classical in instance : PartialOrder (PartialRefinement u s) where le v₁ v₂ := v₁.carrier ⊆ v₂.carrier ∧ ∀ i ∈ v₁.carrier, v₁ i = v₂ i - le_refl v := ⟨Subset.refl _, fun _ _ => rfl⟩ - le_trans v₁ v₂ v₃ h₁₂ h₂₃ := + le_refl _ := ⟨Subset.refl _, fun _ _ => rfl⟩ + le_trans _ _ _ h₁₂ h₂₃ := ⟨Subset.trans h₁₂.1 h₂₃.1, fun i hi => (h₁₂.2 i hi).trans (h₂₃.2 i <| h₁₂.1 hi)⟩ le_antisymm v₁ v₂ h₁₂ h₂₁ := have hc : v₁.carrier = v₂.carrier := Subset.antisymm h₁₂.1 h₂₁.1 diff --git a/Mathlib/Topology/UniformSpace/AbsoluteValue.lean b/Mathlib/Topology/UniformSpace/AbsoluteValue.lean index 55efcadaf71331..b10faf84a84eff 100644 --- a/Mathlib/Topology/UniformSpace/AbsoluteValue.lean +++ b/Mathlib/Topology/UniformSpace/AbsoluteValue.lean @@ -34,7 +34,7 @@ variable {R : Type*} [CommRing R] (abv : AbsoluteValue R 𝕜) /-- The uniform structure coming from an absolute value. -/ def uniformSpace : UniformSpace R := .ofFun (fun x y => abv (y - x)) (by simp) (fun x y => abv.map_sub y x) - (fun x y z => (abv.sub_le _ _ _).trans_eq (add_comm _ _)) + (fun _ _ _ => (abv.sub_le _ _ _).trans_eq (add_comm _ _)) fun ε ε0 => ⟨ε / 2, half_pos ε0, fun _ h₁ _ h₂ => (add_lt_add h₁ h₂).trans_eq (add_halves ε)⟩ theorem hasBasis_uniformity : diff --git a/Mathlib/Topology/UniformSpace/Basic.lean b/Mathlib/Topology/UniformSpace/Basic.lean index caab9ab1db8cb7..f720fa95c4ba65 100644 --- a/Mathlib/Topology/UniformSpace/Basic.lean +++ b/Mathlib/Topology/UniformSpace/Basic.lean @@ -836,7 +836,7 @@ theorem closure_eq_inter_uniformity {t : Set (α × α)} : closure t = ⋂ d ∈ closure t = ⋂ (V) (_ : V ∈ 𝓤 α ∧ SymmetricRel V), V ○ t ○ V := closure_eq_uniformity t _ = ⋂ V ∈ 𝓤 α, V ○ t ○ V := Eq.symm <| - UniformSpace.hasBasis_symmetric.biInter_mem fun V₁ V₂ hV => + UniformSpace.hasBasis_symmetric.biInter_mem fun _ _ hV => compRel_mono (compRel_mono hV Subset.rfl) hV _ = ⋂ V ∈ 𝓤 α, V ○ (t ○ V) := by simp only [compRel_assoc] @@ -854,7 +854,7 @@ theorem uniformity_eq_uniformity_interior : 𝓤 α = (𝓤 α).lift' interior : hs_comp ⟨x, h₁, y, h₂, h₃⟩ have : interior d ∈ 𝓤 α := by filter_upwards [hs] using this simp [this]) - fun s hs => ((𝓤 α).lift' interior).sets_of_superset (mem_lift' hs) interior_subset + fun _ hs => ((𝓤 α).lift' interior).sets_of_superset (mem_lift' hs) interior_subset theorem interior_mem_uniformity {s : Set (α × α)} (hs : s ∈ 𝓤 α) : interior s ∈ 𝓤 α := by rw [uniformity_eq_uniformity_interior]; exact mem_lift' hs @@ -1570,7 +1570,7 @@ the diagonal in the second part. -/ instance Sum.instUniformSpace : UniformSpace (α ⊕ β) where uniformity := map (fun p : α × α => (inl p.1, inl p.2)) (𝓤 α) ⊔ map (fun p : β × β => (inr p.1, inr p.2)) (𝓤 β) - symm := fun s hs ↦ ⟨symm_le_uniformity hs.1, symm_le_uniformity hs.2⟩ + symm := fun _ hs ↦ ⟨symm_le_uniformity hs.1, symm_le_uniformity hs.2⟩ comp := fun s hs ↦ by rcases comp_mem_uniformity_sets hs.1 with ⟨tα, htα, Htα⟩ rcases comp_mem_uniformity_sets hs.2 with ⟨tβ, htβ, Htβ⟩ diff --git a/Mathlib/Topology/UniformSpace/Compact.lean b/Mathlib/Topology/UniformSpace/Compact.lean index 175d8d75ed9464..b9bc2156e776bb 100644 --- a/Mathlib/Topology/UniformSpace/Compact.lean +++ b/Mathlib/Topology/UniformSpace/Compact.lean @@ -70,7 +70,7 @@ theorem unique_uniformity_of_compact [t : TopologicalSpace γ] [CompactSpace γ] /-- The unique uniform structure inducing a given compact topological structure. -/ def uniformSpaceOfCompactT2 [TopologicalSpace γ] [CompactSpace γ] [T2Space γ] : UniformSpace γ where uniformity := 𝓝ˢ (diagonal γ) - symm := continuous_swap.tendsto_nhdsSet fun x => Eq.symm + symm := continuous_swap.tendsto_nhdsSet fun _ => Eq.symm comp := by /- This is the difficult part of the proof. We need to prove that, for each neighborhood `W` of the diagonal `Δ`, there exists a smaller neighborhood `V` such that `V ○ V ⊆ W`. diff --git a/Mathlib/Topology/UniformSpace/Completion.lean b/Mathlib/Topology/UniformSpace/Completion.lean index 4d1365e733ea34..3e599158acc97a 100644 --- a/Mathlib/Topology/UniformSpace/Completion.lean +++ b/Mathlib/Topology/UniformSpace/Completion.lean @@ -111,7 +111,7 @@ private theorem comp_gen : (((𝓤 α).lift' gen).lift' fun s => compRel s s) · exact monotone_gen · exact monotone_id.compRel monotone_id _ ≤ (𝓤 α).lift' fun s => gen <| compRel s s := - lift'_mono' fun s _hs => compRel_gen_gen_subset_gen_compRel + lift'_mono' fun _ _hs => compRel_gen_gen_subset_gen_compRel _ = ((𝓤 α).lift' fun s : Set (α × α) => compRel s s).lift' gen := by rw [lift'_lift'_assoc] · exact monotone_id.compRel monotone_id @@ -211,8 +211,8 @@ instance : CompleteSpace (CauchyFilter α) := completeSpace_extension isUniformInducing_pureCauchy denseRange_pureCauchy fun f hf => let f' : CauchyFilter α := ⟨f, hf⟩ have : map pureCauchy f ≤ (𝓤 <| CauchyFilter α).lift' (preimage (Prod.mk f')) := - le_lift'.2 fun s hs => - let ⟨t, ht₁, (ht₂ : gen t ⊆ s)⟩ := (mem_lift'_sets monotone_gen).mp hs + le_lift'.2 fun _ hs => + let ⟨t, ht₁, ht₂⟩ := (mem_lift'_sets monotone_gen).mp hs let ⟨t', ht', (h : t' ×ˢ t' ⊆ t)⟩ := mem_prod_same_iff.mp (hf.right ht₁) have : t' ⊆ { y : α | (f', pureCauchy y) ∈ gen t } := fun x hx => (f ×ˢ pure x).sets_of_superset (prod_mem_prod ht' hx) h diff --git a/Mathlib/Topology/UniformSpace/UniformConvergence.lean b/Mathlib/Topology/UniformSpace/UniformConvergence.lean index 3d5593d33b3b16..6fe642c53f2e42 100644 --- a/Mathlib/Topology/UniformSpace/UniformConvergence.lean +++ b/Mathlib/Topology/UniformSpace/UniformConvergence.lean @@ -598,11 +598,11 @@ theorem tendstoLocallyUniformlyOn_iff_tendstoLocallyUniformly_comp_coe : tendstoLocallyUniformlyOn_iff_forall_tendsto, ← map_nhds_subtype_val, prod_map_right]; rfl protected theorem TendstoUniformlyOn.tendstoLocallyUniformlyOn (h : TendstoUniformlyOn F f p s) : - TendstoLocallyUniformlyOn F f p s := fun u hu x _ => + TendstoLocallyUniformlyOn F f p s := fun u hu _ _ => ⟨s, self_mem_nhdsWithin, by simpa using h u hu⟩ protected theorem TendstoUniformly.tendstoLocallyUniformly (h : TendstoUniformly F f p) : - TendstoLocallyUniformly F f p := fun u hu x => ⟨univ, univ_mem, by simpa using h u hu⟩ + TendstoLocallyUniformly F f p := fun u hu _ => ⟨univ, univ_mem, by simpa using h u hu⟩ theorem TendstoLocallyUniformlyOn.mono (h : TendstoLocallyUniformlyOn F f p s) (h' : s' ⊆ s) : TendstoLocallyUniformlyOn F f p s' := by diff --git a/Mathlib/Topology/UniformSpace/UniformEmbedding.lean b/Mathlib/Topology/UniformSpace/UniformEmbedding.lean index d70f7fb955c8f2..36dee5874506e1 100644 --- a/Mathlib/Topology/UniformSpace/UniformEmbedding.lean +++ b/Mathlib/Topology/UniformSpace/UniformEmbedding.lean @@ -483,34 +483,34 @@ theorem completeSpace_extension {m : β → α} (hm : IsUniformInducing m) (dens ⟨fun {f : Filter α} (hf : Cauchy f) => let p : Set (α × α) → Set α → Set α := fun s t => { y : α | ∃ x : α, x ∈ t ∧ (x, y) ∈ s } let g := (𝓤 α).lift fun s => f.lift' (p s) - have mp₀ : Monotone p := fun a b h t s ⟨x, xs, xa⟩ => ⟨x, xs, h xa⟩ - have mp₁ : ∀ {s}, Monotone (p s) := fun h x ⟨y, ya, yxs⟩ => ⟨y, h ya, yxs⟩ - have : f ≤ g := le_iInf₂ fun s hs => le_iInf₂ fun t ht => + have mp₀ : Monotone p := fun _ _ h _ _ ⟨x, xs, xa⟩ => ⟨x, xs, h xa⟩ + have mp₁ : ∀ {s}, Monotone (p s) := fun h _ ⟨y, ya, yxs⟩ => ⟨y, h ya, yxs⟩ + have : f ≤ g := le_iInf₂ fun _ hs => le_iInf₂ fun _ ht => le_principal_iff.mpr <| mem_of_superset ht fun x hx => ⟨x, hx, refl_mem_uniformity hs⟩ have : NeBot g := hf.left.mono this have : NeBot (comap m g) := - comap_neBot fun t ht => + comap_neBot fun _ ht => let ⟨t', ht', ht_mem⟩ := (mem_lift_sets <| monotone_lift' monotone_const mp₀).mp ht - let ⟨t'', ht'', ht'_sub⟩ := (mem_lift'_sets mp₁).mp ht_mem - let ⟨x, (hx : x ∈ t'')⟩ := hf.left.nonempty_of_mem ht'' + let ⟨_, ht'', ht'_sub⟩ := (mem_lift'_sets mp₁).mp ht_mem + let ⟨x, hx⟩ := hf.left.nonempty_of_mem ht'' have h₀ : NeBot (𝓝[range m] x) := dense.nhdsWithin_neBot x have h₁ : { y | (x, y) ∈ t' } ∈ 𝓝[range m] x := @mem_inf_of_left α (𝓝 x) (𝓟 (range m)) _ <| mem_nhds_left x ht' have h₂ : range m ∈ 𝓝[range m] x := @mem_inf_of_right α (𝓝 x) (𝓟 (range m)) _ <| Subset.refl _ have : { y | (x, y) ∈ t' } ∩ range m ∈ 𝓝[range m] x := @inter_mem α (𝓝[range m] x) _ _ h₁ h₂ - let ⟨y, xyt', b, b_eq⟩ := h₀.nonempty_of_mem this + let ⟨_, xyt', b, b_eq⟩ := h₀.nonempty_of_mem this ⟨b, b_eq.symm ▸ ht'_sub ⟨x, hx, xyt'⟩⟩ have : Cauchy g := - ⟨‹NeBot g›, fun s hs => - let ⟨s₁, hs₁, (comp_s₁ : compRel s₁ s₁ ⊆ s)⟩ := comp_mem_uniformity_sets hs - let ⟨s₂, hs₂, (comp_s₂ : compRel s₂ s₂ ⊆ s₁)⟩ := comp_mem_uniformity_sets hs₁ + ⟨‹NeBot g›, fun _ hs => + let ⟨s₁, hs₁, comp_s₁⟩ := comp_mem_uniformity_sets hs + let ⟨s₂, hs₂, comp_s₂⟩ := comp_mem_uniformity_sets hs₁ let ⟨t, ht, (prod_t : t ×ˢ t ⊆ s₂)⟩ := mem_prod_same_iff.mp (hf.right hs₂) have hg₁ : p (preimage Prod.swap s₁) t ∈ g := mem_lift (symm_le_uniformity hs₁) <| @mem_lift' α α f _ t ht have hg₂ : p s₂ t ∈ g := mem_lift hs₂ <| @mem_lift' α α f _ t ht have hg : p (Prod.swap ⁻¹' s₁) t ×ˢ p s₂ t ∈ g ×ˢ g := @prod_mem_prod α α _ _ g g hg₁ hg₂ - (g ×ˢ g).sets_of_superset hg fun ⟨a, b⟩ ⟨⟨c₁, c₁t, hc₁⟩, ⟨c₂, c₂t, hc₂⟩⟩ => + (g ×ˢ g).sets_of_superset hg fun ⟨_, _⟩ ⟨⟨c₁, c₁t, hc₁⟩, ⟨c₂, c₂t, hc₂⟩⟩ => have : (c₁, c₂) ∈ t ×ˢ t := ⟨c₁t, c₂t⟩ comp_s₁ <| prod_mk_mem_compRel hc₁ <| comp_s₂ <| prod_mk_mem_compRel (prod_t this) hc₂⟩ have : Cauchy (Filter.comap m g) := ‹Cauchy g›.comap' (le_of_eq hm.comap_uniformity) ‹_› diff --git a/Mathlib/Topology/VectorBundle/Hom.lean b/Mathlib/Topology/VectorBundle/Hom.lean index 3b7a3339e41051..1cf522715e0746 100644 --- a/Mathlib/Topology/VectorBundle/Hom.lean +++ b/Mathlib/Topology/VectorBundle/Hom.lean @@ -109,8 +109,8 @@ def continuousLinearMap : invFun p := ⟨p.1, .comp (e₂.symmL 𝕜₂ p.1) (p.2.comp (e₁.continuousLinearMapAt 𝕜₁ p.1))⟩ source := Bundle.TotalSpace.proj ⁻¹' (e₁.baseSet ∩ e₂.baseSet) target := (e₁.baseSet ∩ e₂.baseSet) ×ˢ Set.univ - map_source' := fun ⟨x, L⟩ h => ⟨h, Set.mem_univ _⟩ - map_target' := fun ⟨x, f⟩ h => h.1 + map_source' := fun ⟨_, _⟩ h => ⟨h, Set.mem_univ _⟩ + map_target' := fun ⟨_, _⟩ h => h.1 left_inv' := fun ⟨x, L⟩ ⟨h₁, h₂⟩ => by simp only [TotalSpace.mk_inj] ext (v : E₁ x) diff --git a/scripts/fix_unused.py b/scripts/fix_unused.py new file mode 100755 index 00000000000000..9bc5679bfdf579 --- /dev/null +++ b/scripts/fix_unused.py @@ -0,0 +1,80 @@ +#! /usr/bin/env python3 + +# https://chatgpt.com/share/66f4e420-66bc-8001-8349-ce3cfb4f23c3 +# Usage: lake build | scripts/fix_unused.py +import re +import sys + +# Parse warning messages and extract file paths, line, column, and variable names +def parse_warnings(warning_lines): + pattern = r"warning: (\S+):(\d+):(\d+): unused variable `([^`]+)`" + warnings = [] + + for line in warning_lines: + match = re.match(pattern, line) + if match: + file_path, line_num, col_num, var_name = match.groups() + warnings.append({ + 'file_path': file_path, + 'line_num': int(line_num), + 'col_num': int(col_num), + 'var_name': var_name + }) + + return warnings + +# Find the actual column index, adjusting for multi-byte Unicode characters +def find_column_index(line, target_col): + """Return the index in the string where the column equals target_col, ignoring visual width.""" + current_col = 0 + for idx, char in enumerate(line): + # Move one "logical column" per character (whether wide or narrow) + if current_col >= target_col: + return idx + current_col += 1 + return len(line) # Return the end if column number exceeds the line length + +# Replace variable with `_` at the specified line and column in the file +def process_file(file_path, edits): + with open(file_path, 'r', encoding='utf-8') as f: + lines = f.readlines() + + for edit in sorted(edits, key=lambda e: e['line_num'], reverse=True): + line_num = edit['line_num'] - 1 + col_num = edit['col_num'] - 1 + var_name = edit['var_name'] + line = lines[line_num] + + # Find the actual starting column index for the variable + actual_col = find_column_index(line, col_num) + + # Replace the variable with `_` + new_line = line[:actual_col] + line[actual_col:].replace(var_name, '_', 1) + lines[line_num] = new_line + + with open(file_path, 'w', encoding='utf-8') as f: + f.writelines(lines) + +# Process all warnings +def process_warnings(warnings): + file_edits = {} + + # Organize warnings by file + for warning in warnings: + file_path = warning['file_path'] + if file_path not in file_edits: + file_edits[file_path] = [] + file_edits[file_path].append(warning) + + # Process each file in reverse order of warnings + for file_path, edits in file_edits.items(): + print(f"Processing {file_path} with {len(edits)} edits.") + process_file(file_path, edits) + +if __name__ == "__main__": + # Read warning lines from stdin + warning_lines = sys.stdin.read().splitlines() + + # Parse and process warnings + warnings = parse_warnings(warning_lines) + process_warnings(warnings) From d839ff4a5d3357058d15dc4ab398095635b2549a Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Mon, 14 Oct 2024 12:17:41 +0000 Subject: [PATCH 108/425] feat(OrderOfElement): add `isOfFinOrder_pow` (#17636) Also add `IsOfFinOrder.of_pow` and a missing `@[to_additive]`. --- Mathlib/GroupTheory/OrderOfElement.lean | 26 ++++++++++++++++++++----- Mathlib/GroupTheory/Torsion.lean | 2 +- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Mathlib/GroupTheory/OrderOfElement.lean b/Mathlib/GroupTheory/OrderOfElement.lean index 9e33d48b219962..1d4e34b53c52d3 100644 --- a/Mathlib/GroupTheory/OrderOfElement.lean +++ b/Mathlib/GroupTheory/OrderOfElement.lean @@ -80,11 +80,32 @@ theorem not_isOfFinOrder_of_injective_pow {x : G} (h : Injective fun n : ℕ => rw [h hnx] at hn_pos exact irrefl 0 hn_pos +/-- 1 is of finite order in any monoid. -/ +@[to_additive (attr := simp) "0 is of finite order in any additive monoid."] +theorem IsOfFinOrder.one : IsOfFinOrder (1 : G) := + isOfFinOrder_iff_pow_eq_one.mpr ⟨1, Nat.one_pos, one_pow 1⟩ + +@[to_additive (attr := deprecated (since := "2024-10-11"))] +alias isOfFinOrder_one := IsOfFinOrder.one + +@[to_additive] lemma IsOfFinOrder.pow {n : ℕ} : IsOfFinOrder a → IsOfFinOrder (a ^ n) := by simp_rw [isOfFinOrder_iff_pow_eq_one] rintro ⟨m, hm, ha⟩ exact ⟨m, hm, by simp [pow_right_comm _ n, ha]⟩ +@[to_additive] +lemma IsOfFinOrder.of_pow {n : ℕ} (h : IsOfFinOrder (a ^ n)) (hn : n ≠ 0) : IsOfFinOrder a := by + rw [isOfFinOrder_iff_pow_eq_one] at * + rcases h with ⟨m, hm, ha⟩ + exact ⟨n * m, by positivity, by rwa [pow_mul]⟩ + +@[to_additive (attr := simp)] +lemma isOfFinOrder_pow {n : ℕ} : IsOfFinOrder (a ^ n) ↔ IsOfFinOrder a ∨ n = 0 := by + rcases Decidable.eq_or_ne n 0 with rfl | hn + · simp + · exact ⟨fun h ↦ .inl <| h.of_pow hn, fun h ↦ (h.resolve_right hn).pow⟩ + /-- Elements of finite order are of finite order in submonoids. -/ @[to_additive "Elements of finite order are of finite order in submonoids."] theorem Submonoid.isOfFinOrder_coe {H : Submonoid G} {x : H} : @@ -107,11 +128,6 @@ theorem IsOfFinOrder.apply {η : Type*} {Gs : η → Type*} [∀ i, Monoid (Gs i obtain ⟨n, npos, hn⟩ := h.exists_pow_eq_one exact fun _ => isOfFinOrder_iff_pow_eq_one.mpr ⟨n, npos, (congr_fun hn.symm _).symm⟩ -/-- 1 is of finite order in any monoid. -/ -@[to_additive "0 is of finite order in any additive monoid."] -theorem isOfFinOrder_one : IsOfFinOrder (1 : G) := - isOfFinOrder_iff_pow_eq_one.mpr ⟨1, Nat.one_pos, one_pow 1⟩ - /-- The submonoid generated by an element is a group if that element has finite order. -/ @[to_additive "The additive submonoid generated by an element is an additive group if that element has finite order."] diff --git a/Mathlib/GroupTheory/Torsion.lean b/Mathlib/GroupTheory/Torsion.lean index 08d223f5db3bad..2c301f72a0d331 100644 --- a/Mathlib/GroupTheory/Torsion.lean +++ b/Mathlib/GroupTheory/Torsion.lean @@ -161,7 +161,7 @@ namespace CommMonoid @[to_additive addTorsion "The torsion submonoid of an additive commutative monoid."] def torsion : Submonoid G where carrier := { x | IsOfFinOrder x } - one_mem' := isOfFinOrder_one + one_mem' := IsOfFinOrder.one mul_mem' hx hy := hx.mul hy variable {G} From fada3e872a81d97a6f7879ae26d13d6be17a9f2a Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Mon, 14 Oct 2024 12:17:43 +0000 Subject: [PATCH 109/425] chore: no need to suppress Aesop warning (#17716) --- lakefile.lean | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lakefile.lean b/lakefile.lean index a4a09667f6c2b7..59b2eae8ed37f9 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -35,8 +35,7 @@ abbrev mathlibOnlyLinters : Array LeanOption := #[ ⟨`linter.style.longLine, true⟩, ⟨`linter.style.longFile, .ofNat 1500⟩, ⟨`linter.style.missingEnd, true⟩, - ⟨`linter.style.setOption, true⟩, - ⟨`aesop.warn.applyIff, false⟩ -- This became a problem after https://github.com/leanprover-community/aesop/commit/29cf094e84ae9852f0011b47b6ddc684ffe4be5f + ⟨`linter.style.setOption, true⟩ ] /-- These options are passed as `leanOptions` to building mathlib, as well as the From 8731f7f43cd397273c86a8a355c33d8416170ced Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Mon, 14 Oct 2024 23:41:51 +1100 Subject: [PATCH 110/425] mess --- Mathlib/Algebra/BigOperators/Group/List.lean | 6 +++--- Mathlib/Data/List/Join.lean | 9 +++++++-- Mathlib/Data/List/Permutation.lean | 6 ++++-- Mathlib/Data/List/Range.lean | 4 +++- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Group/List.lean b/Mathlib/Algebra/BigOperators/Group/List.lean index 6a1a5fb8af68e6..2834111d23dae1 100644 --- a/Mathlib/Algebra/BigOperators/Group/List.lean +++ b/Mathlib/Algebra/BigOperators/Group/List.lean @@ -32,9 +32,9 @@ section Defs /-- Product of a list. `List.prod [a, b, c] = ((1 * a) * b) * c` -/ -@[to_additive "Sum of a list.\n\n`List.sum [a, b, c] = ((0 + a) + b) + c`"] +@[to_additive existing] def prod {α} [Mul α] [One α] : List α → α := - foldl (· * ·) 1 + foldr (· * ·) 1 /-- The alternating sum of a list. -/ def alternatingSum {G : Type*} [Zero G] [Add G] [Neg G] : List G → G @@ -55,7 +55,7 @@ section MulOneClass variable [MulOneClass M] {l : List M} {a : M} -@[to_additive (attr := simp)] +@[to_additive existing, simp] theorem prod_nil : ([] : List M).prod = 1 := rfl diff --git a/Mathlib/Data/List/Join.lean b/Mathlib/Data/List/Join.lean index 69f2b6f90ab34b..f2654bd4d45a66 100644 --- a/Mathlib/Data/List/Join.lean +++ b/Mathlib/Data/List/Join.lean @@ -19,19 +19,24 @@ variable {α β : Type*} namespace List +set_option linter.deprecated false + @[deprecated (since := "2024-02-25")] alias join_filter_isEmpty_eq_false := join_filter_not_isEmpty /-- See `List.length_join` for the corresponding statement using `List.sum`. -/ +@[deprecated length_join (since := "2024-10-14")] lemma length_join' (L : List (List α)) : length (join L) = Nat.sum (map length L) := by induction L <;> [rfl; simp only [*, join, map, Nat.sum_cons, length_append]] /-- See `List.countP_join` for the corresponding statement using `List.sum`. -/ +@[deprecated countP_join (since := "2024-10-14")] lemma countP_join' (p : α → Bool) : ∀ L : List (List α), countP p L.join = Nat.sum (L.map (countP p)) | [] => rfl | a :: l => by rw [join, countP_append, map_cons, Nat.sum_cons, countP_join' _ l] /-- See `List.count_join` for the corresponding statement using `List.sum`. -/ +@[deprecated count_join (since := "2024-10-14")] lemma count_join' [BEq α] (L : List (List α)) (a : α) : L.join.count a = Nat.sum (L.map (count a)) := countP_join' _ _ @@ -55,7 +60,7 @@ theorem take_sum_join' (L : List (List α)) (i : ℕ) : L.join.take (Nat.sum ((L.map length).take i)) = (L.take i).join := by induction L generalizing i · simp - · cases i <;> simp [take_append, *] + · cases i <;> simp [take_append, *, Nat.sum_nil, Nat.sum_cons] /-- In a join, dropping all the elements up to an index which is the sum of the lengths of the first `i` sublists, is the same as taking the join after dropping the first `i` sublists. @@ -65,7 +70,7 @@ theorem drop_sum_join' (L : List (List α)) (i : ℕ) : L.join.drop (Nat.sum ((L.map length).take i)) = (L.drop i).join := by induction L generalizing i · simp - · cases i <;> simp [drop_append, *] + · cases i <;> simp [drop_append, *, Nat.sum_nil, Nat.sum_cons] /-- Taking only the first `i+1` elements in a list, and then dropping the first `i` ones, one is left with a list of length `1` made of the `i`-th element of the original list. -/ diff --git a/Mathlib/Data/List/Permutation.lean b/Mathlib/Data/List/Permutation.lean index dfa46749569338..30ce3ef2d58bbd 100644 --- a/Mathlib/Data/List/Permutation.lean +++ b/Mathlib/Data/List/Permutation.lean @@ -179,20 +179,22 @@ theorem mem_foldr_permutationsAux2 {t : α} {ts : List α} {r L : List (List α) simp only [mem_permutationsAux2', ← this, or_comm, and_left_comm, mem_append, mem_bind, append_assoc, cons_append, exists_prop] +set_option linter.deprecated false in theorem length_foldr_permutationsAux2 (t : α) (ts : List α) (r L : List (List α)) : length (foldr (fun y r => (permutationsAux2 t ts r y id).2) r L) = Nat.sum (map length L) + length r := by simp [foldr_permutationsAux2, Function.comp_def, length_permutationsAux2, length_bind'] +set_option linter.deprecated false in theorem length_foldr_permutationsAux2' (t : α) (ts : List α) (r L : List (List α)) (n) (H : ∀ l ∈ L, length l = n) : length (foldr (fun y r => (permutationsAux2 t ts r y id).2) r L) = n * length L + length r := by rw [length_foldr_permutationsAux2, (_ : Nat.sum (map length L) = n * length L)] induction' L with l L ih - · simp + · simp [Nat.sum_nil] have sum_map : Nat.sum (map length L) = n * length L := ih fun l m => H l (mem_cons_of_mem _ m) have length_l : length l = n := H _ (mem_cons_self _ _) - simp [sum_map, length_l, Nat.mul_add, Nat.add_comm, mul_succ] + simp [sum_map, length_l, Nat.mul_add, Nat.add_comm, mul_succ, Nat.sum_cons] @[simp] theorem permutationsAux_nil (is : List α) : permutationsAux [] is = [] := by diff --git a/Mathlib/Data/List/Range.lean b/Mathlib/Data/List/Range.lean index 63ca906ece4716..58d2902213f1b9 100644 --- a/Mathlib/Data/List/Range.lean +++ b/Mathlib/Data/List/Range.lean @@ -141,11 +141,13 @@ theorem ranges_length (l : List ℕ) : intro s _ simp only [Function.comp_apply, length_map] +set_option linter.deprecated false in /-- See `List.ranges_join` for the version about `List.sum`. -/ lemma ranges_join' : ∀ l : List ℕ, l.ranges.join = range (Nat.sum l) | [] => rfl - | a :: l => by simp only [sum_cons, join, ← map_join, ranges_join', range_add] + | a :: l => by simp only [Nat.sum_cons, join, ← map_join, ranges_join', range_add] +set_option linter.deprecated false in /-- Any entry of any member of `l.ranges` is strictly smaller than `Nat.sum l`. See `List.mem_mem_ranges_iff_lt_sum` for the version about `List.sum`. -/ lemma mem_mem_ranges_iff_lt_natSum (l : List ℕ) {n : ℕ} : From a67c43d5b23965bb3f37259d2c1460380face4e2 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Mon, 14 Oct 2024 13:31:30 +0000 Subject: [PATCH 111/425] chore(Algebra.Group.Units): split into `Defs` and `Basic` file (#17724) The criteria for including a result in `Algebra.Group.Unit.Defs`: * Can it be defined with only `Defs` imports? * Is it needed for a subsequent `def` or `instance`? --- Mathlib.lean | 3 +- Mathlib/Algebra/BigOperators/Group/List.lean | 2 +- Mathlib/Algebra/Divisibility/Units.lean | 2 +- Mathlib/Algebra/FreeMonoid/Basic.lean | 2 +- Mathlib/Algebra/Group/Action/Units.lean | 3 +- Mathlib/Algebra/Group/Int.lean | 1 + Mathlib/Algebra/Group/Nat.lean | 1 - Mathlib/Algebra/Group/Opposite.lean | 2 +- Mathlib/Algebra/Group/Semiconj/Units.lean | 2 +- Mathlib/Algebra/Group/Submonoid/Basic.lean | 2 +- Mathlib/Algebra/Group/Units/Basic.lean | 478 ++++++++++++++++++ .../Group/{Units.lean => Units/Defs.lean} | 400 +-------------- Mathlib/Algebra/Group/Units/Hom.lean | 2 +- .../Algebra/GroupWithZero/Units/Basic.lean | 2 +- .../Algebra/Order/Monoid/Canonical/Defs.lean | 2 +- Mathlib/Algebra/Order/Monoid/Units.lean | 2 +- .../Algebra/Order/Ring/Unbundled/Basic.lean | 2 +- Mathlib/Algebra/Regular/Basic.lean | 2 +- Mathlib/CategoryTheory/Endomorphism.lean | 2 +- Mathlib/Data/Nat/Bits.lean | 1 + Mathlib/RingTheory/LocalRing/Defs.lean | 2 +- Mathlib/RingTheory/MvPowerSeries/Inverse.lean | 2 +- Mathlib/Tactic/FieldSimp.lean | 2 +- scripts/noshake.json | 1 + 24 files changed, 503 insertions(+), 417 deletions(-) create mode 100644 Mathlib/Algebra/Group/Units/Basic.lean rename Mathlib/Algebra/Group/{Units.lean => Units/Defs.lean} (61%) diff --git a/Mathlib.lean b/Mathlib.lean index 9a96bd0fcb9476..c52aa83a52c782 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -299,7 +299,8 @@ import Mathlib.Algebra.Group.TypeTags import Mathlib.Algebra.Group.ULift import Mathlib.Algebra.Group.UniqueProds.Basic import Mathlib.Algebra.Group.UniqueProds.VectorSpace -import Mathlib.Algebra.Group.Units +import Mathlib.Algebra.Group.Units.Basic +import Mathlib.Algebra.Group.Units.Defs import Mathlib.Algebra.Group.Units.Equiv import Mathlib.Algebra.Group.Units.Hom import Mathlib.Algebra.Group.WithOne.Basic diff --git a/Mathlib/Algebra/BigOperators/Group/List.lean b/Mathlib/Algebra/BigOperators/Group/List.lean index 4bfe960292e47f..7eb37c116a4055 100644 --- a/Mathlib/Algebra/BigOperators/Group/List.lean +++ b/Mathlib/Algebra/BigOperators/Group/List.lean @@ -7,7 +7,7 @@ import Mathlib.Algebra.Divisibility.Basic import Mathlib.Algebra.Group.Int import Mathlib.Algebra.Group.Nat import Mathlib.Algebra.Group.Opposite -import Mathlib.Algebra.Group.Units +import Mathlib.Algebra.Group.Units.Basic import Mathlib.Data.List.Perm import Mathlib.Data.List.ProdSigma import Mathlib.Data.List.Range diff --git a/Mathlib/Algebra/Divisibility/Units.lean b/Mathlib/Algebra/Divisibility/Units.lean index 5f8d41a57b2450..4afd288068460f 100644 --- a/Mathlib/Algebra/Divisibility/Units.lean +++ b/Mathlib/Algebra/Divisibility/Units.lean @@ -5,7 +5,7 @@ Authors: Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Amelia Livingston, Neil Strickland, Aaron Anderson -/ import Mathlib.Algebra.Divisibility.Basic -import Mathlib.Algebra.Group.Units +import Mathlib.Algebra.Group.Units.Basic /-! # Divisibility and units diff --git a/Mathlib/Algebra/FreeMonoid/Basic.lean b/Mathlib/Algebra/FreeMonoid/Basic.lean index f3a0b039e5ff23..c2a87d24b37d2d 100644 --- a/Mathlib/Algebra/FreeMonoid/Basic.lean +++ b/Mathlib/Algebra/FreeMonoid/Basic.lean @@ -5,7 +5,7 @@ Authors: Simon Hudon, Yury Kudryashov -/ import Mathlib.Algebra.BigOperators.Group.List import Mathlib.Algebra.Group.Action.Defs -import Mathlib.Algebra.Group.Units +import Mathlib.Algebra.Group.Units.Basic /-! # Free monoid over a given alphabet diff --git a/Mathlib/Algebra/Group/Action/Units.lean b/Mathlib/Algebra/Group/Action/Units.lean index 3894d2568e51a5..9092b7ac468d89 100644 --- a/Mathlib/Algebra/Group/Action/Units.lean +++ b/Mathlib/Algebra/Group/Action/Units.lean @@ -4,7 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Eric Wieser -/ import Mathlib.Algebra.Group.Action.Defs -import Mathlib.Algebra.Group.Units +import Mathlib.Algebra.Group.Basic +import Mathlib.Algebra.Group.Units.Defs /-! # Group actions on and by `Mˣ` diff --git a/Mathlib/Algebra/Group/Int.lean b/Mathlib/Algebra/Group/Int.lean index e30cfc2cfe4b0b..7748ade5f05332 100644 --- a/Mathlib/Algebra/Group/Int.lean +++ b/Mathlib/Algebra/Group/Int.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Jeremy Avigad -/ import Mathlib.Algebra.Group.Nat +import Mathlib.Algebra.Group.Units.Basic import Mathlib.Data.Int.Sqrt /-! diff --git a/Mathlib/Algebra/Group/Nat.lean b/Mathlib/Algebra/Group/Nat.lean index 8ccb770e633d4f..16a01aab071b6f 100644 --- a/Mathlib/Algebra/Group/Nat.lean +++ b/Mathlib/Algebra/Group/Nat.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Floris van Doorn, Leonardo de Moura, Jeremy Avigad, Mario Carneiro -/ import Mathlib.Algebra.Group.Even -import Mathlib.Algebra.Group.Units import Mathlib.Data.Nat.Sqrt /-! diff --git a/Mathlib/Algebra/Group/Opposite.lean b/Mathlib/Algebra/Group/Opposite.lean index 63a5dce25bc2f2..147c42a01e34a8 100644 --- a/Mathlib/Algebra/Group/Opposite.lean +++ b/Mathlib/Algebra/Group/Opposite.lean @@ -6,7 +6,7 @@ Authors: Kenny Lau import Mathlib.Algebra.Group.Commute.Defs import Mathlib.Algebra.Group.Equiv.Basic import Mathlib.Algebra.Group.InjSurj -import Mathlib.Algebra.Group.Units +import Mathlib.Algebra.Group.Units.Defs import Mathlib.Algebra.Opposites import Mathlib.Data.Int.Cast.Defs import Mathlib.Tactic.Spread diff --git a/Mathlib/Algebra/Group/Semiconj/Units.lean b/Mathlib/Algebra/Group/Semiconj/Units.lean index 5a31a5e5130e91..45c46f379e4c24 100644 --- a/Mathlib/Algebra/Group/Semiconj/Units.lean +++ b/Mathlib/Algebra/Group/Semiconj/Units.lean @@ -6,7 +6,7 @@ Authors: Yury Kudryashov -- Some proofs and docs came from mathlib3 `src/algebra/commute.lean` (c) Neil Strickland import Mathlib.Algebra.Group.Semiconj.Defs -import Mathlib.Algebra.Group.Units +import Mathlib.Algebra.Group.Units.Basic /-! # Semiconjugate elements of a semigroup diff --git a/Mathlib/Algebra/Group/Submonoid/Basic.lean b/Mathlib/Algebra/Group/Submonoid/Basic.lean index 9cc78b55ddff2d..69cb89258578ac 100644 --- a/Mathlib/Algebra/Group/Submonoid/Basic.lean +++ b/Mathlib/Algebra/Group/Submonoid/Basic.lean @@ -6,7 +6,7 @@ Amelia Livingston, Yury Kudryashov -/ import Mathlib.Algebra.Group.Hom.Defs import Mathlib.Algebra.Group.Subsemigroup.Basic -import Mathlib.Algebra.Group.Units +import Mathlib.Algebra.Group.Units.Defs /-! # Submonoids: definition and `CompleteLattice` structure diff --git a/Mathlib/Algebra/Group/Units/Basic.lean b/Mathlib/Algebra/Group/Units/Basic.lean new file mode 100644 index 00000000000000..594ac233066ca6 --- /dev/null +++ b/Mathlib/Algebra/Group/Units/Basic.lean @@ -0,0 +1,478 @@ +/- +Copyright (c) 2017 Kenny Lau. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Kenny Lau, Mario Carneiro, Johannes Hölzl, Chris Hughes, Jens Wagemaker, Jon Eugster +-/ +import Mathlib.Algebra.Group.Basic +import Mathlib.Algebra.Group.Commute.Defs +import Mathlib.Algebra.Group.Units.Defs +import Mathlib.Logic.Unique +import Mathlib.Tactic.Nontriviality +import Mathlib.Tactic.Lift +import Mathlib.Tactic.Subsingleton + +/-! +# Units (i.e., invertible elements) of a monoid + +An element of a `Monoid` is a unit if it has a two-sided inverse. +This file contains the basic lemmas on units in a monoid, especially focussing on singleton types +and unique types. + +## TODO + +The results here should be used to golf the basic `Group` lemmas. +-/ + +assert_not_exists Multiplicative +assert_not_exists MonoidWithZero +assert_not_exists DenselyOrdered + +open Function + +universe u + +variable {α : Type u} + +section HasElem + +@[to_additive] +theorem unique_one {α : Type*} [Unique α] [One α] : default = (1 : α) := + Unique.default_eq 1 + +end HasElem + +namespace Units +section Monoid +variable [Monoid α] + +variable (a b c : αˣ) {u : αˣ} + +@[to_additive (attr := simp)] +theorem mul_inv_cancel_right (a : α) (b : αˣ) : a * b * ↑b⁻¹ = a := by + rw [mul_assoc, mul_inv, mul_one] + +@[to_additive (attr := simp)] +theorem inv_mul_cancel_right (a : α) (b : αˣ) : a * ↑b⁻¹ * b = a := by + rw [mul_assoc, inv_mul, mul_one] + +@[to_additive (attr := simp)] +theorem mul_right_inj (a : αˣ) {b c : α} : (a : α) * b = a * c ↔ b = c := + ⟨fun h => by simpa only [inv_mul_cancel_left] using congr_arg (fun x : α => ↑(a⁻¹ : αˣ) * x) h, + congr_arg _⟩ + +@[to_additive (attr := simp)] +theorem mul_left_inj (a : αˣ) {b c : α} : b * a = c * a ↔ b = c := + ⟨fun h => by simpa only [mul_inv_cancel_right] using congr_arg (fun x : α => x * ↑(a⁻¹ : αˣ)) h, + congr_arg (· * a.val)⟩ + +@[to_additive] +theorem eq_mul_inv_iff_mul_eq {a b : α} : a = b * ↑c⁻¹ ↔ a * c = b := + ⟨fun h => by rw [h, inv_mul_cancel_right], fun h => by rw [← h, mul_inv_cancel_right]⟩ + +@[to_additive] +theorem eq_inv_mul_iff_mul_eq {a c : α} : a = ↑b⁻¹ * c ↔ ↑b * a = c := + ⟨fun h => by rw [h, mul_inv_cancel_left], fun h => by rw [← h, inv_mul_cancel_left]⟩ + +@[to_additive] +theorem mul_inv_eq_iff_eq_mul {a c : α} : a * ↑b⁻¹ = c ↔ a = c * b := + ⟨fun h => by rw [← h, inv_mul_cancel_right], fun h => by rw [h, mul_inv_cancel_right]⟩ + +-- Porting note: have to explicitly type annotate the 1 +@[to_additive] +protected theorem inv_eq_of_mul_eq_one_left {a : α} (h : a * u = 1) : ↑u⁻¹ = a := + calc + ↑u⁻¹ = (1 : α) * ↑u⁻¹ := by rw [one_mul] + _ = a := by rw [← h, mul_inv_cancel_right] + + +-- Porting note: have to explicitly type annotate the 1 +@[to_additive] +protected theorem inv_eq_of_mul_eq_one_right {a : α} (h : ↑u * a = 1) : ↑u⁻¹ = a := + calc + ↑u⁻¹ = ↑u⁻¹ * (1 : α) := by rw [mul_one] + _ = a := by rw [← h, inv_mul_cancel_left] + + +@[to_additive] +protected theorem eq_inv_of_mul_eq_one_left {a : α} (h : ↑u * a = 1) : a = ↑u⁻¹ := + (Units.inv_eq_of_mul_eq_one_right h).symm + +@[to_additive] +protected theorem eq_inv_of_mul_eq_one_right {a : α} (h : a * u = 1) : a = ↑u⁻¹ := + (Units.inv_eq_of_mul_eq_one_left h).symm + +@[to_additive (attr := simp)] +theorem mul_inv_eq_one {a : α} : a * ↑u⁻¹ = 1 ↔ a = u := + ⟨inv_inv u ▸ Units.eq_inv_of_mul_eq_one_right, fun h => mul_inv_of_eq h.symm⟩ + +@[to_additive (attr := simp)] +theorem inv_mul_eq_one {a : α} : ↑u⁻¹ * a = 1 ↔ ↑u = a := + ⟨inv_inv u ▸ Units.inv_eq_of_mul_eq_one_right, inv_mul_of_eq⟩ + +@[to_additive] +theorem mul_eq_one_iff_eq_inv {a : α} : a * u = 1 ↔ a = ↑u⁻¹ := by rw [← mul_inv_eq_one, inv_inv] + +@[to_additive] +theorem mul_eq_one_iff_inv_eq {a : α} : ↑u * a = 1 ↔ ↑u⁻¹ = a := by rw [← inv_mul_eq_one, inv_inv] + +@[to_additive] +theorem inv_unique {u₁ u₂ : αˣ} (h : (↑u₁ : α) = ↑u₂) : (↑u₁⁻¹ : α) = ↑u₂⁻¹ := + Units.inv_eq_of_mul_eq_one_right <| by rw [h, u₂.mul_inv] + +end Monoid + +end Units + +section Monoid + +variable [Monoid α] {a : α} + +@[simp] +theorem divp_left_inj (u : αˣ) {a b : α} : a /ₚ u = b /ₚ u ↔ a = b := + Units.mul_left_inj _ + +/- Porting note: to match the mathlib3 behavior, this needs to have higher simp +priority than eq_divp_iff_mul_eq. -/ +@[field_simps 1010] +theorem divp_eq_iff_mul_eq {x : α} {u : αˣ} {y : α} : x /ₚ u = y ↔ y * u = x := + u.mul_left_inj.symm.trans <| by rw [divp_mul_cancel]; exact ⟨Eq.symm, Eq.symm⟩ + +@[field_simps] +theorem eq_divp_iff_mul_eq {x : α} {u : αˣ} {y : α} : x = y /ₚ u ↔ x * u = y := by + rw [eq_comm, divp_eq_iff_mul_eq] + +theorem divp_eq_one_iff_eq {a : α} {u : αˣ} : a /ₚ u = 1 ↔ a = u := + (Units.mul_left_inj u).symm.trans <| by rw [divp_mul_cancel, one_mul] + +/-- Used for `field_simp` to deal with inverses of units. This form of the lemma +is essential since `field_simp` likes to use `inv_eq_one_div` to rewrite +`↑u⁻¹ = ↑(1 / u)`. +-/ +@[field_simps] +theorem inv_eq_one_divp' (u : αˣ) : ((1 / u : αˣ) : α) = 1 /ₚ u := by + rw [one_div, one_divp] + +end Monoid + +namespace LeftCancelMonoid + +variable [LeftCancelMonoid α] [Subsingleton αˣ] {a b : α} + +@[to_additive] +protected theorem eq_one_of_mul_right (h : a * b = 1) : a = 1 := + congr_arg Units.inv <| Subsingleton.elim (Units.mk _ _ (by + rw [← mul_left_cancel_iff (a := a), ← mul_assoc, h, one_mul, mul_one]) h) 1 + +@[to_additive] +protected theorem eq_one_of_mul_left (h : a * b = 1) : b = 1 := by + rwa [LeftCancelMonoid.eq_one_of_mul_right h, one_mul] at h + +@[to_additive (attr := simp)] +protected theorem mul_eq_one : a * b = 1 ↔ a = 1 ∧ b = 1 := + ⟨fun h => ⟨LeftCancelMonoid.eq_one_of_mul_right h, LeftCancelMonoid.eq_one_of_mul_left h⟩, by + rintro ⟨rfl, rfl⟩ + exact mul_one _⟩ + +@[to_additive] +protected theorem mul_ne_one : a * b ≠ 1 ↔ a ≠ 1 ∨ b ≠ 1 := by rw [not_iff_comm]; simp + +end LeftCancelMonoid + +namespace RightCancelMonoid + +variable [RightCancelMonoid α] [Subsingleton αˣ] {a b : α} + +@[to_additive] +protected theorem eq_one_of_mul_right (h : a * b = 1) : a = 1 := + congr_arg Units.inv <| Subsingleton.elim (Units.mk _ _ (by + rw [← mul_right_cancel_iff (a := b), mul_assoc, h, one_mul, mul_one]) h) 1 + +@[to_additive] +protected theorem eq_one_of_mul_left (h : a * b = 1) : b = 1 := by + rwa [RightCancelMonoid.eq_one_of_mul_right h, one_mul] at h + +@[to_additive (attr := simp)] +protected theorem mul_eq_one : a * b = 1 ↔ a = 1 ∧ b = 1 := + ⟨fun h => ⟨RightCancelMonoid.eq_one_of_mul_right h, RightCancelMonoid.eq_one_of_mul_left h⟩, by + rintro ⟨rfl, rfl⟩ + exact mul_one _⟩ + +@[to_additive] +protected theorem mul_ne_one : a * b ≠ 1 ↔ a ≠ 1 ∨ b ≠ 1 := by rw [not_iff_comm]; simp + +end RightCancelMonoid + +section CancelMonoid + +variable [CancelMonoid α] [Subsingleton αˣ] {a b : α} + +@[to_additive] +theorem eq_one_of_mul_right' (h : a * b = 1) : a = 1 := LeftCancelMonoid.eq_one_of_mul_right h + +@[to_additive] +theorem eq_one_of_mul_left' (h : a * b = 1) : b = 1 := LeftCancelMonoid.eq_one_of_mul_left h + +@[to_additive] +theorem mul_eq_one' : a * b = 1 ↔ a = 1 ∧ b = 1 := LeftCancelMonoid.mul_eq_one + +@[to_additive] +theorem mul_ne_one' : a * b ≠ 1 ↔ a ≠ 1 ∨ b ≠ 1 := LeftCancelMonoid.mul_ne_one + +end CancelMonoid + +section CommMonoid + +variable [CommMonoid α] + +@[field_simps] +theorem divp_mul_eq_mul_divp (x y : α) (u : αˣ) : x /ₚ u * y = x * y /ₚ u := by + rw [divp, divp, mul_right_comm] + +-- Theoretically redundant as `field_simp` lemma. +@[field_simps] +theorem divp_eq_divp_iff {x y : α} {ux uy : αˣ} : x /ₚ ux = y /ₚ uy ↔ x * uy = y * ux := by + rw [divp_eq_iff_mul_eq, divp_mul_eq_mul_divp, divp_eq_iff_mul_eq] + +-- Theoretically redundant as `field_simp` lemma. +@[field_simps] +theorem divp_mul_divp (x y : α) (ux uy : αˣ) : x /ₚ ux * (y /ₚ uy) = x * y /ₚ (ux * uy) := by + rw [divp_mul_eq_mul_divp, divp_assoc', divp_divp_eq_divp_mul] + +variable [Subsingleton αˣ] {a b : α} + +@[to_additive] +theorem eq_one_of_mul_right (h : a * b = 1) : a = 1 := + congr_arg Units.inv <| Subsingleton.elim (Units.mk _ _ (by rwa [mul_comm]) h) 1 + +@[to_additive] +theorem eq_one_of_mul_left (h : a * b = 1) : b = 1 := + congr_arg Units.inv <| Subsingleton.elim (Units.mk _ _ h <| by rwa [mul_comm]) 1 + +@[to_additive (attr := simp)] +theorem mul_eq_one : a * b = 1 ↔ a = 1 ∧ b = 1 := + ⟨fun h => ⟨eq_one_of_mul_right h, eq_one_of_mul_left h⟩, by + rintro ⟨rfl, rfl⟩ + exact mul_one _⟩ + +@[to_additive] theorem mul_ne_one : a * b ≠ 1 ↔ a ≠ 1 ∨ b ≠ 1 := by rw [not_iff_comm]; simp + +end CommMonoid + +/-! +# `IsUnit` predicate +-/ + + +section IsUnit + +variable {M : Type*} {N : Type*} + +@[to_additive (attr := nontriviality)] +theorem isUnit_of_subsingleton [Monoid M] [Subsingleton M] (a : M) : IsUnit a := + ⟨⟨a, a, by subsingleton, by subsingleton⟩, rfl⟩ + +@[to_additive] +instance [Monoid M] : CanLift M Mˣ Units.val IsUnit := + { prf := fun _ ↦ id } + +/-- A subsingleton `Monoid` has a unique unit. -/ +@[to_additive "A subsingleton `AddMonoid` has a unique additive unit."] +instance [Monoid M] [Subsingleton M] : Unique Mˣ where + uniq _ := Units.val_eq_one.mp (by subsingleton) + +section Monoid +variable [Monoid M] {a b : M} + +theorem units_eq_one [Subsingleton Mˣ] (u : Mˣ) : u = 1 := by subsingleton + +end Monoid + +namespace IsUnit + +section Monoid + +variable [Monoid M] {a b c : M} + +@[to_additive] +theorem mul_left_inj (h : IsUnit a) : b * a = c * a ↔ b = c := + let ⟨u, hu⟩ := h + hu ▸ u.mul_left_inj + +@[to_additive] +theorem mul_right_inj (h : IsUnit a) : a * b = a * c ↔ b = c := + let ⟨u, hu⟩ := h + hu ▸ u.mul_right_inj + +@[to_additive] +protected theorem mul_left_cancel (h : IsUnit a) : a * b = a * c → b = c := + h.mul_right_inj.1 + +@[to_additive] +protected theorem mul_right_cancel (h : IsUnit b) : a * b = c * b → a = c := + h.mul_left_inj.1 + +@[to_additive] +protected theorem mul_right_injective (h : IsUnit a) : Injective (a * ·) := + fun _ _ => h.mul_left_cancel + +@[to_additive] +protected theorem mul_left_injective (h : IsUnit b) : Injective (· * b) := + fun _ _ => h.mul_right_cancel + +@[to_additive] +theorem isUnit_iff_mulLeft_bijective {a : M} : + IsUnit a ↔ Function.Bijective (a * ·) := + ⟨fun h ↦ ⟨h.mul_right_injective, fun y ↦ ⟨h.unit⁻¹ * y, by simp [← mul_assoc]⟩⟩, fun h ↦ + ⟨⟨a, _, (h.2 1).choose_spec, h.1 + (by simpa [mul_assoc] using congr_arg (· * a) (h.2 1).choose_spec)⟩, rfl⟩⟩ + +@[to_additive] +theorem isUnit_iff_mulRight_bijective {a : M} : + IsUnit a ↔ Function.Bijective (· * a) := + ⟨fun h ↦ ⟨h.mul_left_injective, fun y ↦ ⟨y * h.unit⁻¹, by simp [mul_assoc]⟩⟩, + fun h ↦ ⟨⟨a, _, h.1 (by simpa [mul_assoc] using congr_arg (a * ·) (h.2 1).choose_spec), + (h.2 1).choose_spec⟩, rfl⟩⟩ + +end Monoid + +section DivisionMonoid +variable [DivisionMonoid α] {a b c : α} + +@[to_additive (attr := simp)] +protected lemma mul_inv_cancel_right (h : IsUnit b) (a : α) : a * b * b⁻¹ = a := + h.unit'.mul_inv_cancel_right _ + +@[to_additive (attr := simp)] +protected lemma inv_mul_cancel_right (h : IsUnit b) (a : α) : a * b⁻¹ * b = a := + h.unit'.inv_mul_cancel_right _ + +@[to_additive] +protected lemma eq_mul_inv_iff_mul_eq (h : IsUnit c) : a = b * c⁻¹ ↔ a * c = b := + h.unit'.eq_mul_inv_iff_mul_eq + +@[to_additive] +protected lemma eq_inv_mul_iff_mul_eq (h : IsUnit b) : a = b⁻¹ * c ↔ b * a = c := + h.unit'.eq_inv_mul_iff_mul_eq + +@[to_additive] +protected lemma inv_mul_eq_iff_eq_mul (h : IsUnit a) : a⁻¹ * b = c ↔ b = a * c := + h.unit'.inv_mul_eq_iff_eq_mul + +@[to_additive] +protected lemma mul_inv_eq_iff_eq_mul (h : IsUnit b) : a * b⁻¹ = c ↔ a = c * b := + h.unit'.mul_inv_eq_iff_eq_mul + +@[to_additive] +protected lemma mul_inv_eq_one (h : IsUnit b) : a * b⁻¹ = 1 ↔ a = b := + @Units.mul_inv_eq_one _ _ h.unit' _ + +@[to_additive] +protected lemma inv_mul_eq_one (h : IsUnit a) : a⁻¹ * b = 1 ↔ a = b := + @Units.inv_mul_eq_one _ _ h.unit' _ + +@[to_additive] +protected lemma mul_eq_one_iff_eq_inv (h : IsUnit b) : a * b = 1 ↔ a = b⁻¹ := + @Units.mul_eq_one_iff_eq_inv _ _ h.unit' _ + +@[to_additive] +protected lemma mul_eq_one_iff_inv_eq (h : IsUnit a) : a * b = 1 ↔ a⁻¹ = b := + @Units.mul_eq_one_iff_inv_eq _ _ h.unit' _ + +@[to_additive (attr := simp)] +protected lemma div_mul_cancel (h : IsUnit b) (a : α) : a / b * b = a := by + rw [div_eq_mul_inv, h.inv_mul_cancel_right] + +@[to_additive (attr := simp)] +protected lemma mul_div_cancel_right (h : IsUnit b) (a : α) : a * b / b = a := by + rw [div_eq_mul_inv, h.mul_inv_cancel_right] + +@[to_additive] +protected lemma mul_one_div_cancel (h : IsUnit a) : a * (1 / a) = 1 := by simp [h] + +@[to_additive] +protected lemma one_div_mul_cancel (h : IsUnit a) : 1 / a * a = 1 := by simp [h] + +@[to_additive] +protected lemma div_left_inj (h : IsUnit c) : a / c = b / c ↔ a = b := by + simp only [div_eq_mul_inv] + exact Units.mul_left_inj h.inv.unit' + +@[to_additive] +protected lemma div_eq_iff (h : IsUnit b) : a / b = c ↔ a = c * b := by + rw [div_eq_mul_inv, h.mul_inv_eq_iff_eq_mul] + +@[to_additive] +protected lemma eq_div_iff (h : IsUnit c) : a = b / c ↔ a * c = b := by + rw [div_eq_mul_inv, h.eq_mul_inv_iff_mul_eq] + +@[to_additive] +protected lemma div_eq_of_eq_mul (h : IsUnit b) : a = c * b → a / b = c := + h.div_eq_iff.2 + +@[to_additive] +protected lemma eq_div_of_mul_eq (h : IsUnit c) : a * c = b → a = b / c := + h.eq_div_iff.2 + +@[to_additive] +protected lemma div_eq_one_iff_eq (h : IsUnit b) : a / b = 1 ↔ a = b := + ⟨eq_of_div_eq_one, fun hab => hab.symm ▸ h.div_self⟩ + +@[to_additive] +protected lemma div_mul_left (h : IsUnit b) : b / (a * b) = 1 / a := by + rw [h.div_mul_cancel_right, one_div] + +@[to_additive] +protected lemma mul_mul_div (a : α) (h : IsUnit b) : a * b * (1 / b) = a := by simp [h] + +end DivisionMonoid + +section DivisionCommMonoid +variable [DivisionCommMonoid α] {a b c d : α} + +@[to_additive] +protected lemma div_mul_right (h : IsUnit a) (b : α) : a / (a * b) = 1 / b := by + rw [mul_comm, h.div_mul_left] + +@[to_additive] +protected lemma mul_div_cancel_left (h : IsUnit a) (b : α) : a * b / a = b := by + rw [mul_comm, h.mul_div_cancel_right] + +@[to_additive] +protected lemma mul_div_cancel (h : IsUnit a) (b : α) : a * (b / a) = b := by + rw [mul_comm, h.div_mul_cancel] + +@[to_additive] +protected lemma mul_eq_mul_of_div_eq_div (hb : IsUnit b) (hd : IsUnit d) + (a c : α) (h : a / b = c / d) : a * d = c * b := by + rw [← mul_one a, ← hb.div_self, ← mul_comm_div, h, div_mul_eq_mul_div, hd.div_mul_cancel] + +@[to_additive] +protected lemma div_eq_div_iff (hb : IsUnit b) (hd : IsUnit d) : + a / b = c / d ↔ a * d = c * b := by + rw [← (hb.mul hd).mul_left_inj, ← mul_assoc, hb.div_mul_cancel, ← mul_assoc, mul_right_comm, + hd.div_mul_cancel] + +@[to_additive] +protected lemma div_div_cancel (h : IsUnit a) : a / (a / b) = b := by + rw [div_div_eq_mul_div, h.mul_div_cancel_left] + +@[to_additive] +protected lemma div_div_cancel_left (h : IsUnit a) : a / b / a = b⁻¹ := by + rw [div_eq_mul_inv, div_eq_mul_inv, mul_right_comm, h.mul_inv_cancel, one_mul] + +end DivisionCommMonoid +end IsUnit + +-- namespace +end IsUnit + +attribute [deprecated div_mul_cancel_right (since := "2024-03-20")] IsUnit.div_mul_left +attribute [deprecated sub_add_cancel_right (since := "2024-03-20")] IsAddUnit.sub_add_left +attribute [deprecated div_mul_cancel_left (since := "2024-03-20")] IsUnit.div_mul_right +attribute [deprecated sub_add_cancel_left (since := "2024-03-20")] IsAddUnit.sub_add_right +-- The names `IsUnit.mul_div_cancel` and `IsAddUnit.add_sub_cancel` have been reused +-- @[deprecated (since := "2024-03-20")] alias IsUnit.mul_div_cancel := IsUnit.mul_div_cancel_right +-- @[deprecated (since := "2024-03-20")] +-- alias IsAddUnit.add_sub_cancel := IsAddUnit.add_sub_cancel_right +@[deprecated (since := "2024-03-20")] alias IsUnit.mul_div_cancel' := IsUnit.mul_div_cancel +@[deprecated (since := "2024-03-20")] alias IsAddUnit.add_sub_cancel' := IsAddUnit.add_sub_cancel diff --git a/Mathlib/Algebra/Group/Units.lean b/Mathlib/Algebra/Group/Units/Defs.lean similarity index 61% rename from Mathlib/Algebra/Group/Units.lean rename to Mathlib/Algebra/Group/Units/Defs.lean index 1c93daf4e3123e..3e67d4529c21e5 100644 --- a/Mathlib/Algebra/Group/Units.lean +++ b/Mathlib/Algebra/Group/Units/Defs.lean @@ -3,12 +3,9 @@ Copyright (c) 2017 Kenny Lau. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Kenny Lau, Mario Carneiro, Johannes Hölzl, Chris Hughes, Jens Wagemaker, Jon Eugster -/ -import Mathlib.Algebra.Group.Basic +import Mathlib.Algebra.Group.Defs import Mathlib.Algebra.Group.Commute.Defs -import Mathlib.Logic.Unique -import Mathlib.Tactic.Nontriviality -import Mathlib.Tactic.Lift -import Mathlib.Tactic.Subsingleton +import Mathlib.Logic.Function.Basic /-! # Units (i.e., invertible elements) of a monoid @@ -82,14 +79,6 @@ structure AddUnits (α : Type u) [AddMonoid α] where attribute [to_additive] Units attribute [coe] AddUnits.val -section HasElem - -@[to_additive] -theorem unique_one {α : Type*} [Unique α] [One α] : default = (1 : α) := - Unique.default_eq 1 - -end HasElem - namespace Units section Monoid variable [Monoid α] @@ -231,64 +220,10 @@ theorem mul_inv_cancel_left (a : αˣ) (b : α) : (a : α) * (↑a⁻¹ * b) = b theorem inv_mul_cancel_left (a : αˣ) (b : α) : (↑a⁻¹ : α) * (a * b) = b := by rw [← mul_assoc, inv_mul, one_mul] -@[to_additive (attr := simp)] -theorem mul_inv_cancel_right (a : α) (b : αˣ) : a * b * ↑b⁻¹ = a := by - rw [mul_assoc, mul_inv, mul_one] - -@[to_additive (attr := simp)] -theorem inv_mul_cancel_right (a : α) (b : αˣ) : a * ↑b⁻¹ * b = a := by - rw [mul_assoc, inv_mul, mul_one] - -@[to_additive (attr := simp)] -theorem mul_right_inj (a : αˣ) {b c : α} : (a : α) * b = a * c ↔ b = c := - ⟨fun h => by simpa only [inv_mul_cancel_left] using congr_arg (fun x : α => ↑(a⁻¹ : αˣ) * x) h, - congr_arg _⟩ - -@[to_additive (attr := simp)] -theorem mul_left_inj (a : αˣ) {b c : α} : b * a = c * a ↔ b = c := - ⟨fun h => by simpa only [mul_inv_cancel_right] using congr_arg (fun x : α => x * ↑(a⁻¹ : αˣ)) h, - congr_arg (· * a.val)⟩ - -@[to_additive] -theorem eq_mul_inv_iff_mul_eq {a b : α} : a = b * ↑c⁻¹ ↔ a * c = b := - ⟨fun h => by rw [h, inv_mul_cancel_right], fun h => by rw [← h, mul_inv_cancel_right]⟩ - -@[to_additive] -theorem eq_inv_mul_iff_mul_eq {a c : α} : a = ↑b⁻¹ * c ↔ ↑b * a = c := - ⟨fun h => by rw [h, mul_inv_cancel_left], fun h => by rw [← h, inv_mul_cancel_left]⟩ - @[to_additive] theorem inv_mul_eq_iff_eq_mul {b c : α} : ↑a⁻¹ * b = c ↔ b = a * c := ⟨fun h => by rw [← h, mul_inv_cancel_left], fun h => by rw [h, inv_mul_cancel_left]⟩ -@[to_additive] -theorem mul_inv_eq_iff_eq_mul {a c : α} : a * ↑b⁻¹ = c ↔ a = c * b := - ⟨fun h => by rw [← h, inv_mul_cancel_right], fun h => by rw [h, mul_inv_cancel_right]⟩ - --- Porting note: have to explicitly type annotate the 1 -@[to_additive] -protected theorem inv_eq_of_mul_eq_one_left {a : α} (h : a * u = 1) : ↑u⁻¹ = a := - calc - ↑u⁻¹ = (1 : α) * ↑u⁻¹ := by rw [one_mul] - _ = a := by rw [← h, mul_inv_cancel_right] - - --- Porting note: have to explicitly type annotate the 1 -@[to_additive] -protected theorem inv_eq_of_mul_eq_one_right {a : α} (h : ↑u * a = 1) : ↑u⁻¹ = a := - calc - ↑u⁻¹ = ↑u⁻¹ * (1 : α) := by rw [mul_one] - _ = a := by rw [← h, inv_mul_cancel_left] - - -@[to_additive] -protected theorem eq_inv_of_mul_eq_one_left {a : α} (h : ↑u * a = 1) : a = ↑u⁻¹ := - (Units.inv_eq_of_mul_eq_one_right h).symm - -@[to_additive] -protected theorem eq_inv_of_mul_eq_one_right {a : α} (h : a * u = 1) : a = ↑u⁻¹ := - (Units.inv_eq_of_mul_eq_one_left h).symm - @[to_additive] instance instMonoid : Monoid αˣ := { (inferInstance : MulOneClass αˣ) with @@ -334,24 +269,6 @@ instance instCommGroupUnits {α} [CommMonoid α] : CommGroup αˣ where @[to_additive (attr := simp, norm_cast)] lemma val_pow_eq_pow_val (n : ℕ) : ↑(a ^ n) = (a ^ n : α) := rfl -@[to_additive (attr := simp)] -theorem mul_inv_eq_one {a : α} : a * ↑u⁻¹ = 1 ↔ a = u := - ⟨inv_inv u ▸ Units.eq_inv_of_mul_eq_one_right, fun h => mul_inv_of_eq h.symm⟩ - -@[to_additive (attr := simp)] -theorem inv_mul_eq_one {a : α} : ↑u⁻¹ * a = 1 ↔ ↑u = a := - ⟨inv_inv u ▸ Units.inv_eq_of_mul_eq_one_right, inv_mul_of_eq⟩ - -@[to_additive] -theorem mul_eq_one_iff_eq_inv {a : α} : a * u = 1 ↔ a = ↑u⁻¹ := by rw [← mul_inv_eq_one, inv_inv] - -@[to_additive] -theorem mul_eq_one_iff_inv_eq {a : α} : ↑u * a = 1 ↔ ↑u⁻¹ = a := by rw [← inv_mul_eq_one, inv_inv] - -@[to_additive] -theorem inv_unique {u₁ u₂ : αˣ} (h : (↑u₁ : α) = ↑u₂) : (↑u₁⁻¹ : α) = ↑u₂⁻¹ := - Units.inv_eq_of_mul_eq_one_right <| by rw [h, u₂.mul_inv] - end Monoid section DivisionMonoid @@ -418,27 +335,10 @@ theorem divp_mul_cancel (a : α) (u : αˣ) : a /ₚ u * u = a := theorem mul_divp_cancel (a : α) (u : αˣ) : a * u /ₚ u = a := (mul_assoc _ _ _).trans <| by rw [Units.mul_inv, mul_one] -@[simp] -theorem divp_left_inj (u : αˣ) {a b : α} : a /ₚ u = b /ₚ u ↔ a = b := - Units.mul_left_inj _ - @[field_simps] theorem divp_divp_eq_divp_mul (x : α) (u₁ u₂ : αˣ) : x /ₚ u₁ /ₚ u₂ = x /ₚ (u₂ * u₁) := by simp only [divp, mul_inv_rev, Units.val_mul, mul_assoc] -/- Porting note: to match the mathlib3 behavior, this needs to have higher simp -priority than eq_divp_iff_mul_eq. -/ -@[field_simps 1010] -theorem divp_eq_iff_mul_eq {x : α} {u : αˣ} {y : α} : x /ₚ u = y ↔ y * u = x := - u.mul_left_inj.symm.trans <| by rw [divp_mul_cancel]; exact ⟨Eq.symm, Eq.symm⟩ - -@[field_simps] -theorem eq_divp_iff_mul_eq {x : α} {u : αˣ} {y : α} : x = y /ₚ u ↔ x * u = y := by - rw [eq_comm, divp_eq_iff_mul_eq] - -theorem divp_eq_one_iff_eq {a : α} {u : αˣ} : a /ₚ u = 1 ↔ a = u := - (Units.mul_left_inj u).symm.trans <| by rw [divp_mul_cancel, one_mul] - @[simp] theorem one_divp (u : αˣ) : 1 /ₚ u = ↑u⁻¹ := one_mul _ @@ -447,14 +347,6 @@ theorem one_divp (u : αˣ) : 1 /ₚ u = ↑u⁻¹ := @[field_simps] theorem inv_eq_one_divp (u : αˣ) : ↑u⁻¹ = 1 /ₚ u := by rw [one_divp] -/-- Used for `field_simp` to deal with inverses of units. This form of the lemma -is essential since `field_simp` likes to use `inv_eq_one_div` to rewrite -`↑u⁻¹ = ↑(1 / u)`. --/ -@[field_simps] -theorem inv_eq_one_divp' (u : αˣ) : ((1 / u : αˣ) : α) = 1 /ₚ u := by - rw [one_div, one_divp] - /-- `field_simp` moves division inside `αˣ` to the right, and this lemma lifts the calculation to `α`. -/ @@ -464,115 +356,10 @@ theorem val_div_eq_divp (u₁ u₂ : αˣ) : ↑(u₁ / u₂) = ↑u₁ /ₚ u end Monoid -namespace LeftCancelMonoid - -variable [LeftCancelMonoid α] [Subsingleton αˣ] {a b : α} - -@[to_additive] -protected theorem eq_one_of_mul_right (h : a * b = 1) : a = 1 := - congr_arg Units.inv <| Subsingleton.elim (Units.mk _ _ (by - rw [← mul_left_cancel_iff (a := a), ← mul_assoc, h, one_mul, mul_one]) h) 1 - -@[to_additive] -protected theorem eq_one_of_mul_left (h : a * b = 1) : b = 1 := by - rwa [LeftCancelMonoid.eq_one_of_mul_right h, one_mul] at h - -@[to_additive (attr := simp)] -protected theorem mul_eq_one : a * b = 1 ↔ a = 1 ∧ b = 1 := - ⟨fun h => ⟨LeftCancelMonoid.eq_one_of_mul_right h, LeftCancelMonoid.eq_one_of_mul_left h⟩, by - rintro ⟨rfl, rfl⟩ - exact mul_one _⟩ - -@[to_additive] -protected theorem mul_ne_one : a * b ≠ 1 ↔ a ≠ 1 ∨ b ≠ 1 := by rw [not_iff_comm]; simp - -end LeftCancelMonoid - -namespace RightCancelMonoid - -variable [RightCancelMonoid α] [Subsingleton αˣ] {a b : α} - -@[to_additive] -protected theorem eq_one_of_mul_right (h : a * b = 1) : a = 1 := - congr_arg Units.inv <| Subsingleton.elim (Units.mk _ _ (by - rw [← mul_right_cancel_iff (a := b), mul_assoc, h, one_mul, mul_one]) h) 1 - -@[to_additive] -protected theorem eq_one_of_mul_left (h : a * b = 1) : b = 1 := by - rwa [RightCancelMonoid.eq_one_of_mul_right h, one_mul] at h - -@[to_additive (attr := simp)] -protected theorem mul_eq_one : a * b = 1 ↔ a = 1 ∧ b = 1 := - ⟨fun h => ⟨RightCancelMonoid.eq_one_of_mul_right h, RightCancelMonoid.eq_one_of_mul_left h⟩, by - rintro ⟨rfl, rfl⟩ - exact mul_one _⟩ - -@[to_additive] -protected theorem mul_ne_one : a * b ≠ 1 ↔ a ≠ 1 ∨ b ≠ 1 := by rw [not_iff_comm]; simp - -end RightCancelMonoid - -section CancelMonoid - -variable [CancelMonoid α] [Subsingleton αˣ] {a b : α} - -@[to_additive] -theorem eq_one_of_mul_right' (h : a * b = 1) : a = 1 := LeftCancelMonoid.eq_one_of_mul_right h - -@[to_additive] -theorem eq_one_of_mul_left' (h : a * b = 1) : b = 1 := LeftCancelMonoid.eq_one_of_mul_left h - -@[to_additive] -theorem mul_eq_one' : a * b = 1 ↔ a = 1 ∧ b = 1 := LeftCancelMonoid.mul_eq_one - -@[to_additive] -theorem mul_ne_one' : a * b ≠ 1 ↔ a ≠ 1 ∨ b ≠ 1 := LeftCancelMonoid.mul_ne_one - -end CancelMonoid - -section CommMonoid - -variable [CommMonoid α] - -@[field_simps] -theorem divp_mul_eq_mul_divp (x y : α) (u : αˣ) : x /ₚ u * y = x * y /ₚ u := by - rw [divp, divp, mul_right_comm] - --- Theoretically redundant as `field_simp` lemma. -@[field_simps] -theorem divp_eq_divp_iff {x y : α} {ux uy : αˣ} : x /ₚ ux = y /ₚ uy ↔ x * uy = y * ux := by - rw [divp_eq_iff_mul_eq, divp_mul_eq_mul_divp, divp_eq_iff_mul_eq] - --- Theoretically redundant as `field_simp` lemma. -@[field_simps] -theorem divp_mul_divp (x y : α) (ux uy : αˣ) : x /ₚ ux * (y /ₚ uy) = x * y /ₚ (ux * uy) := by - rw [divp_mul_eq_mul_divp, divp_assoc', divp_divp_eq_divp_mul] - -variable [Subsingleton αˣ] {a b : α} - -@[to_additive] -theorem eq_one_of_mul_right (h : a * b = 1) : a = 1 := - congr_arg Units.inv <| Subsingleton.elim (Units.mk _ _ (by rwa [mul_comm]) h) 1 - -@[to_additive] -theorem eq_one_of_mul_left (h : a * b = 1) : b = 1 := - congr_arg Units.inv <| Subsingleton.elim (Units.mk _ _ h <| by rwa [mul_comm]) 1 - -@[to_additive (attr := simp)] -theorem mul_eq_one : a * b = 1 ↔ a = 1 ∧ b = 1 := - ⟨fun h => ⟨eq_one_of_mul_right h, eq_one_of_mul_left h⟩, by - rintro ⟨rfl, rfl⟩ - exact mul_one _⟩ - -@[to_additive] theorem mul_ne_one : a * b ≠ 1 ↔ a ≠ 1 ∨ b ≠ 1 := by rw [not_iff_comm]; simp - -end CommMonoid - /-! # `IsUnit` predicate -/ - section IsUnit variable {M : Type*} {N : Type*} @@ -602,19 +389,6 @@ theorem isUnit_iff_exists_and_exists [Monoid M] {a : M} : ⟨fun ⟨b, hba, hab⟩ => ⟨⟨b, hba⟩, ⟨b, hab⟩⟩, fun ⟨⟨b, hb⟩, ⟨_, hc⟩⟩ => ⟨b, hb, left_inv_eq_right_inv hc hb ▸ hc⟩⟩ -@[to_additive (attr := nontriviality)] -theorem isUnit_of_subsingleton [Monoid M] [Subsingleton M] (a : M) : IsUnit a := - ⟨⟨a, a, by subsingleton, by subsingleton⟩, rfl⟩ - -@[to_additive] -instance [Monoid M] : CanLift M Mˣ Units.val IsUnit := - { prf := fun _ ↦ id } - -/-- A subsingleton `Monoid` has a unique unit. -/ -@[to_additive "A subsingleton `AddMonoid` has a unique additive unit."] -instance [Monoid M] [Subsingleton M] : Unique Mˣ where - uniq _ := Units.val_eq_one.mp (by subsingleton) - @[to_additive (attr := simp)] protected theorem Units.isUnit [Monoid M] (u : Mˣ) : IsUnit (u : M) := ⟨u, rfl⟩ @@ -651,8 +425,6 @@ lemma IsUnit.exists_left_inv {a : M} (h : IsUnit a) : ∃ b, b * a = 1 := by @[to_additive] lemma IsUnit.pow (n : ℕ) : IsUnit a → IsUnit (a ^ n) := by rintro ⟨u, rfl⟩; exact ⟨u ^ n, rfl⟩ -theorem units_eq_one [Subsingleton Mˣ] (u : Mˣ) : u = 1 := by subsingleton - @[to_additive] lemma isUnit_iff_eq_one [Subsingleton Mˣ] {x : M} : IsUnit x ↔ x = 1 := ⟨fun ⟨u, hu⟩ ↦ by rw [← hu, Subsingleton.elim u 1, Units.val_one], fun h ↦ h ▸ isUnit_one⟩ @@ -746,46 +518,6 @@ theorem mul_val_inv (h : IsUnit a) : a * ↑h.unit⁻¹ = 1 := by instance (x : M) [h : Decidable (∃ u : Mˣ, ↑u = x)] : Decidable (IsUnit x) := h -@[to_additive] -theorem mul_left_inj (h : IsUnit a) : b * a = c * a ↔ b = c := - let ⟨u, hu⟩ := h - hu ▸ u.mul_left_inj - -@[to_additive] -theorem mul_right_inj (h : IsUnit a) : a * b = a * c ↔ b = c := - let ⟨u, hu⟩ := h - hu ▸ u.mul_right_inj - -@[to_additive] -protected theorem mul_left_cancel (h : IsUnit a) : a * b = a * c → b = c := - h.mul_right_inj.1 - -@[to_additive] -protected theorem mul_right_cancel (h : IsUnit b) : a * b = c * b → a = c := - h.mul_left_inj.1 - -@[to_additive] -protected theorem mul_right_injective (h : IsUnit a) : Injective (a * ·) := - fun _ _ => h.mul_left_cancel - -@[to_additive] -protected theorem mul_left_injective (h : IsUnit b) : Injective (· * b) := - fun _ _ => h.mul_right_cancel - -@[to_additive] -theorem isUnit_iff_mulLeft_bijective {a : M} : - IsUnit a ↔ Function.Bijective (a * ·) := - ⟨fun h ↦ ⟨h.mul_right_injective, fun y ↦ ⟨h.unit⁻¹ * y, by simp [← mul_assoc]⟩⟩, fun h ↦ - ⟨⟨a, _, (h.2 1).choose_spec, h.1 - (by simpa [mul_assoc] using congr_arg (· * a) (h.2 1).choose_spec)⟩, rfl⟩⟩ - -@[to_additive] -theorem isUnit_iff_mulRight_bijective {a : M} : - IsUnit a ↔ Function.Bijective (· * a) := - ⟨fun h ↦ ⟨h.mul_left_injective, fun y ↦ ⟨y * h.unit⁻¹, by simp [mul_assoc]⟩⟩, - fun h ↦ ⟨⟨a, _, h.1 (by simpa [mul_assoc] using congr_arg (a * ·) (h.2 1).choose_spec), - (h.2 1).choose_spec⟩, rfl⟩⟩ - end Monoid section DivisionMonoid @@ -822,63 +554,9 @@ protected lemma mul_inv_cancel_left (h : IsUnit a) : ∀ b, a * (a⁻¹ * b) = b protected lemma inv_mul_cancel_left (h : IsUnit a) : ∀ b, a⁻¹ * (a * b) = b := h.unit'.inv_mul_cancel_left -@[to_additive (attr := simp)] -protected lemma mul_inv_cancel_right (h : IsUnit b) (a : α) : a * b * b⁻¹ = a := - h.unit'.mul_inv_cancel_right _ - -@[to_additive (attr := simp)] -protected lemma inv_mul_cancel_right (h : IsUnit b) (a : α) : a * b⁻¹ * b = a := - h.unit'.inv_mul_cancel_right _ - @[to_additive] protected lemma div_self (h : IsUnit a) : a / a = 1 := by rw [div_eq_mul_inv, h.mul_inv_cancel] -@[to_additive] -protected lemma eq_mul_inv_iff_mul_eq (h : IsUnit c) : a = b * c⁻¹ ↔ a * c = b := - h.unit'.eq_mul_inv_iff_mul_eq - -@[to_additive] -protected lemma eq_inv_mul_iff_mul_eq (h : IsUnit b) : a = b⁻¹ * c ↔ b * a = c := - h.unit'.eq_inv_mul_iff_mul_eq - -@[to_additive] -protected lemma inv_mul_eq_iff_eq_mul (h : IsUnit a) : a⁻¹ * b = c ↔ b = a * c := - h.unit'.inv_mul_eq_iff_eq_mul - -@[to_additive] -protected lemma mul_inv_eq_iff_eq_mul (h : IsUnit b) : a * b⁻¹ = c ↔ a = c * b := - h.unit'.mul_inv_eq_iff_eq_mul - -@[to_additive] -protected lemma mul_inv_eq_one (h : IsUnit b) : a * b⁻¹ = 1 ↔ a = b := - @Units.mul_inv_eq_one _ _ h.unit' _ - -@[to_additive] -protected lemma inv_mul_eq_one (h : IsUnit a) : a⁻¹ * b = 1 ↔ a = b := - @Units.inv_mul_eq_one _ _ h.unit' _ - -@[to_additive] -protected lemma mul_eq_one_iff_eq_inv (h : IsUnit b) : a * b = 1 ↔ a = b⁻¹ := - @Units.mul_eq_one_iff_eq_inv _ _ h.unit' _ - -@[to_additive] -protected lemma mul_eq_one_iff_inv_eq (h : IsUnit a) : a * b = 1 ↔ a⁻¹ = b := - @Units.mul_eq_one_iff_inv_eq _ _ h.unit' _ - -@[to_additive (attr := simp)] -protected lemma div_mul_cancel (h : IsUnit b) (a : α) : a / b * b = a := by - rw [div_eq_mul_inv, h.inv_mul_cancel_right] - -@[to_additive (attr := simp)] -protected lemma mul_div_cancel_right (h : IsUnit b) (a : α) : a * b / b = a := by - rw [div_eq_mul_inv, h.mul_inv_cancel_right] - -@[to_additive] -protected lemma mul_one_div_cancel (h : IsUnit a) : a * (1 / a) = 1 := by simp [h] - -@[to_additive] -protected lemma one_div_mul_cancel (h : IsUnit a) : 1 / a * a = 1 := by simp [h] - @[to_additive] lemma inv (h : IsUnit a) : IsUnit a⁻¹ := by obtain ⟨u, hu⟩ := h @@ -888,46 +566,14 @@ lemma inv (h : IsUnit a) : IsUnit a⁻¹ := by @[to_additive] lemma div (ha : IsUnit a) (hb : IsUnit b) : IsUnit (a / b) := by rw [div_eq_mul_inv]; exact ha.mul hb.inv -@[to_additive] -protected lemma div_left_inj (h : IsUnit c) : a / c = b / c ↔ a = b := by - simp only [div_eq_mul_inv] - exact Units.mul_left_inj h.inv.unit' - -@[to_additive] -protected lemma div_eq_iff (h : IsUnit b) : a / b = c ↔ a = c * b := by - rw [div_eq_mul_inv, h.mul_inv_eq_iff_eq_mul] - -@[to_additive] -protected lemma eq_div_iff (h : IsUnit c) : a = b / c ↔ a * c = b := by - rw [div_eq_mul_inv, h.eq_mul_inv_iff_mul_eq] - -@[to_additive] -protected lemma div_eq_of_eq_mul (h : IsUnit b) : a = c * b → a / b = c := - h.div_eq_iff.2 - -@[to_additive] -protected lemma eq_div_of_mul_eq (h : IsUnit c) : a * c = b → a = b / c := - h.eq_div_iff.2 - -@[to_additive] -protected lemma div_eq_one_iff_eq (h : IsUnit b) : a / b = 1 ↔ a = b := - ⟨eq_of_div_eq_one, fun hab => hab.symm ▸ h.div_self⟩ - @[to_additive] protected lemma div_mul_cancel_right (h : IsUnit b) (a : α) : b / (a * b) = a⁻¹ := by rw [div_eq_mul_inv, mul_inv_rev, h.mul_inv_cancel_left] -@[to_additive] -protected lemma div_mul_left (h : IsUnit b) : b / (a * b) = 1 / a := by - rw [h.div_mul_cancel_right, one_div] - @[to_additive] protected lemma mul_div_mul_right (h : IsUnit c) (a b : α) : a * c / (b * c) = a / b := by simp only [div_eq_mul_inv, mul_inv_rev, mul_assoc, h.mul_inv_cancel_left] -@[to_additive] -protected lemma mul_mul_div (a : α) (h : IsUnit b) : a * b * (1 / b) = a := by simp [h] - end DivisionMonoid section DivisionCommMonoid @@ -937,41 +583,10 @@ variable [DivisionCommMonoid α] {a b c d : α} protected lemma div_mul_cancel_left (h : IsUnit a) (b : α) : a / (a * b) = b⁻¹ := by rw [mul_comm, h.div_mul_cancel_right] -@[to_additive] -protected lemma div_mul_right (h : IsUnit a) (b : α) : a / (a * b) = 1 / b := by - rw [mul_comm, h.div_mul_left] - -@[to_additive] -protected lemma mul_div_cancel_left (h : IsUnit a) (b : α) : a * b / a = b := by - rw [mul_comm, h.mul_div_cancel_right] - -@[to_additive] -protected lemma mul_div_cancel (h : IsUnit a) (b : α) : a * (b / a) = b := by - rw [mul_comm, h.div_mul_cancel] - @[to_additive] protected lemma mul_div_mul_left (h : IsUnit c) (a b : α) : c * a / (c * b) = a / b := by rw [mul_comm c, mul_comm c, h.mul_div_mul_right] -@[to_additive] -protected lemma mul_eq_mul_of_div_eq_div (hb : IsUnit b) (hd : IsUnit d) - (a c : α) (h : a / b = c / d) : a * d = c * b := by - rw [← mul_one a, ← hb.div_self, ← mul_comm_div, h, div_mul_eq_mul_div, hd.div_mul_cancel] - -@[to_additive] -protected lemma div_eq_div_iff (hb : IsUnit b) (hd : IsUnit d) : - a / b = c / d ↔ a * d = c * b := by - rw [← (hb.mul hd).mul_left_inj, ← mul_assoc, hb.div_mul_cancel, ← mul_assoc, mul_right_comm, - hd.div_mul_cancel] - -@[to_additive] -protected lemma div_div_cancel (h : IsUnit a) : a / (a / b) = b := by - rw [div_div_eq_mul_div, h.mul_div_cancel_left] - -@[to_additive] -protected lemma div_div_cancel_left (h : IsUnit a) : a / b / a = b⁻¹ := by - rw [div_eq_mul_inv, div_eq_mul_inv, mul_right_comm, h.mul_inv_cancel, one_mul] - end DivisionCommMonoid end IsUnit @@ -1012,14 +627,3 @@ noncomputable def commGroupOfIsUnit [hM : CommMonoid M] (h : ∀ a : M, IsUnit a rw [Units.inv_mul_eq_iff_eq_mul, (h a).unit_spec, mul_one] } end NoncomputableDefs - -attribute [deprecated div_mul_cancel_right (since := "2024-03-20")] IsUnit.div_mul_left -attribute [deprecated sub_add_cancel_right (since := "2024-03-20")] IsAddUnit.sub_add_left -attribute [deprecated div_mul_cancel_left (since := "2024-03-20")] IsUnit.div_mul_right -attribute [deprecated sub_add_cancel_left (since := "2024-03-20")] IsAddUnit.sub_add_right --- The names `IsUnit.mul_div_cancel` and `IsAddUnit.add_sub_cancel` have been reused --- @[deprecated (since := "2024-03-20")] alias IsUnit.mul_div_cancel := IsUnit.mul_div_cancel_right --- @[deprecated (since := "2024-03-20")] --- alias IsAddUnit.add_sub_cancel := IsAddUnit.add_sub_cancel_right -@[deprecated (since := "2024-03-20")] alias IsUnit.mul_div_cancel' := IsUnit.mul_div_cancel -@[deprecated (since := "2024-03-20")] alias IsAddUnit.add_sub_cancel' := IsAddUnit.add_sub_cancel diff --git a/Mathlib/Algebra/Group/Units/Hom.lean b/Mathlib/Algebra/Group/Units/Hom.lean index 09f626ae879048..844235b25ef68e 100644 --- a/Mathlib/Algebra/Group/Units/Hom.lean +++ b/Mathlib/Algebra/Group/Units/Hom.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Johan Commelin, Chris Hughes, Kevin Buzzard -/ import Mathlib.Algebra.Group.Hom.Defs -import Mathlib.Algebra.Group.Units +import Mathlib.Algebra.Group.Units.Basic /-! # Monoid homomorphisms and units diff --git a/Mathlib/Algebra/GroupWithZero/Units/Basic.lean b/Mathlib/Algebra/GroupWithZero/Units/Basic.lean index 4daea455977cf3..7f2b3f9ec3ad80 100644 --- a/Mathlib/Algebra/GroupWithZero/Units/Basic.lean +++ b/Mathlib/Algebra/GroupWithZero/Units/Basic.lean @@ -3,7 +3,7 @@ Copyright (c) 2020 Johan Commelin. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Johan Commelin -/ -import Mathlib.Algebra.Group.Units +import Mathlib.Algebra.Group.Units.Basic import Mathlib.Algebra.GroupWithZero.Basic import Mathlib.Logic.Equiv.Defs import Mathlib.Tactic.Contrapose diff --git a/Mathlib/Algebra/Order/Monoid/Canonical/Defs.lean b/Mathlib/Algebra/Order/Monoid/Canonical/Defs.lean index 7cf5e1c4143ca9..3a2da1f5ad2399 100644 --- a/Mathlib/Algebra/Order/Monoid/Canonical/Defs.lean +++ b/Mathlib/Algebra/Order/Monoid/Canonical/Defs.lean @@ -3,7 +3,7 @@ Copyright (c) 2016 Jeremy Avigad. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Jeremy Avigad, Leonardo de Moura, Mario Carneiro, Johannes Hölzl -/ -import Mathlib.Algebra.Group.Units +import Mathlib.Algebra.Group.Units.Basic import Mathlib.Algebra.Order.Monoid.Defs import Mathlib.Algebra.Order.Monoid.Unbundled.ExistsOfLE import Mathlib.Algebra.NeZero diff --git a/Mathlib/Algebra/Order/Monoid/Units.lean b/Mathlib/Algebra/Order/Monoid/Units.lean index 9e0572e82a0cc3..daf01bce3fef7c 100644 --- a/Mathlib/Algebra/Order/Monoid/Units.lean +++ b/Mathlib/Algebra/Order/Monoid/Units.lean @@ -5,7 +5,7 @@ Authors: Jeremy Avigad, Leonardo de Moura, Mario Carneiro, Johannes Hölzl -/ import Mathlib.Order.Hom.Basic import Mathlib.Order.MinMax -import Mathlib.Algebra.Group.Units +import Mathlib.Algebra.Group.Units.Defs /-! # Units in ordered monoids diff --git a/Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean b/Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean index ea150bfb7d6fe7..5803021b2a9848 100644 --- a/Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean +++ b/Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Jeremy Avigad, Leonardo de Moura, Mario Carneiro, Yaël Dillies -/ import Mathlib.Algebra.Group.Pi.Basic -import Mathlib.Algebra.Group.Units +import Mathlib.Algebra.Group.Units.Basic import Mathlib.Algebra.GroupWithZero.NeZero import Mathlib.Algebra.Order.Group.Unbundled.Basic import Mathlib.Algebra.Order.GroupWithZero.Unbundled diff --git a/Mathlib/Algebra/Regular/Basic.lean b/Mathlib/Algebra/Regular/Basic.lean index 0a534b873b9c39..fd81ff23fd8c03 100644 --- a/Mathlib/Algebra/Regular/Basic.lean +++ b/Mathlib/Algebra/Regular/Basic.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Damiano Testa -/ import Mathlib.Algebra.Group.Commute.Defs -import Mathlib.Algebra.Group.Units +import Mathlib.Algebra.Group.Units.Defs import Mathlib.Algebra.GroupWithZero.Defs import Mathlib.Algebra.Order.Monoid.Unbundled.Basic import Mathlib.Tactic.NthRewrite diff --git a/Mathlib/CategoryTheory/Endomorphism.lean b/Mathlib/CategoryTheory/Endomorphism.lean index 483f7963bef826..1e553ff57a4dc5 100644 --- a/Mathlib/CategoryTheory/Endomorphism.lean +++ b/Mathlib/CategoryTheory/Endomorphism.lean @@ -5,7 +5,7 @@ Authors: Yury Kudryashov, Kim Morrison, Simon Hudon -/ import Mathlib.Algebra.Group.Action.Defs import Mathlib.Algebra.Group.Equiv.Basic -import Mathlib.Algebra.Group.Units +import Mathlib.Algebra.Group.Units.Basic import Mathlib.Algebra.Group.Units.Hom import Mathlib.CategoryTheory.Groupoid import Mathlib.CategoryTheory.Opposites diff --git a/Mathlib/Data/Nat/Bits.lean b/Mathlib/Data/Nat/Bits.lean index 58bfa8b7cbb479..c6e41071fc2140 100644 --- a/Mathlib/Data/Nat/Bits.lean +++ b/Mathlib/Data/Nat/Bits.lean @@ -5,6 +5,7 @@ Authors: Praneeth Kolichala -/ import Mathlib.Algebra.Group.Basic import Mathlib.Algebra.Group.Nat +import Mathlib.Algebra.Group.Units.Basic import Mathlib.Data.Nat.Defs import Mathlib.Data.List.Defs import Mathlib.Tactic.Convert diff --git a/Mathlib/RingTheory/LocalRing/Defs.lean b/Mathlib/RingTheory/LocalRing/Defs.lean index c74c7f0f9a930d..511c0f31a6438b 100644 --- a/Mathlib/RingTheory/LocalRing/Defs.lean +++ b/Mathlib/RingTheory/LocalRing/Defs.lean @@ -3,7 +3,7 @@ Copyright (c) 2018 Kenny Lau. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Kenny Lau, Chris Hughes, Mario Carneiro -/ -import Mathlib.Algebra.Group.Units +import Mathlib.Algebra.Group.Units.Defs import Mathlib.Algebra.Ring.Defs /-! diff --git a/Mathlib/RingTheory/MvPowerSeries/Inverse.lean b/Mathlib/RingTheory/MvPowerSeries/Inverse.lean index d53136ff960c23..d5160e80675891 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Inverse.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Inverse.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Johan Commelin, Kenny Lau -/ -import Mathlib.Algebra.Group.Units +import Mathlib.Algebra.Group.Units.Basic import Mathlib.RingTheory.MvPowerSeries.Basic import Mathlib.RingTheory.MvPowerSeries.NoZeroDivisors import Mathlib.RingTheory.LocalRing.Basic diff --git a/Mathlib/Tactic/FieldSimp.lean b/Mathlib/Tactic/FieldSimp.lean index b02abb4f47983c..af1f591fc5fcbf 100644 --- a/Mathlib/Tactic/FieldSimp.lean +++ b/Mathlib/Tactic/FieldSimp.lean @@ -6,7 +6,7 @@ Authors: Sébastien Gouëzel, David Renshaw import Lean.Elab.Tactic.Basic import Lean.Meta.Tactic.Simp.Main -import Mathlib.Algebra.Group.Units +import Mathlib.Algebra.Group.Units.Basic import Mathlib.Tactic.Positivity.Core import Mathlib.Tactic.NormNum.Core import Mathlib.Util.DischargerAsTactic diff --git a/scripts/noshake.json b/scripts/noshake.json index 6448419d87171d..ad486bd8e6ca49 100644 --- a/scripts/noshake.json +++ b/scripts/noshake.json @@ -418,6 +418,7 @@ "Mathlib.Algebra.Module.LinearMap.Basic": ["Mathlib.Algebra.Star.Basic"], "Mathlib.Algebra.Module.Equiv": ["Mathlib.Algebra.Star.Basic"], "Mathlib.Algebra.Homology.ModuleCat": ["Mathlib.Algebra.Homology.Homotopy"], + "Mathlib.Algebra.Group.Units.Basic": ["Mathlib.Tactic.Subsingleton"], "Mathlib.Algebra.Group.Units": ["Mathlib.Tactic.Subsingleton"], "Mathlib.Algebra.Group.Pi.Basic": ["Batteries.Tactic.Classical"], "Mathlib.Algebra.Group.Defs": ["Mathlib.Data.Int.Notation"], From c421db2bb46151fc4116d8c0d2e7fdb68a1414a9 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Mon, 14 Oct 2024 14:26:01 +0000 Subject: [PATCH 112/425] chore: adaptations for nightly-2024-10-14 (#17727) Co-authored-by: leanprover-community-mathlib4-bot Co-authored-by: Johan Commelin Co-authored-by: adomani Co-authored-by: Kyle Miller --- lake-manifest.json | 2 +- lean-toolchain | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index 0fb978e09f267a..5a7bf89d6a8f11 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "9efd9c267ad7a71c5e3a83e8fbbd446fe61ef119", + "rev": "5f963d5d06cc3c2d3abd0806891133137a59d7eb", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", diff --git a/lean-toolchain b/lean-toolchain index 30684366328531..a7eff1cf43d14e 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-13 +leanprover/lean4:nightly-2024-10-14 From 1659e846af8e35f29f68ea84aaa66e291d430677 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Mon, 14 Oct 2024 14:35:14 +0000 Subject: [PATCH 113/425] chore(Group/Subsemigroup/Basic): split off Defs file (#17725) The criteria for including a result in `Algebra.Group.Subsemigroup.Basic`: * Can it be defined with only `Defs` imports? * Is it needed for a subsequent `def` or `instance`? This mostly prepares for splitting `Submonoid.Basic`. --- Mathlib.lean | 1 + Mathlib/Algebra/Group/Subsemigroup/Basic.lean | 171 +------------ Mathlib/Algebra/Group/Subsemigroup/Defs.lean | 229 ++++++++++++++++++ 3 files changed, 234 insertions(+), 167 deletions(-) create mode 100644 Mathlib/Algebra/Group/Subsemigroup/Defs.lean diff --git a/Mathlib.lean b/Mathlib.lean index c52aa83a52c782..8dff03b97436aa 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -292,6 +292,7 @@ import Mathlib.Algebra.Group.Submonoid.Operations import Mathlib.Algebra.Group.Submonoid.Pointwise import Mathlib.Algebra.Group.Submonoid.Units import Mathlib.Algebra.Group.Subsemigroup.Basic +import Mathlib.Algebra.Group.Subsemigroup.Defs import Mathlib.Algebra.Group.Subsemigroup.Membership import Mathlib.Algebra.Group.Subsemigroup.Operations import Mathlib.Algebra.Group.Support diff --git a/Mathlib/Algebra/Group/Subsemigroup/Basic.lean b/Mathlib/Algebra/Group/Subsemigroup/Basic.lean index c5801a38f6bdbb..fa82da88595fa6 100644 --- a/Mathlib/Algebra/Group/Subsemigroup/Basic.lean +++ b/Mathlib/Algebra/Group/Subsemigroup/Basic.lean @@ -4,23 +4,17 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Johannes Hölzl, Kenny Lau, Johan Commelin, Mario Carneiro, Kevin Buzzard, Amelia Livingston, Yury Kudryashov, Yakov Pechersky -/ -import Mathlib.Algebra.Group.Hom.Defs +import Mathlib.Algebra.Group.Subsemigroup.Defs import Mathlib.Data.Set.Lattice -import Mathlib.Data.SetLike.Basic /-! -# Subsemigroups: definition and `CompleteLattice` structure +# Subsemigroups: `CompleteLattice` structure -This file defines bundled multiplicative and additive subsemigroups. We also define -a `CompleteLattice` structure on `Subsemigroup`s, +This file defines a `CompleteLattice` structure on `Subsemigroup`s, and define the closure of a set as the minimal subsemigroup that includes this set. ## Main definitions -* `Subsemigroup M`: the type of bundled subsemigroup of a magma `M`; the underlying set is given in - the `carrier` field of the structure, and should be accessed through coercion as in `(S : Set M)`. -* `AddSubsemigroup M` : the type of bundled subsemigroups of an additive magma `M`. - For each of the following definitions in the `Subsemigroup` namespace, there is a corresponding definition in the `AddSubsemigroup` namespace. @@ -56,143 +50,9 @@ section NonAssoc variable [Mul M] {s : Set M} variable [Add A] {t : Set A} -/-- `MulMemClass S M` says `S` is a type of sets `s : Set M` that are closed under `(*)` -/ -class MulMemClass (S : Type*) (M : outParam Type*) [Mul M] [SetLike S M] : Prop where - /-- A substructure satisfying `MulMemClass` is closed under multiplication. -/ - mul_mem : ∀ {s : S} {a b : M}, a ∈ s → b ∈ s → a * b ∈ s - -export MulMemClass (mul_mem) - -/-- `AddMemClass S M` says `S` is a type of sets `s : Set M` that are closed under `(+)` -/ -class AddMemClass (S : Type*) (M : outParam Type*) [Add M] [SetLike S M] : Prop where - /-- A substructure satisfying `AddMemClass` is closed under addition. -/ - add_mem : ∀ {s : S} {a b : M}, a ∈ s → b ∈ s → a + b ∈ s - -export AddMemClass (add_mem) - -attribute [to_additive] MulMemClass - -attribute [aesop safe apply (rule_sets := [SetLike])] mul_mem add_mem - -/-- A subsemigroup of a magma `M` is a subset closed under multiplication. -/ -structure Subsemigroup (M : Type*) [Mul M] where - /-- The carrier of a subsemigroup. -/ - carrier : Set M - /-- The product of two elements of a subsemigroup belongs to the subsemigroup. -/ - mul_mem' {a b} : a ∈ carrier → b ∈ carrier → a * b ∈ carrier - -/-- An additive subsemigroup of an additive magma `M` is a subset closed under addition. -/ -structure AddSubsemigroup (M : Type*) [Add M] where - /-- The carrier of an additive subsemigroup. -/ - carrier : Set M - /-- The sum of two elements of an additive subsemigroup belongs to the subsemigroup. -/ - add_mem' {a b} : a ∈ carrier → b ∈ carrier → a + b ∈ carrier - -attribute [to_additive AddSubsemigroup] Subsemigroup - namespace Subsemigroup -@[to_additive] -instance : SetLike (Subsemigroup M) M := - ⟨Subsemigroup.carrier, fun p q h => by cases p; cases q; congr⟩ - -@[to_additive] -instance : MulMemClass (Subsemigroup M) M where mul_mem := fun {_ _ _} => Subsemigroup.mul_mem' _ - -initialize_simps_projections Subsemigroup (carrier → coe) -initialize_simps_projections AddSubsemigroup (carrier → coe) - -@[to_additive (attr := simp)] -theorem mem_carrier {s : Subsemigroup M} {x : M} : x ∈ s.carrier ↔ x ∈ s := - Iff.rfl - -@[to_additive (attr := simp)] -theorem mem_mk {s : Set M} {x : M} (h_mul) : x ∈ mk s h_mul ↔ x ∈ s := - Iff.rfl - -@[to_additive (attr := simp, norm_cast)] -theorem coe_set_mk (s : Set M) (h_mul) : (mk s h_mul : Set M) = s := - rfl - -@[to_additive (attr := simp)] -theorem mk_le_mk {s t : Set M} (h_mul) (h_mul') : mk s h_mul ≤ mk t h_mul' ↔ s ⊆ t := - Iff.rfl - -/-- Two subsemigroups are equal if they have the same elements. -/ -@[to_additive (attr := ext) "Two `AddSubsemigroup`s are equal if they have the same elements."] -theorem ext {S T : Subsemigroup M} (h : ∀ x, x ∈ S ↔ x ∈ T) : S = T := - SetLike.ext h - -/-- Copy a subsemigroup replacing `carrier` with a set that is equal to it. -/ -@[to_additive "Copy an additive subsemigroup replacing `carrier` with a set that is equal to it."] -protected def copy (S : Subsemigroup M) (s : Set M) (hs : s = S) : - Subsemigroup M where - carrier := s - mul_mem' := hs.symm ▸ S.mul_mem' - -variable {S : Subsemigroup M} - -@[to_additive (attr := simp)] -theorem coe_copy {s : Set M} (hs : s = S) : (S.copy s hs : Set M) = s := - rfl - -@[to_additive] -theorem copy_eq {s : Set M} (hs : s = S) : S.copy s hs = S := - SetLike.coe_injective hs - -variable (S) - -/-- A subsemigroup is closed under multiplication. -/ -@[to_additive "An `AddSubsemigroup` is closed under addition."] -protected theorem mul_mem {x y : M} : x ∈ S → y ∈ S → x * y ∈ S := - Subsemigroup.mul_mem' S - -/-- The subsemigroup `M` of the magma `M`. -/ -@[to_additive "The additive subsemigroup `M` of the magma `M`."] -instance : Top (Subsemigroup M) := - ⟨{ carrier := Set.univ - mul_mem' := fun _ _ => Set.mem_univ _ }⟩ - -/-- The trivial subsemigroup `∅` of a magma `M`. -/ -@[to_additive "The trivial `AddSubsemigroup` `∅` of an additive magma `M`."] -instance : Bot (Subsemigroup M) := - ⟨{ carrier := ∅ - mul_mem' := False.elim }⟩ - -@[to_additive] -instance : Inhabited (Subsemigroup M) := - ⟨⊥⟩ - -@[to_additive] -theorem not_mem_bot {x : M} : x ∉ (⊥ : Subsemigroup M) := - Set.not_mem_empty x - -@[to_additive (attr := simp)] -theorem mem_top (x : M) : x ∈ (⊤ : Subsemigroup M) := - Set.mem_univ x - -@[to_additive (attr := simp)] -theorem coe_top : ((⊤ : Subsemigroup M) : Set M) = Set.univ := - rfl - -@[to_additive (attr := simp)] -theorem coe_bot : ((⊥ : Subsemigroup M) : Set M) = ∅ := - rfl - -/-- The inf of two subsemigroups is their intersection. -/ -@[to_additive "The inf of two `AddSubsemigroup`s is their intersection."] -instance : Inf (Subsemigroup M) := - ⟨fun S₁ S₂ => - { carrier := S₁ ∩ S₂ - mul_mem' := fun ⟨hx, hx'⟩ ⟨hy, hy'⟩ => ⟨S₁.mul_mem hx hy, S₂.mul_mem hx' hy'⟩ }⟩ - -@[to_additive (attr := simp)] -theorem coe_inf (p p' : Subsemigroup M) : ((p ⊓ p' : Subsemigroup M) : Set M) = (p : Set M) ∩ p' := - rfl - -@[to_additive (attr := simp)] -theorem mem_inf {p p' : Subsemigroup M} {x : M} : x ∈ p ⊓ p' ↔ x ∈ p ∧ x ∈ p' := - Iff.rfl +variable (S : Subsemigroup M) @[to_additive] instance : InfSet (Subsemigroup M) := @@ -235,19 +95,6 @@ instance : CompleteLattice (Subsemigroup M) := inf_le_left := fun _ _ _ => And.left inf_le_right := fun _ _ _ => And.right } -@[to_additive] -theorem subsingleton_of_subsingleton [Subsingleton (Subsemigroup M)] : Subsingleton M := by - constructor; intro x y - have : ∀ a : M, a ∈ (⊥ : Subsemigroup M) := by simp [Subsingleton.elim (⊥ : Subsemigroup M) ⊤] - exact absurd (this x) not_mem_bot - -@[to_additive] -instance [hn : Nonempty M] : Nontrivial (Subsemigroup M) := - ⟨⟨⊥, ⊤, fun h => by - obtain ⟨x⟩ := id hn - refine absurd (?_ : x ∈ ⊥) not_mem_bot - simp [h]⟩⟩ - /-- The `Subsemigroup` generated by a set. -/ @[to_additive "The `AddSubsemigroup` generated by a set"] def closure (s : Set M) : Subsemigroup M := @@ -385,12 +232,6 @@ variable [Mul N] open Subsemigroup -/-- The subsemigroup of elements `x : M` such that `f x = g x` -/ -@[to_additive "The additive subsemigroup of elements `x : M` such that `f x = g x`"] -def eqLocus (f g : M →ₙ* N) : Subsemigroup M where - carrier := { x | f x = g x } - mul_mem' (hx : _ = _) (hy : _ = _) := by simp [*] - /-- If two mul homomorphisms are equal on a set, then they are equal on its subsemigroup closure. -/ @[to_additive "If two add homomorphisms are equal on a set, then they are equal on its additive subsemigroup closure."] @@ -398,10 +239,6 @@ theorem eqOn_closure {f g : M →ₙ* N} {s : Set M} (h : Set.EqOn f g s) : Set.EqOn f g (closure s) := show closure s ≤ f.eqLocus g from closure_le.2 h -@[to_additive] -theorem eq_of_eqOn_top {f g : M →ₙ* N} (h : Set.EqOn f g (⊤ : Subsemigroup M)) : f = g := - ext fun _ => h trivial - @[to_additive] theorem eq_of_eqOn_dense {s : Set M} (hs : closure s = ⊤) {f g : M →ₙ* N} (h : s.EqOn f g) : f = g := diff --git a/Mathlib/Algebra/Group/Subsemigroup/Defs.lean b/Mathlib/Algebra/Group/Subsemigroup/Defs.lean new file mode 100644 index 00000000000000..946d325924172b --- /dev/null +++ b/Mathlib/Algebra/Group/Subsemigroup/Defs.lean @@ -0,0 +1,229 @@ +/- +Copyright (c) 2018 Johannes Hölzl. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Johannes Hölzl, Kenny Lau, Johan Commelin, Mario Carneiro, Kevin Buzzard, +Amelia Livingston, Yury Kudryashov, Yakov Pechersky +-/ +import Mathlib.Algebra.Group.Hom.Defs +import Mathlib.Data.SetLike.Basic + +/-! +# Subsemigroups: definition + +This file defines bundled multiplicative and additive subsemigroups. + +## Main definitions + +* `Subsemigroup M`: the type of bundled subsemigroup of a magma `M`; the underlying set is given in + the `carrier` field of the structure, and should be accessed through coercion as in `(S : Set M)`. +* `AddSubsemigroup M` : the type of bundled subsemigroups of an additive magma `M`. + +For each of the following definitions in the `Subsemigroup` namespace, there is a corresponding +definition in the `AddSubsemigroup` namespace. + +* `Subsemigroup.copy` : copy of a subsemigroup with `carrier` replaced by a set that is equal but + possibly not definitionally equal to the carrier of the original `Subsemigroup`. + +Similarly, for each of these definitions in the `MulHom` namespace, there is a corresponding +definition in the `AddHom` namespace. + +* `MulHom.eqLocus f g`: the subsemigroup of those `x` such that `f x = g x` + +## Implementation notes + +Subsemigroup inclusion is denoted `≤` rather than `⊆`, although `∈` is defined as +membership of a subsemigroup's underlying set. + +Note that `Subsemigroup M` does not actually require `Semigroup M`, +instead requiring only the weaker `Mul M`. + +This file is designed to have very few dependencies. In particular, it should not use natural +numbers. + +## Tags +subsemigroup, subsemigroups +-/ + +assert_not_exists CompleteLattice +assert_not_exists MonoidWithZero + +-- Only needed for notation +variable {M : Type*} {N : Type*} {A : Type*} + +section NonAssoc + +variable [Mul M] {s : Set M} +variable [Add A] {t : Set A} + +/-- `MulMemClass S M` says `S` is a type of sets `s : Set M` that are closed under `(*)` -/ +class MulMemClass (S : Type*) (M : outParam Type*) [Mul M] [SetLike S M] : Prop where + /-- A substructure satisfying `MulMemClass` is closed under multiplication. -/ + mul_mem : ∀ {s : S} {a b : M}, a ∈ s → b ∈ s → a * b ∈ s + +export MulMemClass (mul_mem) + +/-- `AddMemClass S M` says `S` is a type of sets `s : Set M` that are closed under `(+)` -/ +class AddMemClass (S : Type*) (M : outParam Type*) [Add M] [SetLike S M] : Prop where + /-- A substructure satisfying `AddMemClass` is closed under addition. -/ + add_mem : ∀ {s : S} {a b : M}, a ∈ s → b ∈ s → a + b ∈ s + +export AddMemClass (add_mem) + +attribute [to_additive] MulMemClass + +attribute [aesop safe apply (rule_sets := [SetLike])] mul_mem add_mem + +/-- A subsemigroup of a magma `M` is a subset closed under multiplication. -/ +structure Subsemigroup (M : Type*) [Mul M] where + /-- The carrier of a subsemigroup. -/ + carrier : Set M + /-- The product of two elements of a subsemigroup belongs to the subsemigroup. -/ + mul_mem' {a b} : a ∈ carrier → b ∈ carrier → a * b ∈ carrier + +/-- An additive subsemigroup of an additive magma `M` is a subset closed under addition. -/ +structure AddSubsemigroup (M : Type*) [Add M] where + /-- The carrier of an additive subsemigroup. -/ + carrier : Set M + /-- The sum of two elements of an additive subsemigroup belongs to the subsemigroup. -/ + add_mem' {a b} : a ∈ carrier → b ∈ carrier → a + b ∈ carrier + +attribute [to_additive AddSubsemigroup] Subsemigroup + +namespace Subsemigroup + +@[to_additive] +instance : SetLike (Subsemigroup M) M := + ⟨Subsemigroup.carrier, fun p q h => by cases p; cases q; congr⟩ + +@[to_additive] +instance : MulMemClass (Subsemigroup M) M where mul_mem := fun {_ _ _} => Subsemigroup.mul_mem' _ + +initialize_simps_projections Subsemigroup (carrier → coe) +initialize_simps_projections AddSubsemigroup (carrier → coe) + +@[to_additive (attr := simp)] +theorem mem_carrier {s : Subsemigroup M} {x : M} : x ∈ s.carrier ↔ x ∈ s := + Iff.rfl + +@[to_additive (attr := simp)] +theorem mem_mk {s : Set M} {x : M} (h_mul) : x ∈ mk s h_mul ↔ x ∈ s := + Iff.rfl + +@[to_additive (attr := simp, norm_cast)] +theorem coe_set_mk (s : Set M) (h_mul) : (mk s h_mul : Set M) = s := + rfl + +@[to_additive (attr := simp)] +theorem mk_le_mk {s t : Set M} (h_mul) (h_mul') : mk s h_mul ≤ mk t h_mul' ↔ s ⊆ t := + Iff.rfl + +/-- Two subsemigroups are equal if they have the same elements. -/ +@[to_additive (attr := ext) "Two `AddSubsemigroup`s are equal if they have the same elements."] +theorem ext {S T : Subsemigroup M} (h : ∀ x, x ∈ S ↔ x ∈ T) : S = T := + SetLike.ext h + +/-- Copy a subsemigroup replacing `carrier` with a set that is equal to it. -/ +@[to_additive "Copy an additive subsemigroup replacing `carrier` with a set that is equal to it."] +protected def copy (S : Subsemigroup M) (s : Set M) (hs : s = S) : + Subsemigroup M where + carrier := s + mul_mem' := hs.symm ▸ S.mul_mem' + +variable {S : Subsemigroup M} + +@[to_additive (attr := simp)] +theorem coe_copy {s : Set M} (hs : s = S) : (S.copy s hs : Set M) = s := + rfl + +@[to_additive] +theorem copy_eq {s : Set M} (hs : s = S) : S.copy s hs = S := + SetLike.coe_injective hs + +variable (S) + +/-- A subsemigroup is closed under multiplication. -/ +@[to_additive "An `AddSubsemigroup` is closed under addition."] +protected theorem mul_mem {x y : M} : x ∈ S → y ∈ S → x * y ∈ S := + Subsemigroup.mul_mem' S + +/-- The subsemigroup `M` of the magma `M`. -/ +@[to_additive "The additive subsemigroup `M` of the magma `M`."] +instance : Top (Subsemigroup M) := + ⟨{ carrier := Set.univ + mul_mem' := fun _ _ => Set.mem_univ _ }⟩ + +/-- The trivial subsemigroup `∅` of a magma `M`. -/ +@[to_additive "The trivial `AddSubsemigroup` `∅` of an additive magma `M`."] +instance : Bot (Subsemigroup M) := + ⟨{ carrier := ∅ + mul_mem' := False.elim }⟩ + +@[to_additive] +instance : Inhabited (Subsemigroup M) := + ⟨⊥⟩ + +@[to_additive] +theorem not_mem_bot {x : M} : x ∉ (⊥ : Subsemigroup M) := + Set.not_mem_empty x + +@[to_additive (attr := simp)] +theorem mem_top (x : M) : x ∈ (⊤ : Subsemigroup M) := + Set.mem_univ x + +@[to_additive (attr := simp)] +theorem coe_top : ((⊤ : Subsemigroup M) : Set M) = Set.univ := + rfl + +@[to_additive (attr := simp)] +theorem coe_bot : ((⊥ : Subsemigroup M) : Set M) = ∅ := + rfl + +/-- The inf of two subsemigroups is their intersection. -/ +@[to_additive "The inf of two `AddSubsemigroup`s is their intersection."] +instance : Inf (Subsemigroup M) := + ⟨fun S₁ S₂ => + { carrier := S₁ ∩ S₂ + mul_mem' := fun ⟨hx, hx'⟩ ⟨hy, hy'⟩ => ⟨S₁.mul_mem hx hy, S₂.mul_mem hx' hy'⟩ }⟩ + +@[to_additive (attr := simp)] +theorem coe_inf (p p' : Subsemigroup M) : ((p ⊓ p' : Subsemigroup M) : Set M) = (p : Set M) ∩ p' := + rfl + +@[to_additive (attr := simp)] +theorem mem_inf {p p' : Subsemigroup M} {x : M} : x ∈ p ⊓ p' ↔ x ∈ p ∧ x ∈ p' := + Iff.rfl + +@[to_additive] +theorem subsingleton_of_subsingleton [Subsingleton (Subsemigroup M)] : Subsingleton M := by + constructor; intro x y + have : ∀ a : M, a ∈ (⊥ : Subsemigroup M) := by simp [Subsingleton.elim (⊥ : Subsemigroup M) ⊤] + exact absurd (this x) not_mem_bot + +@[to_additive] +instance [hn : Nonempty M] : Nontrivial (Subsemigroup M) := + ⟨⟨⊥, ⊤, fun h => by + obtain ⟨x⟩ := id hn + refine absurd (?_ : x ∈ ⊥) not_mem_bot + simp [h]⟩⟩ + +end Subsemigroup + +namespace MulHom + +variable [Mul N] + +open Subsemigroup + +/-- The subsemigroup of elements `x : M` such that `f x = g x` -/ +@[to_additive "The additive subsemigroup of elements `x : M` such that `f x = g x`"] +def eqLocus (f g : M →ₙ* N) : Subsemigroup M where + carrier := { x | f x = g x } + mul_mem' (hx : _ = _) (hy : _ = _) := by simp [*] + +@[to_additive] +theorem eq_of_eqOn_top {f g : M →ₙ* N} (h : Set.EqOn f g (⊤ : Subsemigroup M)) : f = g := + ext fun _ => h trivial + +end MulHom + +end NonAssoc From ae5f0c96b60b779d0f4266a52af54b51825f1e1d Mon Sep 17 00:00:00 2001 From: Johan Commelin Date: Mon, 14 Oct 2024 14:35:15 +0000 Subject: [PATCH 114/425] ci(nightly_detect_failure): restore dedup post logic (#17728) This reverts most of commit 3ad544d9d2e7bbd808fb00b0591cb8513764bc24, aka #17329. --- .github/workflows/nightly_detect_failure.yml | 29 ++++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/.github/workflows/nightly_detect_failure.yml b/.github/workflows/nightly_detect_failure.yml index 25835698e99ab6..0f52fa1c48fc2f 100644 --- a/.github/workflows/nightly_detect_failure.yml +++ b/.github/workflows/nightly_detect_failure.yml @@ -212,14 +212,25 @@ jobs: payload = f"🛠️: it looks like it's time to create a new bump/nightly-{current_version} branch from nightly-testing (specifically {sha}), and then PR that to {bump_branch}. " payload += "To do so semi-automatically, run the following script from mathlib root:\n\n" payload += f"```bash\n./scripts/create-adaptation-pr.sh --bumpversion={bump_branch_suffix} --nightlydate={current_version} --nightlysha={sha}\n```\n" - # Post the reminder message - request = { - 'type': 'stream', - 'to': 'nightly-testing', - 'topic': 'Mathlib bump branch reminders', - 'content': payload - } - result = client.send_message(request) - print(result) + # Only post if the message is different + # We compare the first 160 characters, since that includes the date and bump version + if not messages or messages[0]['content'][:160] != payload[:160]: + # Log messages, because the bot seems to repeat itself... + if messages: + print("###### Last message:") + print(messages[0]['content']) + print("###### Current message:") + print(payload) + else: + print('The strings match!') + # Post the reminder message + request = { + 'type': 'stream', + 'to': 'nightly-testing', + 'topic': 'Mathlib bump branch reminders', + 'content': payload + } + result = client.send_message(request) + print(result) else: print('No action needed.') From 9d4865df7a1250d29103d7b552678999859afaa6 Mon Sep 17 00:00:00 2001 From: Robin Carlier <57142648+robin-carlier@users.noreply.github.com> Date: Mon, 14 Oct 2024 15:20:23 +0000 Subject: [PATCH 115/425] feat(CategoryTheory/Limits/Final): Additional equational lemmas for cones extended along final functors (#17723) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an equational lemma for the natural transform of `extentedCocone` in case an explicit lift is already at hand, as well as the dual statement for initial functors. Co-authored-by: Joël Riou <37772949+joelriou@users.noreply.github.com> --- Mathlib/CategoryTheory/Limits/Final.lean | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Mathlib/CategoryTheory/Limits/Final.lean b/Mathlib/CategoryTheory/Limits/Final.lean index 64975ca699d17b..2341721a15f556 100644 --- a/Mathlib/CategoryTheory/Limits/Final.lean +++ b/Mathlib/CategoryTheory/Limits/Final.lean @@ -238,6 +238,17 @@ def extendCocone : Cocone (F ⋙ G) ⥤ Cocone G where · rw [← Functor.map_comp_assoc] } } map f := { hom := f.hom } +/-- Alternative equational lemma for `(extendCocone c).ι.app` in case a lift of the object +is given explicitly. -/ +lemma extendCocone_obj_ι_app' (c : Cocone (F ⋙ G)) {X : D} {Y : C} (f : X ⟶ F.obj Y) : + (extendCocone.obj c).ι.app X = G.map f ≫ c.ι.app Y := by + apply induction (k₀ := f) (z := rfl) F fun Z g => + G.map g ≫ c.ι.app Z = G.map f ≫ c.ι.app Y + · intro _ _ _ _ _ h₁ h₂ + simp [← h₁, ← Functor.comp_map, c.ι.naturality, h₂] + · intro _ _ _ _ _ h₁ h₂ + simp [← h₂, ← h₁, ← Functor.comp_map, c.ι.naturality] + @[simp] theorem colimit_cocone_comp_aux (s : Cocone (F ⋙ G)) (j : C) : G.map (homToLift F (F.obj j)) ≫ s.ι.app (lift F (F.obj j)) = s.ι.app j := by @@ -511,6 +522,17 @@ def extendCone : Cone (F ⋙ G) ⥤ Cone G where · rw [← Functor.map_comp] } } map f := { hom := f.hom } +/-- Alternative equational lemma for `(extendCone c).π.app` in case a lift of the object +is given explicitly. -/ +lemma extendCone_obj_π_app' (c : Cone (F ⋙ G)) {X : C} {Y : D} (f : F.obj X ⟶ Y) : + (extendCone.obj c).π.app Y = c.π.app X ≫ G.map f := by + apply induction (k₀ := f) (z := rfl) F fun Z g => + c.π.app Z ≫ G.map g = c.π.app X ≫ G.map f + · intro _ _ _ _ _ h₁ h₂ + simp [← h₂, ← h₁, ← Functor.comp_map, c.π.naturality] + · intro _ _ _ _ _ h₁ h₂ + simp [← h₁, ← Functor.comp_map, c.π.naturality, h₂] + @[simp] theorem limit_cone_comp_aux (s : Cone (F ⋙ G)) (j : C) : s.π.app (lift F (F.obj j)) ≫ G.map (homToLift F (F.obj j)) = s.π.app j := by From 00d0c1fc47d758fa4e4ec38e5101cffc77c0ea45 Mon Sep 17 00:00:00 2001 From: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com> Date: Mon, 14 Oct 2024 16:06:36 +0000 Subject: [PATCH 116/425] feat: an algebraically closed field is its own algebraic closure (#17720) --- Mathlib/FieldTheory/IsAlgClosed/Basic.lean | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mathlib/FieldTheory/IsAlgClosed/Basic.lean b/Mathlib/FieldTheory/IsAlgClosed/Basic.lean index f8ad1b02ce4a16..f4f1bcc97f7251 100644 --- a/Mathlib/FieldTheory/IsAlgClosed/Basic.lean +++ b/Mathlib/FieldTheory/IsAlgClosed/Basic.lean @@ -223,6 +223,10 @@ instance (priority := 100) IsAlgClosure.separable (R K : Type*) [Field R] [Field [IsAlgClosure R K] [CharZero R] : Algebra.IsSeparable R K := ⟨fun _ => (minpoly.irreducible (Algebra.IsIntegral.isIntegral _)).separable⟩ +instance IsAlgClosed.instIsAlgClosure (F : Type*) [Field F] [IsAlgClosed F] : IsAlgClosure F F where + isAlgClosed := ‹_› + isAlgebraic := .of_finite F F + namespace IsAlgClosed variable {K : Type u} [Field K] {L : Type v} {M : Type w} [Field L] [Algebra K L] [Field M] From 52637b2425406926d8082ae84f065e5688f35fa4 Mon Sep 17 00:00:00 2001 From: damiano Date: Mon, 14 Oct 2024 19:56:34 +0000 Subject: [PATCH 117/425] chore: removed unused variables (#17709) Found by #17715. --- Mathlib/Algebra/Group/Basic.lean | 8 +++---- .../Algebra/GroupWithZero/Action/Basic.lean | 2 +- Mathlib/Algebra/GroupWithZero/Commute.lean | 2 +- Mathlib/Algebra/Order/AddGroupWithTop.lean | 6 ++--- Mathlib/Algebra/Order/Field/InjSurj.lean | 2 +- Mathlib/Algebra/Order/Group/Abs.lean | 2 +- Mathlib/Algebra/Order/Group/Basic.lean | 2 +- Mathlib/Algebra/Order/Group/Defs.lean | 2 +- Mathlib/Algebra/Order/Group/Lattice.lean | 2 +- Mathlib/Algebra/Order/Group/OrderIso.lean | 4 ++-- Mathlib/Algebra/Order/Group/PosPart.lean | 2 +- .../Algebra/Order/Group/Unbundled/Abs.lean | 4 ++-- .../Order/GroupWithZero/Canonical.lean | 2 +- .../Order/GroupWithZero/Unbundled/Lemmas.lean | 2 +- Mathlib/Algebra/Order/Monoid/WithTop.lean | 4 ++-- Mathlib/Algebra/Order/Pi.lean | 5 +--- Mathlib/Algebra/Order/Positive/Ring.lean | 2 +- Mathlib/Algebra/Order/Ring/Canonical.lean | 2 +- Mathlib/Algebra/Order/Ring/Defs.lean | 14 +++++------ .../Algebra/Order/Ring/Unbundled/Basic.lean | 6 ++--- Mathlib/Algebra/Order/Sub/Basic.lean | 4 ++-- Mathlib/Algebra/Ring/Centralizer.lean | 2 +- Mathlib/Algebra/Ring/Divisibility/Basic.lean | 8 +++---- Mathlib/Analysis/Complex/OpenMapping.lean | 2 +- Mathlib/Analysis/Complex/Schwarz.lean | 2 +- .../Normed/Algebra/TrivSqZeroExt.lean | 6 ++--- .../CategoryTheory/GradedObject/Unitor.lean | 2 +- Mathlib/Data/List/MinMax.lean | 6 ++--- Mathlib/Data/Nat/Cast/Order/Basic.lean | 2 +- Mathlib/Data/Nat/Order/Lemmas.lean | 4 ---- Mathlib/Data/Set/NAry.lean | 5 ++-- Mathlib/Data/Set/Pairwise/Basic.lean | 6 ++--- Mathlib/Data/Set/Pairwise/Lattice.lean | 6 ++--- Mathlib/Data/Sum/Order.lean | 2 +- .../Manifold/ContMDiff/NormedSpace.lean | 24 +++++-------------- Mathlib/Geometry/Manifold/MFDeriv/Basic.lean | 2 +- .../ConditionalExpectation/AEMeasurable.lean | 13 ++++------ .../ConditionalExpectation/CondexpL2.lean | 2 +- .../ConditionalExpectation/Unique.lean | 2 +- Mathlib/Order/Antichain.lean | 2 +- Mathlib/Order/BooleanAlgebra.lean | 4 ++-- Mathlib/Order/CompleteBooleanAlgebra.lean | 8 +++---- Mathlib/Order/CompleteLattice.lean | 8 +++---- Mathlib/Order/Interval/Set/Basic.lean | 2 +- Mathlib/Order/Interval/Set/OrdConnected.lean | 4 ++-- Mathlib/Order/ScottContinuity.lean | 6 ++--- Mathlib/Order/SymmDiff.lean | 4 ++-- Mathlib/Tactic/FunProp/Differentiable.lean | 3 +-- Mathlib/Tactic/FunProp/RefinedDiscrTree.lean | 2 -- 49 files changed, 93 insertions(+), 125 deletions(-) diff --git a/Mathlib/Algebra/Group/Basic.lean b/Mathlib/Algebra/Group/Basic.lean index e00263356fbaf4..84357784965a1e 100644 --- a/Mathlib/Algebra/Group/Basic.lean +++ b/Mathlib/Algebra/Group/Basic.lean @@ -24,8 +24,6 @@ assert_not_exists DenselyOrdered open Function -universe u - variable {α β G M : Type*} section ite @@ -117,7 +115,7 @@ instance CommMagma.to_isCommutative [CommMagma G] : Std.Commutative (α := G) ( section MulOneClass -variable {M : Type u} [MulOneClass M] +variable [MulOneClass M] @[to_additive] theorem ite_mul_one {P : Prop} [Decidable P] {a b : M} : @@ -226,7 +224,7 @@ end CommMonoid section LeftCancelMonoid -variable {M : Type u} [LeftCancelMonoid M] {a b : M} +variable [LeftCancelMonoid M] {a b : M} @[to_additive (attr := simp)] theorem mul_right_eq_self : a * b = a ↔ b = 1 := calc @@ -247,7 +245,7 @@ end LeftCancelMonoid section RightCancelMonoid -variable {M : Type u} [RightCancelMonoid M] {a b : M} +variable [RightCancelMonoid M] {a b : M} @[to_additive (attr := simp)] theorem mul_left_eq_self : a * b = b ↔ a = 1 := calc diff --git a/Mathlib/Algebra/GroupWithZero/Action/Basic.lean b/Mathlib/Algebra/GroupWithZero/Action/Basic.lean index 616b74daf1af9f..f61edb220be6bc 100644 --- a/Mathlib/Algebra/GroupWithZero/Action/Basic.lean +++ b/Mathlib/Algebra/GroupWithZero/Action/Basic.lean @@ -51,7 +51,7 @@ group action open Function -variable {G G₀ A M N M₀ N₀ R α : Type*} +variable {G G₀ A M M₀ N₀ R α : Type*} section GroupWithZero variable [GroupWithZero G₀] [MulAction G₀ α] {a : G₀} diff --git a/Mathlib/Algebra/GroupWithZero/Commute.lean b/Mathlib/Algebra/GroupWithZero/Commute.lean index 24a2a0afe674be..5190f384c283e9 100644 --- a/Mathlib/Algebra/GroupWithZero/Commute.lean +++ b/Mathlib/Algebra/GroupWithZero/Commute.lean @@ -83,7 +83,7 @@ theorem div_left (hac : Commute a c) (hbc : Commute b c) : Commute (a / b) c := end Commute section GroupWithZero -variable {G₀ : Type*} [GroupWithZero G₀] +variable [GroupWithZero G₀] theorem pow_inv_comm₀ (a : G₀) (m n : ℕ) : a⁻¹ ^ m * a ^ n = a ^ n * a⁻¹ ^ m := (Commute.refl a).inv_left₀.pow_pow m n diff --git a/Mathlib/Algebra/Order/AddGroupWithTop.lean b/Mathlib/Algebra/Order/AddGroupWithTop.lean index a977f5a486e688..77246c1a05a1ce 100644 --- a/Mathlib/Algebra/Order/AddGroupWithTop.lean +++ b/Mathlib/Algebra/Order/AddGroupWithTop.lean @@ -25,7 +25,7 @@ whereas it is a very common target for valuations. The solutions is to use a typeclass, and that is exactly what we do in this file. -/ -variable {α β : Type*} +variable {α : Type*} /-- A linearly ordered commutative monoid with an additively absorbing `⊤` element. Instances should include number systems with an infinite element adjoined. -/ @@ -47,7 +47,7 @@ instance WithTop.linearOrderedAddCommMonoidWithTop [LinearOrderedAddCommMonoid top_add' := WithTop.top_add } section LinearOrderedAddCommMonoidWithTop -variable [LinearOrderedAddCommMonoidWithTop α] {a b c d x y z : α} {n : ℕ} +variable [LinearOrderedAddCommMonoidWithTop α] @[simp] theorem top_add (a : α) : ⊤ + a = ⊤ := @@ -65,7 +65,7 @@ open Function namespace LinearOrderedAddCommGroup -variable [LinearOrderedAddCommGroup α] {a b c d : α} +variable [LinearOrderedAddCommGroup α] instance instNeg : Neg (WithTop α) where neg := Option.map fun a : α => -a diff --git a/Mathlib/Algebra/Order/Field/InjSurj.lean b/Mathlib/Algebra/Order/Field/InjSurj.lean index 73fb2c67d8eace..771fd9b18fbb14 100644 --- a/Mathlib/Algebra/Order/Field/InjSurj.lean +++ b/Mathlib/Algebra/Order/Field/InjSurj.lean @@ -13,7 +13,7 @@ import Mathlib.Algebra.Order.Ring.InjSurj open Function OrderDual -variable {ι α β : Type*} +variable {α β : Type*} namespace Function.Injective variable [Zero β] [One β] [Add β] [Mul β] [Neg β] [Sub β] [Pow β ℕ] [SMul ℕ β] [SMul ℤ β] diff --git a/Mathlib/Algebra/Order/Group/Abs.lean b/Mathlib/Algebra/Order/Group/Abs.lean index 9693c189cfb6c7..12f0c643f7f22e 100644 --- a/Mathlib/Algebra/Order/Group/Abs.lean +++ b/Mathlib/Algebra/Order/Group/Abs.lean @@ -60,7 +60,7 @@ end LinearOrderedCommGroup section LinearOrderedAddCommGroup -variable [LinearOrderedAddCommGroup α] {a b c d : α} +variable [LinearOrderedAddCommGroup α] {a b c : α} -- Porting note: -- Lean can perfectly well find this instance, diff --git a/Mathlib/Algebra/Order/Group/Basic.lean b/Mathlib/Algebra/Order/Group/Basic.lean index bc99b34b1b8958..09aac4f739e3cc 100644 --- a/Mathlib/Algebra/Order/Group/Basic.lean +++ b/Mathlib/Algebra/Order/Group/Basic.lean @@ -15,7 +15,7 @@ assert_not_exists Set.Subsingleton open Function Int -variable {α M R : Type*} +variable {α : Type*} section OrderedCommGroup variable [OrderedCommGroup α] {m n : ℤ} {a b : α} diff --git a/Mathlib/Algebra/Order/Group/Defs.lean b/Mathlib/Algebra/Order/Group/Defs.lean index 7d7d5e71225f0a..a75ae0afc67113 100644 --- a/Mathlib/Algebra/Order/Group/Defs.lean +++ b/Mathlib/Algebra/Order/Group/Defs.lean @@ -109,7 +109,7 @@ class LinearOrderedCommGroup (α : Type u) extends OrderedCommGroup α, LinearOr section LinearOrderedCommGroup -variable [LinearOrderedCommGroup α] {a b c : α} +variable [LinearOrderedCommGroup α] {a : α} @[to_additive LinearOrderedAddCommGroup.add_lt_add_left] theorem LinearOrderedCommGroup.mul_lt_mul_left' (a b : α) (h : a < b) (c : α) : c * a < c * b := diff --git a/Mathlib/Algebra/Order/Group/Lattice.lean b/Mathlib/Algebra/Order/Group/Lattice.lean index d8a8bf48a1b20b..af14c9db3c4d1f 100644 --- a/Mathlib/Algebra/Order/Group/Lattice.lean +++ b/Mathlib/Algebra/Order/Group/Lattice.lean @@ -37,7 +37,7 @@ lattice, order, group open Function -variable {α β : Type*} +variable {α : Type*} section Group variable [Lattice α] [Group α] diff --git a/Mathlib/Algebra/Order/Group/OrderIso.lean b/Mathlib/Algebra/Order/Group/OrderIso.lean index f4cd51d207bb2e..925163de311e6b 100644 --- a/Mathlib/Algebra/Order/Group/OrderIso.lean +++ b/Mathlib/Algebra/Order/Group/OrderIso.lean @@ -25,7 +25,7 @@ variable [Group α] section TypeclassesLeftRightLE variable [LE α] [CovariantClass α α (· * ·) (· ≤ ·)] [CovariantClass α α (swap (· * ·)) (· ≤ ·)] - {a b c d : α} + {a b : α} section @@ -71,7 +71,7 @@ variable [Group α] [LE α] section Right -variable [CovariantClass α α (swap (· * ·)) (· ≤ ·)] {a b c d : α} +variable [CovariantClass α α (swap (· * ·)) (· ≤ ·)] {a : α} /-- `Equiv.mulRight` as an `OrderIso`. See also `OrderEmbedding.mulRight`. -/ @[to_additive (attr := simps! (config := { simpRhs := true }) toEquiv apply) diff --git a/Mathlib/Algebra/Order/Group/PosPart.lean b/Mathlib/Algebra/Order/Group/PosPart.lean index 8374c0a8ed405e..219b8fc413d442 100644 --- a/Mathlib/Algebra/Order/Group/PosPart.lean +++ b/Mathlib/Algebra/Order/Group/PosPart.lean @@ -43,7 +43,7 @@ positive part, negative part open Function -variable {α β : Type*} +variable {α : Type*} section Lattice variable [Lattice α] diff --git a/Mathlib/Algebra/Order/Group/Unbundled/Abs.lean b/Mathlib/Algebra/Order/Group/Unbundled/Abs.lean index 5ad660f7f4f373..bdbb144c055084 100644 --- a/Mathlib/Algebra/Order/Group/Unbundled/Abs.lean +++ b/Mathlib/Algebra/Order/Group/Unbundled/Abs.lean @@ -102,7 +102,7 @@ variable [CovariantClass α α (swap (· * ·)) (· ≤ ·)] end Group section CommGroup -variable [CommGroup α] [CovariantClass α α (· * ·) (· ≤ ·)] {a b : α} +variable [CommGroup α] [CovariantClass α α (· * ·) (· ≤ ·)] -- Banasiak Proposition 2.12, Zaanen 2nd lecture /-- The absolute value satisfies the triangle inequality. -/ @@ -204,7 +204,7 @@ variable [Group α] [LinearOrder α] {a b : α} @[to_additive] lemma lt_of_mabs_lt : |a|ₘ < b → a < b := (le_mabs_self _).trans_lt -variable [CovariantClass α α (· * ·) (· ≤ ·)] {a b c : α} +variable [CovariantClass α α (· * ·) (· ≤ ·)] {a b : α} @[to_additive (attr := simp) abs_pos] lemma one_lt_mabs : 1 < |a|ₘ ↔ a ≠ 1 := by obtain ha | rfl | ha := lt_trichotomy a 1 diff --git a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean index 1808690367f6d5..930a761c341ac1 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean @@ -49,7 +49,7 @@ instance (priority := 100) canonicallyOrderedAddCommMonoid.toZeroLeOneClass ⟨zero_le 1⟩ section LinearOrderedCommMonoidWithZero -variable [LinearOrderedCommMonoidWithZero α] {a b c d x y z : α} {n : ℕ} +variable [LinearOrderedCommMonoidWithZero α] {a b : α} {n : ℕ} /- The following facts are true more generally in a (linearly) ordered commutative monoid. diff --git a/Mathlib/Algebra/Order/GroupWithZero/Unbundled/Lemmas.lean b/Mathlib/Algebra/Order/GroupWithZero/Unbundled/Lemmas.lean index edc0cb47b953dc..0bbdd7163e56cd 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Unbundled/Lemmas.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Unbundled/Lemmas.lean @@ -12,7 +12,7 @@ import Mathlib.Order.Hom.Basic # Multiplication by a positive element as an order isomorphism -/ -variable {G₀} [GroupWithZero G₀] [Preorder G₀] [ZeroLEOneClass G₀] {a b c d : G₀} +variable {G₀} [GroupWithZero G₀] [Preorder G₀] [ZeroLEOneClass G₀] {a : G₀} /-- `Equiv.mulLeft₀` as an order isomorphism. -/ @[simps! (config := { simpRhs := true })] diff --git a/Mathlib/Algebra/Order/Monoid/WithTop.lean b/Mathlib/Algebra/Order/Monoid/WithTop.lean index 7ce0466e1bece9..b13f9b50c072bd 100644 --- a/Mathlib/Algebra/Order/Monoid/WithTop.lean +++ b/Mathlib/Algebra/Order/Monoid/WithTop.lean @@ -9,9 +9,9 @@ import Mathlib.Algebra.Order.Monoid.Canonical.Defs /-! # Adjoining top/bottom elements to ordered monoids. -/ -universe u v +universe u -variable {α : Type u} {β : Type v} +variable {α : Type u} open Function diff --git a/Mathlib/Algebra/Order/Pi.lean b/Mathlib/Algebra/Order/Pi.lean index 9710857e2382b4..601b52a20fee93 100644 --- a/Mathlib/Algebra/Order/Pi.lean +++ b/Mathlib/Algebra/Order/Pi.lean @@ -13,14 +13,11 @@ import Mathlib.Algebra.Ring.Pi This file defines instances for ordered group, monoid, and related structures on Pi types. -/ -variable {ι I α β γ : Type*} +variable {I α β γ : Type*} -- The indexing type variable {f : I → Type*} --- The family of types already equipped with instances -variable (x y : ∀ i, f i) (i : I) - namespace Pi /-- The product of a family of ordered commutative monoids is an ordered commutative monoid. -/ diff --git a/Mathlib/Algebra/Order/Positive/Ring.lean b/Mathlib/Algebra/Order/Positive/Ring.lean index 27a63fd2e72789..98d4be8046d53a 100644 --- a/Mathlib/Algebra/Order/Positive/Ring.lean +++ b/Mathlib/Algebra/Order/Positive/Ring.lean @@ -19,7 +19,7 @@ open Function namespace Positive -variable {M R K : Type*} +variable {M R : Type*} section AddBasic diff --git a/Mathlib/Algebra/Order/Ring/Canonical.lean b/Mathlib/Algebra/Order/Ring/Canonical.lean index 95f47cbf6819ff..3c450c7ad0c1a5 100644 --- a/Mathlib/Algebra/Order/Ring/Canonical.lean +++ b/Mathlib/Algebra/Order/Ring/Canonical.lean @@ -27,7 +27,7 @@ open Function universe u -variable {α : Type u} {β : Type*} +variable {α : Type u} /-- A canonically ordered commutative semiring is an ordered, commutative semiring in which `a ≤ b` iff there exists `c` with `b = a + c`. This is satisfied by the natural numbers, for example, but diff --git a/Mathlib/Algebra/Order/Ring/Defs.lean b/Mathlib/Algebra/Order/Ring/Defs.lean index 2a1301cc48fc21..d9128b14a9a37c 100644 --- a/Mathlib/Algebra/Order/Ring/Defs.lean +++ b/Mathlib/Algebra/Order/Ring/Defs.lean @@ -109,7 +109,7 @@ open Function universe u -variable {α : Type u} {β : Type*} +variable {α : Type u} /-! Note that `OrderDual` does not satisfy any of the ordered ring typeclasses due to the `zero_le_one` field. -/ @@ -195,7 +195,7 @@ class LinearOrderedCommRing (α : Type u) extends LinearOrderedRing α, CommMono section OrderedSemiring -variable [OrderedSemiring α] {a b c d : α} +variable [OrderedSemiring α] -- see Note [lower instance priority] instance (priority := 100) OrderedSemiring.zeroLEOneClass : ZeroLEOneClass α := { ‹OrderedSemiring α› with } @@ -212,7 +212,7 @@ end OrderedSemiring section OrderedRing -variable [OrderedRing α] {a b c d : α} +variable [OrderedRing α] {a b c : α} -- see Note [lower instance priority] instance (priority := 100) OrderedRing.toOrderedSemiring : OrderedSemiring α := @@ -252,7 +252,7 @@ end OrderedCommRing section StrictOrderedSemiring -variable [StrictOrderedSemiring α] {a b c d : α} +variable [StrictOrderedSemiring α] -- see Note [lower instance priority] instance (priority := 200) StrictOrderedSemiring.toPosMulStrictMono : PosMulStrictMono α := @@ -320,7 +320,7 @@ instance (priority := 100) StrictOrderedCommSemiring.toOrderedCommSemiring : end StrictOrderedCommSemiring section StrictOrderedRing -variable [StrictOrderedRing α] {a b c : α} +variable [StrictOrderedRing α] -- see Note [lower instance priority] instance (priority := 100) StrictOrderedRing.toStrictOrderedSemiring : StrictOrderedSemiring α := @@ -373,7 +373,7 @@ end StrictOrderedCommRing section LinearOrderedSemiring -variable [LinearOrderedSemiring α] {a b c d : α} +variable [LinearOrderedSemiring α] -- see Note [lower instance priority] instance (priority := 200) LinearOrderedSemiring.toPosMulReflectLT : PosMulReflectLT α := @@ -412,7 +412,7 @@ instance (priority := 100) LinearOrderedSemiring.toLinearOrderedCancelAddCommMon end LinearOrderedSemiring section LinearOrderedRing -variable [LinearOrderedRing α] {a b c : α} +variable [LinearOrderedRing α] attribute [local instance] LinearOrderedRing.decidableLE LinearOrderedRing.decidableLT diff --git a/Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean b/Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean index 5803021b2a9848..2aa45b63b34c9f 100644 --- a/Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean +++ b/Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean @@ -338,7 +338,7 @@ theorem mul_lt_of_one_lt_right [ExistsAddOfLE α] [PosMulStrictMono α] section Monotone -variable [Preorder β] {f g : β → α} +variable [Preorder β] {f : β → α} theorem strictAnti_mul_left [ExistsAddOfLE α] [PosMulStrictMono α] [CovariantClass α α (swap (· + ·)) (· < ·)] [ContravariantClass α α (swap (· + ·)) (· < ·)] @@ -409,7 +409,7 @@ end StrictOrderedSemiring section LinearOrderedSemiring -variable [Semiring α] [LinearOrder α] {a b c d : α} +variable [Semiring α] [LinearOrder α] {a b c : α} theorem nonneg_and_nonneg_or_nonpos_and_nonpos_of_mul_nonneg [MulPosStrictMono α] [PosMulStrictMono α] @@ -741,7 +741,7 @@ end LinearOrderedSemiring section LinearOrderedCommSemiring -variable [CommSemiring α] [LinearOrder α] {a b c d : α} +variable [CommSemiring α] [LinearOrder α] {a d : α} lemma max_mul_mul_le_max_mul_max [PosMulMono α] [MulPosMono α] (b c : α) (ha : 0 ≤ a) (hd : 0 ≤ d) : max (a * b) (d * c) ≤ max a c * max d b := diff --git a/Mathlib/Algebra/Order/Sub/Basic.lean b/Mathlib/Algebra/Order/Sub/Basic.lean index 79046c54164c00..b2d6abd8dd4359 100644 --- a/Mathlib/Algebra/Order/Sub/Basic.lean +++ b/Mathlib/Algebra/Order/Sub/Basic.lean @@ -16,7 +16,7 @@ variable {α : Type*} section CanonicallyOrderedAddCommMonoid -variable [CanonicallyOrderedAddCommMonoid α] [Sub α] [OrderedSub α] {a b c d : α} +variable [CanonicallyOrderedAddCommMonoid α] [Sub α] [OrderedSub α] {a b c : α} theorem add_tsub_cancel_iff_le : a + (b - a) = b ↔ a ≤ b := ⟨fun h => le_iff_exists_add.mpr ⟨b - a, h.symm⟩, add_tsub_cancel_of_le⟩ @@ -105,7 +105,7 @@ end CanonicallyOrderedAddCommMonoid section CanonicallyLinearOrderedAddCommMonoid -variable [CanonicallyLinearOrderedAddCommMonoid α] [Sub α] [OrderedSub α] {a b c d : α} +variable [CanonicallyLinearOrderedAddCommMonoid α] [Sub α] [OrderedSub α] {a b c : α} @[simp] theorem tsub_pos_iff_lt : 0 < a - b ↔ b < a := by rw [tsub_pos_iff_not_le, not_le] diff --git a/Mathlib/Algebra/Ring/Centralizer.lean b/Mathlib/Algebra/Ring/Centralizer.lean index 51c57241c8cdc3..1064da90c35ae7 100644 --- a/Mathlib/Algebra/Ring/Centralizer.lean +++ b/Mathlib/Algebra/Ring/Centralizer.lean @@ -11,7 +11,7 @@ import Mathlib.Algebra.Ring.Defs -/ -variable {M : Type*} {S T : Set M} +variable {M : Type*} {S : Set M} namespace Set diff --git a/Mathlib/Algebra/Ring/Divisibility/Basic.lean b/Mathlib/Algebra/Ring/Divisibility/Basic.lean index 5f1dd2b07ea5a6..dbe11489b614e8 100644 --- a/Mathlib/Algebra/Ring/Divisibility/Basic.lean +++ b/Mathlib/Algebra/Ring/Divisibility/Basic.lean @@ -58,7 +58,7 @@ end Semiring section NonUnitalCommSemiring -variable [NonUnitalCommSemiring α] [NonUnitalCommSemiring β] {a b c : α} +variable [NonUnitalCommSemiring α] theorem Dvd.dvd.linear_comb {d x y : α} (hdx : d ∣ x) (hdy : d ∣ y) (a b : α) : d ∣ a * x + b * y := dvd_add (hdx.mul_left a) (hdy.mul_left b) @@ -67,7 +67,7 @@ end NonUnitalCommSemiring section Semigroup -variable [Semigroup α] [HasDistribNeg α] {a b c : α} +variable [Semigroup α] [HasDistribNeg α] {a b : α} /-- An element `a` of a semigroup with a distributive negation divides the negation of an element `b` iff `a` divides `b`. -/ @@ -129,7 +129,7 @@ end NonUnitalRing section Ring -variable [Ring α] {a b c : α} +variable [Ring α] {a b : α} /-- An element a divides the sum a + b if and only if a divides b. -/ @[simp] @@ -155,7 +155,7 @@ end Ring section NonUnitalCommRing -variable [NonUnitalCommRing α] {a b c : α} +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 diff --git a/Mathlib/Analysis/Complex/OpenMapping.lean b/Mathlib/Analysis/Complex/OpenMapping.lean index c37d82d1058c9d..b926e8a60be915 100644 --- a/Mathlib/Analysis/Complex/OpenMapping.lean +++ b/Mathlib/Analysis/Complex/OpenMapping.lean @@ -36,7 +36,7 @@ open Set Filter Metric Complex open scoped Topology variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℂ E] {U : Set E} {f : ℂ → ℂ} {g : E → ℂ} - {z₀ w : ℂ} {ε r m : ℝ} + {z₀ : ℂ} {ε r : ℝ} /-- If the modulus of a holomorphic function `f` is bounded below by `ε` on a circle, then its range contains a disk of radius `ε / 2`. -/ diff --git a/Mathlib/Analysis/Complex/Schwarz.lean b/Mathlib/Analysis/Complex/Schwarz.lean index 4c91fb9c0f8901..9b43623115be13 100644 --- a/Mathlib/Analysis/Complex/Schwarz.lean +++ b/Mathlib/Analysis/Complex/Schwarz.lean @@ -56,7 +56,7 @@ namespace Complex section Space -variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℂ E] {R R₁ R₂ : ℝ} {f : ℂ → E} +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℂ E] {R₁ R₂ : ℝ} {f : ℂ → E} {c z z₀ : ℂ} /-- An auxiliary lemma for `Complex.norm_dslope_le_div_of_mapsTo_ball`. -/ diff --git a/Mathlib/Analysis/Normed/Algebra/TrivSqZeroExt.lean b/Mathlib/Analysis/Normed/Algebra/TrivSqZeroExt.lean index 5a779b05807658..64ad667b3190a4 100644 --- a/Mathlib/Analysis/Normed/Algebra/TrivSqZeroExt.lean +++ b/Mathlib/Analysis/Normed/Algebra/TrivSqZeroExt.lean @@ -264,10 +264,8 @@ noncomputable section Normed section Ring -variable [NormedCommRing S] [NormedRing R] [NormedAddCommGroup M] -variable [Algebra S R] [Module S M] [Module R M] [Module Rᵐᵒᵖ M] -variable [BoundedSMul S R] [BoundedSMul S M] [BoundedSMul R M] [BoundedSMul Rᵐᵒᵖ M] -variable [SMulCommClass R Rᵐᵒᵖ M] [IsScalarTower S R M] [IsScalarTower S Rᵐᵒᵖ M] +variable [NormedRing R] [NormedAddCommGroup M] [Module R M] [Module Rᵐᵒᵖ M] +variable [BoundedSMul R M] [BoundedSMul Rᵐᵒᵖ M] [SMulCommClass R Rᵐᵒᵖ M] instance instL1NormedAddCommGroup : NormedAddCommGroup (tsze R M) := inferInstanceAs <| NormedAddCommGroup (WithLp 1 <| R × M) diff --git a/Mathlib/CategoryTheory/GradedObject/Unitor.lean b/Mathlib/CategoryTheory/GradedObject/Unitor.lean index 6b90c959e367c6..b3491e4f57a7d6 100644 --- a/Mathlib/CategoryTheory/GradedObject/Unitor.lean +++ b/Mathlib/CategoryTheory/GradedObject/Unitor.lean @@ -230,7 +230,7 @@ lemma mapBifunctorRightUnitor_inv_apply (j : J) : e.inv.app (X j) ≫ (F.obj (X j)).map (singleObjApplyIso (0 : I) Y).inv ≫ ιMapBifunctorMapObj F p X ((single₀ I).obj Y) j 0 j (hp j) := rfl -variable {Y Y'} +variable {Y} @[reassoc] lemma mapBifunctorRightUnitor_inv_naturality : diff --git a/Mathlib/Data/List/MinMax.lean b/Mathlib/Data/List/MinMax.lean index b99e001bd5f4f0..6ba04976bda0c9 100644 --- a/Mathlib/Data/List/MinMax.lean +++ b/Mathlib/Data/List/MinMax.lean @@ -28,7 +28,7 @@ variable {α β : Type*} section ArgAux -variable (r : α → α → Prop) [DecidableRel r] {l : List α} {o : Option α} {a m : α} +variable (r : α → α → Prop) [DecidableRel r] {l : List α} {o : Option α} {a : α} /-- Auxiliary definition for `argmax` and `argmin`. -/ def argAux (a : Option α) (b : α) : Option α := @@ -88,7 +88,7 @@ end ArgAux section Preorder -variable [Preorder β] [@DecidableRel β (· < ·)] {f : α → β} {l : List α} {o : Option α} {a m : α} +variable [Preorder β] [@DecidableRel β (· < ·)] {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 @@ -154,7 +154,7 @@ end Preorder section LinearOrder -variable [LinearOrder β] {f : α → β} {l : List α} {o : Option α} {a m : α} +variable [LinearOrder β] {f : α → β} {l : List α} {a m : α} theorem le_of_mem_argmax : a ∈ l → m ∈ argmax f l → f a ≤ f m := fun ha hm => le_of_not_lt <| not_lt_of_mem_argmax ha hm diff --git a/Mathlib/Data/Nat/Cast/Order/Basic.lean b/Mathlib/Data/Nat/Cast/Order/Basic.lean index 392df917a8a697..06c79cba42b281 100644 --- a/Mathlib/Data/Nat/Cast/Order/Basic.lean +++ b/Mathlib/Data/Nat/Cast/Order/Basic.lean @@ -16,7 +16,7 @@ import Mathlib.Order.Hom.Basic assert_not_exists OrderedCommMonoid -variable {α β : Type*} +variable {α : Type*} namespace Nat diff --git a/Mathlib/Data/Nat/Order/Lemmas.lean b/Mathlib/Data/Nat/Order/Lemmas.lean index 72474ceef7eb53..415d72c229f276 100644 --- a/Mathlib/Data/Nat/Order/Lemmas.lean +++ b/Mathlib/Data/Nat/Order/Lemmas.lean @@ -15,10 +15,6 @@ They were separated for now to minimize the porting requirements for tactics during the transition to mathlib4. Please feel free to reorganize these two files. -/ -universe u v - -variable {a b m n k : ℕ} - namespace Nat /-! ### Sets -/ diff --git a/Mathlib/Data/Set/NAry.lean b/Mathlib/Data/Set/NAry.lean index cc3eaa655b1f2b..72515c986a9188 100644 --- a/Mathlib/Data/Set/NAry.lean +++ b/Mathlib/Data/Set/NAry.lean @@ -20,9 +20,8 @@ This file is very similar to `Data.Finset.NAry`, to `Order.Filter.NAry`, and to open Function namespace Set -variable {α α' β β' γ γ' δ δ' ε ε' ζ ζ' ν : Type*} {f f' : α → β → γ} {g g' : α → β → γ → δ} -variable {s s' : Set α} {t t' : Set β} {u u' : Set γ} {v : Set δ} {a a' : α} {b b' : β} {c c' : γ} - {d d' : δ} +variable {α α' β β' γ γ' δ δ' ε ε' ζ ζ' ν : Type*} {f f' : α → β → γ} +variable {s s' : Set α} {t t' : Set β} {u : Set γ} {v : Set δ} {a : α} {b : β} theorem mem_image2_iff (hf : Injective2 f) : f a b ∈ image2 f s t ↔ a ∈ s ∧ b ∈ t := ⟨by diff --git a/Mathlib/Data/Set/Pairwise/Basic.lean b/Mathlib/Data/Set/Pairwise/Basic.lean index a40768a7e768d4..7365c110ac476b 100644 --- a/Mathlib/Data/Set/Pairwise/Basic.lean +++ b/Mathlib/Data/Set/Pairwise/Basic.lean @@ -30,11 +30,11 @@ on `Set.PairwiseDisjoint`, even though the latter unfolds to something nicer. open Function Order Set -variable {α β γ ι ι' : Type*} {r p q : α → α → Prop} +variable {α β γ ι ι' : Type*} {r p : α → α → Prop} section Pairwise -variable {f g : ι → α} {s t u : Set α} {a b : α} +variable {f g : ι → α} {s t : Set α} {a b : α} theorem pairwise_on_bool (hr : Symmetric r) {a b : α} : Pairwise (r on fun c => cond c a b) ↔ r a b := by simpa [Pairwise, Function.onFun] using @hr a b @@ -311,7 +311,7 @@ end PartialOrderBot section SemilatticeInfBot -variable [SemilatticeInf α] [OrderBot α] {s t : Set ι} {f g : ι → α} +variable [SemilatticeInf α] [OrderBot α] {s : Set ι} {f : ι → α} -- classical theorem PairwiseDisjoint.elim' (hs : s.PairwiseDisjoint f) {i j : ι} (hi : i ∈ s) (hj : j ∈ s) diff --git a/Mathlib/Data/Set/Pairwise/Lattice.lean b/Mathlib/Data/Set/Pairwise/Lattice.lean index 6e82a9acdc83d6..c71e6effc04888 100644 --- a/Mathlib/Data/Set/Pairwise/Lattice.lean +++ b/Mathlib/Data/Set/Pairwise/Lattice.lean @@ -15,10 +15,10 @@ In this file we prove many facts about `Pairwise` and the set lattice. open Function Set Order -variable {α β γ ι ι' : Type*} {κ : Sort*} {r p q : α → α → Prop} +variable {α ι ι' : Type*} {κ : Sort*} {r : α → α → Prop} section Pairwise -variable {f g : ι → α} {s t u : Set α} {a b : α} +variable {f : ι → α} {s : Set α} namespace Set @@ -45,7 +45,7 @@ namespace Set section PartialOrderBot -variable [PartialOrder α] [OrderBot α] {s t : Set ι} {f g : ι → α} +variable [PartialOrder α] [OrderBot α] {s : Set ι} {f : ι → α} theorem pairwiseDisjoint_iUnion {g : ι' → Set ι} (h : Directed (· ⊆ ·) g) : (⋃ n, g n).PairwiseDisjoint f ↔ ∀ ⦃n⦄, (g n).PairwiseDisjoint f := diff --git a/Mathlib/Data/Sum/Order.lean b/Mathlib/Data/Sum/Order.lean index 6d1cf4426180c9..27fdc8c6c267a5 100644 --- a/Mathlib/Data/Sum/Order.lean +++ b/Mathlib/Data/Sum/Order.lean @@ -25,7 +25,7 @@ type synonym. -/ -variable {α β γ δ : Type*} +variable {α β γ : Type*} namespace Sum diff --git a/Mathlib/Geometry/Manifold/ContMDiff/NormedSpace.lean b/Mathlib/Geometry/Manifold/ContMDiff/NormedSpace.lean index 0b857f12e00f48..cf3347791e0510 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/NormedSpace.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/NormedSpace.lean @@ -15,7 +15,7 @@ import Mathlib.Analysis.NormedSpace.OperatorNorm.Prod -/ -open Set ChartedSpace SmoothManifoldWithCorners +open Set ChartedSpace open scoped Topology Manifold variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] @@ -23,27 +23,15 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} {M : Type*} [TopologicalSpace M] [ChartedSpace H M] - -- declare a smooth manifold `M'` over the pair `(E', H')`. - {E' : Type*} - [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] {H' : Type*} [TopologicalSpace H'] - {I' : ModelWithCorners 𝕜 E' H'} {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] - [SmoothManifoldWithCorners I' M'] - -- declare a smooth manifold `N` over the pair `(F, G)`. - {F : Type*} - [NormedAddCommGroup F] [NormedSpace 𝕜 F] {G : Type*} [TopologicalSpace G] - {J : ModelWithCorners 𝕜 F G} {N : Type*} [TopologicalSpace N] [ChartedSpace G N] - [SmoothManifoldWithCorners J N] - -- declare a smooth manifold `N'` over the pair `(F', G')`. - {F' : Type*} - [NormedAddCommGroup F'] [NormedSpace 𝕜 F'] {G' : Type*} [TopologicalSpace G'] - {J' : ModelWithCorners 𝕜 F' G'} {N' : Type*} [TopologicalSpace N'] [ChartedSpace G' N'] - [SmoothManifoldWithCorners J' N'] - -- F₁, F₂, F₃, F₄ are normed spaces + -- declare normed spaces `E'`, `F`, `F'`, `F₁`, `F₂`, `F₃`, `F₄`. + {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] + {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] + {F' : Type*} [NormedAddCommGroup F'] [NormedSpace 𝕜 F'] {F₁ : Type*} [NormedAddCommGroup F₁] [NormedSpace 𝕜 F₁] {F₂ : Type*} [NormedAddCommGroup F₂] [NormedSpace 𝕜 F₂] {F₃ : Type*} [NormedAddCommGroup F₃] [NormedSpace 𝕜 F₃] {F₄ : Type*} [NormedAddCommGroup F₄] [NormedSpace 𝕜 F₄] -- declare functions, sets, points and smoothness indices - {f f₁ : M → M'} {s t : Set M} {x : M} {m n : ℕ∞} + {s : Set M} {x : M} {n : ℕ∞} section Module diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean b/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean index 077f6308962443..b1835322451ff5 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Basic.lean @@ -42,7 +42,7 @@ variable {E'' : Type*} [NormedAddCommGroup E''] [NormedSpace 𝕜 E''] {H'' : Type*} [TopologicalSpace H''] {I'' : ModelWithCorners 𝕜 E'' H''} {M'' : Type*} [TopologicalSpace M''] [ChartedSpace H'' M''] - {f f₀ f₁ : M → M'} {x : M} {s t : Set M} {g : M' → M''} {u : Set 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 unfold UniqueMDiffWithinAt diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/AEMeasurable.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/AEMeasurable.lean index 98a2a41d0a2794..bf52c95cfaeaa9 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/AEMeasurable.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/AEMeasurable.lean @@ -175,17 +175,12 @@ theorem AEStronglyMeasurable'.aeStronglyMeasurable'_of_measurableSpace_le_on {α hf_ind.stronglyMeasurable_of_measurableSpace_le_on hs_m hs fun x hxs => Set.indicator_of_not_mem hxs _ -variable {α E' F F' 𝕜 : Type*} {p : ℝ≥0∞} [RCLike 𝕜] +variable {α F F' 𝕜 : Type*} {p : ℝ≥0∞} [RCLike 𝕜] -- 𝕜 for ℝ or ℂ - -- E' for an inner product space on which we compute integrals - [NormedAddCommGroup E'] - [InnerProductSpace 𝕜 E'] [CompleteSpace E'] [NormedSpace ℝ E'] -- F for a Lp submodule - [NormedAddCommGroup F] - [NormedSpace 𝕜 F] + [NormedAddCommGroup F] [NormedSpace 𝕜 F] -- F' for integrals on a Lp submodule - [NormedAddCommGroup F'] - [NormedSpace 𝕜 F'] [NormedSpace ℝ F'] [CompleteSpace F'] + [NormedAddCommGroup F'] [NormedSpace 𝕜 F'] [NormedSpace ℝ F'] section LpMeas @@ -257,7 +252,7 @@ measure `μ.trim hm`. As a consequence, the completeness of `Lp` implies complet `lpMeasSubgroup` (and `lpMeas`). -/ -variable {ι : Type*} {m m0 : MeasurableSpace α} {μ : Measure α} +variable {m m0 : MeasurableSpace α} {μ : Measure α} /-- If `f` belongs to `lpMeasSubgroup F m p μ`, then the measurable function it is almost everywhere equal to (given by `AEMeasurable.mk`) belongs to `ℒp` for the measure `μ.trim hm`. -/ diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean index 577dc56ee22e50..31ce53180ae05c 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean @@ -38,7 +38,7 @@ open scoped ENNReal Topology MeasureTheory namespace MeasureTheory -variable {α E E' F G G' 𝕜 : Type*} {p : ℝ≥0∞} [RCLike 𝕜] +variable {α E E' F G G' 𝕜 : Type*} [RCLike 𝕜] -- 𝕜 for ℝ or ℂ -- E for an inner product space [NormedAddCommGroup E] diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Unique.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Unique.lean index ef56edebde96d0..aa7f322d0889d7 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/Unique.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/Unique.lean @@ -37,7 +37,7 @@ variable {α E' F' 𝕜 : Type*} {p : ℝ≥0∞} {m m0 : MeasurableSpace α} { [InnerProductSpace 𝕜 E'] [CompleteSpace E'] [NormedSpace ℝ E'] -- F' for integrals on a Lp submodule [NormedAddCommGroup F'] - [NormedSpace 𝕜 F'] [NormedSpace ℝ F'] [CompleteSpace F'] + [NormedSpace ℝ F'] [CompleteSpace F'] section UniquenessOfConditionalExpectation diff --git a/Mathlib/Order/Antichain.lean b/Mathlib/Order/Antichain.lean index 3361bfcc25257c..4548a1da022cf8 100644 --- a/Mathlib/Order/Antichain.lean +++ b/Mathlib/Order/Antichain.lean @@ -297,7 +297,7 @@ end General section Pi variable {ι : Type*} {α : ι → Type*} [∀ i, Preorder (α i)] {s t : Set (∀ i, α i)} - {a b c : ∀ i, α i} + {a b : ∀ i, α i} @[inherit_doc] diff --git a/Mathlib/Order/BooleanAlgebra.lean b/Mathlib/Order/BooleanAlgebra.lean index 3d8e0ff5b03f0d..60726797718c40 100644 --- a/Mathlib/Order/BooleanAlgebra.lean +++ b/Mathlib/Order/BooleanAlgebra.lean @@ -58,7 +58,7 @@ open Function OrderDual universe u v -variable {α : Type u} {β : Type*} {w x y z : α} +variable {α : Type u} {β : Type*} {x y z : α} /-! ### Generalized Boolean algebras @@ -779,7 +779,7 @@ instance PUnit.instBooleanAlgebra : BooleanAlgebra PUnit where namespace DistribLattice -variable (α : Type*) [DistribLattice α] +variable (α) [DistribLattice α] /-- An alternative constructor for boolean algebras: diff --git a/Mathlib/Order/CompleteBooleanAlgebra.lean b/Mathlib/Order/CompleteBooleanAlgebra.lean index 8cec133540ae24..8a3e49b9fc5b81 100644 --- a/Mathlib/Order/CompleteBooleanAlgebra.lean +++ b/Mathlib/Order/CompleteBooleanAlgebra.lean @@ -200,7 +200,7 @@ abbrev ofMinimalAxioms (minAx : MinimalAxioms α) : Coframe α where end Order.Coframe namespace CompleteDistribLattice.MinimalAxioms -variable (minAx : MinimalAxioms α) {s : Set α} {a b : α} +variable (minAx : MinimalAxioms α) /-- The `CompleteDistribLattice.MinimalAxioms` element corresponding to a complete distrib lattice. -/ @@ -502,7 +502,7 @@ end Coframe section CompleteDistribLattice -variable [CompleteDistribLattice α] {a b : α} {s t : Set α} +variable [CompleteDistribLattice α] instance OrderDual.instCompleteDistribLattice [CompleteDistribLattice α] : CompleteDistribLattice αᵒᵈ where @@ -578,7 +578,7 @@ instance OrderDual.instCompleteBooleanAlgebra [CompleteBooleanAlgebra α] : section CompleteBooleanAlgebra -variable [CompleteBooleanAlgebra α] {a b : α} {s : Set α} {f : ι → α} +variable [CompleteBooleanAlgebra α] {s : Set α} {f : ι → α} theorem compl_iInf : (iInf f)ᶜ = ⨆ i, (f i)ᶜ := le_antisymm @@ -821,7 +821,7 @@ end lift namespace PUnit -variable (s : Set PUnit.{u + 1}) (x y : PUnit.{u + 1}) +variable (s : Set PUnit.{u + 1}) instance instCompleteAtomicBooleanAlgebra : CompleteAtomicBooleanAlgebra PUnit where __ := PUnit.instBooleanAlgebra diff --git a/Mathlib/Order/CompleteLattice.lean b/Mathlib/Order/CompleteLattice.lean index ae7c9a34e17c82..dc192f4a528ec2 100644 --- a/Mathlib/Order/CompleteLattice.lean +++ b/Mathlib/Order/CompleteLattice.lean @@ -362,7 +362,7 @@ theorem ofDual_iInf [SupSet α] (f : ι → αᵒᵈ) : ofDual (⨅ i, f i) = end OrderDual -variable [CompleteLattice α] {s t : Set α} {a b : α} +variable [CompleteLattice α] {s t : Set α} {b : α} theorem sInf_le_sSup (hs : s.Nonempty) : sInf s ≤ sSup s := isGLB_le_isLUB (isGLB_sInf s) (isLUB_sSup s) hs @@ -468,7 +468,7 @@ end section CompleteLinearOrder -variable [CompleteLinearOrder α] {s t : Set α} {a b : α} +variable [CompleteLinearOrder α] {s : Set α} {a b : α} theorem lt_sSup_iff : b < sSup s ↔ ∃ a ∈ s, b < a := lt_isLUB_iff <| isLUB_sSup s @@ -616,7 +616,7 @@ end InfSet section -variable [CompleteLattice α] {f g s t : ι → α} {a b : α} +variable [CompleteLattice α] {f g s : ι → α} {a b : α} theorem le_iSup (f : ι → α) (i : ι) : f i ≤ iSup f := le_sSup ⟨i, rfl⟩ @@ -1548,7 +1548,7 @@ theorem binary_relation_sInf_iff {α β : Type*} (s : Set (α → β → Prop)) section CompleteLattice -variable {ι : Sort*} [Preorder α] [CompleteLattice β] {s : Set (α → β)} {f : ι → α → β} +variable [Preorder α] [CompleteLattice β] {s : Set (α → β)} {f : ι → α → β} protected lemma Monotone.sSup (hs : ∀ f ∈ s, Monotone f) : Monotone (sSup s) := fun _ _ h ↦ iSup_mono fun f ↦ hs f f.2 h diff --git a/Mathlib/Order/Interval/Set/Basic.lean b/Mathlib/Order/Interval/Set/Basic.lean index aa5fb56defb3c1..3dc63cebf960e9 100644 --- a/Mathlib/Order/Interval/Set/Basic.lean +++ b/Mathlib/Order/Interval/Set/Basic.lean @@ -1481,7 +1481,7 @@ end Lattice section LinearOrder -variable [LinearOrder α] [LinearOrder β] {f : α → β} {a a₁ a₂ b b₁ b₂ c d : α} +variable [LinearOrder α] {a a₁ a₂ b b₁ b₂ c : α} @[simp] theorem Ioi_inter_Ioi : Ioi a ∩ Ioi b = Ioi (a ⊔ b) := diff --git a/Mathlib/Order/Interval/Set/OrdConnected.lean b/Mathlib/Order/Interval/Set/OrdConnected.lean index 85255d6b9f7447..cf733bc167f203 100644 --- a/Mathlib/Order/Interval/Set/OrdConnected.lean +++ b/Mathlib/Order/Interval/Set/OrdConnected.lean @@ -27,7 +27,7 @@ namespace Set section Preorder -variable {α β : Type*} [Preorder α] [Preorder β] {s t : Set α} +variable {α β : Type*} [Preorder α] [Preorder β] {s : Set α} /-- 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 @@ -101,7 +101,7 @@ namespace Set section Preorder -variable {α β : Type*} [Preorder α] [Preorder β] {s t : Set α} +variable {α β : Type*} [Preorder α] [Preorder β] @[simp] lemma image_subtype_val_Icc {s : Set α} [OrdConnected s] (x y : s) : diff --git a/Mathlib/Order/ScottContinuity.lean b/Mathlib/Order/ScottContinuity.lean index 511092cd0a0006..5ed5137f7bd160 100644 --- a/Mathlib/Order/ScottContinuity.lean +++ b/Mathlib/Order/ScottContinuity.lean @@ -32,8 +32,8 @@ open Set variable {α β : Type*} section ScottContinuous -variable [Preorder α] [Preorder β] {D D₁ D₂ : Set (Set α)} {E : Set (Set β)} - {f : α → β} {a : α} +variable [Preorder α] [Preorder β] {D D₁ D₂ : Set (Set α)} + {f : α → β} /-- A function between preorders is said to be Scott continuous on a set `D` of directed sets if it preserves `IsLUB` on elements of `D`. @@ -109,7 +109,7 @@ end ScottContinuous section SemilatticeSup -variable [Preorder α] [SemilatticeSup β] +variable [SemilatticeSup β] lemma ScottContinuousOn.sup₂ {D : Set (Set (β × β))} : ScottContinuousOn D fun (a, b) => (a ⊔ b : β) := by diff --git a/Mathlib/Order/SymmDiff.lean b/Mathlib/Order/SymmDiff.lean index fa8d23d3aa0818..439253b07c5a39 100644 --- a/Mathlib/Order/SymmDiff.lean +++ b/Mathlib/Order/SymmDiff.lean @@ -89,7 +89,7 @@ theorem Bool.symmDiff_eq_xor : ∀ p q : Bool, p ∆ q = xor p q := by decide section GeneralizedCoheytingAlgebra -variable [GeneralizedCoheytingAlgebra α] (a b c d : α) +variable [GeneralizedCoheytingAlgebra α] (a b c : α) @[simp] theorem toDual_symmDiff : toDual (a ∆ b) = toDual a ⇔ toDual b := @@ -192,7 +192,7 @@ end GeneralizedCoheytingAlgebra section GeneralizedHeytingAlgebra -variable [GeneralizedHeytingAlgebra α] (a b c d : α) +variable [GeneralizedHeytingAlgebra α] (a b c : α) @[simp] theorem toDual_bihimp : toDual (a ⇔ b) = toDual a ∆ toDual b := diff --git a/Mathlib/Tactic/FunProp/Differentiable.lean b/Mathlib/Tactic/FunProp/Differentiable.lean index 1d81eec7d76f28..a692cd880dab52 100644 --- a/Mathlib/Tactic/FunProp/Differentiable.lean +++ b/Mathlib/Tactic/FunProp/Differentiable.lean @@ -29,8 +29,7 @@ variable {K : Type*} [NontriviallyNormedField K] variable {E : Type*} [NormedAddCommGroup E] [NormedSpace K E] variable {F : Type*} [NormedAddCommGroup F] [NormedSpace K F] variable {G : Type*} [NormedAddCommGroup G] [NormedSpace K G] -variable {G' : Type*} [NormedAddCommGroup G'] [NormedSpace K G'] -variable {f f₀ f₁ g : E → F} {x} {s t} +variable {f : E → F} {x} {s} theorem differentiableOn_id' : DifferentiableOn K (fun x : E => x) s := diff --git a/Mathlib/Tactic/FunProp/RefinedDiscrTree.lean b/Mathlib/Tactic/FunProp/RefinedDiscrTree.lean index 141a5bb8191074..876dc3a14dc351 100644 --- a/Mathlib/Tactic/FunProp/RefinedDiscrTree.lean +++ b/Mathlib/Tactic/FunProp/RefinedDiscrTree.lean @@ -864,8 +864,6 @@ def mkDTExprs (e : Expr) (config : WhnfCoreConfig) (onlySpecific : Bool) /-! ## Inserting intro a RefinedDiscrTree -/ -variable {α : Type} - /-- If `vs` contains an element `v'` such that `v == v'`, then replace `v'` with `v`. Otherwise, push `v`. See issue #2155 From 9ea3a96243502a6b8bbdf9c6a3187e26101ded89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Calle=20S=C3=B6nne?= Date: Mon, 14 Oct 2024 20:54:24 +0000 Subject: [PATCH 118/425] feat(Tactic/Algebraize): fix mistake in algebraize tactic (#17737) The call to `algebraize` is missing a `withMainContext` causing it to not be able to find previously defined `let` bindings. See [zulip](https://leanprover.zulipchat.com/#narrow/stream/144837-PR-reviews/topic/.2314798.20.20relations.20between.20trace.20maps.20and.20quotients) --- Mathlib/Tactic/Algebraize.lean | 2 +- test/algebraize.lean | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Mathlib/Tactic/Algebraize.lean b/Mathlib/Tactic/Algebraize.lean index 74c3a9eaf82309..96ceb855e0cb11 100644 --- a/Mathlib/Tactic/Algebraize.lean +++ b/Mathlib/Tactic/Algebraize.lean @@ -256,7 +256,7 @@ so in other words it only adds `Algebra` and `IsScalarTower` instances. -/ syntax "algebraize" (ppSpace config)? (ppSpace algebraizeTermSeq)? : tactic elab_rules : tactic - | `(tactic| algebraize $[$config]? $args) => do + | `(tactic| algebraize $[$config]? $args) => withMainContext do let cfg ← elabAlgebraizeConfig (mkOptionalNode config) let t ← match args with | `(algebraizeTermSeq| [$rs,*]) => rs.getElems.mapM fun i => Term.elabTerm i none diff --git a/test/algebraize.lean b/test/algebraize.lean index 7cebc3123da0a7..c2aa17892ab571 100644 --- a/test/algebraize.lean +++ b/test/algebraize.lean @@ -50,6 +50,15 @@ example (A B : Type*) [CommRing A] [CommRing B] (f : A →+* B) : True := by guard_hyp algInst := f.toAlgebra trivial +/-- Synthesize algebra instance from ring hom defined using a `let` statement. -/ +example (A B : Type*) [CommRing A] [CommRing B] (f : A →+* B) : True := by + let f' : A →+* B := f + fail_if_success -- Check that this instance is not available by default + have h : Algebra A B := inferInstance + algebraize [f'] + guard_hyp algInst := f'.toAlgebra + trivial + /-- Synthesize algebra instance from a composition -/ example (A B C : Type*) [CommRing A] [CommRing B] [CommRing C] (f : A →+* B) (g : B →+* C) : True := by From fa858033452c8217e036b23ca7e812ed0f13cd70 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Mon, 14 Oct 2024 23:36:33 +0000 Subject: [PATCH 119/425] feat: add a FloorSemiring instance to NNRat (#13548) Also some missing `norm_cast` lemmas for inequalities of casts between different types. --- Mathlib.lean | 1 + Mathlib/Data/NNRat/Defs.lean | 4 ++ Mathlib/Data/NNRat/Floor.lean | 90 ++++++++++++++++++++++++++++++++ Mathlib/Data/Rat/Cast/Order.lean | 48 +++++++++++++++++ Mathlib/Data/Rat/Floor.lean | 19 +++++-- 5 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 Mathlib/Data/NNRat/Floor.lean diff --git a/Mathlib.lean b/Mathlib.lean index 8dff03b97436aa..48b265283a8c79 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2402,6 +2402,7 @@ import Mathlib.Data.Multiset.Sum import Mathlib.Data.Multiset.Sym import Mathlib.Data.NNRat.BigOperators import Mathlib.Data.NNRat.Defs +import Mathlib.Data.NNRat.Floor import Mathlib.Data.NNRat.Lemmas import Mathlib.Data.NNRat.Order import Mathlib.Data.NNReal.Basic diff --git a/Mathlib/Data/NNRat/Defs.lean b/Mathlib/Data/NNRat/Defs.lean index e41ecbe750139c..2c17c0c61fcc18 100644 --- a/Mathlib/Data/NNRat/Defs.lean +++ b/Mathlib/Data/NNRat/Defs.lean @@ -106,8 +106,12 @@ theorem coe_nonneg (q : ℚ≥0) : (0 : ℚ) ≤ q := q.2 @[simp, norm_cast] lemma coe_zero : ((0 : ℚ≥0) : ℚ) = 0 := rfl +@[simp] lemma num_zero : num 0 = 0 := rfl +@[simp] lemma den_zero : den 0 = 1 := rfl @[simp, norm_cast] lemma coe_one : ((1 : ℚ≥0) : ℚ) = 1 := rfl +@[simp] lemma num_one : num 1 = 1 := rfl +@[simp] lemma den_one : den 1 = 1 := rfl @[simp, norm_cast] theorem coe_add (p q : ℚ≥0) : ((p + q : ℚ≥0) : ℚ) = p + q := diff --git a/Mathlib/Data/NNRat/Floor.lean b/Mathlib/Data/NNRat/Floor.lean new file mode 100644 index 00000000000000..9fffafbea69950 --- /dev/null +++ b/Mathlib/Data/NNRat/Floor.lean @@ -0,0 +1,90 @@ +/- +Copyright (c) 2024 Eric Wieser. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Eric Wieser +-/ +import Mathlib.Data.Rat.Floor + +/-! +# Floor Function for Non-negative Rational Numbers + +## Summary + +We define the `FloorSemiring` instance on `ℚ≥0`, and relate its operators to `NNRat.cast`. + +Note that we cannot talk about `Int.fract`, which currently only works for rings. + +## Tags + +nnrat, rationals, ℚ≥0, floor +-/ + +namespace NNRat + +instance : FloorSemiring ℚ≥0 where + floor q := ⌊q.val⌋₊ + ceil q := ⌈q.val⌉₊ + floor_of_neg h := by simpa using h.trans zero_lt_one + gc_floor {a n} h := by rw [← NNRat.coe_le_coe, Nat.le_floor_iff] <;> norm_cast + gc_ceil {a b} := by rw [← NNRat.coe_le_coe, Nat.ceil_le]; norm_cast + +@[simp, norm_cast] +theorem floor_coe (q : ℚ≥0) : ⌊(q : ℚ)⌋₊ = ⌊q⌋₊ := rfl + +@[simp, norm_cast] +theorem ceil_coe (q : ℚ≥0) : ⌈(q : ℚ)⌉₊ = ⌈q⌉₊ := rfl + +@[simp, norm_cast] +theorem coe_floor (q : ℚ≥0) : ↑⌊q⌋₊ = ⌊(q : ℚ)⌋ := Int.natCast_floor_eq_floor q.coe_nonneg + +@[simp, norm_cast] +theorem coe_ceil (q : ℚ≥0) : ↑⌈q⌉₊ = ⌈(q : ℚ)⌉ := Int.natCast_ceil_eq_ceil q.coe_nonneg + +protected theorem floor_def (q : ℚ≥0) : ⌊q⌋₊ = q.num / q.den := by + rw [← Int.natCast_inj, NNRat.coe_floor, Rat.floor_def, Int.ofNat_ediv, den_coe, num_coe] + +section Semifield + +variable {K} [LinearOrderedSemifield K] [FloorSemiring K] + +@[simp, norm_cast] +theorem floor_cast (x : ℚ≥0) : ⌊(x : K)⌋₊ = ⌊x⌋₊ := + (Nat.floor_eq_iff x.cast_nonneg).2 (mod_cast (Nat.floor_eq_iff x.cast_nonneg).1 (Eq.refl ⌊x⌋₊)) + +@[simp, norm_cast] +theorem ceil_cast (x : ℚ≥0) : ⌈(x : K)⌉₊ = ⌈x⌉₊ := by + obtain rfl | hx := eq_or_ne x 0 + · simp + · refine (Nat.ceil_eq_iff ?_).2 (mod_cast (Nat.ceil_eq_iff ?_).1 (Eq.refl ⌈x⌉₊)) <;> simpa + +end Semifield + +section Field + +variable {K} [LinearOrderedField K] [FloorRing K] + +@[simp, norm_cast] +theorem intFloor_cast (x : ℚ≥0) : ⌊(x : K)⌋ = ⌊(x : ℚ)⌋ := by + rw [Int.floor_eq_iff (α := K), ← coe_floor] + norm_cast + norm_cast + rw [Nat.cast_add_one, ← Nat.floor_eq_iff (zero_le _)] + +@[simp, norm_cast] +theorem intCeil_cast (x : ℚ≥0) : ⌈(x : K)⌉ = ⌈(x : ℚ)⌉ := by + rw [Int.ceil_eq_iff, ← coe_ceil, sub_lt_iff_lt_add] + constructor + · have := NNRat.cast_strictMono (K := K) <| Nat.ceil_lt_add_one <| zero_le x + rw [NNRat.cast_add, NNRat.cast_one] at this + refine Eq.trans_lt ?_ this + norm_cast + · rw [Int.cast_natCast, NNRat.cast_le_natCast] + exact Nat.le_ceil _ + +end Field + +@[norm_cast] +theorem floor_natCast_div_natCast (n d : ℕ) : ⌊(↑n / ↑d : ℚ≥0)⌋₊ = n / d := + Rat.natFloor_natCast_div_natCast n d + +end NNRat diff --git a/Mathlib/Data/Rat/Cast/Order.lean b/Mathlib/Data/Rat/Cast/Order.lean index 2a4ebd3ceadb25..2a1d627e9d6b0f 100644 --- a/Mathlib/Data/Rat/Cast/Order.lean +++ b/Mathlib/Data/Rat/Cast/Order.lean @@ -54,6 +54,38 @@ def castOrderEmbedding : ℚ ↪o K := @[simp] lemma cast_lt_zero : (q : K) < 0 ↔ q < 0 := by norm_cast +@[simp, norm_cast] +theorem cast_le_natCast {m : ℚ} {n : ℕ} : (m : K) ≤ n ↔ m ≤ (n : ℚ) := by + rw [← cast_le (K := K), cast_natCast] + +@[simp, norm_cast] +theorem natCast_le_cast {m : ℕ} {n : ℚ} : (m : K) ≤ n ↔ (m : ℚ) ≤ n := by + rw [← cast_le (K := K), cast_natCast] + +@[simp, norm_cast] +theorem cast_le_intCast {m : ℚ} {n : ℤ} : (m : K) ≤ n ↔ m ≤ (n : ℚ) := by + rw [← cast_le (K := K), cast_intCast] + +@[simp, norm_cast] +theorem intCast_le_cast {m : ℤ} {n : ℚ} : (m : K) ≤ n ↔ (m : ℚ) ≤ n := by + rw [← cast_le (K := K), cast_intCast] + +@[simp, norm_cast] +theorem cast_lt_natCast {m : ℚ} {n : ℕ} : (m : K) < n ↔ m < (n : ℚ) := by + rw [← cast_lt (K := K), cast_natCast] + +@[simp, norm_cast] +theorem natCast_lt_cast {m : ℕ} {n : ℚ} : (m : K) < n ↔ (m : ℚ) < n := by + rw [← cast_lt (K := K), cast_natCast] + +@[simp, norm_cast] +theorem cast_lt_intCast {m : ℚ} {n : ℤ} : (m : K) < n ↔ m < (n : ℚ) := by + rw [← cast_lt (K := K), cast_intCast] + +@[simp, norm_cast] +theorem intCast_lt_cast {m : ℤ} {n : ℚ} : (m : K) < n ↔ (m : ℚ) < n := by + rw [← cast_lt (K := K), cast_intCast] + @[simp, norm_cast] lemma cast_min (p q : ℚ) : (↑(min p q) : K) = min (p : K) (q : K) := (@cast_mono K _).map_min @@ -154,6 +186,22 @@ variable {n : ℕ} [n.AtLeastTwo] end ofNat +@[simp, norm_cast] +theorem cast_le_natCast {m : ℚ≥0} {n : ℕ} : (m : K) ≤ n ↔ m ≤ (n : ℚ≥0) := by + rw [← cast_le (K := K), cast_natCast] + +@[simp, norm_cast] +theorem natCast_le_cast {m : ℕ} {n : ℚ≥0} : (m : K) ≤ n ↔ (m : ℚ≥0) ≤ n := by + rw [← cast_le (K := K), cast_natCast] + +@[simp, norm_cast] +theorem cast_lt_natCast {m : ℚ≥0} {n : ℕ} : (m : K) < n ↔ m < (n : ℚ≥0) := by + rw [← cast_lt (K := K), cast_natCast] + +@[simp, norm_cast] +theorem natCast_lt_cast {m : ℕ} {n : ℚ≥0} : (m : K) < n ↔ (m : ℚ≥0) < n := by + rw [← cast_lt (K := K), cast_natCast] + @[simp, norm_cast] lemma cast_min (p q : ℚ≥0) : (↑(min p q) : K) = min (p : K) (q : K) := (@cast_mono K _).map_min diff --git a/Mathlib/Data/Rat/Floor.lean b/Mathlib/Data/Rat/Floor.lean index 98b0835e7c8081..66006dd0fc0628 100644 --- a/Mathlib/Data/Rat/Floor.lean +++ b/Mathlib/Data/Rat/Floor.lean @@ -49,7 +49,8 @@ instance : FloorRing ℚ := protected theorem floor_def {q : ℚ} : ⌊q⌋ = q.num / q.den := Rat.floor_def' q -theorem floor_int_div_nat_eq_div (n : ℤ) (d : ℕ) : ⌊(↑n : ℚ) / (↑d : ℚ)⌋ = n / (↑d : ℤ) := by +@[norm_cast] +theorem floor_intCast_div_natCast (n : ℤ) (d : ℕ) : ⌊(↑n / ↑d : ℚ)⌋ = n / (↑d : ℤ) := by rw [Rat.floor_def] obtain rfl | hd := @eq_zero_or_pos _ _ d · simp @@ -61,6 +62,18 @@ theorem floor_int_div_nat_eq_div (n : ℤ) (d : ℕ) : ⌊(↑n : ℚ) / (↑d : refine (Int.mul_ediv_mul_of_pos _ _ <| pos_of_mul_pos_left ?_ <| Int.natCast_nonneg q.den).symm rwa [← d_eq_c_mul_denom, Int.natCast_pos] +@[norm_cast] +theorem floor_natCast_div_natCast (n d : ℕ) : ⌊(↑n / ↑d : ℚ)⌋ = n / d := + floor_intCast_div_natCast n d + +@[norm_cast] +theorem natFloor_natCast_div_natCast (n d : ℕ) : ⌊(↑n / ↑d : ℚ)⌋₊ = n / d := by + rw [← Int.ofNat_inj, Int.natCast_floor_eq_floor (by positivity)] + push_cast + exact floor_intCast_div_natCast n d + +@[deprecated (since := "2024-07-23")] alias floor_int_div_nat_eq_div := floor_intCast_div_natCast + @[simp, norm_cast] theorem floor_cast (x : ℚ) : ⌊(x : α)⌋ = ⌊x⌋ := floor_eq_iff.2 (mod_cast floor_eq_iff.1 (Eq.refl ⌊x⌋)) @@ -93,7 +106,7 @@ theorem isInt_intFloor_ofIsRat (r : α) (n : ℤ) (d : ℕ) : rintro ⟨inv, rfl⟩ constructor simp only [invOf_eq_inv, ← div_eq_mul_inv, Int.cast_id] - rw [← floor_int_div_nat_eq_div n d, ← floor_cast (α := α), Rat.cast_div, + rw [← floor_intCast_div_natCast n d, ← floor_cast (α := α), Rat.cast_div, cast_intCast, cast_natCast] /-- `norm_num` extension for `Int.floor` -/ @@ -123,7 +136,7 @@ end NormNum end Rat theorem Int.mod_nat_eq_sub_mul_floor_rat_div {n : ℤ} {d : ℕ} : n % d = n - d * ⌊(n : ℚ) / d⌋ := by - rw [eq_sub_of_add_eq <| Int.emod_add_ediv n d, Rat.floor_int_div_nat_eq_div] + rw [eq_sub_of_add_eq <| Int.emod_add_ediv n d, Rat.floor_intCast_div_natCast] theorem Nat.coprime_sub_mul_floor_rat_div_of_coprime {n d : ℕ} (n_coprime_d : n.Coprime d) : ((n : ℤ) - d * ⌊(n : ℚ) / d⌋).natAbs.Coprime d := by From 23f702a6fcea4c12960ffaee2341bcc484498e4d Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Tue, 15 Oct 2024 00:40:57 +0000 Subject: [PATCH 120/425] chore(Group.Submonoid.Basic): split off `Defs` (#17726) The criteria for including a result in `Algebra.Group.Submonoid.Basic`: * Can it be defined with only `Defs` imports? * Is it needed for a subsequent `def` or `instance`? --- Mathlib.lean | 1 + Mathlib/Algebra/Group/Submonoid/Basic.lean | 243 +------------- Mathlib/Algebra/Group/Submonoid/Defs.lean | 301 ++++++++++++++++++ .../Order/GroupWithZero/Submonoid.lean | 3 +- Mathlib/Deprecated/Submonoid.lean | 2 +- .../RingTheory/OreLocalization/OreSet.lean | 2 +- 6 files changed, 312 insertions(+), 240 deletions(-) create mode 100644 Mathlib/Algebra/Group/Submonoid/Defs.lean diff --git a/Mathlib.lean b/Mathlib.lean index 48b265283a8c79..2b39970731dcff 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -285,6 +285,7 @@ import Mathlib.Algebra.Group.Subgroup.Order import Mathlib.Algebra.Group.Subgroup.Pointwise import Mathlib.Algebra.Group.Subgroup.ZPowers import Mathlib.Algebra.Group.Submonoid.Basic +import Mathlib.Algebra.Group.Submonoid.Defs import Mathlib.Algebra.Group.Submonoid.DistribMulAction import Mathlib.Algebra.Group.Submonoid.Membership import Mathlib.Algebra.Group.Submonoid.MulOpposite diff --git a/Mathlib/Algebra/Group/Submonoid/Basic.lean b/Mathlib/Algebra/Group/Submonoid/Basic.lean index 69cb89258578ac..199f57b66d1fd8 100644 --- a/Mathlib/Algebra/Group/Submonoid/Basic.lean +++ b/Mathlib/Algebra/Group/Submonoid/Basic.lean @@ -5,24 +5,20 @@ Authors: Johannes Hölzl, Kenny Lau, Johan Commelin, Mario Carneiro, Kevin Buzza Amelia Livingston, Yury Kudryashov -/ import Mathlib.Algebra.Group.Hom.Defs +import Mathlib.Algebra.Group.Submonoid.Defs import Mathlib.Algebra.Group.Subsemigroup.Basic import Mathlib.Algebra.Group.Units.Defs /-! -# Submonoids: definition and `CompleteLattice` structure +# Submonoids: `CompleteLattice` structure -This file defines bundled multiplicative and additive submonoids. We also define -a `CompleteLattice` structure on `Submonoid`s, define the closure of a set as the minimal submonoid -that includes this set, and prove a few results about extending properties from a dense set (i.e. -a set with `closure s = ⊤`) to the whole monoid, see `Submonoid.dense_induction` and +This file defines a `CompleteLattice` structure on `Submonoid`s, define the closure of a set as the +minimal submonoid that includes this set, and prove a few results about extending properties from a +dense set (i.e. a set with `closure s = ⊤`) to the whole monoid, see `Submonoid.dense_induction` and `MonoidHom.ofClosureEqTopLeft`/`MonoidHom.ofClosureEqTopRight`. ## Main definitions -* `Submonoid M`: the type of bundled submonoids of a monoid `M`; the underlying set is given in - the `carrier` field of the structure, and should be accessed through coercion as in `(S : Set M)`. -* `AddSubmonoid M` : the type of bundled submonoids of an additive monoid `M`. - For each of the following definitions in the `Submonoid` namespace, there is a corresponding definition in the `AddSubmonoid` namespace. @@ -64,197 +60,9 @@ section NonAssoc variable [MulOneClass M] {s : Set M} variable [AddZeroClass A] {t : Set A} -/-- `OneMemClass S M` says `S` is a type of subsets `s ≤ M`, such that `1 ∈ s` for all `s`. -/ -class OneMemClass (S : Type*) (M : outParam Type*) [One M] [SetLike S M] : Prop where - /-- By definition, if we have `OneMemClass S M`, we have `1 ∈ s` for all `s : S`. -/ - one_mem : ∀ s : S, (1 : M) ∈ s - -export OneMemClass (one_mem) - -/-- `ZeroMemClass S M` says `S` is a type of subsets `s ≤ M`, such that `0 ∈ s` for all `s`. -/ -class ZeroMemClass (S : Type*) (M : outParam Type*) [Zero M] [SetLike S M] : Prop where - /-- By definition, if we have `ZeroMemClass S M`, we have `0 ∈ s` for all `s : S`. -/ - zero_mem : ∀ s : S, (0 : M) ∈ s - -export ZeroMemClass (zero_mem) - -attribute [to_additive] OneMemClass - -attribute [aesop safe apply (rule_sets := [SetLike])] one_mem zero_mem - -section - -/-- A submonoid of a monoid `M` is a subset containing 1 and closed under multiplication. -/ -structure Submonoid (M : Type*) [MulOneClass M] extends Subsemigroup M where - /-- A submonoid contains `1`. -/ - one_mem' : (1 : M) ∈ carrier - -end - -/-- A submonoid of a monoid `M` can be considered as a subsemigroup of that monoid. -/ -add_decl_doc Submonoid.toSubsemigroup - -/-- `SubmonoidClass S M` says `S` is a type of subsets `s ≤ M` that contain `1` -and are closed under `(*)` -/ -class SubmonoidClass (S : Type*) (M : outParam Type*) [MulOneClass M] [SetLike S M] extends - MulMemClass S M, OneMemClass S M : Prop - -section - -/-- An additive submonoid of an additive monoid `M` is a subset containing 0 and - closed under addition. -/ -structure AddSubmonoid (M : Type*) [AddZeroClass M] extends AddSubsemigroup M where - /-- An additive submonoid contains `0`. -/ - zero_mem' : (0 : M) ∈ carrier - -end - -/-- An additive submonoid of an additive monoid `M` can be considered as an -additive subsemigroup of that additive monoid. -/ -add_decl_doc AddSubmonoid.toAddSubsemigroup - -/-- `AddSubmonoidClass S M` says `S` is a type of subsets `s ≤ M` that contain `0` -and are closed under `(+)` -/ -class AddSubmonoidClass (S : Type*) (M : outParam Type*) [AddZeroClass M] [SetLike S M] extends - AddMemClass S M, ZeroMemClass S M : Prop - -attribute [to_additive] Submonoid SubmonoidClass - -@[to_additive (attr := aesop safe apply (rule_sets := [SetLike]))] -theorem pow_mem {M A} [Monoid M] [SetLike A M] [SubmonoidClass A M] {S : A} {x : M} - (hx : x ∈ S) : ∀ n : ℕ, x ^ n ∈ S - | 0 => by - rw [pow_zero] - exact OneMemClass.one_mem S - | n + 1 => by - rw [pow_succ] - exact mul_mem (pow_mem hx n) hx - namespace Submonoid -@[to_additive] -instance : SetLike (Submonoid M) M where - coe s := s.carrier - coe_injective' p q h := by cases p; cases q; congr; exact SetLike.coe_injective' h - -@[to_additive] -instance : SubmonoidClass (Submonoid M) M where - one_mem := Submonoid.one_mem' - mul_mem {s} := s.mul_mem' - -initialize_simps_projections Submonoid (carrier → coe) - -initialize_simps_projections AddSubmonoid (carrier → coe) - -@[to_additive (attr := simp)] -theorem mem_toSubsemigroup {s : Submonoid M} {x : M} : x ∈ s.toSubsemigroup ↔ x ∈ s := - Iff.rfl - --- Porting note: `x ∈ s.carrier` is now syntactically `x ∈ s.toSubsemigroup.carrier`, --- which `simp` already simplifies to `x ∈ s.toSubsemigroup`. So we remove the `@[simp]` attribute --- here, and instead add the simp lemma `mem_toSubsemigroup` to allow `simp` to do this exact --- simplification transitively. -@[to_additive] -theorem mem_carrier {s : Submonoid M} {x : M} : x ∈ s.carrier ↔ x ∈ s := - Iff.rfl - -@[to_additive (attr := simp)] -theorem mem_mk {s : Subsemigroup M} {x : M} (h_one) : x ∈ mk s h_one ↔ x ∈ s := - Iff.rfl - -@[to_additive (attr := simp)] -theorem coe_set_mk {s : Subsemigroup M} (h_one) : (mk s h_one : Set M) = s := - rfl - -@[to_additive (attr := simp)] -theorem mk_le_mk {s t : Subsemigroup M} (h_one) (h_one') : mk s h_one ≤ mk t h_one' ↔ s ≤ t := - Iff.rfl - -/-- Two submonoids are equal if they have the same elements. -/ -@[to_additive (attr := ext) "Two `AddSubmonoid`s are equal if they have the same elements."] -theorem ext {S T : Submonoid M} (h : ∀ x, x ∈ S ↔ x ∈ T) : S = T := - SetLike.ext h - -/-- Copy a submonoid replacing `carrier` with a set that is equal to it. -/ -@[to_additive "Copy an additive submonoid replacing `carrier` with a set that is equal to it."] -protected def copy (S : Submonoid M) (s : Set M) (hs : s = S) : Submonoid M where - carrier := s - one_mem' := show 1 ∈ s from hs.symm ▸ S.one_mem' - mul_mem' := hs.symm ▸ S.mul_mem' - -variable {S : Submonoid M} - -@[to_additive (attr := simp)] -theorem coe_copy {s : Set M} (hs : s = S) : (S.copy s hs : Set M) = s := - rfl - -@[to_additive] -theorem copy_eq {s : Set M} (hs : s = S) : S.copy s hs = S := - SetLike.coe_injective hs - -variable (S) - -/-- A submonoid contains the monoid's 1. -/ -@[to_additive "An `AddSubmonoid` contains the monoid's 0."] -protected theorem one_mem : (1 : M) ∈ S := - one_mem S - -/-- A submonoid is closed under multiplication. -/ -@[to_additive "An `AddSubmonoid` is closed under addition."] -protected theorem mul_mem {x y : M} : x ∈ S → y ∈ S → x * y ∈ S := - mul_mem - -/-- The submonoid `M` of the monoid `M`. -/ -@[to_additive "The additive submonoid `M` of the `AddMonoid M`."] -instance : Top (Submonoid M) := - ⟨{ carrier := Set.univ - one_mem' := Set.mem_univ 1 - mul_mem' := fun _ _ => Set.mem_univ _ }⟩ - -/-- The trivial submonoid `{1}` of a monoid `M`. -/ -@[to_additive "The trivial `AddSubmonoid` `{0}` of an `AddMonoid` `M`."] -instance : Bot (Submonoid M) := - ⟨{ carrier := {1} - one_mem' := Set.mem_singleton 1 - mul_mem' := fun ha hb => by - simp only [Set.mem_singleton_iff] at * - rw [ha, hb, mul_one] }⟩ - -@[to_additive] -instance : Inhabited (Submonoid M) := - ⟨⊥⟩ - -@[to_additive (attr := simp)] -theorem mem_bot {x : M} : x ∈ (⊥ : Submonoid M) ↔ x = 1 := - Set.mem_singleton_iff - -@[to_additive (attr := simp)] -theorem mem_top (x : M) : x ∈ (⊤ : Submonoid M) := - Set.mem_univ x - -@[to_additive (attr := simp)] -theorem coe_top : ((⊤ : Submonoid M) : Set M) = Set.univ := - rfl - -@[to_additive (attr := simp)] -theorem coe_bot : ((⊥ : Submonoid M) : Set M) = {1} := - rfl - -/-- The inf of two submonoids is their intersection. -/ -@[to_additive "The inf of two `AddSubmonoid`s is their intersection."] -instance : Inf (Submonoid M) := - ⟨fun S₁ S₂ => - { carrier := S₁ ∩ S₂ - one_mem' := ⟨S₁.one_mem, S₂.one_mem⟩ - mul_mem' := fun ⟨hx, hx'⟩ ⟨hy, hy'⟩ => ⟨S₁.mul_mem hx hy, S₂.mul_mem hx' hy'⟩ }⟩ - -@[to_additive (attr := simp)] -theorem coe_inf (p p' : Submonoid M) : ((p ⊓ p' : Submonoid M) : Set M) = (p : Set M) ∩ p' := - rfl - -@[to_additive (attr := simp)] -theorem mem_inf {p p' : Submonoid M} {x : M} : x ∈ p ⊓ p' ↔ x ∈ p ∧ x ∈ p' := - Iff.rfl +variable (S : Submonoid M) @[to_additive] instance : InfSet (Submonoid M) := @@ -300,30 +108,6 @@ instance : CompleteLattice (Submonoid M) := inf_le_left := fun _ _ _ => And.left inf_le_right := fun _ _ _ => And.right } -@[to_additive (attr := simp)] -theorem subsingleton_iff : Subsingleton (Submonoid M) ↔ Subsingleton M := - ⟨fun _ => - ⟨fun x y => - have : ∀ i : M, i = 1 := fun i => - mem_bot.mp <| Subsingleton.elim (⊤ : Submonoid M) ⊥ ▸ mem_top i - (this x).trans (this y).symm⟩, - fun _ => - ⟨fun x y => Submonoid.ext fun i => Subsingleton.elim 1 i ▸ by simp [Submonoid.one_mem]⟩⟩ - -@[to_additive (attr := simp)] -theorem nontrivial_iff : Nontrivial (Submonoid M) ↔ Nontrivial M := - not_iff_not.mp - ((not_nontrivial_iff_subsingleton.trans subsingleton_iff).trans - not_nontrivial_iff_subsingleton.symm) - -@[to_additive] -instance [Subsingleton M] : Unique (Submonoid M) := - ⟨⟨⊥⟩, fun a => @Subsingleton.elim _ (subsingleton_iff.mpr ‹_›) a _⟩ - -@[to_additive] -instance [Nontrivial M] : Nontrivial (Submonoid M) := - nontrivial_iff.mpr ‹_› - /-- The `Submonoid` generated by a set. -/ @[to_additive "The `AddSubmonoid` generated by a set"] def closure (s : Set M) : Submonoid M := @@ -500,17 +284,6 @@ variable [MulOneClass N] open Submonoid -/-- The submonoid of elements `x : M` such that `f x = g x` -/ -@[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] - mul_mem' (hx : _ = _) (hy : _ = _) := by simp [*] - -@[to_additive (attr := simp)] -theorem eqLocusM_same (f : M →* N) : f.eqLocusM f = ⊤ := - SetLike.ext fun _ => eq_self_iff_true _ - /-- If two monoid homomorphisms are equal on a set, then they are equal on its submonoid closure. -/ @[to_additive "If two monoid homomorphisms are equal on a set, then they are equal on its submonoid @@ -518,10 +291,6 @@ theorem eqLocusM_same (f : M →* N) : f.eqLocusM f = ⊤ := theorem eqOn_closureM {f g : M →* N} {s : Set M} (h : Set.EqOn f g s) : Set.EqOn f g (closure s) := show closure s ≤ f.eqLocusM g from closure_le.2 h -@[to_additive] -theorem eq_of_eqOn_topM {f g : M →* N} (h : Set.EqOn f g (⊤ : Submonoid M)) : f = g := - ext fun _ => h trivial - @[to_additive] theorem eq_of_eqOn_denseM {s : Set M} (hs : closure s = ⊤) {f g : M →* N} (h : s.EqOn f g) : f = g := diff --git a/Mathlib/Algebra/Group/Submonoid/Defs.lean b/Mathlib/Algebra/Group/Submonoid/Defs.lean new file mode 100644 index 00000000000000..4f005ea6406956 --- /dev/null +++ b/Mathlib/Algebra/Group/Submonoid/Defs.lean @@ -0,0 +1,301 @@ +/- +Copyright (c) 2018 Johannes Hölzl. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Johannes Hölzl, Kenny Lau, Johan Commelin, Mario Carneiro, Kevin Buzzard, +Amelia Livingston, Yury Kudryashov +-/ +import Mathlib.Algebra.Group.Hom.Defs +import Mathlib.Algebra.Group.Subsemigroup.Defs + +/-! +# Submonoids: definition + +This file defines bundled multiplicative and additive submonoids. We also define +a `CompleteLattice` structure on `Submonoid`s, define the closure of a set as the minimal submonoid +that includes this set, and prove a few results about extending properties from a dense set (i.e. +a set with `closure s = ⊤`) to the whole monoid, see `Submonoid.dense_induction` and +`MonoidHom.ofClosureEqTopLeft`/`MonoidHom.ofClosureEqTopRight`. + +## Main definitions + +* `Submonoid M`: the type of bundled submonoids of a monoid `M`; the underlying set is given in + the `carrier` field of the structure, and should be accessed through coercion as in `(S : Set M)`. +* `AddSubmonoid M` : the type of bundled submonoids of an additive monoid `M`. + +For each of the following definitions in the `Submonoid` namespace, there is a corresponding +definition in the `AddSubmonoid` namespace. + +* `Submonoid.copy` : copy of a submonoid with `carrier` replaced by a set that is equal but possibly + not definitionally equal to the carrier of the original `Submonoid`. +* `MonoidHom.eqLocusM`: the submonoid of elements `x : M` such that `f x = g x`; + +## Implementation notes + +Submonoid inclusion is denoted `≤` rather than `⊆`, although `∈` is defined as +membership of a submonoid's underlying set. + +Note that `Submonoid M` does not actually require `Monoid M`, instead requiring only the weaker +`MulOneClass M`. + +This file is designed to have very few dependencies. In particular, it should not use natural +numbers. `Submonoid` is implemented by extending `Subsemigroup` requiring `one_mem'`. + +## Tags +submonoid, submonoids +-/ + +assert_not_exists CompleteLattice +assert_not_exists MonoidWithZero + +-- Only needed for notation +-- Only needed for notation +variable {M : Type*} {N : Type*} +variable {A : Type*} + +section NonAssoc + +variable [MulOneClass M] {s : Set M} +variable [AddZeroClass A] {t : Set A} + +/-- `OneMemClass S M` says `S` is a type of subsets `s ≤ M`, such that `1 ∈ s` for all `s`. -/ +class OneMemClass (S : Type*) (M : outParam Type*) [One M] [SetLike S M] : Prop where + /-- By definition, if we have `OneMemClass S M`, we have `1 ∈ s` for all `s : S`. -/ + one_mem : ∀ s : S, (1 : M) ∈ s + +export OneMemClass (one_mem) + +/-- `ZeroMemClass S M` says `S` is a type of subsets `s ≤ M`, such that `0 ∈ s` for all `s`. -/ +class ZeroMemClass (S : Type*) (M : outParam Type*) [Zero M] [SetLike S M] : Prop where + /-- By definition, if we have `ZeroMemClass S M`, we have `0 ∈ s` for all `s : S`. -/ + zero_mem : ∀ s : S, (0 : M) ∈ s + +export ZeroMemClass (zero_mem) + +attribute [to_additive] OneMemClass + +attribute [aesop safe apply (rule_sets := [SetLike])] one_mem zero_mem + +section + +/-- A submonoid of a monoid `M` is a subset containing 1 and closed under multiplication. -/ +structure Submonoid (M : Type*) [MulOneClass M] extends Subsemigroup M where + /-- A submonoid contains `1`. -/ + one_mem' : (1 : M) ∈ carrier + +end + +/-- A submonoid of a monoid `M` can be considered as a subsemigroup of that monoid. -/ +add_decl_doc Submonoid.toSubsemigroup + +/-- `SubmonoidClass S M` says `S` is a type of subsets `s ≤ M` that contain `1` +and are closed under `(*)` -/ +class SubmonoidClass (S : Type*) (M : outParam Type*) [MulOneClass M] [SetLike S M] extends + MulMemClass S M, OneMemClass S M : Prop + +section + +/-- An additive submonoid of an additive monoid `M` is a subset containing 0 and + closed under addition. -/ +structure AddSubmonoid (M : Type*) [AddZeroClass M] extends AddSubsemigroup M where + /-- An additive submonoid contains `0`. -/ + zero_mem' : (0 : M) ∈ carrier + +end + +/-- An additive submonoid of an additive monoid `M` can be considered as an +additive subsemigroup of that additive monoid. -/ +add_decl_doc AddSubmonoid.toAddSubsemigroup + +/-- `AddSubmonoidClass S M` says `S` is a type of subsets `s ≤ M` that contain `0` +and are closed under `(+)` -/ +class AddSubmonoidClass (S : Type*) (M : outParam Type*) [AddZeroClass M] [SetLike S M] extends + AddMemClass S M, ZeroMemClass S M : Prop + +attribute [to_additive] Submonoid SubmonoidClass + +@[to_additive (attr := aesop safe apply (rule_sets := [SetLike]))] +theorem pow_mem {M A} [Monoid M] [SetLike A M] [SubmonoidClass A M] {S : A} {x : M} + (hx : x ∈ S) : ∀ n : ℕ, x ^ n ∈ S + | 0 => by + rw [pow_zero] + exact OneMemClass.one_mem S + | n + 1 => by + rw [pow_succ] + exact mul_mem (pow_mem hx n) hx + +namespace Submonoid + +@[to_additive] +instance : SetLike (Submonoid M) M where + coe s := s.carrier + coe_injective' p q h := by cases p; cases q; congr; exact SetLike.coe_injective' h + +@[to_additive] +instance : SubmonoidClass (Submonoid M) M where + one_mem := Submonoid.one_mem' + mul_mem {s} := s.mul_mem' + +initialize_simps_projections Submonoid (carrier → coe) + +initialize_simps_projections AddSubmonoid (carrier → coe) + +@[to_additive (attr := simp)] +theorem mem_toSubsemigroup {s : Submonoid M} {x : M} : x ∈ s.toSubsemigroup ↔ x ∈ s := + Iff.rfl + +-- Porting note: `x ∈ s.carrier` is now syntactically `x ∈ s.toSubsemigroup.carrier`, +-- which `simp` already simplifies to `x ∈ s.toSubsemigroup`. So we remove the `@[simp]` attribute +-- here, and instead add the simp lemma `mem_toSubsemigroup` to allow `simp` to do this exact +-- simplification transitively. +@[to_additive] +theorem mem_carrier {s : Submonoid M} {x : M} : x ∈ s.carrier ↔ x ∈ s := + Iff.rfl + +@[to_additive (attr := simp)] +theorem mem_mk {s : Subsemigroup M} {x : M} (h_one) : x ∈ mk s h_one ↔ x ∈ s := + Iff.rfl + +@[to_additive (attr := simp)] +theorem coe_set_mk {s : Subsemigroup M} (h_one) : (mk s h_one : Set M) = s := + rfl + +@[to_additive (attr := simp)] +theorem mk_le_mk {s t : Subsemigroup M} (h_one) (h_one') : mk s h_one ≤ mk t h_one' ↔ s ≤ t := + Iff.rfl + +/-- Two submonoids are equal if they have the same elements. -/ +@[to_additive (attr := ext) "Two `AddSubmonoid`s are equal if they have the same elements."] +theorem ext {S T : Submonoid M} (h : ∀ x, x ∈ S ↔ x ∈ T) : S = T := + SetLike.ext h + +/-- Copy a submonoid replacing `carrier` with a set that is equal to it. -/ +@[to_additive "Copy an additive submonoid replacing `carrier` with a set that is equal to it."] +protected def copy (S : Submonoid M) (s : Set M) (hs : s = S) : Submonoid M where + carrier := s + one_mem' := show 1 ∈ s from hs.symm ▸ S.one_mem' + mul_mem' := hs.symm ▸ S.mul_mem' + +variable {S : Submonoid M} + +@[to_additive (attr := simp)] +theorem coe_copy {s : Set M} (hs : s = S) : (S.copy s hs : Set M) = s := + rfl + +@[to_additive] +theorem copy_eq {s : Set M} (hs : s = S) : S.copy s hs = S := + SetLike.coe_injective hs + +variable (S) + +/-- A submonoid contains the monoid's 1. -/ +@[to_additive "An `AddSubmonoid` contains the monoid's 0."] +protected theorem one_mem : (1 : M) ∈ S := + one_mem S + +/-- A submonoid is closed under multiplication. -/ +@[to_additive "An `AddSubmonoid` is closed under addition."] +protected theorem mul_mem {x y : M} : x ∈ S → y ∈ S → x * y ∈ S := + mul_mem + +/-- The submonoid `M` of the monoid `M`. -/ +@[to_additive "The additive submonoid `M` of the `AddMonoid M`."] +instance : Top (Submonoid M) := + ⟨{ carrier := Set.univ + one_mem' := Set.mem_univ 1 + mul_mem' := fun _ _ => Set.mem_univ _ }⟩ + +/-- The trivial submonoid `{1}` of a monoid `M`. -/ +@[to_additive "The trivial `AddSubmonoid` `{0}` of an `AddMonoid` `M`."] +instance : Bot (Submonoid M) := + ⟨{ carrier := {1} + one_mem' := Set.mem_singleton 1 + mul_mem' := fun ha hb => by + simp only [Set.mem_singleton_iff] at * + rw [ha, hb, mul_one] }⟩ + +@[to_additive] +instance : Inhabited (Submonoid M) := + ⟨⊥⟩ + +@[to_additive (attr := simp)] +theorem mem_bot {x : M} : x ∈ (⊥ : Submonoid M) ↔ x = 1 := + Set.mem_singleton_iff + +@[to_additive (attr := simp)] +theorem mem_top (x : M) : x ∈ (⊤ : Submonoid M) := + Set.mem_univ x + +@[to_additive (attr := simp)] +theorem coe_top : ((⊤ : Submonoid M) : Set M) = Set.univ := + rfl + +@[to_additive (attr := simp)] +theorem coe_bot : ((⊥ : Submonoid M) : Set M) = {1} := + rfl + +/-- The inf of two submonoids is their intersection. -/ +@[to_additive "The inf of two `AddSubmonoid`s is their intersection."] +instance : Inf (Submonoid M) := + ⟨fun S₁ S₂ => + { carrier := S₁ ∩ S₂ + one_mem' := ⟨S₁.one_mem, S₂.one_mem⟩ + mul_mem' := fun ⟨hx, hx'⟩ ⟨hy, hy'⟩ => ⟨S₁.mul_mem hx hy, S₂.mul_mem hx' hy'⟩ }⟩ + +@[to_additive (attr := simp)] +theorem coe_inf (p p' : Submonoid M) : ((p ⊓ p' : Submonoid M) : Set M) = (p : Set M) ∩ p' := + rfl + +@[to_additive (attr := simp)] +theorem mem_inf {p p' : Submonoid M} {x : M} : x ∈ p ⊓ p' ↔ x ∈ p ∧ x ∈ p' := + Iff.rfl + +@[to_additive (attr := simp)] +theorem subsingleton_iff : Subsingleton (Submonoid M) ↔ Subsingleton M := + ⟨fun _ => + ⟨fun x y => + have : ∀ i : M, i = 1 := fun i => + mem_bot.mp <| Subsingleton.elim (⊤ : Submonoid M) ⊥ ▸ mem_top i + (this x).trans (this y).symm⟩, + fun _ => + ⟨fun x y => Submonoid.ext fun i => Subsingleton.elim 1 i ▸ by simp [Submonoid.one_mem]⟩⟩ + +@[to_additive (attr := simp)] +theorem nontrivial_iff : Nontrivial (Submonoid M) ↔ Nontrivial M := + not_iff_not.mp + ((not_nontrivial_iff_subsingleton.trans subsingleton_iff).trans + not_nontrivial_iff_subsingleton.symm) + +@[to_additive] +instance [Subsingleton M] : Unique (Submonoid M) := + ⟨⟨⊥⟩, fun a => @Subsingleton.elim _ (subsingleton_iff.mpr ‹_›) a _⟩ + +@[to_additive] +instance [Nontrivial M] : Nontrivial (Submonoid M) := + nontrivial_iff.mpr ‹_› + +end Submonoid + +namespace MonoidHom + +variable [MulOneClass N] + +open Submonoid + +/-- The submonoid of elements `x : M` such that `f x = g x` -/ +@[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] + mul_mem' (hx : _ = _) (hy : _ = _) := by simp [*] + +@[to_additive (attr := simp)] +theorem eqLocusM_same (f : M →* N) : f.eqLocusM f = ⊤ := + SetLike.ext fun _ => eq_self_iff_true _ + +@[to_additive] +theorem eq_of_eqOn_topM {f g : M →* N} (h : Set.EqOn f g (⊤ : Submonoid M)) : f = g := + ext fun _ => h trivial + +end MonoidHom + +end NonAssoc diff --git a/Mathlib/Algebra/Order/GroupWithZero/Submonoid.lean b/Mathlib/Algebra/Order/GroupWithZero/Submonoid.lean index c3b553bb0ca382..7f47ae1ee88aaf 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Submonoid.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Submonoid.lean @@ -3,8 +3,9 @@ Copyright (c) 2021 Chris Birkbeck. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Chris Birkbeck -/ -import Mathlib.Algebra.Group.Submonoid.Basic +import Mathlib.Algebra.Group.Submonoid.Defs import Mathlib.Algebra.Order.GroupWithZero.Unbundled +import Mathlib.Order.Interval.Set.Basic /-! # The submonoid of positive elements diff --git a/Mathlib/Deprecated/Submonoid.lean b/Mathlib/Deprecated/Submonoid.lean index e7fa4e7c6f2682..f85c670a230b81 100644 --- a/Mathlib/Deprecated/Submonoid.lean +++ b/Mathlib/Deprecated/Submonoid.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Johannes Hölzl, Kenny Lau, Johan Commelin, Mario Carneiro, Kevin Buzzard -/ import Mathlib.Algebra.BigOperators.Group.Finset -import Mathlib.Algebra.Group.Submonoid.Basic +import Mathlib.Algebra.Group.Submonoid.Defs import Mathlib.Deprecated.Group /-! diff --git a/Mathlib/RingTheory/OreLocalization/OreSet.lean b/Mathlib/RingTheory/OreLocalization/OreSet.lean index 5c7b9e4f91dab8..bbb8931b5454b1 100644 --- a/Mathlib/RingTheory/OreLocalization/OreSet.lean +++ b/Mathlib/RingTheory/OreLocalization/OreSet.lean @@ -3,7 +3,7 @@ Copyright (c) 2022 Jakob von Raumer. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Jakob von Raumer, Kevin Klinge -/ -import Mathlib.Algebra.Group.Submonoid.Basic +import Mathlib.Algebra.Group.Submonoid.Defs import Mathlib.Algebra.GroupWithZero.Basic import Mathlib.Algebra.Ring.Regular From 24fa70ce14da2b9da04c6b27e3cc6c7e84f713d3 Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Tue, 15 Oct 2024 01:38:13 +0000 Subject: [PATCH 121/425] Update lean-toolchain for testing https://github.com/leanprover/lean4/pull/5716 --- lake-manifest.json | 4 ++-- lakefile.lean | 2 +- lean-toolchain | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index 5a7bf89d6a8f11..fbf1e3cc6da537 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,10 +5,10 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "5f963d5d06cc3c2d3abd0806891133137a59d7eb", + "rev": "2fc617d4000e08367dbaab8cb9567472bc775c7d", "name": "batteries", "manifestFile": "lake-manifest.json", - "inputRev": "main", + "inputRev": "lean-pr-testing-5716", "inherited": false, "configFile": "lakefile.lean"}, {"url": "https://github.com/leanprover-community/quote4", diff --git a/lakefile.lean b/lakefile.lean index a4a09667f6c2b7..1cf6838a99fd62 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -7,7 +7,7 @@ open Lake DSL ## Mathlib dependencies on upstream projects -/ -require "leanprover-community" / "batteries" @ git "main" +require "leanprover-community" / "batteries" @ git "lean-pr-testing-5716" require "leanprover-community" / "Qq" @ git "master" require "leanprover-community" / "aesop" @ git "master" require "leanprover-community" / "proofwidgets" @ git "v0.0.43-pre" diff --git a/lean-toolchain b/lean-toolchain index a7eff1cf43d14e..1318fb1ce31ab7 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-14 +leanprover/lean4-pr-releases:pr-release-5716 From 9958ee4c7a38fa22589e8d655e9abbb39bdf1a42 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Tue, 15 Oct 2024 03:55:59 +0000 Subject: [PATCH 122/425] chore(GroupTheory/Congruence/Basic): split off `Defs` and `Hom` (#17729) `GroupTheory.Congruence.Defs` sets up the quotient and its monoid structure, and its imports and contents are trimmed down to the minimum to make that possible. `GroupTheory.Congruence.Hom` are those results that couldn't go into `GroupTheory.Congruence.Defs` but can be added after we import monoid homs. --- Mathlib.lean | 2 + Mathlib/GroupTheory/Congruence/Basic.lean | 937 +----------------- .../GroupTheory/Congruence/BigOperators.lean | 2 +- Mathlib/GroupTheory/Congruence/Defs.lean | 817 +++++++++++++++ Mathlib/GroupTheory/Congruence/Hom.lean | 217 ++++ Mathlib/GroupTheory/Congruence/Opposite.lean | 2 +- .../GroupTheory/MonoidLocalization/Basic.lean | 2 +- Mathlib/GroupTheory/QuotientGroup/Basic.lean | 2 +- Mathlib/LinearAlgebra/PiTensorProduct.lean | 1 - .../LinearAlgebra/TensorProduct/Basic.lean | 2 +- 10 files changed, 1044 insertions(+), 940 deletions(-) create mode 100644 Mathlib/GroupTheory/Congruence/Defs.lean create mode 100644 Mathlib/GroupTheory/Congruence/Hom.lean diff --git a/Mathlib.lean b/Mathlib.lean index 2b39970731dcff..bc9d68f0c31f65 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2818,6 +2818,8 @@ import Mathlib.GroupTheory.CommutingProbability import Mathlib.GroupTheory.Complement import Mathlib.GroupTheory.Congruence.Basic import Mathlib.GroupTheory.Congruence.BigOperators +import Mathlib.GroupTheory.Congruence.Defs +import Mathlib.GroupTheory.Congruence.Hom import Mathlib.GroupTheory.Congruence.Opposite import Mathlib.GroupTheory.Coprod.Basic import Mathlib.GroupTheory.CoprodI diff --git a/Mathlib/GroupTheory/Congruence/Basic.lean b/Mathlib/GroupTheory/Congruence/Basic.lean index a6e6e72b5404f9..c17ba1b5ca00b6 100644 --- a/Mathlib/GroupTheory/Congruence/Basic.lean +++ b/Mathlib/GroupTheory/Congruence/Basic.lean @@ -7,19 +7,12 @@ import Mathlib.Algebra.Group.Equiv.Basic import Mathlib.Algebra.Group.Submonoid.Operations import Mathlib.Algebra.GroupWithZero.Action.Defs import Mathlib.Data.Setoid.Basic +import Mathlib.GroupTheory.Congruence.Hom /-! # Congruence relations -This file defines congruence relations: equivalence relations that preserve a binary operation, -which in this case is multiplication or addition. The principal definition is a `structure` -extending a `Setoid` (an equivalence relation), and the inductive definition of the smallest -congruence relation containing a binary relation is also given (see `ConGen`). - -The file also proves basic properties of the quotient of a type by a congruence relation, and the -complete lattice of congruence relations on a type. We then establish an order-preserving bijection -between the set of congruence relations containing a congruence relation `c` and the set of -congruence relations on the quotient by `c`. +This file proves basic properties of the quotient of a type by a congruence relation. The second half of the file concerns congruence relations on monoids, in which case the quotient by the congruence relation is also a monoid. There are results about the universal @@ -27,17 +20,6 @@ property of quotients of monoids, and the isomorphism theorems for monoids. ## Implementation notes -The inductive definition of a congruence relation could be a nested inductive type, defined using -the equivalence closure of a binary relation `EqvGen`, but the recursor generated does not work. -A nested inductive definition could conceivably shorten proofs, because they would allow invocation -of the corresponding lemmas about `EqvGen`. - -The lemmas `refl`, `symm` and `trans` are not tagged with `@[refl]`, `@[symm]`, and `@[trans]` -respectively as these tags do not work on a structure coerced to a binary relation. - -There is a coercion from elements of a type to the element's equivalence class under a -congruence relation. - A congruence relation on a monoid `M` can be thought of as a submonoid of `M × M` for which membership is an equivalence relation, but whilst this fact is established in the file, it is not used, since this perspective adds more layers of definitional unfolding. @@ -53,136 +35,16 @@ variable (M : Type*) {N : Type*} {P : Type*} open Function Setoid -/-- A congruence relation on a type with an addition is an equivalence relation which - preserves addition. -/ -structure AddCon [Add M] extends Setoid M where - /-- Additive congruence relations are closed under addition -/ - add' : ∀ {w x y z}, r w x → r y z → r (w + y) (x + z) - -/-- A congruence relation on a type with a multiplication is an equivalence relation which - preserves multiplication. -/ -@[to_additive AddCon] -structure Con [Mul M] extends Setoid M where - /-- Congruence relations are closed under multiplication -/ - mul' : ∀ {w x y z}, r w x → r y z → r (w * y) (x * z) - -/-- The equivalence relation underlying an additive congruence relation. -/ -add_decl_doc AddCon.toSetoid - -/-- The equivalence relation underlying a multiplicative congruence relation. -/ -add_decl_doc Con.toSetoid - variable {M} -/-- The inductively defined smallest additive congruence relation containing a given binary - relation. -/ -inductive AddConGen.Rel [Add M] (r : M → M → Prop) : M → M → Prop - | of : ∀ x y, r x y → AddConGen.Rel r x y - | refl : ∀ x, AddConGen.Rel r x x - | symm : ∀ {x y}, AddConGen.Rel r x y → AddConGen.Rel r y x - | trans : ∀ {x y z}, AddConGen.Rel r x y → AddConGen.Rel r y z → AddConGen.Rel r x z - | add : ∀ {w x y z}, AddConGen.Rel r w x → AddConGen.Rel r y z → AddConGen.Rel r (w + y) (x + z) - -/-- The inductively defined smallest multiplicative congruence relation containing a given binary - relation. -/ -@[to_additive AddConGen.Rel] -inductive ConGen.Rel [Mul M] (r : M → M → Prop) : M → M → Prop - | of : ∀ x y, r x y → ConGen.Rel r x y - | refl : ∀ x, ConGen.Rel r x x - | symm : ∀ {x y}, ConGen.Rel r x y → ConGen.Rel r y x - | trans : ∀ {x y z}, ConGen.Rel r x y → ConGen.Rel r y z → ConGen.Rel r x z - | mul : ∀ {w x y z}, ConGen.Rel r w x → ConGen.Rel r y z → ConGen.Rel r (w * y) (x * z) - -/-- The inductively defined smallest multiplicative congruence relation containing a given binary - relation. -/ -@[to_additive addConGen "The inductively defined smallest additive congruence relation containing -a given binary relation."] -def conGen [Mul M] (r : M → M → Prop) : Con M := - ⟨⟨ConGen.Rel r, ⟨ConGen.Rel.refl, ConGen.Rel.symm, ConGen.Rel.trans⟩⟩, ConGen.Rel.mul⟩ - namespace Con section variable [Mul M] [Mul N] [Mul P] (c : Con M) -@[to_additive] -instance : Inhabited (Con M) := - ⟨conGen EmptyRelation⟩ - -/-- A coercion from a congruence relation to its underlying binary relation. -/ -@[to_additive "A coercion from an additive congruence relation to its underlying binary relation."] -instance : FunLike (Con M) M (M → Prop) where - coe c := c.r - coe_injective' x y h := by - rcases x with ⟨⟨x, _⟩, _⟩ - rcases y with ⟨⟨y, _⟩, _⟩ - have : x = y := h - subst x; rfl - -@[to_additive (attr := simp)] -theorem rel_eq_coe (c : Con M) : c.r = c := - rfl - -/-- Congruence relations are reflexive. -/ -@[to_additive "Additive congruence relations are reflexive."] -protected theorem refl (x) : c x x := - c.toSetoid.refl' x - -/-- Congruence relations are symmetric. -/ -@[to_additive "Additive congruence relations are symmetric."] -protected theorem symm {x y} : c x y → c y x := c.toSetoid.symm' - -/-- Congruence relations are transitive. -/ -@[to_additive "Additive congruence relations are transitive."] -protected theorem trans {x y z} : c x y → c y z → c x z := c.toSetoid.trans' - -/-- Multiplicative congruence relations preserve multiplication. -/ -@[to_additive "Additive congruence relations preserve addition."] -protected theorem mul {w x y z} : c w x → c y z → c (w * y) (x * z) := c.mul' - -@[to_additive (attr := simp)] -theorem rel_mk {s : Setoid M} {h a b} : Con.mk s h a b ↔ r a b := - Iff.rfl - -/-- Given a type `M` with a multiplication, a congruence relation `c` on `M`, and elements of `M` - `x, y`, `(x, y) ∈ M × M` iff `x` is related to `y` by `c`. -/ -@[to_additive "Given a type `M` with an addition, `x, y ∈ M`, and an additive congruence relation -`c` on `M`, `(x, y) ∈ M × M` iff `x` is related to `y` by `c`."] -instance : Membership (M × M) (Con M) := - ⟨fun c x => c x.1 x.2⟩ - variable {c} -/-- The map sending a congruence relation to its underlying binary relation is injective. -/ -@[to_additive "The map sending an additive congruence relation to its underlying binary relation -is injective."] -theorem ext' {c d : Con M} (H : ⇑c = ⇑d) : c = d := DFunLike.coe_injective H - -/-- Extensionality rule for congruence relations. -/ -@[to_additive (attr := ext) "Extensionality rule for additive congruence relations."] -theorem ext {c d : Con M} (H : ∀ x y, c x y ↔ d x y) : c = d := - ext' <| by ext; apply H - -/-- The map sending a congruence relation to its underlying equivalence relation is injective. -/ -@[to_additive "The map sending an additive congruence relation to its underlying equivalence -relation is injective."] -theorem toSetoid_inj {c d : Con M} (H : c.toSetoid = d.toSetoid) : c = d := - ext <| ext_iff.1 H - -/-- Two congruence relations are equal iff their underlying binary relations are equal. -/ -@[to_additive "Two additive congruence relations are equal iff their underlying binary relations -are equal."] -theorem coe_inj {c d : Con M} : ⇑c = ⇑d ↔ c = d := DFunLike.coe_injective.eq_iff - -/-- The kernel of a multiplication-preserving function as a congruence relation. -/ -@[to_additive "The kernel of an addition-preserving function as an additive congruence relation."] -def mulKer (f : M → P) (h : ∀ x y, f (x * y) = f x * f y) : Con M where - toSetoid := Setoid.ker f - mul' h1 h2 := by - dsimp [Setoid.ker, onFun] at * - rw [h, h1, h2, h] - /-- Given types with multiplications `M, N`, the product of two congruence relations `c` on `M` and `d` on `N`: `(x₁, x₂), (y₁, y₂) ∈ M × N` are related by `c.prod d` iff `x₁` is related to `y₁` by `c` and `x₂` is related to `y₂` by `d`. -/ @@ -199,131 +61,6 @@ 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) } -variable (c) - --- Quotients -/-- Defining the quotient by a congruence relation of a type with a multiplication. -/ -@[to_additive "Defining the quotient by an additive congruence relation of a type with -an addition."] -protected def Quotient := - Quotient c.toSetoid - --- Porting note: made implicit -variable {c} - -/-- The morphism into the quotient by a congruence relation -/ -@[to_additive (attr := coe) "The morphism into the quotient by an additive congruence relation"] -def toQuotient : M → c.Quotient := - Quotient.mk'' - -variable (c) - --- Porting note: was `priority 0`. why? -/-- Coercion from a type with a multiplication to its quotient by a congruence relation. - -See Note [use has_coe_t]. -/ -@[to_additive "Coercion from a type with an addition to its quotient by an additive congruence -relation"] -instance (priority := 10) : CoeTC M c.Quotient := - ⟨toQuotient⟩ - --- Lower the priority since it unifies with any quotient type. -/-- The quotient by a decidable congruence relation has decidable equality. -/ -@[to_additive "The quotient by a decidable additive congruence relation has decidable equality."] -instance (priority := 500) [∀ a b, Decidable (c a b)] : DecidableEq c.Quotient := - inferInstanceAs (DecidableEq (Quotient c.toSetoid)) - -@[to_additive (attr := simp)] -theorem quot_mk_eq_coe {M : Type*} [Mul M] (c : Con M) (x : M) : Quot.mk c x = (x : c.Quotient) := - rfl - --- Porting note (#11215): TODO: restore `elab_as_elim` -/-- The function on the quotient by a congruence relation `c` induced by a function that is - constant on `c`'s equivalence classes. -/ -@[to_additive "The function on the quotient by a congruence relation `c` -induced by a function that is constant on `c`'s equivalence classes."] -protected def liftOn {β} {c : Con M} (q : c.Quotient) (f : M → β) (h : ∀ a b, c a b → f a = f b) : - β := - Quotient.liftOn' q f h - --- Porting note (#11215): TODO: restore `elab_as_elim` -/-- The binary function on the quotient by a congruence relation `c` induced by a binary function - that is constant on `c`'s equivalence classes. -/ -@[to_additive "The binary function on the quotient by a congruence relation `c` -induced by a binary function that is constant on `c`'s equivalence classes."] -protected def liftOn₂ {β} {c : Con M} (q r : c.Quotient) (f : M → M → β) - (h : ∀ a₁ a₂ b₁ b₂, c a₁ b₁ → c a₂ b₂ → f a₁ a₂ = f b₁ b₂) : β := - Quotient.liftOn₂' q r f h - -/-- A version of `Quotient.hrecOn₂'` for quotients by `Con`. -/ -@[to_additive "A version of `Quotient.hrecOn₂'` for quotients by `AddCon`."] -protected def hrecOn₂ {cM : Con M} {cN : Con N} {φ : cM.Quotient → cN.Quotient → Sort*} - (a : cM.Quotient) (b : cN.Quotient) (f : ∀ (x : M) (y : N), φ x y) - (h : ∀ x y x' y', cM x x' → cN y y' → HEq (f x y) (f x' y')) : φ a b := - Quotient.hrecOn₂' a b f h - -@[to_additive (attr := simp)] -theorem hrec_on₂_coe {cM : Con M} {cN : Con N} {φ : cM.Quotient → cN.Quotient → Sort*} (a : M) - (b : N) (f : ∀ (x : M) (y : N), φ x y) - (h : ∀ x y x' y', cM x x' → cN y y' → HEq (f x y) (f x' y')) : - Con.hrecOn₂ (↑a) (↑b) f h = f a b := - rfl - -variable {c} - -/-- The inductive principle used to prove propositions about the elements of a quotient by a - congruence relation. -/ -@[to_additive (attr := elab_as_elim) "The inductive principle used to prove propositions about -the elements of a quotient by an additive congruence relation."] -protected theorem induction_on {C : c.Quotient → Prop} (q : c.Quotient) (H : ∀ x : M, C x) : C q := - Quotient.inductionOn' q H - -/-- A version of `Con.induction_on` for predicates which take two arguments. -/ -@[to_additive (attr := elab_as_elim) "A version of `AddCon.induction_on` for predicates which take -two arguments."] -protected theorem induction_on₂ {d : Con N} {C : c.Quotient → d.Quotient → Prop} (p : c.Quotient) - (q : d.Quotient) (H : ∀ (x : M) (y : N), C x y) : C p q := - Quotient.inductionOn₂' p q H - -variable (c) - -/-- Two elements are related by a congruence relation `c` iff they are represented by the same - element of the quotient by `c`. -/ -@[to_additive (attr := simp) "Two elements are related by an additive congruence relation `c` iff -they are represented by the same element of the quotient by `c`."] -protected theorem eq {a b : M} : (a : c.Quotient) = (b : c.Quotient) ↔ c a b := - Quotient.eq'' - -/-- The multiplication induced on the quotient by a congruence relation on a type with a - multiplication. -/ -@[to_additive "The addition induced on the quotient by an additive congruence relation on a type -with an addition."] -instance hasMul : Mul c.Quotient := - ⟨Quotient.map₂' (· * ·) fun _ _ h1 _ _ h2 => c.mul h1 h2⟩ - -/-- 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 mul_ker_mk_eq : (mulKer ((↑) : M → c.Quotient) fun _ _ => rfl) = c := - ext fun _ _ => Quotient.eq'' - -variable {c} - -/-- The coercion to the quotient of a congruence relation commutes with multiplication (by - definition). -/ -@[to_additive (attr := simp) "The coercion to the quotient of an additive congruence relation -commutes with addition (by definition)."] -theorem coe_mul (x y : M) : (↑(x * y) : c.Quotient) = ↑x * ↑y := - rfl - -/-- Definition of the function on the quotient by a congruence relation `c` induced by a function - that is constant on `c`'s equivalence classes. -/ -@[to_additive (attr := simp) "Definition of the function on the quotient by an additive congruence -relation `c` induced by a function that is constant on `c`'s equivalence classes."] -protected theorem liftOn_coe {β} (c : Con M) (f : M → β) (h : ∀ a b, c a b → f a = f b) (x : M) : - Con.liftOn (x : c.Quotient) f h = f x := - rfl - /-- 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, @@ -332,305 +69,12 @@ 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 } --- The complete lattice of congruence relations on a type -/-- For congruence relations `c, d` on a type `M` with a multiplication, `c ≤ d` iff `∀ x y ∈ M`, - `x` is related to `y` by `d` if `x` is related to `y` by `c`. -/ -@[to_additive "For additive congruence relations `c, d` on a type `M` with an addition, `c ≤ d` iff -`∀ x y ∈ M`, `x` is related to `y` by `d` if `x` is related to `y` by `c`."] -instance : LE (Con M) where - le c d := ∀ ⦃x y⦄, c x y → d x y - -/-- Definition of `≤` for congruence relations. -/ -@[to_additive "Definition of `≤` for additive congruence relations."] -theorem le_def {c d : Con M} : c ≤ d ↔ ∀ {x y}, c x y → d x y := - Iff.rfl - -/-- The infimum of a set of congruence relations on a given type with a multiplication. -/ -@[to_additive "The infimum of a set of additive congruence relations on a given type with -an addition."] -instance : InfSet (Con M) where - sInf S := - { r := fun x y => ∀ c : Con M, c ∈ S → c x y - iseqv := ⟨fun x c _ => c.refl x, fun h c hc => c.symm <| h c hc, - fun h1 h2 c hc => c.trans (h1 c hc) <| h2 c hc⟩ - mul' := fun h1 h2 c hc => c.mul (h1 c hc) <| h2 c hc } - -/-- The infimum of a set of congruence relations is the same as the infimum of the set's image - under the map to the underlying equivalence relation. -/ -@[to_additive "The infimum of a set of additive congruence relations is the same as the infimum of -the set's image under the map to the underlying equivalence relation."] -theorem sInf_toSetoid (S : Set (Con M)) : (sInf S).toSetoid = sInf (toSetoid '' S) := - Setoid.ext' fun x y => - ⟨fun h r ⟨c, hS, hr⟩ => by rw [← hr]; exact h c hS, fun h c hS => h c.toSetoid ⟨c, hS, rfl⟩⟩ - -/-- The infimum of a set of congruence relations is the same as the infimum of the set's image - under the map to the underlying binary relation. -/ -@[to_additive (attr := simp, norm_cast) - "The infimum of a set of additive congruence relations is the same as the infimum - of the set's image under the map to the underlying binary relation."] -theorem coe_sInf (S : Set (Con M)) : - ⇑(sInf S) = sInf ((⇑) '' S) := by - ext - simp only [sInf_image, iInf_apply, iInf_Prop_eq] - rfl - -@[to_additive (attr := simp, norm_cast)] -theorem coe_iInf {ι : Sort*} (f : ι → Con M) : ⇑(iInf f) = ⨅ i, ⇑(f i) := by - rw [iInf, coe_sInf, ← Set.range_comp, sInf_range, Function.comp_def] - -@[to_additive] -instance : PartialOrder (Con M) where - le_refl _ _ _ := id - le_trans _ _ _ h1 h2 _ _ h := h2 <| h1 h - le_antisymm _ _ hc hd := ext fun _ _ => ⟨fun h => hc h, fun h => hd h⟩ - -/-- The complete lattice of congruence relations on a given type with a multiplication. -/ -@[to_additive "The complete lattice of additive congruence relations on a given type with -an addition."] -instance : CompleteLattice (Con M) where - __ := completeLatticeOfInf (Con M) fun s => - ⟨fun r hr x y h => (h : ∀ r ∈ s, (r : Con M) x y) r hr, fun _ hr _ _ h _ hr' => - hr hr' - h⟩ - inf c d := ⟨c.toSetoid ⊓ d.toSetoid, fun h1 h2 => ⟨c.mul h1.1 h2.1, d.mul h1.2 h2.2⟩⟩ - inf_le_left _ _ := fun _ _ h => h.1 - inf_le_right _ _ := fun _ _ h => h.2 - le_inf _ _ _ hb hc := fun _ _ h => ⟨hb h, hc h⟩ - top := { Setoid.completeLattice.top with mul' := by tauto } - le_top _ := fun _ _ _ => trivial - bot := { Setoid.completeLattice.bot with mul' := fun h1 h2 => h1 ▸ h2 ▸ rfl } - bot_le c := fun x _ h => h ▸ c.refl x - -/-- The infimum of two congruence relations equals the infimum of the underlying binary - operations. -/ -@[to_additive (attr := simp, norm_cast) - "The infimum of two additive congruence relations equals the infimum of the underlying binary - operations."] -theorem coe_inf {c d : Con M} : ⇑(c ⊓ d) = ⇑c ⊓ ⇑d := - rfl - -/-- Definition of the infimum of two congruence relations. -/ -@[to_additive "Definition of the infimum of two additive congruence relations."] -theorem inf_iff_and {c d : Con M} {x y} : (c ⊓ d) x y ↔ c x y ∧ d x y := - Iff.rfl - -/-- The inductively defined smallest congruence relation containing a binary relation `r` equals - the infimum of the set of congruence relations containing `r`. -/ -@[to_additive addConGen_eq "The inductively defined smallest additive congruence relation -containing a binary relation `r` equals the infimum of the set of additive congruence relations -containing `r`."] -theorem conGen_eq (r : M → M → Prop) : conGen r = sInf { s : Con M | ∀ x y, r x y → s x y } := - le_antisymm - (le_sInf (fun s hs x y (hxy : (conGen r) x y) => - show s x y by - apply ConGen.Rel.recOn (motive := fun x y _ => s x y) hxy - · exact fun x y h => hs x y h - · exact s.refl' - · exact fun _ => s.symm' - · exact fun _ _ => s.trans' - · exact fun _ _ => s.mul)) - (sInf_le ConGen.Rel.of) - -/-- The smallest congruence relation containing a binary relation `r` is contained in any - congruence relation containing `r`. -/ -@[to_additive addConGen_le "The smallest additive congruence relation containing a binary -relation `r` is contained in any additive congruence relation containing `r`."] -theorem conGen_le {r : M → M → Prop} {c : Con M} (h : ∀ x y, r x y → c x y) : - conGen r ≤ c := by rw [conGen_eq]; exact sInf_le h - -/-- Given binary relations `r, s` with `r` contained in `s`, the smallest congruence relation - containing `s` contains the smallest congruence relation containing `r`. -/ -@[to_additive addConGen_mono "Given binary relations `r, s` with `r` contained in `s`, the -smallest additive congruence relation containing `s` contains the smallest additive congruence -relation containing `r`."] -theorem conGen_mono {r s : M → M → Prop} (h : ∀ x y, r x y → s x y) : conGen r ≤ conGen s := - conGen_le fun x y hr => ConGen.Rel.of _ _ <| h x y hr - -/-- Congruence relations equal the smallest congruence relation in which they are contained. -/ -@[to_additive (attr := simp) addConGen_of_addCon "Additive congruence relations equal the smallest -additive congruence relation in which they are contained."] -theorem conGen_of_con (c : Con M) : conGen c = c := - le_antisymm (by rw [conGen_eq]; exact sInf_le fun _ _ => id) ConGen.Rel.of - --- Porting note: removing simp, simp can prove it -/-- The map sending a binary relation to the smallest congruence relation in which it is - contained is idempotent. -/ -@[to_additive addConGen_idem "The map sending a binary relation to the smallest additive -congruence relation in which it is contained is idempotent."] -theorem conGen_idem (r : M → M → Prop) : conGen (conGen r) = conGen r := - conGen_of_con _ - -/-- The supremum of congruence relations `c, d` equals the smallest congruence relation containing - the binary relation '`x` is related to `y` by `c` or `d`'. -/ -@[to_additive sup_eq_addConGen "The supremum of additive congruence relations `c, d` equals the -smallest additive congruence relation containing the binary relation '`x` is related to `y` -by `c` or `d`'."] -theorem sup_eq_conGen (c d : Con M) : c ⊔ d = conGen fun x y => c x y ∨ d x y := by - rw [conGen_eq] - apply congr_arg sInf - simp only [le_def, or_imp, ← forall_and] - -/-- The supremum of two congruence relations equals the smallest congruence relation containing - the supremum of the underlying binary operations. -/ -@[to_additive "The supremum of two additive congruence relations equals the smallest additive -congruence relation containing the supremum of the underlying binary operations."] -theorem sup_def {c d : Con M} : c ⊔ d = conGen (⇑c ⊔ ⇑d) := by rw [sup_eq_conGen]; rfl - -/-- The supremum of a set of congruence relations `S` equals the smallest congruence relation - containing the binary relation 'there exists `c ∈ S` such that `x` is related to `y` by - `c`'. -/ -@[to_additive sSup_eq_addConGen "The supremum of a set of additive congruence relations `S` equals -the smallest additive congruence relation containing the binary relation 'there exists `c ∈ S` -such that `x` is related to `y` by `c`'."] -theorem sSup_eq_conGen (S : Set (Con M)) : - sSup S = conGen fun x y => ∃ c : Con M, c ∈ S ∧ c x y := by - rw [conGen_eq] - apply congr_arg sInf - ext - exact ⟨fun h _ _ ⟨r, hr⟩ => h hr.1 hr.2, fun h r hS _ _ hr => h _ _ ⟨r, hS, hr⟩⟩ - -/-- The supremum of a set of congruence relations is the same as the smallest congruence relation - containing the supremum of the set's image under the map to the underlying binary relation. -/ -@[to_additive "The supremum of a set of additive congruence relations is the same as the smallest -additive congruence relation containing the supremum of the set's image under the map to the -underlying binary relation."] -theorem sSup_def {S : Set (Con M)} : - sSup S = conGen (sSup ((⇑) '' S)) := by - rw [sSup_eq_conGen, sSup_image] - congr with (x y) - simp only [sSup_image, iSup_apply, iSup_Prop_eq, exists_prop, rel_eq_coe] - -variable (M) - -/-- There is a Galois insertion of congruence relations on a type with a multiplication `M` into - binary relations on `M`. -/ -@[to_additive "There is a Galois insertion of additive congruence relations on a type with -an addition `M` into binary relations on `M`."] -protected def gi : @GaloisInsertion (M → M → Prop) (Con M) _ _ conGen DFunLike.coe where - choice r _ := conGen r - gc _ c := ⟨fun H _ _ h => H <| ConGen.Rel.of _ _ h, @fun H => conGen_of_con c ▸ conGen_mono H⟩ - le_l_u x := (conGen_of_con x).symm ▸ le_refl x - choice_eq _ _ := rfl - -variable {M} (c) - -/-- Given a function `f`, the smallest congruence relation containing the binary relation on `f`'s - image defined by '`x ≈ y` iff the elements of `f⁻¹(x)` are related to the elements of `f⁻¹(y)` - by a congruence relation `c`.' -/ -@[to_additive "Given a function `f`, the smallest additive congruence relation containing the -binary relation on `f`'s image defined by '`x ≈ y` iff the elements of `f⁻¹(x)` are related to the -elements of `f⁻¹(y)` by an additive congruence relation `c`.'"] -def mapGen (f : M → N) : Con N := - conGen fun x y => ∃ a b, f a = x ∧ f b = y ∧ c a b - -/-- Given a surjective multiplicative-preserving function `f` whose kernel is contained in a - congruence relation `c`, the congruence relation on `f`'s codomain defined by '`x ≈ y` iff the - elements of `f⁻¹(x)` are related to the elements of `f⁻¹(y)` by `c`.' -/ -@[to_additive "Given a surjective addition-preserving function `f` whose kernel is contained in -an additive congruence relation `c`, the additive congruence relation on `f`'s codomain defined -by '`x ≈ y` iff the elements of `f⁻¹(x)` are related to the elements of `f⁻¹(y)` by `c`.'"] -def mapOfSurjective (f : M → N) (H : ∀ x y, f (x * y) = f x * f y) (h : mulKer f H ≤ c) - (hf : Surjective f) : Con N := - { c.toSetoid.mapOfSurjective f h hf with - mul' := fun h₁ h₂ => by - rcases h₁ with ⟨a, b, rfl, rfl, h1⟩ - rcases h₂ with ⟨p, q, rfl, rfl, h2⟩ - exact ⟨a * p, b * q, by rw [H], by rw [H], c.mul h1 h2⟩ } - -/-- A specialization of 'the smallest congruence relation containing a congruence relation `c` - equals `c`'. -/ -@[to_additive "A specialization of 'the smallest additive congruence relation containing -an additive congruence relation `c` equals `c`'."] -theorem mapOfSurjective_eq_mapGen {c : Con M} {f : M → N} (H : ∀ x y, f (x * y) = f x * f y) - (h : mulKer f H ≤ c) (hf : Surjective f) : c.mapGen f = c.mapOfSurjective f H h hf := by - rw [← conGen_of_con (c.mapOfSurjective f H h hf)]; rfl - -/-- Given types with multiplications `M, N` and a congruence relation `c` on `N`, a - multiplication-preserving map `f : M → N` induces a congruence relation on `f`'s domain - defined by '`x ≈ y` iff `f(x)` is related to `f(y)` by `c`.' -/ -@[to_additive "Given types with additions `M, N` and an additive congruence relation `c` on `N`, -an addition-preserving map `f : M → N` induces an additive congruence relation on `f`'s domain -defined by '`x ≈ y` iff `f(x)` is related to `f(y)` by `c`.' "] -def comap (f : M → N) (H : ∀ x y, f (x * y) = f x * f y) (c : Con N) : Con M := - { c.toSetoid.comap f with - mul' := @fun w x y z h1 h2 => show c (f (w * y)) (f (x * z)) by rw [H, H]; exact c.mul h1 h2 } - -@[to_additive (attr := simp)] -theorem comap_rel {f : M → N} (H : ∀ x y, f (x * y) = f x * f y) {c : Con N} {x y : M} : - comap f H c x y ↔ c (f x) (f y) := - Iff.rfl - -section - -open Quotient - -/-- Given a congruence relation `c` on a type `M` with a multiplication, the order-preserving - bijection between the set of congruence relations containing `c` and the congruence relations - on the quotient of `M` by `c`. -/ -@[to_additive "Given an additive congruence relation `c` on a type `M` with an addition, -the order-preserving bijection between the set of additive congruence relations containing `c` and -the additive congruence relations on the quotient of `M` by `c`."] -def correspondence : { d // c ≤ d } ≃o Con c.Quotient where - toFun d := - d.1.mapOfSurjective (↑) (fun _ _ => rfl) (by rw [mul_ker_mk_eq]; exact d.2) <| - @Quotient.exists_rep _ c.toSetoid - invFun d := - ⟨comap ((↑) : M → c.Quotient) (fun _ _ => rfl) d, fun x y h => - show d x y by rw [c.eq.2 h]; exact d.refl _⟩ - left_inv d := - -- Porting note: by exact needed for unknown reason - by exact - Subtype.ext_iff_val.2 <| - ext fun x y => - ⟨fun h => - let ⟨a, b, hx, hy, H⟩ := h - d.1.trans (d.1.symm <| d.2 <| c.eq.1 hx) <| d.1.trans H <| d.2 <| c.eq.1 hy, - fun h => ⟨_, _, rfl, rfl, h⟩⟩ - right_inv d := - -- Porting note: by exact needed for unknown reason - by exact - ext fun x y => - ⟨fun h => - let ⟨_, _, hx, hy, H⟩ := h - hx ▸ hy ▸ H, - Con.induction_on₂ x y fun w z h => ⟨w, z, rfl, rfl, h⟩⟩ - map_rel_iff' := @fun s t => by - constructor - · intros h x y hs - rcases h ⟨x, y, rfl, rfl, hs⟩ with ⟨a, b, hx, hy, ht⟩ - exact t.1.trans (t.1.symm <| t.2 <| Quotient.eq_rel.1 hx) - (t.1.trans ht (t.2 <| Quotient.eq_rel.1 hy)) - · intros h _ _ hs - rcases hs with ⟨a, b, hx, hy, Hs⟩ - exact ⟨a, b, hx, hy, h Hs⟩ - -end - end section MulOneClass variable [MulOneClass M] [MulOneClass N] [MulOneClass P] (c : Con M) -/-- The quotient of a monoid by a congruence relation is a monoid. -/ -@[to_additive "The quotient of an `AddMonoid` by an additive congruence relation is -an `AddMonoid`."] -instance mulOneClass : MulOneClass c.Quotient where - one := ((1 : M) : c.Quotient) - mul_one x := Quotient.inductionOn' x fun _ => congr_arg ((↑) : M → c.Quotient) <| mul_one _ - one_mul x := Quotient.inductionOn' x fun _ => congr_arg ((↑) : M → c.Quotient) <| one_mul _ - -variable {c} - -/-- The 1 of the quotient of a monoid by a congruence relation is the equivalence class of the - monoid's 1. -/ -@[to_additive (attr := simp) "The 0 of the quotient of an `AddMonoid` by an additive congruence -relation is the equivalence class of the `AddMonoid`'s 0."] -theorem coe_one : ((1 : M) : c.Quotient) = 1 := - rfl - -variable (c) - -- Porting note: made M implicit /-- The submonoid of `M × M` defined by a congruence relation on a monoid `M`. -/ @[to_additive (attr := coe) "The `AddSubmonoid` of `M × M` defined by an additive congruence @@ -671,131 +115,14 @@ theorem to_submonoid_inj (c d : Con M) (H : (c : Submonoid (M × M)) = d) : c = theorem le_iff {c d : Con M} : c ≤ d ↔ (c : Submonoid (M × M)) ≤ d := ⟨fun h _ H => h H, fun h x y hc => h <| show (x, y) ∈ c from hc⟩ -/-- The kernel of a monoid homomorphism as a congruence relation. -/ -@[to_additive "The kernel of an `AddMonoid` homomorphism as an additive congruence relation."] -def ker (f : M →* P) : Con M := - mulKer f (map_mul f) - -/-- The definition of the congruence relation defined by a monoid homomorphism's kernel. -/ -@[to_additive (attr := simp) "The definition of the additive congruence relation defined by an -`AddMonoid` homomorphism's kernel."] -theorem ker_rel (f : M →* P) {x y} : ker f x y ↔ f x = f y := - Iff.rfl - -/-- There exists an element of the quotient of a monoid by a congruence relation (namely 1). -/ -@[to_additive "There exists an element of the quotient of an `AddMonoid` by a congruence relation -(namely 0)."] -instance Quotient.inhabited : Inhabited c.Quotient := - ⟨((1 : M) : c.Quotient)⟩ - -variable (c) - -/-- The natural homomorphism from a monoid to its quotient by a congruence relation. -/ -@[to_additive "The natural homomorphism from an `AddMonoid` to its quotient by an additive -congruence relation."] -def mk' : M →* c.Quotient := - { toFun := (↑) - map_one' := rfl - map_mul' := fun _ _ => rfl } - variable (x y : M) -/-- The kernel of the natural homomorphism from a monoid to its quotient by a congruence - relation `c` equals `c`. -/ -@[to_additive (attr := simp) "The kernel of the natural homomorphism from an `AddMonoid` to its -quotient by an additive congruence relation `c` equals `c`."] -theorem mk'_ker : ker c.mk' = c := - ext fun _ _ => c.eq - -variable {c} - -/-- The natural homomorphism from a monoid to its quotient by a congruence relation is - surjective. -/ -@[to_additive "The natural homomorphism from an `AddMonoid` to its quotient by a congruence -relation is surjective."] -theorem mk'_surjective : Surjective c.mk' := - Quotient.surjective_Quotient_mk'' - -@[to_additive (attr := simp)] -theorem coe_mk' : (c.mk' : M → c.Quotient) = ((↑) : M → c.Quotient) := - rfl - @[to_additive (attr := simp)] -- Porting note: removed dot notation theorem mrange_mk' : MonoidHom.mrange c.mk' = ⊤ := MonoidHom.mrange_top_iff_surjective.2 mk'_surjective --- Porting note: used to abuse defeq between sets and predicates -@[to_additive] -theorem ker_apply {f : M →* P} {x y} : ker f x y ↔ f x = f y := Iff.rfl - -/-- Given a monoid homomorphism `f : N → M` and a congruence relation `c` on `M`, the congruence - relation induced on `N` by `f` equals the kernel of `c`'s quotient homomorphism composed with - `f`. -/ -@[to_additive "Given an `AddMonoid` homomorphism `f : N → M` and an additive congruence relation -`c` on `M`, the additive congruence relation induced on `N` by `f` equals the kernel of `c`'s -quotient homomorphism composed with `f`."] -theorem comap_eq {f : N →* M} : comap f f.map_mul c = ker (c.mk'.comp f) := - ext fun x y => show c _ _ ↔ c.mk' _ = c.mk' _ by rw [← c.eq]; rfl - -variable (c) (f : M →* P) - -/-- 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 -relation `c` induced by a homomorphism constant on `c`'s equivalence classes."] -def lift (H : c ≤ ker f) : c.Quotient →* P where - toFun x := (Con.liftOn x f) fun _ _ h => H h - map_one' := by rw [← f.map_one]; rfl - map_mul' x y := Con.induction_on₂ x y fun m n => by - dsimp only [← coe_mul, Con.liftOn_coe] - rw [map_mul] - -variable {c f} - -/-- The diagram describing the universal property for quotients of monoids commutes. -/ -@[to_additive "The diagram describing the universal property for quotients of `AddMonoid`s -commutes."] -theorem lift_mk' (H : c ≤ ker f) (x) : c.lift f H (c.mk' x) = f x := - rfl - -/-- The diagram describing the universal property for quotients of monoids commutes. -/ -@[to_additive (attr := simp) "The diagram describing the universal property for quotients of -`AddMonoid`s commutes."] -theorem lift_coe (H : c ≤ ker f) (x : M) : c.lift f H x = f x := - rfl - -/-- The diagram describing the universal property for quotients of monoids commutes. -/ -@[to_additive (attr := simp) "The diagram describing the universal property for quotients of -`AddMonoid`s commutes."] -theorem lift_comp_mk' (H : c ≤ ker f) : (c.lift f H).comp c.mk' = f := by ext; rfl - -/-- Given a homomorphism `f` from the quotient of a monoid by a congruence relation, `f` equals the - homomorphism on the quotient induced by `f` composed with the natural map from the monoid to - the quotient. -/ -@[to_additive (attr := simp) "Given a homomorphism `f` from the quotient of an `AddMonoid` by an -additive congruence relation, `f` equals the homomorphism on the quotient induced by `f` composed -with the natural map from the `AddMonoid` to the quotient."] -theorem lift_apply_mk' (f : c.Quotient →* P) : - (c.lift (f.comp c.mk') fun x y h => show f ↑x = f ↑y by rw [c.eq.2 h]) = f := by - ext x; rcases x with ⟨⟩; rfl - -/-- Homomorphisms on the quotient of a monoid by a congruence relation are equal if they - are equal on elements that are coercions from the monoid. -/ -@[to_additive "Homomorphisms on the quotient of an `AddMonoid` by an additive congruence relation -are equal if they are equal on elements that are coercions from the `AddMonoid`."] -theorem lift_funext (f g : c.Quotient →* P) (h : ∀ a : M, f a = g a) : f = g := by - rw [← lift_apply_mk' f, ← lift_apply_mk' g] - congr 1 - exact DFunLike.ext_iff.2 h - -/-- The uniqueness part of the universal property for quotients of monoids. -/ -@[to_additive "The uniqueness part of the universal property for quotients of `AddMonoid`s."] -theorem lift_unique (H : c ≤ ker f) (g : c.Quotient →* P) (Hg : g.comp c.mk' = f) : - g = c.lift f H := - (lift_funext g (c.lift f H)) fun x => by - subst f - rfl +variable {f : M →* P} /-- Given a congruence relation `c` on a monoid and a homomorphism `f` constant on `c`'s equivalence classes, `f` has the same image as the homomorphism that `f` induces on the @@ -806,42 +133,6 @@ on the quotient."] theorem lift_range (H : c ≤ ker f) : MonoidHom.mrange (c.lift f H) = MonoidHom.mrange f := Submonoid.ext fun x => ⟨by rintro ⟨⟨y⟩, hy⟩; exact ⟨y, hy⟩, fun ⟨y, hy⟩ => ⟨↑y, hy⟩⟩ -/-- Surjective monoid homomorphisms constant on a congruence relation `c`'s equivalence classes - induce a surjective homomorphism on `c`'s quotient. -/ -@[to_additive "Surjective `AddMonoid` homomorphisms constant on an additive congruence -relation `c`'s equivalence classes induce a surjective homomorphism on `c`'s quotient."] -theorem lift_surjective_of_surjective (h : c ≤ ker f) (hf : Surjective f) : - Surjective (c.lift f h) := fun y => - (Exists.elim (hf y)) fun w hw => ⟨w, (lift_mk' h w).symm ▸ hw⟩ - -variable (c f) - -/-- Given a monoid homomorphism `f` from `M` to `P`, the kernel of `f` is the unique congruence - relation on `M` whose induced map from the quotient of `M` to `P` is injective. -/ -@[to_additive "Given an `AddMonoid` homomorphism `f` from `M` to `P`, the kernel of `f` -is the unique additive congruence relation on `M` whose induced map from the quotient of `M` -to `P` is injective."] -theorem ker_eq_lift_of_injective (H : c ≤ ker f) (h : Injective (c.lift f H)) : ker f = c := - toSetoid_inj <| Setoid.ker_eq_lift_of_injective f H h - -variable {c} - -/-- The homomorphism induced on the quotient of a monoid by the kernel of a monoid homomorphism. -/ -@[to_additive "The homomorphism induced on the quotient of an `AddMonoid` by the kernel -of an `AddMonoid` homomorphism."] -def kerLift : (ker f).Quotient →* P := - ((ker f).lift f) fun _ _ => id - -variable {f} - -/-- The diagram described by the universal property for quotients of monoids, when the congruence - relation is the kernel of the homomorphism, commutes. -/ -@[to_additive (attr := simp) "The diagram described by the universal property for quotients -of `AddMonoid`s, when the additive congruence relation is the kernel of the homomorphism, -commutes."] -theorem kerLift_mk (x : M) : kerLift f x = f x := - rfl - /-- Given a monoid homomorphism `f`, the induced homomorphism on the quotient by `f`'s kernel has the same image as `f`. -/ @[to_additive (attr := simp) "Given an `AddMonoid` homomorphism `f`, the induced homomorphism @@ -849,30 +140,6 @@ on the quotient by `f`'s kernel has the same image as `f`."] theorem kerLift_range_eq : MonoidHom.mrange (kerLift f) = MonoidHom.mrange f := lift_range fun _ _ => id -/-- A monoid homomorphism `f` induces an injective homomorphism on the quotient by `f`'s kernel. -/ -@[to_additive "An `AddMonoid` homomorphism `f` induces an injective homomorphism on the quotient -by `f`'s kernel."] -theorem kerLift_injective (f : M →* P) : Injective (kerLift f) := fun x y => - Quotient.inductionOn₂' x y fun _ _ => (ker f).eq.2 - -/-- Given congruence relations `c, d` on a monoid such that `d` contains `c`, `d`'s quotient - map induces a homomorphism from the quotient by `c` to the quotient by `d`. -/ -@[to_additive "Given additive congruence relations `c, d` on an `AddMonoid` such that `d` -contains `c`, `d`'s quotient map induces a homomorphism from the quotient by `c` to the quotient -by `d`."] -def map (c d : Con M) (h : c ≤ d) : c.Quotient →* d.Quotient := - (c.lift d.mk') fun x y hc => show (ker d.mk') x y from (mk'_ker d).symm ▸ h hc - -/-- Given congruence relations `c, d` on a monoid such that `d` contains `c`, the definition of - the homomorphism from the quotient by `c` to the quotient by `d` induced by `d`'s quotient - map. -/ -@[to_additive "Given additive congruence relations `c, d` on an `AddMonoid` such that `d` -contains `c`, the definition of the homomorphism from the quotient by `c` to the quotient by `d` -induced by `d`'s quotient map."] -theorem map_apply {c d : Con M} (h : c ≤ d) (x) : - c.map d h x = c.lift d.mk' (fun _ _ hc => d.eq.2 <| h hc) x := - rfl - variable (c) /-- The **first isomorphism theorem for monoids**. -/ @@ -934,211 +201,13 @@ end MulOneClass section Monoids -/-- Multiplicative congruence relations preserve natural powers. -/ -@[to_additive "Additive congruence relations preserve natural scaling."] -protected theorem pow {M : Type*} [Monoid M] (c : Con M) : - ∀ (n : ℕ) {w x}, c w x → c (w ^ n) (x ^ n) - | 0, w, x, _ => by simpa using c.refl _ - | Nat.succ n, w, x, h => by simpa [pow_succ] using c.mul (Con.pow c n h) h - -@[to_additive] -instance one [MulOneClass M] (c : Con M) : One c.Quotient where - -- Using Quotient.mk'' here instead of c.toQuotient - -- since c.toQuotient is not reducible. - -- This would lead to non-defeq diamonds since this instance ends up in - -- quotients modulo ideals. - one := Quotient.mk'' (1 : M) - -- one := ((1 : M) : c.Quotient) - @[to_additive] theorem smul {α M : Type*} [MulOneClass M] [SMul α M] [IsScalarTower α M M] (c : Con M) (a : α) {w x : M} (h : c w x) : c (a • w) (a • x) := by simpa only [smul_one_mul] using c.mul (c.refl' (a • (1 : M) : M)) h -instance _root_.AddCon.Quotient.nsmul {M : Type*} [AddMonoid M] (c : AddCon M) : - SMul ℕ c.Quotient where - smul n := (Quotient.map' (n • ·)) fun _ _ => c.nsmul n - -@[to_additive existing AddCon.Quotient.nsmul] -instance {M : Type*} [Monoid M] (c : Con M) : Pow c.Quotient ℕ where - pow x n := Quotient.map' (fun x => x ^ n) (fun _ _ => c.pow n) x - -/-- The quotient of a semigroup by a congruence relation is a semigroup. -/ -@[to_additive "The quotient of an `AddSemigroup` by an additive congruence relation is -an `AddSemigroup`."] -instance semigroup {M : Type*} [Semigroup M] (c : Con M) : Semigroup c.Quotient := - { (Function.Surjective.semigroup _ Quotient.surjective_Quotient_mk'' fun _ _ => rfl : - Semigroup c.Quotient) with - /- The `toMul` field is given explicitly for performance reasons. - This avoids any need to unfold `Function.Surjective.semigroup` when the type checker is checking - that instance diagrams commute -/ - toMul := Con.hasMul _ } - -/-- The quotient of a commutative semigroup by a congruence relation is a semigroup. -/ -@[to_additive "The quotient of an `AddCommSemigroup` by an additive congruence relation is -an `AddCommSemigroup`."] -instance commSemigroup {M : Type*} [CommSemigroup M] (c : Con M) : CommSemigroup c.Quotient := - { (Function.Surjective.commSemigroup _ Quotient.surjective_Quotient_mk'' fun _ _ => rfl : - CommSemigroup c.Quotient) with - /- The `toSemigroup` field is given explicitly for performance reasons. - This avoids any need to unfold `Function.Surjective.commSemigroup` when the type checker is - checking that instance diagrams commute -/ - toSemigroup := Con.semigroup _ } - -/-- The quotient of a monoid by a congruence relation is a monoid. -/ -@[to_additive "The quotient of an `AddMonoid` by an additive congruence relation is -an `AddMonoid`."] -instance monoid {M : Type*} [Monoid M] (c : Con M) : Monoid c.Quotient := - { (Function.Surjective.monoid _ Quotient.surjective_Quotient_mk'' rfl - (fun _ _ => rfl) fun _ _ => rfl : Monoid c.Quotient) with - /- The `toSemigroup` and `toOne` fields are given explicitly for performance reasons. - This avoids any need to unfold `Function.Surjective.monoid` when the type checker is - checking that instance diagrams commute -/ - toSemigroup := Con.semigroup _ - toOne := Con.one _ } - -/-- The quotient of a `CommMonoid` by a congruence relation is a `CommMonoid`. -/ -@[to_additive "The quotient of an `AddCommMonoid` by an additive congruence -relation is an `AddCommMonoid`."] -instance commMonoid {M : Type*} [CommMonoid M] (c : Con M) : CommMonoid c.Quotient := - { (Function.Surjective.commMonoid _ Quotient.surjective_Quotient_mk'' rfl - (fun _ _ => rfl) fun _ _ => rfl : CommMonoid c.Quotient) with - /- The `toMonoid` field is given explicitly for performance reasons. - This avoids any need to unfold `Function.Surjective.commMonoid` when the type checker is - checking that instance diagrams commute -/ - toMonoid := Con.monoid _ } - -/-- Sometimes, a group is defined as a quotient of a monoid by a congruence relation. -Usually, the inverse operation is defined as `Setoid.map f _` for some `f`. -This lemma allows to avoid code duplication in the definition of the inverse operation: -instead of proving both `∀ x y, c x y → c (f x) (f y)` (to define the operation) -and `∀ x, c (f x * x) 1` (to prove the group laws), one can only prove the latter. -/ -@[to_additive "Sometimes, an additive group is defined as a quotient of a monoid - by an additive congruence relation. - Usually, the inverse operation is defined as `Setoid.map f _` for some `f`. - This lemma allows to avoid code duplication in the definition of the inverse operation: - instead of proving both `∀ x y, c x y → c (f x) (f y)` (to define the operation) - and `∀ x, c (f x + x) 0` (to prove the group laws), one can only prove the latter."] -theorem map_of_mul_left_rel_one [Monoid M] (c : Con M) - (f : M → M) (hf : ∀ x, c (f x * x) 1) {x y} (h : c x y) : c (f x) (f y) := by - simp only [← Con.eq, coe_one, coe_mul] at * - have hf' : ∀ x : M, (x : c.Quotient) * f x = 1 := fun x ↦ - calc - (x : c.Quotient) * f x = f (f x) * f x * (x * f x) := by simp [hf] - _ = f (f x) * (f x * x) * f x := by ac_rfl - _ = 1 := by simp [hf] - have : (⟨_, _, hf' x, hf x⟩ : c.Quotientˣ) = ⟨_, _, hf' y, hf y⟩ := Units.ext h - exact congr_arg Units.inv this - end Monoids -section Groups - -variable [Group M] [Group N] [Group P] (c : Con M) - -/-- Multiplicative congruence relations preserve inversion. -/ -@[to_additive "Additive congruence relations preserve negation."] -protected theorem inv {x y} (h : c x y) : c x⁻¹ y⁻¹ := - c.map_of_mul_left_rel_one Inv.inv (fun x => by simp only [inv_mul_cancel, c.refl 1]) h - -/-- Multiplicative congruence relations preserve division. -/ -@[to_additive "Additive congruence relations preserve subtraction."] -protected theorem div : ∀ {w x y z}, c w x → c y z → c (w / y) (x / z) := @fun w x y z h1 h2 => by - simpa only [div_eq_mul_inv] using c.mul h1 (c.inv h2) - -/-- Multiplicative congruence relations preserve integer powers. -/ -@[to_additive "Additive congruence relations preserve integer scaling."] -protected theorem zpow : ∀ (n : ℤ) {w x}, c w x → c (w ^ n) (x ^ n) - | Int.ofNat n, w, x, h => by simpa only [zpow_natCast, Int.ofNat_eq_coe] using c.pow n h - | Int.negSucc n, w, x, h => by simpa only [zpow_negSucc] using c.inv (c.pow _ h) - -/-- The inversion induced on the quotient by a congruence relation on a type with an - inversion. -/ -@[to_additive "The negation induced on the quotient by an additive congruence relation on a type -with a negation."] -instance hasInv : Inv c.Quotient := - ⟨(Quotient.map' Inv.inv) fun _ _ => c.inv⟩ - -/-- The division induced on the quotient by a congruence relation on a type with a - division. -/ -@[to_additive "The subtraction induced on the quotient by an additive congruence relation on a type -with a subtraction."] -instance hasDiv : Div c.Quotient := - ⟨(Quotient.map₂' (· / ·)) fun _ _ h₁ _ _ h₂ => c.div h₁ h₂⟩ - -/-- The integer scaling induced on the quotient by a congruence relation on a type with a - subtraction. -/ -instance _root_.AddCon.Quotient.zsmul {M : Type*} [AddGroup M] (c : AddCon M) : - SMul ℤ c.Quotient := - ⟨fun z => (Quotient.map' (z • ·)) fun _ _ => c.zsmul z⟩ - -/-- The integer power induced on the quotient by a congruence relation on a type with a - division. -/ -@[to_additive existing AddCon.Quotient.zsmul] -instance zpowinst : Pow c.Quotient ℤ := - ⟨fun x z => Quotient.map' (fun x => x ^ z) (fun _ _ h => c.zpow z h) x⟩ - -/-- The quotient of a group by a congruence relation is a group. -/ -@[to_additive "The quotient of an `AddGroup` by an additive congruence relation is -an `AddGroup`."] -instance group : Group c.Quotient := - { (Function.Surjective.group Quotient.mk'' - Quotient.surjective_Quotient_mk'' rfl (fun _ _ => rfl) (fun _ => rfl) - (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl : Group c.Quotient) with - toMonoid := Con.monoid _ - toInv := Con.hasInv _ - toDiv := Con.hasDiv _ } - -end Groups - -section Units - -variable {α : Type*} [Monoid M] {c : Con M} - -/-- In order to define a function `(Con.Quotient c)ˣ → α` on the units of `Con.Quotient c`, -where `c : Con M` is a multiplicative congruence on a monoid, it suffices to define a function `f` -that takes elements `x y : M` with proofs of `c (x * y) 1` and `c (y * x) 1`, and returns an element -of `α` provided that `f x y _ _ = f x' y' _ _` whenever `c x x'` and `c y y'`. -/ -@[to_additive] -def liftOnUnits (u : Units c.Quotient) (f : ∀ x y : M, c (x * y) 1 → c (y * x) 1 → α) - (Hf : ∀ x y hxy hyx x' y' hxy' hyx', - c x x' → c y y' → f x y hxy hyx = f x' y' hxy' hyx') : α := by - refine - Con.hrecOn₂ (cN := c) (φ := fun x y => x * y = 1 → y * x = 1 → α) (u : c.Quotient) - (↑u⁻¹ : c.Quotient) - (fun (x y : M) (hxy : (x * y : c.Quotient) = 1) (hyx : (y * x : c.Quotient) = 1) => - f x y (c.eq.1 hxy) (c.eq.1 hyx)) - (fun x y x' y' hx hy => ?_) u.3 u.4 - refine Function.hfunext ?_ ?_ - · rw [c.eq.2 hx, c.eq.2 hy] - · rintro Hxy Hxy' - - refine Function.hfunext ?_ ?_ - · rw [c.eq.2 hx, c.eq.2 hy] - · rintro Hyx Hyx' - - exact heq_of_eq (Hf _ _ _ _ _ _ _ _ hx hy) - -/-- In order to define a function `(Con.Quotient c)ˣ → α` on the units of `Con.Quotient c`, -where `c : Con M` is a multiplicative congruence on a monoid, it suffices to define a function `f` -that takes elements `x y : M` with proofs of `c (x * y) 1` and `c (y * x) 1`, and returns an element -of `α` provided that `f x y _ _ = f x' y' _ _` whenever `c x x'` and `c y y'`. -/ -add_decl_doc AddCon.liftOnAddUnits - -@[to_additive (attr := simp)] -theorem liftOnUnits_mk (f : ∀ x y : M, c (x * y) 1 → c (y * x) 1 → α) - (Hf : ∀ x y hxy hyx x' y' hxy' hyx', c x x' → c y y' → f x y hxy hyx = f x' y' hxy' hyx') - (x y : M) (hxy hyx) : - liftOnUnits ⟨(x : c.Quotient), y, hxy, hyx⟩ f Hf = f x y (c.eq.1 hxy) (c.eq.1 hyx) := - rfl - -@[to_additive (attr := elab_as_elim)] -theorem induction_on_units {p : Units c.Quotient → Prop} (u : Units c.Quotient) - (H : ∀ (x y : M) (hxy : c (x * y) 1) (hyx : c (y * x) 1), p ⟨x, y, c.eq.2 hxy, c.eq.2 hyx⟩) : - p u := by - rcases u with ⟨⟨x⟩, ⟨y⟩, h₁, h₂⟩ - exact H x y (c.eq.1 h₁) (c.eq.1 h₂) - -end Units - section Actions @[to_additive] diff --git a/Mathlib/GroupTheory/Congruence/BigOperators.lean b/Mathlib/GroupTheory/Congruence/BigOperators.lean index 5e4ad659e7ac7a..d7acdc5c89d6d3 100644 --- a/Mathlib/GroupTheory/Congruence/BigOperators.lean +++ b/Mathlib/GroupTheory/Congruence/BigOperators.lean @@ -4,10 +4,10 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Amelia Livingston -/ -import Mathlib.GroupTheory.Congruence.Basic import Mathlib.Algebra.BigOperators.Group.Finset import Mathlib.Algebra.BigOperators.Group.Multiset import Mathlib.Algebra.BigOperators.Group.List +import Mathlib.GroupTheory.Congruence.Defs /-! # Interactions between `∑, ∏` and `(Add)Con` diff --git a/Mathlib/GroupTheory/Congruence/Defs.lean b/Mathlib/GroupTheory/Congruence/Defs.lean new file mode 100644 index 00000000000000..c8c38842eee778 --- /dev/null +++ b/Mathlib/GroupTheory/Congruence/Defs.lean @@ -0,0 +1,817 @@ +/- +Copyright (c) 2019 Amelia Livingston. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Amelia Livingston +-/ +import Mathlib.Algebra.Group.InjSurj +import Mathlib.Algebra.Group.Units.Defs +import Mathlib.Data.Setoid.Basic + +/-! +# Congruence relations + +This file defines congruence relations: equivalence relations that preserve a binary operation, +which in this case is multiplication or addition. The principal definition is a `structure` +extending a `Setoid` (an equivalence relation), and the inductive definition of the smallest +congruence relation containing a binary relation is also given (see `ConGen`). + +The file also proves basic properties of the quotient of a type by a congruence relation, and the +complete lattice of congruence relations on a type. We then establish an order-preserving bijection +between the set of congruence relations containing a congruence relation `c` and the set of +congruence relations on the quotient by `c`. + +The second half of the file concerns congruence relations on monoids, in which case the +quotient by the congruence relation is also a monoid. + +## Implementation notes + +The inductive definition of a congruence relation could be a nested inductive type, defined using +the equivalence closure of a binary relation `EqvGen`, but the recursor generated does not work. +A nested inductive definition could conceivably shorten proofs, because they would allow invocation +of the corresponding lemmas about `EqvGen`. + +The lemmas `refl`, `symm` and `trans` are not tagged with `@[refl]`, `@[symm]`, and `@[trans]` +respectively as these tags do not work on a structure coerced to a binary relation. + +There is a coercion from elements of a type to the element's equivalence class under a +congruence relation. + +A congruence relation on a monoid `M` can be thought of as a submonoid of `M × M` for which +membership is an equivalence relation, but whilst this fact is established in the file, it is not +used, since this perspective adds more layers of definitional unfolding. + +## Tags + +congruence, congruence relation, quotient, quotient by congruence relation, monoid, +quotient monoid, isomorphism theorems +-/ + + +variable (M : Type*) {N : Type*} {P : Type*} + +open Function Setoid + +/-- A congruence relation on a type with an addition is an equivalence relation which + preserves addition. -/ +structure AddCon [Add M] extends Setoid M where + /-- Additive congruence relations are closed under addition -/ + add' : ∀ {w x y z}, r w x → r y z → r (w + y) (x + z) + +/-- A congruence relation on a type with a multiplication is an equivalence relation which + preserves multiplication. -/ +@[to_additive AddCon] +structure Con [Mul M] extends Setoid M where + /-- Congruence relations are closed under multiplication -/ + mul' : ∀ {w x y z}, r w x → r y z → r (w * y) (x * z) + +/-- The equivalence relation underlying an additive congruence relation. -/ +add_decl_doc AddCon.toSetoid + +/-- The equivalence relation underlying a multiplicative congruence relation. -/ +add_decl_doc Con.toSetoid + +variable {M} + +/-- The inductively defined smallest additive congruence relation containing a given binary + relation. -/ +inductive AddConGen.Rel [Add M] (r : M → M → Prop) : M → M → Prop + | of : ∀ x y, r x y → AddConGen.Rel r x y + | refl : ∀ x, AddConGen.Rel r x x + | symm : ∀ {x y}, AddConGen.Rel r x y → AddConGen.Rel r y x + | trans : ∀ {x y z}, AddConGen.Rel r x y → AddConGen.Rel r y z → AddConGen.Rel r x z + | add : ∀ {w x y z}, AddConGen.Rel r w x → AddConGen.Rel r y z → AddConGen.Rel r (w + y) (x + z) + +/-- The inductively defined smallest multiplicative congruence relation containing a given binary + relation. -/ +@[to_additive AddConGen.Rel] +inductive ConGen.Rel [Mul M] (r : M → M → Prop) : M → M → Prop + | of : ∀ x y, r x y → ConGen.Rel r x y + | refl : ∀ x, ConGen.Rel r x x + | symm : ∀ {x y}, ConGen.Rel r x y → ConGen.Rel r y x + | trans : ∀ {x y z}, ConGen.Rel r x y → ConGen.Rel r y z → ConGen.Rel r x z + | mul : ∀ {w x y z}, ConGen.Rel r w x → ConGen.Rel r y z → ConGen.Rel r (w * y) (x * z) + +/-- The inductively defined smallest multiplicative congruence relation containing a given binary + relation. -/ +@[to_additive addConGen "The inductively defined smallest additive congruence relation containing +a given binary relation."] +def conGen [Mul M] (r : M → M → Prop) : Con M := + ⟨⟨ConGen.Rel r, ⟨ConGen.Rel.refl, ConGen.Rel.symm, ConGen.Rel.trans⟩⟩, ConGen.Rel.mul⟩ + +namespace Con + +section + +variable [Mul M] [Mul N] [Mul P] (c : Con M) + +@[to_additive] +instance : Inhabited (Con M) := + ⟨conGen EmptyRelation⟩ + +/-- A coercion from a congruence relation to its underlying binary relation. -/ +@[to_additive "A coercion from an additive congruence relation to its underlying binary relation."] +instance : FunLike (Con M) M (M → Prop) where + coe c := c.r + coe_injective' x y h := by + rcases x with ⟨⟨x, _⟩, _⟩ + rcases y with ⟨⟨y, _⟩, _⟩ + have : x = y := h + subst x; rfl + +@[to_additive (attr := simp)] +theorem rel_eq_coe (c : Con M) : c.r = c := + rfl + +/-- Congruence relations are reflexive. -/ +@[to_additive "Additive congruence relations are reflexive."] +protected theorem refl (x) : c x x := + c.toSetoid.refl' x + +/-- Congruence relations are symmetric. -/ +@[to_additive "Additive congruence relations are symmetric."] +protected theorem symm {x y} : c x y → c y x := c.toSetoid.symm' + +/-- Congruence relations are transitive. -/ +@[to_additive "Additive congruence relations are transitive."] +protected theorem trans {x y z} : c x y → c y z → c x z := c.toSetoid.trans' + +/-- Multiplicative congruence relations preserve multiplication. -/ +@[to_additive "Additive congruence relations preserve addition."] +protected theorem mul {w x y z} : c w x → c y z → c (w * y) (x * z) := c.mul' + +@[to_additive (attr := simp)] +theorem rel_mk {s : Setoid M} {h a b} : Con.mk s h a b ↔ r a b := + Iff.rfl + +/-- Given a type `M` with a multiplication, a congruence relation `c` on `M`, and elements of `M` + `x, y`, `(x, y) ∈ M × M` iff `x` is related to `y` by `c`. -/ +@[to_additive "Given a type `M` with an addition, `x, y ∈ M`, and an additive congruence relation +`c` on `M`, `(x, y) ∈ M × M` iff `x` is related to `y` by `c`."] +instance : Membership (M × M) (Con M) := + ⟨fun c x => c x.1 x.2⟩ + +variable {c} + +/-- The map sending a congruence relation to its underlying binary relation is injective. -/ +@[to_additive "The map sending an additive congruence relation to its underlying binary relation +is injective."] +theorem ext' {c d : Con M} (H : ⇑c = ⇑d) : c = d := DFunLike.coe_injective H + +/-- Extensionality rule for congruence relations. -/ +@[to_additive (attr := ext) "Extensionality rule for additive congruence relations."] +theorem ext {c d : Con M} (H : ∀ x y, c x y ↔ d x y) : c = d := + ext' <| by ext; apply H + +/-- The map sending a congruence relation to its underlying equivalence relation is injective. -/ +@[to_additive "The map sending an additive congruence relation to its underlying equivalence +relation is injective."] +theorem toSetoid_inj {c d : Con M} (H : c.toSetoid = d.toSetoid) : c = d := + ext <| ext_iff.1 H + +/-- Two congruence relations are equal iff their underlying binary relations are equal. -/ +@[to_additive "Two additive congruence relations are equal iff their underlying binary relations +are equal."] +theorem coe_inj {c d : Con M} : ⇑c = ⇑d ↔ c = d := DFunLike.coe_injective.eq_iff + +/-- The kernel of a multiplication-preserving function as a congruence relation. -/ +@[to_additive "The kernel of an addition-preserving function as an additive congruence relation."] +def mulKer (f : M → P) (h : ∀ x y, f (x * y) = f x * f y) : Con M where + toSetoid := Setoid.ker f + mul' h1 h2 := by + dsimp [Setoid.ker, onFun] at * + rw [h, h1, h2, h] + +variable (c) + +-- Quotients +/-- Defining the quotient by a congruence relation of a type with a multiplication. -/ +@[to_additive "Defining the quotient by an additive congruence relation of a type with +an addition."] +protected def Quotient := + Quotient c.toSetoid + +-- Porting note: made implicit +variable {c} + +/-- The morphism into the quotient by a congruence relation -/ +@[to_additive (attr := coe) "The morphism into the quotient by an additive congruence relation"] +def toQuotient : M → c.Quotient := + Quotient.mk'' + +variable (c) + +-- Porting note: was `priority 0`. why? +/-- Coercion from a type with a multiplication to its quotient by a congruence relation. + +See Note [use has_coe_t]. -/ +@[to_additive "Coercion from a type with an addition to its quotient by an additive congruence +relation"] +instance (priority := 10) : CoeTC M c.Quotient := + ⟨toQuotient⟩ + +-- Lower the priority since it unifies with any quotient type. +/-- The quotient by a decidable congruence relation has decidable equality. -/ +@[to_additive "The quotient by a decidable additive congruence relation has decidable equality."] +instance (priority := 500) [∀ a b, Decidable (c a b)] : DecidableEq c.Quotient := + inferInstanceAs (DecidableEq (Quotient c.toSetoid)) + +@[to_additive (attr := simp)] +theorem quot_mk_eq_coe {M : Type*} [Mul M] (c : Con M) (x : M) : Quot.mk c x = (x : c.Quotient) := + rfl + +-- Porting note (#11215): TODO: restore `elab_as_elim` +/-- The function on the quotient by a congruence relation `c` induced by a function that is + constant on `c`'s equivalence classes. -/ +@[to_additive "The function on the quotient by a congruence relation `c` +induced by a function that is constant on `c`'s equivalence classes."] +protected def liftOn {β} {c : Con M} (q : c.Quotient) (f : M → β) (h : ∀ a b, c a b → f a = f b) : + β := + Quotient.liftOn' q f h + +-- Porting note (#11215): TODO: restore `elab_as_elim` +/-- The binary function on the quotient by a congruence relation `c` induced by a binary function + that is constant on `c`'s equivalence classes. -/ +@[to_additive "The binary function on the quotient by a congruence relation `c` +induced by a binary function that is constant on `c`'s equivalence classes."] +protected def liftOn₂ {β} {c : Con M} (q r : c.Quotient) (f : M → M → β) + (h : ∀ a₁ a₂ b₁ b₂, c a₁ b₁ → c a₂ b₂ → f a₁ a₂ = f b₁ b₂) : β := + Quotient.liftOn₂' q r f h + +/-- A version of `Quotient.hrecOn₂'` for quotients by `Con`. -/ +@[to_additive "A version of `Quotient.hrecOn₂'` for quotients by `AddCon`."] +protected def hrecOn₂ {cM : Con M} {cN : Con N} {φ : cM.Quotient → cN.Quotient → Sort*} + (a : cM.Quotient) (b : cN.Quotient) (f : ∀ (x : M) (y : N), φ x y) + (h : ∀ x y x' y', cM x x' → cN y y' → HEq (f x y) (f x' y')) : φ a b := + Quotient.hrecOn₂' a b f h + +@[to_additive (attr := simp)] +theorem hrec_on₂_coe {cM : Con M} {cN : Con N} {φ : cM.Quotient → cN.Quotient → Sort*} (a : M) + (b : N) (f : ∀ (x : M) (y : N), φ x y) + (h : ∀ x y x' y', cM x x' → cN y y' → HEq (f x y) (f x' y')) : + Con.hrecOn₂ (↑a) (↑b) f h = f a b := + rfl + +variable {c} + +/-- The inductive principle used to prove propositions about the elements of a quotient by a + congruence relation. -/ +@[to_additive (attr := elab_as_elim) "The inductive principle used to prove propositions about +the elements of a quotient by an additive congruence relation."] +protected theorem induction_on {C : c.Quotient → Prop} (q : c.Quotient) (H : ∀ x : M, C x) : C q := + Quotient.inductionOn' q H + +/-- A version of `Con.induction_on` for predicates which take two arguments. -/ +@[to_additive (attr := elab_as_elim) "A version of `AddCon.induction_on` for predicates which take +two arguments."] +protected theorem induction_on₂ {d : Con N} {C : c.Quotient → d.Quotient → Prop} (p : c.Quotient) + (q : d.Quotient) (H : ∀ (x : M) (y : N), C x y) : C p q := + Quotient.inductionOn₂' p q H + +variable (c) + +/-- Two elements are related by a congruence relation `c` iff they are represented by the same + element of the quotient by `c`. -/ +@[to_additive (attr := simp) "Two elements are related by an additive congruence relation `c` iff +they are represented by the same element of the quotient by `c`."] +protected theorem eq {a b : M} : (a : c.Quotient) = (b : c.Quotient) ↔ c a b := + Quotient.eq'' + +/-- The multiplication induced on the quotient by a congruence relation on a type with a + multiplication. -/ +@[to_additive "The addition induced on the quotient by an additive congruence relation on a type +with an addition."] +instance hasMul : Mul c.Quotient := + ⟨Quotient.map₂' (· * ·) fun _ _ h1 _ _ h2 => c.mul h1 h2⟩ + +/-- 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 mul_ker_mk_eq : (mulKer ((↑) : M → c.Quotient) fun _ _ => rfl) = c := + ext fun _ _ => Quotient.eq'' + +variable {c} + +/-- The coercion to the quotient of a congruence relation commutes with multiplication (by + definition). -/ +@[to_additive (attr := simp) "The coercion to the quotient of an additive congruence relation +commutes with addition (by definition)."] +theorem coe_mul (x y : M) : (↑(x * y) : c.Quotient) = ↑x * ↑y := + rfl + +/-- Definition of the function on the quotient by a congruence relation `c` induced by a function + that is constant on `c`'s equivalence classes. -/ +@[to_additive (attr := simp) "Definition of the function on the quotient by an additive congruence +relation `c` induced by a function that is constant on `c`'s equivalence classes."] +protected theorem liftOn_coe {β} (c : Con M) (f : M → β) (h : ∀ a b, c a b → f a = f b) (x : M) : + Con.liftOn (x : c.Quotient) f h = f x := + rfl + +-- The complete lattice of congruence relations on a type +/-- For congruence relations `c, d` on a type `M` with a multiplication, `c ≤ d` iff `∀ x y ∈ M`, + `x` is related to `y` by `d` if `x` is related to `y` by `c`. -/ +@[to_additive "For additive congruence relations `c, d` on a type `M` with an addition, `c ≤ d` iff +`∀ x y ∈ M`, `x` is related to `y` by `d` if `x` is related to `y` by `c`."] +instance : LE (Con M) where + le c d := ∀ ⦃x y⦄, c x y → d x y + +/-- Definition of `≤` for congruence relations. -/ +@[to_additive "Definition of `≤` for additive congruence relations."] +theorem le_def {c d : Con M} : c ≤ d ↔ ∀ {x y}, c x y → d x y := + Iff.rfl + +/-- The infimum of a set of congruence relations on a given type with a multiplication. -/ +@[to_additive "The infimum of a set of additive congruence relations on a given type with +an addition."] +instance : InfSet (Con M) where + sInf S := + { r := fun x y => ∀ c : Con M, c ∈ S → c x y + iseqv := ⟨fun x c _ => c.refl x, fun h c hc => c.symm <| h c hc, + fun h1 h2 c hc => c.trans (h1 c hc) <| h2 c hc⟩ + mul' := fun h1 h2 c hc => c.mul (h1 c hc) <| h2 c hc } + +/-- The infimum of a set of congruence relations is the same as the infimum of the set's image + under the map to the underlying equivalence relation. -/ +@[to_additive "The infimum of a set of additive congruence relations is the same as the infimum of +the set's image under the map to the underlying equivalence relation."] +theorem sInf_toSetoid (S : Set (Con M)) : (sInf S).toSetoid = sInf (toSetoid '' S) := + Setoid.ext' fun x y => + ⟨fun h r ⟨c, hS, hr⟩ => by rw [← hr]; exact h c hS, fun h c hS => h c.toSetoid ⟨c, hS, rfl⟩⟩ + +/-- The infimum of a set of congruence relations is the same as the infimum of the set's image + under the map to the underlying binary relation. -/ +@[to_additive (attr := simp, norm_cast) + "The infimum of a set of additive congruence relations is the same as the infimum + of the set's image under the map to the underlying binary relation."] +theorem coe_sInf (S : Set (Con M)) : + ⇑(sInf S) = sInf ((⇑) '' S) := by + ext + simp only [sInf_image, iInf_apply, iInf_Prop_eq] + rfl + +@[to_additive (attr := simp, norm_cast)] +theorem coe_iInf {ι : Sort*} (f : ι → Con M) : ⇑(iInf f) = ⨅ i, ⇑(f i) := by + rw [iInf, coe_sInf, ← Set.range_comp, sInf_range, Function.comp_def] + +@[to_additive] +instance : PartialOrder (Con M) where + le_refl _ _ _ := id + le_trans _ _ _ h1 h2 _ _ h := h2 <| h1 h + le_antisymm _ _ hc hd := ext fun _ _ => ⟨fun h => hc h, fun h => hd h⟩ + +/-- The complete lattice of congruence relations on a given type with a multiplication. -/ +@[to_additive "The complete lattice of additive congruence relations on a given type with +an addition."] +instance : CompleteLattice (Con M) where + __ := completeLatticeOfInf (Con M) fun s => + ⟨fun r hr x y h => (h : ∀ r ∈ s, (r : Con M) x y) r hr, fun r hr x y h r' hr' => + hr hr' + h⟩ + inf c d := ⟨c.toSetoid ⊓ d.toSetoid, fun h1 h2 => ⟨c.mul h1.1 h2.1, d.mul h1.2 h2.2⟩⟩ + inf_le_left _ _ := fun _ _ h => h.1 + inf_le_right _ _ := fun _ _ h => h.2 + le_inf _ _ _ hb hc := fun _ _ h => ⟨hb h, hc h⟩ + top := { Setoid.completeLattice.top with mul' := by tauto } + le_top _ := fun _ _ _ => trivial + bot := { Setoid.completeLattice.bot with mul' := fun h1 h2 => h1 ▸ h2 ▸ rfl } + bot_le c := fun x _ h => h ▸ c.refl x + +/-- The infimum of two congruence relations equals the infimum of the underlying binary + operations. -/ +@[to_additive (attr := simp, norm_cast) + "The infimum of two additive congruence relations equals the infimum of the underlying binary + operations."] +theorem coe_inf {c d : Con M} : ⇑(c ⊓ d) = ⇑c ⊓ ⇑d := + rfl + +/-- Definition of the infimum of two congruence relations. -/ +@[to_additive "Definition of the infimum of two additive congruence relations."] +theorem inf_iff_and {c d : Con M} {x y} : (c ⊓ d) x y ↔ c x y ∧ d x y := + Iff.rfl + +/-- The inductively defined smallest congruence relation containing a binary relation `r` equals + the infimum of the set of congruence relations containing `r`. -/ +@[to_additive addConGen_eq "The inductively defined smallest additive congruence relation +containing a binary relation `r` equals the infimum of the set of additive congruence relations +containing `r`."] +theorem conGen_eq (r : M → M → Prop) : conGen r = sInf { s : Con M | ∀ x y, r x y → s x y } := + le_antisymm + (le_sInf (fun s hs x y (hxy : (conGen r) x y) => + show s x y by + apply ConGen.Rel.recOn (motive := fun x y _ => s x y) hxy + · exact fun x y h => hs x y h + · exact s.refl' + · exact fun _ => s.symm' + · exact fun _ _ => s.trans' + · exact fun _ _ => s.mul)) + (sInf_le ConGen.Rel.of) + +/-- The smallest congruence relation containing a binary relation `r` is contained in any + congruence relation containing `r`. -/ +@[to_additive addConGen_le "The smallest additive congruence relation containing a binary +relation `r` is contained in any additive congruence relation containing `r`."] +theorem conGen_le {r : M → M → Prop} {c : Con M} (h : ∀ x y, r x y → c x y) : + conGen r ≤ c := by rw [conGen_eq]; exact sInf_le h + +/-- Given binary relations `r, s` with `r` contained in `s`, the smallest congruence relation + containing `s` contains the smallest congruence relation containing `r`. -/ +@[to_additive addConGen_mono "Given binary relations `r, s` with `r` contained in `s`, the +smallest additive congruence relation containing `s` contains the smallest additive congruence +relation containing `r`."] +theorem conGen_mono {r s : M → M → Prop} (h : ∀ x y, r x y → s x y) : conGen r ≤ conGen s := + conGen_le fun x y hr => ConGen.Rel.of _ _ <| h x y hr + +/-- Congruence relations equal the smallest congruence relation in which they are contained. -/ +@[to_additive (attr := simp) addConGen_of_addCon "Additive congruence relations equal the smallest +additive congruence relation in which they are contained."] +theorem conGen_of_con (c : Con M) : conGen c = c := + le_antisymm (by rw [conGen_eq]; exact sInf_le fun _ _ => id) ConGen.Rel.of + +-- Porting note: removing simp, simp can prove it +/-- The map sending a binary relation to the smallest congruence relation in which it is + contained is idempotent. -/ +@[to_additive addConGen_idem "The map sending a binary relation to the smallest additive +congruence relation in which it is contained is idempotent."] +theorem conGen_idem (r : M → M → Prop) : conGen (conGen r) = conGen r := + conGen_of_con _ + +/-- The supremum of congruence relations `c, d` equals the smallest congruence relation containing + the binary relation '`x` is related to `y` by `c` or `d`'. -/ +@[to_additive sup_eq_addConGen "The supremum of additive congruence relations `c, d` equals the +smallest additive congruence relation containing the binary relation '`x` is related to `y` +by `c` or `d`'."] +theorem sup_eq_conGen (c d : Con M) : c ⊔ d = conGen fun x y => c x y ∨ d x y := by + rw [conGen_eq] + apply congr_arg sInf + simp only [le_def, or_imp, ← forall_and] + +/-- The supremum of two congruence relations equals the smallest congruence relation containing + the supremum of the underlying binary operations. -/ +@[to_additive "The supremum of two additive congruence relations equals the smallest additive +congruence relation containing the supremum of the underlying binary operations."] +theorem sup_def {c d : Con M} : c ⊔ d = conGen (⇑c ⊔ ⇑d) := by rw [sup_eq_conGen]; rfl + +/-- The supremum of a set of congruence relations `S` equals the smallest congruence relation + containing the binary relation 'there exists `c ∈ S` such that `x` is related to `y` by + `c`'. -/ +@[to_additive sSup_eq_addConGen "The supremum of a set of additive congruence relations `S` equals +the smallest additive congruence relation containing the binary relation 'there exists `c ∈ S` +such that `x` is related to `y` by `c`'."] +theorem sSup_eq_conGen (S : Set (Con M)) : + sSup S = conGen fun x y => ∃ c : Con M, c ∈ S ∧ c x y := by + rw [conGen_eq] + apply congr_arg sInf + ext + exact ⟨fun h _ _ ⟨r, hr⟩ => h hr.1 hr.2, fun h r hS _ _ hr => h _ _ ⟨r, hS, hr⟩⟩ + +/-- The supremum of a set of congruence relations is the same as the smallest congruence relation + containing the supremum of the set's image under the map to the underlying binary relation. -/ +@[to_additive "The supremum of a set of additive congruence relations is the same as the smallest +additive congruence relation containing the supremum of the set's image under the map to the +underlying binary relation."] +theorem sSup_def {S : Set (Con M)} : + sSup S = conGen (sSup ((⇑) '' S)) := by + rw [sSup_eq_conGen, sSup_image] + congr with (x y) + simp only [sSup_image, iSup_apply, iSup_Prop_eq, exists_prop, rel_eq_coe] + +variable (M) + +/-- There is a Galois insertion of congruence relations on a type with a multiplication `M` into + binary relations on `M`. -/ +@[to_additive "There is a Galois insertion of additive congruence relations on a type with +an addition `M` into binary relations on `M`."] +protected def gi : @GaloisInsertion (M → M → Prop) (Con M) _ _ conGen DFunLike.coe where + choice r _ := conGen r + gc _ c := ⟨fun H _ _ h => H <| ConGen.Rel.of _ _ h, @fun H => conGen_of_con c ▸ conGen_mono H⟩ + le_l_u x := (conGen_of_con x).symm ▸ le_refl x + choice_eq _ _ := rfl + +variable {M} (c) + +/-- Given a function `f`, the smallest congruence relation containing the binary relation on `f`'s + image defined by '`x ≈ y` iff the elements of `f⁻¹(x)` are related to the elements of `f⁻¹(y)` + by a congruence relation `c`.' -/ +@[to_additive "Given a function `f`, the smallest additive congruence relation containing the +binary relation on `f`'s image defined by '`x ≈ y` iff the elements of `f⁻¹(x)` are related to the +elements of `f⁻¹(y)` by an additive congruence relation `c`.'"] +def mapGen (f : M → N) : Con N := + conGen fun x y => ∃ a b, f a = x ∧ f b = y ∧ c a b + +/-- Given a surjective multiplicative-preserving function `f` whose kernel is contained in a + congruence relation `c`, the congruence relation on `f`'s codomain defined by '`x ≈ y` iff the + elements of `f⁻¹(x)` are related to the elements of `f⁻¹(y)` by `c`.' -/ +@[to_additive "Given a surjective addition-preserving function `f` whose kernel is contained in +an additive congruence relation `c`, the additive congruence relation on `f`'s codomain defined +by '`x ≈ y` iff the elements of `f⁻¹(x)` are related to the elements of `f⁻¹(y)` by `c`.'"] +def mapOfSurjective (f : M → N) (H : ∀ x y, f (x * y) = f x * f y) (h : mulKer f H ≤ c) + (hf : Surjective f) : Con N := + { c.toSetoid.mapOfSurjective f h hf with + mul' := fun h₁ h₂ => by + rcases h₁ with ⟨a, b, rfl, rfl, h1⟩ + rcases h₂ with ⟨p, q, rfl, rfl, h2⟩ + exact ⟨a * p, b * q, by rw [H], by rw [H], c.mul h1 h2⟩ } + +/-- A specialization of 'the smallest congruence relation containing a congruence relation `c` + equals `c`'. -/ +@[to_additive "A specialization of 'the smallest additive congruence relation containing +an additive congruence relation `c` equals `c`'."] +theorem mapOfSurjective_eq_mapGen {c : Con M} {f : M → N} (H : ∀ x y, f (x * y) = f x * f y) + (h : mulKer f H ≤ c) (hf : Surjective f) : c.mapGen f = c.mapOfSurjective f H h hf := by + rw [← conGen_of_con (c.mapOfSurjective f H h hf)]; rfl + +/-- Given types with multiplications `M, N` and a congruence relation `c` on `N`, a + multiplication-preserving map `f : M → N` induces a congruence relation on `f`'s domain + defined by '`x ≈ y` iff `f(x)` is related to `f(y)` by `c`.' -/ +@[to_additive "Given types with additions `M, N` and an additive congruence relation `c` on `N`, +an addition-preserving map `f : M → N` induces an additive congruence relation on `f`'s domain +defined by '`x ≈ y` iff `f(x)` is related to `f(y)` by `c`.' "] +def comap (f : M → N) (H : ∀ x y, f (x * y) = f x * f y) (c : Con N) : Con M := + { c.toSetoid.comap f with + mul' := @fun w x y z h1 h2 => show c (f (w * y)) (f (x * z)) by rw [H, H]; exact c.mul h1 h2 } + +@[to_additive (attr := simp)] +theorem comap_rel {f : M → N} (H : ∀ x y, f (x * y) = f x * f y) {c : Con N} {x y : M} : + comap f H c x y ↔ c (f x) (f y) := + Iff.rfl + +section + +open Quotient + +/-- Given a congruence relation `c` on a type `M` with a multiplication, the order-preserving + bijection between the set of congruence relations containing `c` and the congruence relations + on the quotient of `M` by `c`. -/ +@[to_additive "Given an additive congruence relation `c` on a type `M` with an addition, +the order-preserving bijection between the set of additive congruence relations containing `c` and +the additive congruence relations on the quotient of `M` by `c`."] +def correspondence : { d // c ≤ d } ≃o Con c.Quotient where + toFun d := + d.1.mapOfSurjective (↑) (fun _ _ => rfl) (by rw [mul_ker_mk_eq]; exact d.2) <| + @Quotient.exists_rep _ c.toSetoid + invFun d := + ⟨comap ((↑) : M → c.Quotient) (fun _ _ => rfl) d, fun x y h => + show d x y by rw [c.eq.2 h]; exact d.refl _⟩ + left_inv d := + -- Porting note: by exact needed for unknown reason + by exact + Subtype.ext_iff_val.2 <| + ext fun x y => + ⟨fun h => + let ⟨a, b, hx, hy, H⟩ := h + d.1.trans (d.1.symm <| d.2 <| c.eq.1 hx) <| d.1.trans H <| d.2 <| c.eq.1 hy, + fun h => ⟨_, _, rfl, rfl, h⟩⟩ + right_inv d := + -- Porting note: by exact needed for unknown reason + by exact + ext fun x y => + ⟨fun h => + let ⟨_, _, hx, hy, H⟩ := h + hx ▸ hy ▸ H, + Con.induction_on₂ x y fun w z h => ⟨w, z, rfl, rfl, h⟩⟩ + map_rel_iff' := @fun s t => by + constructor + · intros h x y hs + rcases h ⟨x, y, rfl, rfl, hs⟩ with ⟨a, b, hx, hy, ht⟩ + exact t.1.trans (t.1.symm <| t.2 <| Quotient.eq_rel.1 hx) + (t.1.trans ht (t.2 <| Quotient.eq_rel.1 hy)) + · intros h _ _ hs + rcases hs with ⟨a, b, hx, hy, Hs⟩ + exact ⟨a, b, hx, hy, h Hs⟩ + +end + +end + +section MulOneClass + +variable [MulOneClass M] [MulOneClass N] [MulOneClass P] (c : Con M) + +/-- The quotient of a monoid by a congruence relation is a monoid. -/ +@[to_additive "The quotient of an `AddMonoid` by an additive congruence relation is +an `AddMonoid`."] +instance mulOneClass : MulOneClass c.Quotient where + one := ((1 : M) : c.Quotient) + mul_one x := Quotient.inductionOn' x fun _ => congr_arg ((↑) : M → c.Quotient) <| mul_one _ + one_mul x := Quotient.inductionOn' x fun _ => congr_arg ((↑) : M → c.Quotient) <| one_mul _ + +variable {c} + +/-- The 1 of the quotient of a monoid by a congruence relation is the equivalence class of the + monoid's 1. -/ +@[to_additive (attr := simp) "The 0 of the quotient of an `AddMonoid` by an additive congruence +relation is the equivalence class of the `AddMonoid`'s 0."] +theorem coe_one : ((1 : M) : c.Quotient) = 1 := + rfl + +/-- There exists an element of the quotient of a monoid by a congruence relation (namely 1). -/ +@[to_additive "There exists an element of the quotient of an `AddMonoid` by a congruence relation +(namely 0)."] +instance Quotient.inhabited : Inhabited c.Quotient := + ⟨((1 : M) : c.Quotient)⟩ + +end MulOneClass + +section Monoids + +/-- Multiplicative congruence relations preserve natural powers. -/ +@[to_additive "Additive congruence relations preserve natural scaling."] +protected theorem pow {M : Type*} [Monoid M] (c : Con M) : + ∀ (n : ℕ) {w x}, c w x → c (w ^ n) (x ^ n) + | 0, w, x, _ => by simpa using c.refl _ + | Nat.succ n, w, x, h => by simpa [pow_succ] using c.mul (Con.pow c n h) h + +@[to_additive] +instance one [MulOneClass M] (c : Con M) : One c.Quotient where + -- Using Quotient.mk'' here instead of c.toQuotient + -- since c.toQuotient is not reducible. + -- This would lead to non-defeq diamonds since this instance ends up in + -- quotients modulo ideals. + one := Quotient.mk'' (1 : M) + -- one := ((1 : M) : c.Quotient) + +instance _root_.AddCon.Quotient.nsmul {M : Type*} [AddMonoid M] (c : AddCon M) : + SMul ℕ c.Quotient where + smul n := (Quotient.map' (n • ·)) fun _ _ => c.nsmul n + +@[to_additive existing AddCon.Quotient.nsmul] +instance {M : Type*} [Monoid M] (c : Con M) : Pow c.Quotient ℕ where + pow x n := Quotient.map' (fun x => x ^ n) (fun _ _ => c.pow n) x + +/-- The quotient of a semigroup by a congruence relation is a semigroup. -/ +@[to_additive "The quotient of an `AddSemigroup` by an additive congruence relation is +an `AddSemigroup`."] +instance semigroup {M : Type*} [Semigroup M] (c : Con M) : Semigroup c.Quotient := + { (Function.Surjective.semigroup _ + Quotient.surjective_Quotient_mk'' fun _ _ => rfl : + Semigroup c.Quotient) with + /- The `toMul` field is given explicitly for performance reasons. + This avoids any need to unfold `Function.Surjective.semigroup` when the type checker is checking + that instance diagrams commute -/ + toMul := Con.hasMul _ } + +/-- The quotient of a commutative semigroup by a congruence relation is a semigroup. -/ +@[to_additive "The quotient of an `AddCommSemigroup` by an additive congruence relation is +an `AddCommSemigroup`."] +instance commSemigroup {M : Type*} [CommSemigroup M] (c : Con M) : CommSemigroup c.Quotient := + { (Function.Surjective.commSemigroup _ Quotient.surjective_Quotient_mk'' fun _ _ => rfl : + CommSemigroup c.Quotient) with + /- The `toSemigroup` field is given explicitly for performance reasons. + This avoids any need to unfold `Function.Surjective.commSemigroup` when the type checker is + checking that instance diagrams commute -/ + toSemigroup := Con.semigroup _ } + +/-- The quotient of a monoid by a congruence relation is a monoid. -/ +@[to_additive "The quotient of an `AddMonoid` by an additive congruence relation is +an `AddMonoid`."] +instance monoid {M : Type*} [Monoid M] (c : Con M) : Monoid c.Quotient := + { (Function.Surjective.monoid _ Quotient.surjective_Quotient_mk'' rfl + (fun _ _ => rfl) fun _ _ => rfl : Monoid c.Quotient) with + /- The `toSemigroup` and `toOne` fields are given explicitly for performance reasons. + This avoids any need to unfold `Function.Surjective.monoid` when the type checker is + checking that instance diagrams commute -/ + toSemigroup := Con.semigroup _ + toOne := Con.one _ } + +/-- The quotient of a `CommMonoid` by a congruence relation is a `CommMonoid`. -/ +@[to_additive "The quotient of an `AddCommMonoid` by an additive congruence +relation is an `AddCommMonoid`."] +instance commMonoid {M : Type*} [CommMonoid M] (c : Con M) : CommMonoid c.Quotient := + { (Function.Surjective.commMonoid _ Quotient.surjective_Quotient_mk'' rfl + (fun _ _ => rfl) fun _ _ => rfl : CommMonoid c.Quotient) with + /- The `toMonoid` field is given explicitly for performance reasons. + This avoids any need to unfold `Function.Surjective.commMonoid` when the type checker is + checking that instance diagrams commute -/ + toMonoid := Con.monoid _ } + +/-- Sometimes, a group is defined as a quotient of a monoid by a congruence relation. +Usually, the inverse operation is defined as `Setoid.map f _` for some `f`. +This lemma allows to avoid code duplication in the definition of the inverse operation: +instead of proving both `∀ x y, c x y → c (f x) (f y)` (to define the operation) +and `∀ x, c (f x * x) 1` (to prove the group laws), one can only prove the latter. -/ +@[to_additive "Sometimes, an additive group is defined as a quotient of a monoid + by an additive congruence relation. + Usually, the inverse operation is defined as `Setoid.map f _` for some `f`. + This lemma allows to avoid code duplication in the definition of the inverse operation: + instead of proving both `∀ x y, c x y → c (f x) (f y)` (to define the operation) + and `∀ x, c (f x + x) 0` (to prove the group laws), one can only prove the latter."] +theorem map_of_mul_left_rel_one [Monoid M] (c : Con M) + (f : M → M) (hf : ∀ x, c (f x * x) 1) {x y} (h : c x y) : c (f x) (f y) := by + simp only [← Con.eq, coe_one, coe_mul] at * + have hf' : ∀ x : M, (x : c.Quotient) * f x = 1 := fun x ↦ + calc + (x : c.Quotient) * f x = f (f x) * f x * (x * f x) := by simp [hf] + _ = f (f x) * (f x * x) * f x := by ac_rfl + _ = 1 := by simp [hf] + have : (⟨_, _, hf' x, hf x⟩ : c.Quotientˣ) = ⟨_, _, hf' y, hf y⟩ := Units.ext h + exact congr_arg Units.inv this + +end Monoids + +section Groups + +variable [Group M] [Group N] [Group P] (c : Con M) + +/-- Multiplicative congruence relations preserve inversion. -/ +@[to_additive "Additive congruence relations preserve negation."] +protected theorem inv {x y} (h : c x y) : c x⁻¹ y⁻¹ := + c.map_of_mul_left_rel_one Inv.inv (fun x => by simp only [inv_mul_cancel, c.refl 1]) h + +/-- Multiplicative congruence relations preserve division. -/ +@[to_additive "Additive congruence relations preserve subtraction."] +protected theorem div : ∀ {w x y z}, c w x → c y z → c (w / y) (x / z) := @fun w x y z h1 h2 => by + simpa only [div_eq_mul_inv] using c.mul h1 (c.inv h2) + +/-- Multiplicative congruence relations preserve integer powers. -/ +@[to_additive "Additive congruence relations preserve integer scaling."] +protected theorem zpow : ∀ (n : ℤ) {w x}, c w x → c (w ^ n) (x ^ n) + | Int.ofNat n, w, x, h => by simpa only [zpow_natCast, Int.ofNat_eq_coe] using c.pow n h + | Int.negSucc n, w, x, h => by simpa only [zpow_negSucc] using c.inv (c.pow _ h) + +/-- The inversion induced on the quotient by a congruence relation on a type with an + inversion. -/ +@[to_additive "The negation induced on the quotient by an additive congruence relation on a type +with a negation."] +instance hasInv : Inv c.Quotient := + ⟨(Quotient.map' Inv.inv) fun _ _ => c.inv⟩ + +/-- The division induced on the quotient by a congruence relation on a type with a + division. -/ +@[to_additive "The subtraction induced on the quotient by an additive congruence relation on a type +with a subtraction."] +instance hasDiv : Div c.Quotient := + ⟨(Quotient.map₂' (· / ·)) fun _ _ h₁ _ _ h₂ => c.div h₁ h₂⟩ + +/-- The integer scaling induced on the quotient by a congruence relation on a type with a + subtraction. -/ +instance _root_.AddCon.Quotient.zsmul {M : Type*} [AddGroup M] (c : AddCon M) : + SMul ℤ c.Quotient := + ⟨fun z => (Quotient.map' (z • ·)) fun _ _ => c.zsmul z⟩ + +/-- The integer power induced on the quotient by a congruence relation on a type with a + division. -/ +@[to_additive existing AddCon.Quotient.zsmul] +instance zpowinst : Pow c.Quotient ℤ := + ⟨fun x z => Quotient.map' (fun x => x ^ z) (fun _ _ h => c.zpow z h) x⟩ + +/-- The quotient of a group by a congruence relation is a group. -/ +@[to_additive "The quotient of an `AddGroup` by an additive congruence relation is +an `AddGroup`."] +instance group : Group c.Quotient := + { (Function.Surjective.group Quotient.mk'' + Quotient.surjective_Quotient_mk'' rfl (fun _ _ => rfl) (fun _ => rfl) + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl : Group c.Quotient) with + toMonoid := Con.monoid _ + toInv := Con.hasInv _ + toDiv := Con.hasDiv _ } + +end Groups + +section Units + +variable {α : Type*} [Monoid M] {c : Con M} + +/-- In order to define a function `(Con.Quotient c)ˣ → α` on the units of `Con.Quotient c`, +where `c : Con M` is a multiplicative congruence on a monoid, it suffices to define a function `f` +that takes elements `x y : M` with proofs of `c (x * y) 1` and `c (y * x) 1`, and returns an element +of `α` provided that `f x y _ _ = f x' y' _ _` whenever `c x x'` and `c y y'`. -/ +@[to_additive] +def liftOnUnits (u : Units c.Quotient) (f : ∀ x y : M, c (x * y) 1 → c (y * x) 1 → α) + (Hf : ∀ x y hxy hyx x' y' hxy' hyx', + c x x' → c y y' → f x y hxy hyx = f x' y' hxy' hyx') : α := by + refine + Con.hrecOn₂ (cN := c) (φ := fun x y => x * y = 1 → y * x = 1 → α) (u : c.Quotient) + (↑u⁻¹ : c.Quotient) + (fun (x y : M) (hxy : (x * y : c.Quotient) = 1) (hyx : (y * x : c.Quotient) = 1) => + f x y (c.eq.1 hxy) (c.eq.1 hyx)) + (fun x y x' y' hx hy => ?_) u.3 u.4 + refine Function.hfunext ?_ ?_ + · rw [c.eq.2 hx, c.eq.2 hy] + · rintro Hxy Hxy' - + refine Function.hfunext ?_ ?_ + · rw [c.eq.2 hx, c.eq.2 hy] + · rintro Hyx Hyx' - + exact heq_of_eq (Hf _ _ _ _ _ _ _ _ hx hy) + +/-- In order to define a function `(Con.Quotient c)ˣ → α` on the units of `Con.Quotient c`, +where `c : Con M` is a multiplicative congruence on a monoid, it suffices to define a function `f` +that takes elements `x y : M` with proofs of `c (x * y) 1` and `c (y * x) 1`, and returns an element +of `α` provided that `f x y _ _ = f x' y' _ _` whenever `c x x'` and `c y y'`. -/ +add_decl_doc AddCon.liftOnAddUnits + +@[to_additive (attr := simp)] +theorem liftOnUnits_mk (f : ∀ x y : M, c (x * y) 1 → c (y * x) 1 → α) + (Hf : ∀ x y hxy hyx x' y' hxy' hyx', c x x' → c y y' → f x y hxy hyx = f x' y' hxy' hyx') + (x y : M) (hxy hyx) : + liftOnUnits ⟨(x : c.Quotient), y, hxy, hyx⟩ f Hf = f x y (c.eq.1 hxy) (c.eq.1 hyx) := + rfl + +@[to_additive (attr := elab_as_elim)] +theorem induction_on_units {p : Units c.Quotient → Prop} (u : Units c.Quotient) + (H : ∀ (x y : M) (hxy : c (x * y) 1) (hyx : c (y * x) 1), p ⟨x, y, c.eq.2 hxy, c.eq.2 hyx⟩) : + p u := by + rcases u with ⟨⟨x⟩, ⟨y⟩, h₁, h₂⟩ + exact H x y (c.eq.1 h₁) (c.eq.1 h₂) + +end Units + +end Con diff --git a/Mathlib/GroupTheory/Congruence/Hom.lean b/Mathlib/GroupTheory/Congruence/Hom.lean new file mode 100644 index 00000000000000..9adfa62245816b --- /dev/null +++ b/Mathlib/GroupTheory/Congruence/Hom.lean @@ -0,0 +1,217 @@ +/- +Copyright (c) 2019 Amelia Livingston. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Amelia Livingston +-/ +import Mathlib.Algebra.Group.Hom.Defs +import Mathlib.GroupTheory.Congruence.Defs + +/-! +# Congruence relations and homomorphisms + +This file contains elementary definitions involving congruence relations and morphisms. + +## Main definitions + + * `Con.ker`: the kernel of a monoid homomorphism as a congruence relation + * `Con.mk'`: the map from a monoid to its quotient by a congruence relation + * `Con.lift`: the homomorphism on the quotient given that the congruence is in the kernel + * `Con.map`: homomorphism from a smaller to a larger quotient + +## Tags + +congruence, congruence relation, quotient, quotient by congruence relation, monoid, +quotient monoid +-/ + + +variable (M : Type*) {N : Type*} {P : Type*} + +open Function Setoid + +variable {M} + +namespace Con + +section MulOneClass + +variable [MulOneClass M] [MulOneClass N] [MulOneClass P] {c : Con M} + +/-- The kernel of a monoid homomorphism as a congruence relation. -/ +@[to_additive "The kernel of an `AddMonoid` homomorphism as an additive congruence relation."] +def ker (f : M →* P) : Con M := + mulKer f (map_mul f) + +/-- The definition of the congruence relation defined by a monoid homomorphism's kernel. -/ +@[to_additive (attr := simp) "The definition of the additive congruence relation defined by an +`AddMonoid` homomorphism's kernel."] +theorem ker_rel (f : M →* P) {x y} : ker f x y ↔ f x = f y := + Iff.rfl + +variable (c) + +/-- The natural homomorphism from a monoid to its quotient by a congruence relation. -/ +@[to_additive "The natural homomorphism from an `AddMonoid` to its quotient by an additive +congruence relation."] +def mk' : M →* c.Quotient := + { toFun := (↑) + map_one' := rfl + map_mul' := fun _ _ => rfl } + +variable (x y : M) + +/-- The kernel of the natural homomorphism from a monoid to its quotient by a congruence + relation `c` equals `c`. -/ +@[to_additive (attr := simp) "The kernel of the natural homomorphism from an `AddMonoid` to its +quotient by an additive congruence relation `c` equals `c`."] +theorem mk'_ker : ker c.mk' = c := + ext fun _ _ => c.eq + +variable {c} + +/-- The natural homomorphism from a monoid to its quotient by a congruence relation is + surjective. -/ +@[to_additive "The natural homomorphism from an `AddMonoid` to its quotient by a congruence +relation is surjective."] +theorem mk'_surjective : Surjective c.mk' := + Quotient.surjective_Quotient_mk'' + +@[to_additive (attr := simp)] +theorem coe_mk' : (c.mk' : M → c.Quotient) = ((↑) : M → c.Quotient) := + rfl + +-- Porting note: used to abuse defeq between sets and predicates +@[to_additive] +theorem ker_apply {f : M →* P} {x y} : ker f x y ↔ f x = f y := Iff.rfl + +/-- Given a monoid homomorphism `f : N → M` and a congruence relation `c` on `M`, the congruence + relation induced on `N` by `f` equals the kernel of `c`'s quotient homomorphism composed with + `f`. -/ +@[to_additive "Given an `AddMonoid` homomorphism `f : N → M` and an additive congruence relation +`c` on `M`, the additive congruence relation induced on `N` by `f` equals the kernel of `c`'s +quotient homomorphism composed with `f`."] +theorem comap_eq {f : N →* M} : comap f f.map_mul c = ker (c.mk'.comp f) := + ext fun x y => show c _ _ ↔ c.mk' _ = c.mk' _ by rw [← c.eq]; rfl + +variable (c) (f : M →* P) + +/-- 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 +relation `c` induced by a homomorphism constant on `c`'s equivalence classes."] +def lift (H : c ≤ ker f) : c.Quotient →* P where + toFun x := (Con.liftOn x f) fun _ _ h => H h + map_one' := by rw [← f.map_one]; rfl + map_mul' x y := Con.induction_on₂ x y fun m n => by + dsimp only [← coe_mul, Con.liftOn_coe] + rw [map_mul] + +variable {c f} + +/-- The diagram describing the universal property for quotients of monoids commutes. -/ +@[to_additive "The diagram describing the universal property for quotients of `AddMonoid`s +commutes."] +theorem lift_mk' (H : c ≤ ker f) (x) : c.lift f H (c.mk' x) = f x := + rfl + +/-- The diagram describing the universal property for quotients of monoids commutes. -/ +@[to_additive (attr := simp) "The diagram describing the universal property for quotients of +`AddMonoid`s commutes."] +theorem lift_coe (H : c ≤ ker f) (x : M) : c.lift f H x = f x := + rfl + +/-- The diagram describing the universal property for quotients of monoids commutes. -/ +@[to_additive (attr := simp) "The diagram describing the universal property for quotients of +`AddMonoid`s commutes."] +theorem lift_comp_mk' (H : c ≤ ker f) : (c.lift f H).comp c.mk' = f := by ext; rfl + +/-- Given a homomorphism `f` from the quotient of a monoid by a congruence relation, `f` equals the + homomorphism on the quotient induced by `f` composed with the natural map from the monoid to + the quotient. -/ +@[to_additive (attr := simp) "Given a homomorphism `f` from the quotient of an `AddMonoid` by an +additive congruence relation, `f` equals the homomorphism on the quotient induced by `f` composed +with the natural map from the `AddMonoid` to the quotient."] +theorem lift_apply_mk' (f : c.Quotient →* P) : + (c.lift (f.comp c.mk') fun x y h => show f ↑x = f ↑y by rw [c.eq.2 h]) = f := by + ext x; rcases x with ⟨⟩; rfl + +/-- Homomorphisms on the quotient of a monoid by a congruence relation are equal if they + are equal on elements that are coercions from the monoid. -/ +@[to_additive "Homomorphisms on the quotient of an `AddMonoid` by an additive congruence relation +are equal if they are equal on elements that are coercions from the `AddMonoid`."] +theorem lift_funext (f g : c.Quotient →* P) (h : ∀ a : M, f a = g a) : f = g := by + rw [← lift_apply_mk' f, ← lift_apply_mk' g] + congr 1 + exact DFunLike.ext_iff.2 h + +/-- The uniqueness part of the universal property for quotients of monoids. -/ +@[to_additive "The uniqueness part of the universal property for quotients of `AddMonoid`s."] +theorem lift_unique (H : c ≤ ker f) (g : c.Quotient →* P) (Hg : g.comp c.mk' = f) : + g = c.lift f H := + (lift_funext g (c.lift f H)) fun x => by + subst f + rfl + +/-- Surjective monoid homomorphisms constant on a congruence relation `c`'s equivalence classes + induce a surjective homomorphism on `c`'s quotient. -/ +@[to_additive "Surjective `AddMonoid` homomorphisms constant on an additive congruence +relation `c`'s equivalence classes induce a surjective homomorphism on `c`'s quotient."] +theorem lift_surjective_of_surjective (h : c ≤ ker f) (hf : Surjective f) : + Surjective (c.lift f h) := fun y => + (Exists.elim (hf y)) fun w hw => ⟨w, (lift_mk' h w).symm ▸ hw⟩ + +variable (c f) + +/-- Given a monoid homomorphism `f` from `M` to `P`, the kernel of `f` is the unique congruence + relation on `M` whose induced map from the quotient of `M` to `P` is injective. -/ +@[to_additive "Given an `AddMonoid` homomorphism `f` from `M` to `P`, the kernel of `f` +is the unique additive congruence relation on `M` whose induced map from the quotient of `M` +to `P` is injective."] +theorem ker_eq_lift_of_injective (H : c ≤ ker f) (h : Injective (c.lift f H)) : ker f = c := + toSetoid_inj <| Setoid.ker_eq_lift_of_injective f H h + +variable {c} + +/-- The homomorphism induced on the quotient of a monoid by the kernel of a monoid homomorphism. -/ +@[to_additive "The homomorphism induced on the quotient of an `AddMonoid` by the kernel +of an `AddMonoid` homomorphism."] +def kerLift : (ker f).Quotient →* P := + ((ker f).lift f) fun _ _ => id + +variable {f} + +/-- The diagram described by the universal property for quotients of monoids, when the congruence + relation is the kernel of the homomorphism, commutes. -/ +@[to_additive (attr := simp) "The diagram described by the universal property for quotients +of `AddMonoid`s, when the additive congruence relation is the kernel of the homomorphism, +commutes."] +theorem kerLift_mk (x : M) : kerLift f x = f x := + rfl + +/-- A monoid homomorphism `f` induces an injective homomorphism on the quotient by `f`'s kernel. -/ +@[to_additive "An `AddMonoid` homomorphism `f` induces an injective homomorphism on the quotient +by `f`'s kernel."] +theorem kerLift_injective (f : M →* P) : Injective (kerLift f) := fun x y => + Quotient.inductionOn₂' x y fun _ _ => (ker f).eq.2 + +/-- Given congruence relations `c, d` on a monoid such that `d` contains `c`, `d`'s quotient + map induces a homomorphism from the quotient by `c` to the quotient by `d`. -/ +@[to_additive "Given additive congruence relations `c, d` on an `AddMonoid` such that `d` +contains `c`, `d`'s quotient map induces a homomorphism from the quotient by `c` to the quotient +by `d`."] +def map (c d : Con M) (h : c ≤ d) : c.Quotient →* d.Quotient := + (c.lift d.mk') fun x y hc => show (ker d.mk') x y from (mk'_ker d).symm ▸ h hc + +/-- Given congruence relations `c, d` on a monoid such that `d` contains `c`, the definition of + the homomorphism from the quotient by `c` to the quotient by `d` induced by `d`'s quotient + map. -/ +@[to_additive "Given additive congruence relations `c, d` on an `AddMonoid` such that `d` +contains `c`, the definition of the homomorphism from the quotient by `c` to the quotient by `d` +induced by `d`'s quotient map."] +theorem map_apply {c d : Con M} (h : c ≤ d) (x) : + c.map d h x = c.lift d.mk' (fun _ _ hc => d.eq.2 <| h hc) x := + rfl + +end MulOneClass + +end Con diff --git a/Mathlib/GroupTheory/Congruence/Opposite.lean b/Mathlib/GroupTheory/Congruence/Opposite.lean index c0701bb273a2f2..6d07398f60e72e 100644 --- a/Mathlib/GroupTheory/Congruence/Opposite.lean +++ b/Mathlib/GroupTheory/Congruence/Opposite.lean @@ -4,8 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Amelia Livingston -/ -import Mathlib.GroupTheory.Congruence.Basic import Mathlib.Algebra.Opposites +import Mathlib.GroupTheory.Congruence.Defs /-! # Congruences on the opposite of a group diff --git a/Mathlib/GroupTheory/MonoidLocalization/Basic.lean b/Mathlib/GroupTheory/MonoidLocalization/Basic.lean index aae0ac762fc973..76275087dc282a 100644 --- a/Mathlib/GroupTheory/MonoidLocalization/Basic.lean +++ b/Mathlib/GroupTheory/MonoidLocalization/Basic.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Amelia Livingston -/ import Mathlib.Algebra.Group.Submonoid.Membership -import Mathlib.GroupTheory.Congruence.Basic +import Mathlib.GroupTheory.Congruence.Hom import Mathlib.RingTheory.OreLocalization.Basic /-! diff --git a/Mathlib/GroupTheory/QuotientGroup/Basic.lean b/Mathlib/GroupTheory/QuotientGroup/Basic.lean index c29572983166b8..5afa39a81c9a42 100644 --- a/Mathlib/GroupTheory/QuotientGroup/Basic.lean +++ b/Mathlib/GroupTheory/QuotientGroup/Basic.lean @@ -6,7 +6,7 @@ Authors: Kevin Buzzard, Patrick Massot -- This file is to a certain extent based on `quotient_module.lean` by Johannes Hölzl. import Mathlib.Algebra.Group.Subgroup.Pointwise -import Mathlib.GroupTheory.Congruence.Basic +import Mathlib.GroupTheory.Congruence.Hom import Mathlib.GroupTheory.Coset.Basic /-! diff --git a/Mathlib/LinearAlgebra/PiTensorProduct.lean b/Mathlib/LinearAlgebra/PiTensorProduct.lean index 051109b80bec88..549483263a2a17 100644 --- a/Mathlib/LinearAlgebra/PiTensorProduct.lean +++ b/Mathlib/LinearAlgebra/PiTensorProduct.lean @@ -3,7 +3,6 @@ Copyright (c) 2020 Frédéric Dupuis. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Frédéric Dupuis, Eric Wieser -/ -import Mathlib.GroupTheory.Congruence.Basic import Mathlib.LinearAlgebra.Multilinear.TensorProduct import Mathlib.Tactic.AdaptationNote diff --git a/Mathlib/LinearAlgebra/TensorProduct/Basic.lean b/Mathlib/LinearAlgebra/TensorProduct/Basic.lean index 98e1a776a87177..8225c569e1d958 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Basic.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Basic.lean @@ -5,7 +5,7 @@ Authors: Kenny Lau, Mario Carneiro -/ import Mathlib.Algebra.Module.Submodule.Bilinear import Mathlib.Algebra.Module.Equiv.Basic -import Mathlib.GroupTheory.Congruence.Basic +import Mathlib.GroupTheory.Congruence.Hom import Mathlib.Tactic.Abel import Mathlib.Tactic.SuppressCompilation From c3bca905925b1e28a13fb918e4927bcf6f1e7750 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Tue, 15 Oct 2024 04:35:51 +0000 Subject: [PATCH 123/425] doc(SetTheory/Ordinal/Notation): rewrap and improve docs (#16283) We mostly just rewrap comment blocks and add some missing periods. --- Mathlib/SetTheory/Ordinal/Notation.lean | 136 +++++++++++------------- 1 file changed, 65 insertions(+), 71 deletions(-) diff --git a/Mathlib/SetTheory/Ordinal/Notation.lean b/Mathlib/SetTheory/Ordinal/Notation.lean index c9d5e0211b86c3..39a46f5780ac94 100644 --- a/Mathlib/SetTheory/Ordinal/Notation.lean +++ b/Mathlib/SetTheory/Ordinal/Notation.lean @@ -3,11 +3,10 @@ Copyright (c) 2018 Mario Carneiro. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Mario Carneiro -/ -import Mathlib.Algebra.Ring.Divisibility.Basic import Mathlib.Data.Ordering.Lemmas +import Mathlib.Data.PNat.Basic import Mathlib.SetTheory.Ordinal.Principal import Mathlib.Tactic.NormNum -import Mathlib.Data.PNat.Basic /-! # Ordinal notation @@ -20,7 +19,7 @@ We say that `o` is in Cantor normal form - `ONote.NF o` - if either `o = 0` or `o = ω ^ e * n + a` with `a < ω ^ e` and `a` in Cantor normal form. The type `NONote` is the type of ordinals below `ε₀` in Cantor normal form. -Various operations (addition, subtraction, multiplication, power function) +Various operations (addition, subtraction, multiplication, exponentiation) are defined on `ONote` and `NONote`. -/ @@ -30,11 +29,10 @@ open Ordinal Order -- Porting note: the generated theorem is warned by `simpNF`. set_option genSizeOfSpec false in -/-- Recursive definition of an ordinal notation. `zero` denotes the - ordinal 0, and `oadd e n a` is intended to refer to `ω^e * n + a`. - For this to be valid Cantor normal form, we must have the exponents - decrease to the right, but we can't state this condition until we've - defined `repr`, so it is a separate definition `NF`. -/ +/-- Recursive definition of an ordinal notation. `zero` denotes the ordinal 0, and `oadd e n a` is +intended to refer to `ω ^ e * n + a`. For this to be a valid Cantor normal form, we must have the +exponents decrease to the right, but we can't state this condition until we've defined `repr`, so we +make it a separate definition `NF`. -/ inductive ONote : Type | zero : ONote | oadd : ONote → ℕ+ → ONote → ONote @@ -69,16 +67,16 @@ noncomputable def repr : ONote → Ordinal.{0} | 0 => 0 | oadd e n a => ω ^ repr e * n + repr a -/-- Auxiliary definition to print an ordinal notation -/ -def toStringAux1 (e : ONote) (n : ℕ) (s : String) : String := +/-- Print `ω^s*n`, omitting `s` if `e = 0` or `e = 1`, and omitting `n` if `n = 1` -/ +private def toString_aux (e : ONote) (n : ℕ) (s : String) : String := if e = 0 then toString n else (if e = 1 then "ω" else "ω^(" ++ s ++ ")") ++ if n = 1 then "" else "*" ++ toString n /-- Print an ordinal notation -/ def toString : ONote → String | zero => "0" - | oadd e n 0 => toStringAux1 e n (toString e) - | oadd e n a => toStringAux1 e n (toString e) ++ " + " ++ toString a + | oadd e n 0 => toString_aux e n (toString e) + | oadd e n a => toString_aux e n (toString e) ++ " + " ++ toString a open Lean in /-- Print an ordinal notation -/ @@ -149,7 +147,10 @@ alias omega_le_oadd := omega0_le_oadd theorem oadd_pos (e n a) : 0 < oadd e n a := @lt_of_lt_of_le _ _ _ (ω ^ repr e) _ (opow_pos (repr e) omega0_pos) (omega0_le_oadd e n a) -/-- Compare ordinal notations -/ +/-- Comparison of ordinal notations: + +`ω ^ e₁ * n₁ + a₁` is less than `ω ^ e₂ * n₂ + a₂` when either `e₁ < e₂`, or `e₁ = e₂` and +`n₁ < n₂`, or `e₁ = e₂`, `n₁ = n₂`, and `a₁ < a₂`. -/ def cmp : ONote → ONote → Ordering | 0, 0 => Ordering.eq | _, 0 => Ordering.gt @@ -175,22 +176,20 @@ protected theorem zero_lt_one : (0 : ONote) < 1 := by simp only [lt_def, repr, opow_zero, Nat.succPNat_coe, Nat.cast_one, mul_one, add_zero, zero_lt_one] -/-- `NFBelow o b` says that `o` is a normal form ordinal notation - satisfying `repr o < ω ^ b`. -/ +/-- `NFBelow o b` says that `o` is a normal form ordinal notation satisfying `repr o < ω ^ b`. -/ inductive NFBelow : ONote → Ordinal.{0} → Prop | zero {b} : NFBelow 0 b | oadd' {e n a eb b} : NFBelow e eb → NFBelow a (repr e) → repr e < b → NFBelow (oadd e n a) b /-- A normal form ordinal notation has the form - ω ^ a₁ * n₁ + ω ^ a₂ * n₂ + ... ω ^ aₖ * nₖ - where `a₁ > a₂ > ... > aₖ` and all the `aᵢ` are - also in normal form. +`ω ^ a₁ * n₁ + ω ^ a₂ * n₂ + ⋯ + ω ^ aₖ * nₖ` - We will essentially only be interested in normal form - ordinal notations, but to avoid complicating the algorithms - we define everything over general ordinal notations and - only prove correctness with normal form as an invariant. -/ +where `a₁ > a₂ > ⋯ > aₖ` and all the `aᵢ` are also in normal form. + +We will essentially only be interested in normal form ordinal notations, but to avoid complicating +the algorithms, we define everything over general ordinal notations and only prove correctness with +normal form as an invariant. -/ class NF (o : ONote) : Prop where out : Exists (NFBelow o) @@ -346,9 +345,8 @@ theorem NF.of_dvd_omega0 {e n a} (h : NF (ONote.oadd e n a)) : @[deprecated (since := "2024-09-30")] alias NF.of_dvd_omega := NF.of_dvd_omega0 -/-- `TopBelow b o` asserts that the largest exponent in `o`, if - it exists, is less than `b`. This is an auxiliary definition - for decidability of `NF`. -/ +/-- `TopBelow b o` asserts that the largest exponent in `o`, if it exists, is less than `b`. This is +an auxiliary definition for decidability of `NF`. -/ def TopBelow (b : ONote) : ONote → Prop | 0 => True | oadd e _ _ => cmp e b = Ordering.lt @@ -583,8 +581,9 @@ theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = rep mul_omega0_dvd (natCast_pos.2 n₁.pos) (nat_lt_omega0 _)] simpa using opow_dvd_opow ω (one_le_iff_ne_zero.2 this) -/-- Calculate division and remainder of `o` mod ω. - `split' o = (a, n)` means `o = ω * a + n`. -/ +/-- Calculate division and remainder of `o` mod `ω`: + +`split' o = (a, n)` means `o = ω * a + n`. -/ def split' : ONote → ONote × ℕ | 0 => (0, 0) | oadd e n a => @@ -593,8 +592,9 @@ def split' : ONote → ONote × ℕ let (a', m) := split' a (oadd (e - 1) n a', m) -/-- Calculate division and remainder of `o` mod ω. - `split o = (a, n)` means `o = a + n`, where `ω ∣ a`. -/ +/-- Calculate division and remainder of `o` mod `ω`: + +`split o = (a, n)` means `o = a + n`, where `ω ∣ a`. -/ def split : ONote → ONote × ℕ | 0 => (0, 0) | oadd e n a => @@ -614,15 +614,13 @@ def mulNat : ONote → ℕ → ONote | _, 0 => 0 | oadd e n a, m + 1 => oadd e (n * m.succPNat) a -/-- Auxiliary definition to compute the ordinal notation for the ordinal -exponentiation in `opow` -/ +/-- Auxiliary definition to compute the ordinal notation for the ordinal exponentiation in `opow` -/ def opowAux (e a0 a : ONote) : ℕ → ℕ → ONote | _, 0 => 0 | 0, m + 1 => oadd e m.succPNat 0 | k + 1, m => scale (e + mulNat a0 k) a + (opowAux e a0 a k m) -/-- Auxiliary definition to compute the ordinal notation for the ordinal -exponentiation in `opow` -/ +/-- Auxiliary definition to compute the ordinal notation for the ordinal exponentiation in `opow` -/ def opowAux2 (o₂ : ONote) (o₁ : ONote × ℕ) : ONote := match o₁ with | (0, 0) => if o₂ = 0 then 1 else 0 @@ -637,8 +635,7 @@ def opowAux2 (o₂ : ONote) (o₁ : ONote × ℕ) : ONote := let eb := a0 * b scale (eb + mulNat a0 k) a + opowAux eb a0 (mulNat a m) k m -/-- `opow o₁ o₂` calculates the ordinal notation for - the ordinal exponential `o₁ ^ o₂`. -/ +/-- `opow o₁ o₂` calculates the ordinal notation for the ordinal exponential `o₁ ^ o₂`. -/ def opow (o₁ o₂ : ONote) : ONote := opowAux2 o₂ (split o₁) instance : Pow ONote ONote := @@ -938,8 +935,11 @@ theorem repr_opow (o₁ o₂) [NF o₁] [NF o₂] : repr (o₁ ^ o₂) = repr o rw [← opow_succ] exact (repr_opow_aux₂ _ ad a00 al _ _).2 -/-- Given an ordinal, returns `inl none` for `0`, `inl (some a)` for `a+1`, and - `inr f` for a limit ordinal `a`, where `f i` is a sequence converging to `a`. -/ +/-- Given an ordinal, returns: + +* `inl none` for `0` +* `inl (some a)` for `a + 1` +* `inr f` for a limit ordinal `a`, where `f i` is a sequence converging to `a` -/ def fundamentalSequence : ONote → (Option ONote) ⊕ (ℕ → ONote) | zero => Sum.inl none | oadd a m b => @@ -977,10 +977,11 @@ private theorem exists_lt_omega0_opow' {α} {o b : Ordinal} (hb : 1 < b) (ho : o exact (H hd).imp fun i hi => h'.trans <| (opow_lt_opow_iff_right hb).2 hi /-- The property satisfied by `fundamentalSequence o`: - * `inl none` means `o = 0` - * `inl (some a)` means `o = succ a` - * `inr f` means `o` is a limit ordinal and `f` is a - strictly increasing sequence which converges to `o` -/ + +* `inl none` means `o = 0` +* `inl (some a)` means `o = succ a` +* `inr f` means `o` is a limit ordinal and `f` is a strictly increasing sequence which converges to + `o` -/ def FundamentalSequenceProp (o : ONote) : (Option ONote) ⊕ (ℕ → ONote) → Prop | Sum.inl none => o = 0 | Sum.inl (some a) => o.repr = succ a.repr ∧ (o.NF → a.NF) @@ -1070,12 +1071,13 @@ theorem fundamentalSequence_has_prop (o) : FundamentalSequenceProp o (fundamenta H.fst.oadd _ (NF.below_of_lt' (lt_trans (h2 i).2.1 H.snd'.repr_lt) ((h2 i).2.2 H.snd))⟩, exists_lt_add h3⟩ -/-- The fast growing hierarchy for ordinal notations `< ε₀`. This is a sequence of -functions `ℕ → ℕ` indexed by ordinals, with the definition: +/-- The fast growing hierarchy for ordinal notations `< ε₀`. This is a sequence of functions `ℕ → ℕ` +indexed by ordinals, with the definition: + * `f_0(n) = n + 1` -* `f_(α+1)(n) = f_α^[n](n)` -* `f_α(n) = f_(α[n])(n)` where `α` is a limit ordinal - and `α[i]` is the fundamental sequence converging to `α` -/ +* `f_(α + 1)(n) = f_α^[n](n)` +* `f_α(n) = f_(α[n])(n)` where `α` is a limit ordinal and `α[i]` is the fundamental sequence + converging to `α` -/ def fastGrowing : ONote → ℕ → ℕ | o => match fundamentalSequence o, fundamentalSequence_has_prop o with @@ -1088,7 +1090,7 @@ def fastGrowing : ONote → ℕ → ℕ fastGrowing (f i) i termination_by o => o --- Porting note: the bug of the linter, should be fixed. +-- Porting note: the linter bug should be fixed. @[nolint unusedHavesSuffices] theorem fastGrowing_def {o : ONote} {x} (e : fundamentalSequence o = x) : fastGrowing o = @@ -1125,8 +1127,6 @@ theorem fastGrowing_one : fastGrowing 1 = fun n => 2 * n := by suffices ∀ a b, Nat.succ^[a] b = b + a from this _ _ intro a b; induction a <;> simp [*, Function.iterate_succ', Nat.add_assoc, -Function.iterate_succ] -section - @[simp] theorem fastGrowing_two : fastGrowing 2 = fun n => (2 ^ n) * n := by rw [@fastGrowing_succ 2 1 rfl]; funext i; rw [fastGrowing_one] @@ -1134,12 +1134,9 @@ theorem fastGrowing_two : fastGrowing 2 = fun n => (2 ^ n) * n := by intro a b; induction a <;> simp [*, Function.iterate_succ, pow_succ, mul_assoc, -Function.iterate_succ] -end - -/-- We can extend the fast growing hierarchy one more step to `ε₀` itself, - using `ω^(ω^...^ω^0)` as the fundamental sequence converging to `ε₀` (which is not an `ONote`). - Extending the fast growing hierarchy beyond this requires a definition of fundamental sequence - for larger ordinals. -/ +/-- We can extend the fast growing hierarchy one more step to `ε₀` itself, using `ω ^ (ω ^ (⋯ ^ ω))` +as the fundamental sequence converging to `ε₀` (which is not an `ONote`). Extending the fast +growing hierarchy beyond this requires a definition of fundamental sequence for larger ordinals. -/ def fastGrowingε₀ (i : ℕ) : ℕ := fastGrowing ((fun a => a.oadd 1 0)^[i] 0) i @@ -1154,11 +1151,11 @@ theorem fastGrowingε₀_two : fastGrowingε₀ 2 = 2048 := by end ONote -/-- The type of normal ordinal notations. (It would have been - nicer to define this right in the inductive type, but `NF o` - requires `repr` which requires `ONote`, so all these things - would have to be defined at once, which messes up the VM - representation.) -/ +/-- The type of normal ordinal notations. + +It would have been nicer to define this right in the inductive type, but `NF o` requires `repr` +which requires `ONote`, so all these things would have to be defined at once, which messes up the VM +representation. -/ def NONote := { o : ONote // o.NF } @@ -1171,17 +1168,15 @@ open ONote instance NF (o : NONote) : NF o.1 := o.2 -/-- Construct a `NONote` from an ordinal notation - (and infer normality) -/ +/-- Construct a `NONote` from an ordinal notation (and infer normality) -/ def mk (o : ONote) [h : ONote.NF o] : NONote := ⟨o, h⟩ /-- The ordinal represented by an ordinal notation. - (This function is noncomputable because ordinal - arithmetic is noncomputable. In computational applications - `NONote` can be used exclusively without reference - to `Ordinal`, but this function allows for correctness - results to be stated.) -/ + +This function is noncomputable because ordinal arithmetic is noncomputable. In computational +applications `NONote` can be used exclusively without reference to `Ordinal`, but this function +allows for correctness results to be stated. -/ noncomputable def repr (o : NONote) : Ordinal := o.1.repr @@ -1233,7 +1228,7 @@ instance : LinearOrder NONote := instance : IsWellOrder NONote (· < ·) where -/-- Asserts that `repr a < ω ^ repr b`. Used in `NONote.recOn` -/ +/-- Asserts that `repr a < ω ^ repr b`. Used in `NONote.recOn`. -/ def below (a b : NONote) : Prop := NFBelow a.1 (repr b) @@ -1241,9 +1236,8 @@ def below (a b : NONote) : Prop := def oadd (e : NONote) (n : ℕ+) (a : NONote) (h : below a e) : NONote := ⟨_, NF.oadd e.2 n h⟩ -/-- This is a recursor-like theorem for `NONote` suggesting an - inductive definition, which can't actually be defined this - way due to conflicting dependencies. -/ +/-- This is a recursor-like theorem for `NONote` suggesting an inductive definition, which can't +actually be defined this way due to conflicting dependencies. -/ @[elab_as_elim] def recOn {C : NONote → Sort*} (o : NONote) (H0 : C 0) (H1 : ∀ e n a h, C e → C a → C (oadd e n a h)) : C o := by From c78db1435bce112c36922972590b0183fcb4d7c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Tue, 15 Oct 2024 05:14:09 +0000 Subject: [PATCH 124/425] feat(Data/List/GroupBy): Basic API for `List.GroupBy` (#16818) --- Mathlib.lean | 1 + Mathlib/Data/List/GroupBy.lean | 142 +++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 Mathlib/Data/List/GroupBy.lean diff --git a/Mathlib.lean b/Mathlib.lean index bc9d68f0c31f65..73a67c8cf37936 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2316,6 +2316,7 @@ import Mathlib.Data.List.Enum import Mathlib.Data.List.FinRange import Mathlib.Data.List.Forall2 import Mathlib.Data.List.GetD +import Mathlib.Data.List.GroupBy import Mathlib.Data.List.Indexes import Mathlib.Data.List.Infix import Mathlib.Data.List.InsertNth diff --git a/Mathlib/Data/List/GroupBy.lean b/Mathlib/Data/List/GroupBy.lean new file mode 100644 index 00000000000000..6449cb7da1b97a --- /dev/null +++ b/Mathlib/Data/List/GroupBy.lean @@ -0,0 +1,142 @@ +/- +Copyright (c) 2024 Violeta Hernández Palacios. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Violeta Hernández Palacios +-/ +import Mathlib.Data.List.Chain + +/-! +# Group consecutive elements in a list by a relation + +This file provides the basic API for `List.groupBy` which is defined in Core. +The main results are the following: + +- `List.join_groupBy`: the lists in `List.groupBy` join to the original list. +- `List.nil_not_mem_groupBy`: the empty list is not contained in `List.groupBy`. +- `List.chain'_of_mem_groupBy`: any two adjacent elements in a list in `List.groupBy` are related by + the specified relation. +- `List.chain'_getLast_head_groupBy`: the last element of each list in `List.groupBy` is not + related to the first element of the next list. +-/ + +namespace List + +variable {α : Type*} {m : List α} + +@[simp] +theorem groupBy_nil (r : α → α → Bool) : groupBy r [] = [] := + rfl + +private theorem groupByLoop_eq_append {r : α → α → Bool} {l : List α} {a : α} {g : List α} + (gs : List (List α)) : groupBy.loop r l a g gs = gs.reverse ++ groupBy.loop r l a g [] := by + induction l generalizing a g gs with + | nil => simp [groupBy.loop] + | cons b l IH => + simp_rw [groupBy.loop] + split <;> rw [IH] + conv_rhs => rw [IH] + simp + +private theorem join_groupByLoop {r : α → α → Bool} {l : List α} {a : α} {g : List α} : + (groupBy.loop r l a g []).join = g.reverse ++ a :: l := by + induction l generalizing a g with + | nil => simp [groupBy.loop] + | cons b l IH => + rw [groupBy.loop, groupByLoop_eq_append [_]] + split <;> simp [IH] + +@[simp] +theorem join_groupBy (r : α → α → Bool) (l : List α) : (l.groupBy r).join = l := + match l with + | nil => rfl + | cons _ _ => join_groupByLoop + +private theorem nil_not_mem_groupByLoop {r : α → α → Bool} {l : List α} {a : α} {g : List α} : + [] ∉ groupBy.loop r l a g [] := by + induction l generalizing a g with + | nil => + simp [groupBy.loop] + | cons b l IH => + rw [groupBy.loop] + split + · exact IH + · rw [groupByLoop_eq_append, mem_append] + simpa using IH + +theorem nil_not_mem_groupBy (r : α → α → Bool) (l : List α) : [] ∉ l.groupBy r := + match l with + | nil => not_mem_nil _ + | cons _ _ => nil_not_mem_groupByLoop + +theorem ne_nil_of_mem_groupBy (r : α → α → Bool) {l : List α} (h : m ∈ l.groupBy r) : m ≠ [] := by + rintro rfl + exact nil_not_mem_groupBy r l h + +private theorem chain'_of_mem_groupByLoop {r : α → α → Bool} {l : List α} {a : α} {g : List α} + (hga : ∀ b ∈ g.head?, r b a) (hg : g.Chain' fun y x ↦ r x y) + (h : m ∈ groupBy.loop r l a g []) : m.Chain' fun x y ↦ r x y := by + induction l generalizing a g with + | nil => + rw [groupBy.loop, reverse_cons, mem_append, mem_reverse, mem_singleton] at h + obtain hm | rfl := h + · exact (not_mem_nil m hm).elim + · apply List.chain'_reverse.1 + rw [reverse_reverse] + exact chain'_cons'.2 ⟨hga, hg⟩ + | cons b l IH => + simp [groupBy.loop] at h + split at h + · apply IH _ (chain'_cons'.2 ⟨hga, hg⟩) h + intro b hb + rw [head?_cons, Option.mem_some_iff] at hb + rwa [← hb] + · rw [groupByLoop_eq_append, mem_append, reverse_singleton, mem_singleton] at h + obtain rfl | hm := h + · apply List.chain'_reverse.1 + rw [reverse_append, reverse_cons, reverse_nil, nil_append, reverse_reverse] + exact chain'_cons'.2 ⟨hga, hg⟩ + · apply IH _ chain'_nil hm + rintro _ ⟨⟩ + +theorem chain'_of_mem_groupBy {r : α → α → Bool} {l : List α} (h : m ∈ l.groupBy r) : + m.Chain' fun x y ↦ r x y := by + cases l with + | nil => cases h + | cons a l => + apply chain'_of_mem_groupByLoop _ _ h + · rintro _ ⟨⟩ + · exact chain'_nil + +private theorem chain'_getLast_head_groupByLoop {r : α → α → Bool} (l : List α) {a : α} + {g : List α} {gs : List (List α)} (hgs' : [] ∉ gs) + (hgs : gs.Chain' fun b a ↦ ∃ ha hb, r (a.getLast ha) (b.head hb) = false) + (hga : ∀ m ∈ gs.head?, ∃ ha hb, r (m.getLast ha) ((g.reverse ++ [a]).head hb) = false) : + (groupBy.loop r l a g gs).Chain' fun a b ↦ ∃ ha hb, r (a.getLast ha) (b.head hb) = false := by + induction l generalizing a g gs with + | nil => + rw [groupBy.loop, reverse_cons] + apply List.chain'_reverse.1 + simpa using chain'_cons'.2 ⟨hga, hgs⟩ + | cons b l IH => + rw [groupBy.loop] + split + · apply IH hgs' hgs + intro m hm + obtain ⟨ha, _, H⟩ := hga m hm + refine ⟨ha, append_ne_nil_of_right_ne_nil _ (cons_ne_nil _ _), ?_⟩ + rwa [reverse_cons, head_append_of_ne_nil] + · apply IH + · simpa using hgs' + · rw [reverse_cons] + apply chain'_cons'.2 ⟨hga, hgs⟩ + · simpa + +theorem chain'_getLast_head_groupBy (r : α → α → Bool) (l : List α) : + (l.groupBy r).Chain' fun a b ↦ ∃ ha hb, r (a.getLast ha) (b.head hb) = false := by + cases l with + | nil => exact chain'_nil + | cons _ _ => + apply chain'_getLast_head_groupByLoop _ (not_mem_nil _) chain'_nil + rintro _ ⟨⟩ + +end List From 74b17a171fe8ba33353bfdc87c47fae2af792271 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Tue, 15 Oct 2024 06:04:03 +0000 Subject: [PATCH 125/425] chore(RingTheory/OreLocalization): split into `GroupTheory.OreLocalization` (#17730) The files `Mathlib/GroupTheory/OreLocalization/OreSet.lean` and `Mathlib/GroupTheory/OreLocalization/Basic.lean` contain the results of `Mathlib/RingTheory/OreLocalization/OreSet.lean` and `Mathlib/RingTheory/OreLocalization/Basic.lean` that don't involve rings or monoids with zero. Co-authored-by: Kim Morrison --- Mathlib.lean | 2 + .../GroupTheory/MonoidLocalization/Basic.lean | 2 +- .../MonoidLocalization/MonoidWithZero.lean | 1 + .../GroupTheory/OreLocalization/Basic.lean | 641 ++++++++++++++++++ .../GroupTheory/OreLocalization/OreSet.lean | 120 ++++ Mathlib/RingTheory/OreLocalization/Basic.lean | 610 +---------------- .../RingTheory/OreLocalization/OreSet.lean | 103 +-- 7 files changed, 770 insertions(+), 709 deletions(-) create mode 100644 Mathlib/GroupTheory/OreLocalization/Basic.lean create mode 100644 Mathlib/GroupTheory/OreLocalization/OreSet.lean diff --git a/Mathlib.lean b/Mathlib.lean index 73a67c8cf37936..76f49cf3294a22 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2873,6 +2873,8 @@ import Mathlib.GroupTheory.NoncommCoprod import Mathlib.GroupTheory.NoncommPiCoprod import Mathlib.GroupTheory.Order.Min import Mathlib.GroupTheory.OrderOfElement +import Mathlib.GroupTheory.OreLocalization.Basic +import Mathlib.GroupTheory.OreLocalization.OreSet import Mathlib.GroupTheory.PGroup import Mathlib.GroupTheory.Perm.Basic import Mathlib.GroupTheory.Perm.Closure diff --git a/Mathlib/GroupTheory/MonoidLocalization/Basic.lean b/Mathlib/GroupTheory/MonoidLocalization/Basic.lean index 76275087dc282a..7780b5a72ee674 100644 --- a/Mathlib/GroupTheory/MonoidLocalization/Basic.lean +++ b/Mathlib/GroupTheory/MonoidLocalization/Basic.lean @@ -5,7 +5,7 @@ Authors: Amelia Livingston -/ import Mathlib.Algebra.Group.Submonoid.Membership import Mathlib.GroupTheory.Congruence.Hom -import Mathlib.RingTheory.OreLocalization.Basic +import Mathlib.GroupTheory.OreLocalization.Basic /-! # Localizations of commutative monoids diff --git a/Mathlib/GroupTheory/MonoidLocalization/MonoidWithZero.lean b/Mathlib/GroupTheory/MonoidLocalization/MonoidWithZero.lean index 3c6c5f38a066e5..af6a28afe26720 100644 --- a/Mathlib/GroupTheory/MonoidLocalization/MonoidWithZero.lean +++ b/Mathlib/GroupTheory/MonoidLocalization/MonoidWithZero.lean @@ -5,6 +5,7 @@ Authors: Amelia Livingston -/ import Mathlib.Algebra.Regular.Basic import Mathlib.GroupTheory.MonoidLocalization.Basic +import Mathlib.RingTheory.OreLocalization.Basic /-! # Localizations of commutative monoids with zeroes diff --git a/Mathlib/GroupTheory/OreLocalization/Basic.lean b/Mathlib/GroupTheory/OreLocalization/Basic.lean new file mode 100644 index 00000000000000..82c2f2d7c5cd19 --- /dev/null +++ b/Mathlib/GroupTheory/OreLocalization/Basic.lean @@ -0,0 +1,641 @@ +/- +Copyright (c) 2022 Jakob von Raumer. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jakob von Raumer, Kevin Klinge, Andrew Yang +-/ +import Mathlib.Algebra.Group.Submonoid.Operations +import Mathlib.GroupTheory.OreLocalization.OreSet + +/-! + +# Localization over left Ore sets. + +This file defines the localization of a monoid over a left Ore set and proves its universal +mapping property. + +## Notations + +Introduces the notation `R[S⁻¹]` for the Ore localization of a monoid `R` at a right Ore +subset `S`. Also defines a new heterogeneous division notation `r /ₒ s` for a numerator `r : R` and +a denominator `s : S`. + +## References + +* +* [Zoran Škoda, *Noncommutative localization in noncommutative geometry*][skoda2006] + + +## Tags +localization, Ore, non-commutative + +-/ + +assert_not_exists MonoidWithZero +assert_not_exists Ring + +universe u + +open OreLocalization + +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 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 + iseqv := by + refine ⟨fun _ => ⟨1, 1, by simp⟩, ?_, ?_⟩ + · rintro ⟨r, s⟩ ⟨r', s'⟩ ⟨u, v, hru, hsu⟩; dsimp only at * + rcases oreCondition (s : R) s' with ⟨r₂, s₂, h₁⟩ + rcases oreCondition r₂ u with ⟨r₃, s₃, h₂⟩ + have : r₃ * v * s = s₃ * s₂ * s := by + -- Porting note: the proof used `assoc_rw` + rw [mul_assoc _ (s₂ : R), h₁, ← mul_assoc, h₂, mul_assoc, ← hsu, ← mul_assoc] + rcases ore_right_cancel (r₃ * v) (s₃ * s₂) s this with ⟨w, hw⟩ + refine ⟨w * (s₃ * s₂), w * (r₃ * u), ?_, ?_⟩ <;> + simp only [Submonoid.coe_mul, Submonoid.smul_def, ← hw] + · simp only [mul_smul, hru, ← Submonoid.smul_def] + · simp only [mul_assoc, hsu] + · rintro ⟨r₁, s₁⟩ ⟨r₂, s₂⟩ ⟨r₃, s₃⟩ ⟨u, v, hur₁, hs₁u⟩ ⟨u', v', hur₂, hs₂u⟩ + rcases oreCondition v' u with ⟨r', s', h⟩; dsimp only at * + refine ⟨s' * u', r' * v, ?_, ?_⟩ <;> + simp only [Submonoid.smul_def, Submonoid.coe_mul, mul_smul, mul_assoc] at * + · rw [hur₂, smul_smul, h, mul_smul, hur₁] + · rw [hs₂u, ← mul_assoc, h, mul_assoc, hs₁u] + +end OreLocalization + +/-- The Ore localization of a monoid and a submonoid fulfilling the Ore condition. -/ +@[to_additive AddOreLocalization "The Ore localization of an additive monoid and a submonoid +fulfilling the Ore condition."] +def OreLocalization {R : Type*} [Monoid R] (S : Submonoid R) [OreSet S] + (X : Type*) [MulAction R X] := + Quotient (OreLocalization.oreEqv S X) + +namespace OreLocalization + +section Monoid + +variable (R : Type*) [Monoid R] (S : Submonoid R) [OreSet S] + +@[inherit_doc OreLocalization] +scoped syntax:1075 term noWs atomic("[" term "⁻¹" noWs "]") : term +macro_rules | `($R[$S⁻¹]) => ``(OreLocalization $S $R) + +attribute [local instance] oreEqv + +variable {R S} +variable {X} [MulAction R X] + +/-- The division in the Ore localization `X[S⁻¹]`, as a fraction of an element of `X` and `S`. -/ +@[to_additive "The subtraction in the Ore localization, +as a difference of an element of `X` and `S`."] +def oreDiv (r : X) (s : S) : X[S⁻¹] := + Quotient.mk' (r, s) + +@[inherit_doc] +infixl:70 " /ₒ " => oreDiv + +@[inherit_doc] +infixl:65 " -ₒ " => _root_.AddOreLocalization.oreSub + +@[to_additive (attr := elab_as_elim, cases_eliminator, induction_eliminator)] +protected theorem ind {β : X[S⁻¹] → Prop} + (c : ∀ (r : X) (s : S), β (r /ₒ s)) : ∀ q, β q := by + apply Quotient.ind + rintro ⟨r, s⟩ + exact c r s + +@[to_additive] +theorem oreDiv_eq_iff {r₁ r₂ : X} {s₁ s₂ : S} : + r₁ /ₒ s₁ = r₂ /ₒ s₂ ↔ ∃ (u : S) (v : R), u • r₂ = v • r₁ ∧ u * s₂ = v * s₁ := + Quotient.eq'' + +/-- A fraction `r /ₒ s` is equal to its expansion by an arbitrary factor `t` if `t * s ∈ S`. -/ +@[to_additive "A difference `r -ₒ s` is equal to its expansion by an +arbitrary translation `t` if `t + s ∈ S`."] +protected theorem expand (r : X) (s : S) (t : R) (hst : t * (s : R) ∈ S) : + r /ₒ s = t • r /ₒ ⟨t * s, hst⟩ := by + apply Quotient.sound + exact ⟨s, s * t, by rw [mul_smul, Submonoid.smul_def], by rw [← mul_assoc]⟩ + +/-- A fraction is equal to its expansion by a factor from `S`. -/ +@[to_additive "A difference is equal to its expansion by a summand from `S`."] +protected theorem expand' (r : X) (s s' : S) : r /ₒ s = s' • r /ₒ (s' * s) := + OreLocalization.expand r s s' (by norm_cast; apply SetLike.coe_mem) + +/-- Fractions which differ by a factor of the numerator can be proven equal if +those factors expand to equal elements of `R`. -/ +@[to_additive "Differences whose minuends differ by a common summand can be proven equal if +those summands expand to equal elements of `R`."] +protected theorem eq_of_num_factor_eq {r r' r₁ r₂ : R} {s t : S} (h : t * r = t * r') : + r₁ * r * r₂ /ₒ s = r₁ * r' * r₂ /ₒ s := by + rcases oreCondition r₁ t with ⟨r₁', t', hr₁⟩ + rw [OreLocalization.expand' _ s t', OreLocalization.expand' _ s t'] + congr 1 + -- Porting note (#11215): TODO: use `assoc_rw`? + calc (t' : R) * (r₁ * r * r₂) + = t' * r₁ * r * r₂ := by simp [← mul_assoc] + _ = r₁' * t * r * r₂ := by rw [hr₁] + _ = r₁' * (t * r) * r₂ := by simp [← mul_assoc] + _ = r₁' * (t * r') * r₂ := by rw [h] + _ = r₁' * t * r' * r₂ := by simp [← mul_assoc] + _ = t' * r₁ * r' * r₂ := by rw [hr₁] + _ = t' * (r₁ * r' * r₂) := by simp [← mul_assoc] + +/-- A function or predicate over `X` and `S` can be lifted to `X[S⁻¹]` if it is invariant +under expansion on the left. -/ +@[to_additive "A function or predicate over `X` and `S` can be lifted to the localizaton if it is +invariant under expansion on the left."] +def liftExpand {C : Sort*} (P : X → S → C) + (hP : ∀ (r : X) (t : R) (s : S) (ht : t * s ∈ S), P r s = P (t • r) ⟨t * s, ht⟩) : + X[S⁻¹] → C := + Quotient.lift (fun p : X × S => P p.1 p.2) fun (r₁, s₁) (r₂, s₂) ⟨u, v, hr₂, hs₂⟩ => by + dsimp at * + have s₁vS : v * s₁ ∈ S := by + rw [← hs₂, ← S.coe_mul] + exact SetLike.coe_mem (u * s₂) + replace hs₂ : u * s₂ = ⟨_, s₁vS⟩ := by ext; simp [hs₂] + rw [hP r₁ v s₁ s₁vS, hP r₂ u s₂ (by norm_cast; rwa [hs₂]), ← hr₂] + simp only [← hs₂]; rfl + +@[to_additive (attr := simp)] +theorem liftExpand_of {C : Sort*} {P : X → S → C} + {hP : ∀ (r : X) (t : R) (s : S) (ht : t * s ∈ S), P r s = P (t • r) ⟨t * s, ht⟩} (r : X) + (s : S) : liftExpand P hP (r /ₒ s) = P r s := + rfl + +/-- A version of `liftExpand` used to simultaneously lift functions with two arguments +in `X[S⁻¹]`. -/ +@[to_additive "A version of `liftExpand` used to simultaneously lift functions with two arguments"] +def lift₂Expand {C : Sort*} (P : X → S → X → S → C) + (hP : + ∀ (r₁ : X) (t₁ : R) (s₁ : S) (ht₁ : t₁ * s₁ ∈ S) (r₂ : X) (t₂ : R) (s₂ : S) + (ht₂ : t₂ * s₂ ∈ S), + P r₁ s₁ r₂ s₂ = P (t₁ • r₁) ⟨t₁ * s₁, ht₁⟩ (t₂ • r₂) ⟨t₂ * s₂, ht₂⟩) : + X[S⁻¹] → X[S⁻¹] → C := + liftExpand + (fun r₁ s₁ => liftExpand (P r₁ s₁) fun r₂ t₂ s₂ ht₂ => by + have := hP r₁ 1 s₁ (by simp) r₂ t₂ s₂ ht₂ + simp [this]) + fun r₁ t₁ s₁ ht₁ => by + ext x; induction' x with r₂ s₂ + dsimp only + rw [liftExpand_of, liftExpand_of, hP r₁ t₁ s₁ ht₁ r₂ 1 s₂ (by simp)]; simp + +@[to_additive (attr := simp)] +theorem lift₂Expand_of {C : Sort*} {P : X → S → X → S → C} + {hP : + ∀ (r₁ : X) (t₁ : R) (s₁ : S) (ht₁ : t₁ * s₁ ∈ S) (r₂ : X) (t₂ : R) (s₂ : S) + (ht₂ : t₂ * s₂ ∈ S), + P r₁ s₁ r₂ s₂ = P (t₁ • r₁) ⟨t₁ * s₁, ht₁⟩ (t₂ • r₂) ⟨t₂ * s₂, ht₂⟩} + (r₁ : X) (s₁ : S) (r₂ : X) (s₂ : S) : lift₂Expand P hP (r₁ /ₒ s₁) (r₂ /ₒ s₂) = P r₁ s₁ r₂ s₂ := + rfl + +@[to_additive] +private def smul' (r₁ : R) (s₁ : S) (r₂ : X) (s₂ : S) : X[S⁻¹] := + oreNum r₁ s₂ • r₂ /ₒ (oreDenom r₁ s₂ * s₁) + +@[to_additive] +private theorem smul'_char (r₁ : R) (r₂ : X) (s₁ s₂ : S) (u : S) (v : R) (huv : u * r₁ = v * s₂) : + OreLocalization.smul' r₁ s₁ r₂ s₂ = v • r₂ /ₒ (u * s₁) := by + -- Porting note: `assoc_rw` was not ported yet + simp only [smul'] + have h₀ := ore_eq r₁ s₂; set v₀ := oreNum r₁ s₂; set u₀ := oreDenom r₁ s₂ + rcases oreCondition (u₀ : R) u with ⟨r₃, s₃, h₃⟩ + have := + calc + r₃ * v * s₂ = r₃ * (u * r₁) := by rw [mul_assoc, ← huv] + _ = s₃ * (u₀ * r₁) := by rw [← mul_assoc, ← mul_assoc, h₃] + _ = s₃ * v₀ * s₂ := by rw [mul_assoc, h₀] + rcases ore_right_cancel _ _ _ this with ⟨s₄, hs₄⟩ + symm; rw [oreDiv_eq_iff] + use s₄ * s₃ + use s₄ * r₃ + simp only [Submonoid.coe_mul, Submonoid.smul_def, smul_eq_mul] + constructor + · rw [smul_smul, mul_assoc (c := v₀), ← hs₄] + simp only [smul_smul, mul_assoc] + · rw [← mul_assoc (b := (u₀ : R)), mul_assoc (c := (u₀ : R)), h₃] + simp only [mul_assoc] + +/-- The multiplication on the Ore localization of monoids. -/ +@[to_additive] +private def 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₁⟩ + rw [smul'_char _ _ _ _ _ _ h₁] + rcases oreCondition r ⟨_, hs⟩ with ⟨r₂', s₂', h₂⟩ + rw [smul'_char _ _ _ _ _ _ h₂] + rcases oreCondition (s₁' : R) (s₂') with ⟨r₃', s₃', h₃⟩ + have : s₃' * r₁' * s' = (r₃' * r₂' * r₂) * s' := by + rw [mul_assoc, ← h₁, ← mul_assoc, h₃, mul_assoc, h₂] + simp [mul_assoc] + rcases ore_right_cancel _ _ _ this with ⟨s₄', h₄⟩ + have : (s₄' * r₃') * (s₂' * s) ∈ S := by + rw [mul_assoc, ← mul_assoc r₃', ← h₃] + exact (s₄' * (s₃' * s₁' * s)).2 + rw [OreLocalization.expand' _ _ (s₄' * s₃'), OreLocalization.expand _ (s₂' * s) _ this] + simp only [Submonoid.smul_def, Submonoid.coe_mul, smul_smul, mul_assoc, h₄] + congr 1 + ext; simp only [Submonoid.coe_mul, ← mul_assoc] + rw [mul_assoc (s₄' : R), h₃, ← mul_assoc] + +/-- The scalar multiplication on the Ore localization of monoids. -/ +@[to_additive (attr := irreducible) + "the vector addition on the Ore localization of additive monoids."] +protected def smul : R[S⁻¹] → X[S⁻¹] → X[S⁻¹] := + liftExpand smul'' fun r₁ r₂ s hs => by + ext x + induction' x with x s₂ + show OreLocalization.smul' r₁ s x s₂ = OreLocalization.smul' (r₂ * r₁) ⟨_, hs⟩ x s₂ + rcases oreCondition r₁ s₂ with ⟨r₁', s₁', h₁⟩ + rw [smul'_char _ _ _ _ _ _ h₁] + rcases oreCondition (r₂ * r₁) s₂ with ⟨r₂', s₂', h₂⟩ + rw [smul'_char _ _ _ _ _ _ h₂] + rcases oreCondition (s₂' * r₂) (s₁') with ⟨r₃', s₃', h₃⟩ + have : s₃' * r₂' * s₂ = r₃' * r₁' * s₂ := by + rw [mul_assoc, ← h₂, ← mul_assoc _ r₂, ← mul_assoc, h₃, mul_assoc, h₁, mul_assoc] + rcases ore_right_cancel _ _ _ this with ⟨s₄', h₄⟩ + have : (s₄' * r₃') * (s₁' * s) ∈ S := by + rw [← mul_assoc, mul_assoc _ r₃', ← h₃, ← mul_assoc, ← mul_assoc, mul_assoc] + exact mul_mem (s₄' * s₃' * s₂').2 hs + rw [OreLocalization.expand' (r₂' • x) _ (s₄' * s₃'), OreLocalization.expand _ _ _ this] + simp only [Submonoid.smul_def, Submonoid.coe_mul, smul_smul, mul_assoc, h₄] + congr 1 + ext; simp only [Submonoid.coe_mul, ← mul_assoc] + rw [mul_assoc _ r₃', ← h₃, ← mul_assoc, ← mul_assoc] + +@[to_additive] +instance : SMul R[S⁻¹] X[S⁻¹] := + ⟨OreLocalization.smul⟩ + +@[to_additive] +instance : Mul R[S⁻¹] := + ⟨OreLocalization.smul⟩ + +@[to_additive] +theorem oreDiv_smul_oreDiv {r₁ : R} {r₂ : X} {s₁ s₂ : S} : + (r₁ /ₒ s₁) • (r₂ /ₒ s₂) = oreNum r₁ s₂ • r₂ /ₒ (oreDenom r₁ s₂ * s₁) := by + with_unfolding_all rfl + +@[to_additive] +theorem oreDiv_mul_oreDiv {r₁ : R} {r₂ : R} {s₁ s₂ : S} : + (r₁ /ₒ s₁) * (r₂ /ₒ s₂) = oreNum r₁ s₂ * r₂ /ₒ (oreDenom r₁ s₂ * s₁) := by + with_unfolding_all rfl + +/-- A characterization lemma for the scalar multiplication on the Ore localization, +allowing for a choice of Ore numerator and Ore denominator. -/ +@[to_additive "A characterization lemma for the vector addition on the Ore localization, +allowing for a choice of Ore minuend and Ore subtrahend."] +theorem oreDiv_smul_char (r₁ : R) (r₂ : X) (s₁ s₂ : S) (r' : R) (s' : S) (huv : s' * r₁ = r' * s₂) : + (r₁ /ₒ s₁) • (r₂ /ₒ s₂) = r' • r₂ /ₒ (s' * s₁) := by + with_unfolding_all exact smul'_char r₁ r₂ s₁ s₂ s' r' huv + +/-- A characterization lemma for the multiplication on the Ore localization, allowing for a choice +of Ore numerator and Ore denominator. -/ +@[to_additive "A characterization lemma for the addition on the Ore localization, +allowing for a choice of Ore minuend and Ore subtrahend."] +theorem oreDiv_mul_char (r₁ r₂ : R) (s₁ s₂ : S) (r' : R) (s' : S) (huv : s' * r₁ = r' * s₂) : + r₁ /ₒ s₁ * (r₂ /ₒ s₂) = r' * r₂ /ₒ (s' * s₁) := by + with_unfolding_all exact smul'_char r₁ r₂ s₁ s₂ s' r' huv + +/-- Another characterization lemma for the scalar multiplication on the Ore localizaion delivering +Ore witnesses and conditions bundled in a sigma type. -/ +@[to_additive "Another characterization lemma for the vector addition on the + Ore localizaion delivering Ore witnesses and conditions bundled in a sigma type."] +def oreDivSMulChar' (r₁ : R) (r₂ : X) (s₁ s₂ : S) : + Σ'r' : R, Σ's' : S, s' * r₁ = r' * s₂ ∧ (r₁ /ₒ s₁) • (r₂ /ₒ s₂) = r' • r₂ /ₒ (s' * s₁) := + ⟨oreNum r₁ s₂, oreDenom r₁ s₂, ore_eq r₁ s₂, oreDiv_smul_oreDiv⟩ + +/-- Another characterization lemma for the multiplication on the Ore localizaion delivering +Ore witnesses and conditions bundled in a sigma type. -/ +@[to_additive "Another characterization lemma for the addition on the Ore localizaion delivering + Ore witnesses and conditions bundled in a sigma type."] +def oreDivMulChar' (r₁ r₂ : R) (s₁ s₂ : S) : + Σ'r' : R, Σ's' : S, s' * r₁ = r' * s₂ ∧ r₁ /ₒ s₁ * (r₂ /ₒ s₂) = r' * r₂ /ₒ (s' * s₁) := + ⟨oreNum r₁ s₂, oreDenom r₁ s₂, ore_eq r₁ s₂, oreDiv_mul_oreDiv⟩ + +/-- `1` in the localization, defined as `1 /ₒ 1`. -/ +@[to_additive (attr := irreducible) "`0` in the additive localization, defined as `0 -ₒ 0`."] +protected def one : R[S⁻¹] := 1 /ₒ 1 + +@[to_additive] +instance : One R[S⁻¹] := + ⟨OreLocalization.one⟩ + +@[to_additive] +protected theorem one_def : (1 : R[S⁻¹]) = 1 /ₒ 1 := by + with_unfolding_all rfl + +@[to_additive] +instance : Inhabited R[S⁻¹] := + ⟨1⟩ + +@[to_additive (attr := simp)] +protected theorem div_eq_one' {r : R} (hr : r ∈ S) : r /ₒ ⟨r, hr⟩ = 1 := by + rw [OreLocalization.one_def, oreDiv_eq_iff] + exact ⟨⟨r, hr⟩, 1, by simp, by simp⟩ + +@[to_additive (attr := simp)] +protected theorem div_eq_one {s : S} : (s : R) /ₒ s = 1 := + OreLocalization.div_eq_one' _ + +@[to_additive] +protected theorem one_smul (x : X[S⁻¹]) : (1 : R[S⁻¹]) • x = x := by + induction' x with r s + simp [OreLocalization.one_def, oreDiv_smul_char 1 r 1 s 1 s (by simp)] + +@[to_additive] +protected theorem one_mul (x : R[S⁻¹]) : 1 * x = x := + OreLocalization.one_smul x + +@[to_additive] +protected theorem mul_one (x : R[S⁻¹]) : x * 1 = x := by + induction' x with r s + simp [OreLocalization.one_def, oreDiv_mul_char r (1 : R) s (1 : S) r 1 (by simp)] + +@[to_additive] +protected theorem mul_smul (x y : R[S⁻¹]) (z : X[S⁻¹]) : (x * y) • z = x • y • z := by + -- Porting note: `assoc_rw` was not ported yet + induction' x with r₁ s₁ + induction' y with r₂ s₂ + induction' z with r₃ s₃ + rcases oreDivMulChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha' + rcases oreDivSMulChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; rw [hb']; clear hb' + rcases oreCondition ra sb with ⟨rc, sc, hc⟩ + rw [oreDiv_smul_char (ra * r₂) r₃ (sa * s₁) s₃ (rc * rb) sc]; swap + · rw [← mul_assoc _ ra, hc, mul_assoc, hb, ← mul_assoc] + rw [← mul_assoc, mul_smul] + symm; apply oreDiv_smul_char + rw [Submonoid.coe_mul, Submonoid.coe_mul, ← mul_assoc, ← hc, mul_assoc _ ra, ← ha, mul_assoc] + +@[to_additive] +protected theorem mul_assoc (x y z : R[S⁻¹]) : x * y * z = x * (y * z) := + OreLocalization.mul_smul x y z + +/-- `npow` of `OreLocalization` -/ +@[to_additive (attr := irreducible) "`nsmul` of `AddOreLocalization`"] +protected def npow : ℕ → R[S⁻¹] → R[S⁻¹] := npowRec + +unseal OreLocalization.npow in +@[to_additive] +instance : Monoid R[S⁻¹] where + one_mul := OreLocalization.one_mul + mul_one := OreLocalization.mul_one + mul_assoc := OreLocalization.mul_assoc + npow := OreLocalization.npow + +@[to_additive] +instance instMulActionOreLocalization : MulAction R[S⁻¹] X[S⁻¹] where + one_smul := OreLocalization.one_smul + mul_smul := OreLocalization.mul_smul + +@[to_additive] +protected theorem mul_inv (s s' : S) : ((s : R) /ₒ s') * ((s' : R) /ₒ s) = 1 := by + simp [oreDiv_mul_char (s : R) s' s' s 1 1 (by simp)] + +@[to_additive (attr := simp)] +protected theorem one_div_smul {r : X} {s t : S} : ((1 : R) /ₒ t) • (r /ₒ s) = r /ₒ (s * t) := by + simp [oreDiv_smul_char 1 r t s 1 s (by simp)] + +@[to_additive (attr := simp)] +protected theorem one_div_mul {r : R} {s t : S} : (1 /ₒ t) * (r /ₒ s) = r /ₒ (s * t) := by + simp [oreDiv_mul_char 1 r t s 1 s (by simp)] + +@[to_additive (attr := simp)] +protected theorem smul_cancel {r : X} {s t : S} : ((s : R) /ₒ t) • (r /ₒ s) = r /ₒ t := by + simp [oreDiv_smul_char s.1 r t s 1 1 (by simp)] + +@[to_additive (attr := simp)] +protected theorem mul_cancel {r : R} {s t : S} : ((s : R) /ₒ t) * (r /ₒ s) = r /ₒ t := by + simp [oreDiv_mul_char s.1 r t s 1 1 (by simp)] + +@[to_additive (attr := simp)] +protected theorem smul_cancel' {r₁ : R} {r₂ : X} {s t : S} : + ((r₁ * s) /ₒ t) • (r₂ /ₒ s) = (r₁ • r₂) /ₒ t := by + simp [oreDiv_smul_char (r₁ * s) r₂ t s r₁ 1 (by simp)] + +@[to_additive (attr := simp)] +protected theorem mul_cancel' {r₁ r₂ : R} {s t : S} : + ((r₁ * s) /ₒ t) * (r₂ /ₒ s) = (r₁ * r₂) /ₒ t := by + simp [oreDiv_mul_char (r₁ * s) r₂ t s r₁ 1 (by simp)] + +@[to_additive (attr := simp)] +theorem smul_div_one {p : R} {r : X} {s : S} : (p /ₒ s) • (r /ₒ 1) = (p • r) /ₒ s := by + simp [oreDiv_smul_char p r s 1 p 1 (by simp)] + +@[to_additive (attr := simp)] +theorem mul_div_one {p r : R} {s : S} : (p /ₒ s) * (r /ₒ 1) = (p * r) /ₒ s := by + --TODO use coercion r ↦ r /ₒ 1 + simp [oreDiv_mul_char p r s 1 p 1 (by simp)] + +/-- The fraction `s /ₒ 1` as a unit in `R[S⁻¹]`, where `s : S`. -/ +@[to_additive "The difference `s -ₒ 0` as a an additive unit."] +def numeratorUnit (s : S) : Units R[S⁻¹] where + val := (s : R) /ₒ 1 + inv := (1 : R) /ₒ s + val_inv := OreLocalization.mul_inv s 1 + inv_val := OreLocalization.mul_inv 1 s + +/-- The multiplicative homomorphism from `R` to `R[S⁻¹]`, mapping `r : R` to the +fraction `r /ₒ 1`. -/ +@[to_additive "The additive homomorphism from `R` to `AddOreLocalization R S`, + mapping `r : R` to the difference `r -ₒ 0`."] +def numeratorHom : R →* R[S⁻¹] where + toFun r := r /ₒ 1 + map_one' := by with_unfolding_all rfl + map_mul' _ _ := mul_div_one.symm + +@[to_additive] +theorem numeratorHom_apply {r : R} : numeratorHom r = r /ₒ (1 : S) := + rfl + +@[to_additive] +theorem numerator_isUnit (s : S) : IsUnit (numeratorHom (s : R) : R[S⁻¹]) := + ⟨numeratorUnit s, rfl⟩ + +section UMP + +variable {T : Type*} [Monoid T] +variable (f : R →* T) (fS : S →* Units T) + +/-- The universal lift from a morphism `R →* T`, which maps elements of `S` to units of `T`, +to a morphism `R[S⁻¹] →* T`. -/ +@[to_additive "The universal lift from a morphism `R →+ T`, which maps elements of `S` to + additive-units of `T`, to a morphism `AddOreLocalization R S →+ T`."] +def universalMulHom (hf : ∀ s : S, f s = fS s) : R[S⁻¹] →* T where + -- Porting note(#12129): additional beta reduction needed + toFun x := + x.liftExpand (fun r s => ((fS s)⁻¹ : Units T) * f r) fun r t s ht => by + simp only [smul_eq_mul] + have : (fS ⟨t * s, ht⟩ : T) = f t * fS s := by + simp only [← hf, MonoidHom.map_mul] + conv_rhs => + rw [MonoidHom.map_mul, ← one_mul (f r), ← Units.val_one, ← mul_inv_cancel (fS s)] + rw [Units.val_mul, mul_assoc, ← mul_assoc _ (fS s : T), ← this, ← mul_assoc] + simp only [one_mul, Units.inv_mul] + map_one' := by beta_reduce; rw [OreLocalization.one_def, liftExpand_of]; simp + map_mul' x y := by + -- Porting note: `simp only []` required, not just for beta reductions + beta_reduce + simp only [] -- TODO more! + induction' x with r₁ s₁ + induction' y with r₂ s₂ + rcases oreDivMulChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha' + rw [liftExpand_of, liftExpand_of, liftExpand_of, Units.inv_mul_eq_iff_eq_mul, map_mul, map_mul, + Units.val_mul, mul_assoc, ← mul_assoc (fS s₁ : T), ← mul_assoc (fS s₁ : T), Units.mul_inv, + one_mul, ← hf, ← mul_assoc, ← map_mul _ _ r₁, ha, map_mul, hf s₂, mul_assoc, + ← mul_assoc (fS s₂ : T), (fS s₂).mul_inv, one_mul] + +variable (hf : ∀ s : S, f s = fS s) + +@[to_additive] +theorem universalMulHom_apply {r : R} {s : S} : + universalMulHom f fS hf (r /ₒ s) = ((fS s)⁻¹ : Units T) * f r := + rfl + +@[to_additive] +theorem universalMulHom_commutes {r : R} : universalMulHom f fS hf (numeratorHom r) = f r := by + simp [numeratorHom_apply, universalMulHom_apply] + +/-- The universal morphism `universalMulHom` is unique. -/ +@[to_additive "The universal morphism `universalAddHom` is unique."] +theorem universalMulHom_unique (φ : R[S⁻¹] →* T) (huniv : ∀ r : R, φ (numeratorHom r) = f r) : + φ = universalMulHom f fS hf := by + ext x; induction' x with r s + rw [universalMulHom_apply, ← huniv r, numeratorHom_apply, ← one_mul (φ (r /ₒ s)), ← + Units.val_one, ← inv_mul_cancel (fS s), Units.val_mul, mul_assoc, ← hf, ← huniv, ← φ.map_mul, + numeratorHom_apply, OreLocalization.mul_cancel] + +end UMP + +end Monoid + +section SMul + +variable {R R' M X : Type*} [Monoid M] {S : Submonoid M} [OreSet S] [MulAction M X] +variable [SMul R X] [SMul R M] [IsScalarTower R M M] [IsScalarTower R M X] +variable [SMul R' X] [SMul R' M] [IsScalarTower R' M M] [IsScalarTower R' M X] +variable [SMul R R'] [IsScalarTower R R' M] + +/-- Scalar multiplication in a monoid localization. -/ +@[to_additive (attr := irreducible) "Vector addition in an additive monoid localization."] +protected def hsmul (c : R) : + X[S⁻¹] → X[S⁻¹] := + liftExpand (fun m s ↦ oreNum (c • 1) s • m /ₒ oreDenom (c • 1) s) (fun r t s ht ↦ by + dsimp only + rw [← mul_one (oreDenom (c • 1) s), ← oreDiv_smul_oreDiv, ← mul_one (oreDenom (c • 1) _), + ← oreDiv_smul_oreDiv, ← OreLocalization.expand]) + +/- Warning: This gives an diamond on `SMul R[S⁻¹] M[S⁻¹][S⁻¹]`, but we will almost never localize +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)] +instance [SMul R X] [SMul R M] [IsScalarTower R M X] [IsScalarTower R M M] : SMul R (X[S⁻¹]) where + smul := OreLocalization.hsmul + +@[to_additive] +theorem smul_oreDiv (r : R) (x : X) (s : S) : + r • (x /ₒ s) = oreNum (r • 1) s • x /ₒ oreDenom (r • 1) s := by with_unfolding_all rfl + +@[to_additive (attr := simp)] +theorem oreDiv_one_smul (r : M) (x : X[S⁻¹]) : (r /ₒ (1 : S)) • x = r • x := by + induction' x using OreLocalization.ind with r' s + rw [smul_oreDiv, oreDiv_smul_oreDiv, mul_one, smul_eq_mul, mul_one] + +@[to_additive] +theorem smul_one_smul (r : R) (x : X[S⁻¹]) : (r • 1 : M) • x = r • x := by + induction' x using OreLocalization.ind with r' s + simp only [smul_oreDiv, smul_eq_mul, mul_one] + +@[to_additive] +theorem smul_one_oreDiv_one_smul (r : R) (x : X[S⁻¹]) : + ((r • 1 : M) /ₒ (1 : S)) • x = r • x := by + rw [oreDiv_one_smul, smul_one_smul] + +@[to_additive] +instance : IsScalarTower R R' X[S⁻¹] where + smul_assoc r m x := by + rw [← smul_one_oreDiv_one_smul, ← smul_one_oreDiv_one_smul, ← smul_one_oreDiv_one_smul, + ← mul_smul, mul_div_one] + simp only [smul_eq_mul, mul_one, smul_mul_assoc, smul_assoc, one_mul] + +@[to_additive] +instance [SMulCommClass R R' M] : SMulCommClass R R' X[S⁻¹] where + smul_comm r m x := by + rw [← smul_one_smul m, ← smul_assoc, smul_comm, smul_assoc, smul_one_smul] + +@[to_additive] +instance : IsScalarTower R M[S⁻¹] X[S⁻¹] where + smul_assoc r m x := by + rw [← smul_one_oreDiv_one_smul, ← smul_one_oreDiv_one_smul, ← mul_smul, smul_eq_mul] + +@[to_additive] +instance [SMulCommClass R M M] : SMulCommClass R M[S⁻¹] X[S⁻¹] where + smul_comm r x y := by + induction' x using OreLocalization.ind with r₁ s₁ + induction' y using OreLocalization.ind with r₂ s₂ + rw [← smul_one_oreDiv_one_smul, ← smul_one_oreDiv_one_smul, smul_smul, smul_smul, + mul_div_one, oreDiv_mul_char _ _ _ _ (r • 1) s₁ (by simp), mul_one] + simp + +@[to_additive] +instance [SMul Rᵐᵒᵖ M] [SMul Rᵐᵒᵖ X] [IsScalarTower Rᵐᵒᵖ M M] [IsScalarTower Rᵐᵒᵖ M X] + [IsCentralScalar R M] : IsCentralScalar R X[S⁻¹] where + op_smul_eq_smul r x := by + rw [← smul_one_oreDiv_one_smul, ← smul_one_oreDiv_one_smul, op_smul_eq_smul] + +@[to_additive] +instance {R} [Monoid R] [MulAction R M] [IsScalarTower R M M] + [MulAction R X] [IsScalarTower R M X] : MulAction R X[S⁻¹] where + one_smul := OreLocalization.ind fun x s ↦ by + rw [← smul_one_oreDiv_one_smul, one_smul, ← OreLocalization.one_def, one_smul] + mul_smul s₁ s₂ x := by rw [← smul_eq_mul, smul_assoc] + +@[to_additive] +theorem smul_oreDiv_one (r : R) (x : X) : r • (x /ₒ (1 : S)) = (r • x) /ₒ (1 : S) := by + rw [← smul_one_oreDiv_one_smul, smul_div_one, smul_assoc, one_smul] + +end SMul + +section CommMonoid + +variable {R : Type*} [CommMonoid R] {S : Submonoid R} [OreSet S] + +@[to_additive] +theorem oreDiv_mul_oreDiv_comm {r₁ r₂ : R} {s₁ s₂ : S} : + r₁ /ₒ s₁ * (r₂ /ₒ s₂) = r₁ * r₂ /ₒ (s₁ * s₂) := by + rw [oreDiv_mul_char r₁ r₂ s₁ s₂ r₁ s₂ (by simp [mul_comm]), mul_comm s₂] + +@[to_additive] +instance : CommMonoid R[S⁻¹] where + mul_comm := fun x y => by + induction' x with r₁ s₁ + induction' y with r₂ s₂ + rw [oreDiv_mul_oreDiv_comm, oreDiv_mul_oreDiv_comm, mul_comm r₁, mul_comm s₁] + +end CommMonoid + +section Zero + +variable {R : Type*} [Monoid R] {S : Submonoid R} [OreSet S] {X : Type*} [Zero X] +variable [MulAction R X] + + +/-- `0` in the localization, defined as `0 /ₒ 1`. -/ +@[irreducible] +protected def zero : X[S⁻¹] := 0 /ₒ 1 + +instance : Zero X[S⁻¹] := + ⟨OreLocalization.zero⟩ + +protected theorem zero_def : (0 : X[S⁻¹]) = 0 /ₒ 1 := by + with_unfolding_all rfl + +end Zero + +end OreLocalization diff --git a/Mathlib/GroupTheory/OreLocalization/OreSet.lean b/Mathlib/GroupTheory/OreLocalization/OreSet.lean new file mode 100644 index 00000000000000..3f414ea7b61d12 --- /dev/null +++ b/Mathlib/GroupTheory/OreLocalization/OreSet.lean @@ -0,0 +1,120 @@ +/- +Copyright (c) 2022 Jakob von Raumer. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jakob von Raumer, Kevin Klinge +-/ +import Mathlib.Algebra.Group.Submonoid.Defs + +/-! + +# (Left) Ore sets + +This defines left Ore sets on arbitrary monoids. + +## References + +* https://ncatlab.org/nlab/show/Ore+set + +-/ + +namespace AddOreLocalization + +/-- A submonoid `S` of an additive monoid `R` is (left) Ore if common summands on the right can be +turned into common summands on the left, and if each pair of `r : R` and `s : S` admits an Ore +minuend `v : R` and an Ore subtrahend `u : S` such that `u + r = v + s`. -/ +class AddOreSet {R : Type*} [AddMonoid R] (S : AddSubmonoid R) where + /-- Common summands on the right can be turned into common summands on the left, a weak form of +cancellability. -/ + ore_right_cancel : ∀ (r₁ r₂ : R) (s : S), r₁ + s = r₂ + s → ∃ s' : S, s' + r₁ = s' + r₂ + /-- The Ore minuend of a difference. -/ + oreMin : R → S → R + /-- The Ore subtrahend of a difference. -/ + oreSubtra : R → S → S + /-- The Ore condition of a difference, expressed in terms of `oreMin` and `oreSubtra`. -/ + ore_eq : ∀ (r : R) (s : S), oreSubtra r s + r = oreMin r s + s + +end AddOreLocalization + +namespace OreLocalization + +section Monoid + +/-- A submonoid `S` of a monoid `R` is (left) Ore if common factors on the right can be turned +into common factors on the left, and if each pair of `r : R` and `s : S` admits an Ore numerator +`v : R` and an Ore denominator `u : S` such that `u * r = v * s`. -/ +@[to_additive AddOreLocalization.AddOreSet] +class OreSet {R : Type*} [Monoid R] (S : Submonoid R) where + /-- Common factors on the right can be turned into common factors on the left, a weak form of +cancellability. -/ + ore_right_cancel : ∀ (r₁ r₂ : R) (s : S), r₁ * s = r₂ * s → ∃ s' : S, s' * r₁ = s' * r₂ + /-- The Ore numerator of a fraction. -/ + oreNum : R → S → R + /-- The Ore denominator of a fraction. -/ + oreDenom : R → S → S + /-- The Ore condition of a fraction, expressed in terms of `oreNum` and `oreDenom`. -/ + ore_eq : ∀ (r : R) (s : S), oreDenom r s * r = oreNum r s * s + +-- TODO: use this once it's available. +-- run_cmd to_additive.map_namespace `OreLocalization `AddOreLocalization + +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] +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 + +/-- The Ore numerator of a fraction. -/ +@[to_additive AddOreLocalization.oreMin "The Ore minuend of a difference."] +def oreNum (r : R) (s : S) : R := + OreSet.oreNum r s + +/-- The Ore denominator of a fraction. -/ +@[to_additive AddOreLocalization.oreSubtra "The Ore subtrahend of a difference."] +def oreDenom (r : R) (s : S) : S := + OreSet.oreDenom r s + +/-- The Ore condition of a fraction, expressed in terms of `oreNum` and `oreDenom`. -/ +@[to_additive AddOreLocalization.add_ore_eq + "The Ore condition of a difference, expressed in terms of `oreMin` and `oreSubtra`."] +theorem ore_eq (r : R) (s : S) : oreDenom r s * r = oreNum r s * s := + OreSet.ore_eq r s + +/-- The Ore condition bundled in a sigma type. This is useful in situations where we want to obtain +both witnesses and the condition for a given fraction. -/ +@[to_additive AddOreLocalization.addOreCondition + "The Ore condition bundled in a sigma type. This is useful in situations where we want to obtain +both witnesses and the condition for a given difference."] +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] +instance oreSetBot : OreSet (⊥ : Submonoid R) where + ore_right_cancel _ _ s h := + ⟨s, by + rcases s with ⟨s, hs⟩ + rw [Submonoid.mem_bot] at hs + subst hs + rw [mul_one, mul_one] at h + subst h + rfl⟩ + oreNum r _ := r + oreDenom _ s := s + ore_eq _ s := by + rcases s with ⟨s, hs⟩ + rw [Submonoid.mem_bot] at hs + simp [hs] + +/-- Every submonoid of a commutative monoid is an Ore set. -/ +@[to_additive AddOreLocalization.addOreSetComm] +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 + oreDenom _ s := s + ore_eq r s := by rw [mul_comm] + +end Monoid + +end OreLocalization diff --git a/Mathlib/RingTheory/OreLocalization/Basic.lean b/Mathlib/RingTheory/OreLocalization/Basic.lean index 04732f2a57a298..2ae4ee073b5f84 100644 --- a/Mathlib/RingTheory/OreLocalization/Basic.lean +++ b/Mathlib/RingTheory/OreLocalization/Basic.lean @@ -4,20 +4,13 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Jakob von Raumer, Kevin Klinge, Andrew Yang -/ import Mathlib.Algebra.Group.Submonoid.DistribMulAction -import Mathlib.RingTheory.OreLocalization.OreSet +import Mathlib.GroupTheory.OreLocalization.Basic /-! # Localization over left Ore sets. -This file defines the localization of a monoid over a left Ore set and proves its universal -mapping property. - -## Notations - -Introduces the notation `R[S⁻¹]` for the Ore localization of a monoid `R` at a right Ore -subset `S`. Also defines a new heterogeneous division notation `r /ₒ s` for a numerator `r : R` and -a denominator `s : S`. +This file proves results on the localization of rings (monoids with zeros) over a left Ore set. ## References @@ -37,605 +30,6 @@ open OreLocalization 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 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 - iseqv := by - refine ⟨fun _ => ⟨1, 1, by simp⟩, ?_, ?_⟩ - · rintro ⟨r, s⟩ ⟨r', s'⟩ ⟨u, v, hru, hsu⟩; dsimp only at * - rcases oreCondition (s : R) s' with ⟨r₂, s₂, h₁⟩ - rcases oreCondition r₂ u with ⟨r₃, s₃, h₂⟩ - have : r₃ * v * s = s₃ * s₂ * s := by - -- Porting note: the proof used `assoc_rw` - rw [mul_assoc _ (s₂ : R), h₁, ← mul_assoc, h₂, mul_assoc, ← hsu, ← mul_assoc] - rcases ore_right_cancel (r₃ * v) (s₃ * s₂) s this with ⟨w, hw⟩ - refine ⟨w * (s₃ * s₂), w * (r₃ * u), ?_, ?_⟩ <;> - simp only [Submonoid.coe_mul, Submonoid.smul_def, ← hw] - · simp only [mul_smul, hru, ← Submonoid.smul_def] - · simp only [mul_assoc, hsu] - · rintro ⟨r₁, s₁⟩ ⟨r₂, s₂⟩ ⟨r₃, s₃⟩ ⟨u, v, hur₁, hs₁u⟩ ⟨u', v', hur₂, hs₂u⟩ - rcases oreCondition v' u with ⟨r', s', h⟩; dsimp only at * - refine ⟨s' * u', r' * v, ?_, ?_⟩ <;> - simp only [Submonoid.smul_def, Submonoid.coe_mul, mul_smul, mul_assoc] at * - · rw [hur₂, smul_smul, h, mul_smul, hur₁] - · rw [hs₂u, ← mul_assoc, h, mul_assoc, hs₁u] - -end OreLocalization - -/-- The Ore localization of a monoid and a submonoid fulfilling the Ore condition. -/ -@[to_additive AddOreLocalization "The Ore localization of an additive monoid and a submonoid -fulfilling the Ore condition."] -def OreLocalization {R : Type*} [Monoid R] (S : Submonoid R) [OreSet S] - (X : Type*) [MulAction R X] := - Quotient (OreLocalization.oreEqv S X) - -namespace OreLocalization - -section Monoid - -variable (R : Type*) [Monoid R] (S : Submonoid R) [OreSet S] - -@[inherit_doc OreLocalization] -scoped syntax:1075 term noWs atomic("[" term "⁻¹" noWs "]") : term -macro_rules | `($R[$S⁻¹]) => ``(OreLocalization $S $R) - -attribute [local instance] oreEqv - -variable {R S} -variable {X} [MulAction R X] - -/-- The division in the Ore localization `X[S⁻¹]`, as a fraction of an element of `X` and `S`. -/ -@[to_additive "The subtraction in the Ore localization, -as a difference of an element of `X` and `S`."] -def oreDiv (r : X) (s : S) : X[S⁻¹] := - Quotient.mk' (r, s) - -@[inherit_doc] -infixl:70 " /ₒ " => oreDiv - -@[inherit_doc] -infixl:65 " -ₒ " => _root_.AddOreLocalization.oreSub - -@[to_additive (attr := elab_as_elim, cases_eliminator, induction_eliminator)] -protected theorem ind {β : X[S⁻¹] → Prop} - (c : ∀ (r : X) (s : S), β (r /ₒ s)) : ∀ q, β q := by - apply Quotient.ind - rintro ⟨r, s⟩ - exact c r s - -@[to_additive] -theorem oreDiv_eq_iff {r₁ r₂ : X} {s₁ s₂ : S} : - r₁ /ₒ s₁ = r₂ /ₒ s₂ ↔ ∃ (u : S) (v : R), u • r₂ = v • r₁ ∧ u * s₂ = v * s₁ := - Quotient.eq'' - -/-- A fraction `r /ₒ s` is equal to its expansion by an arbitrary factor `t` if `t * s ∈ S`. -/ -@[to_additive "A difference `r -ₒ s` is equal to its expansion by an -arbitrary translation `t` if `t + s ∈ S`."] -protected theorem expand (r : X) (s : S) (t : R) (hst : t * (s : R) ∈ S) : - r /ₒ s = t • r /ₒ ⟨t * s, hst⟩ := by - apply Quotient.sound - exact ⟨s, s * t, by rw [mul_smul, Submonoid.smul_def], by rw [← mul_assoc]⟩ - -/-- A fraction is equal to its expansion by a factor from `S`. -/ -@[to_additive "A difference is equal to its expansion by a summand from `S`."] -protected theorem expand' (r : X) (s s' : S) : r /ₒ s = s' • r /ₒ (s' * s) := - OreLocalization.expand r s s' (by norm_cast; apply SetLike.coe_mem) - -/-- Fractions which differ by a factor of the numerator can be proven equal if -those factors expand to equal elements of `R`. -/ -@[to_additive "Differences whose minuends differ by a common summand can be proven equal if -those summands expand to equal elements of `R`."] -protected theorem eq_of_num_factor_eq {r r' r₁ r₂ : R} {s t : S} (h : t * r = t * r') : - r₁ * r * r₂ /ₒ s = r₁ * r' * r₂ /ₒ s := by - rcases oreCondition r₁ t with ⟨r₁', t', hr₁⟩ - rw [OreLocalization.expand' _ s t', OreLocalization.expand' _ s t'] - congr 1 - -- Porting note (#11215): TODO: use `assoc_rw`? - calc (t' : R) * (r₁ * r * r₂) - = t' * r₁ * r * r₂ := by simp [← mul_assoc] - _ = r₁' * t * r * r₂ := by rw [hr₁] - _ = r₁' * (t * r) * r₂ := by simp [← mul_assoc] - _ = r₁' * (t * r') * r₂ := by rw [h] - _ = r₁' * t * r' * r₂ := by simp [← mul_assoc] - _ = t' * r₁ * r' * r₂ := by rw [hr₁] - _ = t' * (r₁ * r' * r₂) := by simp [← mul_assoc] - -/-- A function or predicate over `X` and `S` can be lifted to `X[S⁻¹]` if it is invariant -under expansion on the left. -/ -@[to_additive "A function or predicate over `X` and `S` can be lifted to the localizaton if it is -invariant under expansion on the left."] -def liftExpand {C : Sort*} (P : X → S → C) - (hP : ∀ (r : X) (t : R) (s : S) (ht : t * s ∈ S), P r s = P (t • r) ⟨t * s, ht⟩) : - X[S⁻¹] → C := - Quotient.lift (fun p : X × S => P p.1 p.2) fun (r₁, s₁) (r₂, s₂) ⟨u, v, hr₂, hs₂⟩ => by - dsimp at * - have s₁vS : v * s₁ ∈ S := by - rw [← hs₂, ← S.coe_mul] - exact SetLike.coe_mem (u * s₂) - replace hs₂ : u * s₂ = ⟨_, s₁vS⟩ := by ext; simp [hs₂] - rw [hP r₁ v s₁ s₁vS, hP r₂ u s₂ (by norm_cast; rwa [hs₂]), ← hr₂] - simp only [← hs₂]; rfl - -@[to_additive (attr := simp)] -theorem liftExpand_of {C : Sort*} {P : X → S → C} - {hP : ∀ (r : X) (t : R) (s : S) (ht : t * s ∈ S), P r s = P (t • r) ⟨t * s, ht⟩} (r : X) - (s : S) : liftExpand P hP (r /ₒ s) = P r s := - rfl - -/-- A version of `liftExpand` used to simultaneously lift functions with two arguments -in `X[S⁻¹]`. -/ -@[to_additive "A version of `liftExpand` used to simultaneously lift functions with two arguments"] -def lift₂Expand {C : Sort*} (P : X → S → X → S → C) - (hP : - ∀ (r₁ : X) (t₁ : R) (s₁ : S) (ht₁ : t₁ * s₁ ∈ S) (r₂ : X) (t₂ : R) (s₂ : S) - (ht₂ : t₂ * s₂ ∈ S), - P r₁ s₁ r₂ s₂ = P (t₁ • r₁) ⟨t₁ * s₁, ht₁⟩ (t₂ • r₂) ⟨t₂ * s₂, ht₂⟩) : - X[S⁻¹] → X[S⁻¹] → C := - liftExpand - (fun r₁ s₁ => liftExpand (P r₁ s₁) fun r₂ t₂ s₂ ht₂ => by - have := hP r₁ 1 s₁ (by simp) r₂ t₂ s₂ ht₂ - simp [this]) - fun r₁ t₁ s₁ ht₁ => by - ext x; induction' x with r₂ s₂ - dsimp only - rw [liftExpand_of, liftExpand_of, hP r₁ t₁ s₁ ht₁ r₂ 1 s₂ (by simp)]; simp - -@[to_additive (attr := simp)] -theorem lift₂Expand_of {C : Sort*} {P : X → S → X → S → C} - {hP : - ∀ (r₁ : X) (t₁ : R) (s₁ : S) (ht₁ : t₁ * s₁ ∈ S) (r₂ : X) (t₂ : R) (s₂ : S) - (ht₂ : t₂ * s₂ ∈ S), - P r₁ s₁ r₂ s₂ = P (t₁ • r₁) ⟨t₁ * s₁, ht₁⟩ (t₂ • r₂) ⟨t₂ * s₂, ht₂⟩} - (r₁ : X) (s₁ : S) (r₂ : X) (s₂ : S) : lift₂Expand P hP (r₁ /ₒ s₁) (r₂ /ₒ s₂) = P r₁ s₁ r₂ s₂ := - rfl - -@[to_additive] -private def smul' (r₁ : R) (s₁ : S) (r₂ : X) (s₂ : S) : X[S⁻¹] := - oreNum r₁ s₂ • r₂ /ₒ (oreDenom r₁ s₂ * s₁) - -@[to_additive] -private theorem smul'_char (r₁ : R) (r₂ : X) (s₁ s₂ : S) (u : S) (v : R) (huv : u * r₁ = v * s₂) : - OreLocalization.smul' r₁ s₁ r₂ s₂ = v • r₂ /ₒ (u * s₁) := by - -- Porting note: `assoc_rw` was not ported yet - simp only [smul'] - have h₀ := ore_eq r₁ s₂; set v₀ := oreNum r₁ s₂; set u₀ := oreDenom r₁ s₂ - rcases oreCondition (u₀ : R) u with ⟨r₃, s₃, h₃⟩ - have := - calc - r₃ * v * s₂ = r₃ * (u * r₁) := by rw [mul_assoc, ← huv] - _ = s₃ * (u₀ * r₁) := by rw [← mul_assoc, ← mul_assoc, h₃] - _ = s₃ * v₀ * s₂ := by rw [mul_assoc, h₀] - rcases ore_right_cancel _ _ _ this with ⟨s₄, hs₄⟩ - symm; rw [oreDiv_eq_iff] - use s₄ * s₃ - use s₄ * r₃ - simp only [Submonoid.coe_mul, Submonoid.smul_def, smul_eq_mul] - constructor - · rw [smul_smul, mul_assoc (c := v₀), ← hs₄] - simp only [smul_smul, mul_assoc] - · rw [← mul_assoc (b := (u₀ : R)), mul_assoc (c := (u₀ : R)), h₃] - simp only [mul_assoc] - -/-- The multiplication on the Ore localization of monoids. -/ -@[to_additive] -private def 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₁⟩ - rw [smul'_char _ _ _ _ _ _ h₁] - rcases oreCondition r ⟨_, hs⟩ with ⟨r₂', s₂', h₂⟩ - rw [smul'_char _ _ _ _ _ _ h₂] - rcases oreCondition (s₁' : R) (s₂') with ⟨r₃', s₃', h₃⟩ - have : s₃' * r₁' * s' = (r₃' * r₂' * r₂) * s' := by - rw [mul_assoc, ← h₁, ← mul_assoc, h₃, mul_assoc, h₂] - simp [mul_assoc] - rcases ore_right_cancel _ _ _ this with ⟨s₄', h₄⟩ - have : (s₄' * r₃') * (s₂' * s) ∈ S := by - rw [mul_assoc, ← mul_assoc r₃', ← h₃] - exact (s₄' * (s₃' * s₁' * s)).2 - rw [OreLocalization.expand' _ _ (s₄' * s₃'), OreLocalization.expand _ (s₂' * s) _ this] - simp only [Submonoid.smul_def, Submonoid.coe_mul, smul_smul, mul_assoc, h₄] - congr 1 - ext; simp only [Submonoid.coe_mul, ← mul_assoc] - rw [mul_assoc (s₄' : R), h₃, ← mul_assoc] - -/-- The scalar multiplication on the Ore localization of monoids. -/ -@[to_additive (attr := irreducible) - "the vector addition on the Ore localization of additive monoids."] -protected def smul : R[S⁻¹] → X[S⁻¹] → X[S⁻¹] := - liftExpand smul'' fun r₁ r₂ s hs => by - ext x - induction' x with x s₂ - show OreLocalization.smul' r₁ s x s₂ = OreLocalization.smul' (r₂ * r₁) ⟨_, hs⟩ x s₂ - rcases oreCondition r₁ s₂ with ⟨r₁', s₁', h₁⟩ - rw [smul'_char _ _ _ _ _ _ h₁] - rcases oreCondition (r₂ * r₁) s₂ with ⟨r₂', s₂', h₂⟩ - rw [smul'_char _ _ _ _ _ _ h₂] - rcases oreCondition (s₂' * r₂) (s₁') with ⟨r₃', s₃', h₃⟩ - have : s₃' * r₂' * s₂ = r₃' * r₁' * s₂ := by - rw [mul_assoc, ← h₂, ← mul_assoc _ r₂, ← mul_assoc, h₃, mul_assoc, h₁, mul_assoc] - rcases ore_right_cancel _ _ _ this with ⟨s₄', h₄⟩ - have : (s₄' * r₃') * (s₁' * s) ∈ S := by - rw [← mul_assoc, mul_assoc _ r₃', ← h₃, ← mul_assoc, ← mul_assoc, mul_assoc] - exact mul_mem (s₄' * s₃' * s₂').2 hs - rw [OreLocalization.expand' (r₂' • x) _ (s₄' * s₃'), OreLocalization.expand _ _ _ this] - simp only [Submonoid.smul_def, Submonoid.coe_mul, smul_smul, mul_assoc, h₄] - congr 1 - ext; simp only [Submonoid.coe_mul, ← mul_assoc] - rw [mul_assoc _ r₃', ← h₃, ← mul_assoc, ← mul_assoc] - -@[to_additive] -instance : SMul R[S⁻¹] X[S⁻¹] := - ⟨OreLocalization.smul⟩ - -@[to_additive] -instance : Mul R[S⁻¹] := - ⟨OreLocalization.smul⟩ - -@[to_additive] -theorem oreDiv_smul_oreDiv {r₁ : R} {r₂ : X} {s₁ s₂ : S} : - (r₁ /ₒ s₁) • (r₂ /ₒ s₂) = oreNum r₁ s₂ • r₂ /ₒ (oreDenom r₁ s₂ * s₁) := by - with_unfolding_all rfl - -@[to_additive] -theorem oreDiv_mul_oreDiv {r₁ : R} {r₂ : R} {s₁ s₂ : S} : - (r₁ /ₒ s₁) * (r₂ /ₒ s₂) = oreNum r₁ s₂ * r₂ /ₒ (oreDenom r₁ s₂ * s₁) := by - with_unfolding_all rfl - -/-- A characterization lemma for the scalar multiplication on the Ore localization, -allowing for a choice of Ore numerator and Ore denominator. -/ -@[to_additive "A characterization lemma for the vector addition on the Ore localization, -allowing for a choice of Ore minuend and Ore subtrahend."] -theorem oreDiv_smul_char (r₁ : R) (r₂ : X) (s₁ s₂ : S) (r' : R) (s' : S) (huv : s' * r₁ = r' * s₂) : - (r₁ /ₒ s₁) • (r₂ /ₒ s₂) = r' • r₂ /ₒ (s' * s₁) := by - with_unfolding_all exact smul'_char r₁ r₂ s₁ s₂ s' r' huv - -/-- A characterization lemma for the multiplication on the Ore localization, allowing for a choice -of Ore numerator and Ore denominator. -/ -@[to_additive "A characterization lemma for the addition on the Ore localization, -allowing for a choice of Ore minuend and Ore subtrahend."] -theorem oreDiv_mul_char (r₁ r₂ : R) (s₁ s₂ : S) (r' : R) (s' : S) (huv : s' * r₁ = r' * s₂) : - r₁ /ₒ s₁ * (r₂ /ₒ s₂) = r' * r₂ /ₒ (s' * s₁) := by - with_unfolding_all exact smul'_char r₁ r₂ s₁ s₂ s' r' huv - -/-- Another characterization lemma for the scalar multiplication on the Ore localizaion delivering -Ore witnesses and conditions bundled in a sigma type. -/ -@[to_additive "Another characterization lemma for the vector addition on the - Ore localizaion delivering Ore witnesses and conditions bundled in a sigma type."] -def oreDivSMulChar' (r₁ : R) (r₂ : X) (s₁ s₂ : S) : - Σ'r' : R, Σ's' : S, s' * r₁ = r' * s₂ ∧ (r₁ /ₒ s₁) • (r₂ /ₒ s₂) = r' • r₂ /ₒ (s' * s₁) := - ⟨oreNum r₁ s₂, oreDenom r₁ s₂, ore_eq r₁ s₂, oreDiv_smul_oreDiv⟩ - -/-- Another characterization lemma for the multiplication on the Ore localizaion delivering -Ore witnesses and conditions bundled in a sigma type. -/ -@[to_additive "Another characterization lemma for the addition on the Ore localizaion delivering - Ore witnesses and conditions bundled in a sigma type."] -def oreDivMulChar' (r₁ r₂ : R) (s₁ s₂ : S) : - Σ'r' : R, Σ's' : S, s' * r₁ = r' * s₂ ∧ r₁ /ₒ s₁ * (r₂ /ₒ s₂) = r' * r₂ /ₒ (s' * s₁) := - ⟨oreNum r₁ s₂, oreDenom r₁ s₂, ore_eq r₁ s₂, oreDiv_mul_oreDiv⟩ - -/-- `1` in the localization, defined as `1 /ₒ 1`. -/ -@[to_additive (attr := irreducible) "`0` in the additive localization, defined as `0 -ₒ 0`."] -protected def one : R[S⁻¹] := 1 /ₒ 1 - -@[to_additive] -instance : One R[S⁻¹] := - ⟨OreLocalization.one⟩ - -@[to_additive] -protected theorem one_def : (1 : R[S⁻¹]) = 1 /ₒ 1 := by - with_unfolding_all rfl - -@[to_additive] -instance : Inhabited R[S⁻¹] := - ⟨1⟩ - -@[to_additive (attr := simp)] -protected theorem div_eq_one' {r : R} (hr : r ∈ S) : r /ₒ ⟨r, hr⟩ = 1 := by - rw [OreLocalization.one_def, oreDiv_eq_iff] - exact ⟨⟨r, hr⟩, 1, by simp, by simp⟩ - -@[to_additive (attr := simp)] -protected theorem div_eq_one {s : S} : (s : R) /ₒ s = 1 := - OreLocalization.div_eq_one' _ - -@[to_additive] -protected theorem one_smul (x : X[S⁻¹]) : (1 : R[S⁻¹]) • x = x := by - induction' x with r s - simp [OreLocalization.one_def, oreDiv_smul_char 1 r 1 s 1 s (by simp)] - -@[to_additive] -protected theorem one_mul (x : R[S⁻¹]) : 1 * x = x := - OreLocalization.one_smul x - -@[to_additive] -protected theorem mul_one (x : R[S⁻¹]) : x * 1 = x := by - induction' x with r s - simp [OreLocalization.one_def, oreDiv_mul_char r (1 : R) s (1 : S) r 1 (by simp)] - -@[to_additive] -protected theorem mul_smul (x y : R[S⁻¹]) (z : X[S⁻¹]) : (x * y) • z = x • y • z := by - -- Porting note: `assoc_rw` was not ported yet - induction' x with r₁ s₁ - induction' y with r₂ s₂ - induction' z with r₃ s₃ - rcases oreDivMulChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha' - rcases oreDivSMulChar' r₂ r₃ s₂ s₃ with ⟨rb, sb, hb, hb'⟩; rw [hb']; clear hb' - rcases oreCondition ra sb with ⟨rc, sc, hc⟩ - rw [oreDiv_smul_char (ra * r₂) r₃ (sa * s₁) s₃ (rc * rb) sc]; swap - · rw [← mul_assoc _ ra, hc, mul_assoc, hb, ← mul_assoc] - rw [← mul_assoc, mul_smul] - symm; apply oreDiv_smul_char - rw [Submonoid.coe_mul, Submonoid.coe_mul, ← mul_assoc, ← hc, mul_assoc _ ra, ← ha, mul_assoc] - -@[to_additive] -protected theorem mul_assoc (x y z : R[S⁻¹]) : x * y * z = x * (y * z) := - OreLocalization.mul_smul x y z - -/-- `npow` of `OreLocalization` -/ -@[to_additive (attr := irreducible) "`nsmul` of `AddOreLocalization`"] -protected def npow : ℕ → R[S⁻¹] → R[S⁻¹] := npowRec - -unseal OreLocalization.npow in -@[to_additive] -instance : Monoid R[S⁻¹] where - one_mul := OreLocalization.one_mul - mul_one := OreLocalization.mul_one - mul_assoc := OreLocalization.mul_assoc - npow := OreLocalization.npow - -@[to_additive] -instance instMulActionOreLocalization : MulAction R[S⁻¹] X[S⁻¹] where - one_smul := OreLocalization.one_smul - mul_smul := OreLocalization.mul_smul - -@[to_additive] -protected theorem mul_inv (s s' : S) : ((s : R) /ₒ s') * ((s' : R) /ₒ s) = 1 := by - simp [oreDiv_mul_char (s : R) s' s' s 1 1 (by simp)] - -@[to_additive (attr := simp)] -protected theorem one_div_smul {r : X} {s t : S} : ((1 : R) /ₒ t) • (r /ₒ s) = r /ₒ (s * t) := by - simp [oreDiv_smul_char 1 r t s 1 s (by simp)] - -@[to_additive (attr := simp)] -protected theorem one_div_mul {r : R} {s t : S} : (1 /ₒ t) * (r /ₒ s) = r /ₒ (s * t) := by - simp [oreDiv_mul_char 1 r t s 1 s (by simp)] - -@[to_additive (attr := simp)] -protected theorem smul_cancel {r : X} {s t : S} : ((s : R) /ₒ t) • (r /ₒ s) = r /ₒ t := by - simp [oreDiv_smul_char s.1 r t s 1 1 (by simp)] - -@[to_additive (attr := simp)] -protected theorem mul_cancel {r : R} {s t : S} : ((s : R) /ₒ t) * (r /ₒ s) = r /ₒ t := by - simp [oreDiv_mul_char s.1 r t s 1 1 (by simp)] - -@[to_additive (attr := simp)] -protected theorem smul_cancel' {r₁ : R} {r₂ : X} {s t : S} : - ((r₁ * s) /ₒ t) • (r₂ /ₒ s) = (r₁ • r₂) /ₒ t := by - simp [oreDiv_smul_char (r₁ * s) r₂ t s r₁ 1 (by simp)] - -@[to_additive (attr := simp)] -protected theorem mul_cancel' {r₁ r₂ : R} {s t : S} : - ((r₁ * s) /ₒ t) * (r₂ /ₒ s) = (r₁ * r₂) /ₒ t := by - simp [oreDiv_mul_char (r₁ * s) r₂ t s r₁ 1 (by simp)] - -@[to_additive (attr := simp)] -theorem smul_div_one {p : R} {r : X} {s : S} : (p /ₒ s) • (r /ₒ 1) = (p • r) /ₒ s := by - simp [oreDiv_smul_char p r s 1 p 1 (by simp)] - -@[to_additive (attr := simp)] -theorem mul_div_one {p r : R} {s : S} : (p /ₒ s) * (r /ₒ 1) = (p * r) /ₒ s := by - --TODO use coercion r ↦ r /ₒ 1 - simp [oreDiv_mul_char p r s 1 p 1 (by simp)] - -/-- The fraction `s /ₒ 1` as a unit in `R[S⁻¹]`, where `s : S`. -/ -@[to_additive "The difference `s -ₒ 0` as a an additive unit."] -def numeratorUnit (s : S) : Units R[S⁻¹] where - val := (s : R) /ₒ 1 - inv := (1 : R) /ₒ s - val_inv := OreLocalization.mul_inv s 1 - inv_val := OreLocalization.mul_inv 1 s - -/-- The multiplicative homomorphism from `R` to `R[S⁻¹]`, mapping `r : R` to the -fraction `r /ₒ 1`. -/ -@[to_additive "The additive homomorphism from `R` to `AddOreLocalization R S`, - mapping `r : R` to the difference `r -ₒ 0`."] -def numeratorHom : R →* R[S⁻¹] where - toFun r := r /ₒ 1 - map_one' := by with_unfolding_all rfl - map_mul' _ _ := mul_div_one.symm - -@[to_additive] -theorem numeratorHom_apply {r : R} : numeratorHom r = r /ₒ (1 : S) := - rfl - -@[to_additive] -theorem numerator_isUnit (s : S) : IsUnit (numeratorHom (s : R) : R[S⁻¹]) := - ⟨numeratorUnit s, rfl⟩ - -section UMP - -variable {T : Type*} [Monoid T] -variable (f : R →* T) (fS : S →* Units T) - -/-- The universal lift from a morphism `R →* T`, which maps elements of `S` to units of `T`, -to a morphism `R[S⁻¹] →* T`. -/ -@[to_additive "The universal lift from a morphism `R →+ T`, which maps elements of `S` to - additive-units of `T`, to a morphism `AddOreLocalization R S →+ T`."] -def universalMulHom (hf : ∀ s : S, f s = fS s) : R[S⁻¹] →* T where - -- Porting note(#12129): additional beta reduction needed - toFun x := - x.liftExpand (fun r s => ((fS s)⁻¹ : Units T) * f r) fun r t s ht => by - simp only [smul_eq_mul] - have : (fS ⟨t * s, ht⟩ : T) = f t * fS s := by - simp only [← hf, MonoidHom.map_mul] - conv_rhs => - rw [MonoidHom.map_mul, ← one_mul (f r), ← Units.val_one, ← mul_inv_cancel (fS s)] - rw [Units.val_mul, mul_assoc, ← mul_assoc _ (fS s : T), ← this, ← mul_assoc] - simp only [one_mul, Units.inv_mul] - map_one' := by beta_reduce; rw [OreLocalization.one_def, liftExpand_of]; simp - map_mul' x y := by - -- Porting note: `simp only []` required, not just for beta reductions - beta_reduce - simp only [] -- TODO more! - induction' x with r₁ s₁ - induction' y with r₂ s₂ - rcases oreDivMulChar' r₁ r₂ s₁ s₂ with ⟨ra, sa, ha, ha'⟩; rw [ha']; clear ha' - rw [liftExpand_of, liftExpand_of, liftExpand_of, Units.inv_mul_eq_iff_eq_mul, map_mul, map_mul, - Units.val_mul, mul_assoc, ← mul_assoc (fS s₁ : T), ← mul_assoc (fS s₁ : T), Units.mul_inv, - one_mul, ← hf, ← mul_assoc, ← map_mul _ _ r₁, ha, map_mul, hf s₂, mul_assoc, - ← mul_assoc (fS s₂ : T), (fS s₂).mul_inv, one_mul] - -variable (hf : ∀ s : S, f s = fS s) - -@[to_additive] -theorem universalMulHom_apply {r : R} {s : S} : - universalMulHom f fS hf (r /ₒ s) = ((fS s)⁻¹ : Units T) * f r := - rfl - -@[to_additive] -theorem universalMulHom_commutes {r : R} : universalMulHom f fS hf (numeratorHom r) = f r := by - simp [numeratorHom_apply, universalMulHom_apply] - -/-- The universal morphism `universalMulHom` is unique. -/ -@[to_additive "The universal morphism `universalAddHom` is unique."] -theorem universalMulHom_unique (φ : R[S⁻¹] →* T) (huniv : ∀ r : R, φ (numeratorHom r) = f r) : - φ = universalMulHom f fS hf := by - ext x; induction' x with r s - rw [universalMulHom_apply, ← huniv r, numeratorHom_apply, ← one_mul (φ (r /ₒ s)), ← - Units.val_one, ← inv_mul_cancel (fS s), Units.val_mul, mul_assoc, ← hf, ← huniv, ← φ.map_mul, - numeratorHom_apply, OreLocalization.mul_cancel] - -end UMP - -end Monoid - -section SMul - -variable {R R' M X : Type*} [Monoid M] {S : Submonoid M} [OreSet S] [MulAction M X] -variable [SMul R X] [SMul R M] [IsScalarTower R M M] [IsScalarTower R M X] -variable [SMul R' X] [SMul R' M] [IsScalarTower R' M M] [IsScalarTower R' M X] -variable [SMul R R'] [IsScalarTower R R' M] - -/-- Scalar multiplication in a monoid localization. -/ -@[to_additive (attr := irreducible) "Vector addition in an additive monoid localization."] -protected def hsmul (c : R) : - X[S⁻¹] → X[S⁻¹] := - liftExpand (fun m s ↦ oreNum (c • 1) s • m /ₒ oreDenom (c • 1) s) (fun r t s ht ↦ by - dsimp only - rw [← mul_one (oreDenom (c • 1) s), ← oreDiv_smul_oreDiv, ← mul_one (oreDenom (c • 1) _), - ← oreDiv_smul_oreDiv, ← OreLocalization.expand]) - -/- Warning: This gives an diamond on `SMul R[S⁻¹] M[S⁻¹][S⁻¹]`, but we will almost never localize -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)] -instance [SMul R X] [SMul R M] [IsScalarTower R M X] [IsScalarTower R M M] : SMul R (X[S⁻¹]) where - smul := OreLocalization.hsmul - -@[to_additive] -theorem smul_oreDiv (r : R) (x : X) (s : S) : - r • (x /ₒ s) = oreNum (r • 1) s • x /ₒ oreDenom (r • 1) s := by with_unfolding_all rfl - -@[to_additive (attr := simp)] -theorem oreDiv_one_smul (r : M) (x : X[S⁻¹]) : (r /ₒ (1 : S)) • x = r • x := by - induction' x using OreLocalization.ind with r' s - rw [smul_oreDiv, oreDiv_smul_oreDiv, mul_one, smul_eq_mul, mul_one] - -@[to_additive] -theorem smul_one_smul (r : R) (x : X[S⁻¹]) : (r • 1 : M) • x = r • x := by - induction' x using OreLocalization.ind with r' s - simp only [smul_oreDiv, smul_eq_mul, mul_one] - -@[to_additive] -theorem smul_one_oreDiv_one_smul (r : R) (x : X[S⁻¹]) : - ((r • 1 : M) /ₒ (1 : S)) • x = r • x := by - rw [oreDiv_one_smul, smul_one_smul] - -@[to_additive] -instance : IsScalarTower R R' X[S⁻¹] where - smul_assoc r m x := by - rw [← smul_one_oreDiv_one_smul, ← smul_one_oreDiv_one_smul, ← smul_one_oreDiv_one_smul, - ← mul_smul, mul_div_one] - simp only [smul_eq_mul, mul_one, smul_mul_assoc, smul_assoc, one_mul] - -@[to_additive] -instance [SMulCommClass R R' M] : SMulCommClass R R' X[S⁻¹] where - smul_comm r m x := by - rw [← smul_one_smul m, ← smul_assoc, smul_comm, smul_assoc, smul_one_smul] - -@[to_additive] -instance : IsScalarTower R M[S⁻¹] X[S⁻¹] where - smul_assoc r m x := by - rw [← smul_one_oreDiv_one_smul, ← smul_one_oreDiv_one_smul, ← mul_smul, smul_eq_mul] - -@[to_additive] -instance [SMulCommClass R M M] : SMulCommClass R M[S⁻¹] X[S⁻¹] where - smul_comm r x y := by - induction' x using OreLocalization.ind with r₁ s₁ - induction' y using OreLocalization.ind with r₂ s₂ - rw [← smul_one_oreDiv_one_smul, ← smul_one_oreDiv_one_smul, smul_smul, smul_smul, - mul_div_one, oreDiv_mul_char _ _ _ _ (r • 1) s₁ (by simp), mul_one] - simp - -@[to_additive] -instance [SMul Rᵐᵒᵖ M] [SMul Rᵐᵒᵖ X] [IsScalarTower Rᵐᵒᵖ M M] [IsScalarTower Rᵐᵒᵖ M X] - [IsCentralScalar R M] : IsCentralScalar R X[S⁻¹] where - op_smul_eq_smul r x := by - rw [← smul_one_oreDiv_one_smul, ← smul_one_oreDiv_one_smul, op_smul_eq_smul] - -@[to_additive] -instance {R} [Monoid R] [MulAction R M] [IsScalarTower R M M] - [MulAction R X] [IsScalarTower R M X] : MulAction R X[S⁻¹] where - one_smul := OreLocalization.ind fun x s ↦ by - rw [← smul_one_oreDiv_one_smul, one_smul, ← OreLocalization.one_def, one_smul] - mul_smul s₁ s₂ x := by rw [← smul_eq_mul, smul_assoc] - -@[to_additive] -theorem smul_oreDiv_one (r : R) (x : X) : r • (x /ₒ (1 : S)) = (r • x) /ₒ (1 : S) := by - rw [← smul_one_oreDiv_one_smul, smul_div_one, smul_assoc, one_smul] - -end SMul - -section CommMonoid - -variable {R : Type*} [CommMonoid R] {S : Submonoid R} [OreSet S] - -@[to_additive] -theorem oreDiv_mul_oreDiv_comm {r₁ r₂ : R} {s₁ s₂ : S} : - r₁ /ₒ s₁ * (r₂ /ₒ s₂) = r₁ * r₂ /ₒ (s₁ * s₂) := by - rw [oreDiv_mul_char r₁ r₂ s₁ s₂ r₁ s₂ (by simp [mul_comm]), mul_comm s₂] - -@[to_additive] -instance : CommMonoid R[S⁻¹] where - mul_comm := fun x y => by - induction' x with r₁ s₁ - induction' y with r₂ s₂ - rw [oreDiv_mul_oreDiv_comm, oreDiv_mul_oreDiv_comm, mul_comm r₁, mul_comm s₁] - -end CommMonoid - -section Zero - -variable {R : Type*} [Monoid R] {S : Submonoid R} [OreSet S] {X : Type*} [Zero X] -variable [MulAction R X] - - -/-- `0` in the localization, defined as `0 /ₒ 1`. -/ -@[irreducible] -protected def zero : X[S⁻¹] := 0 /ₒ 1 - -instance : Zero X[S⁻¹] := - ⟨OreLocalization.zero⟩ - -protected theorem zero_def : (0 : X[S⁻¹]) = 0 /ₒ 1 := by - with_unfolding_all rfl - -end Zero - section MonoidWithZero variable {R : Type*} [MonoidWithZero R] {S : Submonoid R} [OreSet S] diff --git a/Mathlib/RingTheory/OreLocalization/OreSet.lean b/Mathlib/RingTheory/OreLocalization/OreSet.lean index bbb8931b5454b1..27bf74cc46864b 100644 --- a/Mathlib/RingTheory/OreLocalization/OreSet.lean +++ b/Mathlib/RingTheory/OreLocalization/OreSet.lean @@ -6,12 +6,13 @@ Authors: Jakob von Raumer, Kevin Klinge import Mathlib.Algebra.Group.Submonoid.Defs import Mathlib.Algebra.GroupWithZero.Basic import Mathlib.Algebra.Ring.Regular +import Mathlib.GroupTheory.OreLocalization.OreSet /-! -# (Left) Ore sets +# (Left) Ore sets and rings -This defines left Ore sets on arbitrary monoids. +This file contains results on left Ore sets for rings and monoids with zero. ## References @@ -19,106 +20,8 @@ This defines left Ore sets on arbitrary monoids. -/ -namespace AddOreLocalization - -/-- A submonoid `S` of an additive monoid `R` is (left) Ore if common summands on the right can be -turned into common summands on the left, and if each pair of `r : R` and `s : S` admits an Ore -minuend `v : R` and an Ore subtrahend `u : S` such that `u + r = v + s`. -/ -class AddOreSet {R : Type*} [AddMonoid R] (S : AddSubmonoid R) where - /-- Common summands on the right can be turned into common summands on the left, a weak form of -cancellability. -/ - ore_right_cancel : ∀ (r₁ r₂ : R) (s : S), r₁ + s = r₂ + s → ∃ s' : S, s' + r₁ = s' + r₂ - /-- The Ore minuend of a difference. -/ - oreMin : R → S → R - /-- The Ore subtrahend of a difference. -/ - oreSubtra : R → S → S - /-- The Ore condition of a difference, expressed in terms of `oreMin` and `oreSubtra`. -/ - ore_eq : ∀ (r : R) (s : S), oreSubtra r s + r = oreMin r s + s - -end AddOreLocalization - namespace OreLocalization -section Monoid - -/-- A submonoid `S` of a monoid `R` is (left) Ore if common factors on the right can be turned -into common factors on the left, and if each pair of `r : R` and `s : S` admits an Ore numerator -`v : R` and an Ore denominator `u : S` such that `u * r = v * s`. -/ -@[to_additive AddOreLocalization.AddOreSet] -class OreSet {R : Type*} [Monoid R] (S : Submonoid R) where - /-- Common factors on the right can be turned into common factors on the left, a weak form of -cancellability. -/ - ore_right_cancel : ∀ (r₁ r₂ : R) (s : S), r₁ * s = r₂ * s → ∃ s' : S, s' * r₁ = s' * r₂ - /-- The Ore numerator of a fraction. -/ - oreNum : R → S → R - /-- The Ore denominator of a fraction. -/ - oreDenom : R → S → S - /-- The Ore condition of a fraction, expressed in terms of `oreNum` and `oreDenom`. -/ - ore_eq : ∀ (r : R) (s : S), oreDenom r s * r = oreNum r s * s - --- TODO: use this once it's available. --- run_cmd to_additive.map_namespace `OreLocalization `AddOreLocalization - -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] -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 - -/-- The Ore numerator of a fraction. -/ -@[to_additive AddOreLocalization.oreMin "The Ore minuend of a difference."] -def oreNum (r : R) (s : S) : R := - OreSet.oreNum r s - -/-- The Ore denominator of a fraction. -/ -@[to_additive AddOreLocalization.oreSubtra "The Ore subtrahend of a difference."] -def oreDenom (r : R) (s : S) : S := - OreSet.oreDenom r s - -/-- The Ore condition of a fraction, expressed in terms of `oreNum` and `oreDenom`. -/ -@[to_additive AddOreLocalization.add_ore_eq - "The Ore condition of a difference, expressed in terms of `oreMin` and `oreSubtra`."] -theorem ore_eq (r : R) (s : S) : oreDenom r s * r = oreNum r s * s := - OreSet.ore_eq r s - -/-- The Ore condition bundled in a sigma type. This is useful in situations where we want to obtain -both witnesses and the condition for a given fraction. -/ -@[to_additive AddOreLocalization.addOreCondition - "The Ore condition bundled in a sigma type. This is useful in situations where we want to obtain -both witnesses and the condition for a given difference."] -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] -instance oreSetBot : OreSet (⊥ : Submonoid R) where - ore_right_cancel _ _ s h := - ⟨s, by - rcases s with ⟨s, hs⟩ - rw [Submonoid.mem_bot] at hs - subst hs - rw [mul_one, mul_one] at h - subst h - rfl⟩ - oreNum r _ := r - oreDenom _ s := s - ore_eq _ s := by - rcases s with ⟨s, hs⟩ - rw [Submonoid.mem_bot] at hs - simp [hs] - -/-- Every submonoid of a commutative monoid is an Ore set. -/ -@[to_additive AddOreLocalization.addOreSetComm] -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 - oreDenom _ s := s - ore_eq r s := by rw [mul_comm] - -end Monoid - /-- Cancellability in monoids with zeros can act as a replacement for the `ore_right_cancel` condition of an ore set. -/ def oreSetOfCancelMonoidWithZero {R : Type*} [CancelMonoidWithZero R] {S : Submonoid R} From dbbb99abc96dcc3399b3801e57433c8f94b069e3 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Tue, 15 Oct 2024 06:49:47 +0000 Subject: [PATCH 126/425] chore(GroupTheory/MonoidLocalization/Basic): split off `Away` (#17731) This modifies `GroupTheory/MonoidLocalization/Basic.lean` by splitting off `Localization.Away` into its own file. This allows us to significantly reduce the imports, and in combination with #17730 we no longer need to know about rings or monoids with zero to define the localization of a monoid. Co-authored-by: Kim Morrison --- Mathlib.lean | 1 + .../GroupTheory/MonoidLocalization/Away.lean | 172 ++++++++++++++++++ .../GroupTheory/MonoidLocalization/Basic.lean | 140 +------------- .../MonoidLocalization/MonoidWithZero.lean | 1 + .../RingTheory/Localization/Away/Basic.lean | 1 + Mathlib/RingTheory/Localization/Ideal.lean | 1 + Mathlib/SetTheory/Surreal/Dyadic.lean | 1 + 7 files changed, 182 insertions(+), 135 deletions(-) create mode 100644 Mathlib/GroupTheory/MonoidLocalization/Away.lean diff --git a/Mathlib.lean b/Mathlib.lean index 76f49cf3294a22..f93955efd69410 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2865,6 +2865,7 @@ import Mathlib.GroupTheory.GroupAction.Support import Mathlib.GroupTheory.GroupExtension.Defs import Mathlib.GroupTheory.HNNExtension import Mathlib.GroupTheory.Index +import Mathlib.GroupTheory.MonoidLocalization.Away import Mathlib.GroupTheory.MonoidLocalization.Basic import Mathlib.GroupTheory.MonoidLocalization.MonoidWithZero import Mathlib.GroupTheory.MonoidLocalization.Order diff --git a/Mathlib/GroupTheory/MonoidLocalization/Away.lean b/Mathlib/GroupTheory/MonoidLocalization/Away.lean new file mode 100644 index 00000000000000..7bf763ad98465c --- /dev/null +++ b/Mathlib/GroupTheory/MonoidLocalization/Away.lean @@ -0,0 +1,172 @@ +/- +Copyright (c) 2019 Amelia Livingston. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Amelia Livingston +-/ +import Mathlib.Algebra.Group.Submonoid.Membership +import Mathlib.GroupTheory.MonoidLocalization.Basic + +/-! +# Localizing commutative monoids away from an alement + +We treat the special case of localizing away from an element in the sections +`AwayMap` and `Away`. + +## Tags +localization, monoid localization, quotient monoid, congruence relation, characteristic predicate, +commutative monoid, grothendieck group +-/ + +open Function + +section CommMonoid + +variable {M : Type*} [CommMonoid M] {S : Submonoid M} {N : Type*} [CommMonoid N] {P : Type*} + [CommMonoid P] + +namespace Submonoid + +namespace LocalizationMap + +section AwayMap + +variable {g : M →* P} (hg : ∀ y : S, IsUnit (g y)) +variable (x : M) + +/-- Given `x : M`, the type of `CommMonoid` homomorphisms `f : M →* N` such that `N` +is isomorphic to the Localization of `M` at the Submonoid generated by `x`. -/ +@[to_additive + "Given `x : M`, the type of `AddCommMonoid` homomorphisms `f : M →+ N` such that `N` +is isomorphic to the localization of `M` at the AddSubmonoid generated by `x`."] +abbrev AwayMap (N' : Type*) [CommMonoid N'] := LocalizationMap (powers x) N' + +variable (F : AwayMap x N) + +/-- Given `x : M` and a Localization map `F : M →* N` away from `x`, `invSelf` is `(F x)⁻¹`. -/ +noncomputable def AwayMap.invSelf : N := F.mk' 1 ⟨x, mem_powers _⟩ + +/-- Given `x : M`, a Localization map `F : M →* N` away from `x`, and a map of `CommMonoid`s +`g : M →* P` such that `g x` is invertible, the homomorphism induced from `N` to `P` sending +`z : N` to `g y * (g x)⁻ⁿ`, where `y : M, n : ℕ` are such that `z = F y * (F x)⁻ⁿ`. -/ +noncomputable def AwayMap.lift (hg : IsUnit (g x)) : N →* P := + Submonoid.LocalizationMap.lift F fun y ↦ + show IsUnit (g y.1) by + obtain ⟨n, hn⟩ := y.2 + rw [← hn, g.map_pow] + exact IsUnit.pow n hg + +@[simp] +theorem AwayMap.lift_eq (hg : IsUnit (g x)) (a : M) : F.lift x hg (F.toMap a) = g a := + Submonoid.LocalizationMap.lift_eq _ _ _ + +@[simp] +theorem AwayMap.lift_comp (hg : IsUnit (g x)) : (F.lift x hg).comp F.toMap = g := + Submonoid.LocalizationMap.lift_comp _ _ + +/-- Given `x y : M` and Localization maps `F : M →* N, G : M →* P` away from `x` and `x * y` +respectively, the homomorphism induced from `N` to `P`. -/ +noncomputable def awayToAwayRight (y : M) (G : AwayMap (x * y) P) : N →* P := + F.lift x <| + show IsUnit (G.toMap x) from + isUnit_of_mul_eq_one (G.toMap x) (G.mk' y ⟨x * y, mem_powers _⟩) <| by + rw [mul_mk'_eq_mk'_of_mul, mk'_self] + +end AwayMap + +end LocalizationMap + +end Submonoid + +namespace AddSubmonoid + +namespace LocalizationMap + +section AwayMap + +variable {A : Type*} [AddCommMonoid A] (x : A) {B : Type*} [AddCommMonoid B] (F : AwayMap x B) + {C : Type*} [AddCommMonoid C] {g : A →+ C} + +/-- Given `x : A` and a Localization map `F : A →+ B` away from `x`, `neg_self` is `- (F x)`. -/ +noncomputable def AwayMap.negSelf : B := + F.mk' 0 ⟨x, mem_multiples _⟩ + +/-- Given `x : A`, a localization map `F : A →+ B` away from `x`, and a map of `AddCommMonoid`s +`g : A →+ C` such that `g x` is invertible, the homomorphism induced from `B` to `C` sending +`z : B` to `g y - n • g x`, where `y : A, n : ℕ` are such that `z = F y - n • F x`. -/ +noncomputable def AwayMap.lift (hg : IsAddUnit (g x)) : B →+ C := + AddSubmonoid.LocalizationMap.lift F fun y ↦ + show IsAddUnit (g y.1) by + obtain ⟨n, hn⟩ := y.2 + rw [← hn] + dsimp + rw [g.map_nsmul] + exact IsAddUnit.map (nsmulAddMonoidHom n : C →+ C) hg + +@[simp] +theorem AwayMap.lift_eq (hg : IsAddUnit (g x)) (a : A) : F.lift x hg (F.toMap a) = g a := + AddSubmonoid.LocalizationMap.lift_eq _ _ _ + +@[simp] +theorem AwayMap.lift_comp (hg : IsAddUnit (g x)) : (F.lift x hg).comp F.toMap = g := + AddSubmonoid.LocalizationMap.lift_comp _ _ + +/-- Given `x y : A` and Localization maps `F : A →+ B, G : A →+ C` away from `x` and `x + y` +respectively, the homomorphism induced from `B` to `C`. -/ +noncomputable def awayToAwayRight (y : A) (G : AwayMap (x + y) C) : B →+ C := + F.lift x <| + show IsAddUnit (G.toMap x) from + isAddUnit_of_add_eq_zero (G.toMap x) (G.mk' y ⟨x + y, mem_multiples _⟩) <| by + rw [add_mk'_eq_mk'_of_add, mk'_self] + +end AwayMap + +end LocalizationMap + +end AddSubmonoid + +namespace Localization + +section Away + +variable (x : M) + +/-- Given `x : M`, the Localization of `M` at the Submonoid generated by `x`, as a quotient. -/ +@[to_additive + "Given `x : M`, the Localization of `M` at the Submonoid generated by `x`, as a quotient."] +abbrev Away := + Localization (Submonoid.powers x) + +/-- Given `x : M`, `invSelf` is `x⁻¹` in the Localization (as a quotient type) of `M` at the +Submonoid generated by `x`. -/ +@[to_additive + "Given `x : M`, `negSelf` is `-x` in the Localization (as a quotient type) of `M` at the +Submonoid generated by `x`."] +def Away.invSelf : Away x := + mk 1 ⟨x, Submonoid.mem_powers _⟩ + +/-- Given `x : M`, the natural hom sending `y : M`, `M` a `CommMonoid`, to the equivalence class +of `(y, 1)` in the Localization of `M` at the Submonoid generated by `x`. -/ +@[to_additive + "Given `x : M`, the natural hom sending `y : M`, `M` an `AddCommMonoid`, to the equivalence +class of `(y, 0)` in the Localization of `M` at the Submonoid generated by `x`."] +abbrev Away.monoidOf : Submonoid.LocalizationMap.AwayMap x (Away x) := + Localization.monoidOf (Submonoid.powers x) + +-- @[simp] -- Porting note (#10618): simp can prove thisrove this +@[to_additive] +theorem Away.mk_eq_monoidOf_mk' : mk = (Away.monoidOf x).mk' := by simp + +/-- Given `x : M` and a Localization map `f : M →* N` away from `x`, we get an isomorphism between +the Localization of `M` at the Submonoid generated by `x` as a quotient type and `N`. -/ +@[to_additive + "Given `x : M` and a Localization map `f : M →+ N` away from `x`, we get an isomorphism between +the Localization of `M` at the Submonoid generated by `x` as a quotient type and `N`."] +noncomputable def Away.mulEquivOfQuotient (f : Submonoid.LocalizationMap.AwayMap x N) : + Away x ≃* N := + Localization.mulEquivOfQuotient f + +end Away + +end Localization + +end CommMonoid diff --git a/Mathlib/GroupTheory/MonoidLocalization/Basic.lean b/Mathlib/GroupTheory/MonoidLocalization/Basic.lean index 7780b5a72ee674..a05b795f2c3c4a 100644 --- a/Mathlib/GroupTheory/MonoidLocalization/Basic.lean +++ b/Mathlib/GroupTheory/MonoidLocalization/Basic.lean @@ -3,7 +3,7 @@ Copyright (c) 2019 Amelia Livingston. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Amelia Livingston -/ -import Mathlib.Algebra.Group.Submonoid.Membership +import Mathlib.Algebra.Group.Submonoid.Defs import Mathlib.GroupTheory.Congruence.Hom import Mathlib.GroupTheory.OreLocalization.Basic @@ -27,8 +27,7 @@ Given such a localization map `f : M →* N`, we can define the surjection maps elements of `S` to invertible elements of the codomain. Similarly, given commutative monoids `P, Q`, a submonoid `T` of `P` and a localization map for `T` from `P` to `Q`, then a homomorphism `g : M →* P` such that `g(S) ⊆ T` induces a homomorphism of localizations, `LocalizationMap.map`, -from `N` to `Q`. We treat the special case of localizing away from an element in the sections -`AwayMap` and `Away`. +from `N` to `Q`. We also define the quotient of `M × S` by the unique congruence relation (equivalence relation preserving a binary operation) `r` such that for any other congruence relation `s` on `M × S` @@ -74,6 +73,9 @@ localization, monoid localization, quotient monoid, congruence relation, charact commutative monoid, grothendieck group -/ +assert_not_exists MonoidWithZero +assert_not_exists Ring + open Function namespace AddSubmonoid @@ -991,101 +993,10 @@ theorem map_surjective_of_surjective (hg : Surjective g) (k : LocalizationMap (S use f.mk' x ⟨s, hs⟩ rw [map_mk'] -section AwayMap - -variable (x : M) - -/-- Given `x : M`, the type of `CommMonoid` homomorphisms `f : M →* N` such that `N` -is isomorphic to the Localization of `M` at the Submonoid generated by `x`. -/ -@[to_additive - "Given `x : M`, the type of `AddCommMonoid` homomorphisms `f : M →+ N` such that `N` -is isomorphic to the localization of `M` at the AddSubmonoid generated by `x`."] -abbrev AwayMap (N' : Type*) [CommMonoid N'] := LocalizationMap (powers x) N' - -variable (F : AwayMap x N) - -/-- Given `x : M` and a Localization map `F : M →* N` away from `x`, `invSelf` is `(F x)⁻¹`. -/ -noncomputable def AwayMap.invSelf : N := F.mk' 1 ⟨x, mem_powers _⟩ - -/-- Given `x : M`, a Localization map `F : M →* N` away from `x`, and a map of `CommMonoid`s -`g : M →* P` such that `g x` is invertible, the homomorphism induced from `N` to `P` sending -`z : N` to `g y * (g x)⁻ⁿ`, where `y : M, n : ℕ` are such that `z = F y * (F x)⁻ⁿ`. -/ -noncomputable def AwayMap.lift (hg : IsUnit (g x)) : N →* P := - Submonoid.LocalizationMap.lift F fun y ↦ - show IsUnit (g y.1) by - obtain ⟨n, hn⟩ := y.2 - rw [← hn, g.map_pow] - exact IsUnit.pow n hg - -@[simp] -theorem AwayMap.lift_eq (hg : IsUnit (g x)) (a : M) : F.lift x hg (F.toMap a) = g a := - Submonoid.LocalizationMap.lift_eq _ _ _ - -@[simp] -theorem AwayMap.lift_comp (hg : IsUnit (g x)) : (F.lift x hg).comp F.toMap = g := - Submonoid.LocalizationMap.lift_comp _ _ - -/-- Given `x y : M` and Localization maps `F : M →* N, G : M →* P` away from `x` and `x * y` -respectively, the homomorphism induced from `N` to `P`. -/ -noncomputable def awayToAwayRight (y : M) (G : AwayMap (x * y) P) : N →* P := - F.lift x <| - show IsUnit (G.toMap x) from - isUnit_of_mul_eq_one (G.toMap x) (G.mk' y ⟨x * y, mem_powers _⟩) <| by - rw [mul_mk'_eq_mk'_of_mul, mk'_self] - -end AwayMap - end LocalizationMap end Submonoid -namespace AddSubmonoid - -namespace LocalizationMap - -section AwayMap - -variable {A : Type*} [AddCommMonoid A] (x : A) {B : Type*} [AddCommMonoid B] (F : AwayMap x B) - {C : Type*} [AddCommMonoid C] {g : A →+ C} - -/-- Given `x : A` and a Localization map `F : A →+ B` away from `x`, `neg_self` is `- (F x)`. -/ -noncomputable def AwayMap.negSelf : B := - F.mk' 0 ⟨x, mem_multiples _⟩ - -/-- Given `x : A`, a localization map `F : A →+ B` away from `x`, and a map of `AddCommMonoid`s -`g : A →+ C` such that `g x` is invertible, the homomorphism induced from `B` to `C` sending -`z : B` to `g y - n • g x`, where `y : A, n : ℕ` are such that `z = F y - n • F x`. -/ -noncomputable def AwayMap.lift (hg : IsAddUnit (g x)) : B →+ C := - AddSubmonoid.LocalizationMap.lift F fun y ↦ - show IsAddUnit (g y.1) by - obtain ⟨n, hn⟩ := y.2 - rw [← hn] - dsimp - rw [g.map_nsmul] - exact IsAddUnit.map (nsmulAddMonoidHom n : C →+ C) hg - -@[simp] -theorem AwayMap.lift_eq (hg : IsAddUnit (g x)) (a : A) : F.lift x hg (F.toMap a) = g a := - AddSubmonoid.LocalizationMap.lift_eq _ _ _ - -@[simp] -theorem AwayMap.lift_comp (hg : IsAddUnit (g x)) : (F.lift x hg).comp F.toMap = g := - AddSubmonoid.LocalizationMap.lift_comp _ _ - -/-- Given `x y : A` and Localization maps `F : A →+ B, G : A →+ C` away from `x` and `x + y` -respectively, the homomorphism induced from `B` to `C`. -/ -noncomputable def awayToAwayRight (y : A) (G : AwayMap (x + y) C) : B →+ C := - F.lift x <| - show IsAddUnit (G.toMap x) from - isAddUnit_of_add_eq_zero (G.toMap x) (G.mk' y ⟨x + y, mem_multiples _⟩) <| by - rw [add_mk'_eq_mk'_of_add, mk'_self] - -end AwayMap - -end LocalizationMap - -end AddSubmonoid - namespace Submonoid namespace LocalizationMap @@ -1377,47 +1288,6 @@ theorem mulEquivOfQuotient_symm_monoidOf (x) : (mulEquivOfQuotient f).symm (f.toMap x) = (monoidOf S).toMap x := f.lift_eq (monoidOf S).map_units _ -section Away - -variable (x : M) - -/-- Given `x : M`, the Localization of `M` at the Submonoid generated by `x`, as a quotient. -/ -@[to_additive - "Given `x : M`, the Localization of `M` at the Submonoid generated by `x`, as a quotient."] -abbrev Away := - Localization (Submonoid.powers x) - -/-- Given `x : M`, `invSelf` is `x⁻¹` in the Localization (as a quotient type) of `M` at the -Submonoid generated by `x`. -/ -@[to_additive - "Given `x : M`, `negSelf` is `-x` in the Localization (as a quotient type) of `M` at the -Submonoid generated by `x`."] -def Away.invSelf : Away x := - mk 1 ⟨x, Submonoid.mem_powers _⟩ - -/-- Given `x : M`, the natural hom sending `y : M`, `M` a `CommMonoid`, to the equivalence class -of `(y, 1)` in the Localization of `M` at the Submonoid generated by `x`. -/ -@[to_additive - "Given `x : M`, the natural hom sending `y : M`, `M` an `AddCommMonoid`, to the equivalence -class of `(y, 0)` in the Localization of `M` at the Submonoid generated by `x`."] -abbrev Away.monoidOf : Submonoid.LocalizationMap.AwayMap x (Away x) := - Localization.monoidOf (Submonoid.powers x) - --- @[simp] -- Porting note (#10618): simp can prove thisrove this -@[to_additive] -theorem Away.mk_eq_monoidOf_mk' : mk = (Away.monoidOf x).mk' := by simp - -/-- Given `x : M` and a Localization map `f : M →* N` away from `x`, we get an isomorphism between -the Localization of `M` at the Submonoid generated by `x` as a quotient type and `N`. -/ -@[to_additive - "Given `x : M` and a Localization map `f : M →+ N` away from `x`, we get an isomorphism between -the Localization of `M` at the Submonoid generated by `x` as a quotient type and `N`."] -noncomputable def Away.mulEquivOfQuotient (f : Submonoid.LocalizationMap.AwayMap x N) : - Away x ≃* N := - Localization.mulEquivOfQuotient f - -end Away - end Localization end CommMonoid diff --git a/Mathlib/GroupTheory/MonoidLocalization/MonoidWithZero.lean b/Mathlib/GroupTheory/MonoidLocalization/MonoidWithZero.lean index af6a28afe26720..edb758c5a32685 100644 --- a/Mathlib/GroupTheory/MonoidLocalization/MonoidWithZero.lean +++ b/Mathlib/GroupTheory/MonoidLocalization/MonoidWithZero.lean @@ -3,6 +3,7 @@ Copyright (c) 2019 Amelia Livingston. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Amelia Livingston -/ +import Mathlib.Algebra.GroupWithZero.Hom import Mathlib.Algebra.Regular.Basic import Mathlib.GroupTheory.MonoidLocalization.Basic import Mathlib.RingTheory.OreLocalization.Basic diff --git a/Mathlib/RingTheory/Localization/Away/Basic.lean b/Mathlib/RingTheory/Localization/Away/Basic.lean index 13a452b4b4e865..c223f1c5f05f05 100644 --- a/Mathlib/RingTheory/Localization/Away/Basic.lean +++ b/Mathlib/RingTheory/Localization/Away/Basic.lean @@ -3,6 +3,7 @@ Copyright (c) 2018 Kenny Lau. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Kenny Lau, Mario Carneiro, Johan Commelin, Amelia Livingston, Anne Baanen -/ +import Mathlib.GroupTheory.MonoidLocalization.Away import Mathlib.RingTheory.UniqueFactorizationDomain import Mathlib.RingTheory.Localization.Basic diff --git a/Mathlib/RingTheory/Localization/Ideal.lean b/Mathlib/RingTheory/Localization/Ideal.lean index 3882ffbd9f01a7..990c36d781bd65 100644 --- a/Mathlib/RingTheory/Localization/Ideal.lean +++ b/Mathlib/RingTheory/Localization/Ideal.lean @@ -3,6 +3,7 @@ Copyright (c) 2018 Kenny Lau. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Kenny Lau, Mario Carneiro, Johan Commelin, Amelia Livingston, Anne Baanen -/ +import Mathlib.GroupTheory.MonoidLocalization.Away import Mathlib.RingTheory.Ideal.QuotientOperations import Mathlib.RingTheory.Localization.Basic diff --git a/Mathlib/SetTheory/Surreal/Dyadic.lean b/Mathlib/SetTheory/Surreal/Dyadic.lean index f47d76361786ec..2fcd752dc36c54 100644 --- a/Mathlib/SetTheory/Surreal/Dyadic.lean +++ b/Mathlib/SetTheory/Surreal/Dyadic.lean @@ -6,6 +6,7 @@ Authors: Apurva Nakade import Mathlib.Algebra.Algebra.Defs import Mathlib.Algebra.Order.Group.Basic import Mathlib.Algebra.Order.Ring.Basic +import Mathlib.GroupTheory.MonoidLocalization.Away import Mathlib.RingTheory.Localization.Basic import Mathlib.SetTheory.Game.Birthday import Mathlib.SetTheory.Surreal.Multiplication From 70c331f10e5c19f7ee2c00bc3e5f73ce05217f2d Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Tue, 15 Oct 2024 07:28:19 +0000 Subject: [PATCH 127/425] Update lean-toolchain for testing https://github.com/leanprover/lean4/pull/5720 --- lake-manifest.json | 4 ++-- lakefile.lean | 2 +- lean-toolchain | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index 5a7bf89d6a8f11..31e3bec7909930 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,10 +5,10 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "5f963d5d06cc3c2d3abd0806891133137a59d7eb", + "rev": "deeb06d863e8b08dc053b6fb9c1078ec53235061", "name": "batteries", "manifestFile": "lake-manifest.json", - "inputRev": "main", + "inputRev": "lean-pr-testing-5720", "inherited": false, "configFile": "lakefile.lean"}, {"url": "https://github.com/leanprover-community/quote4", diff --git a/lakefile.lean b/lakefile.lean index a4a09667f6c2b7..7fbc713a5965d6 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -7,7 +7,7 @@ open Lake DSL ## Mathlib dependencies on upstream projects -/ -require "leanprover-community" / "batteries" @ git "main" +require "leanprover-community" / "batteries" @ git "lean-pr-testing-5720" require "leanprover-community" / "Qq" @ git "master" require "leanprover-community" / "aesop" @ git "master" require "leanprover-community" / "proofwidgets" @ git "v0.0.43-pre" diff --git a/lean-toolchain b/lean-toolchain index a7eff1cf43d14e..1bee49741ed3d8 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-14 +leanprover/lean4-pr-releases:pr-release-5720 From 427742c47dc65f1bf0b388a769307e6abcd24af1 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Tue, 15 Oct 2024 07:35:23 +0000 Subject: [PATCH 128/425] chore(RingTheory/Localization/Basic): split off `Defs` (#17735) This PR splits off a `RingTheory.Localization.Defs` file that is supposed to contain the definition of `IsLocalization` and the ring structure on `Localization`, and some basic results that don't need further imports. I am quite sure that we can minimize the transitive imports a bit further but this seems like a decent point to stop for now. Co-authored-by: Kim Morrison --- Mathlib.lean | 1 + Mathlib/Algebra/Module/LocalizedModule.lean | 3 +- Mathlib/Algebra/Polynomial/Laurent.lean | 2 +- Mathlib/RingTheory/Localization/Basic.lean | 800 +--------------- Mathlib/RingTheory/Localization/Defs.lean | 901 +++++++++++++++++++ Mathlib/RingTheory/Localization/Integer.lean | 4 +- Mathlib/SetTheory/Surreal/Dyadic.lean | 5 +- 7 files changed, 919 insertions(+), 797 deletions(-) create mode 100644 Mathlib/RingTheory/Localization/Defs.lean diff --git a/Mathlib.lean b/Mathlib.lean index f93955efd69410..dc71e6f68be109 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4000,6 +4000,7 @@ import Mathlib.RingTheory.Localization.Away.Lemmas import Mathlib.RingTheory.Localization.BaseChange import Mathlib.RingTheory.Localization.Basic import Mathlib.RingTheory.Localization.Cardinality +import Mathlib.RingTheory.Localization.Defs import Mathlib.RingTheory.Localization.Finiteness import Mathlib.RingTheory.Localization.FractionRing import Mathlib.RingTheory.Localization.Ideal diff --git a/Mathlib/Algebra/Module/LocalizedModule.lean b/Mathlib/Algebra/Module/LocalizedModule.lean index 8cb4bff99cb6b1..231ab81c8c7888 100644 --- a/Mathlib/Algebra/Module/LocalizedModule.lean +++ b/Mathlib/Algebra/Module/LocalizedModule.lean @@ -4,8 +4,9 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Andrew Yang, Jujian Zhang -/ import Mathlib.Algebra.Algebra.Bilinear -import Mathlib.RingTheory.Localization.Basic import Mathlib.Algebra.Exact +import Mathlib.Algebra.Algebra.Tower +import Mathlib.RingTheory.Localization.Defs /-! # Localized Module diff --git a/Mathlib/Algebra/Polynomial/Laurent.lean b/Mathlib/Algebra/Polynomial/Laurent.lean index 08c3c4ff40db24..cd5d3cd5dc75a0 100644 --- a/Mathlib/Algebra/Polynomial/Laurent.lean +++ b/Mathlib/Algebra/Polynomial/Laurent.lean @@ -6,7 +6,7 @@ Authors: Damiano Testa import Mathlib.Algebra.Polynomial.AlgebraMap import Mathlib.Algebra.Polynomial.Reverse import Mathlib.Algebra.Polynomial.Inductions -import Mathlib.RingTheory.Localization.Basic +import Mathlib.RingTheory.Localization.Defs /-! # Laurent polynomials diff --git a/Mathlib/RingTheory/Localization/Basic.lean b/Mathlib/RingTheory/Localization/Basic.lean index 60472d72cb4017..9778d31970f782 100644 --- a/Mathlib/RingTheory/Localization/Basic.lean +++ b/Mathlib/RingTheory/Localization/Basic.lean @@ -8,10 +8,13 @@ import Mathlib.Algebra.GroupWithZero.NonZeroDivisors import Mathlib.GroupTheory.MonoidLocalization.MonoidWithZero import Mathlib.RingTheory.OreLocalization.Ring import Mathlib.RingTheory.Ideal.Basic +import Mathlib.RingTheory.Localization.Defs /-! # Localizations of commutative rings +This file contains various basic results on localizations. + We characterize the localization of a commutative ring `R` at a submonoid `M` up to isomorphism; that is, a commutative ring `S` is the localization of `R` at `M` iff we can find a ring homomorphism `f : R →+* S` satisfying 3 properties: @@ -29,26 +32,9 @@ variable [Algebra R S] [Algebra P Q] (M : Submonoid R) (T : Submonoid P) ## Main definitions - * `IsLocalization (M : Submonoid R) (S : Type*)` is a typeclass expressing that `S` is a - localization of `R` at `M`, i.e. the canonical map `algebraMap R S : R →+* S` is a - localization map (satisfying the above properties). - * `IsLocalization.mk' S` is a surjection sending `(x, y) : R × M` to `f x * (f y)⁻¹` - * `IsLocalization.lift` is the ring homomorphism from `S` induced by a homomorphism from `R` - which maps elements of `M` to invertible elements of the codomain. - * `IsLocalization.map S Q` is the ring homomorphism from `S` to `Q` which maps elements - of `M` to elements of `T` - * `IsLocalization.ringEquivOfRingEquiv`: if `R` and `P` are isomorphic by an isomorphism - sending `M` to `T`, then `S` and `Q` are isomorphic * `IsLocalization.algEquiv`: if `Q` is another localization of `R` at `M`, then `S` and `Q` are isomorphic as `R`-algebras -## Main results - - * `Localization M S`, a construction of the localization as a quotient type, defined in - `GroupTheory.MonoidLocalization`, has `CommRing`, `Algebra R` and `IsLocalization M` - instances if `R` is a ring. `Localization.Away`, `Localization.AtPrime` and `FractionRing` - are abbreviations for `Localization`s and have their corresponding `IsLocalization` instances - ## Implementation notes In maths it is natural to reason up to isomorphism, but in Lean we cannot naturally `rewrite` one @@ -86,225 +72,15 @@ open Function section CommSemiring -variable {R : Type*} [CommSemiring R] (M : Submonoid R) (S : Type*) [CommSemiring S] +variable {R : Type*} [CommSemiring R] {M : Submonoid R} {S : Type*} [CommSemiring S] variable [Algebra R S] {P : Type*} [CommSemiring P] -/-- The typeclass `IsLocalization (M : Submonoid R) S` where `S` is an `R`-algebra -expresses that `S` is isomorphic to the localization of `R` at `M`. -/ -@[mk_iff] class IsLocalization : Prop where - -- Porting note: add ' to fields, and made new versions of these with either `S` or `M` explicit. - /-- Everything in the image of `algebraMap` is a unit -/ - map_units' : ∀ y : M, IsUnit (algebraMap R S y) - /-- The `algebraMap` is surjective -/ - surj' : ∀ z : S, ∃ x : R × M, z * algebraMap R S x.2 = algebraMap R S x.1 - /-- The kernel of `algebraMap` is contained in the annihilator of `M`; - it is then equal to the annihilator by `map_units'` -/ - exists_of_eq : ∀ {x y}, algebraMap R S x = algebraMap R S y → ∃ c : M, ↑c * x = ↑c * y - -variable {M} - namespace IsLocalization section IsLocalization variable [IsLocalization M S] -section - -@[inherit_doc IsLocalization.map_units'] -theorem map_units : ∀ y : M, IsUnit (algebraMap R S y) := - IsLocalization.map_units' - -variable (M) {S} -@[inherit_doc IsLocalization.surj'] -theorem surj : ∀ z : S, ∃ x : R × M, z * algebraMap R S x.2 = algebraMap R S x.1 := - IsLocalization.surj' - -variable (S) -@[inherit_doc IsLocalization.exists_of_eq] -theorem eq_iff_exists {x y} : algebraMap R S x = algebraMap R S y ↔ ∃ c : M, ↑c * x = ↑c * y := - Iff.intro IsLocalization.exists_of_eq fun ⟨c, h⟩ ↦ by - apply_fun algebraMap R S at h - rw [map_mul, map_mul] at h - exact (IsLocalization.map_units S c).mul_right_inj.mp h - -variable {S} -theorem of_le (N : Submonoid R) (h₁ : M ≤ N) (h₂ : ∀ r ∈ N, IsUnit (algebraMap R S r)) : - IsLocalization N S where - map_units' r := h₂ r r.2 - surj' s := - have ⟨⟨x, y, hy⟩, H⟩ := IsLocalization.surj M s - ⟨⟨x, y, h₁ hy⟩, H⟩ - exists_of_eq {x y} := by - rw [IsLocalization.eq_iff_exists M] - rintro ⟨c, hc⟩ - exact ⟨⟨c, h₁ c.2⟩, hc⟩ - -variable (S) - -/-- `IsLocalization.toLocalizationWithZeroMap M S` shows `S` is the monoid localization of -`R` at `M`. -/ -@[simps] -def toLocalizationWithZeroMap : Submonoid.LocalizationWithZeroMap M S where - __ := algebraMap R S - toFun := algebraMap R S - map_units' := IsLocalization.map_units _ - surj' := IsLocalization.surj _ - exists_of_eq _ _ := IsLocalization.exists_of_eq - -/-- `IsLocalization.toLocalizationMap M S` shows `S` is the monoid localization of `R` at `M`. -/ -abbrev toLocalizationMap : Submonoid.LocalizationMap M S := - (toLocalizationWithZeroMap M S).toLocalizationMap - -@[simp] -theorem toLocalizationMap_toMap : (toLocalizationMap M S).toMap = (algebraMap R S : R →*₀ S) := - rfl - -theorem toLocalizationMap_toMap_apply (x) : (toLocalizationMap M S).toMap x = algebraMap R S x := - rfl - -theorem surj₂ : ∀ z w : S, ∃ z' w' : R, ∃ d : M, - (z * algebraMap R S d = algebraMap R S z') ∧ (w * algebraMap R S d = algebraMap R S w') := - (toLocalizationMap M S).surj₂ - -end - -variable (M) {S} - -/-- Given a localization map `f : M →* N`, a section function sending `z : N` to some -`(x, y) : M × S` such that `f x * (f y)⁻¹ = z`. -/ -noncomputable def sec (z : S) : R × M := - Classical.choose <| IsLocalization.surj _ z - -@[simp] -theorem toLocalizationMap_sec : (toLocalizationMap M S).sec = sec M := - rfl - -/-- Given `z : S`, `IsLocalization.sec M z` is defined to be a pair `(x, y) : R × M` such -that `z * f y = f x` (so this lemma is true by definition). -/ -theorem sec_spec (z : S) : - z * algebraMap R S (IsLocalization.sec M z).2 = algebraMap R S (IsLocalization.sec M z).1 := - Classical.choose_spec <| IsLocalization.surj _ z - -/-- Given `z : S`, `IsLocalization.sec M z` is defined to be a pair `(x, y) : R × M` such -that `z * f y = f x`, so this lemma is just an application of `S`'s commutativity. -/ -theorem sec_spec' (z : S) : - algebraMap R S (IsLocalization.sec M z).1 = algebraMap R S (IsLocalization.sec M z).2 * z := by - rw [mul_comm, sec_spec] - -variable {M} - -/-- If `M` contains `0` then the localization at `M` is trivial. -/ -theorem subsingleton (h : 0 ∈ M) : Subsingleton S := (toLocalizationMap M S).subsingleton h - -theorem map_right_cancel {x y} {c : M} (h : algebraMap R S (c * x) = algebraMap R S (c * y)) : - algebraMap R S x = algebraMap R S y := - (toLocalizationMap M S).map_right_cancel h - -theorem map_left_cancel {x y} {c : M} (h : algebraMap R S (x * c) = algebraMap R S (y * c)) : - algebraMap R S x = algebraMap R S y := - (toLocalizationMap M S).map_left_cancel h - -theorem eq_zero_of_fst_eq_zero {z x} {y : M} (h : z * algebraMap R S y = algebraMap R S x) - (hx : x = 0) : z = 0 := by - rw [hx, (algebraMap R S).map_zero] at h - exact (IsUnit.mul_left_eq_zero (IsLocalization.map_units S y)).1 h - -variable (M S) - -theorem map_eq_zero_iff (r : R) : algebraMap R S r = 0 ↔ ∃ m : M, ↑m * r = 0 := by - constructor - · intro h - obtain ⟨m, hm⟩ := (IsLocalization.eq_iff_exists M S).mp ((algebraMap R S).map_zero.trans h.symm) - exact ⟨m, by simpa using hm.symm⟩ - · rintro ⟨m, hm⟩ - rw [← (IsLocalization.map_units S m).mul_right_inj, mul_zero, ← RingHom.map_mul, hm, - RingHom.map_zero] - -variable {M} - -/-- `IsLocalization.mk' S` is the surjection sending `(x, y) : R × M` to -`f x * (f y)⁻¹`. -/ -noncomputable def mk' (x : R) (y : M) : S := - (toLocalizationMap M S).mk' x y - -@[simp] -theorem mk'_sec (z : S) : mk' S (IsLocalization.sec M z).1 (IsLocalization.sec M z).2 = z := - (toLocalizationMap M S).mk'_sec _ - -theorem mk'_mul (x₁ x₂ : R) (y₁ y₂ : M) : mk' S (x₁ * x₂) (y₁ * y₂) = mk' S x₁ y₁ * mk' S x₂ y₂ := - (toLocalizationMap M S).mk'_mul _ _ _ _ - -theorem mk'_one (x) : mk' S x (1 : M) = algebraMap R S x := - (toLocalizationMap M S).mk'_one _ - -@[simp] -theorem mk'_spec (x) (y : M) : mk' S x y * algebraMap R S y = algebraMap R S x := - (toLocalizationMap M S).mk'_spec _ _ - -@[simp] -theorem mk'_spec' (x) (y : M) : algebraMap R S y * mk' S x y = algebraMap R S x := - (toLocalizationMap M S).mk'_spec' _ _ - -@[simp] -theorem mk'_spec_mk (x) (y : R) (hy : y ∈ M) : - mk' S x ⟨y, hy⟩ * algebraMap R S y = algebraMap R S x := - mk'_spec S x ⟨y, hy⟩ - -@[simp] -theorem mk'_spec'_mk (x) (y : R) (hy : y ∈ M) : - algebraMap R S y * mk' S x ⟨y, hy⟩ = algebraMap R S x := - mk'_spec' S x ⟨y, hy⟩ - -variable {S} - -theorem eq_mk'_iff_mul_eq {x} {y : M} {z} : - z = mk' S x y ↔ z * algebraMap R S y = algebraMap R S x := - (toLocalizationMap M S).eq_mk'_iff_mul_eq - -theorem eq_mk'_of_mul_eq {x : R} {y : M} {z : R} (h : z * y = x) : (algebraMap R S) z = mk' S x y := - eq_mk'_iff_mul_eq.mpr (by rw [← h, map_mul]) - -theorem mk'_eq_iff_eq_mul {x} {y : M} {z} : - mk' S x y = z ↔ algebraMap R S x = z * algebraMap R S y := - (toLocalizationMap M S).mk'_eq_iff_eq_mul - -theorem mk'_add_eq_iff_add_mul_eq_mul {x} {y : M} {z₁ z₂} : - mk' S x y + z₁ = z₂ ↔ algebraMap R S x + z₁ * algebraMap R S y = z₂ * algebraMap R S y := by - rw [← mk'_spec S x y, ← IsUnit.mul_left_inj (IsLocalization.map_units S y), right_distrib] - -theorem mk'_pow (x : R) (y : M) (n : ℕ) : mk' S (x ^ n) (y ^ n) = mk' S x y ^ n := by - simp_rw [IsLocalization.mk'_eq_iff_eq_mul, SubmonoidClass.coe_pow, map_pow, ← mul_pow] - simp - -variable (M) - -theorem mk'_surjective (z : S) : ∃ (x : _) (y : M), mk' S x y = z := - let ⟨r, hr⟩ := IsLocalization.surj _ z - ⟨r.1, r.2, (eq_mk'_iff_mul_eq.2 hr).symm⟩ - -variable (S) - -/-- The localization of a `Fintype` is a `Fintype`. Cannot be an instance. -/ -noncomputable def fintype' [Fintype R] : Fintype S := - have := Classical.propDecidable - Fintype.ofSurjective (Function.uncurry <| IsLocalization.mk' S) fun a => - Prod.exists'.mpr <| IsLocalization.mk'_surjective M a - -variable {M S} - -/-- Localizing at a submonoid with 0 inside it leads to the trivial ring. -/ -def uniqueOfZeroMem (h : (0 : R) ∈ M) : Unique S := - uniqueOfZeroEqOne <| by simpa using IsLocalization.map_units S ⟨0, h⟩ - -theorem mk'_eq_iff_eq {x₁ x₂} {y₁ y₂ : M} : - mk' S x₁ y₁ = mk' S x₂ y₂ ↔ algebraMap R S (y₂ * x₁) = algebraMap R S (y₁ * x₂) := - (toLocalizationMap M S).mk'_eq_iff_eq - -theorem mk'_eq_iff_eq' {x₁ x₂} {y₁ y₂ : M} : - mk' S x₁ y₁ = mk' S x₂ y₂ ↔ algebraMap R S (x₁ * y₂) = algebraMap R S (x₂ * y₁) := - (toLocalizationMap M S).mk'_eq_iff_eq' - theorem mk'_mem_iff {x} {y : M} {I : Ideal S} : mk' S x y ∈ I ↔ algebraMap R S x ∈ I := by constructor <;> intro h · rw [← mk'_spec S x y, mul_comm] @@ -314,198 +90,10 @@ theorem mk'_mem_iff {x} {y : M} {I : Ideal S} : mk' S x y ∈ I ↔ algebraMap R have := I.mul_mem_left b h rwa [mul_comm, mul_assoc, hb, mul_one] at this -protected theorem eq {a₁ b₁} {a₂ b₂ : M} : - mk' S a₁ a₂ = mk' S b₁ b₂ ↔ ∃ c : M, ↑c * (↑b₂ * a₁) = c * (a₂ * b₁) := - (toLocalizationMap M S).eq - -theorem mk'_eq_zero_iff (x : R) (s : M) : mk' S x s = 0 ↔ ∃ m : M, ↑m * x = 0 := by - rw [← (map_units S s).mul_left_inj, mk'_spec, zero_mul, map_eq_zero_iff M] - -@[simp] -theorem mk'_zero (s : M) : IsLocalization.mk' S 0 s = 0 := by - rw [eq_comm, IsLocalization.eq_mk'_iff_mul_eq, zero_mul, map_zero] - -theorem ne_zero_of_mk'_ne_zero {x : R} {y : M} (hxy : IsLocalization.mk' S x y ≠ 0) : x ≠ 0 := by - rintro rfl - exact hxy (IsLocalization.mk'_zero _) - -section Ext - -theorem eq_iff_eq [Algebra R P] [IsLocalization M P] {x y} : - algebraMap R S x = algebraMap R S y ↔ algebraMap R P x = algebraMap R P y := - (toLocalizationMap M S).eq_iff_eq (toLocalizationMap M P) - -theorem mk'_eq_iff_mk'_eq [Algebra R P] [IsLocalization M P] {x₁ x₂} {y₁ y₂ : M} : - mk' S x₁ y₁ = mk' S x₂ y₂ ↔ mk' P x₁ y₁ = mk' P x₂ y₂ := - (toLocalizationMap M S).mk'_eq_iff_mk'_eq (toLocalizationMap M P) - -theorem mk'_eq_of_eq {a₁ b₁ : R} {a₂ b₂ : M} (H : ↑a₂ * b₁ = ↑b₂ * a₁) : - mk' S a₁ a₂ = mk' S b₁ b₂ := - (toLocalizationMap M S).mk'_eq_of_eq H - -theorem mk'_eq_of_eq' {a₁ b₁ : R} {a₂ b₂ : M} (H : b₁ * ↑a₂ = a₁ * ↑b₂) : - mk' S a₁ a₂ = mk' S b₁ b₂ := - (toLocalizationMap M S).mk'_eq_of_eq' H - -theorem mk'_cancel (a : R) (b c : M) : - mk' S (a * c) (b * c) = mk' S a b := (toLocalizationMap M S).mk'_cancel _ _ _ - -variable (S) - -@[simp] -theorem mk'_self {x : R} (hx : x ∈ M) : mk' S x ⟨x, hx⟩ = 1 := - (toLocalizationMap M S).mk'_self _ hx - -@[simp] -theorem mk'_self' {x : M} : mk' S (x : R) x = 1 := - (toLocalizationMap M S).mk'_self' _ - -theorem mk'_self'' {x : M} : mk' S x.1 x = 1 := - mk'_self' _ - -end Ext - -theorem mul_mk'_eq_mk'_of_mul (x y : R) (z : M) : - (algebraMap R S) x * mk' S y z = mk' S (x * y) z := - (toLocalizationMap M S).mul_mk'_eq_mk'_of_mul _ _ _ - -theorem mk'_eq_mul_mk'_one (x : R) (y : M) : mk' S x y = (algebraMap R S) x * mk' S 1 y := - ((toLocalizationMap M S).mul_mk'_one_eq_mk' _ _).symm - -@[simp] -theorem mk'_mul_cancel_left (x : R) (y : M) : mk' S (y * x : R) y = (algebraMap R S) x := - (toLocalizationMap M S).mk'_mul_cancel_left _ _ - -theorem mk'_mul_cancel_right (x : R) (y : M) : mk' S (x * y) y = (algebraMap R S) x := - (toLocalizationMap M S).mk'_mul_cancel_right _ _ - -@[simp] -theorem mk'_mul_mk'_eq_one (x y : M) : mk' S (x : R) y * mk' S (y : R) x = 1 := by - rw [← mk'_mul, mul_comm]; exact mk'_self _ _ - -theorem mk'_mul_mk'_eq_one' (x : R) (y : M) (h : x ∈ M) : mk' S x y * mk' S (y : R) ⟨x, h⟩ = 1 := - mk'_mul_mk'_eq_one ⟨x, h⟩ _ - -theorem smul_mk' (x y : R) (m : M) : x • mk' S y m = mk' S (x * y) m := by - nth_rw 2 [← one_mul m] - rw [mk'_mul, mk'_one, Algebra.smul_def] - -@[simp] theorem smul_mk'_one (x : R) (m : M) : x • mk' S 1 m = mk' S x m := by - rw [smul_mk', mul_one] - -@[simp] lemma smul_mk'_self {m : M} {r : R} : - (m : R) • mk' S r m = algebraMap R S r := by - rw [smul_mk', mk'_mul_cancel_left] - -@[simps] -instance invertible_mk'_one (s : M) : Invertible (IsLocalization.mk' S (1 : R) s) where - invOf := algebraMap R S s - invOf_mul_self := by simp - mul_invOf_self := by simp - -section - -variable (M) - -theorem isUnit_comp (j : S →+* P) (y : M) : IsUnit (j.comp (algebraMap R S) y) := - (toLocalizationMap M S).isUnit_comp j.toMonoidHom _ - -end - -/-- Given a localization map `f : R →+* S` for a submonoid `M ⊆ R` and a map of `CommSemiring`s -`g : R →+* P` such that `g(M) ⊆ Units P`, `f x = f y → g x = g y` for all `x y : R`. -/ -theorem eq_of_eq {g : R →+* P} (hg : ∀ y : M, IsUnit (g y)) {x y} - (h : (algebraMap R S) x = (algebraMap R S) y) : g x = g y := - Submonoid.LocalizationMap.eq_of_eq (toLocalizationMap M S) (g := g.toMonoidHom) hg h - -theorem mk'_add (x₁ x₂ : R) (y₁ y₂ : M) : - mk' S (x₁ * y₂ + x₂ * y₁) (y₁ * y₂) = mk' S x₁ y₁ + mk' S x₂ y₂ := - mk'_eq_iff_eq_mul.2 <| - Eq.symm - (by - rw [mul_comm (_ + _), mul_add, mul_mk'_eq_mk'_of_mul, mk'_add_eq_iff_add_mul_eq_mul, - mul_comm (_ * _), ← mul_assoc, add_comm, ← map_mul, mul_mk'_eq_mk'_of_mul, - mk'_add_eq_iff_add_mul_eq_mul] - simp only [map_add, Submonoid.coe_mul, map_mul] - ring) - -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 - rw [mul_comm, ← one_mul z₁, ← Units.inv_mul (IsUnit.liftRight (g.toMonoidHom.restrict 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] - -theorem lift_spec_mul_add {g : R →+* P} (hg : ∀ y : M, IsUnit (g y)) (z w w' v) : - ((toLocalizationWithZeroMap M S).lift g.toMonoidWithZeroHom hg) z * w + w' = v ↔ - g ((toLocalizationMap M S).sec z).1 * w + g ((toLocalizationMap M S).sec z).2 * w' = - g ((toLocalizationMap M S).sec z).2 * v := by - erw [mul_comm, ← mul_assoc, mul_add_inv_left hg, mul_comm] - rfl - -/-- Given a localization map `f : R →+* S` for a submonoid `M ⊆ R` and a map of `CommSemiring`s -`g : R →+* P` such that `g y` is invertible for all `y : M`, the homomorphism induced from -`S` to `P` sending `z : S` to `g x * (g y)⁻¹`, where `(x, y) : R × M` are such that -`z = f x * (f y)⁻¹`. -/ -noncomputable def lift {g : R →+* P} (hg : ∀ y : M, IsUnit (g y)) : S →+* P := - { Submonoid.LocalizationWithZeroMap.lift (toLocalizationWithZeroMap M S) - g.toMonoidWithZeroHom hg with - map_add' := by - intro x y - erw [(toLocalizationMap M S).lift_spec, mul_add, mul_comm, eq_comm, lift_spec_mul_add, - add_comm, mul_comm, mul_assoc, mul_comm, mul_assoc, lift_spec_mul_add] - simp_rw [← mul_assoc] - show g _ * g _ * g _ + g _ * g _ * g _ = g _ * g _ * g _ - simp_rw [← map_mul g, ← map_add g] - apply eq_of_eq (S := S) hg - simp only [sec_spec', toLocalizationMap_sec, map_add, map_mul] - ring } - variable {g : R →+* P} (hg : ∀ y : M, IsUnit (g y)) -/-- Given a localization map `f : R →+* S` for a submonoid `M ⊆ R` and a map of `CommSemiring`s -`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)⁻¹ := - (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 := - (toLocalizationMap M S).lift_mk'_spec _ _ _ _ - -@[simp] -theorem lift_eq (x : R) : lift hg ((algebraMap R S) x) = g x := - (toLocalizationMap M S).lift_eq _ _ - -theorem lift_eq_iff {x y : R × M} : - lift hg (mk' S x.1 x.2) = lift hg (mk' S y.1 y.2) ↔ g (x.1 * y.2) = g (y.1 * x.2) := - (toLocalizationMap M S).lift_eq_iff _ - -@[simp] -theorem lift_comp : (lift hg).comp (algebraMap R S) = g := - RingHom.ext <| (DFunLike.ext_iff (F := MonoidHom _ _)).1 <| (toLocalizationMap M S).lift_comp _ - -@[simp] -theorem lift_of_comp (j : S →+* P) : lift (isUnit_comp M j) = j := - RingHom.ext <| (DFunLike.ext_iff (F := MonoidHom _ _)).1 <| - (toLocalizationMap M S).lift_of_comp j.toMonoidHom - -variable (M) - -section -include M - -/-- See note [partially-applied ext lemmas] -/ -theorem monoidHom_ext ⦃j k : S →* P⦄ - (h : j.comp (algebraMap R S : R →* S) = k.comp (algebraMap R S)) : j = k := - Submonoid.LocalizationMap.epic_of_localizationMap (toLocalizationMap M S) <| DFunLike.congr_fun h - -/-- See note [partially-applied ext lemmas] -/ -theorem ringHom_ext ⦃j k : S →+* P⦄ (h : j.comp (algebraMap R S) = k.comp (algebraMap R S)) : - j = k := - RingHom.coe_monoidHom_injective <| monoidHom_ext M <| MonoidHom.ext <| RingHom.congr_fun h - +variable (M) in +include M in /- This is not an instance because the submonoid `M` would become a metavariable in typeclass search. -/ theorem algHom_subsingleton [Algebra R P] : Subsingleton (S →ₐ[R] P) := @@ -513,154 +101,6 @@ theorem algHom_subsingleton [Algebra R P] : Subsingleton (S →ₐ[R] P) := AlgHom.coe_ringHom_injective <| IsLocalization.ringHom_ext M <| by rw [f.comp_algebraMap, g.comp_algebraMap]⟩ -/-- To show `j` and `k` agree on the whole localization, it suffices to show they agree -on the image of the base ring, if they preserve `1` and `*`. -/ -protected theorem ext (j k : S → P) (hj1 : j 1 = 1) (hk1 : k 1 = 1) - (hjm : ∀ a b, j (a * b) = j a * j b) (hkm : ∀ a b, k (a * b) = k a * k b) - (h : ∀ a, j (algebraMap R S a) = k (algebraMap R S a)) : j = k := - let j' : MonoidHom S P := - { toFun := j, map_one' := hj1, map_mul' := hjm } - let k' : MonoidHom S P := - { toFun := k, map_one' := hk1, map_mul' := hkm } - have : j' = k' := monoidHom_ext M (MonoidHom.ext h) - show j'.toFun = k'.toFun by rw [this] -end - -variable {M} - -theorem lift_unique {j : S →+* P} (hj : ∀ x, j ((algebraMap R S) x) = g x) : lift hg = j := - RingHom.ext <| - (DFunLike.ext_iff (F := MonoidHom _ _)).1 <| - Submonoid.LocalizationMap.lift_unique (toLocalizationMap M S) (g := g.toMonoidHom) hg - (j := j.toMonoidHom) hj - -@[simp] -theorem lift_id (x) : lift (map_units S : ∀ _ : M, IsUnit _) x = x := - (toLocalizationMap M S).lift_id _ - -theorem lift_surjective_iff : - Surjective (lift hg : S → P) ↔ ∀ v : P, ∃ x : R × M, v * g x.2 = g x.1 := - (toLocalizationMap M S).lift_surjective_iff hg - -theorem lift_injective_iff : - Injective (lift hg : S → P) ↔ ∀ x y, algebraMap R S x = algebraMap R S y ↔ g x = g y := - (toLocalizationMap M S).lift_injective_iff hg - -section Map - -variable {T : Submonoid P} {Q : Type*} [CommSemiring Q] -variable [Algebra P Q] [IsLocalization T Q] - -section - -variable (Q) - -/-- Map a homomorphism `g : R →+* P` to `S →+* Q`, where `S` and `Q` are -localizations of `R` and `P` at `M` and `T` respectively, -such that `g(M) ⊆ T`. - -We send `z : S` to `algebraMap P Q (g x) * (algebraMap P Q (g y))⁻¹`, where -`(x, y) : R × M` are such that `z = f x * (f y)⁻¹`. -/ -noncomputable def map (g : R →+* P) (hy : M ≤ T.comap g) : S →+* Q := - lift (M := M) (g := (algebraMap P Q).comp g) fun y => map_units _ ⟨g y, hy y.2⟩ - -end - -section -variable (hy : M ≤ T.comap g) -include hy - --- Porting note: added `simp` attribute, since it proves very similar lemmas marked `simp` -@[simp] -theorem map_eq (x) : map Q g hy ((algebraMap R S) x) = algebraMap P Q (g x) := - lift_eq (fun y => map_units _ ⟨g y, hy y.2⟩) x - -@[simp] -theorem map_comp : (map Q g hy).comp (algebraMap R S) = (algebraMap P Q).comp g := - lift_comp fun y => map_units _ ⟨g y, hy y.2⟩ - -theorem map_mk' (x) (y : M) : map Q g hy (mk' S x y) = mk' Q (g x) ⟨g y, hy y.2⟩ := - Submonoid.LocalizationMap.map_mk' (toLocalizationMap M S) (g := g.toMonoidHom) - (fun y => hy y.2) (k := toLocalizationMap T Q) .. - -theorem map_unique (j : S →+* Q) (hj : ∀ x : R, j (algebraMap R S x) = algebraMap P Q (g x)) : - map Q g hy = j := - lift_unique (fun y => map_units _ ⟨g y, hy y.2⟩) hj - -/-- If `CommSemiring` homs `g : R →+* P, l : P →+* A` induce maps of localizations, the composition -of the induced maps equals the map of localizations induced by `l ∘ g`. -/ -theorem map_comp_map {A : Type*} [CommSemiring A] {U : Submonoid A} {W} [CommSemiring W] - [Algebra A W] [IsLocalization U W] {l : P →+* A} (hl : T ≤ U.comap l) : - (map W l hl).comp (map Q g hy : S →+* _) = map W (l.comp g) fun _ hx => hl (hy hx) := - RingHom.ext fun x => - Submonoid.LocalizationMap.map_map (P := P) (toLocalizationMap M S) (fun y => hy y.2) - (toLocalizationMap U W) (fun w => hl w.2) x - -/-- If `CommSemiring` homs `g : R →+* P, l : P →+* A` induce maps of localizations, the composition -of the induced maps equals the map of localizations induced by `l ∘ g`. -/ -theorem map_map {A : Type*} [CommSemiring A] {U : Submonoid A} {W} [CommSemiring W] [Algebra A W] - [IsLocalization U W] {l : P →+* A} (hl : T ≤ U.comap l) (x : S) : - map W l hl (map Q g hy x) = map W (l.comp g) (fun _ hx => hl (hy hx)) x := by - rw [← map_comp_map (Q := Q) hy hl]; rfl - -theorem map_smul (x : S) (z : R) : map Q g hy (z • x : S) = g z • map Q g hy x := by - rw [Algebra.smul_def, Algebra.smul_def, RingHom.map_mul, map_eq] - -end - -@[simp] -theorem map_id_mk' {Q : Type*} [CommSemiring Q] [Algebra R Q] [IsLocalization M Q] (x) (y : M) : - map Q (RingHom.id R) (le_refl M) (mk' S x y) = mk' Q x y := - map_mk' .. - -@[simp] -theorem map_id (z : S) (h : M ≤ M.comap (RingHom.id R) := le_refl M) : - map S (RingHom.id _) h z = z := - lift_id _ - -section - -variable (S Q) - -/-- 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`. -/ -@[simps] -noncomputable def ringEquivOfRingEquiv (h : R ≃+* P) (H : M.map h.toMonoidHom = T) : S ≃+* Q := - have H' : T.map h.symm.toMonoidHom = M := by - rw [← M.map_id, ← H, Submonoid.map_map] - congr - ext - apply h.symm_apply_apply - { map Q (h : R →+* P) (M.le_comap_of_map_le (le_of_eq H)) with - toFun := map Q (h : R →+* P) (M.le_comap_of_map_le (le_of_eq H)) - invFun := map S (h.symm : P →+* R) (T.le_comap_of_map_le (le_of_eq H')) - left_inv := fun x => by - rw [map_map, map_unique _ (RingHom.id _), RingHom.id_apply] - simp - right_inv := fun x => by - rw [map_map, map_unique _ (RingHom.id _), RingHom.id_apply] - simp } - -end - -theorem ringEquivOfRingEquiv_eq_map {j : R ≃+* P} (H : M.map j.toMonoidHom = T) : - (ringEquivOfRingEquiv S Q j H : S →+* Q) = - map Q (j : R →+* P) (M.le_comap_of_map_le (le_of_eq H)) := - rfl - --- Porting note (#10618): removed `simp`, `simp` can prove it -theorem ringEquivOfRingEquiv_eq {j : R ≃+* P} (H : M.map j.toMonoidHom = T) (x) : - ringEquivOfRingEquiv S Q j H ((algebraMap R S) x) = algebraMap P Q (j x) := by - simp - -theorem ringEquivOfRingEquiv_mk' {j : R ≃+* P} (H : M.map j.toMonoidHom = T) (x : R) (y : M) : - ringEquivOfRingEquiv S Q j H (mk' S x y) = - mk' Q (j x) ⟨j y, show j y ∈ T from H ▸ Set.mem_image_of_mem j y.2⟩ := by - simp [map_mk'] - -end Map - section AlgEquiv variable {Q : Type*} [CommSemiring Q] [Algebra R Q] [IsLocalization M Q] @@ -696,11 +136,6 @@ protected lemma bijective (f : S →+* Q) (hf : f.comp (algebraMap R S) = algebr end AlgEquiv section at_units -lemma at_units (S : Submonoid R) - (hS : S ≤ IsUnit.submonoid R) : IsLocalization S R where - map_units' y := hS y.prop - surj' := fun s ↦ ⟨⟨s, 1⟩, by simp⟩ - exists_of_eq := fun {x y} (e : x = y) ↦ ⟨1, e ▸ rfl⟩ variable (R M) @@ -721,27 +156,11 @@ noncomputable def atUnits (H : M ≤ IsUnit.submonoid R) : R ≃ₐ[R] S := by end at_units -section - -variable (M S) (Q : Type*) [CommSemiring Q] [Algebra P Q] - -/-- Injectivity of a map descends to the map induced on localizations. -/ -theorem map_injective_of_injective (h : Function.Injective g) [IsLocalization (M.map g) Q] : - Function.Injective (map Q g M.le_comap_map : S → Q) := - (toLocalizationMap M S).map_injective_of_injective h (toLocalizationMap (M.map g) Q) - -/-- Surjectivity of a map descends to the map induced on localizations. -/ -theorem map_surjective_of_surjective (h : Function.Surjective g) [IsLocalization (M.map g) Q] : - Function.Surjective (map Q g M.le_comap_map : S → Q) := - (toLocalizationMap M S).map_surjective_of_surjective h (toLocalizationMap (M.map g) Q) - -end - end IsLocalization section -variable (M) {S} +variable (M) theorem isLocalization_of_algEquiv [Algebra R P] [IsLocalization M S] (h : S ≃ₐ[R] P) : IsLocalization M P := by @@ -769,65 +188,10 @@ theorem isLocalization_iff_of_ringEquiv (h : S ≃+* P) : letI := (h.toRingHom.comp <| algebraMap R S).toAlgebra isLocalization_iff_of_algEquiv M { h with commutes' := fun _ => rfl } -variable (S) - -theorem isLocalization_of_base_ringEquiv [IsLocalization M S] (h : R ≃+* P) : - haveI := ((algebraMap R S).comp h.symm.toRingHom).toAlgebra - IsLocalization (M.map h.toMonoidHom) S := by - letI : Algebra P S := ((algebraMap R S).comp h.symm.toRingHom).toAlgebra - constructor - · rintro ⟨_, ⟨y, hy, rfl⟩⟩ - convert IsLocalization.map_units S ⟨y, hy⟩ - dsimp only [RingHom.algebraMap_toAlgebra, RingHom.comp_apply] - exact congr_arg _ (h.symm_apply_apply _) - · intro y - obtain ⟨⟨x, s⟩, e⟩ := IsLocalization.surj M y - refine ⟨⟨h x, _, _, s.prop, rfl⟩, ?_⟩ - dsimp only [RingHom.algebraMap_toAlgebra, RingHom.comp_apply] at e ⊢ - convert e <;> exact h.symm_apply_apply _ - · intro x y - rw [RingHom.algebraMap_toAlgebra, RingHom.comp_apply, RingHom.comp_apply, - IsLocalization.eq_iff_exists M S] - simp_rw [← h.toEquiv.apply_eq_iff_eq] - change (∃ c : M, h (c * h.symm x) = h (c * h.symm y)) → _ - simp only [RingEquiv.apply_symm_apply, RingEquiv.map_mul] - exact fun ⟨c, e⟩ ↦ ⟨⟨_, _, c.prop, rfl⟩, e⟩ - -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.toMonoidHom) S := by - letI : Algebra P S := ((algebraMap R S).comp h.symm.toRingHom).toAlgebra - refine ⟨fun _ => isLocalization_of_base_ringEquiv M S h, ?_⟩ - intro H - convert isLocalization_of_base_ringEquiv (Submonoid.map (RingEquiv.toMonoidHom h) M) S h.symm - · erw [Submonoid.map_equiv_eq_comap_symm, Submonoid.comap_map_eq_of_injective] - exact h.toEquiv.injective - rw [RingHom.algebraMap_toAlgebra, RingHom.comp_assoc] - simp only [RingHom.comp_id, RingEquiv.symm_symm, RingEquiv.symm_toRingHom_comp_toRingHom] - apply Algebra.algebra_ext - intro r - rw [RingHom.algebraMap_toAlgebra] - end variable (M) -theorem nonZeroDivisors_le_comap [IsLocalization M S] : - nonZeroDivisors R ≤ (nonZeroDivisors S).comap (algebraMap R S) := by - rintro a ha b (e : b * algebraMap R S a = 0) - obtain ⟨x, s, rfl⟩ := mk'_surjective M b - rw [← @mk'_one R _ M, ← mk'_mul, ← (algebraMap R S).map_zero, ← @mk'_one R _ M, - IsLocalization.eq] at e - obtain ⟨c, e⟩ := e - rw [mul_zero, mul_zero, Submonoid.coe_one, one_mul, ← mul_assoc] at e - rw [mk'_eq_zero_iff] - exact ⟨c, ha _ e⟩ - -theorem map_nonZeroDivisors_le [IsLocalization M S] : - (nonZeroDivisors R).map (algebraMap R S) ≤ nonZeroDivisors S := - Submonoid.map_le_iff_le_comap.mpr (nonZeroDivisors_le_comap M S) - /-- If `S₁` is the localization of `R` at `M₁` and `S₂` is the localization of `R` at `M₂`, then every localization `T` of `S₂` at `M₁` is also a localization of `S₁` at `M₂`, in other words `M₁⁻¹M₂⁻¹R` can be identified with `M₂⁻¹M₁⁻¹R`. -/ @@ -876,74 +240,6 @@ namespace Localization open IsLocalization -/-! ### Constructing a localization at a given submonoid -/ - -section - -instance instUniqueLocalization [Subsingleton R] : Unique (Localization M) where - uniq a := by - with_unfolding_all show a = mk 1 1 - exact Localization.induction_on a fun _ => by - congr <;> apply Subsingleton.elim - -theorem add_mk (a b c d) : (mk a b : Localization M) + mk c d = - mk ((b : R) * c + (d : R) * a) (b * d) := by - rw [add_comm (b * c) (d * a), mul_comm b d] - exact OreLocalization.oreDiv_add_oreDiv - -theorem add_mk_self (a b c) : (mk a b : Localization M) + mk c b = mk (a + c) b := by - rw [add_mk, mk_eq_mk_iff, r_eq_r'] - refine (r' M).symm ⟨1, ?_⟩ - simp only [Submonoid.coe_one, Submonoid.coe_mul] - ring - -/-- For any given denominator `b : M`, the map `a ↦ a / b` is an `AddMonoidHom` from `R` to - `Localization M`-/ -@[simps] -def mkAddMonoidHom (b : M) : R →+ Localization M where - toFun a := mk a b - map_zero' := mk_zero _ - map_add' _ _ := (add_mk_self _ _ _).symm - -theorem mk_sum {ι : Type*} (f : ι → R) (s : Finset ι) (b : M) : - mk (∑ i ∈ s, f i) b = ∑ i ∈ s, mk (f i) b := - map_sum (mkAddMonoidHom b) f s - -theorem mk_list_sum (l : List R) (b : M) : mk l.sum b = (l.map fun a => mk a b).sum := - map_list_sum (mkAddMonoidHom b) l - -theorem mk_multiset_sum (l : Multiset R) (b : M) : mk l.sum b = (l.map fun a => mk a b).sum := - (mkAddMonoidHom b).map_multiset_sum l - -instance isLocalization : IsLocalization M (Localization M) where - map_units' := (Localization.monoidOf M).map_units - surj' := (Localization.monoidOf M).surj - exists_of_eq := (Localization.monoidOf M).eq_iff_exists.mp - -end - -@[simp] -theorem toLocalizationMap_eq_monoidOf : toLocalizationMap M (Localization M) = monoidOf M := - rfl - -theorem monoidOf_eq_algebraMap (x) : (monoidOf M).toMap x = algebraMap R (Localization M) x := - rfl - -theorem mk_one_eq_algebraMap (x) : mk x 1 = algebraMap R (Localization M) x := - rfl - -theorem mk_eq_mk'_apply (x y) : mk x y = IsLocalization.mk' (Localization M) x y := by - rw [mk_eq_monoidOf_mk'_apply, mk', toLocalizationMap_eq_monoidOf] - --- Porting note: removed `simp`. Left hand side can be simplified; not clear what normal form should ---be. -theorem mk_eq_mk' : (mk : R → M → Localization M) = IsLocalization.mk' (Localization M) := - mk_eq_monoidOf_mk' - -theorem mk_algebraMap {A : Type*} [CommSemiring A] [Algebra A R] (m : A) : - mk (algebraMap A R m) 1 = algebraMap A (Localization M) m := by - rw [mk_eq_mk', mk'_eq_iff_eq_mul, Submonoid.coe_one, map_one, mul_one]; rfl - theorem mk_natCast (m : ℕ) : (mk m 1 : Localization M) = m := by simpa using mk_algebraMap (R := R) (A := ℕ) _ @@ -954,7 +250,7 @@ variable [IsLocalization M S] section -variable (M) +variable (S) (M) /-- The localization of `R` at `M` as a quotient type is isomorphic to any other localization. -/ @[simps!] @@ -1002,12 +298,6 @@ variable [Algebra R S] {P : Type*} [CommRing P] namespace Localization -theorem neg_mk (a b) : -(mk a b : Localization M) = mk (-a) b := OreLocalization.neg_def _ _ - -theorem sub_mk (a c) (b d) : (mk a b : Localization M) - mk c d = - mk ((d : R) * a - b * c) (b * d) := by - rw [sub_eq_add_neg, neg_mk, add_mk, add_comm, mul_neg, ← sub_eq_add_neg] - theorem mk_intCast (m : ℤ) : (mk m 1 : Localization M) = m := by simpa using mk_algebraMap (R := R) (A := ℤ) _ @@ -1016,80 +306,6 @@ alias mk_int_cast := mk_intCast end Localization -namespace IsLocalization - -variable {K : Type*} [IsLocalization M S] - -theorem to_map_eq_zero_iff {x : R} (hM : M ≤ nonZeroDivisors R) : algebraMap R S x = 0 ↔ x = 0 := by - rw [← (algebraMap R S).map_zero] - constructor <;> intro h - · cases' (eq_iff_exists M S).mp h with c hc - rw [mul_zero, mul_comm] at hc - exact hM c.2 x hc - · rw [h] - -protected theorem injective (hM : M ≤ nonZeroDivisors R) : Injective (algebraMap R S) := by - rw [injective_iff_map_eq_zero (algebraMap R S)] - intro a ha - rwa [to_map_eq_zero_iff S hM] at ha - -protected theorem to_map_ne_zero_of_mem_nonZeroDivisors [Nontrivial R] (hM : M ≤ nonZeroDivisors R) - {x : R} (hx : x ∈ nonZeroDivisors R) : algebraMap R S x ≠ 0 := - show (algebraMap R S).toMonoidWithZeroHom x ≠ 0 from - map_ne_zero_of_mem_nonZeroDivisors (algebraMap R S) (IsLocalization.injective S hM) hx - -variable {S} - -theorem sec_snd_ne_zero [Nontrivial R] (hM : M ≤ nonZeroDivisors R) (x : S) : - ((sec M x).snd : R) ≠ 0 := - nonZeroDivisors.coe_ne_zero ⟨(sec M x).snd.val, hM (sec M x).snd.property⟩ - -theorem sec_fst_ne_zero [Nontrivial R] [NoZeroDivisors S] (hM : M ≤ nonZeroDivisors R) {x : S} - (hx : x ≠ 0) : (sec M x).fst ≠ 0 := by - have hsec := sec_spec M x - intro hfst - rw [hfst, map_zero, mul_eq_zero, _root_.map_eq_zero_iff] at hsec - · exact Or.elim hsec hx (sec_snd_ne_zero hM x) - · exact IsLocalization.injective S hM - -variable {Q : Type*} [CommRing Q] {g : R →+* P} [Algebra P Q] -variable (A : Type*) [CommRing A] [IsDomain A] - -/-- A `CommRing` `S` which is the localization of a ring `R` without zero divisors at a subset of -non-zero elements does not have zero divisors. -/ -theorem noZeroDivisors_of_le_nonZeroDivisors [Algebra A S] {M : Submonoid A} [IsLocalization M S] - (hM : M ≤ nonZeroDivisors A) : NoZeroDivisors S := - { eq_zero_or_eq_zero_of_mul_eq_zero := by - intro z w h - cases' surj M z with x hx - cases' surj M w with y hy - have : - z * w * algebraMap A S y.2 * algebraMap A S x.2 = algebraMap A S x.1 * algebraMap A S y.1 := - by rw [mul_assoc z, hy, ← hx]; ring - rw [h, zero_mul, zero_mul, ← (algebraMap A S).map_mul] at this - cases' eq_zero_or_eq_zero_of_mul_eq_zero ((to_map_eq_zero_iff S hM).mp this.symm) with H H - · exact Or.inl (eq_zero_of_fst_eq_zero hx H) - · exact Or.inr (eq_zero_of_fst_eq_zero hy H) } - -/-- A `CommRing` `S` which is the localization of an integral domain `R` at a subset of -non-zero elements is an integral domain. -/ -theorem isDomain_of_le_nonZeroDivisors [Algebra A S] {M : Submonoid A} [IsLocalization M S] - (hM : M ≤ nonZeroDivisors A) : IsDomain S := by - apply @NoZeroDivisors.to_isDomain _ _ (id _) (id _) - · exact - ⟨⟨(algebraMap A S) 0, (algebraMap A S) 1, fun h => - zero_ne_one (IsLocalization.injective S hM h)⟩⟩ - · exact noZeroDivisors_of_le_nonZeroDivisors _ hM - -variable {A} - -/-- The localization of an integral domain to a set of non-zero elements is an integral domain. -/ -theorem isDomain_localization {M : Submonoid A} (hM : M ≤ nonZeroDivisors A) : - IsDomain (Localization M) := - isDomain_of_le_nonZeroDivisors _ hM - -end IsLocalization - open IsLocalization /-- If `R` is a field, then localizing at a submonoid not containing `0` adds no new elements. -/ diff --git a/Mathlib/RingTheory/Localization/Defs.lean b/Mathlib/RingTheory/Localization/Defs.lean new file mode 100644 index 00000000000000..4206bfa0fece7f --- /dev/null +++ b/Mathlib/RingTheory/Localization/Defs.lean @@ -0,0 +1,901 @@ +/- +Copyright (c) 2018 Kenny Lau. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Kenny Lau, Mario Carneiro, Johan Commelin, Amelia Livingston, Anne Baanen +-/ +import Mathlib.GroupTheory.MonoidLocalization.MonoidWithZero +import Mathlib.RingTheory.OreLocalization.Ring +import Mathlib.Tactic.Ring + +/-! +# Localizations of commutative rings + +We characterize the localization of a commutative ring `R` at a submonoid `M` up to +isomorphism; that is, a commutative ring `S` is the localization of `R` at `M` iff we can find a +ring homomorphism `f : R →+* S` satisfying 3 properties: +1. For all `y ∈ M`, `f y` is a unit; +2. For all `z : S`, there exists `(x, y) : R × M` such that `z * f y = f x`; +3. For all `x, y : R` such that `f x = f y`, there exists `c ∈ M` such that `x * c = y * c`. + (The converse is a consequence of 1.) + +In the following, let `R, P` be commutative rings, `S, Q` be `R`- and `P`-algebras +and `M, T` be submonoids of `R` and `P` respectively, e.g.: +``` +variable (R S P Q : Type*) [CommRing R] [CommRing S] [CommRing P] [CommRing Q] +variable [Algebra R S] [Algebra P Q] (M : Submonoid R) (T : Submonoid P) +``` + +## Main definitions + + * `IsLocalization (M : Submonoid R) (S : Type*)` is a typeclass expressing that `S` is a + localization of `R` at `M`, i.e. the canonical map `algebraMap R S : R →+* S` is a + localization map (satisfying the above properties). + * `IsLocalization.mk' S` is a surjection sending `(x, y) : R × M` to `f x * (f y)⁻¹` + * `IsLocalization.lift` is the ring homomorphism from `S` induced by a homomorphism from `R` + which maps elements of `M` to invertible elements of the codomain. + * `IsLocalization.map S Q` is the ring homomorphism from `S` to `Q` which maps elements + of `M` to elements of `T` + * `IsLocalization.ringEquivOfRingEquiv`: if `R` and `P` are isomorphic by an isomorphism + sending `M` to `T`, then `S` and `Q` are isomorphic + +## Main results + + * `Localization M S`, a construction of the localization as a quotient type, defined in + `GroupTheory.MonoidLocalization`, has `CommRing`, `Algebra R` and `IsLocalization M` + instances if `R` is a ring. `Localization.Away`, `Localization.AtPrime` and `FractionRing` + are abbreviations for `Localization`s and have their corresponding `IsLocalization` instances + +## Implementation notes + +In maths it is natural to reason up to isomorphism, but in Lean we cannot naturally `rewrite` one +structure with an isomorphic one; one way around this is to isolate a predicate characterizing +a structure up to isomorphism, and reason about things that satisfy the predicate. + +A previous version of this file used a fully bundled type of ring localization maps, +then used a type synonym `f.codomain` for `f : LocalizationMap M S` to instantiate the +`R`-algebra structure on `S`. This results in defining ad-hoc copies for everything already +defined on `S`. By making `IsLocalization` a predicate on the `algebraMap R S`, +we can ensure the localization map commutes nicely with other `algebraMap`s. + +To prove most lemmas about a localization map `algebraMap R S` in this file we invoke the +corresponding proof for the underlying `CommMonoid` localization map +`IsLocalization.toLocalizationMap M S`, which can be found in `GroupTheory.MonoidLocalization` +and the namespace `Submonoid.LocalizationMap`. + +To reason about the localization as a quotient type, use `mk_eq_of_mk'` and associated lemmas. +These show the quotient map `mk : R → M → Localization M` equals the surjection +`LocalizationMap.mk'` induced by the map `algebraMap : R →+* Localization M`. +The lemma `mk_eq_of_mk'` hence gives you access to the results in the rest of the file, +which are about the `LocalizationMap.mk'` induced by any localization map. + +The proof that "a `CommRing` `K` which is the localization of an integral domain `R` at `R \ {0}` +is a field" is a `def` rather than an `instance`, so if you want to reason about a field of +fractions `K`, assume `[Field K]` instead of just `[CommRing K]`. + +## Tags +localization, ring localization, commutative ring localization, characteristic predicate, +commutative ring, field of fractions +-/ + +assert_not_exists AlgHom +assert_not_exists Ideal + +open Function + +section CommSemiring + +variable {R : Type*} [CommSemiring R] (M : Submonoid R) (S : Type*) [CommSemiring S] +variable [Algebra R S] {P : Type*} [CommSemiring P] + +/-- The typeclass `IsLocalization (M : Submonoid R) S` where `S` is an `R`-algebra +expresses that `S` is isomorphic to the localization of `R` at `M`. -/ +@[mk_iff] class IsLocalization : Prop where + -- Porting note: add ' to fields, and made new versions of these with either `S` or `M` explicit. + /-- Everything in the image of `algebraMap` is a unit -/ + map_units' : ∀ y : M, IsUnit (algebraMap R S y) + /-- The `algebraMap` is surjective -/ + surj' : ∀ z : S, ∃ x : R × M, z * algebraMap R S x.2 = algebraMap R S x.1 + /-- The kernel of `algebraMap` is contained in the annihilator of `M`; + it is then equal to the annihilator by `map_units'` -/ + exists_of_eq : ∀ {x y}, algebraMap R S x = algebraMap R S y → ∃ c : M, ↑c * x = ↑c * y + +variable {M} + +namespace IsLocalization + +section IsLocalization + +variable [IsLocalization M S] + +section + +@[inherit_doc IsLocalization.map_units'] +theorem map_units : ∀ y : M, IsUnit (algebraMap R S y) := + IsLocalization.map_units' + +variable (M) {S} +@[inherit_doc IsLocalization.surj'] +theorem surj : ∀ z : S, ∃ x : R × M, z * algebraMap R S x.2 = algebraMap R S x.1 := + IsLocalization.surj' + +variable (S) +@[inherit_doc IsLocalization.exists_of_eq] +theorem eq_iff_exists {x y} : algebraMap R S x = algebraMap R S y ↔ ∃ c : M, ↑c * x = ↑c * y := + Iff.intro IsLocalization.exists_of_eq fun ⟨c, h⟩ ↦ by + apply_fun algebraMap R S at h + rw [map_mul, map_mul] at h + exact (IsLocalization.map_units S c).mul_right_inj.mp h + +variable {S} +theorem of_le (N : Submonoid R) (h₁ : M ≤ N) (h₂ : ∀ r ∈ N, IsUnit (algebraMap R S r)) : + IsLocalization N S where + map_units' r := h₂ r r.2 + surj' s := + have ⟨⟨x, y, hy⟩, H⟩ := IsLocalization.surj M s + ⟨⟨x, y, h₁ hy⟩, H⟩ + exists_of_eq {x y} := by + rw [IsLocalization.eq_iff_exists M] + rintro ⟨c, hc⟩ + exact ⟨⟨c, h₁ c.2⟩, hc⟩ + +variable (S) + +/-- `IsLocalization.toLocalizationWithZeroMap M S` shows `S` is the monoid localization of +`R` at `M`. -/ +@[simps] +def toLocalizationWithZeroMap : Submonoid.LocalizationWithZeroMap M S where + __ := algebraMap R S + toFun := algebraMap R S + map_units' := IsLocalization.map_units _ + surj' := IsLocalization.surj _ + exists_of_eq _ _ := IsLocalization.exists_of_eq + +/-- `IsLocalization.toLocalizationMap M S` shows `S` is the monoid localization of `R` at `M`. -/ +abbrev toLocalizationMap : Submonoid.LocalizationMap M S := + (toLocalizationWithZeroMap M S).toLocalizationMap + +@[simp] +theorem toLocalizationMap_toMap : (toLocalizationMap M S).toMap = (algebraMap R S : R →*₀ S) := + rfl + +theorem toLocalizationMap_toMap_apply (x) : (toLocalizationMap M S).toMap x = algebraMap R S x := + rfl + +theorem surj₂ : ∀ z w : S, ∃ z' w' : R, ∃ d : M, + (z * algebraMap R S d = algebraMap R S z') ∧ (w * algebraMap R S d = algebraMap R S w') := + (toLocalizationMap M S).surj₂ + +end + +variable (M) {S} + +/-- Given a localization map `f : M →* N`, a section function sending `z : N` to some +`(x, y) : M × S` such that `f x * (f y)⁻¹ = z`. -/ +noncomputable def sec (z : S) : R × M := + Classical.choose <| IsLocalization.surj _ z + +@[simp] +theorem toLocalizationMap_sec : (toLocalizationMap M S).sec = sec M := + rfl + +/-- Given `z : S`, `IsLocalization.sec M z` is defined to be a pair `(x, y) : R × M` such +that `z * f y = f x` (so this lemma is true by definition). -/ +theorem sec_spec (z : S) : + z * algebraMap R S (IsLocalization.sec M z).2 = algebraMap R S (IsLocalization.sec M z).1 := + Classical.choose_spec <| IsLocalization.surj _ z + +/-- Given `z : S`, `IsLocalization.sec M z` is defined to be a pair `(x, y) : R × M` such +that `z * f y = f x`, so this lemma is just an application of `S`'s commutativity. -/ +theorem sec_spec' (z : S) : + algebraMap R S (IsLocalization.sec M z).1 = algebraMap R S (IsLocalization.sec M z).2 * z := by + rw [mul_comm, sec_spec] + +variable {M} + +/-- If `M` contains `0` then the localization at `M` is trivial. -/ +theorem subsingleton (h : 0 ∈ M) : Subsingleton S := (toLocalizationMap M S).subsingleton h + +theorem map_right_cancel {x y} {c : M} (h : algebraMap R S (c * x) = algebraMap R S (c * y)) : + algebraMap R S x = algebraMap R S y := + (toLocalizationMap M S).map_right_cancel h + +theorem map_left_cancel {x y} {c : M} (h : algebraMap R S (x * c) = algebraMap R S (y * c)) : + algebraMap R S x = algebraMap R S y := + (toLocalizationMap M S).map_left_cancel h + +theorem eq_zero_of_fst_eq_zero {z x} {y : M} (h : z * algebraMap R S y = algebraMap R S x) + (hx : x = 0) : z = 0 := by + rw [hx, (algebraMap R S).map_zero] at h + exact (IsUnit.mul_left_eq_zero (IsLocalization.map_units S y)).1 h + +variable (M S) + +theorem map_eq_zero_iff (r : R) : algebraMap R S r = 0 ↔ ∃ m : M, ↑m * r = 0 := by + constructor + · intro h + obtain ⟨m, hm⟩ := (IsLocalization.eq_iff_exists M S).mp ((algebraMap R S).map_zero.trans h.symm) + exact ⟨m, by simpa using hm.symm⟩ + · rintro ⟨m, hm⟩ + rw [← (IsLocalization.map_units S m).mul_right_inj, mul_zero, ← RingHom.map_mul, hm, + RingHom.map_zero] + +variable {M} + +/-- `IsLocalization.mk' S` is the surjection sending `(x, y) : R × M` to +`f x * (f y)⁻¹`. -/ +noncomputable def mk' (x : R) (y : M) : S := + (toLocalizationMap M S).mk' x y + +@[simp] +theorem mk'_sec (z : S) : mk' S (IsLocalization.sec M z).1 (IsLocalization.sec M z).2 = z := + (toLocalizationMap M S).mk'_sec _ + +theorem mk'_mul (x₁ x₂ : R) (y₁ y₂ : M) : mk' S (x₁ * x₂) (y₁ * y₂) = mk' S x₁ y₁ * mk' S x₂ y₂ := + (toLocalizationMap M S).mk'_mul _ _ _ _ + +theorem mk'_one (x) : mk' S x (1 : M) = algebraMap R S x := + (toLocalizationMap M S).mk'_one _ + +@[simp] +theorem mk'_spec (x) (y : M) : mk' S x y * algebraMap R S y = algebraMap R S x := + (toLocalizationMap M S).mk'_spec _ _ + +@[simp] +theorem mk'_spec' (x) (y : M) : algebraMap R S y * mk' S x y = algebraMap R S x := + (toLocalizationMap M S).mk'_spec' _ _ + +@[simp] +theorem mk'_spec_mk (x) (y : R) (hy : y ∈ M) : + mk' S x ⟨y, hy⟩ * algebraMap R S y = algebraMap R S x := + mk'_spec S x ⟨y, hy⟩ + +@[simp] +theorem mk'_spec'_mk (x) (y : R) (hy : y ∈ M) : + algebraMap R S y * mk' S x ⟨y, hy⟩ = algebraMap R S x := + mk'_spec' S x ⟨y, hy⟩ + +variable {S} + +theorem eq_mk'_iff_mul_eq {x} {y : M} {z} : + z = mk' S x y ↔ z * algebraMap R S y = algebraMap R S x := + (toLocalizationMap M S).eq_mk'_iff_mul_eq + +theorem eq_mk'_of_mul_eq {x : R} {y : M} {z : R} (h : z * y = x) : (algebraMap R S) z = mk' S x y := + eq_mk'_iff_mul_eq.mpr (by rw [← h, map_mul]) + +theorem mk'_eq_iff_eq_mul {x} {y : M} {z} : + mk' S x y = z ↔ algebraMap R S x = z * algebraMap R S y := + (toLocalizationMap M S).mk'_eq_iff_eq_mul + +theorem mk'_add_eq_iff_add_mul_eq_mul {x} {y : M} {z₁ z₂} : + mk' S x y + z₁ = z₂ ↔ algebraMap R S x + z₁ * algebraMap R S y = z₂ * algebraMap R S y := by + rw [← mk'_spec S x y, ← IsUnit.mul_left_inj (IsLocalization.map_units S y), right_distrib] + +theorem mk'_pow (x : R) (y : M) (n : ℕ) : mk' S (x ^ n) (y ^ n) = mk' S x y ^ n := by + simp_rw [IsLocalization.mk'_eq_iff_eq_mul, SubmonoidClass.coe_pow, map_pow, ← mul_pow] + simp + +variable (M) + +theorem mk'_surjective (z : S) : ∃ (x : _) (y : M), mk' S x y = z := + let ⟨r, hr⟩ := IsLocalization.surj _ z + ⟨r.1, r.2, (eq_mk'_iff_mul_eq.2 hr).symm⟩ + +variable (S) + +/-- The localization of a `Fintype` is a `Fintype`. Cannot be an instance. -/ +noncomputable def fintype' [Fintype R] : Fintype S := + have := Classical.propDecidable + Fintype.ofSurjective (Function.uncurry <| IsLocalization.mk' S) fun a => + Prod.exists'.mpr <| IsLocalization.mk'_surjective M a + +variable {M S} + +/-- Localizing at a submonoid with 0 inside it leads to the trivial ring. -/ +def uniqueOfZeroMem (h : (0 : R) ∈ M) : Unique S := + uniqueOfZeroEqOne <| by simpa using IsLocalization.map_units S ⟨0, h⟩ + +theorem mk'_eq_iff_eq {x₁ x₂} {y₁ y₂ : M} : + mk' S x₁ y₁ = mk' S x₂ y₂ ↔ algebraMap R S (y₂ * x₁) = algebraMap R S (y₁ * x₂) := + (toLocalizationMap M S).mk'_eq_iff_eq + +theorem mk'_eq_iff_eq' {x₁ x₂} {y₁ y₂ : M} : + mk' S x₁ y₁ = mk' S x₂ y₂ ↔ algebraMap R S (x₁ * y₂) = algebraMap R S (x₂ * y₁) := + (toLocalizationMap M S).mk'_eq_iff_eq' + +protected theorem eq {a₁ b₁} {a₂ b₂ : M} : + mk' S a₁ a₂ = mk' S b₁ b₂ ↔ ∃ c : M, ↑c * (↑b₂ * a₁) = c * (a₂ * b₁) := + (toLocalizationMap M S).eq + +theorem mk'_eq_zero_iff (x : R) (s : M) : mk' S x s = 0 ↔ ∃ m : M, ↑m * x = 0 := by + rw [← (map_units S s).mul_left_inj, mk'_spec, zero_mul, map_eq_zero_iff M] + +@[simp] +theorem mk'_zero (s : M) : IsLocalization.mk' S 0 s = 0 := by + rw [eq_comm, IsLocalization.eq_mk'_iff_mul_eq, zero_mul, map_zero] + +theorem ne_zero_of_mk'_ne_zero {x : R} {y : M} (hxy : IsLocalization.mk' S x y ≠ 0) : x ≠ 0 := by + rintro rfl + exact hxy (IsLocalization.mk'_zero _) + +section Ext + +theorem eq_iff_eq [Algebra R P] [IsLocalization M P] {x y} : + algebraMap R S x = algebraMap R S y ↔ algebraMap R P x = algebraMap R P y := + (toLocalizationMap M S).eq_iff_eq (toLocalizationMap M P) + +theorem mk'_eq_iff_mk'_eq [Algebra R P] [IsLocalization M P] {x₁ x₂} {y₁ y₂ : M} : + mk' S x₁ y₁ = mk' S x₂ y₂ ↔ mk' P x₁ y₁ = mk' P x₂ y₂ := + (toLocalizationMap M S).mk'_eq_iff_mk'_eq (toLocalizationMap M P) + +theorem mk'_eq_of_eq {a₁ b₁ : R} {a₂ b₂ : M} (H : ↑a₂ * b₁ = ↑b₂ * a₁) : + mk' S a₁ a₂ = mk' S b₁ b₂ := + (toLocalizationMap M S).mk'_eq_of_eq H + +theorem mk'_eq_of_eq' {a₁ b₁ : R} {a₂ b₂ : M} (H : b₁ * ↑a₂ = a₁ * ↑b₂) : + mk' S a₁ a₂ = mk' S b₁ b₂ := + (toLocalizationMap M S).mk'_eq_of_eq' H + +theorem mk'_cancel (a : R) (b c : M) : + mk' S (a * c) (b * c) = mk' S a b := (toLocalizationMap M S).mk'_cancel _ _ _ + +variable (S) + +@[simp] +theorem mk'_self {x : R} (hx : x ∈ M) : mk' S x ⟨x, hx⟩ = 1 := + (toLocalizationMap M S).mk'_self _ hx + +@[simp] +theorem mk'_self' {x : M} : mk' S (x : R) x = 1 := + (toLocalizationMap M S).mk'_self' _ + +theorem mk'_self'' {x : M} : mk' S x.1 x = 1 := + mk'_self' _ + +end Ext + +theorem mul_mk'_eq_mk'_of_mul (x y : R) (z : M) : + (algebraMap R S) x * mk' S y z = mk' S (x * y) z := + (toLocalizationMap M S).mul_mk'_eq_mk'_of_mul _ _ _ + +theorem mk'_eq_mul_mk'_one (x : R) (y : M) : mk' S x y = (algebraMap R S) x * mk' S 1 y := + ((toLocalizationMap M S).mul_mk'_one_eq_mk' _ _).symm + +@[simp] +theorem mk'_mul_cancel_left (x : R) (y : M) : mk' S (y * x : R) y = (algebraMap R S) x := + (toLocalizationMap M S).mk'_mul_cancel_left _ _ + +theorem mk'_mul_cancel_right (x : R) (y : M) : mk' S (x * y) y = (algebraMap R S) x := + (toLocalizationMap M S).mk'_mul_cancel_right _ _ + +@[simp] +theorem mk'_mul_mk'_eq_one (x y : M) : mk' S (x : R) y * mk' S (y : R) x = 1 := by + rw [← mk'_mul, mul_comm]; exact mk'_self _ _ + +theorem mk'_mul_mk'_eq_one' (x : R) (y : M) (h : x ∈ M) : mk' S x y * mk' S (y : R) ⟨x, h⟩ = 1 := + mk'_mul_mk'_eq_one ⟨x, h⟩ _ + +theorem smul_mk' (x y : R) (m : M) : x • mk' S y m = mk' S (x * y) m := by + nth_rw 2 [← one_mul m] + rw [mk'_mul, mk'_one, Algebra.smul_def] + +@[simp] theorem smul_mk'_one (x : R) (m : M) : x • mk' S 1 m = mk' S x m := by + rw [smul_mk', mul_one] + +@[simp] lemma smul_mk'_self {m : M} {r : R} : + (m : R) • mk' S r m = algebraMap R S r := by + rw [smul_mk', mk'_mul_cancel_left] + +@[simps] +instance invertible_mk'_one (s : M) : Invertible (IsLocalization.mk' S (1 : R) s) where + invOf := algebraMap R S s + invOf_mul_self := by simp + mul_invOf_self := by simp + +section + +variable (M) + +theorem isUnit_comp (j : S →+* P) (y : M) : IsUnit (j.comp (algebraMap R S) y) := + (toLocalizationMap M S).isUnit_comp j.toMonoidHom _ + +end + +/-- Given a localization map `f : R →+* S` for a submonoid `M ⊆ R` and a map of `CommSemiring`s +`g : R →+* P` such that `g(M) ⊆ Units P`, `f x = f y → g x = g y` for all `x y : R`. -/ +theorem eq_of_eq {g : R →+* P} (hg : ∀ y : M, IsUnit (g y)) {x y} + (h : (algebraMap R S) x = (algebraMap R S) y) : g x = g y := + Submonoid.LocalizationMap.eq_of_eq (toLocalizationMap M S) (g := g.toMonoidHom) hg h + +theorem mk'_add (x₁ x₂ : R) (y₁ y₂ : M) : + mk' S (x₁ * y₂ + x₂ * y₁) (y₁ * y₂) = mk' S x₁ y₁ + mk' S x₂ y₂ := + mk'_eq_iff_eq_mul.2 <| + Eq.symm + (by + rw [mul_comm (_ + _), mul_add, mul_mk'_eq_mk'_of_mul, mk'_add_eq_iff_add_mul_eq_mul, + mul_comm (_ * _), ← mul_assoc, add_comm, ← map_mul, mul_mk'_eq_mk'_of_mul, + mk'_add_eq_iff_add_mul_eq_mul] + simp only [map_add, Submonoid.coe_mul, map_mul] + ring) + +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 + rw [mul_comm, ← one_mul z₁, ← Units.inv_mul (IsUnit.liftRight (g.toMonoidHom.restrict 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] + +theorem lift_spec_mul_add {g : R →+* P} (hg : ∀ y : M, IsUnit (g y)) (z w w' v) : + ((toLocalizationWithZeroMap M S).lift g.toMonoidWithZeroHom hg) z * w + w' = v ↔ + g ((toLocalizationMap M S).sec z).1 * w + g ((toLocalizationMap M S).sec z).2 * w' = + g ((toLocalizationMap M S).sec z).2 * v := by + erw [mul_comm, ← mul_assoc, mul_add_inv_left hg, mul_comm] + rfl + +/-- Given a localization map `f : R →+* S` for a submonoid `M ⊆ R` and a map of `CommSemiring`s +`g : R →+* P` such that `g y` is invertible for all `y : M`, the homomorphism induced from +`S` to `P` sending `z : S` to `g x * (g y)⁻¹`, where `(x, y) : R × M` are such that +`z = f x * (f y)⁻¹`. -/ +noncomputable def lift {g : R →+* P} (hg : ∀ y : M, IsUnit (g y)) : S →+* P := + { Submonoid.LocalizationWithZeroMap.lift (toLocalizationWithZeroMap M S) + g.toMonoidWithZeroHom hg with + map_add' := by + intro x y + erw [(toLocalizationMap M S).lift_spec, mul_add, mul_comm, eq_comm, lift_spec_mul_add, + add_comm, mul_comm, mul_assoc, mul_comm, mul_assoc, lift_spec_mul_add] + simp_rw [← mul_assoc] + show g _ * g _ * g _ + g _ * g _ * g _ = g _ * g _ * g _ + simp_rw [← map_mul g, ← map_add g] + apply eq_of_eq (S := S) hg + simp only [sec_spec', toLocalizationMap_sec, map_add, map_mul] + ring } + +variable {g : R →+* P} (hg : ∀ y : M, IsUnit (g y)) + +/-- Given a localization map `f : R →+* S` for a submonoid `M ⊆ R` and a map of `CommSemiring`s +`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)⁻¹ := + (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 := + (toLocalizationMap M S).lift_mk'_spec _ _ _ _ + +@[simp] +theorem lift_eq (x : R) : lift hg ((algebraMap R S) x) = g x := + (toLocalizationMap M S).lift_eq _ _ + +theorem lift_eq_iff {x y : R × M} : + lift hg (mk' S x.1 x.2) = lift hg (mk' S y.1 y.2) ↔ g (x.1 * y.2) = g (y.1 * x.2) := + (toLocalizationMap M S).lift_eq_iff _ + +@[simp] +theorem lift_comp : (lift hg).comp (algebraMap R S) = g := + RingHom.ext <| (DFunLike.ext_iff (F := MonoidHom _ _)).1 <| (toLocalizationMap M S).lift_comp _ + +@[simp] +theorem lift_of_comp (j : S →+* P) : lift (isUnit_comp M j) = j := + RingHom.ext <| (DFunLike.ext_iff (F := MonoidHom _ _)).1 <| + (toLocalizationMap M S).lift_of_comp j.toMonoidHom + +variable (M) + +section +include M + +/-- See note [partially-applied ext lemmas] -/ +theorem monoidHom_ext ⦃j k : S →* P⦄ + (h : j.comp (algebraMap R S : R →* S) = k.comp (algebraMap R S)) : j = k := + Submonoid.LocalizationMap.epic_of_localizationMap (toLocalizationMap M S) <| DFunLike.congr_fun h + +/-- See note [partially-applied ext lemmas] -/ +theorem ringHom_ext ⦃j k : S →+* P⦄ (h : j.comp (algebraMap R S) = k.comp (algebraMap R S)) : + j = k := + RingHom.coe_monoidHom_injective <| monoidHom_ext M <| MonoidHom.ext <| RingHom.congr_fun h + +/-- To show `j` and `k` agree on the whole localization, it suffices to show they agree +on the image of the base ring, if they preserve `1` and `*`. -/ +protected theorem ext (j k : S → P) (hj1 : j 1 = 1) (hk1 : k 1 = 1) + (hjm : ∀ a b, j (a * b) = j a * j b) (hkm : ∀ a b, k (a * b) = k a * k b) + (h : ∀ a, j (algebraMap R S a) = k (algebraMap R S a)) : j = k := + let j' : MonoidHom S P := + { toFun := j, map_one' := hj1, map_mul' := hjm } + let k' : MonoidHom S P := + { toFun := k, map_one' := hk1, map_mul' := hkm } + have : j' = k' := monoidHom_ext M (MonoidHom.ext h) + show j'.toFun = k'.toFun by rw [this] +end + +variable {M} + +theorem lift_unique {j : S →+* P} (hj : ∀ x, j ((algebraMap R S) x) = g x) : lift hg = j := + RingHom.ext <| + (DFunLike.ext_iff (F := MonoidHom _ _)).1 <| + Submonoid.LocalizationMap.lift_unique (toLocalizationMap M S) (g := g.toMonoidHom) hg + (j := j.toMonoidHom) hj + +@[simp] +theorem lift_id (x) : lift (map_units S : ∀ _ : M, IsUnit _) x = x := + (toLocalizationMap M S).lift_id _ + +theorem lift_surjective_iff : + Surjective (lift hg : S → P) ↔ ∀ v : P, ∃ x : R × M, v * g x.2 = g x.1 := + (toLocalizationMap M S).lift_surjective_iff hg + +theorem lift_injective_iff : + Injective (lift hg : S → P) ↔ ∀ x y, algebraMap R S x = algebraMap R S y ↔ g x = g y := + (toLocalizationMap M S).lift_injective_iff hg + +section Map + +variable {T : Submonoid P} {Q : Type*} [CommSemiring Q] +variable [Algebra P Q] [IsLocalization T Q] + +section + +variable (Q) + +/-- Map a homomorphism `g : R →+* P` to `S →+* Q`, where `S` and `Q` are +localizations of `R` and `P` at `M` and `T` respectively, +such that `g(M) ⊆ T`. + +We send `z : S` to `algebraMap P Q (g x) * (algebraMap P Q (g y))⁻¹`, where +`(x, y) : R × M` are such that `z = f x * (f y)⁻¹`. -/ +noncomputable def map (g : R →+* P) (hy : M ≤ T.comap g) : S →+* Q := + lift (M := M) (g := (algebraMap P Q).comp g) fun y => map_units _ ⟨g y, hy y.2⟩ + +end + +section +variable (hy : M ≤ T.comap g) +include hy + +-- Porting note: added `simp` attribute, since it proves very similar lemmas marked `simp` +@[simp] +theorem map_eq (x) : map Q g hy ((algebraMap R S) x) = algebraMap P Q (g x) := + lift_eq (fun y => map_units _ ⟨g y, hy y.2⟩) x + +@[simp] +theorem map_comp : (map Q g hy).comp (algebraMap R S) = (algebraMap P Q).comp g := + lift_comp fun y => map_units _ ⟨g y, hy y.2⟩ + +theorem map_mk' (x) (y : M) : map Q g hy (mk' S x y) = mk' Q (g x) ⟨g y, hy y.2⟩ := + Submonoid.LocalizationMap.map_mk' (toLocalizationMap M S) (g := g.toMonoidHom) + (fun y => hy y.2) (k := toLocalizationMap T Q) .. + +theorem map_unique (j : S →+* Q) (hj : ∀ x : R, j (algebraMap R S x) = algebraMap P Q (g x)) : + map Q g hy = j := + lift_unique (fun y => map_units _ ⟨g y, hy y.2⟩) hj + +/-- If `CommSemiring` homs `g : R →+* P, l : P →+* A` induce maps of localizations, the composition +of the induced maps equals the map of localizations induced by `l ∘ g`. -/ +theorem map_comp_map {A : Type*} [CommSemiring A] {U : Submonoid A} {W} [CommSemiring W] + [Algebra A W] [IsLocalization U W] {l : P →+* A} (hl : T ≤ U.comap l) : + (map W l hl).comp (map Q g hy : S →+* _) = map W (l.comp g) fun _ hx => hl (hy hx) := + RingHom.ext fun x => + Submonoid.LocalizationMap.map_map (P := P) (toLocalizationMap M S) (fun y => hy y.2) + (toLocalizationMap U W) (fun w => hl w.2) x + +/-- If `CommSemiring` homs `g : R →+* P, l : P →+* A` induce maps of localizations, the composition +of the induced maps equals the map of localizations induced by `l ∘ g`. -/ +theorem map_map {A : Type*} [CommSemiring A] {U : Submonoid A} {W} [CommSemiring W] [Algebra A W] + [IsLocalization U W] {l : P →+* A} (hl : T ≤ U.comap l) (x : S) : + map W l hl (map Q g hy x) = map W (l.comp g) (fun _ hx => hl (hy hx)) x := by + rw [← map_comp_map (Q := Q) hy hl]; rfl + +theorem map_smul (x : S) (z : R) : map Q g hy (z • x : S) = g z • map Q g hy x := by + rw [Algebra.smul_def, Algebra.smul_def, RingHom.map_mul, map_eq] + +end + +@[simp] +theorem map_id_mk' {Q : Type*} [CommSemiring Q] [Algebra R Q] [IsLocalization M Q] (x) (y : M) : + map Q (RingHom.id R) (le_refl M) (mk' S x y) = mk' Q x y := + map_mk' .. + +@[simp] +theorem map_id (z : S) (h : M ≤ M.comap (RingHom.id R) := le_refl M) : + map S (RingHom.id _) h z = z := + lift_id _ + +section + +variable (S Q) + +/-- 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`. -/ +@[simps] +noncomputable def ringEquivOfRingEquiv (h : R ≃+* P) (H : M.map h.toMonoidHom = T) : S ≃+* Q := + have H' : T.map h.symm.toMonoidHom = M := by + rw [← M.map_id, ← H, Submonoid.map_map] + congr + ext + apply h.symm_apply_apply + { map Q (h : R →+* P) (M.le_comap_of_map_le (le_of_eq H)) with + toFun := map Q (h : R →+* P) (M.le_comap_of_map_le (le_of_eq H)) + invFun := map S (h.symm : P →+* R) (T.le_comap_of_map_le (le_of_eq H')) + left_inv := fun x => by + rw [map_map, map_unique _ (RingHom.id _), RingHom.id_apply] + simp + right_inv := fun x => by + rw [map_map, map_unique _ (RingHom.id _), RingHom.id_apply] + simp } + +end + +theorem ringEquivOfRingEquiv_eq_map {j : R ≃+* P} (H : M.map j.toMonoidHom = T) : + (ringEquivOfRingEquiv S Q j H : S →+* Q) = + map Q (j : R →+* P) (M.le_comap_of_map_le (le_of_eq H)) := + rfl + +-- Porting note (#10618): removed `simp`, `simp` can prove it +theorem ringEquivOfRingEquiv_eq {j : R ≃+* P} (H : M.map j.toMonoidHom = T) (x) : + ringEquivOfRingEquiv S Q j H ((algebraMap R S) x) = algebraMap P Q (j x) := by + simp + +theorem ringEquivOfRingEquiv_mk' {j : R ≃+* P} (H : M.map j.toMonoidHom = T) (x : R) (y : M) : + ringEquivOfRingEquiv S Q j H (mk' S x y) = + mk' Q (j x) ⟨j y, show j y ∈ T from H ▸ Set.mem_image_of_mem j y.2⟩ := by + simp [map_mk'] + +end Map + +section at_units +lemma at_units (S : Submonoid R) + (hS : S ≤ IsUnit.submonoid R) : IsLocalization S R where + map_units' y := hS y.prop + surj' := fun s ↦ ⟨⟨s, 1⟩, by simp⟩ + exists_of_eq := fun {x y} (e : x = y) ↦ ⟨1, e ▸ rfl⟩ + +end at_units + +section + +variable (M S) (Q : Type*) [CommSemiring Q] [Algebra P Q] + +/-- Injectivity of a map descends to the map induced on localizations. -/ +theorem map_injective_of_injective (h : Function.Injective g) [IsLocalization (M.map g) Q] : + Function.Injective (map Q g M.le_comap_map : S → Q) := + (toLocalizationMap M S).map_injective_of_injective h (toLocalizationMap (M.map g) Q) + +/-- Surjectivity of a map descends to the map induced on localizations. -/ +theorem map_surjective_of_surjective (h : Function.Surjective g) [IsLocalization (M.map g) Q] : + Function.Surjective (map Q g M.le_comap_map : S → Q) := + (toLocalizationMap M S).map_surjective_of_surjective h (toLocalizationMap (M.map g) Q) + +end + +end IsLocalization + +section + +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.toMonoidHom) S := by + letI : Algebra P S := ((algebraMap R S).comp h.symm.toRingHom).toAlgebra + constructor + · rintro ⟨_, ⟨y, hy, rfl⟩⟩ + convert IsLocalization.map_units S ⟨y, hy⟩ + dsimp only [RingHom.algebraMap_toAlgebra, RingHom.comp_apply] + exact congr_arg _ (h.symm_apply_apply _) + · intro y + obtain ⟨⟨x, s⟩, e⟩ := IsLocalization.surj M y + refine ⟨⟨h x, _, _, s.prop, rfl⟩, ?_⟩ + dsimp only [RingHom.algebraMap_toAlgebra, RingHom.comp_apply] at e ⊢ + convert e <;> exact h.symm_apply_apply _ + · intro x y + rw [RingHom.algebraMap_toAlgebra, RingHom.comp_apply, RingHom.comp_apply, + IsLocalization.eq_iff_exists M S] + simp_rw [← h.toEquiv.apply_eq_iff_eq] + change (∃ c : M, h (c * h.symm x) = h (c * h.symm y)) → _ + simp only [RingEquiv.apply_symm_apply, RingEquiv.map_mul] + exact fun ⟨c, e⟩ ↦ ⟨⟨_, _, c.prop, rfl⟩, e⟩ + +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.toMonoidHom) S := by + letI : Algebra P S := ((algebraMap R S).comp h.symm.toRingHom).toAlgebra + refine ⟨fun _ => isLocalization_of_base_ringEquiv M S h, ?_⟩ + intro H + convert isLocalization_of_base_ringEquiv (Submonoid.map (RingEquiv.toMonoidHom h) M) S h.symm + · erw [Submonoid.map_equiv_eq_comap_symm, Submonoid.comap_map_eq_of_injective] + exact h.toEquiv.injective + rw [RingHom.algebraMap_toAlgebra, RingHom.comp_assoc] + simp only [RingHom.comp_id, RingEquiv.symm_symm, RingEquiv.symm_toRingHom_comp_toRingHom] + apply Algebra.algebra_ext + intro r + rw [RingHom.algebraMap_toAlgebra] + +end + +variable (M) + +theorem nonZeroDivisors_le_comap [IsLocalization M S] : + nonZeroDivisors R ≤ (nonZeroDivisors S).comap (algebraMap R S) := by + rintro a ha b (e : b * algebraMap R S a = 0) + obtain ⟨x, s, rfl⟩ := mk'_surjective M b + rw [← @mk'_one R _ M, ← mk'_mul, ← (algebraMap R S).map_zero, ← @mk'_one R _ M, + IsLocalization.eq] at e + obtain ⟨c, e⟩ := e + rw [mul_zero, mul_zero, Submonoid.coe_one, one_mul, ← mul_assoc] at e + rw [mk'_eq_zero_iff] + exact ⟨c, ha _ e⟩ + +theorem map_nonZeroDivisors_le [IsLocalization M S] : + (nonZeroDivisors R).map (algebraMap R S) ≤ nonZeroDivisors S := + Submonoid.map_le_iff_le_comap.mpr (nonZeroDivisors_le_comap M S) + +end IsLocalization + +namespace Localization + +open IsLocalization + +/-! ### Constructing a localization at a given submonoid -/ + +section + +instance instUniqueLocalization [Subsingleton R] : Unique (Localization M) where + uniq a := by + with_unfolding_all show a = mk 1 1 + exact Localization.induction_on a fun _ => by + congr <;> apply Subsingleton.elim + +theorem add_mk (a b c d) : (mk a b : Localization M) + mk c d = + mk ((b : R) * c + (d : R) * a) (b * d) := by + rw [add_comm (b * c) (d * a), mul_comm b d] + exact OreLocalization.oreDiv_add_oreDiv + +theorem add_mk_self (a b c) : (mk a b : Localization M) + mk c b = mk (a + c) b := by + rw [add_mk, mk_eq_mk_iff, r_eq_r'] + refine (r' M).symm ⟨1, ?_⟩ + simp only [Submonoid.coe_one, Submonoid.coe_mul] + ring + +/-- For any given denominator `b : M`, the map `a ↦ a / b` is an `AddMonoidHom` from `R` to + `Localization M`-/ +@[simps] +def mkAddMonoidHom (b : M) : R →+ Localization M where + toFun a := mk a b + map_zero' := mk_zero _ + map_add' _ _ := (add_mk_self _ _ _).symm + +theorem mk_sum {ι : Type*} (f : ι → R) (s : Finset ι) (b : M) : + mk (∑ i ∈ s, f i) b = ∑ i ∈ s, mk (f i) b := + map_sum (mkAddMonoidHom b) f s + +theorem mk_list_sum (l : List R) (b : M) : mk l.sum b = (l.map fun a => mk a b).sum := + map_list_sum (mkAddMonoidHom b) l + +theorem mk_multiset_sum (l : Multiset R) (b : M) : mk l.sum b = (l.map fun a => mk a b).sum := + (mkAddMonoidHom b).map_multiset_sum l + +instance isLocalization : IsLocalization M (Localization M) where + map_units' := (Localization.monoidOf M).map_units + surj' := (Localization.monoidOf M).surj + exists_of_eq := (Localization.monoidOf M).eq_iff_exists.mp + +end + +@[simp] +theorem toLocalizationMap_eq_monoidOf : toLocalizationMap M (Localization M) = monoidOf M := + rfl + +theorem monoidOf_eq_algebraMap (x) : (monoidOf M).toMap x = algebraMap R (Localization M) x := + rfl + +theorem mk_one_eq_algebraMap (x) : mk x 1 = algebraMap R (Localization M) x := + rfl + +theorem mk_eq_mk'_apply (x y) : mk x y = IsLocalization.mk' (Localization M) x y := by + rw [mk_eq_monoidOf_mk'_apply, mk', toLocalizationMap_eq_monoidOf] + +-- Porting note: removed `simp`. Left hand side can be simplified; not clear what normal form should +--be. +theorem mk_eq_mk' : (mk : R → M → Localization M) = IsLocalization.mk' (Localization M) := + mk_eq_monoidOf_mk' + +theorem mk_algebraMap {A : Type*} [CommSemiring A] [Algebra A R] (m : A) : + mk (algebraMap A R m) 1 = algebraMap A (Localization M) m := by + rw [mk_eq_mk', mk'_eq_iff_eq_mul, Submonoid.coe_one, map_one, mul_one]; rfl + +end Localization + +end CommSemiring + +section CommRing + +variable {R : Type*} [CommRing R] {M : Submonoid R} (S : Type*) [CommRing S] +variable [Algebra R S] {P : Type*} [CommRing P] + +namespace Localization + +theorem neg_mk (a b) : -(mk a b : Localization M) = mk (-a) b := OreLocalization.neg_def _ _ + +theorem sub_mk (a c) (b d) : (mk a b : Localization M) - mk c d = + mk ((d : R) * a - b * c) (b * d) := by + rw [sub_eq_add_neg, neg_mk, add_mk, add_comm, mul_neg, ← sub_eq_add_neg] + +end Localization + +namespace IsLocalization + +variable {K : Type*} [IsLocalization M S] + +theorem to_map_eq_zero_iff {x : R} (hM : M ≤ nonZeroDivisors R) : algebraMap R S x = 0 ↔ x = 0 := by + rw [← (algebraMap R S).map_zero] + constructor <;> intro h + · cases' (eq_iff_exists M S).mp h with c hc + rw [mul_zero, mul_comm] at hc + exact hM c.2 x hc + · rw [h] + +protected theorem injective (hM : M ≤ nonZeroDivisors R) : Injective (algebraMap R S) := by + rw [injective_iff_map_eq_zero (algebraMap R S)] + intro a ha + rwa [to_map_eq_zero_iff S hM] at ha + +protected theorem to_map_ne_zero_of_mem_nonZeroDivisors [Nontrivial R] (hM : M ≤ nonZeroDivisors R) + {x : R} (hx : x ∈ nonZeroDivisors R) : algebraMap R S x ≠ 0 := + show (algebraMap R S).toMonoidWithZeroHom x ≠ 0 from + map_ne_zero_of_mem_nonZeroDivisors (algebraMap R S) (IsLocalization.injective S hM) hx + +variable {S} + +theorem sec_snd_ne_zero [Nontrivial R] (hM : M ≤ nonZeroDivisors R) (x : S) : + ((sec M x).snd : R) ≠ 0 := + nonZeroDivisors.coe_ne_zero ⟨(sec M x).snd.val, hM (sec M x).snd.property⟩ + +theorem sec_fst_ne_zero [Nontrivial R] [NoZeroDivisors S] (hM : M ≤ nonZeroDivisors R) {x : S} + (hx : x ≠ 0) : (sec M x).fst ≠ 0 := by + have hsec := sec_spec M x + intro hfst + rw [hfst, map_zero, mul_eq_zero, _root_.map_eq_zero_iff] at hsec + · exact Or.elim hsec hx (sec_snd_ne_zero hM x) + · exact IsLocalization.injective S hM + +variable {Q : Type*} [CommRing Q] {g : R →+* P} [Algebra P Q] +variable (A : Type*) [CommRing A] [IsDomain A] + +/-- A `CommRing` `S` which is the localization of a ring `R` without zero divisors at a subset of +non-zero elements does not have zero divisors. -/ +theorem noZeroDivisors_of_le_nonZeroDivisors [Algebra A S] {M : Submonoid A} [IsLocalization M S] + (hM : M ≤ nonZeroDivisors A) : NoZeroDivisors S := + { eq_zero_or_eq_zero_of_mul_eq_zero := by + intro z w h + cases' surj M z with x hx + cases' surj M w with y hy + have : + z * w * algebraMap A S y.2 * algebraMap A S x.2 = algebraMap A S x.1 * algebraMap A S y.1 := + by rw [mul_assoc z, hy, ← hx]; ring + rw [h, zero_mul, zero_mul, ← (algebraMap A S).map_mul] at this + cases' eq_zero_or_eq_zero_of_mul_eq_zero ((to_map_eq_zero_iff S hM).mp this.symm) with H H + · exact Or.inl (eq_zero_of_fst_eq_zero hx H) + · exact Or.inr (eq_zero_of_fst_eq_zero hy H) } + +/-- A `CommRing` `S` which is the localization of an integral domain `R` at a subset of +non-zero elements is an integral domain. -/ +theorem isDomain_of_le_nonZeroDivisors [Algebra A S] {M : Submonoid A} [IsLocalization M S] + (hM : M ≤ nonZeroDivisors A) : IsDomain S := by + apply @NoZeroDivisors.to_isDomain _ _ (id _) (id _) + · exact + ⟨⟨(algebraMap A S) 0, (algebraMap A S) 1, fun h => + zero_ne_one (IsLocalization.injective S hM h)⟩⟩ + · exact noZeroDivisors_of_le_nonZeroDivisors _ hM + +variable {A} + +/-- The localization of an integral domain to a set of non-zero elements is an integral domain. -/ +theorem isDomain_localization {M : Submonoid A} (hM : M ≤ nonZeroDivisors A) : + IsDomain (Localization M) := + isDomain_of_le_nonZeroDivisors _ hM + +end IsLocalization + +end CommRing diff --git a/Mathlib/RingTheory/Localization/Integer.lean b/Mathlib/RingTheory/Localization/Integer.lean index 8c368cd7d7f3a6..57e98b99133568 100644 --- a/Mathlib/RingTheory/Localization/Integer.lean +++ b/Mathlib/RingTheory/Localization/Integer.lean @@ -3,7 +3,9 @@ Copyright (c) 2018 Kenny Lau. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Kenny Lau, Mario Carneiro, Johan Commelin, Amelia Livingston, Anne Baanen -/ -import Mathlib.RingTheory.Localization.Basic +import Mathlib.Algebra.Group.Pointwise.Set.Basic +import Mathlib.Algebra.Ring.Subsemiring.Basic +import Mathlib.RingTheory.Localization.Defs /-! # Integer elements of a localization diff --git a/Mathlib/SetTheory/Surreal/Dyadic.lean b/Mathlib/SetTheory/Surreal/Dyadic.lean index 2fcd752dc36c54..66e64a35705b57 100644 --- a/Mathlib/SetTheory/Surreal/Dyadic.lean +++ b/Mathlib/SetTheory/Surreal/Dyadic.lean @@ -5,11 +5,12 @@ Authors: Apurva Nakade -/ import Mathlib.Algebra.Algebra.Defs import Mathlib.Algebra.Order.Group.Basic -import Mathlib.Algebra.Order.Ring.Basic import Mathlib.GroupTheory.MonoidLocalization.Away -import Mathlib.RingTheory.Localization.Basic +import Mathlib.RingTheory.Localization.Defs import Mathlib.SetTheory.Game.Birthday import Mathlib.SetTheory.Surreal.Multiplication +import Mathlib.Tactic.Linarith +import Mathlib.Algebra.Ring.Regular /-! # Dyadic numbers From d376bfc5782e90bafe2815b936ece41bf3b69f05 Mon Sep 17 00:00:00 2001 From: Robin Carlier <57142648+robin-carlier@users.noreply.github.com> Date: Tue, 15 Oct 2024 07:43:57 +0000 Subject: [PATCH 129/425] feat(CategoryTheory/Limits/Shapes/Reflexive): the walking reflexive pair (#8013) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Define `WalkingReflexivePair`, the category indexing reflexive pair. - Show that the forgetful functor from this category to `WalkingParallelPair` is `Final`. - Show that coequalizers of reflexive pairs are equivalent to colimits of diagrams indexed by `WalkingReflexivePair`. - Show that having coequalizers of all reflexive pairs is equivalent to having all `WalkingReflexivePair`-shaped colimits. Co-authored-by: Joël Riou <37772949+joelriou@users.noreply.github.com> Co-authored-by: Violeta Hernández Co-authored-by: Robin Carlier --- .../Limits/Shapes/Reflexive.lean | 510 +++++++++++++++++- 1 file changed, 504 insertions(+), 6 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean b/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean index 7a9ccc2d5140d5..cb15f1505053c7 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean @@ -1,29 +1,52 @@ /- Copyright (c) 2020 Bhavik Mehta. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Bhavik Mehta +Authors: Bhavik Mehta, Robin Carlier -/ +import Mathlib.CategoryTheory.Limits.Final import Mathlib.CategoryTheory.Limits.Shapes.Equalizers import Mathlib.CategoryTheory.Limits.Shapes.KernelPair /-! # Reflexive coequalizers -We define reflexive pairs as a pair of morphisms which have a common section. We say a category has -reflexive coequalizers if it has coequalizers of all reflexive pairs. -Reflexive coequalizers often enjoy nicer properties than general coequalizers, and feature heavily -in some versions of the monadicity theorem. +This file deals with reflexive pairs, which are pairs of morphisms with a common section. + +A reflexive coequalizer is a coequalizer of such a pair. These kind of coequalizers often enjoy +nicer properties than general coequalizers, and feature heavily in some versions of the monadicity +theorem. We also give some examples of reflexive pairs: for an adjunction `F ⊣ G` with counit `ε`, the pair `(FGε_B, ε_FGB)` is reflexive. If a pair `f,g` is a kernel pair for some morphism, then it is reflexive. +## Main definitions + +* `IsReflexivePair` is the predicate that f and g have a common section. +* `WalkingReflexivePair` is the diagram indexing pairs with a common section. +* A `reflexiveCofork` is a cocone on a diagram indexed by `WalkingReflexivePair`. +* `WalkingReflexivePair.inclusionWalkingReflexivePair` is the inclustion functor from + `WalkingParallelPair` to `WalkingReflexivePair`. It acts on reflexive pairs as forgetting + the common section. +* `HasReflexiveCoequalizers` is the predicate that a category has all colimits of reflexive pairs. +* `reflexiveCoequalizerIsoCoequalizer`: an isomorphism promoting the coequalizer of a reflexive pair + to the colimit of a diagram out of the walking reflexive pair. + +## Main statements + +* `IsKernelPair.isReflexivePair`: A kernel pair is a reflexive pair +* `WalkingParallelPair.inclusionWalkingReflexivePair_final`: The inclusion functor is final. +* `hasReflexiveCoequalizers_iff`: A category has coequalizers of reflexive pairs if and only iff it + has all colimits of shape `WalkingReflexivePair`. + # TODO * If `C` has binary coproducts and reflexive coequalizers, then it has all coequalizers. * If `T` is a monad on cocomplete category `C`, then `Algebra T` is cocomplete iff it has reflexive coequalizers. * If `C` is locally cartesian closed and has reflexive coequalizers, then it has images: in fact regular epi (and hence strong epi) images. +* Bundle the reflexive pairs of kernel pairs and of adjunction as functors out of the walking + reflexive pair. -/ @@ -148,6 +171,481 @@ instance (priority := 100) hasCoreflexiveEqualizers_of_hasEqualizers [HasEqualiz end Limits -open Limits +end CategoryTheory + +namespace CategoryTheory + +universe v v₂ u u₂ + +namespace Limits + +/-- The type of objects for the diagram indexing reflexive (co)equalizers -/ +inductive WalkingReflexivePair : Type where + | zero + | one + deriving DecidableEq, Inhabited + +open WalkingReflexivePair + +namespace WalkingReflexivePair + +/-- The type of morphisms for the diagram indexing reflexive (co)equalizers -/ +inductive Hom : (WalkingReflexivePair → WalkingReflexivePair → Type) + | left : Hom one zero + | right : Hom one zero + | reflexion : Hom zero one + | leftCompReflexion : Hom one one + | rightCompReflexion : Hom one one + | id (X : WalkingReflexivePair) : Hom X X + deriving DecidableEq + +attribute [-simp, nolint simpNF] Hom.id.sizeOf_spec +attribute [-simp, nolint simpNF] Hom.leftCompReflexion.sizeOf_spec +attribute [-simp, nolint simpNF] Hom.rightCompReflexion.sizeOf_spec + +/-- Composition of morphisms in the diagram indexing reflexive (co)equalizers -/ +def Hom.comp : + ∀ { X Y Z : WalkingReflexivePair } (_ : Hom X Y) + (_ : Hom Y Z), Hom X Z + | _, _, _, id _, h => h + | _, _, _, h, id _ => h + | _, _, _, reflexion, left => id zero + | _, _, _, reflexion, right => id zero + | _, _, _, reflexion, rightCompReflexion => reflexion + | _, _, _, reflexion, leftCompReflexion => reflexion + | _, _, _, left, reflexion => leftCompReflexion + | _, _, _, right, reflexion => rightCompReflexion + | _, _, _, rightCompReflexion, rightCompReflexion => rightCompReflexion + | _, _, _, rightCompReflexion, leftCompReflexion => rightCompReflexion + | _, _, _, rightCompReflexion, right => right + | _, _, _, rightCompReflexion, left => right + | _, _, _, leftCompReflexion, left => left + | _, _, _, leftCompReflexion, right => left + | _, _, _, leftCompReflexion, rightCompReflexion => leftCompReflexion + | _, _, _, leftCompReflexion, leftCompReflexion => leftCompReflexion + +instance category : SmallCategory WalkingReflexivePair where + Hom := Hom + id := Hom.id + comp := Hom.comp + comp_id := by intro _ _ f; cases f <;> rfl + id_comp := by intro _ _ f; cases f <;> rfl + assoc := by intro _ _ _ _ f g h; cases f <;> cases g <;> cases h <;> rfl + +open Hom + +@[simp] +lemma Hom.id_eq (X : WalkingReflexivePair) : + Hom.id X = 𝟙 X := by rfl + +@[reassoc (attr := simp)] +lemma reflexion_comp_left : reflexion ≫ left = 𝟙 zero := rfl + +@[reassoc (attr := simp)] +lemma reflexion_comp_right : reflexion ≫ right = 𝟙 zero := rfl + +@[simp] +lemma leftCompReflexion_eq : leftCompReflexion = (left ≫ reflexion : one ⟶ one) := rfl + +@[simp] +lemma rightCompReflexion_eq : rightCompReflexion = (right ≫ reflexion : one ⟶ one) := rfl + +section FunctorsOutOfWalkingReflexivePair + +variable {C : Type u} [Category.{v} C] + +@[reassoc (attr := simp)] +lemma map_reflexion_comp_map_left (F : WalkingReflexivePair ⥤ C) : + F.map reflexion ≫ F.map left = 𝟙 (F.obj zero) := by + rw [← F.map_comp, reflexion_comp_left, F.map_id] + +@[reassoc (attr := simp)] +lemma map_reflexion_comp_map_right (F : WalkingReflexivePair ⥤ C) : + F.map reflexion ≫ F.map right = 𝟙 (F.obj zero) := by + rw [← F.map_comp, reflexion_comp_right, F.map_id] + +end FunctorsOutOfWalkingReflexivePair + +end WalkingReflexivePair + +namespace WalkingParallelPair + +/-- The inclusion functor forgetting the common section -/ +@[simps!] +def inclusionWalkingReflexivePair : WalkingParallelPair ⥤ WalkingReflexivePair where + obj := fun x => match x with + | one => WalkingReflexivePair.zero + | zero => WalkingReflexivePair.one + map := fun f => match f with + | .left => WalkingReflexivePair.Hom.left + | .right => WalkingReflexivePair.Hom.right + | .id _ => WalkingReflexivePair.Hom.id _ + map_comp := by + intro _ _ _ f g; cases f <;> cases g <;> rfl + +variable {C : Type u} [Category.{v} C] + +instance (X : WalkingReflexivePair) : + Nonempty (StructuredArrow X inclusionWalkingReflexivePair) := by + cases X with + | zero => exact ⟨StructuredArrow.mk (Y := one) (𝟙 _)⟩ + | one => exact ⟨StructuredArrow.mk (Y := zero) (𝟙 _)⟩ + +open WalkingReflexivePair.Hom in +instance (X : WalkingReflexivePair) : + IsConnected (StructuredArrow X inclusionWalkingReflexivePair) := by + cases X with + | zero => + refine IsConnected.of_induct (j₀ := StructuredArrow.mk (Y := one) (𝟙 _)) ?_ + rintro p h₁ h₂ ⟨⟨⟨⟩⟩, (_ | _), ⟨_⟩⟩ + · exact (h₂ (StructuredArrow.homMk .left)).2 h₁ + · exact h₁ + | one => + refine IsConnected.of_induct (j₀ := StructuredArrow.mk (Y := zero) (𝟙 _)) + (fun p h₁ h₂ ↦ ?_) + have hₗ : StructuredArrow.mk left ∈ p := (h₂ (StructuredArrow.homMk .left)).1 h₁ + have hᵣ : StructuredArrow.mk right ∈ p := (h₂ (StructuredArrow.homMk .right)).1 h₁ + rintro ⟨⟨⟨⟩⟩, (_ | _), ⟨_⟩⟩ + · exact (h₂ (StructuredArrow.homMk .left)).2 hₗ + · exact (h₂ (StructuredArrow.homMk .right)).2 hᵣ + all_goals assumption + +/-- The inclusion functor is a final functor -/ +instance inclusionWalkingReflexivePair_final : Functor.Final inclusionWalkingReflexivePair where + out := inferInstance + +end WalkingParallelPair + +end Limits + +namespace Limits + +open WalkingReflexivePair + +variable {C : Type u} [Category.{v} C] + +variable {A B : C} + +/-- Bundle the data of a parallel pair along with a common section as a functor out of the walking +reflexive pair -/ +def reflexivePair (f g : A ⟶ B) (s : B ⟶ A) + (sl : s ≫ f = 𝟙 B := by aesop_cat) (sr : s ≫ g = 𝟙 B := by aesop_cat) : + (WalkingReflexivePair ⥤ C) where + obj x := + match x with + | zero => B + | one => A + map h := + match h with + | .id _ => 𝟙 _ + | .left => f + | .right => g + | .reflexion => s + | .rightCompReflexion => g ≫ s + | .leftCompReflexion => f ≫ s + map_comp := by + rintro _ _ _ ⟨⟩ g <;> cases g <;> + simp only [Category.id_comp, Category.comp_id, Category.assoc, sl, sr, + reassoc_of% sl, reassoc_of% sr] <;> rfl + +section + +variable {A B : C} +variable (f g : A ⟶ B) (s : B ⟶ A) {sl : s ≫ f = 𝟙 B} {sr : s ≫ g = 𝟙 B} + +@[simp] lemma reflexivePair_obj_zero : (reflexivePair f g s sl sr).obj zero = B := rfl + +@[simp] lemma reflexivePair_obj_one : (reflexivePair f g s sl sr).obj one = A := rfl + +@[simp] lemma reflexivePair_map_right : (reflexivePair f g s sl sr).map .left = f := rfl + +@[simp] lemma reflexivePair_map_left : (reflexivePair f g s sl sr).map .right = g := rfl + +@[simp] lemma reflexivePair_map_reflexion : (reflexivePair f g s sl sr).map .reflexion = s := rfl + +end + +/-- (Noncomputably) bundle the data of a reflexive pair as a functor out of the walking reflexive +pair -/ +noncomputable def ofIsReflexivePair (f g : A ⟶ B) [IsReflexivePair f g] : + WalkingReflexivePair ⥤ C := reflexivePair f g (commonSection f g) + +@[simp] +lemma ofIsReflexivePair_map_left (f g : A ⟶ B) [IsReflexivePair f g] : + (ofIsReflexivePair f g).map .left = f := rfl + +@[simp] +lemma ofIsReflexivePair_map_right (f g : A ⟶ B) [IsReflexivePair f g] : + (ofIsReflexivePair f g).map .right = g := rfl + +/-- The natural isomorphism between the diagram obtained by forgetting the reflexion of +`ofIsReflexivePair f g` and the original parallel pair. -/ +noncomputable def inclusionWalkingReflexivePairOfIsReflexivePairIso + (f g : A ⟶ B) [IsReflexivePair f g] : + WalkingParallelPair.inclusionWalkingReflexivePair ⋙ (ofIsReflexivePair f g) ≅ + parallelPair f g := + diagramIsoParallelPair _ + +end Limits + +namespace Limits + +variable {C : Type u} [Category.{v} C] + +namespace reflexivePair + +open WalkingReflexivePair WalkingReflexivePair.Hom + +section +section NatTrans + +variable {F G : WalkingReflexivePair ⥤ C} + (e₀ : F.obj zero ⟶ G.obj zero) (e₁ : F.obj one ⟶ G.obj one) + (h₁ : F.map left ≫ e₀ = e₁ ≫ G.map left := by aesop_cat) + (h₂ : F.map right ≫ e₀ = e₁ ≫ G.map right := by aesop_cat) + (h₃ : F.map reflexion ≫ e₁ = e₀ ≫ G.map reflexion := by aesop_cat) + +/-- A constructor for natural transformations between functors from `WalkingReflexivePair`. -/ +def mkNatTrans : F ⟶ G where + app := fun x ↦ match x with + | zero => e₀ + | one => e₁ + naturality _ _ f := by + cases f + all_goals + dsimp + simp only [Functor.map_id, Category.id_comp, Category.comp_id, + Functor.map_comp, h₁, h₂, h₃, reassoc_of% h₁, reassoc_of% h₂, + reflexivePair_map_reflexion, reflexivePair_map_left, reflexivePair_map_right, + Category.assoc] + +@[simp] +lemma mkNatTrans_app_zero : (mkNatTrans e₀ e₁ h₁ h₂ h₃).app zero = e₀ := rfl + +@[simp] +lemma mkNatTrans_app_one : (mkNatTrans e₀ e₁ h₁ h₂ h₃).app one = e₁ := rfl + +end NatTrans +section NatIso + +variable {F G : WalkingReflexivePair ⥤ C} +/-- Constructor for natural isomorphisms between functors out of `WalkingReflexivePair`. -/ +@[simps!] +def mkNatIso (e₀ : F.obj zero ≅ G.obj zero) (e₁ : F.obj one ≅ G.obj one) + (h₁ : F.map left ≫ e₀.hom = e₁.hom ≫ G.map left := by aesop_cat) + (h₂ : F.map right ≫ e₀.hom = e₁.hom ≫ G.map right := by aesop_cat) + (h₃ : F.map reflexion ≫ e₁.hom = e₀.hom ≫ G.map reflexion := by aesop_cat) : + F ≅ G where + hom := mkNatTrans e₀.hom e₁.hom + inv := mkNatTrans e₀.inv e₁.inv + (by rw [← cancel_epi e₁.hom, e₁.hom_inv_id_assoc, ← reassoc_of% h₁, e₀.hom_inv_id, + Category.comp_id]) + (by rw [← cancel_epi e₁.hom, e₁.hom_inv_id_assoc, ← reassoc_of% h₂, e₀.hom_inv_id, + Category.comp_id]) + (by rw [← cancel_epi e₀.hom, e₀.hom_inv_id_assoc, ← reassoc_of% h₃, e₁.hom_inv_id, + Category.comp_id]) + hom_inv_id := by ext x; cases x <;> simp + inv_hom_id := by ext x; cases x <;> simp + +variable (F) + +/-- Every functor out of `WalkingReflexivePair` is isomorphic to the `reflexivePair` given by +its components -/ +@[simps!] +def diagramIsoReflexivePair : + F ≅ reflexivePair (F.map left) (F.map right) (F.map reflexion) := + mkNatIso (Iso.refl _) (Iso.refl _) + +end NatIso + +/-- A `reflexivePair` composed with a functor is isomorphic to the `reflexivePair` obtained by +applying the functor at each map. -/ +@[simps!] +def compRightIso {D : Type u₂} [Category.{v₂} D] {A B : C} + (f g : A ⟶ B) (s : B ⟶ A) (sl : s ≫ f = 𝟙 B) (sr : s ≫ g = 𝟙 B) (F : C ⥤ D) : + (reflexivePair f g s sl sr) ⋙ F ≅ reflexivePair (F.map f) (F.map g) (F.map s) + (by simp only [← Functor.map_comp, sl, Functor.map_id]) + (by simp only [← Functor.map_comp, sr, Functor.map_id]) := + mkNatIso (Iso.refl _) (Iso.refl _) + +lemma whiskerRightMkNatTrans {F G : WalkingReflexivePair ⥤ C} + (e₀ : F.obj zero ⟶ G.obj zero) (e₁ : F.obj one ⟶ G.obj one) + {h₁ : F.map left ≫ e₀ = e₁ ≫ G.map left} + {h₂ : F.map right ≫ e₀ = e₁ ≫ G.map right} + {h₃ : F.map reflexion ≫ e₁ = e₀ ≫ G.map reflexion} + {D : Type u₂} [Category.{v₂} D] (H : C ⥤ D) : + whiskerRight (mkNatTrans e₀ e₁ : F ⟶ G) H = + mkNatTrans (H.map e₀) (H.map e₁) + (by simp only [Functor.comp_obj, Functor.comp_map, ← Functor.map_comp, h₁]) + (by simp only [Functor.comp_obj, Functor.comp_map, ← Functor.map_comp, h₂]) + (by simp only [Functor.comp_obj, Functor.comp_map, ← Functor.map_comp, h₃]) := by + ext x; cases x <;> simp + +end + +/-- Any functor out of the WalkingReflexivePair yields a reflexive pair -/ +instance to_isReflexivePair {F : WalkingReflexivePair ⥤ C} : + IsReflexivePair (F.map .left) (F.map .right) := + ⟨F.map .reflexion, map_reflexion_comp_map_left F, map_reflexion_comp_map_right F⟩ + +end reflexivePair + +/-- A `ReflexiveCofork` is a cocone over a `WalkingReflexivePair`-shaped diagram. -/ +abbrev ReflexiveCofork (F : WalkingReflexivePair ⥤ C) := Cocone F + +namespace ReflexiveCofork + +open WalkingReflexivePair WalkingReflexivePair.Hom + +variable {F : WalkingReflexivePair ⥤ C} + +/-- The tail morphism of a reflexive cofork. -/ +abbrev π (G : ReflexiveCofork F) : F.obj zero ⟶ G.pt := G.ι.app zero + +/-- Constructor for `ReflexiveCofork` -/ +@[simps pt] +def mk {X : C} (π : F.obj zero ⟶ X) (h : F.map left ≫ π = F.map right ≫ π) : + ReflexiveCofork F where + pt := X + ι := reflexivePair.mkNatTrans π (F.map left ≫ π) + +@[simp] +lemma mk_π {X : C} (π : F.obj zero ⟶ X) (h : F.map left ≫ π = F.map right ≫ π) : + (mk π h).π = π := rfl + +lemma condition (G : ReflexiveCofork F) : F.map left ≫ G.π = F.map right ≫ G.π := by + erw [Cocone.w G left, Cocone.w G right] + +@[simp] +lemma app_one_eq_π (G : ReflexiveCofork F) : G.ι.app zero = G.π := rfl + +/-- The underlying `Cofork` of a `ReflexiveCofork`. -/ +abbrev toCofork (G : ReflexiveCofork F) : Cofork (F.map left) (F.map right) := + Cofork.ofπ G.π (by simp) + +end ReflexiveCofork + +noncomputable section +open WalkingReflexivePair WalkingReflexivePair.Hom + +variable (F : WalkingReflexivePair ⥤ C) + +/-- 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] +def reflexiveCoforkEquivCofork : + ReflexiveCofork F ≌ Cofork (F.map left) (F.map right) := + (Functor.Final.coconesEquiv _ F).symm.trans (Cocones.precomposeEquivalence + (diagramIsoParallelPair (WalkingParallelPair.inclusionWalkingReflexivePair ⋙ F))).symm + +@[simp] +lemma reflexiveCoforkEquivCofork_functor_obj_π (G : ReflexiveCofork F) : + ((reflexiveCoforkEquivCofork F).functor.obj G).π = G.π := by + dsimp [reflexiveCoforkEquivCofork] + rw [ReflexiveCofork.π, Cofork.π] + aesop_cat + +@[simp] +lemma reflexiveCoforkEquivCofork_inverse_obj_π + (G : Cofork (F.map left) (F.map right)) : + ((reflexiveCoforkEquivCofork F).inverse.obj G).π = G.π := by + dsimp only [reflexiveCoforkEquivCofork, Equivalence.symm, Equivalence.trans, + ReflexiveCofork.π, Cocones.precomposeEquivalence, Cocones.precompose, + Functor.comp, Functor.Final.coconesEquiv] + rw [Functor.Final.extendCocone_obj_ι_app' (Y := .one) (f := 𝟙 zero)] + simp + +/-- The equivalence between reflexive coforks and coforks sends a reflexive cofork to its underlying +cofork. -/ +def reflexiveCoforkEquivCoforkObjIso (G : ReflexiveCofork F) : + (reflexiveCoforkEquivCofork F).functor.obj G ≅ G.toCofork := + Cofork.ext (Iso.refl _) + (by simp [reflexiveCoforkEquivCofork, Cofork.π]) + +lemma hasReflexiveCoequalizer_iff_hasCoequalizer : + HasColimit F ↔ HasCoequalizer (F.map left) (F.map right) := by + simpa only [hasColimit_iff_hasInitial_cocone] + using Equivalence.hasInitial_iff (reflexiveCoforkEquivCofork F) + +instance reflexivePair_hasColimit_of_hasCoequalizer + [h : HasCoequalizer (F.map left) (F.map right)] : HasColimit F := + hasReflexiveCoequalizer_iff_hasCoequalizer _|>.mpr h + +/-- A reflexive cofork is a colimit cocone if and only if the underlying cofork is. -/ +def ReflexiveCofork.isColimitEquiv (G : ReflexiveCofork F) : + IsColimit (G.toCofork) ≃ IsColimit G := + IsColimit.equivIsoColimit (reflexiveCoforkEquivCoforkObjIso F G).symm|>.trans <| + (IsColimit.precomposeHomEquiv (diagramIsoParallelPair _).symm (G.whisker _)).trans <| + Functor.Final.isColimitWhiskerEquiv _ _ + +section + +variable [HasCoequalizer (F.map left) (F.map right)] + +/-- The colimit of a functor out of the walking reflexive pair is the same as the colimit of the +underlying parallel pair. -/ +def reflexiveCoequalizerIsoCoequalizer : + colimit F ≅ coequalizer (F.map left) (F.map right) := + ((ReflexiveCofork.isColimitEquiv _ _).symm (colimit.isColimit F)).coconePointUniqueUpToIso + (colimit.isColimit _) + +@[reassoc (attr := simp)] +lemma ι_reflexiveCoequalizerIsoCoequalizer_hom : + colimit.ι F zero ≫ (reflexiveCoequalizerIsoCoequalizer F).hom = + coequalizer.π (F.map left) (F.map right) := + IsColimit.comp_coconePointUniqueUpToIso_hom + ((ReflexiveCofork.isColimitEquiv F _).symm _) _ WalkingParallelPair.one + +@[reassoc (attr := simp)] +lemma π_reflexiveCoequalizerIsoCoequalizer_inv : + coequalizer.π _ _ ≫ (reflexiveCoequalizerIsoCoequalizer F).inv = colimit.ι F _ := by + rw [reflexiveCoequalizerIsoCoequalizer] + simp only [colimit.comp_coconePointUniqueUpToIso_inv, Cofork.ofπ_pt, colimit.cocone_x, + Cofork.ofπ_ι_app, colimit.cocone_ι] + +end + +variable {A B : C} {f g : A ⟶ B} [IsReflexivePair f g] [h : HasCoequalizer f g] + +instance ofIsReflexivePair_hasColimit_of_hasCoequalizer : + HasColimit (ofIsReflexivePair f g) := + hasReflexiveCoequalizer_iff_hasCoequalizer _|>.mpr h + +/-- The coequalizer of a reflexive pair can be promoted to the colimit of a diagram out of the +walking reflexive pair -/ +def colimitOfIsReflexivePairIsoCoequalizer : + colimit (ofIsReflexivePair f g) ≅ coequalizer f g := + @reflexiveCoequalizerIsoCoequalizer _ _ (ofIsReflexivePair f g) h + + +@[reassoc (attr := simp)] +lemma ι_colimitOfIsReflexivePairIsoCoequalizer_hom : + colimit.ι (ofIsReflexivePair f g) zero ≫ colimitOfIsReflexivePairIsoCoequalizer.hom = + coequalizer.π f g := @ι_reflexiveCoequalizerIsoCoequalizer_hom _ _ _ h + +@[reassoc (attr := simp)] +lemma π_colimitOfIsReflexivePairIsoCoequalizer_inv : + coequalizer.π f g ≫ colimitOfIsReflexivePairIsoCoequalizer.inv = + colimit.ι (ofIsReflexivePair f g) zero := + @π_reflexiveCoequalizerIsoCoequalizer_inv _ _ (ofIsReflexivePair f g) h + +end +end Limits + +namespace Limits + +open WalkingReflexivePair + +variable {C : Type u} [Category.{v} C] + +/-- A category has coequalizers of reflexive pairs if and only if it has all colimits indexed by the +walking reflexive pair. -/ +theorem hasReflexiveCoequalizers_iff : + HasColimitsOfShape WalkingReflexivePair C ↔ HasReflexiveCoequalizers C := + ⟨fun _ ↦ ⟨fun _ _ f g _ ↦ (hasReflexiveCoequalizer_iff_hasCoequalizer + (reflexivePair f g (commonSection f g))).1 inferInstance⟩, + fun _ ↦ ⟨inferInstance⟩⟩ + +end Limits end CategoryTheory From 196b03b8b64975872fbde68b171da11291f0f4fd Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Tue, 15 Oct 2024 08:21:55 +0000 Subject: [PATCH 130/425] feat(RingTheory/Locally): stability properties of `Locally P` (#17335) If a property of ring homomorphisms `P` is stable under base-change, composition, localizations, etc. then so is `Locally P`. Co-authored-by: Christian Merten <136261474+chrisflav@users.noreply.github.com> --- Mathlib/RingTheory/LocalProperties/Basic.lean | 18 +- .../RingTheory/Localization/Away/Basic.lean | 12 ++ Mathlib/RingTheory/RingHom/Locally.lean | 202 ++++++++++++++++++ 3 files changed, 225 insertions(+), 7 deletions(-) diff --git a/Mathlib/RingTheory/LocalProperties/Basic.lean b/Mathlib/RingTheory/LocalProperties/Basic.lean index 966f297fe56568..9c1bfac28d009f 100644 --- a/Mathlib/RingTheory/LocalProperties/Basic.lean +++ b/Mathlib/RingTheory/LocalProperties/Basic.lean @@ -201,19 +201,23 @@ lemma RingHom.HoldsForLocalizationAway.containsIdentities (hPl : HoldsForLocaliz introv R exact hPl.of_bijective _ _ Function.bijective_id -theorem RingHom.PropertyIsLocal.respectsIso (hP : RingHom.PropertyIsLocal @P) : - RingHom.RespectsIso @P := by - constructor - · intro R S T _ _ _ f e hf +lemma RingHom.StableUnderCompositionWithLocalizationAway.respectsIso + (hP : StableUnderCompositionWithLocalizationAway P) : + RespectsIso P where + left {R S T} _ _ _ f e hf := by letI := e.toRingHom.toAlgebra have : IsLocalization.Away (1 : S) T := IsLocalization.away_of_isUnit_of_bijective _ isUnit_one e.bijective - exact hP.StableUnderCompositionWithLocalizationAway.left T (1 : S) f hf - · intro R S T _ _ _ f e hf + exact hP.left T (1 : S) f hf + right {R S T} _ _ _ f e hf := by letI := e.toRingHom.toAlgebra have : IsLocalization.Away (1 : R) S := IsLocalization.away_of_isUnit_of_bijective _ isUnit_one e.bijective - exact hP.StableUnderCompositionWithLocalizationAway.right S (1 : R) f hf + exact hP.right S (1 : R) f hf + +theorem RingHom.PropertyIsLocal.respectsIso (hP : RingHom.PropertyIsLocal @P) : + RingHom.RespectsIso @P := + hP.StableUnderCompositionWithLocalizationAway.respectsIso -- Almost all arguments are implicit since this is not intended to use mid-proof. theorem RingHom.LocalizationPreserves.away (H : RingHom.LocalizationPreserves @P) (r : R) diff --git a/Mathlib/RingTheory/Localization/Away/Basic.lean b/Mathlib/RingTheory/Localization/Away/Basic.lean index c223f1c5f05f05..3c1532d750273c 100644 --- a/Mathlib/RingTheory/Localization/Away/Basic.lean +++ b/Mathlib/RingTheory/Localization/Away/Basic.lean @@ -232,6 +232,18 @@ lemma mul' (T : Type*) [CommSemiring T] [Algebra S T] [Algebra R T] [IsScalarTow IsLocalization.Away (x * y) T := mul_comm x y ▸ mul S T x y +/-- Localizing the localization of `R` at `x` at the image of `y` is the same as localizing +`R` at `y * x`. -/ +instance (x y : R) [IsLocalization.Away x S] : + IsLocalization.Away (y * x) (Localization.Away (algebraMap R S y)) := + IsLocalization.Away.mul S (Localization.Away (algebraMap R S y)) _ _ + +/-- Localizing the localization of `R` at `x` at the image of `y` is the same as localizing +`R` at `x * y`. -/ +instance (x y : R) [IsLocalization.Away x S] : + IsLocalization.Away (x * y) (Localization.Away (algebraMap R S y)) := + IsLocalization.Away.mul' S (Localization.Away (algebraMap R S y)) _ _ + /-- If `S₁` is the localization of `R` away from `f` and `S₂` is the localization away from `g`, then any localization `T` of `S₂` away from `f` is also a localization of `S₁` away from `g`. -/ lemma commutes {R : Type*} [CommSemiring R] (S₁ S₂ T : Type*) [CommSemiring S₁] diff --git a/Mathlib/RingTheory/RingHom/Locally.lean b/Mathlib/RingTheory/RingHom/Locally.lean index fc54b147cef5b1..d4adb0bedebb74 100644 --- a/Mathlib/RingTheory/RingHom/Locally.lean +++ b/Mathlib/RingTheory/RingHom/Locally.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Christian Merten -/ import Mathlib.RingTheory.LocalProperties.Basic +import Mathlib.RingTheory.Localization.BaseChange import Mathlib.RingTheory.Localization.Away.Lemmas /-! @@ -25,6 +26,15 @@ composition, base change, etc., so is `Locally P`. ## Main results - `RingHom.locally_ofLocalizationSpanTarget`: `Locally P` is local on the target. +- `RingHom.locally_holdsForLocalizationAway`: `Locally P` holds for localization away maps + if `P` does. +- `RingHom.locally_stableUnderBaseChange`: `Locally P` is stable under base change if `P` is. +- `RingHom.locally_stableUnderComposition`: `Locally P` is stable under composition + if `P` is and `P` is preserved under localizations. +- `RingHom.locally_stableUnderCompositionWithLocalizationAway`: `Locally P` is stable under + composition with localization away maps if `P` is. +- `RingHom.locally_localizationPreserves`: If `P` is preserved by localizations, then so is + `Locally P`. -/ @@ -143,4 +153,196 @@ lemma locally_ofLocalizationSpanTarget (hP : RespectsIso P) : end OfLocalizationSpanTarget +section Stability + +/-- 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 + refine ⟨e '' s, ?_, ?_⟩ + · rw [← Ideal.map_span, hsone, Ideal.map_top] + · rintro - ⟨a, ha, rfl⟩ + let e' : Localization.Away a ≃+* Localization.Away (e a) := + IsLocalization.ringEquivOfRingEquiv _ _ e (Submonoid.map_powers e a) + have : (algebraMap T (Localization.Away (e a))).comp e.toRingHom = + e'.toRingHom.comp (algebraMap S (Localization.Away a)) := by + ext x + simp [e'] + rw [← RingHom.comp_assoc, this, RingHom.comp_assoc] + apply hPi.left + exact hs a ha + right {R S T} _ _ _ f e := fun ⟨s, hsone, hs⟩ ↦ + ⟨s, hsone, fun a ha ↦ (RingHom.comp_assoc _ _ _).symm ▸ hPi.right _ _ (hs a ha)⟩ + +/-- If `P` holds for localization away maps, then so does `Locally P`. -/ +lemma locally_holdsForLocalizationAway (hPa : HoldsForLocalizationAway P) : + HoldsForLocalizationAway (Locally P) := by + introv R _ + use {1} + 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)) := + IsLocalization.isLocalization_of_algEquiv (Submonoid.powers r) e + rw [← IsScalarTower.algebraMap_eq] + apply hPa _ r + +/-- If `P` preserves localizations, then `Locally P` is stable under composition if `P` is. -/ +lemma locally_stableUnderComposition (hPi : RespectsIso P) (hPl : LocalizationPreserves P) + (hPc : StableUnderComposition P) : + StableUnderComposition (Locally P) := by + classical + intro R S T _ _ _ f g hf hg + rw [locally_iff_finite] at hf hg + obtain ⟨sf, hsfone, hsf⟩ := hf + obtain ⟨sg, hsgone, hsg⟩ := hg + rw [locally_iff_exists hPi] + refine ⟨sf × sg, fun (a, b) ↦ g a * b, ?_, + fun (a, b) ↦ Localization.Away ((algebraMap T (Localization.Away b.val)) (g a.val)), + inferInstance, inferInstance, inferInstance, ?_⟩ + · rw [eq_top_iff, ← hsgone, Ideal.span_le] + intro t ht + have : 1 ∈ Ideal.span (Set.range <| fun a : sf ↦ a.val) := by simp [hsfone] + simp only [mem_ideal_span_range_iff_exists_fun, SetLike.mem_coe] at this ⊢ + obtain ⟨cf, hcf⟩ := this + let cg : sg → T := Pi.single ⟨t, ht⟩ 1 + use fun (a, b) ↦ g (cf a) * cg b + simp [cg, Pi.single_apply, Fintype.sum_prod_type, ← mul_assoc, ← Finset.sum_mul, ← map_mul, + ← map_sum, hcf] at hcf ⊢ + · intro ⟨a, b⟩ + let g' := (algebraMap T (Localization.Away b.val)).comp g + let a' := (algebraMap T (Localization.Away b.val)) (g a.val) + have : (algebraMap T <| Localization.Away a').comp (g.comp f) = + (Localization.awayMap g' a.val).comp ((algebraMap S (Localization.Away a.val)).comp f) := by + ext x + simp only [coe_comp, Function.comp_apply, a'] + change _ = Localization.awayMap g' a.val (algebraMap S _ (f x)) + simp only [Localization.awayMap, IsLocalization.Away.map, IsLocalization.map_eq] + rfl + simp only [this] + apply hPc _ _ (hsf a.val a.property) + apply @hPl _ _ _ _ g' _ _ _ _ _ _ _ _ ?_ (hsg b.val b.property) + exact IsLocalization.Away.instMapRingHomPowersOfCoe (Localization.Away (g' a.val)) a.val + +/-- If `P` is stable under composition with localization away maps, then so is `Locally P`. -/ +lemma locally_stableUnderCompositionWithLocalizationAway + (hPa : StableUnderCompositionWithLocalizationAway P) : + StableUnderCompositionWithLocalizationAway (Locally P) where + left R S T _ _ _ _ t _ f hf := by + simp only [locally_iff_isLocalization (hPa.respectsIso) f] at hf + obtain ⟨s, hsone, hs⟩ := hf + 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)) := + (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 + 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) + (Localization.Away (algebraMap S T a)) := + IsLocalization.Away.commutes _ T ((Localization.Away (algebraMap S T a))) a t + apply hPa.left _ (algebraMap S (Localization.Away a) t) + apply hs a ha + right R S T _ _ _ _ r _ f := fun ⟨s, hsone, hs⟩ ↦ by + refine ⟨s, hsone, fun t ht ↦ ?_⟩ + rw [← comp_assoc] + exact hPa.right _ r _ (hs t ht) + +attribute [local instance] Algebra.TensorProduct.rightAlgebra in +/-- If `P` is stable under base change, then so is `Locally P`. -/ +lemma locally_stableUnderBaseChange (hPi : RespectsIso P) (hPb : StableUnderBaseChange P) : + StableUnderBaseChange (Locally P) := by + apply StableUnderBaseChange.mk _ (locally_respectsIso hPi) + introv hf + obtain ⟨s, hsone, hs⟩ := hf + rw [locally_iff_exists hPi] + letI (a : s) : Algebra (S ⊗[R] T) (S ⊗[R] Localization.Away a.val) := + (Algebra.TensorProduct.map (AlgHom.id R S) (IsScalarTower.toAlgHom R _ _)).toRingHom.toAlgebra + letI (a : s) : Algebra T (S ⊗[R] Localization.Away a.val) := + ((algebraMap _ (S ⊗[R] Localization.Away a.val)).comp (algebraMap T (S ⊗[R] T))).toAlgebra + haveI (a : s) : IsScalarTower T (S ⊗[R] T) (S ⊗[R] Localization.Away a.val) := + IsScalarTower.of_algebraMap_eq' rfl + haveI (a : s) : IsScalarTower T (Localization.Away a.val) (S ⊗[R] Localization.Away a.val) := + IsScalarTower.of_algebraMap_eq' rfl + haveI (a : s) : IsScalarTower S (S ⊗[R] T) (S ⊗[R] Localization.Away a.val) := + IsScalarTower.of_algebraMap_eq <| by + intro x + simp [RingHom.algebraMap_toAlgebra] + haveI (a : s) : Algebra.IsPushout T (Localization.Away a.val) (S ⊗[R] T) + (S ⊗[R] Localization.Away a.val) := by + rw [← Algebra.IsPushout.comp_iff (R := R) (R' := S)] + infer_instance + refine ⟨s, fun a ↦ Algebra.TensorProduct.includeRight a.val, ?_, + fun a ↦ (S ⊗[R] Localization.Away a.val), inferInstance, inferInstance, ?_, ?_⟩ + · rw [← Set.image_eq_range, ← Ideal.map_span, hsone, Ideal.map_top] + · intro a + convert_to IsLocalization (Algebra.algebraMapSubmonoid (S ⊗[R] T) (Submonoid.powers a.val)) + (S ⊗[R] Localization.Away a.val) + · simp only [Algebra.TensorProduct.includeRight_apply, Algebra.algebraMapSubmonoid, + Submonoid.map_powers] + rfl + · rw [← isLocalizedModule_iff_isLocalization, isLocalizedModule_iff_isBaseChange + (S := Submonoid.powers a.val) (A := Localization.Away a.val)] + exact Algebra.IsPushout.out + · intro a + have : (algebraMap (S ⊗[R] T) (S ⊗[R] Localization.Away a.val)).comp + Algebra.TensorProduct.includeLeftRingHom = + Algebra.TensorProduct.includeLeftRingHom := by + ext x + simp [RingHom.algebraMap_toAlgebra] + rw [this] + apply hPb R (Localization.Away a.val) + rw [IsScalarTower.algebraMap_eq R T (Localization.Away a.val)] + apply hs a a.property + +/-- If `P` is preserved by localizations, then so is `Locally P`. -/ +lemma locally_localizationPreserves (hPi : RespectsIso P) (hPl : LocalizationPreserves P) : + LocalizationPreserves (Locally P) := by + introv R hf + obtain ⟨s, hsone, hs⟩ := hf + rw [locally_iff_exists hPi] + let Mₐ (a : s) : Submonoid (Localization.Away a.val) := + (M.map f).map (algebraMap S (Localization.Away a.val)) + 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) : + IsLocalization (M.map ((algebraMap S (Localization.Away a.val)).comp f)) (Sₐ a) := by + rw [hM] + infer_instance + haveI (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) := + (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) := + 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 ↦ ?_⟩ + · rw [← Set.image_eq_range, ← Ideal.map_span, hsone, Ideal.map_top] + · convert IsLocalization.commutes (T := Sₐ a) (M₁ := M.map f) (S₁ := S') + (S₂ := Localization.Away a.val) (M₂ := Submonoid.powers a.val) + simp [Algebra.algebraMapSubmonoid] + · rw [algebraMap_toAlgebra, IsLocalization.map_comp_map] + apply hPl + exact hs a.val a.property + +/-- If `P` is preserved by localizations and stable under composition with localization +away maps, then `Locally P` is a local property of ring homomorphisms. -/ +lemma locally_propertyIsLocal (hPl : LocalizationPreserves P) + (hPa : StableUnderCompositionWithLocalizationAway P) : PropertyIsLocal (Locally P) where + LocalizationPreserves := locally_localizationPreserves hPa.respectsIso hPl + StableUnderCompositionWithLocalizationAway := + locally_stableUnderCompositionWithLocalizationAway hPa + OfLocalizationSpanTarget := locally_ofLocalizationSpanTarget hPa.respectsIso + +end Stability + end RingHom From 7f96f257c37aa7b1d6e1e35a156fdb4a6eece265 Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Tue, 15 Oct 2024 08:22:23 +0000 Subject: [PATCH 131/425] chore: bump to nightly-2024-10-15 --- lean-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lean-toolchain b/lean-toolchain index a7eff1cf43d14e..af6a54a1b05087 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-14 +leanprover/lean4:nightly-2024-10-15 From bd0d0691a7213176ee69080076d50f77cc22eff6 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Tue, 15 Oct 2024 19:23:14 +1100 Subject: [PATCH 132/425] fixes for leanprover/lean4#5716 --- Mathlib/Combinatorics/Enumerative/Composition.lean | 2 +- Mathlib/Data/List/DropRight.lean | 2 +- Mathlib/GroupTheory/Coxeter/Inversion.lean | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/Combinatorics/Enumerative/Composition.lean b/Mathlib/Combinatorics/Enumerative/Composition.lean index 917e4a7e41dbc6..e6258701750cb7 100644 --- a/Mathlib/Combinatorics/Enumerative/Composition.lean +++ b/Mathlib/Combinatorics/Enumerative/Composition.lean @@ -636,7 +636,7 @@ theorem getElem_splitWrtCompositionAux (l : List α) (ns : List ℕ) {i : ℕ} simp · simp only [splitWrtCompositionAux, getElem_cons_succ, IH, take, sum_cons, Nat.add_eq, add_zero, splitAt_eq, drop_take, drop_drop] - rw [add_comm (sum _) n, Nat.add_sub_add_left] + rw [Nat.add_sub_add_left] /-- The `i`-th sublist in the splitting of a list `l` along a composition `c`, is the slice of `l` between the indices `c.sizeUpTo i` and `c.sizeUpTo (i+1)`, i.e., the indices in the `i`-th diff --git a/Mathlib/Data/List/DropRight.lean b/Mathlib/Data/List/DropRight.lean index 10638f80de52e0..f55afc95cdd9f4 100644 --- a/Mathlib/Data/List/DropRight.lean +++ b/Mathlib/Data/List/DropRight.lean @@ -212,7 +212,7 @@ theorem rtakeWhile_idempotent (p : α → Bool) (l : List α) : rtakeWhile_eq_self_iff.mpr fun _ => mem_rtakeWhile_imp lemma rdrop_add (i j : ℕ) : (l.rdrop i).rdrop j = l.rdrop (i + j) := by - simp_rw [rdrop_eq_reverse_drop_reverse, reverse_reverse, drop_drop, Nat.add_comm] + simp_rw [rdrop_eq_reverse_drop_reverse, reverse_reverse, drop_drop] @[simp] lemma rdrop_append_length {l₁ l₂ : List α} : diff --git a/Mathlib/GroupTheory/Coxeter/Inversion.lean b/Mathlib/GroupTheory/Coxeter/Inversion.lean index 18946d5bd27dcd..c5c613cf20c6a5 100644 --- a/Mathlib/GroupTheory/Coxeter/Inversion.lean +++ b/Mathlib/GroupTheory/Coxeter/Inversion.lean @@ -401,8 +401,8 @@ theorem IsReduced.nodup_rightInvSeq {ω : List B} (rω : cs.IsReduced ω) : List rw [h₂, cs.getD_rightInvSeq, cs.getD_rightInvSeq, (Nat.sub_add_cancel (by omega) : j' - 1 + 1 = j'), eraseIdx_eq_take_drop_succ, drop_append_eq_append_drop, drop_of_length_le (by simp [j_lt_j'.le]), length_take, - drop_drop, nil_append, min_eq_left_of_lt (j_lt_j'.trans j'_lt_length), ← add_assoc, - Nat.sub_add_cancel (by omega), mul_left_inj, mul_right_inj] + drop_drop, nil_append, min_eq_left_of_lt (j_lt_j'.trans j'_lt_length), Nat.add_comm, + ← add_assoc, Nat.sub_add_cancel (by omega), mul_left_inj, mul_right_inj] congr 2 show get? (take j ω ++ drop (j + 1) ω) (j' - 1) = get? ω j' rw [get?_eq_getElem?, get?_eq_getElem?, From 200b6dce2af56bccc8314038637c285150a09133 Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Tue, 15 Oct 2024 08:58:47 +0000 Subject: [PATCH 133/425] feat(AlgebraicGeometry): api for morphism properties local at the source and target (#17302) A morphism property, that is both local at the source and the target and additionally is stable under post-composition with open immersions, can be checked locally around points of the source. This is what the [stacks](https://stacks.math.columbia.edu/tag/04QW) project calls "local on the source-and-target". --- .../AlgebraicGeometry/Morphisms/Basic.lean | 31 ++++++++ .../Morphisms/RingHomProperties.lean | 71 +++++++++++++++++++ Mathlib/AlgebraicGeometry/OpenImmersion.lean | 30 ++++++++ Mathlib/AlgebraicGeometry/Restrict.lean | 4 ++ 4 files changed, 136 insertions(+) diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean b/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean index 2cd009c1f7312c..a9f5d34528df43 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean @@ -234,6 +234,11 @@ lemma comp {UX : Scheme.{u}} (H : P f) (i : UX ⟶ X) [IsOpenImmersion i] : P (i ≫ f) := (iff_of_openCover' f (X.affineCover.add i)).mp H .none +/-- If `P` is local at the source, then it respects composition on the left with open immersions. -/ +instance respectsLeft_isOpenImmersion {P : MorphismProperty Scheme} + [IsLocalAtSource P] : P.RespectsLeft @IsOpenImmersion where + precomp i _ _ hf := IsLocalAtSource.comp hf i + lemma of_iSup_eq_top {ι} (U : ι → X.Opens) (hU : iSup U = ⊤) (H : ∀ i, P ((U i).ι ≫ f)) : P f := by refine (iff_of_openCover' f @@ -270,6 +275,32 @@ lemma isLocalAtTarget [P.IsMultiplicative] · exact hP _ _ · exact fun H ↦ P.comp_mem _ _ H (of_isOpenImmersion _) +section IsLocalAtSourceAndTarget + +/-- If `P` is local at the source and the target, then restriction on both source and target +preserves `P`. -/ +lemma resLE [IsLocalAtTarget P] {U : Y.Opens} {V : X.Opens} (e : V ≤ f ⁻¹ᵁ U) + (hf : P f) : P (f.resLE U V e) := + IsLocalAtSource.comp (IsLocalAtTarget.restrict hf U) _ + +/-- If `P` is local at the source, local at the target and is stable under post-composition with +open immersions, then `P` can be checked locally around points. -/ +lemma iff_exists_resLE [IsLocalAtTarget P] [P.RespectsRight @IsOpenImmersion] : + P f ↔ ∀ x : X, ∃ (U : Y.Opens) (V : X.Opens) (_ : x ∈ V.1) (e : V ≤ f ⁻¹ᵁ U), + P (f.resLE U V e) := by + refine ⟨fun hf x ↦ ⟨⊤, ⊤, trivial, by simp, resLE _ hf⟩, fun hf ↦ ?_⟩ + choose U V hxU e hf using hf + rw [IsLocalAtSource.iff_of_iSup_eq_top (fun x : X ↦ V x) (P := P)] + · intro x + rw [← Scheme.Hom.resLE_comp_ι _ (e x)] + exact MorphismProperty.RespectsRight.postcomp (Q := @IsOpenImmersion) _ inferInstance _ (hf x) + · rw [eq_top_iff] + rintro x - + simp only [Opens.coe_iSup, Set.mem_iUnion, SetLike.mem_coe] + use x, hxU x + +end IsLocalAtSourceAndTarget + end IsLocalAtSource /-- An `AffineTargetMorphismProperty` is a class of morphisms from an arbitrary scheme into an diff --git a/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean b/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean index 1a867be2b4d2a7..9a5b418ed0cd6a 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean @@ -192,6 +192,9 @@ lemma HasAffineProperty : HasAffineProperty P (sourceAffineLocally Q) where (isLocal_ringHomProperty P).ofLocalizationSpan eq_targetAffineLocally' := eq_affineLocally P +/- This is only `inferInstance` because of the `@[local instance]` on `HasAffineProperty` above. -/ +instance (priority := 900) : IsLocalAtTarget P := inferInstance + theorem appLE (H : P f) (U : Y.affineOpens) (V : X.affineOpens) (e) : Q (f.appLE U V e) := by rw [eq_affineLocally P, affineLocally_iff_affineOpens_le] at H exact H _ _ _ @@ -365,6 +368,74 @@ lemma stableUnderBaseChange (hP : RingHom.StableUnderBaseChange Q) : P.StableUnd rw [iff_of_isAffine (P := P)] at H ⊢ exact hP.pullback_fst_app_top _ (isLocal_ringHomProperty P).respectsIso _ _ H +include Q in +private lemma respects_isOpenImmersion_aux {X Y : Scheme.{u}} [IsAffine Y] {U : Y.Opens} + (f : X ⟶ U.toScheme) (hf : P f) : P (f ≫ U.ι) := by + wlog hYa : ∃ (a : Γ(Y, ⊤)), U = Y.basicOpen a generalizing X Y + · obtain ⟨(Us : Set Y.Opens), hUs, heq⟩ := Opens.isBasis_iff_cover.mp (isBasis_basicOpen Y) U + let V (s : Us) : X.Opens := f ⁻¹ᵁ U.ι ⁻¹ᵁ s + rw [IsLocalAtSource.iff_of_iSup_eq_top (P := P) V] + intro s + let f' : (V s).toScheme ⟶ U.ι ⁻¹ᵁ s := f ∣_ U.ι ⁻¹ᵁ s + have hf' : P f' := IsLocalAtTarget.restrict hf _ + let e : (U.ι ⁻¹ᵁ s).toScheme ≅ s := IsOpenImmersion.isoOfRangeEq ((U.ι ⁻¹ᵁ s).ι ≫ U.ι) s.1.ι + (by simpa [Set.range_comp, Set.image_preimage_eq_iff, heq] using le_sSup s.2) + have heq : (V s).ι ≫ f ≫ U.ι = f' ≫ e.hom ≫ s.1.ι := by + simp only [IsOpenImmersion.isoOfRangeEq_hom_fac, f', e, morphismRestrict_ι_assoc] + rw [heq, ← Category.assoc] + refine this _ ?_ ?_ + · rwa [P.cancel_right_of_respectsIso] + · obtain ⟨a, ha⟩ := hUs s.2 + use a, ha.symm + · apply f.preimage_iSup_eq_top + apply U.ι.image_injective + simp only [U.ι.image_iSup, U.ι.image_preimage_eq_opensRange_inter, Scheme.Opens.opensRange_ι] + conv_rhs => rw [Scheme.Hom.image_top_eq_opensRange, Scheme.Opens.opensRange_ι, heq] + ext : 1 + have (i : Us) : U ⊓ i.1 = i.1 := by simp [heq, le_sSup i.property] + simp [this] + obtain ⟨a, rfl⟩ := hYa + wlog hX : IsAffine X generalizing X Y + · rw [IsLocalAtSource.iff_of_iSup_eq_top (P := P) _ (iSup_affineOpens_eq_top _)] + intro V + rw [← Category.assoc] + exact this _ _ (IsLocalAtSource.comp hf _) V.2 + rw [HasRingHomProperty.iff_of_isAffine (P := P)] at hf ⊢ + exact (isLocal_ringHomProperty P).StableUnderCompositionWithLocalizationAway.right _ a _ hf + +/-- Any property of scheme morphisms induced by a property of ring homomorphisms is stable +under composition with open immersions. -/ +instance respects_isOpenImmersion : P.Respects @IsOpenImmersion where + postcomp {X Y Z} i hi f hf := by + wlog hZ : IsAffine Z generalizing X Y Z + · rw [IsLocalAtTarget.iff_of_iSup_eq_top (P := P) _ (iSup_affineOpens_eq_top _)] + intro U + rw [morphismRestrict_comp] + exact this _ inferInstance _ (IsLocalAtTarget.restrict hf _) U.2 + let e : Y ≅ i.opensRange.toScheme := IsOpenImmersion.isoOfRangeEq i i.opensRange.ι (by simp) + rw [show f ≫ i = f ≫ e.hom ≫ i.opensRange.ι by simp [e], ← Category.assoc] + exact respects_isOpenImmersion_aux _ (by rwa [P.cancel_right_of_respectsIso]) + +open RingHom in +/-- `P` can be checked locally around points of the source. -/ +lemma iff_exists_appLE : 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) := by + refine ⟨fun hf x ↦ ?_, fun hf ↦ (IsLocalAtSource.iff_exists_resLE (P := P)).mpr <| fun x ↦ ?_⟩ + · obtain ⟨U, hU, hfx, _⟩ := Opens.isBasis_iff_nbhd.mp (isBasis_affine_open Y) + (Opens.mem_top <| f.val.base x) + obtain ⟨V, hV, hx, e⟩ := Opens.isBasis_iff_nbhd.mp (isBasis_affine_open X) + (show x ∈ f ⁻¹ᵁ U from hfx) + use ⟨U, hU⟩, ⟨V, hV⟩, hx, e + apply appLE P f hf + · 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 Q).RespectsIso := toMorphismProperty_respectsIso_iff.mp <| + (isLocal_ringHomProperty P).respectsIso + exact (MorphismProperty.arrow_mk_iso_iff (toMorphismProperty Q) (arrowResLEAppIso f U V e)).mpr + hf + end HasRingHomProperty end AlgebraicGeometry diff --git a/Mathlib/AlgebraicGeometry/OpenImmersion.lean b/Mathlib/AlgebraicGeometry/OpenImmersion.lean index 70d24f7442e9bb..860d3cba578d79 100644 --- a/Mathlib/AlgebraicGeometry/OpenImmersion.lean +++ b/Mathlib/AlgebraicGeometry/OpenImmersion.lean @@ -115,6 +115,20 @@ lemma image_preimage_eq_opensRange_inter (U : Y.Opens) : f ''ᵁ f ⁻¹ᵁ U = apply Opens.ext simp [Set.image_preimage_eq_range_inter] +lemma image_injective : Function.Injective (f ''ᵁ ·) := by + intro U V hUV + simpa using congrArg (f ⁻¹ᵁ ·) hUV + +lemma image_iSup {ι : Sort*} (s : ι → X.Opens) : + (f ''ᵁ ⨆ (i : ι), s i) = ⨆ (i : ι), f ''ᵁ s i := by + ext : 1 + simp [Set.image_iUnion] + +lemma image_iSup₂ {ι : Sort*} {κ : ι → Sort*} (s : (i : ι) → κ i → X.Opens) : + (f ''ᵁ ⨆ (i : ι), ⨆ (j : κ i), s i j) = ⨆ (i : ι), ⨆ (j : κ i), f ''ᵁ s i j := by + ext : 1 + simp [Set.image_iUnion₂] + /-- 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 U).symm @@ -348,6 +362,16 @@ instance stalk_iso {X Y : Scheme.{u}} (f : X ⟶ Y) [IsOpenImmersion f] (x : X) IsIso (f.stalkMap x) := inferInstanceAs <| IsIso (f.val.stalkMap x) +lemma of_comp {X Y Z : Scheme.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) [IsOpenImmersion g] + [IsOpenImmersion (f ≫ g)] : IsOpenImmersion f := + haveI (x : X) : IsIso (f.stalkMap x) := + haveI : IsIso (g.stalkMap (f.val.base x) ≫ f.stalkMap x) := by + rw [← Scheme.stalkMap_comp] + infer_instance + IsIso.of_isIso_comp_left (f := g.stalkMap (f.val.base x)) _ + IsOpenImmersion.of_stalk_iso _ <| + OpenEmbedding.of_comp _ (Scheme.Hom.openEmbedding g) (Scheme.Hom.openEmbedding (f ≫ g)) + theorem iff_stalk_iso {X Y : Scheme.{u}} (f : X ⟶ Y) : IsOpenImmersion f ↔ OpenEmbedding f.1.base ∧ ∀ x, IsIso (f.stalkMap x) := ⟨fun H => ⟨H.1, fun x ↦ inferInstanceAs <| IsIso (f.val.stalkMap x)⟩, @@ -600,6 +624,12 @@ def ΓIsoTop {X Y : Scheme.{u}} (f : X ⟶ Y) [IsOpenImmersion f] : Γ(X, ⊤) ≅ Γ(Y, f.opensRange) := (f.appIso ⊤).symm ≪≫ Y.presheaf.mapIso (eqToIso f.image_top_eq_opensRange.symm).op +instance {Z : Scheme.{u}} (f : X ⟶ Z) (g : Y ⟶ Z) [IsOpenImmersion f] + (H' : Set.range g.val.base ⊆ Set.range f.val.base) [IsOpenImmersion g] : + IsOpenImmersion (IsOpenImmersion.lift f g H') := + haveI : IsOpenImmersion (IsOpenImmersion.lift f g H' ≫ f) := by simpa + IsOpenImmersion.of_comp _ f + end IsOpenImmersion namespace Scheme diff --git a/Mathlib/AlgebraicGeometry/Restrict.lean b/Mathlib/AlgebraicGeometry/Restrict.lean index d4c45b8f826f42..dd7a7046d4bdf6 100644 --- a/Mathlib/AlgebraicGeometry/Restrict.lean +++ b/Mathlib/AlgebraicGeometry/Restrict.lean @@ -218,6 +218,10 @@ normal-form for the induced morphism `U.toScheme ⟶ V.toScheme`. -/ lemma Scheme.restrictFunctor_map_left {U V : X.Opens} (i : U ⟶ V) : (X.restrictFunctor.map i).left = IsOpenImmersion.lift (V.ι) U.ι (by simpa using i.le) := rfl +instance {U V : X.Opens} (i : U ⟶ V) : IsOpenImmersion (X.restrictFunctor.map i).left := by + rw [X.restrictFunctor_map_left] + infer_instance + -- Porting note: the `by ...` used to be automatically done by unification magic @[reassoc] theorem Scheme.restrictFunctor_map_ofRestrict {U V : X.Opens} (i : U ⟶ V) : From a3160292dd3d71ab2caa8d371bc5084882db89f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Degenne?= Date: Tue, 15 Oct 2024 09:10:34 +0000 Subject: [PATCH 134/425] feat(Probability/Kernel): rnDeriv lemmas (#17682) --- Mathlib/Probability/Kernel/RadonNikodym.lean | 67 ++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/Mathlib/Probability/Kernel/RadonNikodym.lean b/Mathlib/Probability/Kernel/RadonNikodym.lean index 9e0392d8f287bc..4966a4d770e7c8 100644 --- a/Mathlib/Probability/Kernel/RadonNikodym.lean +++ b/Mathlib/Probability/Kernel/RadonNikodym.lean @@ -549,4 +549,71 @@ instance [hκ : IsFiniteKernel κ] [IsFiniteKernel η] : IsFiniteKernel (singula simp exact (self_le_add_left _ _).trans (h.le.trans (measure_le_bound _ _ _)) +/-- For two kernels `κ, η`, the singular part of `κ a` with respect to `η a` is a measurable +function of `a`. -/ +lemma measurable_singularPart (κ η : Kernel α γ) [IsFiniteKernel κ] [IsFiniteKernel η] : + Measurable (fun a ↦ (κ a).singularPart (η a)) := by + refine Measure.measurable_of_measurable_coe _ (fun s hs ↦ ?_) + simp_rw [← κ.singularPart_eq_singularPart_measure, κ.singularPart_def η] + exact Kernel.measurable_coe _ hs + +lemma rnDeriv_self (κ : Kernel α γ) [IsFiniteKernel κ] (a : α) : rnDeriv κ κ a =ᵐ[κ a] 1 := + (κ.rnDeriv_eq_rnDeriv_measure).trans (κ a).rnDeriv_self + +lemma rnDeriv_singularPart (κ ν : Kernel α γ) [IsFiniteKernel κ] [IsFiniteKernel ν] (a : α) : + rnDeriv (singularPart κ ν) ν a =ᵐ[ν a] 0 := by + filter_upwards [(singularPart κ ν).rnDeriv_eq_rnDeriv_measure, + (Measure.rnDeriv_eq_zero _ _).mpr (mutuallySingular_singularPart κ ν a)] with x h1 h2 + rw [h1, h2] + +lemma rnDeriv_lt_top (κ η : Kernel α γ) [IsFiniteKernel κ] [IsFiniteKernel η] {a : α} : + ∀ᵐ x ∂(η a), rnDeriv κ η a x < ∞ := by + filter_upwards [κ.rnDeriv_eq_rnDeriv_measure, (κ a).rnDeriv_ne_top _] + with x heq htop using heq ▸ htop.lt_top + +lemma rnDeriv_ne_top (κ η : Kernel α γ) [IsFiniteKernel κ] [IsFiniteKernel η] {a : α} : + ∀ᵐ x ∂(η a), rnDeriv κ η a x ≠ ∞ := by + filter_upwards [κ.rnDeriv_lt_top η] with a h using h.ne + +lemma rnDeriv_pos [IsFiniteKernel κ] [IsFiniteKernel η] {a : α} (ha : κ a ≪ η a) : + ∀ᵐ x ∂(κ a), 0 < rnDeriv κ η a x := by + filter_upwards [ha.ae_le κ.rnDeriv_eq_rnDeriv_measure, Measure.rnDeriv_pos ha] + with x heq hpos using heq ▸ hpos + +lemma rnDeriv_toReal_pos [IsFiniteKernel κ] [IsFiniteKernel η] {a : α} (h : κ a ≪ η a) : + ∀ᵐ x ∂(κ a), 0 < (rnDeriv κ η a x).toReal := by + filter_upwards [rnDeriv_pos h, h.ae_le (rnDeriv_ne_top κ _)] with x h0 htop + simp_all only [pos_iff_ne_zero, ne_eq, ENNReal.toReal_pos, not_false_eq_true, and_self] + +lemma rnDeriv_add (κ ν η : Kernel α γ) [IsFiniteKernel κ] [IsFiniteKernel ν] [IsFiniteKernel η] + (a : α) : + 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] + +lemma withDensity_rnDeriv_le (κ η : Kernel α γ) [IsFiniteKernel κ] [IsFiniteKernel η] (a : α) : + η.withDensity (κ.rnDeriv η) a ≤ κ a := by + refine Measure.le_intro (fun s hs _ ↦ ?_) + rw [Kernel.withDensity_apply'] + swap; · exact κ.measurable_rnDeriv _ + rw [setLIntegral_congr_fun hs ((κ.rnDeriv_eq_rnDeriv_measure).mono (fun x hx _ ↦ hx)), + ← withDensity_apply _ hs] + exact (κ a).withDensity_rnDeriv_le _ _ + +lemma withDensity_rnDeriv_eq [IsFiniteKernel κ] [IsFiniteKernel η] {a : α} (h : κ a ≪ η a) : + η.withDensity (κ.rnDeriv η) a = κ a := by + rw [Kernel.withDensity_apply] + swap; · exact κ.measurable_rnDeriv _ + have h_ae := κ.rnDeriv_eq_rnDeriv_measure (η := η) (a := a) + rw [MeasureTheory.withDensity_congr_ae h_ae, (κ a).withDensity_rnDeriv_eq _ h] + +lemma rnDeriv_withDensity [IsFiniteKernel κ] {f : α → γ → ℝ≥0∞} [IsFiniteKernel (withDensity κ f)] + (hf : Measurable (Function.uncurry f)) (a : α) : + (κ.withDensity f).rnDeriv κ a =ᵐ[κ a] f a := by + have h_ae := (κ.withDensity f).rnDeriv_eq_rnDeriv_measure (η := κ) (a := a) + have hf' : ∀ a, Measurable (f a) := fun _ ↦ hf.of_uncurry_left + filter_upwards [h_ae, (κ a).rnDeriv_withDensity (hf' a)] with x hx1 hx2 + rw [hx1, κ.withDensity_apply hf, hx2] + end ProbabilityTheory.Kernel From 41475d2a4e4da9da4278bd2b328e51a8717cf53a Mon Sep 17 00:00:00 2001 From: D-Thomine <100795491+D-Thomine@users.noreply.github.com> Date: Tue, 15 Oct 2024 09:10:36 +0000 Subject: [PATCH 135/425] chore(Topology.Instances.EReal): simplify proofs (#17738) And remove a couple of unnecessary hypotheses along the way. --- Mathlib/Topology/Instances/EReal.lean | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/Mathlib/Topology/Instances/EReal.lean b/Mathlib/Topology/Instances/EReal.lean index 08db54290d7bd0..f6f81f163a7bd4 100644 --- a/Mathlib/Topology/Instances/EReal.lean +++ b/Mathlib/Topology/Instances/EReal.lean @@ -184,22 +184,11 @@ lemma tendsto_toReal_atBot : Tendsto EReal.toReal (𝓝[≠] ⊥) atBot := by variable {α : Type*} {u v : α → EReal} -lemma add_iInf_le_iInf_add : (⨅ x, u x) + (⨅ x, v x) ≤ ⨅ x, (u + v) x := by - refine add_le_of_forall_add_le fun a a_u b b_v ↦ ?_ - rw [lt_iInf_iff] at a_u b_v - rcases a_u with ⟨c, a_c, c_u⟩ - rcases b_v with ⟨d, b_d, d_v⟩ - simp only [Pi.add_apply, le_iInf_iff] - exact fun x ↦ add_le_add (lt_of_lt_of_le a_c (c_u x)).le (lt_of_lt_of_le b_d (d_v x)).le - -lemma iSup_add_le_add_iSup (h : ⨆ x, u x ≠ ⊥ ∨ ⨆ x, v x ≠ ⊤) (h' : ⨆ x, u x ≠ ⊤ ∨ ⨆ x, v x ≠ ⊥) : - ⨆ x, (u + v) x ≤ (⨆ x, u x) + (⨆ x, v x) := by - refine le_add_of_forall_le_add h h' fun a a_u b b_v ↦ ?_ - rw [gt_iff_lt, iSup_lt_iff] at a_u b_v - rcases a_u with ⟨c, a_c, c_u⟩ - rcases b_v with ⟨d, b_d, d_v⟩ - simp only [Pi.add_apply, iSup_le_iff] - exact fun x ↦ add_le_add (lt_of_le_of_lt (c_u x) a_c).le (lt_of_le_of_lt (d_v x) b_d).le +lemma add_iInf_le_iInf_add : (⨅ x, u x) + ⨅ x, v x ≤ ⨅ x, (u + v) x := + le_iInf fun i ↦ add_le_add (iInf_le u i) (iInf_le v i) + +lemma iSup_add_le_add_iSup : ⨆ x, (u + v) x ≤ (⨆ x, u x) + ⨆ x, v x := + iSup_le fun i ↦ add_le_add (le_iSup u i) (le_iSup v i) /-! ### Liminfs and Limsups -/ From b97f8e523cc26b8d6b01a03bdbdeee7616b29835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20B=C3=B6ving?= Date: Tue, 15 Oct 2024 11:24:29 +0200 Subject: [PATCH 136/425] use upstreamed theory --- Mathlib/Data/BitVec.lean | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/Mathlib/Data/BitVec.lean b/Mathlib/Data/BitVec.lean index 15c3c502cabf71..2e3e65b8796440 100644 --- a/Mathlib/Data/BitVec.lean +++ b/Mathlib/Data/BitVec.lean @@ -58,31 +58,9 @@ instance : CommSemiring (BitVec w) := (fun _ => rfl) /- toFin_natCast -/ -- The statement in the new API would be: `n#(k.succ) = ((n / 2)#k).concat (n % 2 != 0)` -@[simp] theorem ofInt_negSucc {w n : Nat} : - BitVec.ofInt w (Int.negSucc n) = ~~~.ofNat w n := by - simp only [BitVec.ofInt, Int.toNat, Int.ofNat_eq_coe, toNat_eq, toNat_ofNatLt, toNat_not, - toNat_ofNat] - cases h : Int.negSucc n % ((2 ^ w : Nat) : Int) - case ofNat => - rw [Int.ofNat_eq_coe, Int.negSucc_emod] at h - · dsimp only - omega - · omega - case negSucc a => - have neg := Int.negSucc_lt_zero a - have _ : 0 ≤ Int.negSucc n % ((2 ^ w : Nat) : Int) := Int.emod_nonneg _ (by omega) - omega - @[simp] lemma ofFin_neg {x : Fin (2 ^ w)} : ofFin (-x) = -(ofFin x) := by ext; rw [neg_eq_zero_sub]; simp; rfl -@[simp] lemma ofFin_ofNat (n : ℕ) : - ofFin (no_index (OfNat.ofNat n : Fin (2^w))) = OfNat.ofNat n := by - simp only [OfNat.ofNat, Fin.ofNat', BitVec.ofNat, Nat.and_pow_two_sub_one_eq_mod] - -theorem toFin_inj {x y : BitVec w} : x.toFin = y.toFin ↔ x = y := - toFin_injective.eq_iff - @[simp] lemma ofFin_natCast (n : ℕ) : ofFin (n : Fin (2^w)) = n := by simp only [Nat.cast, NatCast.natCast, OfNat.ofNat, BitVec.ofNat, Nat.and_pow_two_sub_one_eq_mod] rfl @@ -99,7 +77,7 @@ theorem ofFin_intCast (z : ℤ) : ofFin (z : Fin (2^w)) = ↑z := by unfold Int.castDef cases' z with z z · rfl - · rw [ofInt_negSucc] + · rw [ofInt_negSucc_eq_not_ofNat] simp only [Nat.cast_add, Nat.cast_one, neg_add_rev] rw [← add_ofFin, ofFin_neg, ofFin_ofNat, ofNat_eq_ofNat, ofFin_neg, ofFin_natCast, natCast_eq_ofNat, negOne_eq_allOnes, ← sub_toAdd, allOnes_sub_eq_not] @@ -107,10 +85,6 @@ theorem ofFin_intCast (z : ℤ) : ofFin (z : Fin (2^w)) = ↑z := by theorem toFin_intCast (z : ℤ) : toFin (z : BitVec w) = z := by apply toFin_inj.mpr <| (ofFin_intCast z).symm -lemma toFin_zero : toFin (0 : BitVec w) = 0 := rfl -lemma toFin_one : toFin (1 : BitVec w) = 1 := by - rw [toFin_inj]; simp only [ofNat_eq_ofNat, ofFin_ofNat] - instance : CommRing (BitVec w) := toFin_injective.commRing _ toFin_zero toFin_one toFin_add toFin_mul toFin_neg toFin_sub From bb2c66284cc44fccf45defa1018231e82f5e3adf Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Tue, 15 Oct 2024 09:36:00 +0000 Subject: [PATCH 137/425] chore: remove useless import of `Batteries.Lean.HashSet` (#17763) Neither file actually seems to make use of any of the operations defined in the import, so we might as well drop the import entirely. --- Mathlib/Tactic/Linter/FlexibleLinter.lean | 1 - Mathlib/Tactic/Linter/HashCommandLinter.lean | 1 - 2 files changed, 2 deletions(-) diff --git a/Mathlib/Tactic/Linter/FlexibleLinter.lean b/Mathlib/Tactic/Linter/FlexibleLinter.lean index 525285a97bfef7..ae157b8775b05f 100644 --- a/Mathlib/Tactic/Linter/FlexibleLinter.lean +++ b/Mathlib/Tactic/Linter/FlexibleLinter.lean @@ -5,7 +5,6 @@ Authors: Damiano Testa -/ import Lean.Elab.Command import Batteries.Data.Array.Basic -import Batteries.Lean.HashSet /-! # The "flexible" linter diff --git a/Mathlib/Tactic/Linter/HashCommandLinter.lean b/Mathlib/Tactic/Linter/HashCommandLinter.lean index 66cac438ada340..3dd02b53429522 100644 --- a/Mathlib/Tactic/Linter/HashCommandLinter.lean +++ b/Mathlib/Tactic/Linter/HashCommandLinter.lean @@ -5,7 +5,6 @@ Authors: Damiano Testa -/ import Lean.Elab.Command -import Batteries.Lean.HashSet /-! # `#`-command linter From 1ca352ae8aec6f02cee3dab6d7e0a5ebac555977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20B=C3=B6ving?= Date: Tue, 15 Oct 2024 11:41:20 +0200 Subject: [PATCH 138/425] simplify --- Mathlib/Data/BitVec.lean | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Mathlib/Data/BitVec.lean b/Mathlib/Data/BitVec.lean index 2e3e65b8796440..494a1f0294db44 100644 --- a/Mathlib/Data/BitVec.lean +++ b/Mathlib/Data/BitVec.lean @@ -59,14 +59,13 @@ instance : CommSemiring (BitVec w) := -- The statement in the new API would be: `n#(k.succ) = ((n / 2)#k).concat (n % 2 != 0)` @[simp] lemma ofFin_neg {x : Fin (2 ^ w)} : ofFin (-x) = -(ofFin x) := by - ext; rw [neg_eq_zero_sub]; simp; rfl + rfl @[simp] lemma ofFin_natCast (n : ℕ) : ofFin (n : Fin (2^w)) = n := by - simp only [Nat.cast, NatCast.natCast, OfNat.ofNat, BitVec.ofNat, Nat.and_pow_two_sub_one_eq_mod] rfl lemma toFin_natCast (n : ℕ) : toFin (n : BitVec w) = n := by - rw [toFin_inj]; simp only [ofFin_natCast] + rfl theorem ofFin_intCast (z : ℤ) : ofFin (z : Fin (2^w)) = ↑z := by cases w From 507f3d724e2be9ba6cf21762c3c107abffe72af7 Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Tue, 15 Oct 2024 09:58:35 +0000 Subject: [PATCH 139/425] Trigger CI for https://github.com/leanprover/lean4/pull/5323 --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index bacec35e7f2c13..5a77087e20dddb 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "913b2c6071f3e5ef5907cd0a92a07c2ea49d4e3c", + "rev": "38ef6de7f47e8e9103b6547c1f7ec20e9a676730", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "lean-pr-testing-5323", From 5f0628eab56cdcf7a33982a270433e0fc3a6e9a5 Mon Sep 17 00:00:00 2001 From: damiano Date: Tue, 15 Oct 2024 09:59:56 +0000 Subject: [PATCH 140/425] chore: remove and rename variables (#17760) I also relabeled some indices, since some intermediate variables vanished in the process. --- Mathlib/Analysis/Normed/Operator/Compact.lean | 24 +-- .../Geometry/Manifold/ContMDiffMFDeriv.lean | 8 +- .../LinearAlgebra/Matrix/BilinearForm.lean | 167 +++++++++--------- .../Integral/IntegralEqImproper.lean | 10 +- 4 files changed, 99 insertions(+), 110 deletions(-) diff --git a/Mathlib/Analysis/Normed/Operator/Compact.lean b/Mathlib/Analysis/Normed/Operator/Compact.lean index ee6b5ed2c85f77..633508c11661e3 100644 --- a/Mathlib/Analysis/Normed/Operator/Compact.lean +++ b/Mathlib/Analysis/Normed/Operator/Compact.lean @@ -68,7 +68,7 @@ section Characterizations section -variable {R₁ R₂ : Type*} [Semiring R₁] [Semiring R₂] {σ₁₂ : R₁ →+* R₂} {M₁ M₂ : Type*} +variable {R₁ : Type*} [Semiring R₁] {M₁ M₂ : Type*} [TopologicalSpace M₁] [AddCommMonoid M₁] [TopologicalSpace M₂] theorem isCompactOperator_iff_exists_mem_nhds_image_subset_compact (f : M₁ → M₂) : @@ -112,7 +112,7 @@ end Bounded section NormedSpace variable {𝕜₁ 𝕜₂ : Type*} [NontriviallyNormedField 𝕜₁] [SeminormedRing 𝕜₂] {σ₁₂ : 𝕜₁ →+* 𝕜₂} - {M₁ M₂ M₃ : Type*} [SeminormedAddCommGroup M₁] [TopologicalSpace M₂] [AddCommMonoid M₂] + {M₁ M₂ : Type*} [SeminormedAddCommGroup M₁] [TopologicalSpace M₂] [AddCommMonoid M₂] [NormedSpace 𝕜₁ M₁] [Module 𝕜₂ M₂] theorem IsCompactOperator.image_subset_compact_of_bounded [ContinuousConstSMul 𝕜₂ M₂] @@ -178,10 +178,10 @@ end Characterizations section Operations -variable {R₁ R₂ R₃ R₄ : Type*} [Semiring R₁] [Semiring R₂] [CommSemiring R₃] [CommSemiring R₄] - {σ₁₂ : R₁ →+* R₂} {σ₁₄ : R₁ →+* R₄} {σ₃₄ : R₃ →+* R₄} {M₁ M₂ M₃ M₄ : Type*} [TopologicalSpace M₁] - [AddCommMonoid M₁] [TopologicalSpace M₂] [AddCommMonoid M₂] [TopologicalSpace M₃] - [AddCommGroup M₃] [TopologicalSpace M₄] [AddCommGroup M₄] +variable {R₁ R₄ : Type*} [Semiring R₁] [CommSemiring R₄] + {σ₁₄ : R₁ →+* R₄} {M₁ M₂ M₄ : Type*} [TopologicalSpace M₁] + [AddCommMonoid M₁] [TopologicalSpace M₂] [AddCommMonoid M₂] + [TopologicalSpace M₄] [AddCommGroup M₄] theorem IsCompactOperator.smul {S : Type*} [Monoid S] [DistribMulAction S M₂] [ContinuousConstSMul S M₂] {f : M₁ → M₂} (hf : IsCompactOperator f) (c : S) : @@ -247,8 +247,8 @@ end Comp section CodRestrict -variable {R₁ R₂ : Type*} [Semiring R₁] [Semiring R₂] {σ₁₂ : R₁ →+* R₂} {M₁ M₂ : Type*} - [TopologicalSpace M₁] [TopologicalSpace M₂] [AddCommMonoid M₁] [AddCommMonoid M₂] [Module R₁ M₁] +variable {R₂ : Type*} [Semiring R₂] {M₁ M₂ : Type*} + [TopologicalSpace M₁] [TopologicalSpace M₂] [AddCommMonoid M₁] [AddCommMonoid M₂] [Module R₂ M₂] theorem IsCompactOperator.codRestrict {f : M₁ → M₂} (hf : IsCompactOperator f) {V : Submodule R₂ M₂} @@ -261,10 +261,10 @@ end CodRestrict section Restrict -variable {R₁ R₂ R₃ : Type*} [Semiring R₁] [Semiring R₂] [Semiring R₃] {σ₁₂ : R₁ →+* R₂} - {σ₂₃ : R₂ →+* R₃} {M₁ M₂ M₃ : Type*} [TopologicalSpace M₁] [UniformSpace M₂] - [TopologicalSpace M₃] [AddCommMonoid M₁] [AddCommMonoid M₂] [AddCommMonoid M₃] [Module R₁ M₁] - [Module R₂ M₂] [Module R₃ M₃] +variable {R₁ R₂ : Type*} [Semiring R₁] [Semiring R₂] {σ₁₂ : R₁ →+* R₂} + {M₁ M₂ : Type*} [TopologicalSpace M₁] [UniformSpace M₂] + [AddCommMonoid M₁] [AddCommMonoid M₂] [Module R₁ M₁] + [Module R₂ M₂] /-- If a compact operator preserves a closed submodule, its restriction to that submodule is compact. diff --git a/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean b/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean index 98fc2cc47a1e1c..efcc63b456d66b 100644 --- a/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean +++ b/Mathlib/Geometry/Manifold/ContMDiffMFDeriv.lean @@ -45,13 +45,9 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {F' : Type*} [NormedAddCommGroup F'] [NormedSpace 𝕜 F'] {G' : Type*} [TopologicalSpace G'] {J' : ModelWithCorners 𝕜 F' G'} {N' : Type*} [TopologicalSpace N'] [ChartedSpace G' N'] - -- declare some additional normed spaces, used for fibers of vector bundles - {F₁ : Type*} - [NormedAddCommGroup F₁] [NormedSpace 𝕜 F₁] {F₂ : Type*} [NormedAddCommGroup F₂] - [NormedSpace 𝕜 F₂] -- declare functions, sets, points and smoothness indices - {f f₁ : M → M'} - {s s₁ t : Set M} {x : M} {m n : ℕ∞} + {f : M → M'} + {s : Set M} {m n : ℕ∞} -- Porting note: section about deducing differentiability from smoothness moved to -- `Geometry.Manifold.MFDeriv.Basic` diff --git a/Mathlib/LinearAlgebra/Matrix/BilinearForm.lean b/Mathlib/LinearAlgebra/Matrix/BilinearForm.lean index f6e6c15a38732f..6ba3a7550fedf7 100644 --- a/Mathlib/LinearAlgebra/Matrix/BilinearForm.lean +++ b/Mathlib/LinearAlgebra/Matrix/BilinearForm.lean @@ -21,11 +21,8 @@ This file defines the conversion between bilinear forms and matrices. ## Notations In this file we use the following type variables: - - `M`, `M'`, ... are modules over the commutative semiring `R`, - - `M₁`, `M₁'`, ... are modules over the commutative ring `R₁`, - - `M₂`, `M₂'`, ... are modules over the commutative semiring `R₂`, - - `M₃`, `M₃'`, ... are modules over the commutative ring `R₃`, - - `V`, ... is a vector space over the field `K`. + - `M₁` is a module over the commutative semiring `R₁`, + - `M₂` is a module over the commutative ring `R₂`. ## Tags @@ -35,12 +32,8 @@ bilinear form, bilin form, BilinearForm, matrix, basis open LinearMap (BilinForm) -variable {R : Type*} {M : Type*} [CommSemiring R] [AddCommMonoid M] [Module R M] -variable {R₁ : Type*} {M₁ : Type*} [CommRing R₁] [AddCommGroup M₁] [Module R₁ M₁] -variable {R₂ : Type*} {M₂ : Type*} [CommSemiring R₂] [AddCommMonoid M₂] [Module R₂ M₂] -variable {R₃ : Type*} {M₃ : Type*} [CommRing R₃] [AddCommGroup M₃] [Module R₃ M₃] -variable {V : Type*} {K : Type*} [Field K] [AddCommGroup V] [Module K V] -variable {B : BilinForm R M} {B₁ : BilinForm R₁ M₁} {B₂ : BilinForm R₂ M₂} +variable {R₁ : Type*} {M₁ : Type*} [CommSemiring R₁] [AddCommMonoid M₁] [Module R₁ M₁] +variable {R₂ : Type*} {M₂ : Type*} [CommRing R₂] [AddCommGroup M₂] [Module R₂ M₂] section Matrix @@ -53,30 +46,30 @@ open Matrix /-- The map from `Matrix n n R` to bilinear forms on `n → R`. This is an auxiliary definition for the equivalence `Matrix.toBilin'`. -/ -def Matrix.toBilin'Aux [Fintype n] (M : Matrix n n R₂) : BilinForm R₂ (n → R₂) := +def Matrix.toBilin'Aux [Fintype n] (M : Matrix n n R₁) : BilinForm R₁ (n → R₁) := Matrix.toLinearMap₂'Aux _ _ M -theorem Matrix.toBilin'Aux_single [Fintype n] [DecidableEq n] (M : Matrix n n R₂) (i j : n) : +theorem Matrix.toBilin'Aux_single [Fintype n] [DecidableEq n] (M : Matrix n n R₁) (i j : n) : M.toBilin'Aux (Pi.single i 1) (Pi.single j 1) = M i j := Matrix.toLinearMap₂'Aux_single _ _ _ _ _ /-- The linear map from bilinear forms to `Matrix n n R` given an `n`-indexed basis. This is an auxiliary definition for the equivalence `Matrix.toBilin'`. -/ -def BilinForm.toMatrixAux (b : n → M₂) : BilinForm R₂ M₂ →ₗ[R₂] Matrix n n R₂ := - LinearMap.toMatrix₂Aux R₂ b b +def BilinForm.toMatrixAux (b : n → M₁) : BilinForm R₁ M₁ →ₗ[R₁] Matrix n n R₁ := + LinearMap.toMatrix₂Aux R₁ b b @[simp] -theorem LinearMap.BilinForm.toMatrixAux_apply (B : BilinForm R₂ M₂) (b : n → M₂) (i j : n) : +theorem LinearMap.BilinForm.toMatrixAux_apply (B : BilinForm R₁ M₁) (b : n → M₁) (i j : n) : -- Porting note: had to hint the base ring even though it should be clear from context... - BilinForm.toMatrixAux (R₂ := R₂) b B i j = B (b i) (b j) := - LinearMap.toMatrix₂Aux_apply R₂ B _ _ _ _ + BilinForm.toMatrixAux (R₁ := R₁) b B i j = B (b i) (b j) := + LinearMap.toMatrix₂Aux_apply R₁ B _ _ _ _ variable [Fintype n] [Fintype o] -theorem toBilin'Aux_toMatrixAux [DecidableEq n] (B₂ : BilinForm R₂ (n → R₂)) : +theorem toBilin'Aux_toMatrixAux [DecidableEq n] (B₂ : BilinForm R₁ (n → R₁)) : -- Porting note: had to hint the base ring even though it should be clear from context... - Matrix.toBilin'Aux (BilinForm.toMatrixAux (R₂ := R₂) (fun j => Pi.single j 1) B₂) = B₂ := by + Matrix.toBilin'Aux (BilinForm.toMatrixAux (R₁ := R₁) (fun j => Pi.single j 1) B₂) = B₂ := by rw [BilinForm.toMatrixAux, Matrix.toBilin'Aux, toLinearMap₂'Aux_toMatrix₂Aux] section ToMatrix' @@ -90,95 +83,95 @@ This section deals with the conversion between matrices and bilinear forms on `n variable [DecidableEq n] [DecidableEq o] /-- The linear equivalence between bilinear forms on `n → R` and `n × n` matrices -/ -def LinearMap.BilinForm.toMatrix' : BilinForm R₂ (n → R₂) ≃ₗ[R₂] Matrix n n R₂ := - LinearMap.toMatrix₂' R₂ +def LinearMap.BilinForm.toMatrix' : BilinForm R₁ (n → R₁) ≃ₗ[R₁] Matrix n n R₁ := + LinearMap.toMatrix₂' R₁ /-- The linear equivalence between `n × n` matrices and bilinear forms on `n → R` -/ -def Matrix.toBilin' : Matrix n n R₂ ≃ₗ[R₂] BilinForm R₂ (n → R₂) := +def Matrix.toBilin' : Matrix n n R₁ ≃ₗ[R₁] BilinForm R₁ (n → R₁) := BilinForm.toMatrix'.symm @[simp] -theorem Matrix.toBilin'Aux_eq (M : Matrix n n R₂) : Matrix.toBilin'Aux M = Matrix.toBilin' M := +theorem Matrix.toBilin'Aux_eq (M : Matrix n n R₁) : Matrix.toBilin'Aux M = Matrix.toBilin' M := rfl -theorem Matrix.toBilin'_apply (M : Matrix n n R₂) (x y : n → R₂) : +theorem Matrix.toBilin'_apply (M : Matrix n n R₁) (x y : n → R₁) : Matrix.toBilin' M x y = ∑ i, ∑ j, x i * M i j * y j := (Matrix.toLinearMap₂'_apply _ _ _).trans (by simp only [smul_eq_mul, mul_assoc, mul_comm, mul_left_comm]) -theorem Matrix.toBilin'_apply' (M : Matrix n n R₂) (v w : n → R₂) : +theorem Matrix.toBilin'_apply' (M : Matrix n n R₁) (v w : n → R₁) : Matrix.toBilin' M v w = Matrix.dotProduct v (M *ᵥ w) := Matrix.toLinearMap₂'_apply' _ _ _ @[simp] -theorem Matrix.toBilin'_single (M : Matrix n n R₂) (i j : n) : +theorem Matrix.toBilin'_single (M : Matrix n n R₁) (i j : n) : Matrix.toBilin' M (Pi.single i 1) (Pi.single j 1) = M i j := by simp [Matrix.toBilin'_apply, Pi.single_apply] set_option linter.deprecated false in @[simp, deprecated Matrix.toBilin'_single (since := "2024-08-09")] -theorem Matrix.toBilin'_stdBasis (M : Matrix n n R₂) (i j : n) : +theorem Matrix.toBilin'_stdBasis (M : Matrix n n R₁) (i j : n) : Matrix.toBilin' M - (LinearMap.stdBasis R₂ (fun _ ↦ R₂) i 1) - (LinearMap.stdBasis R₂ (fun _ ↦ R₂) j 1) = M i j := Matrix.toBilin'_single _ _ _ + (LinearMap.stdBasis R₁ (fun _ ↦ R₁) i 1) + (LinearMap.stdBasis R₁ (fun _ ↦ R₁) j 1) = M i j := Matrix.toBilin'_single _ _ _ @[simp] theorem LinearMap.BilinForm.toMatrix'_symm : - (BilinForm.toMatrix'.symm : Matrix n n R₂ ≃ₗ[R₂] _) = Matrix.toBilin' := + (BilinForm.toMatrix'.symm : Matrix n n R₁ ≃ₗ[R₁] _) = Matrix.toBilin' := rfl @[simp] theorem Matrix.toBilin'_symm : - (Matrix.toBilin'.symm : _ ≃ₗ[R₂] Matrix n n R₂) = BilinForm.toMatrix' := + (Matrix.toBilin'.symm : _ ≃ₗ[R₁] Matrix n n R₁) = BilinForm.toMatrix' := BilinForm.toMatrix'.symm_symm @[simp] -theorem Matrix.toBilin'_toMatrix' (B : BilinForm R₂ (n → R₂)) : +theorem Matrix.toBilin'_toMatrix' (B : BilinForm R₁ (n → R₁)) : Matrix.toBilin' (BilinForm.toMatrix' B) = B := Matrix.toBilin'.apply_symm_apply B namespace LinearMap @[simp] -theorem BilinForm.toMatrix'_toBilin' (M : Matrix n n R₂) : +theorem BilinForm.toMatrix'_toBilin' (M : Matrix n n R₁) : BilinForm.toMatrix' (Matrix.toBilin' M) = M := - (LinearMap.toMatrix₂' R₂).apply_symm_apply M + (LinearMap.toMatrix₂' R₁).apply_symm_apply M @[simp] -theorem BilinForm.toMatrix'_apply (B : BilinForm R₂ (n → R₂)) (i j : n) : +theorem BilinForm.toMatrix'_apply (B : BilinForm R₁ (n → R₁)) (i j : n) : BilinForm.toMatrix' B i j = B (Pi.single i 1) (Pi.single j 1) := LinearMap.toMatrix₂'_apply _ _ _ -- Porting note: dot notation for bundled maps doesn't work in the rest of this section @[simp] -theorem BilinForm.toMatrix'_comp (B : BilinForm R₂ (n → R₂)) (l r : (o → R₂) →ₗ[R₂] n → R₂) : +theorem BilinForm.toMatrix'_comp (B : BilinForm R₁ (n → R₁)) (l r : (o → R₁) →ₗ[R₁] n → R₁) : BilinForm.toMatrix' (B.comp l r) = (LinearMap.toMatrix' l)ᵀ * BilinForm.toMatrix' B * LinearMap.toMatrix' r := LinearMap.toMatrix₂'_compl₁₂ B _ _ -theorem BilinForm.toMatrix'_compLeft (B : BilinForm R₂ (n → R₂)) (f : (n → R₂) →ₗ[R₂] n → R₂) : +theorem BilinForm.toMatrix'_compLeft (B : BilinForm R₁ (n → R₁)) (f : (n → R₁) →ₗ[R₁] n → R₁) : BilinForm.toMatrix' (B.compLeft f) = (LinearMap.toMatrix' f)ᵀ * BilinForm.toMatrix' B := LinearMap.toMatrix₂'_comp B _ -theorem BilinForm.toMatrix'_compRight (B : BilinForm R₂ (n → R₂)) (f : (n → R₂) →ₗ[R₂] n → R₂) : +theorem BilinForm.toMatrix'_compRight (B : BilinForm R₁ (n → R₁)) (f : (n → R₁) →ₗ[R₁] n → R₁) : BilinForm.toMatrix' (B.compRight f) = BilinForm.toMatrix' B * LinearMap.toMatrix' f := LinearMap.toMatrix₂'_compl₂ B _ -theorem BilinForm.mul_toMatrix'_mul (B : BilinForm R₂ (n → R₂)) (M : Matrix o n R₂) - (N : Matrix n o R₂) : M * BilinForm.toMatrix' B * N = +theorem BilinForm.mul_toMatrix'_mul (B : BilinForm R₁ (n → R₁)) (M : Matrix o n R₁) + (N : Matrix n o R₁) : M * BilinForm.toMatrix' B * N = BilinForm.toMatrix' (B.comp (Matrix.toLin' Mᵀ) (Matrix.toLin' N)) := LinearMap.mul_toMatrix₂'_mul B _ _ -theorem BilinForm.mul_toMatrix' (B : BilinForm R₂ (n → R₂)) (M : Matrix n n R₂) : +theorem BilinForm.mul_toMatrix' (B : BilinForm R₁ (n → R₁)) (M : Matrix n n R₁) : M * BilinForm.toMatrix' B = BilinForm.toMatrix' (B.compLeft (Matrix.toLin' Mᵀ)) := LinearMap.mul_toMatrix' B _ -theorem BilinForm.toMatrix'_mul (B : BilinForm R₂ (n → R₂)) (M : Matrix n n R₂) : +theorem BilinForm.toMatrix'_mul (B : BilinForm R₁ (n → R₁)) (M : Matrix n n R₁) : BilinForm.toMatrix' B * M = BilinForm.toMatrix' (B.compRight (Matrix.toLin' M)) := LinearMap.toMatrix₂'_mul B _ end LinearMap -theorem Matrix.toBilin'_comp (M : Matrix n n R₂) (P Q : Matrix n o R₂) : +theorem Matrix.toBilin'_comp (M : Matrix n n R₁) (P Q : Matrix n o R₁) : M.toBilin'.comp (Matrix.toLin' P) (Matrix.toLin' Q) = Matrix.toBilin' (Pᵀ * M * Q) := BilinForm.toMatrix'.injective (by simp only [BilinForm.toMatrix'_comp, BilinForm.toMatrix'_toBilin', toMatrix'_toLin']) @@ -194,32 +187,32 @@ a module with a fixed basis. -/ -variable [DecidableEq n] (b : Basis n R₂ M₂) +variable [DecidableEq n] (b : Basis n R₁ M₁) /-- `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 BilinForm.toMatrix : BilinForm R₂ M₂ ≃ₗ[R₂] Matrix n n R₂ := +noncomputable def BilinForm.toMatrix : BilinForm R₁ M₁ ≃ₗ[R₁] Matrix n n R₁ := LinearMap.toMatrix₂ b b /-- `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₂ := +noncomputable def Matrix.toBilin : Matrix n n R₁ ≃ₗ[R₁] BilinForm R₁ M₁ := (BilinForm.toMatrix b).symm @[simp] -theorem BilinForm.toMatrix_apply (B : BilinForm R₂ M₂) (i j : n) : +theorem 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 _ _ @[simp] -theorem Matrix.toBilin_apply (M : Matrix n n R₂) (x y : M₂) : +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 := (Matrix.toLinearMap₂_apply _ _ _ _ _).trans (by simp only [smul_eq_mul, mul_assoc, mul_comm, mul_left_comm]) -- Not a `simp` lemma since `BilinForm.toMatrix` needs an extra argument -theorem BilinearForm.toMatrixAux_eq (B : BilinForm R₂ M₂) : - BilinForm.toMatrixAux (R₂ := R₂) b B = BilinForm.toMatrix b B := +theorem BilinearForm.toMatrixAux_eq (B : BilinForm R₁ M₁) : + BilinForm.toMatrixAux (R₁ := R₁) b B = BilinForm.toMatrix b B := LinearMap.toMatrix₂Aux_eq _ _ B @[simp] @@ -230,62 +223,62 @@ theorem BilinForm.toMatrix_symm : (BilinForm.toMatrix b).symm = Matrix.toBilin b theorem Matrix.toBilin_symm : (Matrix.toBilin b).symm = BilinForm.toMatrix b := (BilinForm.toMatrix b).symm_symm -theorem Matrix.toBilin_basisFun : Matrix.toBilin (Pi.basisFun R₂ n) = Matrix.toBilin' := by +theorem Matrix.toBilin_basisFun : Matrix.toBilin (Pi.basisFun R₁ n) = Matrix.toBilin' := by ext M simp only [coe_comp, coe_single, Function.comp_apply, toBilin_apply, Pi.basisFun_repr, toBilin'_apply] theorem BilinForm.toMatrix_basisFun : - BilinForm.toMatrix (Pi.basisFun R₂ n) = BilinForm.toMatrix' := by + BilinForm.toMatrix (Pi.basisFun R₁ n) = BilinForm.toMatrix' := by rw [BilinForm.toMatrix, BilinForm.toMatrix', LinearMap.toMatrix₂_basisFun] @[simp] -theorem Matrix.toBilin_toMatrix (B : BilinForm R₂ M₂) : +theorem Matrix.toBilin_toMatrix (B : BilinForm R₁ M₁) : Matrix.toBilin b (BilinForm.toMatrix b B) = B := (Matrix.toBilin b).apply_symm_apply B @[simp] -theorem BilinForm.toMatrix_toBilin (M : Matrix n n R₂) : +theorem BilinForm.toMatrix_toBilin (M : Matrix n n R₁) : BilinForm.toMatrix b (Matrix.toBilin b M) = M := (BilinForm.toMatrix b).apply_symm_apply M -variable {M₂' : Type*} [AddCommMonoid M₂'] [Module R₂ M₂'] -variable (c : Basis o R₂ M₂') +variable {M₂' : Type*} [AddCommMonoid M₂'] [Module R₁ M₂'] +variable (c : Basis o R₁ M₂') variable [DecidableEq o] -- Cannot be a `simp` lemma because `b` must be inferred. -theorem BilinForm.toMatrix_comp (B : BilinForm R₂ M₂) (l r : M₂' →ₗ[R₂] M₂) : +theorem BilinForm.toMatrix_comp (B : BilinForm R₁ M₁) (l r : M₂' →ₗ[R₁] M₁) : BilinForm.toMatrix c (B.comp l r) = (LinearMap.toMatrix c b l)ᵀ * BilinForm.toMatrix b B * LinearMap.toMatrix c b r := LinearMap.toMatrix₂_compl₁₂ _ _ _ _ B _ _ -theorem BilinForm.toMatrix_compLeft (B : BilinForm R₂ M₂) (f : M₂ →ₗ[R₂] M₂) : +theorem 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 _ -theorem BilinForm.toMatrix_compRight (B : BilinForm R₂ M₂) (f : M₂ →ₗ[R₂] M₂) : +theorem 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 _ @[simp] -theorem BilinForm.toMatrix_mul_basis_toMatrix (c : Basis o R₂ M₂) (B : BilinForm R₂ M₂) : +theorem 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 -theorem BilinForm.mul_toMatrix_mul (B : BilinForm R₂ M₂) (M : Matrix o n R₂) (N : Matrix n o R₂) : +theorem 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 _ _ -theorem BilinForm.mul_toMatrix (B : BilinForm R₂ M₂) (M : Matrix n n R₂) : +theorem 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 _ -theorem BilinForm.toMatrix_mul (B : BilinForm R₂ M₂) (M : Matrix n n R₂) : +theorem 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 _ -theorem Matrix.toBilin_comp (M : Matrix n n R₂) (P Q : Matrix n o R₂) : +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 rw [Matrix.toBilin, BilinForm.toMatrix, Matrix.toBilin, BilinForm.toMatrix, toMatrix₂_symm, @@ -301,8 +294,8 @@ section MatrixAdjoints open Matrix variable {n : Type*} [Fintype n] -variable (b : Basis n R₃ M₃) -variable (J J₃ A A' : Matrix n n R₃) +variable (b : Basis n R₂ M₂) +variable (J J₃ A A' : Matrix n n R₂) @[simp] theorem isAdjointPair_toBilin' [DecidableEq n] : @@ -318,7 +311,7 @@ theorem isAdjointPair_toBilin [DecidableEq n] : Matrix.IsAdjointPair J J₃ A A' := isAdjointPair_toLinearMap₂ _ _ _ _ _ _ -theorem Matrix.isAdjointPair_equiv' [DecidableEq n] (P : Matrix n n R₃) (h : IsUnit P) : +theorem Matrix.isAdjointPair_equiv' [DecidableEq n] (P : Matrix n n R₂) (h : IsUnit P) : (Pᵀ * J * P).IsAdjointPair (Pᵀ * J * P) A A' ↔ J.IsAdjointPair J (P * A * P⁻¹) (P * A' * P⁻¹) := Matrix.isAdjointPair_equiv _ _ _ _ h @@ -327,10 +320,10 @@ variable [DecidableEq n] /-- The submodule of pair-self-adjoint matrices with respect to bilinear forms corresponding to given matrices `J`, `J₂`. -/ -def pairSelfAdjointMatricesSubmodule' : Submodule R₃ (Matrix n n R₃) := +def pairSelfAdjointMatricesSubmodule' : Submodule R₂ (Matrix n n R₂) := (BilinForm.isPairSelfAdjointSubmodule (Matrix.toBilin' J) (Matrix.toBilin' J₃)).map - ((LinearMap.toMatrix' : ((n → R₃) →ₗ[R₃] n → R₃) ≃ₗ[R₃] Matrix n n R₃) : - ((n → R₃) →ₗ[R₃] n → R₃) →ₗ[R₃] Matrix n n R₃) + ((LinearMap.toMatrix' : ((n → R₂) →ₗ[R₂] n → R₂) ≃ₗ[R₂] Matrix n n R₂) : + ((n → R₂) →ₗ[R₂] n → R₂) →ₗ[R₂] Matrix n n R₂) theorem mem_pairSelfAdjointMatricesSubmodule' : A ∈ pairSelfAdjointMatricesSubmodule J J₃ ↔ Matrix.IsAdjointPair J J₃ A A := by @@ -338,7 +331,7 @@ theorem mem_pairSelfAdjointMatricesSubmodule' : /-- The submodule of self-adjoint matrices with respect to the bilinear form corresponding to the matrix `J`. -/ -def selfAdjointMatricesSubmodule' : Submodule R₃ (Matrix n n R₃) := +def selfAdjointMatricesSubmodule' : Submodule R₂ (Matrix n n R₂) := pairSelfAdjointMatricesSubmodule J J theorem mem_selfAdjointMatricesSubmodule' : @@ -347,7 +340,7 @@ theorem mem_selfAdjointMatricesSubmodule' : /-- The submodule of skew-adjoint matrices with respect to the bilinear form corresponding to the matrix `J`. -/ -def skewAdjointMatricesSubmodule' : Submodule R₃ (Matrix n n R₃) := +def skewAdjointMatricesSubmodule' : Submodule R₂ (Matrix n n R₂) := pairSelfAdjointMatricesSubmodule (-J) J theorem mem_skewAdjointMatricesSubmodule' : @@ -364,49 +357,49 @@ section Det open Matrix -variable {A : Type*} [CommRing A] [IsDomain A] [Module A M₃] (B₃ : BilinForm A M₃) +variable {A : Type*} [CommRing A] [IsDomain A] [Module A M₂] (B₃ : BilinForm A M₂) variable {ι : Type*} [DecidableEq ι] [Fintype ι] -theorem _root_.Matrix.nondegenerate_toBilin'_iff_nondegenerate_toBilin {M : Matrix ι ι R₂} - (b : Basis ι R₂ M₂) : M.toBilin'.Nondegenerate ↔ (Matrix.toBilin b M).Nondegenerate := +theorem _root_.Matrix.nondegenerate_toBilin'_iff_nondegenerate_toBilin {M : Matrix ι ι R₁} + (b : Basis ι R₁ M₁) : M.toBilin'.Nondegenerate ↔ (Matrix.toBilin b M).Nondegenerate := (nondegenerate_congr_iff b.equivFun.symm).symm -- Lemmas transferring nondegeneracy between a matrix and its associated bilinear form -theorem _root_.Matrix.Nondegenerate.toBilin' {M : Matrix ι ι R₃} (h : M.Nondegenerate) : +theorem _root_.Matrix.Nondegenerate.toBilin' {M : Matrix ι ι R₂} (h : M.Nondegenerate) : M.toBilin'.Nondegenerate := fun x hx => h.eq_zero_of_ortho fun y => by simpa only [toBilin'_apply'] using hx y @[simp] -theorem _root_.Matrix.nondegenerate_toBilin'_iff {M : Matrix ι ι R₃} : +theorem _root_.Matrix.nondegenerate_toBilin'_iff {M : Matrix ι ι R₂} : M.toBilin'.Nondegenerate ↔ M.Nondegenerate := ⟨fun h v hv => h v fun w => (M.toBilin'_apply' _ _).trans <| hv w, Matrix.Nondegenerate.toBilin'⟩ -theorem _root_.Matrix.Nondegenerate.toBilin {M : Matrix ι ι R₃} (h : M.Nondegenerate) - (b : Basis ι R₃ M₃) : (Matrix.toBilin b M).Nondegenerate := +theorem _root_.Matrix.Nondegenerate.toBilin {M : Matrix ι ι R₂} (h : M.Nondegenerate) + (b : Basis ι R₂ M₂) : (Matrix.toBilin b M).Nondegenerate := (Matrix.nondegenerate_toBilin'_iff_nondegenerate_toBilin b).mp h.toBilin' @[simp] -theorem _root_.Matrix.nondegenerate_toBilin_iff {M : Matrix ι ι R₃} (b : Basis ι R₃ M₃) : +theorem _root_.Matrix.nondegenerate_toBilin_iff {M : Matrix ι ι R₂} (b : Basis ι R₂ M₂) : (Matrix.toBilin b M).Nondegenerate ↔ M.Nondegenerate := by rw [← Matrix.nondegenerate_toBilin'_iff_nondegenerate_toBilin, Matrix.nondegenerate_toBilin'_iff] /-! Lemmas transferring nondegeneracy between a bilinear form and its associated matrix -/ @[simp] -theorem nondegenerate_toMatrix'_iff {B : BilinForm R₃ (ι → R₃)} : +theorem nondegenerate_toMatrix'_iff {B : BilinForm R₂ (ι → R₂)} : B.toMatrix'.Nondegenerate (m := ι) ↔ B.Nondegenerate := Matrix.nondegenerate_toBilin'_iff.symm.trans <| (Matrix.toBilin'_toMatrix' B).symm ▸ Iff.rfl -theorem Nondegenerate.toMatrix' {B : BilinForm R₃ (ι → R₃)} (h : B.Nondegenerate) : +theorem Nondegenerate.toMatrix' {B : BilinForm R₂ (ι → R₂)} (h : B.Nondegenerate) : B.toMatrix'.Nondegenerate := nondegenerate_toMatrix'_iff.mpr h @[simp] -theorem nondegenerate_toMatrix_iff {B : BilinForm R₃ M₃} (b : Basis ι R₃ M₃) : +theorem nondegenerate_toMatrix_iff {B : BilinForm R₂ M₂} (b : Basis ι R₂ M₂) : (BilinForm.toMatrix b B).Nondegenerate ↔ B.Nondegenerate := (Matrix.nondegenerate_toBilin_iff b).symm.trans <| (Matrix.toBilin_toMatrix b B).symm ▸ Iff.rfl -theorem Nondegenerate.toMatrix {B : BilinForm R₃ M₃} (h : B.Nondegenerate) (b : Basis ι R₃ M₃) : +theorem Nondegenerate.toMatrix {B : BilinForm R₂ M₂} (h : B.Nondegenerate) (b : Basis ι R₂ M₂) : (BilinForm.toMatrix b B).Nondegenerate := (nondegenerate_toMatrix_iff b).mpr h @@ -420,11 +413,11 @@ theorem nondegenerate_toBilin'_of_det_ne_zero' (M : Matrix ι ι A) (h : M.det M.toBilin'.Nondegenerate := nondegenerate_toBilin'_iff_det_ne_zero.mpr h -theorem nondegenerate_iff_det_ne_zero {B : BilinForm A M₃} (b : Basis ι A M₃) : +theorem nondegenerate_iff_det_ne_zero {B : BilinForm A M₂} (b : Basis ι A M₂) : B.Nondegenerate ↔ (BilinForm.toMatrix b B).det ≠ 0 := by rw [← Matrix.nondegenerate_iff_det_ne_zero, nondegenerate_toMatrix_iff] -theorem nondegenerate_of_det_ne_zero (b : Basis ι A M₃) (h : (BilinForm.toMatrix b B₃).det ≠ 0) : +theorem nondegenerate_of_det_ne_zero (b : Basis ι A M₂) (h : (BilinForm.toMatrix b B₃).det ≠ 0) : B₃.Nondegenerate := (nondegenerate_iff_det_ne_zero b).mpr h diff --git a/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean b/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean index 2defb3e6bfd2fd..d2bec25790e579 100644 --- a/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean +++ b/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean @@ -642,7 +642,7 @@ open scoped Interval section IoiFTC -variable {E : Type*} {f f' : ℝ → E} {g g' : ℝ → ℝ} {a b l : ℝ} {m : E} [NormedAddCommGroup E] +variable {E : Type*} {f f' : ℝ → E} {g g' : ℝ → ℝ} {a l : ℝ} {m : E} [NormedAddCommGroup E] [NormedSpace ℝ E] /-- If the derivative of a function defined on the real line is integrable close to `+∞`, then @@ -864,7 +864,7 @@ end IoiFTC section IicFTC -variable {E : Type*} {f f' : ℝ → E} {g g' : ℝ → ℝ} {a b l : ℝ} {m : E} [NormedAddCommGroup E] +variable {E : Type*} {f f' : ℝ → E} {a : ℝ} {m : E} [NormedAddCommGroup E] [NormedSpace ℝ E] /-- If the derivative of a function defined on the real line is integrable close to `-∞`, then @@ -983,7 +983,7 @@ end IicFTC section UnivFTC -variable {E : Type*} {f f' : ℝ → E} {g g' : ℝ → ℝ} {a b l : ℝ} {m n : E} [NormedAddCommGroup E] +variable {E : Type*} {f f' : ℝ → E} {m n : E} [NormedAddCommGroup E] [NormedSpace ℝ E] /-- **Fundamental theorem of calculus-2**, on the whole real line @@ -1025,7 +1025,7 @@ open Real open scoped Interval -variable {E : Type*} {f : ℝ → E} [NormedAddCommGroup E] [NormedSpace ℝ E] +variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] /-- Change-of-variables formula for `Ioi` integrals of vector-valued functions, proved by taking limits from the result for finite intervals. -/ @@ -1224,7 +1224,7 @@ end IntegrationByPartsBilinear section IntegrationByPartsAlgebra variable {A : Type*} [NormedRing A] [NormedAlgebra ℝ A] - {a b : ℝ} {a' b' : A} {u : ℝ → A} {v : ℝ → A} {u' : ℝ → A} {v' : ℝ → A} + {a : ℝ} {a' b' : A} {u : ℝ → A} {v : ℝ → A} {u' : ℝ → A} {v' : ℝ → A} /-- For finite intervals, see: `intervalIntegral.integral_deriv_mul_eq_sub`. -/ theorem integral_deriv_mul_eq_sub [CompleteSpace A] From b1339713239c1b5d346e9775890d2932826312d8 Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Tue, 15 Oct 2024 10:13:37 +0000 Subject: [PATCH 141/425] refactor(Maschke): use `IsUnit` instead of `Invertible` (#17754) --- Mathlib/RepresentationTheory/Maschke.lean | 37 +++++++++++------------ 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/Mathlib/RepresentationTheory/Maschke.lean b/Mathlib/RepresentationTheory/Maschke.lean index 7eaec76c225f9a..a3351fef477c7f 100644 --- a/Mathlib/RepresentationTheory/Maschke.lean +++ b/Mathlib/RepresentationTheory/Maschke.lean @@ -12,19 +12,18 @@ import Mathlib.RingTheory.SimpleModule We prove **Maschke's theorem** for finite groups, in the formulation that every submodule of a `k[G]` module has a complement, -when `k` is a field with `Invertible (Fintype.card G : k)`. +when `k` is a field with `Fintype.card G` invertible in `k`. We do the core computation in greater generality. -For any `[CommRing k]` in which `[Invertible (Fintype.card G : k)]`, +For any commutative ring `k` in which `Fintype.card G` is invertible, and a `k[G]`-linear map `i : V → W` which admits a `k`-linear retraction `π`, we produce a `k[G]`-linear retraction by taking the average over `G` of the conjugates of `π`. ## Implementation Notes -* These results assume `Invertible (Fintype.card G : k)` which is equivalent to the more -familiar `¬(ringChar k ∣ Fintype.card G)`. It is possible to convert between them using -`invertibleOfRingCharNotDvd` and `not_ringChar_dvd_of_invertible`. +* These results assume `IsUnit (Fintype.card G : k)` which is equivalent to the more + familiar `¬(ringChar k ∣ Fintype.card G)`. ## Future work It's not so far to give the usual statement, that every finite dimensional representation @@ -55,7 +54,7 @@ namespace LinearMap -- At first we work with any `[CommRing k]`, and add the assumption that --- `[Invertible (Fintype.card G : k)]` when it is required. +-- `IsUnit (Fintype.card G : k)` when it is required. variable {k : Type u} [CommRing k] {G : Type u} [Group G] variable {V : Type v} [AddCommGroup V] [Module k V] [Module (MonoidAlgebra k G) V] variable [IsScalarTower k (MonoidAlgebra k G) V] @@ -65,7 +64,7 @@ variable (π : W →ₗ[k] V) /-- We define the conjugate of `π` by `g`, as a `k`-linear map. -/ def conjugate (g : G) : W →ₗ[k] V := - .comp (.comp (GroupSMul.linearMap k V g⁻¹) π) (GroupSMul.linearMap k W g) + GroupSMul.linearMap k V g⁻¹ ∘ₗ π ∘ₗ GroupSMul.linearMap k W g theorem conjugate_apply (g : G) (v : W) : π.conjugate g v = MonoidAlgebra.single g⁻¹ (1 : k) • π (MonoidAlgebra.single g (1 : k) • v) := @@ -75,7 +74,7 @@ variable (i : V →ₗ[MonoidAlgebra k G] W) section -theorem conjugate_i (h : ∀ v : V, (π : W → V) (i v) = v) (g : G) (v : V) : +theorem conjugate_i (h : ∀ v : V, π (i v) = v) (g : G) (v : V) : (conjugate π g : W → V) (i v) = v := by rw [conjugate_apply, ← i.map_smul, h, ← mul_smul, single_mul_single, mul_one, inv_mul_cancel, ← one_def, one_smul] @@ -108,24 +107,22 @@ theorem sumOfConjugatesEquivariant_apply (v : W) : section -variable [Invertible (Fintype.card G : k)] - /-- We construct our `k[G]`-linear retraction of `i` as $$ \frac{1}{|G|} \sum_{g \in G} g⁻¹ • π(g • -). $$ -/ def equivariantProjection : W →ₗ[MonoidAlgebra k G] V := - ⅟(Fintype.card G : k) • π.sumOfConjugatesEquivariant G + Ring.inverse (Fintype.card G : k) • π.sumOfConjugatesEquivariant G theorem equivariantProjection_apply (v : W) : - π.equivariantProjection G v = ⅟(Fintype.card G : k) • ∑ g : G, π.conjugate g v := by + π.equivariantProjection G v = Ring.inverse (Fintype.card G : k) • ∑ g : G, π.conjugate g v := by simp only [equivariantProjection, smul_apply, sumOfConjugatesEquivariant_apply] -theorem equivariantProjection_condition (h : ∀ v : V, (π : W → V) (i v) = v) (v : V) : - (π.equivariantProjection G) (i v) = v := by +theorem equivariantProjection_condition (hcard : IsUnit (Fintype.card G : k)) + (h : ∀ v : V, π (i v) = v) (v : V) : (π.equivariantProjection G) (i v) = v := by rw [equivariantProjection_apply] simp only [conjugate_i π i h] rw [Finset.sum_const, Finset.card_univ, ← Nat.cast_smul_eq_nsmul k, smul_smul, - Invertible.invOf_mul_self, one_smul] + Ring.inverse_mul_cancel _ hcard, one_smul] end @@ -136,13 +133,13 @@ end namespace MonoidAlgebra -- Now we work over a `[Field k]`. -variable {k : Type u} [Field k] {G : Type u} [Fintype G] [Invertible (Fintype.card G : k)] +variable {k : Type u} [Field k] {G : Type u} [Fintype G] [NeZero (Fintype.card G : k)] variable [Group G] variable {V : Type u} [AddCommGroup V] [Module (MonoidAlgebra k G) V] variable {W : Type u} [AddCommGroup W] [Module (MonoidAlgebra k G) W] -theorem exists_leftInverse_of_injective (f : V →ₗ[MonoidAlgebra k G] W) - (hf : LinearMap.ker f = ⊥) : +theorem exists_leftInverse_of_injective + (f : V →ₗ[MonoidAlgebra k G] W) (hf : LinearMap.ker f = ⊥) : ∃ g : W →ₗ[MonoidAlgebra k G] V, g.comp f = LinearMap.id := by let A := MonoidAlgebra k G letI : Module k W := .compHom W (algebraMap k A) @@ -152,7 +149,7 @@ theorem exists_leftInverse_of_injective (f : V →ₗ[MonoidAlgebra k G] W) obtain ⟨φ, hφ⟩ := (f.restrictScalars k).exists_leftInverse_of_injective <| by simp only [hf, Submodule.restrictScalars_bot, LinearMap.ker_restrictScalars] refine ⟨φ.equivariantProjection G, DFunLike.ext _ _ ?_⟩ - exact φ.equivariantProjection_condition G _ <| DFunLike.congr_fun hφ + exact φ.equivariantProjection_condition G _ (.mk0 _ <| NeZero.ne _) <| DFunLike.congr_fun hφ namespace Submodule @@ -167,7 +164,7 @@ instance complementedLattice : ComplementedLattice (Submodule (MonoidAlgebra k G ⟨exists_isCompl⟩ instance [AddGroup G] : IsSemisimpleRing (AddMonoidAlgebra k G) := - letI : Invertible (Fintype.card (Multiplicative G) : k) := by + haveI : NeZero (Fintype.card (Multiplicative G) : k) := by rwa [Fintype.card_congr Multiplicative.toAdd] (AddMonoidAlgebra.toMultiplicativeAlgEquiv k G (R := ℕ)).toRingEquiv.symm.isSemisimpleRing From c9428b0dd6704e88e5703a7c1ab96dbcbac9ea41 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Tue, 15 Oct 2024 10:13:38 +0000 Subject: [PATCH 142/425] chore: split off `RBMap` dependency from `Mathlib.Data.Tree` (#17764) `Tree.ofRBNode` does not seem to be used in Mathlib anyway, so let's avoid an unnecessary import of Batteries and move this to a new leaf file in case anyone needs to use it still. --- Mathlib.lean | 1 + Mathlib/Data/Tree/Basic.lean | 8 -------- Mathlib/Data/Tree/RBMap.lean | 37 ++++++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 Mathlib/Data/Tree/RBMap.lean diff --git a/Mathlib.lean b/Mathlib.lean index dc71e6f68be109..8cd33465fca3ab 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2628,6 +2628,7 @@ import Mathlib.Data.Sym.Sym2.Init import Mathlib.Data.Sym.Sym2.Order import Mathlib.Data.Tree.Basic import Mathlib.Data.Tree.Get +import Mathlib.Data.Tree.RBMap import Mathlib.Data.TwoPointing import Mathlib.Data.TypeMax import Mathlib.Data.TypeVec diff --git a/Mathlib/Data/Tree/Basic.lean b/Mathlib/Data/Tree/Basic.lean index 4628f0ce38b536..95ebf3246593cf 100644 --- a/Mathlib/Data/Tree/Basic.lean +++ b/Mathlib/Data/Tree/Basic.lean @@ -3,7 +3,6 @@ Copyright (c) 2019 mathlib community. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Mario Carneiro, Wojciech Nawrocki -/ -import Batteries.Data.RBMap.Basic import Mathlib.Data.Nat.Notation import Mathlib.Tactic.TypeStar import Mathlib.Util.CompileInductive @@ -46,13 +45,6 @@ variable {α : Type u} instance : Inhabited (Tree α) := ⟨nil⟩ -open Batteries (RBNode) - -/-- Makes a `Tree α` out of a red-black tree. -/ -def ofRBNode : RBNode α → Tree α - | RBNode.nil => nil - | RBNode.node _color l key r => node key (ofRBNode l) (ofRBNode r) - /-- Apply a function to each value in the tree. This is the `map` function for the `Tree` functor. -/ def map {β} (f : α → β) : Tree α → Tree β diff --git a/Mathlib/Data/Tree/RBMap.lean b/Mathlib/Data/Tree/RBMap.lean new file mode 100644 index 00000000000000..6ea502b79c94ce --- /dev/null +++ b/Mathlib/Data/Tree/RBMap.lean @@ -0,0 +1,37 @@ +/- +Copyright (c) 2019 mathlib community. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Mario Carneiro, Wojciech Nawrocki +-/ +import Batteries.Data.RBMap.Basic +import Mathlib.Data.Tree.Basic + +/-! +# Binary tree and RBMaps + +In this file we define `Tree.ofRBNode`. +This definition was moved from the main file to avoid a dependency on `RBMap`. + +## TODO + +Implement a `Traversable` instance for `Tree`. + +## References + + +-/ + +namespace Tree + +universe u + +variable {α : Type u} + +open Batteries (RBNode) + +/-- Makes a `Tree α` out of a red-black tree. -/ +def ofRBNode : RBNode α → Tree α + | RBNode.nil => nil + | RBNode.node _color l key r => node key (ofRBNode l) (ofRBNode r) + +end Tree From 404e1f3639ecd6329883e3481b6bc49b3b6378e4 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Tue, 15 Oct 2024 21:20:58 +1100 Subject: [PATCH 143/425] bump batteries --- lake-manifest.json | 4 ++-- lakefile.lean | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index 4ce8fab0e9cbaf..12f886e8d32725 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,10 +5,10 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "ad3ba5ff13913874b80146b54d0a4e5b9b739451", + "rev": "9a67ae906126e0c185dbc9f5999a417c188a671c", "name": "batteries", "manifestFile": "lake-manifest.json", - "inputRev": "main", + "inputRev": "nightly-testing", "inherited": false, "configFile": "lakefile.lean"}, {"url": "https://github.com/leanprover-community/quote4", diff --git a/lakefile.lean b/lakefile.lean index 59b2eae8ed37f9..ac51402c176115 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -7,7 +7,7 @@ open Lake DSL ## Mathlib dependencies on upstream projects -/ -require "leanprover-community" / "batteries" @ git "main" +require "leanprover-community" / "batteries" @ git "nightly-testing" require "leanprover-community" / "Qq" @ git "master" require "leanprover-community" / "aesop" @ git "master" require "leanprover-community" / "proofwidgets" @ git "v0.0.43-pre" From 37f4d8e25bac1663fd3266d6880fb033233007bb Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Tue, 15 Oct 2024 21:23:03 +1100 Subject: [PATCH 144/425] fixes --- Mathlib/Logic/Function/Basic.lean | 8 -------- Mathlib/Logic/Function/Defs.lean | 16 ---------------- Mathlib/Tactic/Linter/HaveLetLinter.lean | 2 +- Mathlib/Tactic/Linter/UnusedTactic.lean | 2 +- Mathlib/Tactic/ToAdditive/Frontend.lean | 8 ++++---- 5 files changed, 6 insertions(+), 30 deletions(-) diff --git a/Mathlib/Logic/Function/Basic.lean b/Mathlib/Logic/Function/Basic.lean index 131ecb1c0731d4..875afd15a520f7 100644 --- a/Mathlib/Logic/Function/Basic.lean +++ b/Mathlib/Logic/Function/Basic.lean @@ -710,14 +710,6 @@ end FactorsThrough theorem uncurry_def {α β γ} (f : α → β → γ) : uncurry f = fun p ↦ f p.1 p.2 := rfl -@[simp] -theorem uncurry_apply_pair {α β γ} (f : α → β → γ) (x : α) (y : β) : uncurry f (x, y) = f x y := - rfl - -@[simp] -theorem curry_apply {α β γ} (f : α × β → γ) (x : α) (y : β) : curry f x y = f (x, y) := - rfl - section Bicomp variable {α β γ δ ε : Type*} diff --git a/Mathlib/Logic/Function/Defs.lean b/Mathlib/Logic/Function/Defs.lean index ab1505baf76fa8..59d9f8331492aa 100644 --- a/Mathlib/Logic/Function/Defs.lean +++ b/Mathlib/Logic/Function/Defs.lean @@ -177,22 +177,6 @@ namespace Function variable {α : Type u₁} {β : Type u₂} {φ : Type u₃} -/-- Interpret a function on `α × β` as a function with two arguments. -/ -@[inline] -def curry : (α × β → φ) → α → β → φ := fun f a b => f (a, b) - -/-- Interpret a function with two arguments as a function on `α × β` -/ -@[inline] -def uncurry : (α → β → φ) → α × β → φ := fun f a => f a.1 a.2 - -@[simp] -theorem curry_uncurry (f : α → β → φ) : curry (uncurry f) = f := - rfl - -@[simp] -theorem uncurry_curry (f : α × β → φ) : uncurry (curry f) = f := - funext fun ⟨_a, _b⟩ => rfl - protected theorem LeftInverse.id {g : β → α} {f : α → β} (h : LeftInverse g f) : g ∘ f = id := funext h diff --git a/Mathlib/Tactic/Linter/HaveLetLinter.lean b/Mathlib/Tactic/Linter/HaveLetLinter.lean index 08b0435b8de7c5..fe586741660b66 100644 --- a/Mathlib/Tactic/Linter/HaveLetLinter.lean +++ b/Mathlib/Tactic/Linter/HaveLetLinter.lean @@ -102,7 +102,7 @@ def nonPropHaves : InfoTree → CommandElabM (Array (Syntax × Format)) := -- so that we can then isolate the `fvarId`s that are created by `have` let oldMvdecls := (i.goalsBefore.map (mctx.decls.find? ·)).reduceOption let oldLctx := oldMvdecls.map (·.lctx) - let oldDecls := (oldLctx.map (·.decls.toList.reduceOption)).join + let oldDecls := (oldLctx.map (·.decls.toList.reduceOption)).flatten let oldFVars := oldDecls.map (·.fvarId) -- `newDecls` are the local declarations whose `FVarID` did not exist before the `have` -- effectively they are the declarations that we want to test for being in `Prop` or not. diff --git a/Mathlib/Tactic/Linter/UnusedTactic.lean b/Mathlib/Tactic/Linter/UnusedTactic.lean index 67eb1b34f7d9f0..52bfc9bf05573f 100644 --- a/Mathlib/Tactic/Linter/UnusedTactic.lean +++ b/Mathlib/Tactic/Linter/UnusedTactic.lean @@ -162,7 +162,7 @@ variable (ignoreTacticKinds : NameHashSet) (isTacKind : SyntaxNodeKind → Bool) `MetavarContext` `mctx`. -/ def getNames (mctx : MetavarContext) : List Name := let lcts := mctx.decls.toList.map (MetavarDecl.lctx ∘ Prod.snd) - let locDecls := (lcts.map (PersistentArray.toList ∘ LocalContext.decls)).join.reduceOption + let locDecls := (lcts.map (PersistentArray.toList ∘ LocalContext.decls)).flatten.reduceOption locDecls.map LocalDecl.userName mutual diff --git a/Mathlib/Tactic/ToAdditive/Frontend.lean b/Mathlib/Tactic/ToAdditive/Frontend.lean index bdc528a2940732..b5064e04762fd5 100644 --- a/Mathlib/Tactic/ToAdditive/Frontend.lean +++ b/Mathlib/Tactic/ToAdditive/Frontend.lean @@ -567,11 +567,11 @@ where /-- Implementation of `applyReplacementFun`. -/ match e with | .const n₀ ls₀ => do let n₁ := n₀.mapPrefix findTranslation? - let ls₁ : List Level := if 0 ∈ (reorderFn n₀).join then ls₀.swapFirstTwo else ls₀ + let ls₁ : List Level := if 0 ∈ (reorderFn n₀).flatten then ls₀.swapFirstTwo else ls₀ if trace then if n₀ != n₁ then dbg_trace s!"changing {n₀} to {n₁}" - if 0 ∈ (reorderFn n₀).join then + if 0 ∈ (reorderFn n₀).flatten then dbg_trace s!"reordering the universe variables from {ls₀} to {ls₁}" return some <| Lean.mkConst n₁ ls₁ | .app g x => do @@ -651,7 +651,7 @@ def expand (e : Expr) : MetaM Expr := do if reorder.isEmpty then -- no need to expand if nothing needs reordering return .continue - let needed_n := reorder.join.foldr Nat.max 0 + 1 + let needed_n := reorder.flatten.foldr Nat.max 0 + 1 -- the second disjunct is a temporary fix to avoid infinite loops. -- We may need to use `replaceRec` or something similar to not change the head of an application if needed_n ≤ es.size || es.size == 0 then @@ -684,7 +684,7 @@ def reorderLambda (reorder : List (List Nat) := []) (src : Expr) : MetaM Expr := def updateDecl (tgt : Name) (srcDecl : ConstantInfo) (reorder : List (List Nat) := []) : MetaM ConstantInfo := do let mut decl := srcDecl.updateName tgt - if 0 ∈ reorder.join then + if 0 ∈ reorder.flatten then decl := decl.updateLevelParams decl.levelParams.swapFirstTwo decl := decl.updateType <| ← applyReplacementFun <| ← reorderForall reorder <| ← expand <| ← unfoldAuxLemmas decl.type From a8d89aad7e51b90b1d78621c57b8aafef36ba95d Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Tue, 15 Oct 2024 21:42:30 +1100 Subject: [PATCH 145/425] fixes --- Mathlib/Algebra/BigOperators/Group/List.lean | 53 ++++++---- Mathlib/Algebra/FreeMonoid/Basic.lean | 10 +- Mathlib/Data/Fin/Basic.lean | 4 - Mathlib/Data/List/Basic.lean | 28 ++--- Mathlib/Data/List/Chain.lean | 12 ++- Mathlib/Data/List/Forall2.lean | 8 +- Mathlib/Data/List/GroupBy.lean | 10 +- Mathlib/Data/List/Indexes.lean | 100 ++---------------- Mathlib/Data/List/Join.lean | 89 ++++++++++------ Mathlib/Data/List/Nodup.lean | 9 +- Mathlib/Data/List/OfFn.lean | 10 +- Mathlib/Data/List/Perm.lean | 4 +- Mathlib/Data/List/Range.lean | 12 ++- Mathlib/Data/List/Sigma.lean | 8 +- Mathlib/Data/List/Sublists.lean | 2 +- Mathlib/Data/List/Zip.lean | 9 -- Mathlib/Data/Multiset/Bind.lean | 5 +- .../CategoryTheory/Coherence/Basic.lean | 2 +- Mathlib/Tactic/CongrExclamation.lean | 2 +- Mathlib/Tactic/Linarith/Preprocessing.lean | 2 +- Mathlib/Tactic/Widget/StringDiagram.lean | 14 +-- Mathlib/Testing/SlimCheck/Sampleable.lean | 4 +- 22 files changed, 171 insertions(+), 226 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Group/List.lean b/Mathlib/Algebra/BigOperators/Group/List.lean index 7eb37c116a4055..69d4afc12ffe69 100644 --- a/Mathlib/Algebra/BigOperators/Group/List.lean +++ b/Mathlib/Algebra/BigOperators/Group/List.lean @@ -118,8 +118,11 @@ theorem prod_concat : (l.concat a).prod = l.prod * a := by rw [concat_eq_append, prod_append, prod_singleton] @[to_additive (attr := simp)] -theorem prod_join {l : List (List M)} : l.join.prod = (l.map List.prod).prod := by - induction l <;> [rfl; simp only [*, List.join, map, prod_append, prod_cons]] +theorem prod_flatten {l : List (List M)} : l.flatten.prod = (l.map List.prod).prod := by + induction l <;> [rfl; simp only [*, List.flatten, map, prod_append, prod_cons]] + +@[deprecated (since := "2024-10-15")] alias prod_join := prod_flatten +@[deprecated (since := "2024-10-15")] alias sum_join := sum_flatten @[to_additive] theorem prod_eq_foldr {l : List M} : l.prod = foldr (· * ·) 1 l := rfl @@ -639,7 +642,9 @@ namespace List lemma length_sigma {σ : α → Type*} (l₁ : List α) (l₂ : ∀ a, List (σ a)) : length (l₁.sigma l₂) = (l₁.map fun a ↦ length (l₂ a)).sum := by simp [length_sigma'] -lemma ranges_join (l : List ℕ) : l.ranges.join = range l.sum := by simp [ranges_join'] +lemma ranges_flatten (l : List ℕ) : l.ranges.flatten = range l.sum := by simp [ranges_flatten'] + +@[deprecated (since := "2024-10-15")] alias ranges_join := ranges_flatten /-- Any entry of any member of `l.ranges` is strictly smaller than `l.sum`. -/ lemma mem_mem_ranges_iff_lt_sum (l : List ℕ) {n : ℕ} : @@ -648,37 +653,47 @@ lemma mem_mem_ranges_iff_lt_sum (l : List ℕ) {n : ℕ} : @[simp] theorem length_bind (l : List α) (f : α → List β) : length (List.bind l f) = sum (map (length ∘ f) l) := by - rw [List.bind, length_join, map_map, Nat.sum_eq_listSum] + rw [List.bind, length_flatten, map_map, Nat.sum_eq_listSum] lemma countP_bind (p : β → Bool) (l : List α) (f : α → List β) : countP p (l.bind f) = sum (map (countP p ∘ f) l) := by - rw [List.bind, countP_join, map_map] + rw [List.bind, countP_flatten, map_map] simp lemma count_bind [BEq β] (l : List α) (f : α → List β) (x : β) : count x (l.bind f) = sum (map (count x ∘ f) l) := countP_bind _ _ _ -/-- In a join, taking the first elements up to an index which is the sum of the lengths of the -first `i` sublists, is the same as taking the join of the first `i` sublists. -/ -lemma take_sum_join (L : List (List α)) (i : ℕ) : - L.join.take ((L.map length).take i).sum = (L.take i).join := by simpa using take_sum_join' _ _ +/-- In a flatten, taking the first elements up to an index which is the sum of the lengths of the +first `i` sublists, is the same as taking the flatten of the first `i` sublists. -/ +lemma take_sum_flatten (L : List (List α)) (i : ℕ) : + L.flatten.take ((L.map length).take i).sum = (L.take i).flatten := by + simpa using take_sum_flatten' _ _ + +@[deprecated (since := "2024-10-15")] alias take_sum_join := take_sum_flatten -/-- In a join, dropping all the elements up to an index which is the sum of the lengths of the +/-- In a flatten, dropping all the elements up to an index which is the sum of the lengths of the first `i` sublists, is the same as taking the join after dropping the first `i` sublists. -/ -lemma drop_sum_join (L : List (List α)) (i : ℕ) : - L.join.drop ((L.map length).take i).sum = (L.drop i).join := by simpa using drop_sum_join' _ _ +lemma drop_sum_flatten (L : List (List α)) (i : ℕ) : + L.flatten.drop ((L.map length).take i).sum = (L.drop i).flatten := by + simpa using drop_sum_flatten' _ _ -/-- In a join of sublists, taking the slice between the indices `A` and `B - 1` gives back the +@[deprecated (since := "2024-10-15")] alias drop_sum_join := drop_sum_flatten + +/-- In a flatten of sublists, taking the slice between the indices `A` and `B - 1` gives back the original sublist of index `i` if `A` is the sum of the lengths of sublists of index `< i`, and `B` is the sum of the lengths of sublists of index `≤ i`. -/ -lemma drop_take_succ_join_eq_getElem (L : List (List α)) (i : Nat) (h : i < L.length) : - (L.join.take ((L.map length).take (i + 1)).sum).drop ((L.map length).take i).sum = L[i] := by - simpa using drop_take_succ_join_eq_getElem' _ _ _ +lemma drop_take_succ_flatten_eq_getElem (L : List (List α)) (i : Nat) (h : i < L.length) : + (L.flatten.take ((L.map length).take (i + 1)).sum).drop ((L.map length).take i).sum = L[i] := by + simpa using drop_take_succ_flatten_eq_getElem' _ _ _ + +@[deprecated (since := "2024-06-11")] +alias drop_take_succ_join_eq_getElem := drop_take_succ_flatten_eq_getElem -@[deprecated drop_take_succ_join_eq_getElem (since := "2024-06-11")] +@[deprecated drop_take_succ_flatten_eq_getElem (since := "2024-06-11")] lemma drop_take_succ_join_eq_get (L : List (List α)) (i : Fin L.length) : - (L.join.take ((L.map length).take (i + 1)).sum).drop ((L.map length).take i).sum = get L i := by - rw [drop_take_succ_join_eq_getElem _ _ i.2] + (L.flatten.take ((L.map length).take (i + 1)).sum).drop + ((L.map length).take i).sum = get L i := by + rw [drop_take_succ_flatten_eq_getElem _ _ i.2] simp end List diff --git a/Mathlib/Algebra/FreeMonoid/Basic.lean b/Mathlib/Algebra/FreeMonoid/Basic.lean index c2a87d24b37d2d..c078811da88be7 100644 --- a/Mathlib/Algebra/FreeMonoid/Basic.lean +++ b/Mathlib/Algebra/FreeMonoid/Basic.lean @@ -80,13 +80,17 @@ theorem toList_mul (xs ys : FreeMonoid α) : toList (xs * ys) = toList xs ++ toL theorem ofList_append (xs ys : List α) : ofList (xs ++ ys) = ofList xs * ofList ys := rfl @[to_additive (attr := simp)] -theorem toList_prod (xs : List (FreeMonoid α)) : toList xs.prod = (xs.map toList).join := by - induction xs <;> simp [*, List.join] +theorem toList_prod (xs : List (FreeMonoid α)) : toList xs.prod = (xs.map toList).flatten := by + induction xs <;> simp [*, List.flatten] @[to_additive (attr := simp)] -theorem ofList_join (xs : List (List α)) : ofList xs.join = (xs.map ofList).prod := +theorem ofList_flatten (xs : List (List α)) : ofList xs.flatten = (xs.map ofList).prod := toList.injective <| by simp +@[deprecated (since := "2024-10-15")] alias ofList_join := ofList_flatten +@[deprecated (since := "2024-10-15")] +alias _root_.FreeAddMonoid.ofList_join := _root_.FreeAddMonoid.ofList_flatten + /-- Embeds an element of `α` into `FreeMonoid α` as a singleton list. -/ @[to_additive "Embeds an element of `α` into `FreeAddMonoid α` as a singleton list."] def of (x : α) : FreeMonoid α := ofList [x] diff --git a/Mathlib/Data/Fin/Basic.lean b/Mathlib/Data/Fin/Basic.lean index edc71f8ff4d06c..2c22f3ae72aeb3 100644 --- a/Mathlib/Data/Fin/Basic.lean +++ b/Mathlib/Data/Fin/Basic.lean @@ -410,10 +410,6 @@ theorem nontrivial_iff_two_le : Nontrivial (Fin n) ↔ 2 ≤ n := by section Monoid --- Porting note (#10618): removing `simp`, `simp` can prove it with AddCommMonoid instance -protected theorem add_zero [NeZero n] (k : Fin n) : k + 0 = k := by - simp only [add_def, val_zero', Nat.add_zero, mod_eq_of_lt (is_lt k)] - instance inhabitedFinOneAdd (n : ℕ) : Inhabited (Fin (1 + n)) := haveI : NeZero (1 + n) := by rw [Nat.add_comm]; infer_instance inferInstance diff --git a/Mathlib/Data/List/Basic.lean b/Mathlib/Data/List/Basic.lean index 0d8e6a7b48ee42..5e2ac7f43629c9 100644 --- a/Mathlib/Data/List/Basic.lean +++ b/Mathlib/Data/List/Basic.lean @@ -897,11 +897,11 @@ theorem bind_ret_eq_map (f : α → β) (l : List α) : l.bind (List.ret ∘ f) theorem bind_congr {l : List α} {f g : α → List β} (h : ∀ x ∈ l, f x = g x) : List.bind l f = List.bind l g := - (congr_arg List.join <| map_congr_left h : _) + (congr_arg List.flatten <| map_congr_left h : _) theorem infix_bind_of_mem {a : α} {as : List α} (h : a ∈ as) (f : α → List α) : f a <:+: as.bind f := - List.infix_of_mem_join (List.mem_map_of_mem f h) + List.infix_of_mem_flatten (List.mem_map_of_mem f h) @[simp] theorem map_eq_map {α β} (f : α → β) (l : List α) : f <$> l = map f l := @@ -1391,24 +1391,24 @@ theorem splitOnP_cons (x : α) (xs : List α) : if p x then [] :: xs.splitOnP p else (xs.splitOnP p).modifyHead (cons x) := by rw [splitOnP, splitOnP.go]; split <;> [rfl; simp [splitOnP.go_acc]] -/-- The original list `L` can be recovered by joining the lists produced by `splitOnP p L`, +/-- The original list `L` can be recovered by flattening the lists produced by `splitOnP p L`, interspersed with the elements `L.filter p`. -/ theorem splitOnP_spec (as : List α) : - join (zipWith (· ++ ·) (splitOnP p as) (((as.filter p).map fun x => [x]) ++ [[]])) = as := by + flatten (zipWith (· ++ ·) (splitOnP p as) (((as.filter p).map fun x => [x]) ++ [[]])) = as := by induction as with | nil => rfl | cons a as' ih => rw [splitOnP_cons, filter] by_cases h : p a - · rw [if_pos h, h, map, cons_append, zipWith, nil_append, join, cons_append, cons_inj_right] + · rw [if_pos h, h, map, cons_append, zipWith, nil_append, flatten, cons_append, cons_inj_right] exact ih - · rw [if_neg h, eq_false_of_ne_true h, join_zipWith (splitOnP_ne_nil _ _) + · rw [if_neg h, eq_false_of_ne_true h, flatten_zipWith (splitOnP_ne_nil _ _) (append_ne_nil_of_right_ne_nil _ (cons_ne_nil [] [])), cons_inj_right] exact ih where - join_zipWith {xs ys : List (List α)} {a : α} (hxs : xs ≠ []) (hys : ys ≠ []) : - join (zipWith (fun x x_1 ↦ x ++ x_1) (modifyHead (cons a) xs) ys) = - a :: join (zipWith (fun x x_1 ↦ x ++ x_1) xs ys) := by + flatten_zipWith {xs ys : List (List α)} {a : α} (hxs : xs ≠ []) (hys : ys ≠ []) : + flatten (zipWith (fun x x_1 ↦ x ++ x_1) (modifyHead (cons a) xs) ys) = + a :: flatten (zipWith (fun x x_1 ↦ x ++ x_1) xs ys) := by cases xs with | nil => contradiction | cons => cases ys with | nil => contradiction | cons => rfl @@ -1432,15 +1432,15 @@ theorem splitOnP_first (h : ∀ x ∈ xs, ¬p x) (sep : α) (hsep : p sep) (as : /-- `intercalate [x]` is the left inverse of `splitOn x` -/ theorem intercalate_splitOn (x : α) [DecidableEq α] : [x].intercalate (xs.splitOn x) = xs := by simp only [intercalate, splitOn] - induction' xs with hd tl ih; · simp [join] + induction' xs with hd tl ih; · simp [flatten] cases' h' : splitOnP (· == x) tl with hd' tl'; · exact (splitOnP_ne_nil _ tl h').elim rw [h'] at ih rw [splitOnP_cons] split_ifs with h · rw [beq_iff_eq] at h subst h - simp [ih, join, h'] - cases tl' <;> simpa [join, h'] using ih + simp [ih, flatten, h'] + cases tl' <;> simpa [flatten, h'] using ih /-- `splitOn x` is the left inverse of `intercalate [x]`, on the domain consisting of each nonempty list of lists `ls` whose elements do not contain `x` -/ @@ -1449,13 +1449,13 @@ theorem splitOn_intercalate [DecidableEq α] (x : α) (hx : ∀ l ∈ ls, x ∉ simp only [intercalate] induction' ls with hd tl ih; · contradiction cases tl - · suffices hd.splitOn x = [hd] by simpa [join] + · suffices hd.splitOn x = [hd] by simpa [flatten] refine splitOnP_eq_single _ _ ?_ intro y hy H rw [eq_of_beq H] at hy refine hx hd ?_ hy simp - · simp only [intersperse_cons_cons, singleton_append, join] + · simp only [intersperse_cons_cons, singleton_append, flatten] specialize ih _ _ · intro l hl apply hx l diff --git a/Mathlib/Data/List/Chain.lean b/Mathlib/Data/List/Chain.lean index 65eb76b1208730..68e6ea109eac65 100644 --- a/Mathlib/Data/List/Chain.lean +++ b/Mathlib/Data/List/Chain.lean @@ -307,18 +307,20 @@ theorem Chain'.append_overlap {l₁ l₂ l₃ : List α} (h₁ : Chain' R (l₁ h₁.append h₂.right_of_append <| by simpa only [getLast?_append_of_ne_nil _ hn] using (chain'_append.1 h₂).2.2 -lemma chain'_join : ∀ {L : List (List α)}, [] ∉ L → - (Chain' R L.join ↔ (∀ l ∈ L, Chain' R l) ∧ +lemma chain'_flatten : ∀ {L : List (List α)}, [] ∉ L → + (Chain' R L.flatten ↔ (∀ l ∈ L, Chain' R l) ∧ L.Chain' (fun l₁ l₂ => ∀ᵉ (x ∈ l₁.getLast?) (y ∈ l₂.head?), R x y)) | [], _ => by simp -| [l], _ => by simp [join] +| [l], _ => by simp [flatten] | (l₁ :: l₂ :: L), hL => by rw [mem_cons, not_or, ← Ne] at hL - rw [join, chain'_append, chain'_join hL.2, forall_mem_cons, chain'_cons] + rw [flatten, chain'_append, chain'_flatten hL.2, forall_mem_cons, chain'_cons] rw [mem_cons, not_or, ← Ne] at hL - simp only [forall_mem_cons, and_assoc, join, head?_append_of_ne_nil _ hL.2.1.symm] + simp only [forall_mem_cons, and_assoc, flatten, head?_append_of_ne_nil _ hL.2.1.symm] exact Iff.rfl.and (Iff.rfl.and <| Iff.rfl.and and_comm) +@[deprecated (since := "2024-10-15")] alias chain'_join := chain'_flatten + /-- If `a` and `b` are related by the reflexive transitive closure of `r`, then there is an `r`-chain starting from `a` and ending on `b`. The converse of `relationReflTransGen_of_exists_chain`. diff --git a/Mathlib/Data/List/Forall2.lean b/Mathlib/Data/List/Forall2.lean index 20808976c60ab9..f70e1557c45d3d 100644 --- a/Mathlib/Data/List/Forall2.lean +++ b/Mathlib/Data/List/Forall2.lean @@ -224,12 +224,14 @@ theorem forall₂_reverse_iff {l₁ l₂} : Forall₂ R (reverse l₁) (reverse exact rel_reverse h) fun h => rel_reverse h -theorem rel_join : (Forall₂ (Forall₂ R) ⇒ Forall₂ R) join join +theorem rel_flatten : (Forall₂ (Forall₂ R) ⇒ Forall₂ R) flatten flatten | [], [], Forall₂.nil => Forall₂.nil - | _, _, Forall₂.cons h₁ h₂ => rel_append h₁ (rel_join h₂) + | _, _, Forall₂.cons h₁ h₂ => rel_append h₁ (rel_flatten h₂) + +@[deprecated (since := "2025-10-15")] alias rel_join := rel_flatten theorem rel_bind : (Forall₂ R ⇒ (R ⇒ Forall₂ P) ⇒ Forall₂ P) List.bind List.bind := - fun _ _ h₁ _ _ h₂ => rel_join (rel_map (@h₂) h₁) + fun _ _ h₁ _ _ h₂ => rel_flatten (rel_map (@h₂) h₁) theorem rel_foldl : ((P ⇒ R ⇒ P) ⇒ P ⇒ Forall₂ R ⇒ P) foldl foldl | _, _, _, _, _, h, _, _, Forall₂.nil => h diff --git a/Mathlib/Data/List/GroupBy.lean b/Mathlib/Data/List/GroupBy.lean index 6449cb7da1b97a..31f7d2baa25957 100644 --- a/Mathlib/Data/List/GroupBy.lean +++ b/Mathlib/Data/List/GroupBy.lean @@ -37,8 +37,8 @@ private theorem groupByLoop_eq_append {r : α → α → Bool} {l : List α} {a conv_rhs => rw [IH] simp -private theorem join_groupByLoop {r : α → α → Bool} {l : List α} {a : α} {g : List α} : - (groupBy.loop r l a g []).join = g.reverse ++ a :: l := by +private theorem flatten_groupByLoop {r : α → α → Bool} {l : List α} {a : α} {g : List α} : + (groupBy.loop r l a g []).flatten = g.reverse ++ a :: l := by induction l generalizing a g with | nil => simp [groupBy.loop] | cons b l IH => @@ -46,10 +46,12 @@ private theorem join_groupByLoop {r : α → α → Bool} {l : List α} {a : α} split <;> simp [IH] @[simp] -theorem join_groupBy (r : α → α → Bool) (l : List α) : (l.groupBy r).join = l := +theorem flatten_groupBy (r : α → α → Bool) (l : List α) : (l.groupBy r).flatten = l := match l with | nil => rfl - | cons _ _ => join_groupByLoop + | cons _ _ => flatten_groupByLoop + +@[deprecated (since := "2024-10-15")] alias join_groupBy := flatten_groupBy private theorem nil_not_mem_groupByLoop {r : α → α → Bool} {l : List α} {a : α} {g : List α} : [] ∉ groupBy.loop r l a g [] := by diff --git a/Mathlib/Data/List/Indexes.lean b/Mathlib/Data/List/Indexes.lean index 7e53018e89d4b4..3d8da0f6ca7895 100644 --- a/Mathlib/Data/List/Indexes.lean +++ b/Mathlib/Data/List/Indexes.lean @@ -24,11 +24,6 @@ variable {α : Type u} {β : Type v} section MapIdx -@[simp] -theorem mapIdx_nil {α β} (f : ℕ → α → β) : mapIdx f [] = [] := - rfl - - theorem list_reverse_induction (p : List α → Prop) (base : p []) (ind : ∀ (l : List α) (e : α), p l → p (l ++ [e])) : (∀ (l : List α), p l) := by let q := fun l ↦ p (reverse l) @@ -41,42 +36,15 @@ theorem list_reverse_induction (p : List α → Prop) (base : p []) · apply pq; simp only [reverse_nil, base] · apply pq; simp only [reverse_cons]; apply ind; apply qp; rw [reverse_reverse]; exact ih -theorem mapIdxGo_append : ∀ (f : ℕ → α → β) (l₁ l₂ : List α) (arr : Array β), - mapIdx.go f (l₁ ++ l₂) arr = mapIdx.go f l₂ (List.toArray (mapIdx.go f l₁ arr)) := by - intros f l₁ l₂ arr - generalize e : (l₁ ++ l₂).length = len - revert l₁ l₂ arr - induction' len with len ih <;> intros l₁ l₂ arr h - · have l₁_nil : l₁ = [] := by - cases l₁ - · rfl - · contradiction - have l₂_nil : l₂ = [] := by - cases l₂ - · rfl - · rw [List.length_append] at h; contradiction - rw [l₁_nil, l₂_nil]; simp only [mapIdx.go, List.toArray_toList] - · cases' l₁ with head tail <;> simp only [mapIdx.go] - · simp only [nil_append, List.toArray_toList] - · simp only [List.append_eq] - rw [ih] - · simp only [cons_append, length_cons, length_append, Nat.succ.injEq] at h - simp only [length_append, h] - -theorem mapIdxGo_length : ∀ (f : ℕ → α → β) (l : List α) (arr : Array β), - length (mapIdx.go f l arr) = length l + arr.size := by - intro f l - induction' l with head tail ih - · intro; simp only [mapIdx.go, length_nil, Nat.zero_add] - · intro; simp only [mapIdx.go]; rw [ih]; simp only [Array.size_push, length_cons] - simp only [Nat.add_succ, Fin.add_zero, Nat.add_comm] +@[deprecated (since := "2024-10-15")] alias mapIdxGo_append := mapIdx_go_append +@[deprecated (since := "2024-10-15")] alias mapIdxGo_length := mapIdx_go_length theorem mapIdx_append_one : ∀ (f : ℕ → α → β) (l : List α) (e : α), mapIdx f (l ++ [e]) = mapIdx f l ++ [f l.length e] := by intros f l e unfold mapIdx - rw [mapIdxGo_append f l [e]] - simp only [mapIdx.go, Array.size_toArray, mapIdxGo_length, length_nil, Nat.add_zero, + rw [mapIdx_go_append] + simp only [mapIdx.go, Array.size_toArray, mapIdx_go_length, length_nil, Nat.add_zero, Array.push_toList, Array.toList_toArray] @[local simp] @@ -103,66 +71,10 @@ theorem map_enumFrom_eq_zipWith : ∀ (l : List α) (n : ℕ) (f : ℕ → α simp only [comp, Nat.add_assoc, Nat.add_comm, Nat.add_succ] simp only [length_cons, Nat.succ.injEq] at e; exact e -theorem length_mapIdx_go (f : ℕ → α → β) : ∀ (l : List α) (arr : Array β), - (mapIdx.go f l arr).length = l.length + arr.size - | [], _ => by simp [mapIdx.go] - | a :: l, _ => by - simp only [mapIdx.go, length_cons] - rw [length_mapIdx_go] - simp - omega - -@[simp] theorem length_mapIdx (l : List α) (f : ℕ → α → β) : (l.mapIdx f).length = l.length := by - simp [mapIdx, length_mapIdx_go] - -theorem getElem?_mapIdx_go (f : ℕ → α → β) : ∀ (l : List α) (arr : Array β) (i : ℕ), - (mapIdx.go f l arr)[i]? = - if h : i < arr.size then some arr[i] else Option.map (f i) l[i - arr.size]? - | [], arr, i => by - simp only [mapIdx.go, Array.toListImpl_eq, getElem?_eq, Array.length_toList, - Array.getElem_eq_getElem_toList, length_nil, Nat.not_lt_zero, ↓reduceDIte, Option.map_none'] - | a :: l, arr, i => by - rw [mapIdx.go, getElem?_mapIdx_go] - simp only [Array.size_push] - split <;> split - · simp only [Option.some.injEq] - rw [Array.getElem_eq_getElem_toList] - simp only [Array.push_toList] - rw [getElem_append_left, Array.getElem_eq_getElem_toList] - · have : i = arr.size := by omega - simp_all - · omega - · have : i - arr.size = i - (arr.size + 1) + 1 := by omega - simp_all - -@[simp] theorem getElem?_mapIdx (l : List α) (f : ℕ → α → β) (i : ℕ) : - (l.mapIdx f)[i]? = Option.map (f i) l[i]? := by - simp [mapIdx, getElem?_mapIdx_go] - -theorem mapIdx_eq_enum_map (l : List α) (f : ℕ → α → β) : - l.mapIdx f = l.enum.map (Function.uncurry f) := by - ext1 i - simp only [getElem?_mapIdx, Option.map, getElem?_map, getElem?_enum] - split <;> simp - -@[simp] -theorem mapIdx_cons (l : List α) (f : ℕ → α → β) (a : α) : - mapIdx f (a :: l) = f 0 a :: mapIdx (fun i ↦ f (i + 1)) l := by - simp [mapIdx_eq_enum_map, enum_eq_zip_range, map_uncurry_zip_eq_zipWith, - range_succ_eq_map, zipWith_map_left] - -theorem mapIdx_append (K L : List α) (f : ℕ → α → β) : - (K ++ L).mapIdx f = K.mapIdx f ++ L.mapIdx fun i a ↦ f (i + K.length) a := by - induction' K with a J IH generalizing f - · rfl - · simp [IH fun i ↦ f (i + 1), Nat.add_assoc] - -@[simp] -theorem mapIdx_eq_nil {f : ℕ → α → β} {l : List α} : List.mapIdx f l = [] ↔ l = [] := by - rw [List.mapIdx_eq_enum_map, List.map_eq_nil_iff, List.enum_eq_nil] +@[deprecated (since := "2024-10-15")] alias mapIdx_eq_nil := mapIdx_eq_nil_iff theorem get_mapIdx (l : List α) (f : ℕ → α → β) (i : ℕ) (h : i < l.length) - (h' : i < (l.mapIdx f).length := h.trans_le (l.length_mapIdx f).ge) : + (h' : i < (l.mapIdx f).length := h.trans_le length_mapIdx.ge) : (l.mapIdx f).get ⟨i, h'⟩ = f i (l.get ⟨i, h⟩) := by simp [mapIdx_eq_enum_map, enum_eq_zip_range] diff --git a/Mathlib/Data/List/Join.lean b/Mathlib/Data/List/Join.lean index 69f2b6f90ab34b..0db25d1afe7e5b 100644 --- a/Mathlib/Data/List/Join.lean +++ b/Mathlib/Data/List/Join.lean @@ -21,27 +21,34 @@ namespace List @[deprecated (since := "2024-02-25")] alias join_filter_isEmpty_eq_false := join_filter_not_isEmpty -/-- See `List.length_join` for the corresponding statement using `List.sum`. -/ -lemma length_join' (L : List (List α)) : length (join L) = Nat.sum (map length L) := by - induction L <;> [rfl; simp only [*, join, map, Nat.sum_cons, length_append]] +/-- See `List.length_flatten` for the corresponding statement using `List.sum`. -/ +lemma length_flatten' (L : List (List α)) : length (flatten L) = Nat.sum (map length L) := by + induction L <;> [rfl; simp only [*, flatten, map, Nat.sum_cons, length_append]] -/-- See `List.countP_join` for the corresponding statement using `List.sum`. -/ -lemma countP_join' (p : α → Bool) : - ∀ L : List (List α), countP p L.join = Nat.sum (L.map (countP p)) +@[deprecated (since := "2024-10-25")] alias length_join' := length_flatten' + +/-- See `List.countP_flatten` for the corresponding statement using `List.sum`. -/ +lemma countP_flatten' (p : α → Bool) : + ∀ L : List (List α), countP p L.flatten = Nat.sum (L.map (countP p)) | [] => rfl - | a :: l => by rw [join, countP_append, map_cons, Nat.sum_cons, countP_join' _ l] + | a :: l => by rw [flatten, countP_append, map_cons, Nat.sum_cons, countP_flatten' _ l] + +@[deprecated (since := "2024-10-25")] alias countP_join' := countP_flatten' -/-- See `List.count_join` for the corresponding statement using `List.sum`. -/ -lemma count_join' [BEq α] (L : List (List α)) (a : α) : - L.join.count a = Nat.sum (L.map (count a)) := countP_join' _ _ +/-- See `List.count_flatten` for the corresponding statement using `List.sum`. -/ +lemma count_flatten' [BEq α] (L : List (List α)) (a : α) : + L.flatten.count a = Nat.sum (L.map (count a)) := countP_flatten' _ _ + +@[deprecated (since := "2024-10-25")] alias count_join' := count_flatten' /-- See `List.length_bind` for the corresponding statement using `List.sum`. -/ lemma length_bind' (l : List α) (f : α → List β) : - length (l.bind f) = Nat.sum (map (length ∘ f) l) := by rw [List.bind, length_join', map_map] + length (l.bind f) = Nat.sum (map (length ∘ f) l) := by rw [List.bind, length_flatten', map_map] /-- See `List.countP_bind` for the corresponding statement using `List.sum`. -/ lemma countP_bind' (p : β → Bool) (l : List α) (f : α → List β) : - countP p (l.bind f) = Nat.sum (map (countP p ∘ f) l) := by rw [List.bind, countP_join', map_map] + countP p (l.bind f) = Nat.sum (map (countP p ∘ f) l) := by + rw [List.bind, countP_flatten', map_map] /-- See `List.count_bind` for the corresponding statement using `List.sum`. -/ lemma count_bind' [BEq β] (l : List α) (f : α → List β) (x : β) : @@ -50,23 +57,27 @@ lemma count_bind' [BEq β] (l : List α) (f : α → List β) (x : β) : /-- In a join, taking the first elements up to an index which is the sum of the lengths of the first `i` sublists, is the same as taking the join of the first `i` sublists. -See `List.take_sum_join` for the corresponding statement using `List.sum`. -/ -theorem take_sum_join' (L : List (List α)) (i : ℕ) : - L.join.take (Nat.sum ((L.map length).take i)) = (L.take i).join := by +See `List.take_sum_flatten` for the corresponding statement using `List.sum`. -/ +theorem take_sum_flatten' (L : List (List α)) (i : ℕ) : + L.flatten.take (Nat.sum ((L.map length).take i)) = (L.take i).flatten := by induction L generalizing i · simp · cases i <;> simp [take_append, *] +@[deprecated (since := "2024-10-25")] alias take_sum_join' := take_sum_flatten' + /-- In a join, dropping all the elements up to an index which is the sum of the lengths of the first `i` sublists, is the same as taking the join after dropping the first `i` sublists. -See `List.drop_sum_join` for the corresponding statement using `List.sum`. -/ -theorem drop_sum_join' (L : List (List α)) (i : ℕ) : - L.join.drop (Nat.sum ((L.map length).take i)) = (L.drop i).join := by +See `List.drop_sum_flatten` for the corresponding statement using `List.sum`. -/ +theorem drop_sum_flatten' (L : List (List α)) (i : ℕ) : + L.flatten.drop (Nat.sum ((L.map length).take i)) = (L.drop i).flatten := by induction L generalizing i · simp · cases i <;> simp [drop_append, *] +@[deprecated (since := "2024-10-25")] alias drop_sum_join' := drop_sum_flatten' + /-- Taking only the first `i+1` elements in a list, and then dropping the first `i` ones, one is left with a list of length `1` made of the `i`-th element of the original list. -/ theorem drop_take_succ_eq_cons_getElem (L : List α) (i : Nat) (h : i < L.length) : @@ -82,38 +93,46 @@ theorem drop_take_succ_eq_cons_get (L : List α) (i : Fin L.length) : (L.take (i + 1)).drop i = [get L i] := by simp [drop_take_succ_eq_cons_getElem] -/-- In a join of sublists, taking the slice between the indices `A` and `B - 1` gives back the +/-- In a flatten of sublists, taking the slice between the indices `A` and `B - 1` gives back the original sublist of index `i` if `A` is the sum of the lengths of sublists of index `< i`, and `B` is the sum of the lengths of sublists of index `≤ i`. -See `List.drop_take_succ_join_eq_getElem` for the corresponding statement using `List.sum`. -/ -theorem drop_take_succ_join_eq_getElem' (L : List (List α)) (i : Nat) (h : i < L.length) : - (L.join.take (Nat.sum ((L.map length).take (i + 1)))).drop (Nat.sum ((L.map length).take i)) = - L[i] := by +See `List.drop_take_succ_flatten_eq_getElem` for the corresponding statement using `List.sum`. -/ +theorem drop_take_succ_flatten_eq_getElem' (L : List (List α)) (i : Nat) (h : i < L.length) : + (L.flatten.take (Nat.sum ((L.map length).take (i + 1)))).drop + (Nat.sum ((L.map length).take i)) = L[i] := by have : (L.map length).take i = ((L.take (i + 1)).map length).take i := by simp [map_take, take_take, Nat.min_eq_left] - simp only [this, length_map, take_sum_join', drop_sum_join', drop_take_succ_eq_cons_getElem, h, - join, append_nil] + simp only [this, length_map, take_sum_flatten', drop_sum_flatten', + drop_take_succ_eq_cons_getElem, h, flatten, append_nil] + +@[deprecated (since := "2024-10-15")] +alias drop_take_succ_join_eq_getElem' := drop_take_succ_flatten_eq_getElem' -@[deprecated drop_take_succ_join_eq_getElem' (since := "2024-06-11")] +@[deprecated drop_take_succ_flatten_eq_getElem' (since := "2024-06-11")] theorem drop_take_succ_join_eq_get' (L : List (List α)) (i : Fin L.length) : - (L.join.take (Nat.sum ((L.map length).take (i + 1)))).drop (Nat.sum ((L.map length).take i)) = - get L i := by - simp [drop_take_succ_join_eq_getElem'] + (L.flatten.take (Nat.sum ((L.map length).take (i + 1)))).drop + (Nat.sum ((L.map length).take i)) = get L i := by + simp [drop_take_succ_flatten_eq_getElem'] -theorem join_drop_length_sub_one {L : List (List α)} (h : L ≠ []) : - (L.drop (L.length - 1)).join = L.getLast h := by +theorem flatten_drop_length_sub_one {L : List (List α)} (h : L ≠ []) : + (L.drop (L.length - 1)).flatten = L.getLast h := by induction L using List.reverseRecOn · cases h rfl · simp +@[deprecated (since := "2024-10-15")] alias join_drop_length_sub_one := flatten_drop_length_sub_one + /-- We can rebracket `x ++ (l₁ ++ x) ++ (l₂ ++ x) ++ ... ++ (lₙ ++ x)` to `(x ++ l₁) ++ (x ++ l₂) ++ ... ++ (x ++ lₙ) ++ x` where `L = [l₁, l₂, ..., lₙ]`. -/ -theorem append_join_map_append (L : List (List α)) (x : List α) : - x ++ (L.map (· ++ x)).join = (L.map (x ++ ·)).join ++ x := by +theorem append_flatten_map_append (L : List (List α)) (x : List α) : + x ++ (L.map (· ++ x)).flatten = (L.map (x ++ ·)).flatten ++ x := by induction L with - | nil => rw [map_nil, join, append_nil, map_nil, join, nil_append] - | cons _ _ ih => rw [map_cons, join, map_cons, join, append_assoc, ih, append_assoc, append_assoc] + | nil => rw [map_nil, flatten, append_nil, map_nil, flatten, nil_append] + | cons _ _ ih => + rw [map_cons, flatten, map_cons, flatten, append_assoc, ih, append_assoc, append_assoc] + +@[deprecated (since := "2024-10-15")] alias append_join_map_append := append_flatten_map_append @[deprecated (since := "2024-08-15")] alias sublist_join := sublist_join_of_mem diff --git a/Mathlib/Data/List/Nodup.lean b/Mathlib/Data/List/Nodup.lean index f04247b8a01935..438d1ecf9ea7d3 100644 --- a/Mathlib/Data/List/Nodup.lean +++ b/Mathlib/Data/List/Nodup.lean @@ -254,15 +254,16 @@ theorem Nodup.erase_get [DecidableEq α] {l : List α} (hl : l.Nodup) (i : Fin l theorem Nodup.diff [DecidableEq α] : l₁.Nodup → (l₁.diff l₂).Nodup := Nodup.sublist <| diff_sublist _ _ +theorem nodup_flatten {L : List (List α)} : + Nodup (flatten L) ↔ (∀ l ∈ L, Nodup l) ∧ Pairwise Disjoint L := by + simp only [Nodup, pairwise_flatten, disjoint_left.symm, forall_mem_ne] -theorem nodup_join {L : List (List α)} : - Nodup (join L) ↔ (∀ l ∈ L, Nodup l) ∧ Pairwise Disjoint L := by - simp only [Nodup, pairwise_join, disjoint_left.symm, forall_mem_ne] +@[deprecated (since := "2025-10-15")] alias nodup_join := nodup_flatten theorem nodup_bind {l₁ : List α} {f : α → List β} : Nodup (l₁.bind f) ↔ (∀ x ∈ l₁, Nodup (f x)) ∧ Pairwise (fun a b : α => Disjoint (f a) (f b)) l₁ := by - simp only [List.bind, nodup_join, pairwise_map, and_comm, and_left_comm, mem_map, + simp only [List.bind, nodup_flatten, pairwise_map, and_comm, and_left_comm, mem_map, exists_imp, and_imp] rw [show (∀ (l : List β) (x : α), f x = l → x ∈ l₁ → Nodup l) ↔ ∀ x : α, x ∈ l₁ → Nodup (f x) from forall_swap.trans <| forall_congr' fun _ => forall_eq'] diff --git a/Mathlib/Data/List/OfFn.lean b/Mathlib/Data/List/OfFn.lean index 9aa74790b948bd..1ecaf83a93964e 100644 --- a/Mathlib/Data/List/OfFn.lean +++ b/Mathlib/Data/List/OfFn.lean @@ -110,20 +110,20 @@ theorem ofFn_fin_append {m n} (a : Fin m → α) (b : Fin n → α) : /-- This breaks a list of `m*n` items into `m` groups each containing `n` elements. -/ theorem ofFn_mul {m n} (f : Fin (m * n) → α) : - List.ofFn f = List.join (List.ofFn fun i : Fin m => List.ofFn fun j : Fin n => f ⟨i * n + j, + List.ofFn f = List.flatten (List.ofFn fun i : Fin m => List.ofFn fun j : Fin n => f ⟨i * n + j, calc ↑i * n + j < (i + 1) * n := (Nat.add_lt_add_left j.prop _).trans_eq (by rw [Nat.add_mul, Nat.one_mul]) _ ≤ _ := Nat.mul_le_mul_right _ i.prop⟩) := by induction' m with m IH - · simp [ofFn_zero, Nat.zero_mul, ofFn_zero, join] + · simp [ofFn_zero, Nat.zero_mul, ofFn_zero, flatten] · simp_rw [ofFn_succ', succ_mul] - simp [join_concat, ofFn_add, IH] + simp [flatten_concat, ofFn_add, IH] rfl /-- This breaks a list of `m*n` items into `n` groups each containing `m` elements. -/ theorem ofFn_mul' {m n} (f : Fin (m * n) → α) : - List.ofFn f = List.join (List.ofFn fun i : Fin n => List.ofFn fun j : Fin m => f ⟨m * i + j, + List.ofFn f = List.flatten (List.ofFn fun i : Fin n => List.ofFn fun j : Fin m => f ⟨m * i + j, calc m * i + j < m * (i + 1) := (Nat.add_lt_add_left j.prop _).trans_eq (by rw [Nat.mul_add, Nat.mul_one]) @@ -171,7 +171,7 @@ theorem ofFn_const : ∀ (n : ℕ) (c : α), (ofFn fun _ : Fin n => c) = replica @[simp] theorem ofFn_fin_repeat {m} (a : Fin m → α) (n : ℕ) : - List.ofFn (Fin.repeat n a) = (List.replicate n (List.ofFn a)).join := by + List.ofFn (Fin.repeat n a) = (List.replicate n (List.ofFn a)).flatten := by simp_rw [ofFn_mul, ← ofFn_const, Fin.repeat, Fin.modNat, Nat.add_comm, Nat.add_mul_mod_self_right, Nat.mod_eq_of_lt (Fin.is_lt _)] diff --git a/Mathlib/Data/List/Perm.lean b/Mathlib/Data/List/Perm.lean index be40ad9d20e430..2cf64feeb63cdc 100644 --- a/Mathlib/Data/List/Perm.lean +++ b/Mathlib/Data/List/Perm.lean @@ -275,11 +275,9 @@ theorem Perm.inter_append {l t₁ t₂ : List α} (h : Disjoint t₁ t₂) : end - - theorem Perm.bind_left (l : List α) {f g : α → List β} (h : ∀ a ∈ l, f a ~ g a) : l.bind f ~ l.bind g := - Perm.join_congr <| by + Perm.flatten_congr <| by rwa [List.forall₂_map_right_iff, List.forall₂_map_left_iff, List.forall₂_same] theorem bind_append_perm (l : List α) (f g : α → List β) : diff --git a/Mathlib/Data/List/Range.lean b/Mathlib/Data/List/Range.lean index 63ca906ece4716..bd491ba6ccd4ab 100644 --- a/Mathlib/Data/List/Range.lean +++ b/Mathlib/Data/List/Range.lean @@ -141,20 +141,22 @@ theorem ranges_length (l : List ℕ) : intro s _ simp only [Function.comp_apply, length_map] -/-- See `List.ranges_join` for the version about `List.sum`. -/ -lemma ranges_join' : ∀ l : List ℕ, l.ranges.join = range (Nat.sum l) +/-- See `List.ranges_flatten` for the version about `List.sum`. -/ +lemma ranges_flatten' : ∀ l : List ℕ, l.ranges.flatten = range (Nat.sum l) | [] => rfl - | a :: l => by simp only [sum_cons, join, ← map_join, ranges_join', range_add] + | a :: l => by simp only [sum_cons, flatten, ← map_flatten, ranges_flatten', range_add] + +@[deprecated (since := "2024-10-15")] alias ranges_join' := ranges_flatten' /-- Any entry of any member of `l.ranges` is strictly smaller than `Nat.sum l`. See `List.mem_mem_ranges_iff_lt_sum` for the version about `List.sum`. -/ lemma mem_mem_ranges_iff_lt_natSum (l : List ℕ) {n : ℕ} : (∃ s ∈ l.ranges, n ∈ s) ↔ n < Nat.sum l := by - rw [← mem_range, ← ranges_join', mem_join] + rw [← mem_range, ← ranges_flatten', mem_flatten] /-- The members of `l.ranges` have no duplicate -/ theorem ranges_nodup {l s : List ℕ} (hs : s ∈ ranges l) : s.Nodup := - (List.pairwise_join.mp <| by rw [ranges_join']; exact nodup_range _).1 s hs + (List.pairwise_flatten.mp <| by rw [ranges_flatten']; exact nodup_range _).1 s hs end Ranges diff --git a/Mathlib/Data/List/Sigma.lean b/Mathlib/Data/List/Sigma.lean index 7064c0948f068d..3d3691f534fbfe 100644 --- a/Mathlib/Data/List/Sigma.lean +++ b/Mathlib/Data/List/Sigma.lean @@ -118,13 +118,15 @@ protected theorem NodupKeys.nodup {l : List (Sigma β)} : NodupKeys l → Nodup theorem perm_nodupKeys {l₁ l₂ : List (Sigma β)} (h : l₁ ~ l₂) : NodupKeys l₁ ↔ NodupKeys l₂ := (h.map _).nodup_iff -theorem nodupKeys_join {L : List (List (Sigma β))} : - NodupKeys (join L) ↔ (∀ l ∈ L, NodupKeys l) ∧ Pairwise Disjoint (L.map keys) := by - rw [nodupKeys_iff_pairwise, pairwise_join, pairwise_map] +theorem nodupKeys_flatten {L : List (List (Sigma β))} : + NodupKeys (flatten L) ↔ (∀ l ∈ L, NodupKeys l) ∧ Pairwise Disjoint (L.map keys) := by + rw [nodupKeys_iff_pairwise, pairwise_flatten, pairwise_map] refine and_congr (forall₂_congr fun l _ => by simp [nodupKeys_iff_pairwise]) ?_ apply iff_of_eq; congr with (l₁ l₂) simp [keys, disjoint_iff_ne, Sigma.forall] +@[deprecated (since := "2024-10-15")] alias nodupKeys_join := nodupKeys_flatten + theorem nodup_enum_map_fst (l : List α) : (l.enum.map Prod.fst).Nodup := by simp [List.nodup_range] theorem mem_ext {l₀ l₁ : List (Sigma β)} (nd₀ : l₀.Nodup) (nd₁ : l₁.Nodup) diff --git a/Mathlib/Data/List/Sublists.lean b/Mathlib/Data/List/Sublists.lean index 5521bdab8a956a..a01b524b626c68 100644 --- a/Mathlib/Data/List/Sublists.lean +++ b/Mathlib/Data/List/Sublists.lean @@ -136,7 +136,7 @@ theorem sublists_append (l₁ l₂ : List α) : | nil => simp | cons a l₁ ih => rw [foldr_cons, ih] - simp [List.bind, join_join, Function.comp_def] + simp [List.bind, flatten_flatten, Function.comp_def] theorem sublists_cons (a : α) (l : List α) : sublists (a :: l) = sublists l >>= (fun x => [x, a :: x]) := diff --git a/Mathlib/Data/List/Zip.lean b/Mathlib/Data/List/Zip.lean index a05e606d213ad4..b7f0009d75359a 100644 --- a/Mathlib/Data/List/Zip.lean +++ b/Mathlib/Data/List/Zip.lean @@ -166,13 +166,4 @@ theorem mem_zip_inits_tails {l : List α} {init tail : List α} : use tl', tail simp_all -theorem map_uncurry_zip_eq_zipWith (f : α → β → γ) (l : List α) (l' : List β) : - map (Function.uncurry f) (l.zip l') = zipWith f l l' := by - rw [zip] - induction' l with hd tl hl generalizing l' - · simp - · cases' l' with hd' tl' - · simp - · simp [hl] - end List diff --git a/Mathlib/Data/Multiset/Bind.lean b/Mathlib/Data/Multiset/Bind.lean index 89ddc4a81c8f68..2f8c64e94ac94c 100644 --- a/Mathlib/Data/Multiset/Bind.lean +++ b/Mathlib/Data/Multiset/Bind.lean @@ -30,15 +30,14 @@ namespace Multiset /-! ### Join -/ - /-- `join S`, where `S` is a multiset of multisets, is the lift of the list join operation, that is, the union of all the sets. join {{1, 2}, {1, 2}, {0, 1}} = {0, 1, 1, 1, 2, 2} -/ def join : Multiset (Multiset α) → Multiset α := sum -theorem coe_join : - ∀ L : List (List α), join (L.map ((↑) : List α → Multiset α) : Multiset (Multiset α)) = L.join +theorem coe_join : ∀ L : List (List α), join (L.map ((↑) : List α → Multiset α) : + Multiset (Multiset α)) = L.flatten | [] => rfl | l :: L => by exact congr_arg (fun s : Multiset α => ↑l + s) (coe_join L) diff --git a/Mathlib/Tactic/CategoryTheory/Coherence/Basic.lean b/Mathlib/Tactic/CategoryTheory/Coherence/Basic.lean index 53facfd616c829..4bbaa1c4136cc4 100644 --- a/Mathlib/Tactic/CategoryTheory/Coherence/Basic.lean +++ b/Mathlib/Tactic/CategoryTheory/Coherence/Basic.lean @@ -102,6 +102,6 @@ def main (ρ : Type) [Context ρ] [MonadMor₁ (CoherenceM ρ)] [MonadMor₂Iso try pureCoherence ρ nm mvarId catch _ => return [mvarId] - return mvarIds''.join + return mvarIds''.flatten end Mathlib.Tactic.BicategoryLike diff --git a/Mathlib/Tactic/CongrExclamation.lean b/Mathlib/Tactic/CongrExclamation.lean index 93901abe7dd663..c8d472db8a0a4a 100644 --- a/Mathlib/Tactic/CongrExclamation.lean +++ b/Mathlib/Tactic/CongrExclamation.lean @@ -549,7 +549,7 @@ where return ← loop mvar.mvarId! if let some patt ← CongrMetaM.nextPattern then let gs ← Term.TermElabM.run' <| Lean.Elab.Tactic.RCases.rintro #[patt] none mvarId - List.join <$> gs.mapM loop + List.flatten <$> gs.mapM loop else let (_, mvarId) ← mvarId.intro1 loop mvarId diff --git a/Mathlib/Tactic/Linarith/Preprocessing.lean b/Mathlib/Tactic/Linarith/Preprocessing.lean index 2a496d4cd5670f..19d09f6f023a54 100644 --- a/Mathlib/Tactic/Linarith/Preprocessing.lean +++ b/Mathlib/Tactic/Linarith/Preprocessing.lean @@ -426,6 +426,6 @@ so the size of the list may change. -/ def preprocess (pps : List GlobalBranchingPreprocessor) (g : MVarId) (l : List Expr) : MetaM (List Branch) := g.withContext <| - pps.foldlM (fun ls pp => return (← ls.mapM fun (g, l) => do pp.process g l).join) [(g, l)] + pps.foldlM (fun ls pp => return (← ls.mapM fun (g, l) => do pp.process g l).flatten) [(g, l)] end Linarith diff --git a/Mathlib/Tactic/Widget/StringDiagram.lean b/Mathlib/Tactic/Widget/StringDiagram.lean index 9ba22761bcd5ee..0fc3e7560bdbcb 100644 --- a/Mathlib/Tactic/Widget/StringDiagram.lean +++ b/Mathlib/Tactic/Widget/StringDiagram.lean @@ -157,8 +157,8 @@ def WhiskerRight.nodes (v h₁ h₂ : ℕ) : WhiskerRight → List Node | WhiskerRight.of η => [.atom ⟨v, h₁, h₂, η⟩] | WhiskerRight.whisker _ η f => let ηs := η.nodes v h₁ h₂ - let k₁ := (ηs.map (fun n ↦ n.srcList)).join.length - let k₂ := (ηs.map (fun n ↦ n.tarList)).join.length + let k₁ := (ηs.map (fun n ↦ n.srcList)).flatten.length + let k₂ := (ηs.map (fun n ↦ n.tarList)).flatten.length let s : Node := .id ⟨v, h₁ + k₁, h₂ + k₂, f⟩ ηs ++ [s] @@ -168,8 +168,8 @@ def HorizontalComp.nodes (v h₁ h₂ : ℕ) : HorizontalComp → List Node | HorizontalComp.of η => η.nodes v h₁ h₂ | HorizontalComp.cons _ η ηs => let s₁ := η.nodes v h₁ h₂ - let k₁ := (s₁.map (fun n ↦ n.srcList)).join.length - let k₂ := (s₁.map (fun n ↦ n.tarList)).join.length + let k₁ := (s₁.map (fun n ↦ n.srcList)).flatten.length + let k₂ := (s₁.map (fun n ↦ n.tarList)).flatten.length let s₂ := ηs.nodes v (h₁ + k₁) (h₂ + k₂) s₁ ++ s₂ @@ -211,8 +211,8 @@ def pairs {α : Type} : List α → List (α × α) := def NormalExpr.strands (e : NormalExpr) : CoherenceM ρ (List (List Strand)) := do let l ← e.nodes (pairs l).mapM fun (x, y) ↦ do - let xs := (x.map (fun n ↦ n.tarList)).join - let ys := (y.map (fun n ↦ n.srcList)).join + let xs := (x.map (fun n ↦ n.tarList)).flatten + let ys := (y.map (fun n ↦ n.srcList)).flatten -- sanity check if xs.length ≠ ys.length then throwError "The number of the start and end points of a string does not match." @@ -266,7 +266,7 @@ display as labels in the diagram. -/ def mkStringDiagram (nodes : List (List Node)) (strands : List (List Strand)) : DiagramBuilderM PUnit := do /- Add 2-morphisms. -/ - for x in nodes.join do + for x in nodes.flatten do match x with | .atom _ => do addPenroseVar "Atom" x.toPenroseVar | .id _ => do addPenroseVar "Id" x.toPenroseVar diff --git a/Mathlib/Testing/SlimCheck/Sampleable.lean b/Mathlib/Testing/SlimCheck/Sampleable.lean index f5cedcf3cb6807..569bec9cac7fa5 100644 --- a/Mathlib/Testing/SlimCheck/Sampleable.lean +++ b/Mathlib/Testing/SlimCheck/Sampleable.lean @@ -158,7 +158,7 @@ instance Fin.shrinkable {n : Nat} : Shrinkable (Fin n.succ) where /-- `Int.shrinkable` operates like `Nat.shrinkable` but also includes the negative variants. -/ instance Int.shrinkable : Shrinkable Int where - shrink n := Nat.shrink n.natAbs |>.map (fun x ↦ ([x, -x] : List ℤ)) |>.join + shrink n := Nat.shrink n.natAbs |>.map (fun x ↦ ([x, -x] : List ℤ)) |>.flatten instance Rat.shrinkable : Shrinkable Rat where shrink r := @@ -187,7 +187,7 @@ open Shrinkable instance List.shrinkable [Shrinkable α] : Shrinkable (List α) where shrink := fun L => (L.mapIdx fun i _ => L.eraseIdx i) ++ - (L.mapIdx fun i a => (shrink a).map fun a' => L.modifyNth (fun _ => a') i).join + (L.mapIdx fun i a => (shrink a).map fun a' => L.modifyNth (fun _ => a') i).flatten end Shrinkers From 2b2adcdc3a26b247b1ca866b96429d0a2875db12 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Tue, 15 Oct 2024 21:47:36 +1100 Subject: [PATCH 146/425] fixes --- .../Enumerative/Composition.lean | 30 ++++++++++++------- Mathlib/Computability/DFA.lean | 2 +- Mathlib/Computability/Language.lean | 17 ++++++----- Mathlib/Computability/Primrec.lean | 6 ++-- Mathlib/Computability/RegularExpressions.lean | 10 +++---- Mathlib/Tactic/ComputeDegree.lean | 4 +-- Mathlib/Tactic/RewriteSearch.lean | 2 +- 7 files changed, 41 insertions(+), 30 deletions(-) diff --git a/Mathlib/Combinatorics/Enumerative/Composition.lean b/Mathlib/Combinatorics/Enumerative/Composition.lean index 917e4a7e41dbc6..3f06a1f76284ac 100644 --- a/Mathlib/Combinatorics/Enumerative/Composition.lean +++ b/Mathlib/Combinatorics/Enumerative/Composition.lean @@ -674,8 +674,8 @@ theorem get_splitWrtComposition (l : List α) (c : Composition n) get (l.splitWrtComposition c) i = (l.take (c.sizeUpTo (i + 1))).drop (c.sizeUpTo i) := by simp [getElem_splitWrtComposition] -theorem join_splitWrtCompositionAux {ns : List ℕ} : - ∀ {l : List α}, ns.sum = l.length → (l.splitWrtCompositionAux ns).join = l := by +theorem flatten_splitWrtCompositionAux {ns : List ℕ} : + ∀ {l : List α}, ns.sum = l.length → (l.splitWrtCompositionAux ns).flatten = l := by induction' ns with n ns IH <;> intro l h <;> simp at h · exact (length_eq_zero.1 h.symm).symm simp only [splitWrtCompositionAux_cons]; dsimp @@ -683,21 +683,29 @@ theorem join_splitWrtCompositionAux {ns : List ℕ} : · simp · rw [length_drop, ← h, add_tsub_cancel_left] -/-- If one splits a list along a composition, and then joins the sublists, one gets back the +@[deprecated (since := "2024-10-15")] +alias join_splitWrtCompositionAux := flatten_splitWrtCompositionAux + +/-- If one splits a list along a composition, and then flattens the sublists, one gets back the original list. -/ @[simp] -theorem join_splitWrtComposition (l : List α) (c : Composition l.length) : - (l.splitWrtComposition c).join = l := - join_splitWrtCompositionAux c.blocks_sum +theorem flatten_splitWrtComposition (l : List α) (c : Composition l.length) : + (l.splitWrtComposition c).flatten = l := + flatten_splitWrtCompositionAux c.blocks_sum + +@[deprecated (since := "2024-10-15")] alias join_splitWrtComposition := flatten_splitWrtComposition -/-- If one joins a list of lists and then splits the join along the right composition, one gets -back the original list of lists. -/ +/-- If one joins a list of lists and then splits the flattening along the right composition, +one gets back the original list of lists. -/ @[simp] -theorem splitWrtComposition_join (L : List (List α)) (c : Composition L.join.length) - (h : map length L = c.blocks) : splitWrtComposition (join L) c = L := by - simp only [eq_self_iff_true, and_self_iff, eq_iff_join_eq, join_splitWrtComposition, +theorem splitWrtComposition_flatten (L : List (List α)) (c : Composition L.flatten.length) + (h : map length L = c.blocks) : splitWrtComposition (flatten L) c = L := by + simp only [eq_self_iff_true, and_self_iff, eq_iff_flatten_eq, flatten_splitWrtComposition, map_length_splitWrtComposition, h] +@[deprecated (since := "2024-10-15")] +alias splitWrtComposition_join := splitWrtComposition_flatten + end List /-! diff --git a/Mathlib/Computability/DFA.lean b/Mathlib/Computability/DFA.lean index 48d4c116389873..19f997e872be6a 100644 --- a/Mathlib/Computability/DFA.lean +++ b/Mathlib/Computability/DFA.lean @@ -142,7 +142,7 @@ theorem evalFrom_of_pow {x y : List α} {s : σ} (hx : M.evalFrom s x = s) · rfl · have ha := hS a (List.mem_cons_self _ _) rw [Set.mem_singleton_iff] at ha - rw [List.join, evalFrom_of_append, ha, hx] + rw [List.flatten, evalFrom_of_append, ha, hx] apply ih intro z hz exact hS z (List.mem_cons_of_mem a hz) diff --git a/Mathlib/Computability/Language.lean b/Mathlib/Computability/Language.lean index 4e40a3919b388b..b8f3f94d0bb7b7 100644 --- a/Mathlib/Computability/Language.lean +++ b/Mathlib/Computability/Language.lean @@ -76,9 +76,9 @@ theorem mul_def (l m : Language α) : l * m = image2 (· ++ ·) l m := /-- The Kleene star of a language `L` is the set of all strings which can be written by concatenating strings from `L`. -/ -instance : KStar (Language α) := ⟨fun l ↦ {x | ∃ L : List (List α), x = L.join ∧ ∀ y ∈ L, y ∈ l}⟩ +instance : KStar (Language α) := ⟨fun l ↦ {x | ∃ L : List (List α), x = L.flatten ∧ ∀ y ∈ L, y ∈ l}⟩ -lemma kstar_def (l : Language α) : l∗ = {x | ∃ L : List (List α), x = L.join ∧ ∀ y ∈ L, y ∈ l} := +lemma kstar_def (l : Language α) : l∗ = {x | ∃ L : List (List α), x = L.flatten ∧ ∀ y ∈ L, y ∈ l} := rfl -- Porting note: `reducible` attribute cannot be local, @@ -106,10 +106,10 @@ theorem mem_mul : x ∈ l * m ↔ ∃ a ∈ l, ∃ b ∈ m, a ++ b = x := theorem append_mem_mul : a ∈ l → b ∈ m → a ++ b ∈ l * m := mem_image2_of_mem -theorem mem_kstar : x ∈ l∗ ↔ ∃ L : List (List α), x = L.join ∧ ∀ y ∈ L, y ∈ l := +theorem mem_kstar : x ∈ l∗ ↔ ∃ L : List (List α), x = L.flatten ∧ ∀ y ∈ L, y ∈ l := Iff.rfl -theorem join_mem_kstar {L : List (List α)} (h : ∀ y ∈ L, y ∈ l) : L.join ∈ l∗ := +theorem join_mem_kstar {L : List (List α)} (h : ∀ y ∈ L, y ∈ l) : L.flatten ∈ l∗ := ⟨L, rfl, h⟩ theorem nil_mem_kstar (l : Language α) : [] ∈ l∗ := @@ -156,10 +156,11 @@ theorem map_map (g : β → γ) (f : α → β) (l : Language α) : map g (map f simp [map, image_image] lemma mem_kstar_iff_exists_nonempty {x : List α} : - x ∈ l∗ ↔ ∃ S : List (List α), x = S.join ∧ ∀ y ∈ S, y ∈ l ∧ y ≠ [] := by + x ∈ l∗ ↔ ∃ S : List (List α), x = S.flatten ∧ ∀ y ∈ S, y ∈ l ∧ y ≠ [] := by constructor · rintro ⟨S, rfl, h⟩ - refine ⟨S.filter fun l ↦ !List.isEmpty l, by simp [List.join_filter_not_isEmpty], fun y hy ↦ ?_⟩ + refine ⟨S.filter fun l ↦ !List.isEmpty l, + by simp [List.flatten_filter_not_isEmpty], fun y hy ↦ ?_⟩ -- Porting note: The previous code was: -- rw [mem_filter, empty_iff_eq_nil] at hy rw [mem_filter, Bool.not_eq_true', ← Bool.bool_iff_false, List.isEmpty_iff] at hy @@ -168,7 +169,7 @@ lemma mem_kstar_iff_exists_nonempty {x : List α} : exact ⟨S, hx, fun y hy ↦ (h y hy).1⟩ theorem kstar_def_nonempty (l : Language α) : - l∗ = { x | ∃ S : List (List α), x = S.join ∧ ∀ y ∈ S, y ∈ l ∧ y ≠ [] } := by + l∗ = { x | ∃ S : List (List α), x = S.flatten ∧ ∀ y ∈ S, y ∈ l ∧ y ≠ [] } := by ext x; apply mem_kstar_iff_exists_nonempty theorem le_iff (l m : Language α) : l ≤ m ↔ l + m = m := @@ -202,7 +203,7 @@ theorem add_iSup {ι : Sort v} [Nonempty ι] (l : ι → Language α) (m : Langu sup_iSup theorem mem_pow {l : Language α} {x : List α} {n : ℕ} : - x ∈ l ^ n ↔ ∃ S : List (List α), x = S.join ∧ S.length = n ∧ ∀ y ∈ S, y ∈ l := by + x ∈ l ^ n ↔ ∃ S : List (List α), x = S.flatten ∧ S.length = n ∧ ∀ y ∈ S, y ∈ l := by induction' n with n ihn generalizing x · simp only [mem_one, pow_zero, length_eq_zero] constructor diff --git a/Mathlib/Computability/Primrec.lean b/Mathlib/Computability/Primrec.lean index 17cbe2ce38bec5..36e36c0d4f5d16 100644 --- a/Mathlib/Computability/Primrec.lean +++ b/Mathlib/Computability/Primrec.lean @@ -953,12 +953,14 @@ theorem list_range : Primrec List.range := (nat_rec' .id (const []) ((list_concat.comp snd fst).comp snd).to₂).of_eq fun n => by simp; induction n <;> simp [*, List.range_succ] -theorem list_join : Primrec (@List.join α) := +theorem list_flatten : Primrec (@List.flatten α) := (list_foldr .id (const []) <| to₂ <| comp (@list_append α _) snd).of_eq fun l => by dsimp; induction l <;> simp [*] +@[deprecated (since := "2024-10-15")] alias list_join := list_flatten + theorem list_bind {f : α → List β} {g : α → β → List σ} (hf : Primrec f) (hg : Primrec₂ g) : - Primrec (fun a => (f a).bind (g a)) := list_join.comp (list_map hf hg) + Primrec (fun a => (f a).bind (g a)) := list_flatten.comp (list_map hf hg) theorem optionToList : Primrec (Option.toList : Option α → List α) := (option_casesOn Primrec.id (const []) diff --git a/Mathlib/Computability/RegularExpressions.lean b/Mathlib/Computability/RegularExpressions.lean index 7835066c73ec15..da53a917cd11da 100644 --- a/Mathlib/Computability/RegularExpressions.lean +++ b/Mathlib/Computability/RegularExpressions.lean @@ -274,7 +274,7 @@ theorem mul_rmatch_iff (P Q : RegularExpression α) (x : List α) : theorem star_rmatch_iff (P : RegularExpression α) : ∀ x : List α, (star P).rmatch x ↔ ∃ S : List (List α), x - = S.join ∧ ∀ t ∈ S, t ≠ [] ∧ P.rmatch t := + = S.flatten ∧ ∀ t ∈ S, t ≠ [] ∧ P.rmatch t := fun x => by have IH := fun t (_h : List.length t < List.length x) => star_rmatch_iff P t clear star_rmatch_iff @@ -307,15 +307,15 @@ theorem star_rmatch_iff (P : RegularExpression α) : · cases' t' with b t · simp only [forall_eq_or_imp, List.mem_cons] at helem simp only [eq_self_iff_true, not_true, Ne, false_and] at helem - simp only [List.join, List.cons_append, List.cons_eq_cons] at hsum - refine ⟨t, U.join, hsum.2, ?_, ?_⟩ + simp only [List.flatten, List.cons_append, List.cons_eq_cons] at hsum + refine ⟨t, U.flatten, hsum.2, ?_, ?_⟩ · specialize helem (b :: t) (by simp) rw [rmatch] at helem convert helem.2 exact hsum.1 - · have hwf : U.join.length < (List.cons a x).length := by + · have hwf : U.flatten.length < (List.cons a x).length := by rw [hsum.1, hsum.2] - simp only [List.length_append, List.length_join, List.length] + simp only [List.length_append, List.length_flatten, List.length] omega rw [IH _ hwf] refine ⟨U, rfl, fun t h => helem t ?_⟩ diff --git a/Mathlib/Tactic/ComputeDegree.lean b/Mathlib/Tactic/ComputeDegree.lean index 792092c33497a6..9ac6f406599b90 100644 --- a/Mathlib/Tactic/ComputeDegree.lean +++ b/Mathlib/Tactic/ComputeDegree.lean @@ -379,7 +379,7 @@ def try_rfl (mvs : List MVarId) : MetaM (List MVarId) := do else pure [g] | none => return [g] - return (assignable.join ++ tried_rfl.join) + return (assignable.flatten ++ tried_rfl.flatten) /-- `splitApply mvs static` takes two lists of `MVarId`s. The first list, `mvs`, @@ -397,7 +397,7 @@ def splitApply (mvs static : List MVarId) : MetaM ((List MVarId) × (List MVarId let progress := ← can_progress.mapM fun mv => do let lem := dispatchLemma <| twoHeadsArgs (← mv.getType'') mv.applyConst <| lem - return (progress.join, static ++ curr_static) + return (progress.flatten, static ++ curr_static) /-- `miscomputedDegree? deg false_goals` takes as input * an `Expr`ession `deg`, representing the degree of a polynomial diff --git a/Mathlib/Tactic/RewriteSearch.lean b/Mathlib/Tactic/RewriteSearch.lean index f91c389946783c..c8739c4316a718 100644 --- a/Mathlib/Tactic/RewriteSearch.lean +++ b/Mathlib/Tactic/RewriteSearch.lean @@ -85,7 +85,7 @@ Tokenize a string at whitespace, and then pull off delimiters. -- this makes it "cheap" to change one identifier for another. def tokenize (e : Expr) : MetaM (List String) := do let s := (← ppExpr e).pretty - return s.splitOn.map splitDelimiters |>.join + return s.splitOn.map splitDelimiters |>.flatten /-- Data structure containing the history of a rewrite search. From 1fca38f670fa7b737631f3c9e11af869f56bbe1e Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Tue, 15 Oct 2024 21:57:38 +1100 Subject: [PATCH 147/425] fix --- Mathlib/Analysis/Analytic/Composition.lean | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Mathlib/Analysis/Analytic/Composition.lean b/Mathlib/Analysis/Analytic/Composition.lean index e439182fb3de17..98bf2da3823b90 100644 --- a/Mathlib/Analysis/Analytic/Composition.lean +++ b/Mathlib/Analysis/Analytic/Composition.lean @@ -1021,9 +1021,9 @@ def gather (a : Composition n) (b : Composition a.length) : Composition n where _ ≤ j.sum := length_le_sum_of_one_le _ H intro i hi apply a.one_le_blocks - rw [← a.blocks.join_splitWrtComposition b] - exact mem_join_of_mem hj hi - blocks_sum := by rw [← sum_join, join_splitWrtComposition, a.blocks_sum] + rw [← a.blocks.flatten_splitWrtComposition b] + exact mem_flatten_of_mem hj hi + blocks_sum := by rw [← sum_flatten, flatten_splitWrtComposition, a.blocks_sum] theorem length_gather (a : Composition n) (b : Composition a.length) : length (a.gather b) = b.length := @@ -1042,8 +1042,8 @@ def sigmaCompositionAux (a : Composition n) (b : Composition a.length) blocks_pos {i} hi := a.blocks_pos (by - rw [← a.blocks.join_splitWrtComposition b] - exact mem_join_of_mem (List.getElem_mem _) hi) + rw [← a.blocks.flatten_splitWrtComposition b] + exact mem_flatten_of_mem (List.getElem_mem _) hi) blocks_sum := by simp [Composition.blocksFun, getElem_map, Composition.gather] theorem length_sigmaCompositionAux (a : Composition n) (b : Composition a.length) @@ -1130,9 +1130,9 @@ def sigmaEquivSigmaPi (n : ℕ) : Σ c : Composition n, ∀ i : Fin c.length, Composition (c.blocksFun i) where toFun i := ⟨i.1.gather i.2, i.1.sigmaCompositionAux i.2⟩ invFun i := - ⟨{ blocks := (ofFn fun j => (i.2 j).blocks).join + ⟨{ blocks := (ofFn fun j => (i.2 j).blocks).flatten blocks_pos := by - simp only [and_imp, List.mem_join, exists_imp, forall_mem_ofFn_iff] + simp only [and_imp, List.mem_flatten, exists_imp, forall_mem_ofFn_iff] exact @fun i j hj => Composition.blocks_pos _ hj blocks_sum := by simp [sum_ofFn, Composition.blocks_sum, Composition.sum_blocksFun] }, { blocks := ofFn fun j => (i.2 j).length @@ -1149,7 +1149,7 @@ def sigmaEquivSigmaPi (n : ℕ) : dsimp constructor · conv_rhs => - rw [← join_splitWrtComposition a.blocks b, ← ofFn_get (splitWrtComposition a.blocks b)] + rw [← flatten_splitWrtComposition a.blocks b, ← ofFn_get (splitWrtComposition a.blocks b)] have A : length (gather a b) = List.length (splitWrtComposition a.blocks b) := by simp only [length, gather, length_map, length_splitWrtComposition] congr! 2 @@ -1173,13 +1173,13 @@ def sigmaEquivSigmaPi (n : ℕ) : · congr ext1 dsimp [Composition.gather] - rwa [splitWrtComposition_join] + rwa [splitWrtComposition_flatten] simp only [map_ofFn] rfl · rw [Fin.heq_fun_iff] · intro i dsimp [Composition.sigmaCompositionAux] - rw [getElem_of_eq (splitWrtComposition_join _ _ _)] + rw [getElem_of_eq (splitWrtComposition_flatten _ _ _)] · simp only [List.getElem_ofFn] · simp only [map_ofFn] rfl From f87f0ec95cec45e45bdbeba6aa7f6c02a542f1cd Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Tue, 15 Oct 2024 12:11:16 +0000 Subject: [PATCH 148/425] feat: lemmas about exterior (#17765) --- Mathlib/Order/Filter/Ker.lean | 4 ++-- Mathlib/Topology/Exterior.lean | 20 +++++++++++++++++--- Mathlib/Topology/NhdsSet.lean | 6 ++++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/Mathlib/Order/Filter/Ker.lean b/Mathlib/Order/Filter/Ker.lean index 84ab8db20e0cf6..ee06f9c53a8d10 100644 --- a/Mathlib/Order/Filter/Ker.lean +++ b/Mathlib/Order/Filter/Ker.lean @@ -38,9 +38,9 @@ lemma ker_surjective : Surjective (ker : Filter α → Set α) := gi_principal_k @[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_iInf (f : ι → Filter α) : ker (⨅ i, f i) = ⨅ i, ker (f i) := +@[simp] lemma ker_iInf (f : ι → Filter α) : ker (⨅ i, f i) = ⋂ i, ker (f i) := gi_principal_ker.gc.u_iInf -@[simp] lemma ker_sInf (S : Set (Filter α)) : ker (sInf S) = ⨅ f ∈ S, ker f := +@[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 _ diff --git a/Mathlib/Topology/Exterior.lean b/Mathlib/Topology/Exterior.lean index fcf995f4c441ad..511879082540a1 100644 --- a/Mathlib/Topology/Exterior.lean +++ b/Mathlib/Topology/Exterior.lean @@ -19,7 +19,7 @@ In this file we prove basic properties of this operation. open Set Filter open scoped Topology -variable {X : Type*} [TopologicalSpace X] {s t : Set X} {x y : X} +variable {ι : Sort*} {X : Type*} [TopologicalSpace X] {s t : Set X} {x y : X} lemma exterior_singleton_eq_ker_nhds (x : X) : exterior {x} = (𝓝 x).ker := by simp [exterior] @@ -49,8 +49,7 @@ lemma IsOpen.exterior_subset (ht : IsOpen t) : exterior s ⊆ t ↔ s ⊆ t := @[deprecated (since := "2024-09-18")] alias IsOpen.exterior_subset_iff := IsOpen.exterior_subset @[simp] -theorem exterior_iUnion {ι : Sort*} (s : ι → Set X) : - exterior (⋃ i, s i) = ⋃ i, exterior (s i) := by +theorem exterior_iUnion (s : ι → Set X) : exterior (⋃ i, s i) = ⋃ i, exterior (s i) := by simp only [exterior, nhdsSet_iUnion, ker_iSup] @[simp] @@ -61,6 +60,21 @@ theorem exterior_union (s t : Set X) : exterior (s ∪ t) = exterior s ∪ exter theorem exterior_sUnion (S : Set (Set X)) : exterior (⋃₀ S) = ⋃ s ∈ S, exterior s := by simp only [sUnion_eq_biUnion, exterior_iUnion] +theorem exterior_iInter_subset {s : ι → Set X} : exterior (⋂ i, s i) ⊆ ⋂ i, exterior (s i) := by + simp_rw [exterior] + refine ker_mono (nhdsSet_iInter_le _) |>.trans_eq ?_ + simp_rw [ker_iInf] + +theorem exterior_inter_subset {s t : Set X} : exterior (s ∩ t) ⊆ exterior s ∩ exterior t := by + simp_rw [exterior] + refine ker_mono (nhdsSet_inter_le _ _) |>.trans_eq ?_ + rw [ker_inf _ _] + +theorem exterior_sInter_subset {s : Set (Set X)} : exterior (⋂₀ s) ⊆ ⋂ x ∈ s, exterior x := by + simp_rw [exterior] + refine ker_mono (nhdsSet_sInter_le _) |>.trans_eq ?_ + simp_rw [ker_iInf] + theorem mem_exterior_iff_specializes : x ∈ exterior s ↔ ∃ y ∈ s, x ⤳ y := calc x ∈ exterior s ↔ x ∈ exterior (⋃ y ∈ s, {y}) := by simp _ ↔ ∃ y ∈ s, x ⤳ y := by diff --git a/Mathlib/Topology/NhdsSet.lean b/Mathlib/Topology/NhdsSet.lean index 3a3f45b2eeff7e..9b361653607e12 100644 --- a/Mathlib/Topology/NhdsSet.lean +++ b/Mathlib/Topology/NhdsSet.lean @@ -162,6 +162,12 @@ if `X` has two elements and the coarse topology and `s` and `t` are distinct sin theorem nhdsSet_inter_le (s t : Set X) : 𝓝ˢ (s ∩ t) ≤ 𝓝ˢ s ⊓ 𝓝ˢ t := (monotone_nhdsSet (X := X)).map_inf_le s t +theorem nhdsSet_iInter_le {ι : Sort*} (s : ι → Set X) : 𝓝ˢ (⋂ i, s i) ≤ ⨅ i, 𝓝ˢ (s i) := + (monotone_nhdsSet (X := X)).map_iInf_le + +theorem nhdsSet_sInter_le (s : Set (Set X)) : 𝓝ˢ (⋂₀ s) ≤ ⨅ x ∈ s, 𝓝ˢ x := + (monotone_nhdsSet (X := X)).map_sInf_le + variable (s) in theorem IsClosed.nhdsSet_le_sup (h : IsClosed t) : 𝓝ˢ s ≤ 𝓝ˢ (s ∩ t) ⊔ 𝓟 (tᶜ) := calc From 33e2fef67fda5aae526e68e1d8ccff8a4b327e5f Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Tue, 15 Oct 2024 13:30:52 +0000 Subject: [PATCH 149/425] chore(CategoryTheory): Unique->Nonempty+Subsingleton (#17748) Assume `[Nonempty _] [Subsingleton _]` instead of `[Unique _]` whenever `default` isn't used outside of proofs. --- .../CategoryTheory/ChosenFiniteProducts.lean | 2 +- .../Limits/Shapes/Biproducts.lean | 11 +++++----- .../Limits/Shapes/Products.lean | 20 +++++++++---------- .../Limits/Shapes/Terminal.lean | 12 +++++++---- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/Mathlib/CategoryTheory/ChosenFiniteProducts.lean b/Mathlib/CategoryTheory/ChosenFiniteProducts.lean index 4c342ebe1413b8..a41ef978ef9887 100644 --- a/Mathlib/CategoryTheory/ChosenFiniteProducts.lean +++ b/Mathlib/CategoryTheory/ChosenFiniteProducts.lean @@ -208,7 +208,7 @@ instance (priority := 100) : Limits.HasFiniteProducts C := letI : ∀ (X Y : C), Limits.HasLimit (Limits.pair X Y) := fun _ _ => .mk <| ChosenFiniteProducts.product _ _ letI : Limits.HasBinaryProducts C := Limits.hasBinaryProducts_of_hasLimit_pair _ - letI : Limits.HasTerminal C := Limits.hasTerminal_of_unique (𝟙_ _) + letI : Limits.HasTerminal C := Limits.hasTerminal_of_unique (𝟙_ C) hasFiniteProducts_of_has_binary_and_terminal end ChosenFiniteProducts diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean b/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean index ba161d31082771..78e960db24953c 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean @@ -1028,12 +1028,12 @@ instance (priority := 100) hasZeroObject_of_hasFiniteBiproducts [HasFiniteBiprod section -variable {C} [Unique J] (f : J → C) +variable {C} attribute [local simp] eq_iff_true_of_subsingleton in /-- The limit bicone for the biproduct over an index type with exactly one term. -/ @[simps] -def limitBiconeOfUnique : LimitBicone f where +def limitBiconeOfUnique [Unique J] (f : J → C) : LimitBicone f where bicone := { pt := f default π := fun j => eqToHom (by congr; rw [← Unique.uniq] ) @@ -1042,12 +1042,13 @@ def limitBiconeOfUnique : LimitBicone f where { isLimit := (limitConeOfUnique f).isLimit isColimit := (colimitCoconeOfUnique f).isColimit } -instance (priority := 100) hasBiproduct_unique : HasBiproduct f := - HasBiproduct.mk (limitBiconeOfUnique f) +instance (priority := 100) hasBiproduct_unique [Subsingleton J] [Nonempty J] (f : J → C) : + HasBiproduct f := + let ⟨_⟩ := nonempty_unique J; .mk (limitBiconeOfUnique f) /-- A biproduct over an index type with exactly one term is just the object over that term. -/ @[simps!] -def biproductUniqueIso : ⨁ f ≅ f default := +def biproductUniqueIso [Unique J] (f : J → C) : ⨁ f ≅ f default := (biproduct.uniqueUpToIso _ (limitBiconeOfUnique f).isBilimit).symm end diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Products.lean b/Mathlib/CategoryTheory/Limits/Shapes/Products.lean index aa816cb1ee4daa..e5ec9c17d3c2a3 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Products.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Products.lean @@ -661,11 +661,9 @@ theorem hasProducts_of_limit_fans (lf : ∀ {J : Type w} (f : J → C), Fan f) section Unique -variable [Unique β] (f : β → C) - /-- The limit cone for the product over an index type with exactly one term. -/ @[simps] -def limitConeOfUnique : LimitCone (Discrete.functor f) where +def limitConeOfUnique [Unique β] (f : β → C) : LimitCone (Discrete.functor f) where cone := { pt := f default π := Discrete.natTrans (fun ⟨j⟩ => eqToHom (by @@ -682,17 +680,18 @@ def limitConeOfUnique : LimitCone (Discrete.functor f) where specialize w default simpa using w } -instance (priority := 100) hasProduct_unique : HasProduct f := - HasLimit.mk (limitConeOfUnique f) +instance (priority := 100) hasProduct_unique [Nonempty β] [Subsingleton β] (f : β → C) : + HasProduct 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 : ∏ᶜ f ≅ f default := +def productUniqueIso [Unique β] (f : β → C) : ∏ᶜ f ≅ f default := IsLimit.conePointUniqueUpToIso (limit.isLimit _) (limitConeOfUnique f).isLimit /-- The colimit cocone for the coproduct over an index type with exactly one term. -/ @[simps] -def colimitCoconeOfUnique : ColimitCocone (Discrete.functor f) where +def colimitCoconeOfUnique [Unique β] (f : β → C) : ColimitCocone (Discrete.functor f) where cocone := { pt := f default ι := Discrete.natTrans (fun ⟨j⟩ => eqToHom (by @@ -710,12 +709,13 @@ def colimitCoconeOfUnique : ColimitCocone (Discrete.functor f) where erw [Category.id_comp] at w exact w } -instance (priority := 100) hasCoproduct_unique : HasCoproduct f := - HasColimit.mk (colimitCoconeOfUnique f) +instance (priority := 100) hasCoproduct_unique [Nonempty β] [Subsingleton β] (f : β → C) : + HasCoproduct f := + 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 : ∐ f ≅ f default := +def coproductUniqueIso [Unique β] (f : β → C) : ∐ f ≅ f default := IsColimit.coconePointUniqueUpToIso (colimit.isColimit _) (colimitCoconeOfUnique f).isColimit end Unique diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Terminal.lean b/Mathlib/CategoryTheory/Limits/Shapes/Terminal.lean index eb36394aaa77b8..03741e73c82af8 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Terminal.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Terminal.lean @@ -306,8 +306,10 @@ variable {C} /-- We can more explicitly show that a category has a terminal object by specifying the object, and showing there is a unique morphism to it from any other object. -/ -theorem hasTerminal_of_unique (X : C) [h : ∀ Y : C, Unique (Y ⟶ X)] : HasTerminal C := - { has_limit := fun F => HasLimit.mk ⟨_, (isTerminalEquivUnique F X).invFun h⟩ } +theorem hasTerminal_of_unique (X : C) [∀ Y, Nonempty (Y ⟶ X)] [∀ Y, Subsingleton (Y ⟶ X)] : + HasTerminal C where + has_limit F := .mk ⟨_, (isTerminalEquivUnique F X).invFun fun _ ↦ + ⟨Classical.inhabited_of_nonempty', (Subsingleton.elim · _)⟩⟩ theorem IsTerminal.hasTerminal {X : C} (h : IsTerminal X) : HasTerminal C := { has_limit := fun F => HasLimit.mk ⟨⟨X, by aesop_cat, by aesop_cat⟩, @@ -315,8 +317,10 @@ theorem IsTerminal.hasTerminal {X : C} (h : IsTerminal X) : HasTerminal C := /-- We can more explicitly show that a category has an initial object by specifying the object, and showing there is a unique morphism from it to any other object. -/ -theorem hasInitial_of_unique (X : C) [h : ∀ Y : C, Unique (X ⟶ Y)] : HasInitial C := - { has_colimit := fun F => HasColimit.mk ⟨_, (isInitialEquivUnique F X).invFun h⟩ } +theorem hasInitial_of_unique (X : C) [∀ Y, Nonempty (X ⟶ Y)] [∀ Y, Subsingleton (X ⟶ Y)] : + HasInitial C where + has_colimit F := .mk ⟨_, (isInitialEquivUnique F X).invFun fun _ ↦ + ⟨Classical.inhabited_of_nonempty', (Subsingleton.elim · _)⟩⟩ theorem IsInitial.hasInitial {X : C} (h : IsInitial X) : HasInitial C where has_colimit F := From b71a497062cee55d6ea0c674b6bdd7312ea190ce Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Tue, 15 Oct 2024 14:06:17 +0000 Subject: [PATCH 150/425] chore: move `Init.Algebra.Classes` and its remaining dependencies to `Deprecated` (#17769) The results in this file have been deprecated for a while and none seem to be used in Mathlib except for other deprecated results that aren't used either. So let's move everything to the `Deprecated` folder in order to empty out the `Init` folder. --- Mathlib.lean | 4 +- .../AlgebraClasses.lean} | 8 ++-- Mathlib/Deprecated/Equiv.lean | 30 +++++++++++++++ Mathlib/Deprecated/RelClasses.lean | 38 +++++++++++++++++++ Mathlib/Logic/Equiv/Basic.lean | 11 ------ Mathlib/Order/RelClasses.lean | 11 ------ 6 files changed, 74 insertions(+), 28 deletions(-) rename Mathlib/{Init/Algebra/Classes.lean => Deprecated/AlgebraClasses.lean} (95%) create mode 100644 Mathlib/Deprecated/Equiv.lean create mode 100644 Mathlib/Deprecated/RelClasses.lean diff --git a/Mathlib.lean b/Mathlib.lean index 8cd33465fca3ab..54521d3fb26f3c 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2651,10 +2651,13 @@ import Mathlib.Data.ZMod.Factorial import Mathlib.Data.ZMod.IntUnitsPower import Mathlib.Data.ZMod.Quotient import Mathlib.Data.ZMod.Units +import Mathlib.Deprecated.AlgebraClasses import Mathlib.Deprecated.Aliases import Mathlib.Deprecated.Combinator +import Mathlib.Deprecated.Equiv import Mathlib.Deprecated.Group import Mathlib.Deprecated.HashMap +import Mathlib.Deprecated.RelClasses import Mathlib.Deprecated.Ring import Mathlib.Deprecated.Subfield import Mathlib.Deprecated.Subgroup @@ -2923,7 +2926,6 @@ import Mathlib.GroupTheory.Torsion import Mathlib.GroupTheory.Transfer import Mathlib.InformationTheory.Hamming import Mathlib.Init -import Mathlib.Init.Algebra.Classes import Mathlib.Init.Data.Nat.Lemmas import Mathlib.Init.Logic import Mathlib.Lean.CoreM diff --git a/Mathlib/Init/Algebra/Classes.lean b/Mathlib/Deprecated/AlgebraClasses.lean similarity index 95% rename from Mathlib/Init/Algebra/Classes.lean rename to Mathlib/Deprecated/AlgebraClasses.lean index bb4475917a4fd9..cc26f497422b29 100644 --- a/Mathlib/Init/Algebra/Classes.lean +++ b/Mathlib/Deprecated/AlgebraClasses.lean @@ -6,12 +6,10 @@ Authors: Leonardo de Moura import Mathlib.Order.Defs /-! -# Note about `Mathlib/Init/` -The files in `Mathlib/Init` are leftovers from the port from Mathlib3. -(They contain content moved from lean3 itself that Mathlib needed but was not moved to lean4.) +# Note about deprecated files -We intend to move all the content of these files out into the main `Mathlib` directory structure. -Contributions assisting with this are appreciated. +This file is deprecated, and is no longer imported by anything in mathlib other than other +deprecated files, and test files. You should not need to import it. # Unbundled algebra classes diff --git a/Mathlib/Deprecated/Equiv.lean b/Mathlib/Deprecated/Equiv.lean new file mode 100644 index 00000000000000..74bc9b68ecdd34 --- /dev/null +++ b/Mathlib/Deprecated/Equiv.lean @@ -0,0 +1,30 @@ +/- +Copyright (c) 2015 Microsoft Corporation. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Leonardo de Moura, Mario Carneiro +-/ +import Mathlib.Deprecated.AlgebraClasses +import Mathlib.Logic.Equiv.Defs +/-! +# Note about deprecated files + +This file is deprecated, and is no longer imported by anything in mathlib other than other +deprecated files, and test files. You should not need to import it. + +# Unbundled algebra classes and `Equiv` + +This file contains a few deprecated results on the `Is*` classes introduced in +`Mathlib/Deprecated/AlgebraClasses.lean` that involve the `Equiv` type. +-/ + +variable {α₁ β₁ : Type*} (e : α₁ ≃ β₁) (f : α₁ → α₁ → α₁) + +set_option linter.deprecated false + +@[deprecated (since := "2024-09-11")] +instance [IsLeftCancel α₁ f] : IsLeftCancel β₁ (e.arrowCongr (e.arrowCongr e) f) := + ⟨e.surjective.forall₃.2 fun x y z => by simpa using @IsLeftCancel.left_cancel _ f _ x y z⟩ + +@[deprecated (since := "2024-09-11")] +instance [IsRightCancel α₁ f] : IsRightCancel β₁ (e.arrowCongr (e.arrowCongr e) f) := + ⟨e.surjective.forall₃.2 fun x y z => by simpa using @IsRightCancel.right_cancel _ f _ x y z⟩ diff --git a/Mathlib/Deprecated/RelClasses.lean b/Mathlib/Deprecated/RelClasses.lean new file mode 100644 index 00000000000000..357b10283c2d5c --- /dev/null +++ b/Mathlib/Deprecated/RelClasses.lean @@ -0,0 +1,38 @@ +/- +Copyright (c) 2020 Jeremy Avigad. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jeremy Avigad, Mario Carneiro, Yury Kudryashov +-/ +import Mathlib.Deprecated.AlgebraClasses +import Mathlib.Order.RelClasses + +/-! +# Note about deprecated files + +This file is deprecated, and is no longer imported by anything in mathlib other than other +deprecated files, and test files. You should not need to import it. + +# Unbundled relation classes + +In this file we prove some properties of `Is*` classes defined in +`Mathlib/Deprecated/AlgebraClasses.lean`. + +-/ + +set_option linter.deprecated false + +universe u v + +variable {α : Type u} + +open Function + +@[deprecated (since := "2024-07-30")] +theorem IsTotalPreorder.swap (r) [IsTotalPreorder α r] : IsTotalPreorder α (swap r) := + { @IsPreorder.swap α r _, @IsTotal.swap α r _ with } + +@[deprecated (since := "2024-08-22")] instance [LinearOrder α] : IsTotalPreorder α (· ≤ ·) where +@[deprecated (since := "2024-08-22")] instance [LinearOrder α] : IsTotalPreorder α (· ≥ ·) where + +@[deprecated (since := "2024-07-30")] +instance [LinearOrder α] : IsIncompTrans α (· < ·) := by infer_instance diff --git a/Mathlib/Logic/Equiv/Basic.lean b/Mathlib/Logic/Equiv/Basic.lean index 2176dc8c6d48a0..34383fc48d3886 100644 --- a/Mathlib/Logic/Equiv/Basic.lean +++ b/Mathlib/Logic/Equiv/Basic.lean @@ -9,7 +9,6 @@ import Mathlib.Data.Prod.Basic import Mathlib.Data.Sigma.Basic import Mathlib.Data.Subtype import Mathlib.Data.Sum.Basic -import Mathlib.Init.Algebra.Classes import Mathlib.Logic.Equiv.Defs import Mathlib.Logic.Function.Conjugate import Mathlib.Tactic.Coe @@ -1732,16 +1731,6 @@ instance [Std.Associative f] : Std.Associative (e.arrowCongr (e.arrowCongr e) f) instance [Std.IdempotentOp f] : Std.IdempotentOp (e.arrowCongr (e.arrowCongr e) f) := (e.semiconj₂_conj f).isIdempotent_right e.surjective -set_option linter.deprecated false in -@[deprecated (since := "2024-09-11")] -instance [IsLeftCancel α₁ f] : IsLeftCancel β₁ (e.arrowCongr (e.arrowCongr e) f) := - ⟨e.surjective.forall₃.2 fun x y z => by simpa using @IsLeftCancel.left_cancel _ f _ x y z⟩ - -set_option linter.deprecated false in -@[deprecated (since := "2024-09-11")] -instance [IsRightCancel α₁ f] : IsRightCancel β₁ (e.arrowCongr (e.arrowCongr e) f) := - ⟨e.surjective.forall₃.2 fun x y z => by simpa using @IsRightCancel.right_cancel _ f _ x y z⟩ - end BinaryOp section ULift diff --git a/Mathlib/Order/RelClasses.lean b/Mathlib/Order/RelClasses.lean index 1f6bd1a3387583..2e5d1f0e9e0d31 100644 --- a/Mathlib/Order/RelClasses.lean +++ b/Mathlib/Order/RelClasses.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Jeremy Avigad, Mario Carneiro, Yury Kudryashov -/ import Mathlib.Data.Nat.Defs -import Mathlib.Init.Algebra.Classes import Mathlib.Logic.IsEmpty import Mathlib.Order.Basic import Mathlib.Tactic.MkIffOfInductiveProp @@ -90,10 +89,6 @@ theorem IsStrictOrder.swap (r) [IsStrictOrder α r] : IsStrictOrder α (swap r) theorem IsPartialOrder.swap (r) [IsPartialOrder α r] : IsPartialOrder α (swap r) := { @IsPreorder.swap α r _, @IsAntisymm.swap α r _ with } -@[deprecated (since := "2024-07-30")] -theorem IsTotalPreorder.swap (r) [IsTotalPreorder α r] : IsTotalPreorder α (swap r) := - { @IsPreorder.swap α r _, @IsTotal.swap α r _ with } - @[deprecated (since := "2024-07-30")] theorem IsLinearOrder.swap (r) [IsLinearOrder α r] : IsLinearOrder α (swap r) := { @IsPartialOrder.swap α r _, @IsTotal.swap α r _ with } @@ -777,9 +772,6 @@ instance LE.isTotal [LinearOrder α] : IsTotal α (· ≤ ·) := instance [LinearOrder α] : IsTotal α (· ≥ ·) := IsTotal.swap _ -@[deprecated (since := "2024-08-22")] instance [LinearOrder α] : IsTotalPreorder α (· ≤ ·) where -@[deprecated (since := "2024-08-22")] instance [LinearOrder α] : IsTotalPreorder α (· ≥ ·) where - instance [LinearOrder α] : IsLinearOrder α (· ≤ ·) where instance [LinearOrder α] : IsLinearOrder α (· ≥ ·) where @@ -800,9 +792,6 @@ instance [LinearOrder α] : IsStrictTotalOrder α (· < ·) where instance [LinearOrder α] : IsOrderConnected α (· < ·) := by infer_instance -@[deprecated (since := "2024-07-30")] -instance [LinearOrder α] : IsIncompTrans α (· < ·) := by infer_instance - @[deprecated (since := "2024-07-30")] instance [LinearOrder α] : IsStrictWeakOrder α (· < ·) := by infer_instance From 07f7d4a0629860e81d046b99cf4b5c9911e0be56 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Tue, 15 Oct 2024 14:56:12 +0000 Subject: [PATCH 151/425] chore: remove `eqns` attributes that do not change equations (#17772) As far as I can tell, the only use of `eqns` that we really need is in the `irreducible_def` command. Many other usages can be replaced with a few small changes, and a few do not seem to have been for older versions of Lean before they unfolded `match` in a nice way. This PR removes the usages of `eqns` that do not seem to change any unfolding behaviour in current versions of Lean. --- Mathlib/Computability/TMToPartrec.lean | 20 ++++++++++++-------- Mathlib/Logic/Function/Defs.lean | 2 -- Mathlib/SetTheory/Ordinal/Notation.lean | 7 ------- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/Mathlib/Computability/TMToPartrec.lean b/Mathlib/Computability/TMToPartrec.lean index 79a322e54c7543..a19ae0a5453fde 100644 --- a/Mathlib/Computability/TMToPartrec.lean +++ b/Mathlib/Computability/TMToPartrec.lean @@ -997,30 +997,34 @@ def tr : Λ' → Stmt' cond (natEnd s.iget) (Λ'.ret k) <| Λ'.clear natEnd main <| trNormal f (Cont'.fix f k) | Λ'.ret Cont'.halt => (load fun _ => none) <| halt -/- Porting note: The equation lemma of `tr` simplifies to `match` structures. To prevent this, -we replace equation lemmas of `tr`. -/ - +@[simp] theorem tr_move (p k₁ k₂ q) : tr (Λ'.move p k₁ k₂ q) = pop' k₁ (branch (fun s => s.elim true p) (goto fun _ => q) (push' k₂ <| goto fun _ => Λ'.move p k₁ k₂ q)) := rfl +@[simp] theorem tr_push (k f q) : tr (Λ'.push k f q) = branch (fun s => (f s).isSome) ((push k fun s => (f s).iget) <| goto fun _ => q) (goto fun _ => q) := rfl +@[simp] theorem tr_read (q) : tr (Λ'.read q) = goto q := rfl +@[simp] theorem tr_clear (p k q) : tr (Λ'.clear p k q) = pop' k (branch (fun s => s.elim true p) (goto fun _ => q) (goto fun _ => Λ'.clear p k q)) := rfl +@[simp] theorem tr_copy (q) : tr (Λ'.copy q) = pop' rev (branch Option.isSome (push' main <| push' stack <| goto fun _ => Λ'.copy q) (goto fun _ => q)) := rfl +@[simp] theorem tr_succ (q) : tr (Λ'.succ q) = pop' main (branch (fun s => s = some Γ'.bit1) ((push rev fun _ => Γ'.bit0) <| goto fun _ => Λ'.succ q) <| branch (fun s => s = some Γ'.cons) ((push main fun _ => Γ'.cons) <| (push main fun _ => Γ'.bit1) <| goto fun _ => unrev q) ((push main fun _ => Γ'.bit1) <| goto fun _ => unrev q)) := rfl +@[simp] theorem tr_pred (q₁ q₂) : tr (Λ'.pred q₁ q₂) = pop' main (branch (fun s => s = some Γ'.bit0) ((push rev fun _ => Γ'.bit1) <| goto fun _ => Λ'.pred q₁ q₂) <| branch (fun s => natEnd s.iget) (goto fun _ => q₁) @@ -1028,26 +1032,26 @@ theorem tr_pred (q₁ q₂) : tr (Λ'.pred q₁ q₂) = pop' main (branch (fun s branch (fun s => natEnd s.iget) (goto fun _ => unrev q₂) ((push rev fun _ => Γ'.bit0) <| goto fun _ => unrev q₂))) := rfl +@[simp] theorem tr_ret_cons₁ (fs k) : tr (Λ'.ret (Cont'.cons₁ fs k)) = goto fun _ => move₂ (fun _ => false) main aux <| move₂ (fun s => s = Γ'.consₗ) stack main <| move₂ (fun _ => false) aux stack <| trNormal fs (Cont'.cons₂ k) := rfl +@[simp] theorem tr_ret_cons₂ (k) : tr (Λ'.ret (Cont'.cons₂ k)) = goto fun _ => head stack <| Λ'.ret k := rfl +@[simp] theorem tr_ret_comp (f k) : tr (Λ'.ret (Cont'.comp f k)) = goto fun _ => trNormal f k := rfl +@[simp] theorem tr_ret_fix (f k) : tr (Λ'.ret (Cont'.fix f k)) = pop' main (goto fun s => cond (natEnd s.iget) (Λ'.ret k) <| Λ'.clear natEnd main <| trNormal f (Cont'.fix f k)) := rfl +@[simp] theorem tr_ret_halt : tr (Λ'.ret Cont'.halt) = (load fun _ => none) halt := rfl -attribute - [eqns tr_move tr_push tr_read tr_clear tr_copy tr_succ tr_pred tr_ret_cons₁ - tr_ret_cons₂ tr_ret_comp tr_ret_fix tr_ret_halt] tr -attribute [simp] tr - /-- Translating a `Cont` continuation to a `Cont'` continuation simply entails dropping all the data. This data is instead encoded in `trContStack` in the configuration. -/ def trCont : Cont → Cont' diff --git a/Mathlib/Logic/Function/Defs.lean b/Mathlib/Logic/Function/Defs.lean index ab1505baf76fa8..0d0d15994a4f79 100644 --- a/Mathlib/Logic/Function/Defs.lean +++ b/Mathlib/Logic/Function/Defs.lean @@ -21,8 +21,6 @@ namespace Function -- Porting note: fix the universe of `ζ`, it used to be `u₁` variable {α : Sort u₁} {β : Sort u₂} {φ : Sort u₃} {δ : Sort u₄} {ζ : Sort u₅} -attribute [eqns comp_def] comp - lemma flip_def {f : α → β → φ} : flip f = fun b a => f a b := rfl #adaptation_note /-- nightly-2024-03-16 diff --git a/Mathlib/SetTheory/Ordinal/Notation.lean b/Mathlib/SetTheory/Ordinal/Notation.lean index 39a46f5780ac94..9df8635093a8b6 100644 --- a/Mathlib/SetTheory/Ordinal/Notation.lean +++ b/Mathlib/SetTheory/Ordinal/Notation.lean @@ -1004,13 +1004,6 @@ theorem fundamentalSequenceProp_inr (o f) : ∀ a, a < o.repr → ∃ i, a < (f i).repr := Iff.rfl -attribute - [eqns - fundamentalSequenceProp_inl_none - fundamentalSequenceProp_inl_some - fundamentalSequenceProp_inr] - FundamentalSequenceProp - theorem fundamentalSequence_has_prop (o) : FundamentalSequenceProp o (fundamentalSequence o) := by induction' o with a m b iha ihb; · exact rfl rw [fundamentalSequence] From a917edfde5e52d46c0cd003b4627ab8988270063 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Tue, 15 Oct 2024 14:56:13 +0000 Subject: [PATCH 152/425] chore(Analysis): remove `eqns` attribute (#17773) Mathlib builds fine if we remove this attribute, although the linter complains since the generated `match` lemmas overlap a bit. So we remove the attribute and add `@[simp]` attributes to the previous manual equation lemmas, instead of the `fpowerSeries` map itself. --- Mathlib/Analysis/Analytic/Linear.lean | 12 ++++-------- .../Analysis/Calculus/FormalMultilinearSeries.lean | 7 +++---- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/Mathlib/Analysis/Analytic/Linear.lean b/Mathlib/Analysis/Analytic/Linear.lean index e527cda45057c6..bd405daef58954 100644 --- a/Mathlib/Analysis/Analytic/Linear.lean +++ b/Mathlib/Analysis/Analytic/Linear.lean @@ -77,30 +77,26 @@ def fpowerSeriesBilinear (f : E →L[𝕜] F →L[𝕜] G) (x : E × F) : Formal | 2 => f.uncurryBilinear | _ => 0 +@[simp] theorem fpowerSeriesBilinear_apply_zero (f : E →L[𝕜] F →L[𝕜] G) (x : E × F) : fpowerSeriesBilinear f x 0 = ContinuousMultilinearMap.uncurry0 𝕜 _ (f x.1 x.2) := rfl +@[simp] theorem fpowerSeriesBilinear_apply_one (f : E →L[𝕜] F →L[𝕜] G) (x : E × F) : fpowerSeriesBilinear f x 1 = (continuousMultilinearCurryFin1 𝕜 (E × F) G).symm (f.deriv₂ x) := rfl +@[simp] theorem fpowerSeriesBilinear_apply_two (f : E →L[𝕜] F →L[𝕜] G) (x : E × F) : fpowerSeriesBilinear f x 2 = f.uncurryBilinear := rfl +@[simp] theorem fpowerSeriesBilinear_apply_add_three (f : E →L[𝕜] F →L[𝕜] G) (x : E × F) (n) : fpowerSeriesBilinear f x (n + 3) = 0 := rfl -attribute - [eqns - fpowerSeriesBilinear_apply_zero - fpowerSeriesBilinear_apply_one - fpowerSeriesBilinear_apply_two - fpowerSeriesBilinear_apply_add_three] fpowerSeriesBilinear -attribute [simp] fpowerSeriesBilinear - @[simp] theorem fpowerSeriesBilinear_radius (f : E →L[𝕜] F →L[𝕜] G) (x : E × F) : (f.fpowerSeriesBilinear x).radius = ∞ := diff --git a/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean b/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean index 06d42a093e0312..7de7ac12143697 100644 --- a/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean +++ b/Mathlib/Analysis/Calculus/FormalMultilinearSeries.lean @@ -360,21 +360,20 @@ def fpowerSeries (f : E →L[𝕜] F) (x : E) : FormalMultilinearSeries 𝕜 E F | 1 => (continuousMultilinearCurryFin1 𝕜 E F).symm f | _ => 0 +@[simp] theorem fpowerSeries_apply_zero (f : E →L[𝕜] F) (x : E) : f.fpowerSeries x 0 = ContinuousMultilinearMap.uncurry0 𝕜 _ (f x) := rfl +@[simp] theorem fpowerSeries_apply_one (f : E →L[𝕜] F) (x : E) : f.fpowerSeries x 1 = (continuousMultilinearCurryFin1 𝕜 E F).symm f := rfl +@[simp] theorem fpowerSeries_apply_add_two (f : E →L[𝕜] F) (x : E) (n : ℕ) : f.fpowerSeries x (n + 2) = 0 := rfl -attribute - [eqns fpowerSeries_apply_zero fpowerSeries_apply_one fpowerSeries_apply_add_two] fpowerSeries -attribute [simp] fpowerSeries - end ContinuousLinearMap end Linear From 1b5eaee6c30b1cbe7669e1c4c125eb11d21ef5e8 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Tue, 15 Oct 2024 14:56:14 +0000 Subject: [PATCH 153/425] chore(AlgebraicTopology): remove `eqns` attribute (#17774) This `eqns` does slightly change the generated lemmas: `objX.eq_2` talks about `n.succ` while `objX_add_one` talks about `n + 1`. Still, it's easy enough to replace the one failing unfold in a `rw` with a `rw [objX_add_one]`. --- Mathlib/AlgebraicTopology/AlternatingFaceMapComplex.lean | 2 +- Mathlib/AlgebraicTopology/MooreComplex.lean | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Mathlib/AlgebraicTopology/AlternatingFaceMapComplex.lean b/Mathlib/AlgebraicTopology/AlternatingFaceMapComplex.lean index de7b73ca2ffc3b..25c2c3588b0e9b 100644 --- a/Mathlib/AlgebraicTopology/AlternatingFaceMapComplex.lean +++ b/Mathlib/AlgebraicTopology/AlternatingFaceMapComplex.lean @@ -255,7 +255,7 @@ def inclusionOfMooreComplexMap (X : SimplicialObject A) : rw [Fin.sum_univ_succ, Fintype.sum_eq_zero] swap · intro j - rw [NormalizedMooreComplex.objX, comp_zsmul, + rw [NormalizedMooreComplex.objX_add_one, comp_zsmul, ← factorThru_arrow _ _ (finset_inf_arrow_factors Finset.univ _ _ (Finset.mem_univ j)), Category.assoc, kernelSubobject_arrow_comp, comp_zero, smul_zero] -- finally, we study the remaining term which is induced by X.δ 0 diff --git a/Mathlib/AlgebraicTopology/MooreComplex.lean b/Mathlib/AlgebraicTopology/MooreComplex.lean index 5ab0ded88a8b6b..0ce1710a542c89 100644 --- a/Mathlib/AlgebraicTopology/MooreComplex.lean +++ b/Mathlib/AlgebraicTopology/MooreComplex.lean @@ -59,16 +59,13 @@ def objX : ∀ n : ℕ, Subobject (X.obj (op (SimplexCategory.mk n))) | 0 => ⊤ | n + 1 => Finset.univ.inf fun k : Fin (n + 1) => kernelSubobject (X.δ k.succ) -theorem objX_zero : objX X 0 = ⊤ := +@[simp] theorem objX_zero : objX X 0 = ⊤ := rfl -theorem objX_add_one (n) : +@[simp] theorem objX_add_one (n) : objX X (n + 1) = Finset.univ.inf fun k : Fin (n + 1) => kernelSubobject (X.δ k.succ) := rfl -attribute [eqns objX_zero objX_add_one] objX -attribute [simp] objX - /-- The differentials in the normalized Moore complex. -/ @[simp] From b562c300b1aa371a31abd240d9695d0a2b32f380 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Tue, 15 Oct 2024 15:56:24 +0000 Subject: [PATCH 154/425] chore: move `Init.Data.Nat.Lemmas` to `Deprecated.NatLemmas` (#17770) The results in this file have been deprecated for a while and none seem to be used in Mathlib. So let's move everything to the `Deprecated` folder in order to empty out the `Init` folder. --- Mathlib.lean | 2 +- .../Data/Nat/Lemmas.lean => Deprecated/NatLemmas.lean} | 8 +++----- scripts/noshake.json | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) rename Mathlib/{Init/Data/Nat/Lemmas.lean => Deprecated/NatLemmas.lean} (83%) diff --git a/Mathlib.lean b/Mathlib.lean index 54521d3fb26f3c..e89693e2a71db8 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2657,6 +2657,7 @@ import Mathlib.Deprecated.Combinator import Mathlib.Deprecated.Equiv import Mathlib.Deprecated.Group import Mathlib.Deprecated.HashMap +import Mathlib.Deprecated.NatLemmas import Mathlib.Deprecated.RelClasses import Mathlib.Deprecated.Ring import Mathlib.Deprecated.Subfield @@ -2926,7 +2927,6 @@ import Mathlib.GroupTheory.Torsion import Mathlib.GroupTheory.Transfer import Mathlib.InformationTheory.Hamming import Mathlib.Init -import Mathlib.Init.Data.Nat.Lemmas import Mathlib.Init.Logic import Mathlib.Lean.CoreM import Mathlib.Lean.Elab.Tactic.Basic diff --git a/Mathlib/Init/Data/Nat/Lemmas.lean b/Mathlib/Deprecated/NatLemmas.lean similarity index 83% rename from Mathlib/Init/Data/Nat/Lemmas.lean rename to Mathlib/Deprecated/NatLemmas.lean index fe8bd94cacac29..37fd557b3fec3f 100644 --- a/Mathlib/Init/Data/Nat/Lemmas.lean +++ b/Mathlib/Deprecated/NatLemmas.lean @@ -8,12 +8,10 @@ import Mathlib.Util.AssertExists import Mathlib.Data.Nat.Notation /-! -# Note about `Mathlib/Init/` -The files in `Mathlib/Init` are leftovers from the port from Mathlib3. -(They contain content moved from lean3 itself that Mathlib needed but was not moved to lean4.) +# Note about deprecated files -We intend to move all the content of these files out into the main `Mathlib` directory structure. -Contributions assisting with this are appreciated. +This file is deprecated, and is no longer imported by anything in mathlib other than other +deprecated files, and test files. You should not need to import it. -/ assert_not_exists Preorder diff --git a/scripts/noshake.json b/scripts/noshake.json index ad486bd8e6ca49..44d4594c37546d 100644 --- a/scripts/noshake.json +++ b/scripts/noshake.json @@ -344,7 +344,7 @@ "Mathlib.Lean.Meta": ["Batteries.Logic"], "Mathlib.Lean.Expr.ExtraRecognizers": ["Mathlib.Data.Set.Operations"], "Mathlib.Lean.Expr.Basic": ["Batteries.Logic"], - "Mathlib.Init.Data.Nat.Lemmas": ["Batteries.Data.Nat.Lemmas", "Batteries.WF"], + "Mathlib.Deprecated.NatLemmas": ["Batteries.Data.Nat.Lemmas", "Batteries.WF"], "Mathlib.GroupTheory.MonoidLocalization.Basic": ["Mathlib.Init.Data.Prod"], "Mathlib.Geometry.Manifold.Sheaf.Smooth": ["Mathlib.CategoryTheory.Sites.Whiskering"], From b68a7e4eb5d4eb441afeb4dcec0028571e17cba9 Mon Sep 17 00:00:00 2001 From: damiano Date: Tue, 15 Oct 2024 15:56:25 +0000 Subject: [PATCH 155/425] chore: more unused variables (#17777) --- Mathlib/Algebra/BigOperators/Expect.lean | 10 +++++----- .../Algebra/Group/Pointwise/Finset/Basic.lean | 14 +++++++------- Mathlib/Algebra/Group/Units/Basic.lean | 8 ++++---- Mathlib/Algebra/Module/Submodule/Ker.lean | 17 +++++++---------- Mathlib/Analysis/Calculus/Deriv/Inverse.lean | 13 +++++-------- Mathlib/Analysis/Calculus/Deriv/Slope.lean | 15 ++++++--------- Mathlib/Analysis/Calculus/FDeriv/Add.lean | 14 +++++--------- Mathlib/Analysis/Calculus/FDeriv/Mul.lean | 14 ++++---------- Mathlib/Analysis/LocallyConvex/Basic.lean | 8 ++++---- .../NormedSpace/OperatorNorm/NormedSpace.lean | 19 ++++++++----------- Mathlib/CategoryTheory/Comma/Basic.lean | 2 +- Mathlib/LinearAlgebra/LinearIndependent.lean | 19 ++++++++----------- .../MetricSpace/HausdorffDimension.lean | 2 +- Mathlib/Topology/MetricSpace/HolderNorm.lean | 4 ++-- 14 files changed, 67 insertions(+), 92 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Expect.lean b/Mathlib/Algebra/BigOperators/Expect.lean index cf6a0e4d72664c..22969768a5f4f7 100644 --- a/Mathlib/Algebra/BigOperators/Expect.lean +++ b/Mathlib/Algebra/BigOperators/Expect.lean @@ -111,7 +111,7 @@ open scoped BigOperators namespace Finset section AddCommMonoid variable [AddCommMonoid M] [Module ℚ≥0 M] [AddCommMonoid N] [Module ℚ≥0 N] {s t : Finset ι} - {f g : ι → M} {m : N → M} {p q : ι → Prop} [DecidablePred p] [DecidablePred q] + {f g : ι → M} {p q : ι → Prop} [DecidablePred p] [DecidablePred q] lemma expect_univ [Fintype ι] : 𝔼 i, f i = (∑ i, f i) /ℚ Fintype.card ι := by rw [expect, card_univ] @@ -299,7 +299,7 @@ lemma smul_expect {G : Type*} [DistribSMul G M] [SMulCommClass G ℚ≥0 M] (a : end AddCommMonoid section AddCommGroup -variable [AddCommGroup M] [Module ℚ≥0 M] [Field N] [Module ℚ≥0 N] {s : Finset ι} +variable [AddCommGroup M] [Module ℚ≥0 M] lemma expect_sub_distrib (s : Finset ι) (f g : ι → M) : 𝔼 i ∈ s, (f i - g i) = 𝔼 i ∈ s, f i - 𝔼 i ∈ s, g i := by @@ -312,7 +312,7 @@ lemma expect_neg_distrib (s : Finset ι) (f : ι → M) : 𝔼 i ∈ s, -f i = - end AddCommGroup section Semiring -variable [Semiring M] [Module ℚ≥0 M] {s : Finset ι} {f g : ι → M} {m : N → M} +variable [Semiring M] [Module ℚ≥0 M] @[simp] lemma card_mul_expect (s : Finset ι) (f : ι → M) : s.card * 𝔼 i ∈ s, f i = ∑ i ∈ s, f i := by rw [← nsmul_eq_mul, card_smul_expect] @@ -344,7 +344,7 @@ lemma expect_pow (s : Finset ι) (f : ι → M) (n : ℕ) : end CommSemiring section Semifield -variable [Semifield M] [CharZero M] {s : Finset ι} {f g : ι → M} {m : N → M} +variable [Semifield M] [CharZero M] lemma expect_boole_mul [Fintype ι] [Nonempty ι] [DecidableEq ι] (f : ι → M) (i : ι) : 𝔼 j, ite (i = j) (Fintype.card ι : M) 0 * f j = f i := by @@ -387,7 +387,7 @@ namespace Fintype variable [Fintype ι] [Fintype κ] section AddCommMonoid -variable [AddCommMonoid M] [Module ℚ≥0 M] {f : ι → M} +variable [AddCommMonoid M] [Module ℚ≥0 M] /-- `Fintype.expect_bijective` is a variant of `Finset.expect_bij` that accepts `Function.Bijective`. diff --git a/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean b/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean index 7338d907b43604..c51cd98506df20 100644 --- a/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean +++ b/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean @@ -176,7 +176,7 @@ end One section Inv -variable [DecidableEq α] [Inv α] {s s₁ s₂ t t₁ t₂ u : Finset α} {a b : α} +variable [DecidableEq α] [Inv α] {s t : Finset α} {a : α} /-- The pointwise inversion of finset `s⁻¹` is defined as `{x⁻¹ | x ∈ s}` in locale `Pointwise`. -/ @[to_additive @@ -950,7 +950,7 @@ end Distrib section MulZeroClass -variable [MulZeroClass α] {s t : Finset α} +variable [MulZeroClass α] {s : Finset α} /-! Note that `Finset` is not a `MulZeroClass` because `0 * ∅ ≠ 0`. -/ @@ -1031,7 +1031,7 @@ end Group section GroupWithZero -variable [GroupWithZero α] {s t : Finset α} +variable [GroupWithZero α] {s : Finset α} theorem div_zero_subset (s : Finset α) : s / 0 ⊆ 0 := by simp [subset_iff, mem_div] @@ -1049,7 +1049,7 @@ end Instances section Group -variable [Group α] {s t : Finset α} {a b : α} +variable [Group α] {a b : α} @[to_additive (attr := simp)] theorem preimage_mul_left_singleton : @@ -1321,7 +1321,7 @@ open Pointwise section SMul -variable [DecidableEq β] [SMul α β] {s s₁ s₂ t u : Finset β} {a : α} {b : β} +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 "The translation of a finset `s` by a vector `a`: `a +ᵥ s = {a +ᵥ x | x ∈ s}`."] @@ -1793,7 +1793,7 @@ lemma Nonempty.zero_smul (ht : t.Nonempty) : (0 : Finset α) • t = 0 := lemma zero_smul_finset_subset (s : Finset β) : (0 : α) • s ⊆ 0 := image_subset_iff.2 fun x _ ↦ mem_zero.2 <| zero_smul α x -variable [NoZeroSMulDivisors α β] {a : α} +variable [NoZeroSMulDivisors α β] lemma zero_mem_smul_iff : (0 : β) ∈ s • t ↔ (0 : α) ∈ s ∧ t.Nonempty ∨ (0 : β) ∈ t ∧ s.Nonempty := by @@ -1990,7 +1990,7 @@ end Mul section SMul -variable [SMul α β] [DecidableEq β] {a : α} {s : Set α} {t : Set β} +variable [SMul α β] [DecidableEq β] {s : Set α} {t : Set β} @[to_additive (attr := simp)] theorem toFinset_smul (s : Set α) (t : Set β) [Fintype s] [Fintype t] [Fintype ↑(s • t)] : diff --git a/Mathlib/Algebra/Group/Units/Basic.lean b/Mathlib/Algebra/Group/Units/Basic.lean index 594ac233066ca6..3630673d90f593 100644 --- a/Mathlib/Algebra/Group/Units/Basic.lean +++ b/Mathlib/Algebra/Group/Units/Basic.lean @@ -45,7 +45,7 @@ namespace Units section Monoid variable [Monoid α] -variable (a b c : αˣ) {u : αˣ} +variable (b c : αˣ) {u : αˣ} @[to_additive (attr := simp)] theorem mul_inv_cancel_right (a : α) (b : αˣ) : a * b * ↑b⁻¹ = a := by @@ -125,7 +125,7 @@ end Units section Monoid -variable [Monoid α] {a : α} +variable [Monoid α] @[simp] theorem divp_left_inj (u : αˣ) {a b : α} : a /ₚ u = b /ₚ u ↔ a = b := @@ -265,7 +265,7 @@ end CommMonoid section IsUnit -variable {M : Type*} {N : Type*} +variable {M : Type*} @[to_additive (attr := nontriviality)] theorem isUnit_of_subsingleton [Monoid M] [Subsingleton M] (a : M) : IsUnit a := @@ -281,7 +281,7 @@ instance [Monoid M] [Subsingleton M] : Unique Mˣ where uniq _ := Units.val_eq_one.mp (by subsingleton) section Monoid -variable [Monoid M] {a b : M} +variable [Monoid M] theorem units_eq_one [Subsingleton Mˣ] (u : Mˣ) : u = 1 := by subsingleton diff --git a/Mathlib/Algebra/Module/Submodule/Ker.lean b/Mathlib/Algebra/Module/Submodule/Ker.lean index e329b35726b802..23ce2537e64cc8 100644 --- a/Mathlib/Algebra/Module/Submodule/Ker.lean +++ b/Mathlib/Algebra/Module/Submodule/Ker.lean @@ -29,7 +29,7 @@ open Function open Pointwise -variable {R : Type*} {R₁ : Type*} {R₂ : Type*} {R₃ : Type*} +variable {R : Type*} {R₂ : Type*} {R₃ : Type*} variable {K : Type*} variable {M : Type*} {M₁ : Type*} {M₂ : Type*} {M₃ : Type*} variable {V : Type*} {V₂ : Type*} @@ -43,13 +43,11 @@ section AddCommMonoid variable [Semiring R] [Semiring R₂] [Semiring R₃] variable [AddCommMonoid M] [AddCommMonoid M₂] [AddCommMonoid M₃] -variable {σ₁₂ : R →+* R₂} {σ₂₃ : R₂ →+* R₃} {σ₁₃ : R →+* R₃} -variable [RingHomCompTriple σ₁₂ σ₂₃ σ₁₃] variable [Module R M] [Module R₂ M₂] [Module R₃ M₃] open Submodule -variable {σ₂₁ : R₂ →+* R} {τ₁₂ : R →+* R₂} {τ₂₃ : R₂ →+* R₃} {τ₁₃ : R →+* R₃} +variable {τ₁₂ : R →+* R₂} {τ₂₃ : R₂ →+* R₃} {τ₁₃ : R →+* R₃} variable [RingHomCompTriple τ₁₂ τ₂₃ τ₁₃] variable {F : Type*} [FunLike F M M₂] [SemilinearMapClass F τ₁₂ M M₂] @@ -150,11 +148,10 @@ end AddCommMonoid section Ring -variable [Ring R] [Ring R₂] [Ring R₃] -variable [AddCommGroup M] [AddCommGroup M₂] [AddCommGroup M₃] -variable [Module R M] [Module R₂ M₂] [Module R₃ M₃] -variable {τ₁₂ : R →+* R₂} {τ₂₃ : R₂ →+* R₃} {τ₁₃ : R →+* R₃} -variable [RingHomCompTriple τ₁₂ τ₂₃ τ₁₃] +variable [Ring R] [Ring R₂] +variable [AddCommGroup M] [AddCommGroup M₂] +variable [Module R M] [Module R₂ M₂] +variable {τ₁₂ : R →+* R₂} variable {F : Type*} [FunLike F M M₂] [SemilinearMapClass F τ₁₂ M M₂] variable {f : F} @@ -227,7 +224,7 @@ section AddCommMonoid variable [Semiring R] [Semiring R₂] [AddCommMonoid M] [AddCommMonoid M₂] variable [Module R M] [Module R₂ M₂] -variable (p p' : Submodule R M) (q : Submodule R₂ M₂) +variable (p : Submodule R M) variable {τ₁₂ : R →+* R₂} variable {F : Type*} [FunLike F M M₂] [SemilinearMapClass F τ₁₂ M M₂] diff --git a/Mathlib/Analysis/Calculus/Deriv/Inverse.lean b/Mathlib/Analysis/Calculus/Deriv/Inverse.lean index 424877d8f983b5..226fea832b664f 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Inverse.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Inverse.lean @@ -22,19 +22,16 @@ derivative, inverse function -/ -universe u v w +universe u v -open scoped Classical Topology ENNReal -open Filter Asymptotics Set +open scoped Topology +open Filter Set variable {𝕜 : Type u} [NontriviallyNormedField 𝕜] variable {F : Type v} [NormedAddCommGroup F] [NormedSpace 𝕜 F] -variable {E : Type w} [NormedAddCommGroup E] [NormedSpace 𝕜 E] -variable {f f₀ f₁ g : 𝕜 → F} -variable {f' f₀' f₁' g' : F} +variable {f : 𝕜 → F} +variable {f' : F} variable {x : 𝕜} -variable {s t : Set 𝕜} -variable {L L₁ L₂ : Filter 𝕜} theorem HasStrictDerivAt.hasStrictFDerivAt_equiv {f : 𝕜 → 𝕜} {f' x : 𝕜} (hf : HasStrictDerivAt f f' x) (hf' : f' ≠ 0) : diff --git a/Mathlib/Analysis/Calculus/Deriv/Slope.lean b/Mathlib/Analysis/Calculus/Deriv/Slope.lean index 6ffd40c2005199..546d82ea875e71 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Slope.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Slope.lean @@ -25,23 +25,20 @@ derivative, slope -/ -universe u v w +universe u v -noncomputable section +open scoped Topology -open Topology Filter TopologicalSpace -open Filter Set +open Filter TopologicalSpace Set section NormedField variable {𝕜 : Type u} [NontriviallyNormedField 𝕜] variable {F : Type v} [NormedAddCommGroup F] [NormedSpace 𝕜 F] -variable {E : Type w} [NormedAddCommGroup E] [NormedSpace 𝕜 E] -variable {f f₀ f₁ g : 𝕜 → F} -variable {f' f₀' f₁' g' : F} +variable {f : 𝕜 → F} +variable {f' : F} variable {x : 𝕜} -variable {s t : Set 𝕜} -variable {L L₁ L₂ : Filter 𝕜} +variable {s : Set 𝕜} /-- If the domain has dimension one, then Fréchet derivative is equivalent to the classical definition with a limit. In this version we have to take the limit along the subset `-{x}`, diff --git a/Mathlib/Analysis/Calculus/FDeriv/Add.lean b/Mathlib/Analysis/Calculus/FDeriv/Add.lean index 18d203c64bd48b..f68849f4601a00 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Add.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Add.lean @@ -21,10 +21,9 @@ This file contains the usual formulas (and existence assertions) for the derivat -/ -open Filter Asymptotics ContinuousLinearMap Set Metric +open Filter Asymptotics ContinuousLinearMap open scoped Classical -open Topology NNReal Filter Asymptotics ENNReal noncomputable section @@ -33,14 +32,11 @@ section variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] -variable {G : Type*} [NormedAddCommGroup G] [NormedSpace 𝕜 G] -variable {G' : Type*} [NormedAddCommGroup G'] [NormedSpace 𝕜 G'] -variable {f f₀ f₁ g : E → F} -variable {f' f₀' f₁' g' : E →L[𝕜] F} -variable (e : E →L[𝕜] F) +variable {f g : E → F} +variable {f' g' : E →L[𝕜] F} variable {x : E} -variable {s t : Set E} -variable {L L₁ L₂ : Filter E} +variable {s : Set E} +variable {L : Filter E} section ConstSMul diff --git a/Mathlib/Analysis/Calculus/FDeriv/Mul.lean b/Mathlib/Analysis/Calculus/FDeriv/Mul.lean index 990bb02bd95999..a33ed2ab821e14 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Mul.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Mul.lean @@ -21,10 +21,7 @@ This file contains the usual formulas (and existence assertions) for the derivat -/ -open scoped Classical -open Filter Asymptotics ContinuousLinearMap Set Metric Topology NNReal ENNReal - -noncomputable section +open Asymptotics ContinuousLinearMap Topology section @@ -32,13 +29,10 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] variable {G : Type*} [NormedAddCommGroup G] [NormedSpace 𝕜 G] -variable {G' : Type*} [NormedAddCommGroup G'] [NormedSpace 𝕜 G'] -variable {f f₀ f₁ g : E → F} -variable {f' f₀' f₁' g' : E →L[𝕜] F} -variable (e : E →L[𝕜] F) +variable {f : E → F} +variable {f' : E →L[𝕜] F} variable {x : E} -variable {s t : Set E} -variable {L L₁ L₂ : Filter E} +variable {s : Set E} section CLMCompApply diff --git a/Mathlib/Analysis/LocallyConvex/Basic.lean b/Mathlib/Analysis/LocallyConvex/Basic.lean index 4b242d68099283..b8e661ddf003f1 100644 --- a/Mathlib/Analysis/LocallyConvex/Basic.lean +++ b/Mathlib/Analysis/LocallyConvex/Basic.lean @@ -50,7 +50,7 @@ variable [SeminormedRing 𝕜] section SMul -variable [SMul 𝕜 E] {s t u v A B : Set E} +variable [SMul 𝕜 E] {s A B : Set E} variable (𝕜) /-- A set `A` is balanced if `a • A` is contained in `A` whenever `a` has norm at most `1`. -/ @@ -111,7 +111,7 @@ end SMul section Module -variable [AddCommGroup E] [Module 𝕜 E] {s s₁ s₂ t t₁ t₂ : Set E} +variable [AddCommGroup E] [Module 𝕜 E] {s t : Set E} theorem Balanced.neg : Balanced 𝕜 s → Balanced 𝕜 (-s) := forall₂_imp fun _ _ h => (smul_set_neg _ _).subset.trans <| neg_subset_neg.2 h @@ -142,7 +142,7 @@ end SeminormedRing section NormedDivisionRing -variable [NormedDivisionRing 𝕜] [AddCommGroup E] [Module 𝕜 E] {s t : Set E} {x : E} {a b : 𝕜} +variable [NormedDivisionRing 𝕜] [AddCommGroup E] [Module 𝕜 E] {s t : Set E} theorem absorbs_iff_eventually_nhdsWithin_zero : Absorbs 𝕜 s t ↔ ∀ᶠ c : 𝕜 in 𝓝[≠] 0, MapsTo (c • ·) t s := by @@ -172,7 +172,7 @@ end NormedDivisionRing section NormedField variable [NormedField 𝕜] [NormedRing 𝕝] [NormedSpace 𝕜 𝕝] [AddCommGroup E] [Module 𝕜 E] - [SMulWithZero 𝕝 E] [IsScalarTower 𝕜 𝕝 E] {s t u v A B : Set E} {x : E} {a b : 𝕜} + [SMulWithZero 𝕝 E] [IsScalarTower 𝕜 𝕝 E] {s A : Set E} {x : E} {a b : 𝕜} /-- Scalar multiplication (by possibly different types) of a balanced set is monotone. -/ theorem Balanced.smul_mono (hs : Balanced 𝕝 s) {a : 𝕝} {b : 𝕜} (h : ‖a‖ ≤ ‖b‖) : a • s ⊆ b • s := by diff --git a/Mathlib/Analysis/NormedSpace/OperatorNorm/NormedSpace.lean b/Mathlib/Analysis/NormedSpace/OperatorNorm/NormedSpace.lean index 253805834044d7..27e0b924878499 100644 --- a/Mathlib/Analysis/NormedSpace/OperatorNorm/NormedSpace.lean +++ b/Mathlib/Analysis/NormedSpace/OperatorNorm/NormedSpace.lean @@ -16,12 +16,10 @@ underlying space has a norm (rather than just a seminorm). suppress_compilation -open Bornology -open Filter hiding map_smul -open scoped NNReal Topology Uniformity +open scoped NNReal Topology -- the `ₗ` subscript variables are for special cases about linear (as opposed to semilinear) maps -variable {𝕜 𝕜₂ 𝕜₃ E Eₗ F Fₗ G Gₗ 𝓕 : Type*} +variable {𝕜 𝕜₂ 𝕜₃ E F Fₗ G : Type*} section Normed @@ -34,8 +32,8 @@ open Metric ContinuousLinearMap section variable [NontriviallyNormedField 𝕜] [NontriviallyNormedField 𝕜₂] [NontriviallyNormedField 𝕜₃] - [NormedSpace 𝕜 E] [NormedSpace 𝕜₂ F] [NormedSpace 𝕜₃ G] [NormedSpace 𝕜 Fₗ] (c : 𝕜) - {σ₁₂ : 𝕜 →+* 𝕜₂} {σ₂₃ : 𝕜₂ →+* 𝕜₃} (f g : E →SL[σ₁₂] F) (x y z : E) + [NormedSpace 𝕜 E] [NormedSpace 𝕜₂ F] [NormedSpace 𝕜₃ G] [NormedSpace 𝕜 Fₗ] + {σ₁₂ : 𝕜 →+* 𝕜₂} {σ₂₃ : 𝕜₂ →+* 𝕜₃} (f : E →SL[σ₁₂] F) namespace LinearMap @@ -181,8 +179,8 @@ end namespace ContinuousLinearMap variable [NontriviallyNormedField 𝕜] [NontriviallyNormedField 𝕜₂] [NontriviallyNormedField 𝕜₃] - [NormedSpace 𝕜 E] [NormedSpace 𝕜₂ F] [NormedSpace 𝕜₃ G] [NormedSpace 𝕜 Fₗ] (c : 𝕜) - {σ₁₂ : 𝕜 →+* 𝕜₂} {σ₂₃ : 𝕜₂ →+* 𝕜₃} + [NormedSpace 𝕜 E] [NormedSpace 𝕜₂ F] [NormedSpace 𝕜₃ G] [NormedSpace 𝕜 Fₗ] + {σ₂₃ : 𝕜₂ →+* 𝕜₃} variable {𝕜₂' : Type*} [NontriviallyNormedField 𝕜₂'] {F' : Type*} [NormedAddCommGroup F'] [NormedSpace 𝕜₂' F'] {σ₂' : 𝕜₂' →+* 𝕜₂} {σ₂'' : 𝕜₂ →+* 𝕜₂'} {σ₂₃' : 𝕜₂' →+* 𝕜₃} @@ -229,8 +227,7 @@ end ContinuousLinearMap namespace Submodule -variable [NontriviallyNormedField 𝕜] [NontriviallyNormedField 𝕜₂] [NontriviallyNormedField 𝕜₃] - [NormedSpace 𝕜 E] [NormedSpace 𝕜₂ F] {σ₁₂ : 𝕜 →+* 𝕜₂} +variable [NontriviallyNormedField 𝕜] [NormedSpace 𝕜 E] theorem norm_subtypeL (K : Submodule 𝕜 E) [Nontrivial K] : ‖K.subtypeL‖ = 1 := K.subtypeₗᵢ.norm_toContinuousLinearMap @@ -239,7 +236,7 @@ end Submodule namespace ContinuousLinearEquiv -variable [NontriviallyNormedField 𝕜] [NontriviallyNormedField 𝕜₂] [NontriviallyNormedField 𝕜₃] +variable [NontriviallyNormedField 𝕜] [NontriviallyNormedField 𝕜₂] [NormedSpace 𝕜 E] [NormedSpace 𝕜₂ F] {σ₁₂ : 𝕜 →+* 𝕜₂} {σ₂₁ : 𝕜₂ →+* 𝕜} [RingHomInvPair σ₁₂ σ₂₁] [RingHomInvPair σ₂₁ σ₁₂] diff --git a/Mathlib/CategoryTheory/Comma/Basic.lean b/Mathlib/CategoryTheory/Comma/Basic.lean index c88e7997a1eebf..8cff758d674631 100644 --- a/Mathlib/CategoryTheory/Comma/Basic.lean +++ b/Mathlib/CategoryTheory/Comma/Basic.lean @@ -363,7 +363,7 @@ end section -variable {C : Type u₄} [Category.{v₄} C] {D : Type u₅} [Category.{v₅} D] +variable {C : Type u₄} [Category.{v₄} C] /-- The functor `(F ⋙ L, R) ⥤ (L, R)` -/ @[simps] diff --git a/Mathlib/LinearAlgebra/LinearIndependent.lean b/Mathlib/LinearAlgebra/LinearIndependent.lean index 4b279b9b0bd229..c198ef6a8918de 100644 --- a/Mathlib/LinearAlgebra/LinearIndependent.lean +++ b/Mathlib/LinearAlgebra/LinearIndependent.lean @@ -86,14 +86,13 @@ open Cardinal universe u' u variable {ι : Type u'} {ι' : Type*} {R : Type*} {K : Type*} -variable {M : Type*} {M' M'' : Type*} {V : Type u} {V' : Type*} +variable {M : Type*} {M' : Type*} {V : Type u} section Module variable {v : ι → M} -variable [Semiring R] [AddCommMonoid M] [AddCommMonoid M'] [AddCommMonoid M''] -variable [Module R M] [Module R M'] [Module R M''] -variable {a b : R} {x y : M} +variable [Semiring R] [AddCommMonoid M] [AddCommMonoid M'] +variable [Module R M] [Module R M'] variable (R) (v) /-- `LinearIndependent R v` states the family of vectors `v` is linearly independent over `R`. -/ @@ -515,9 +514,8 @@ end Module section Module variable {v : ι → M} -variable [Ring R] [AddCommGroup M] [AddCommGroup M'] [AddCommGroup M''] -variable [Module R M] [Module R M'] [Module R M''] -variable {a b : R} {x y : M} +variable [Ring R] [AddCommGroup M] [AddCommGroup M'] +variable [Module R M] [Module R M'] theorem linearIndependent_iff_injective_linearCombination : LinearIndependent R v ↔ Function.Injective (Finsupp.linearCombination R v) := @@ -1187,7 +1185,7 @@ section Nontrivial variable [Ring R] [Nontrivial R] [AddCommGroup M] [AddCommGroup M'] variable [Module R M] [NoZeroSMulDivisors R M] [Module R M'] -variable {v : ι → M} {s t : Set M} {x y z : M} +variable {s t : Set M} theorem linearIndependent_unique_iff (v : ι → M) [Unique ι] : LinearIndependent R v ↔ v default ≠ 0 := by @@ -1213,9 +1211,8 @@ These can be considered generalizations of properties of linear independence in section Module -variable [DivisionRing K] [AddCommGroup V] [AddCommGroup V'] -variable [Module K V] [Module K V'] -variable {v : ι → V} {s t : Set V} {x y z : V} +variable [DivisionRing K] [AddCommGroup V] [Module K V] +variable {v : ι → V} {s t : Set V} {x y : V} open Submodule diff --git a/Mathlib/Topology/MetricSpace/HausdorffDimension.lean b/Mathlib/Topology/MetricSpace/HausdorffDimension.lean index 46a5798a92a077..eba2e6682959fc 100644 --- a/Mathlib/Topology/MetricSpace/HausdorffDimension.lean +++ b/Mathlib/Topology/MetricSpace/HausdorffDimension.lean @@ -254,7 +254,7 @@ end -/ -variable {C K r : ℝ≥0} {f : X → Y} {s t : Set X} +variable {C K r : ℝ≥0} {f : X → Y} {s : Set X} /-- If `f` is a Hölder continuous map with exponent `r > 0`, then `dimH (f '' s) ≤ dimH s / r`. -/ theorem HolderOnWith.dimH_image_le (h : HolderOnWith C r f s) (hr : 0 < r) : diff --git a/Mathlib/Topology/MetricSpace/HolderNorm.lean b/Mathlib/Topology/MetricSpace/HolderNorm.lean index 2081edf7d838d3..864d59f082ad44 100644 --- a/Mathlib/Topology/MetricSpace/HolderNorm.lean +++ b/Mathlib/Topology/MetricSpace/HolderNorm.lean @@ -30,7 +30,7 @@ Hölder norm, Hoelder norm, Holder norm -/ -variable {X Y Z : Type*} +variable {X Y : Type*} open Filter Set @@ -196,7 +196,7 @@ end MetricSpace section SeminormedAddCommGroup variable [MetricSpace X] [NormedAddCommGroup Y] -variable {C r : ℝ≥0} {f g : X → Y} +variable {r : ℝ≥0} {f g : X → Y} lemma MemHolder.add (hf : MemHolder r f) (hg : MemHolder r g) : MemHolder r (f + g) := (hf.holderWith.add hg.holderWith).memHolder From a5f83b52871c5420ee5ca4eaebcfa8b1e37663b5 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Tue, 15 Oct 2024 16:48:49 +0000 Subject: [PATCH 156/425] chore: split off `Rat`-based functions from `Mathlib.Lean.Expr.Basic` (#17778) Basic functions for working with expressions don't need to know about the rational numbers. (I checked this manually since `assert_not_exists` ins't imported here yet!) --- Mathlib.lean | 1 + Mathlib/Data/Nat/GCD/Basic.lean | 1 + Mathlib/Data/Nat/GCD/BigOperators.lean | 1 + Mathlib/Data/Nat/Prime/Defs.lean | 1 + Mathlib/Lean/Expr/Basic.lean | 34 -------------- Mathlib/Lean/Expr/Rat.lean | 56 +++++++++++++++++++++++ Mathlib/Tactic/NormNum/Core.lean | 1 + Mathlib/Testing/SlimCheck/Sampleable.lean | 1 + 8 files changed, 62 insertions(+), 34 deletions(-) create mode 100644 Mathlib/Lean/Expr/Rat.lean diff --git a/Mathlib.lean b/Mathlib.lean index e89693e2a71db8..26c0f12b2cf585 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2936,6 +2936,7 @@ import Mathlib.Lean.Exception import Mathlib.Lean.Expr import Mathlib.Lean.Expr.Basic import Mathlib.Lean.Expr.ExtraRecognizers +import Mathlib.Lean.Expr.Rat import Mathlib.Lean.Expr.ReplaceRec import Mathlib.Lean.GoalsLocation import Mathlib.Lean.Json diff --git a/Mathlib/Data/Nat/GCD/Basic.lean b/Mathlib/Data/Nat/GCD/Basic.lean index 8d4d667ffa251f..ff926c64b40058 100644 --- a/Mathlib/Data/Nat/GCD/Basic.lean +++ b/Mathlib/Data/Nat/GCD/Basic.lean @@ -3,6 +3,7 @@ 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 -/ +import Batteries.Data.Nat.Gcd import Mathlib.Algebra.GroupWithZero.Divisibility import Mathlib.Algebra.Ring.Nat diff --git a/Mathlib/Data/Nat/GCD/BigOperators.lean b/Mathlib/Data/Nat/GCD/BigOperators.lean index 279f92b1b9c530..ced2ef1aa916bf 100644 --- a/Mathlib/Data/Nat/GCD/BigOperators.lean +++ b/Mathlib/Data/Nat/GCD/BigOperators.lean @@ -3,6 +3,7 @@ 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 -/ +import Batteries.Data.Nat.Gcd import Mathlib.Algebra.BigOperators.Group.Finset /-! # Lemmas about coprimality with big products. diff --git a/Mathlib/Data/Nat/Prime/Defs.lean b/Mathlib/Data/Nat/Prime/Defs.lean index 67e72199f933ab..638f139f80dd6f 100644 --- a/Mathlib/Data/Nat/Prime/Defs.lean +++ b/Mathlib/Data/Nat/Prime/Defs.lean @@ -3,6 +3,7 @@ Copyright (c) 2015 Microsoft Corporation. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Leonardo de Moura, Jeremy Avigad, Mario Carneiro -/ +import Batteries.Data.Nat.Gcd import Mathlib.Algebra.Associated.Basic import Mathlib.Algebra.Ring.Parity diff --git a/Mathlib/Lean/Expr/Basic.lean b/Mathlib/Lean/Expr/Basic.lean index 5991b427482937..02701a1fb4c6db 100644 --- a/Mathlib/Lean/Expr/Basic.lean +++ b/Mathlib/Lean/Expr/Basic.lean @@ -7,7 +7,6 @@ Floris van Doorn, Edward Ayers, Arthur Paulino import Mathlib.Init import Lean.Meta.Tactic.Rewrite import Batteries.Lean.Expr -import Batteries.Data.Rat.Basic import Batteries.Tactic.Alias import Lean.Elab.Binders @@ -205,39 +204,6 @@ def eraseProofs (e : Expr) : MetaM Expr := else return .continue) -/-- -Check if an expression is a "rational in normal form", -i.e. either an integer number in normal form, -or `n / d` where `n` is an integer in normal form, `d` is a natural number in normal form, -`d ≠ 1`, and `n` and `d` are coprime (in particular, we check that `(mkRat n d).den = d`). -If so returns the rational number. --/ -def rat? (e : Expr) : Option Rat := do - if e.isAppOfArity ``Div.div 4 then - let d ← e.appArg!.nat? - guard (d ≠ 1) - let n ← e.appFn!.appArg!.int? - let q := mkRat n d - guard (q.den = d) - pure q - else - e.int? - -/-- -Test if an expression represents an explicit number written in normal form: -* A "natural number in normal form" is an expression `OfNat.ofNat n`, even if it is not of type `ℕ`, - as long as `n` is a literal. -* An "integer in normal form" is an expression which is either a natural number in number form, - or `-n`, where `n` is a natural number in normal form. -* A "rational in normal form" is an expressions which is either an integer in normal form, - or `n / d` where `n` is an integer in normal form, `d` is a natural number in normal form, - `d ≠ 1`, and `n` and `d` are coprime (in particular, we check that `(mkRat n d).den = d`). --/ -def isExplicitNumber : Expr → Bool - | .lit _ => true - | .mdata _ e => isExplicitNumber e - | e => e.rat?.isSome - /-- If an `Expr` has form `.fvar n`, then returns `some n`, otherwise `none`. -/ def fvarId? : Expr → Option FVarId | .fvar n => n diff --git a/Mathlib/Lean/Expr/Rat.lean b/Mathlib/Lean/Expr/Rat.lean new file mode 100644 index 00000000000000..7eb5996b72aa55 --- /dev/null +++ b/Mathlib/Lean/Expr/Rat.lean @@ -0,0 +1,56 @@ +/- +Copyright (c) 2019 Robert Y. Lewis. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Mario Carneiro, Kim Morrison +-/ +import Mathlib.Init +import Batteries.Data.Rat.Basic +import Batteries.Tactic.Alias + +/-! +# Additional operations on Expr and rational numbers + +This file defines some operations involving `Expr` and rational numbers. + +## Main definitions + + * `Lean.Expr.isExplicitNumber`: is an expression a number in normal form? + This includes natural numbers, integers and rationals. +-/ + +namespace Lean.Expr + +/-- +Check if an expression is a "rational in normal form", +i.e. either an integer number in normal form, +or `n / d` where `n` is an integer in normal form, `d` is a natural number in normal form, +`d ≠ 1`, and `n` and `d` are coprime (in particular, we check that `(mkRat n d).den = d`). +If so returns the rational number. +-/ +def rat? (e : Expr) : Option Rat := do + if e.isAppOfArity ``Div.div 4 then + let d ← e.appArg!.nat? + guard (d ≠ 1) + let n ← e.appFn!.appArg!.int? + let q := mkRat n d + guard (q.den = d) + pure q + else + e.int? + +/-- +Test if an expression represents an explicit number written in normal form: +* A "natural number in normal form" is an expression `OfNat.ofNat n`, even if it is not of type `ℕ`, + as long as `n` is a literal. +* An "integer in normal form" is an expression which is either a natural number in number form, + or `-n`, where `n` is a natural number in normal form. +* A "rational in normal form" is an expressions which is either an integer in normal form, + or `n / d` where `n` is an integer in normal form, `d` is a natural number in normal form, + `d ≠ 1`, and `n` and `d` are coprime (in particular, we check that `(mkRat n d).den = d`). +-/ +def isExplicitNumber : Expr → Bool + | .lit _ => true + | .mdata _ e => isExplicitNumber e + | e => e.rat?.isSome + +end Lean.Expr diff --git a/Mathlib/Tactic/NormNum/Core.lean b/Mathlib/Tactic/NormNum/Core.lean index 2c3834acb555fb..0c2aec57cf959d 100644 --- a/Mathlib/Tactic/NormNum/Core.lean +++ b/Mathlib/Tactic/NormNum/Core.lean @@ -3,6 +3,7 @@ Copyright (c) 2022 Mario Carneiro. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Mario Carneiro -/ +import Mathlib.Lean.Expr.Rat import Mathlib.Tactic.NormNum.Result import Mathlib.Util.Qq import Lean.Elab.Tactic.Location diff --git a/Mathlib/Testing/SlimCheck/Sampleable.lean b/Mathlib/Testing/SlimCheck/Sampleable.lean index f5cedcf3cb6807..96f6e2b638df69 100644 --- a/Mathlib/Testing/SlimCheck/Sampleable.lean +++ b/Mathlib/Testing/SlimCheck/Sampleable.lean @@ -3,6 +3,7 @@ Copyright (c) 2022 Henrik Böving. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Henrik Böving, Simon Hudon -/ +import Batteries.Data.Rat.Basic import Mathlib.Algebra.Order.Ring.Int import Mathlib.Data.List.Monad import Mathlib.Testing.SlimCheck.Gen From f0db54da200b24b2c0584268e17b63d78f5f1690 Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Tue, 15 Oct 2024 17:24:34 +0000 Subject: [PATCH 157/425] Trigger CI for https://github.com/leanprover/lean4/pull/5720 --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 31e3bec7909930..8f8f129413a594 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "deeb06d863e8b08dc053b6fb9c1078ec53235061", + "rev": "0ff2d7ddbdfba09d910317fda5103a826dfd9ccb", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "lean-pr-testing-5720", From a4dc2792719f61a29392c8e80fb34cb116c43a65 Mon Sep 17 00:00:00 2001 From: YnirPaz Date: Tue, 15 Oct 2024 17:51:50 +0000 Subject: [PATCH 158/425] refactor(SetTheory/Ordinal/Arithmetic): generalize universes of iSup theorems (#16996) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generalize the universes of `iSup` theorems. Co-authored-by: Violeta Hernández --- Mathlib/SetTheory/Ordinal/Arithmetic.lean | 54 +++++++++++----------- Mathlib/SetTheory/Ordinal/Exponential.lean | 3 +- Mathlib/SetTheory/Ordinal/FixedPoint.lean | 8 ++-- Mathlib/SetTheory/ZFC/Rank.lean | 8 ++-- 4 files changed, 36 insertions(+), 37 deletions(-) diff --git a/Mathlib/SetTheory/Ordinal/Arithmetic.lean b/Mathlib/SetTheory/Ordinal/Arithmetic.lean index 85687f4ba62929..7c37366aa8dd13 100644 --- a/Mathlib/SetTheory/Ordinal/Arithmetic.lean +++ b/Mathlib/SetTheory/Ordinal/Arithmetic.lean @@ -6,6 +6,7 @@ Authors: Mario Carneiro, Floris van Doorn, Violeta Hernández Palacios import Mathlib.SetTheory.Ordinal.Basic import Mathlib.Data.Nat.SuccPred import Mathlib.Algebra.GroupWithZero.Divisibility +import Mathlib.Logic.UnivLE /-! # Ordinal arithmetic @@ -1167,27 +1168,38 @@ theorem bddAbove_range {ι : Type u} (f : ι → Ordinal.{max u v}) : BddAbove ( exact le_of_lt (Cardinal.lt_ord.2 ((lt_succ _).trans_le (le_ciSup (Cardinal.bddAbove_range.{_, v} _) _)))⟩ -/-- `le_ciSup` whenever the outputs live in a higher universe than the inputs. -/ -protected theorem le_iSup {ι : Type u} (f : ι → Ordinal.{max u v}) : ∀ i, f i ≤ iSup f := - le_ciSup (bddAbove_range f) +theorem bddAbove_of_small (s : Set Ordinal.{u}) [h : Small.{u} s] : BddAbove s := by + obtain ⟨a, ha⟩ := bddAbove_range (fun x => ((@equivShrink s h).symm x).val) + use a + intro b hb + simpa using ha (mem_range_self (equivShrink s ⟨b, hb⟩)) + +theorem bddAbove_iff_small {s : Set Ordinal.{u}} : BddAbove s ↔ Small.{u} s := + ⟨fun ⟨a, h⟩ => small_subset <| show s ⊆ Iic a from fun _ hx => h hx, fun _ => + bddAbove_of_small _⟩ + +/-- `le_ciSup` whenever the input type is small in the output universe. This lemma sometimes +fails to infer `f` in simple cases and needs it to be given explicitly. -/ +protected theorem le_iSup {ι} (f : ι → Ordinal.{u}) [Small.{u} ι] : ∀ i, f i ≤ iSup f := + le_ciSup (bddAbove_of_small _) set_option linter.deprecated false in @[deprecated Ordinal.le_iSup (since := "2024-08-27")] theorem le_sup {ι : Type u} (f : ι → Ordinal.{max u v}) : ∀ i, f i ≤ sup.{_, v} f := fun i => Ordinal.le_iSup f i -/-- `ciSup_le_iff'` whenever the outputs live in a higher universe than the inputs. -/ -protected theorem iSup_le_iff {ι : Type u} {f : ι → Ordinal.{max u v}} {a} : +/-- `ciSup_le_iff'` whenever the input type is small in the output universe. -/ +protected theorem iSup_le_iff {ι} {f : ι → Ordinal.{u}} {a : Ordinal.{u}} [Small.{u} ι] : iSup f ≤ a ↔ ∀ i, f i ≤ a := - ciSup_le_iff' (bddAbove_range f) + ciSup_le_iff' (bddAbove_of_small _) set_option linter.deprecated false in @[deprecated Ordinal.iSup_le_iff (since := "2024-08-27")] theorem sup_le_iff {ι : Type u} {f : ι → Ordinal.{max u v}} {a} : sup.{_, v} f ≤ a ↔ ∀ i, f i ≤ a := Ordinal.iSup_le_iff -/-- `ciSup_le'` whenever the outputs live in a higher universe than the inputs. -/ -protected theorem iSup_le {ι : Type u} {f : ι → Ordinal.{max u v}} {a} : +/-- `ciSup_le'` whenever the input type is small in the output universe. -/ +protected theorem iSup_le {ι} {f : ι → Ordinal.{u}} {a} : (∀ i, f i ≤ a) → iSup f ≤ a := ciSup_le' @@ -1197,7 +1209,7 @@ theorem sup_le {ι : Type u} {f : ι → Ordinal.{max u v}} {a} : (∀ i, f i Ordinal.iSup_le -- TODO: generalize to conditionally complete linear orders. -protected theorem lt_iSup {ι : Type u} {f : ι → Ordinal.{max u v}} {a} : +protected theorem lt_iSup {ι} {f : ι → Ordinal.{u}} {a : Ordinal.{u}} [Small.{u} ι] : a < iSup f ↔ ∃ i, a < f i := by rw [← not_iff_not] simpa using Ordinal.iSup_le_iff @@ -1219,7 +1231,7 @@ theorem ne_sup_iff_lt_sup {ι : Type u} {f : ι → Ordinal.{max u v}} : ne_iSup_iff_lt_iSup -- TODO: state in terms of `IsSuccLimit`. -theorem succ_lt_iSup_of_ne_iSup {ι : Type u} {f : ι → Ordinal.{max u v}} +theorem succ_lt_iSup_of_ne_iSup {ι} {f : ι → Ordinal.{u}} [Small.{u} ι] (hf : ∀ i, f i ≠ iSup f) {a} (hao : a < iSup f) : succ a < iSup f := by by_contra! hoa exact hao.not_le (Ordinal.iSup_le fun i => le_of_lt_succ <| @@ -1234,7 +1246,7 @@ theorem sup_not_succ_of_ne_sup {ι : Type u} {f : ι → Ordinal.{max u v}} hao.not_le (sup_le fun i => le_of_lt_succ <| (lt_of_le_of_ne (le_sup _ _) (hf i)).trans_le hoa) -- TODO: generalize to conditionally complete lattices. -theorem iSup_eq_zero_iff {ι : Type u} {f : ι → Ordinal.{max u v}} : +theorem iSup_eq_zero_iff {ι} {f : ι → Ordinal.{u}} [Small.{u} ι] : iSup f = 0 ↔ ∀ i, f i = 0 := by refine ⟨fun h i => ?_, fun h => @@ -1304,14 +1316,14 @@ theorem sup_eq_of_range_eq {ι : Type u} {ι' : Type v} Ordinal.iSup_eq_of_range_eq h -- TODO: generalize to conditionally complete lattices -theorem iSup_sum {α : Type u} {β : Type v} (f : α ⊕ β → Ordinal.{max u v w}) : +theorem iSup_sum {α β} (f : α ⊕ β → Ordinal.{u}) [Small.{u} α] [Small.{u} β]: iSup f = max (⨆ a, f (Sum.inl a)) (⨆ b, f (Sum.inr b)) := by apply (Ordinal.iSup_le _).antisymm (max_le _ _) · rintro (i | i) - · exact le_max_of_le_left (Ordinal.le_iSup.{u, max u v w} _ i) - · exact le_max_of_le_right (Ordinal.le_iSup.{v, max u v w} _ i) + · exact le_max_of_le_left (Ordinal.le_iSup (fun x ↦ f (Sum.inl x)) i) + · exact le_max_of_le_right (Ordinal.le_iSup (fun x ↦ f (Sum.inr x)) i) all_goals - apply csSup_le_csSup' (bddAbove_range _) + apply csSup_le_csSup' (bddAbove_of_small _) rintro i ⟨a, rfl⟩ apply mem_range_self @@ -1349,18 +1361,6 @@ theorem le_sup_shrink_equiv {s : Set Ordinal.{u}} (hs : Small.{u} s) (a) (ha : a convert le_sup.{u, u} (fun x => ((@equivShrink s hs).symm x).val) ((@equivShrink s hs) ⟨a, ha⟩) rw [symm_apply_apply] --- TODO: move this together with `bddAbove_range`. - -theorem bddAbove_of_small (s : Set Ordinal.{u}) [h : Small.{u} s] : BddAbove s := by - obtain ⟨a, ha⟩ := bddAbove_range (fun x => ((@equivShrink s h).symm x).val) - use a - intro b hb - simpa using ha (mem_range_self (equivShrink s ⟨b, hb⟩)) - -theorem bddAbove_iff_small {s : Set Ordinal.{u}} : BddAbove s ↔ Small.{u} s := - ⟨fun ⟨a, h⟩ => small_subset <| show s ⊆ Iic a from fun _ hx => h hx, fun _ => - bddAbove_of_small _⟩ - set_option linter.deprecated false in @[deprecated (since := "2024-08-27")] theorem sup_eq_sSup {s : Set Ordinal.{u}} (hs : Small.{u} s) : diff --git a/Mathlib/SetTheory/Ordinal/Exponential.lean b/Mathlib/SetTheory/Ordinal/Exponential.lean index cfc85d758a4995..902f6a296c0359 100644 --- a/Mathlib/SetTheory/Ordinal/Exponential.lean +++ b/Mathlib/SetTheory/Ordinal/Exponential.lean @@ -493,8 +493,7 @@ theorem iSup_pow {o : Ordinal} (ho : 0 < o) : ⨆ n : ℕ, o ^ n = o ^ ω := by · exact (isNormal_opow ho₁).apply_omega0 · rw [one_opow] refine le_antisymm (Ordinal.iSup_le fun n => by rw [one_opow]) ?_ - convert Ordinal.le_iSup _ 0 - rw [Nat.cast_zero, opow_zero] + exact_mod_cast Ordinal.le_iSup _ 0 set_option linter.deprecated false in @[deprecated iSup_pow (since := "2024-08-27")] diff --git a/Mathlib/SetTheory/Ordinal/FixedPoint.lean b/Mathlib/SetTheory/Ordinal/FixedPoint.lean index 4af5b1ee190ea9..d9f8f5bb5f7f8c 100644 --- a/Mathlib/SetTheory/Ordinal/FixedPoint.lean +++ b/Mathlib/SetTheory/Ordinal/FixedPoint.lean @@ -60,7 +60,7 @@ theorem foldr_le_nfpFamily (f : ι → Ordinal → Ordinal) Ordinal.le_iSup _ _ theorem le_nfpFamily (f : ι → Ordinal → Ordinal) (a) : a ≤ nfpFamily f a := - Ordinal.le_iSup _ [] + Ordinal.le_iSup (fun _ ↦ List.foldr _ a _) [] theorem lt_nfpFamily {a b} : a < nfpFamily.{u, v} f b ↔ ∃ l, a < List.foldr f b l := Ordinal.lt_iSup @@ -253,7 +253,7 @@ theorem foldr_le_nfpBFamily {o : Ordinal} theorem le_nfpBFamily {o : Ordinal} (f : ∀ b < o, Ordinal → Ordinal) (a) : a ≤ nfpBFamily.{u, v} o f a := - Ordinal.le_iSup _ [] + Ordinal.le_iSup (fun _ ↦ List.foldr _ a _) [] theorem lt_nfpBFamily {a b} : a < nfpBFamily.{u, v} o f b ↔ ∃ l, a < List.foldr (familyOfBFamily o f) b l := @@ -265,7 +265,7 @@ theorem nfpBFamily_le_iff {o : Ordinal} {f : ∀ b < o, Ordinal → Ordinal} {a theorem nfpBFamily_le {o : Ordinal} {f : ∀ b < o, Ordinal → Ordinal} {a b} : (∀ l, List.foldr (familyOfBFamily o f) a l ≤ b) → nfpBFamily.{u, v} o f a ≤ b := - Ordinal.iSup_le.{u, v} + Ordinal.iSup_le theorem nfpBFamily_monotone (hf : ∀ i hi, Monotone (f i hi)) : Monotone (nfpBFamily.{u, v} o f) := nfpFamily_monotone fun _ => hf _ _ @@ -422,7 +422,7 @@ theorem sup_iterate_eq_nfp (f : Ordinal.{u} → Ordinal.{u}) (a : Ordinal.{u}) : theorem iterate_le_nfp (f a n) : f^[n] a ≤ nfp f a := by rw [← iSup_iterate_eq_nfp] - exact Ordinal.le_iSup _ n + exact Ordinal.le_iSup (fun n ↦ f^[n] a) n theorem le_nfp (f a) : a ≤ nfp f a := iterate_le_nfp f a 0 diff --git a/Mathlib/SetTheory/ZFC/Rank.lean b/Mathlib/SetTheory/ZFC/Rank.lean index 2cecc412eaa354..a537948adaba89 100644 --- a/Mathlib/SetTheory/ZFC/Rank.lean +++ b/Mathlib/SetTheory/ZFC/Rank.lean @@ -114,10 +114,10 @@ theorem rank_eq_wfRank : lift.{u + 1, u} (rank x) = mem_wf.rank x := by induction' x using mem_wf.induction with x ih rw [mem_wf.rank_eq] simp_rw [← fun y : { y // y ∈ x } => ih y y.2] - apply (le_of_forall_lt _).antisymm (Ordinal.iSup_le.{u + 1, u} _) <;> intro h + apply (le_of_forall_lt _).antisymm (Ordinal.iSup_le _) <;> intro h · rw [lt_lift_iff] rintro ⟨o, rfl, h⟩ - simpa [Ordinal.lt_iSup.{u + 1, u}] using lt_rank_iff.1 h + simpa [Ordinal.lt_iSup] using lt_rank_iff.1 h · simpa using rank_lt_of_mem h.2 end PSet @@ -200,10 +200,10 @@ theorem rank_eq_wfRank : lift.{u + 1, u} (rank x) = mem_wf.rank x := by induction' x using inductionOn with x ih rw [mem_wf.rank_eq] simp_rw [← fun y : { y // y ∈ x } => ih y y.2] - apply (le_of_forall_lt _).antisymm (Ordinal.iSup_le.{u + 1, u} _) <;> intro h + apply (le_of_forall_lt _).antisymm (Ordinal.iSup_le _) <;> intro h · rw [lt_lift_iff] rintro ⟨o, rfl, h⟩ - simpa [Ordinal.lt_iSup.{u + 1, u}] using lt_rank_iff.1 h + simpa [Ordinal.lt_iSup] using lt_rank_iff.1 h · simpa using rank_lt_of_mem h.2 end ZFSet From cc1693f9891a89b1836cfd5d8f279cfec2557774 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Tue, 15 Oct 2024 17:51:51 +0000 Subject: [PATCH 159/425] feat(SetTheory/ZFC/Basic): add `IsWellFounded` instances (#17683) This allows the `IsAsymm` and `IsIrrefl` instances to be deduced automatically. --- Mathlib/SetTheory/ZFC/Basic.lean | 41 ++++++++++++-------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/Mathlib/SetTheory/ZFC/Basic.lean b/Mathlib/SetTheory/ZFC/Basic.lean index bbfd6ee8f1eac5..788bd0c5e01389 100644 --- a/Mathlib/SetTheory/ZFC/Basic.lean +++ b/Mathlib/SetTheory/ZFC/Basic.lean @@ -250,20 +250,17 @@ private theorem mem_wf_aux : ∀ {x y : PSet.{u}}, Equiv x y → Acc (· ∈ ·) theorem mem_wf : @WellFounded PSet (· ∈ ·) := ⟨fun x => mem_wf_aux <| Equiv.refl x⟩ +instance : IsWellFounded PSet (· ∈ ·) := + ⟨mem_wf⟩ + instance : WellFoundedRelation PSet := ⟨_, mem_wf⟩ -instance : IsAsymm PSet (· ∈ ·) := - mem_wf.isAsymm - -instance : IsIrrefl PSet (· ∈ ·) := - mem_wf.isIrrefl - theorem mem_asymm {x y : PSet} : x ∈ y → y ∉ x := - asymm (r := (· ∈ ·)) + asymm_of (· ∈ ·) theorem mem_irrefl (x : PSet) : x ∉ x := - irrefl (r := (· ∈ ·)) x + irrefl_of (· ∈ ·) x /-- Convert a pre-set to a `Set` of pre-sets. -/ def toSet (u : PSet.{u}) : Set PSet.{u} := @@ -1017,21 +1014,17 @@ theorem mem_wf : @WellFounded ZFSet (· ∈ ·) := theorem inductionOn {p : ZFSet → Prop} (x) (h : ∀ x, (∀ y ∈ x, p y) → p x) : p x := mem_wf.induction x h +instance : IsWellFounded ZFSet (· ∈ ·) := + ⟨mem_wf⟩ + instance : WellFoundedRelation ZFSet := ⟨_, mem_wf⟩ -instance : IsAsymm ZFSet (· ∈ ·) := - mem_wf.isAsymm - --- Porting note: this can't be inferred automatically for some reason. -instance : IsIrrefl ZFSet (· ∈ ·) := - mem_wf.isIrrefl - theorem mem_asymm {x y : ZFSet} : x ∈ y → y ∉ x := - asymm (r := (· ∈ ·)) + asymm_of (· ∈ ·) theorem mem_irrefl (x : ZFSet) : x ∉ x := - irrefl (r := (· ∈ ·)) x + irrefl_of (· ∈ ·) x theorem regularity (x : ZFSet.{u}) (h : x ≠ ∅) : ∃ y ∈ x, x ∩ y = ∅ := by_contradiction fun ne => @@ -1310,21 +1303,17 @@ theorem mem_wf : @WellFounded Class.{u} (· ∈ ·) := rintro B ⟨x, rfl, _⟩ exact H x⟩ +instance : IsWellFounded Class (· ∈ ·) := + ⟨mem_wf⟩ + instance : WellFoundedRelation Class := ⟨_, mem_wf⟩ -instance : IsAsymm Class (· ∈ ·) := - mem_wf.isAsymm - --- Porting note: this can't be inferred automatically for some reason. -instance : IsIrrefl Class (· ∈ ·) := - mem_wf.isIrrefl - theorem mem_asymm {x y : Class} : x ∈ y → y ∉ x := - asymm (r := (· ∈ ·)) + asymm_of (· ∈ ·) theorem mem_irrefl (x : Class) : x ∉ x := - irrefl (r := (· ∈ ·)) x + irrefl_of (· ∈ ·) x /-- **There is no universal set.** This is stated as `univ ∉ univ`, meaning that `univ` (the class of all sets) is proper (does not From 27ca8188dc20fb61ac2f2878268ce5748a324a6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Tue, 15 Oct 2024 17:51:53 +0000 Subject: [PATCH 160/425] chore(SetTheory/Ordinal/Principal): minor golfing (#17743) --- Mathlib/SetTheory/Ordinal/Principal.lean | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Mathlib/SetTheory/Ordinal/Principal.lean b/Mathlib/SetTheory/Ordinal/Principal.lean index c20573c3505921..58596bf0f6d53d 100644 --- a/Mathlib/SetTheory/Ordinal/Principal.lean +++ b/Mathlib/SetTheory/Ordinal/Principal.lean @@ -288,7 +288,7 @@ theorem principal_mul_of_le_two {o : Ordinal} (ho : o ≤ 2) : Principal (· * theorem principal_add_of_principal_mul {o : Ordinal} (ho : Principal (· * ·) o) (ho₂ : o ≠ 2) : Principal (· + ·) o := by cases' lt_or_gt_of_ne ho₂ with ho₁ ho₂ - · replace ho₁ : o < succ 1 := by simpa using ho₁ + · replace ho₁ : o < succ 1 := by rwa [succ_one] rw [lt_succ_iff] at ho₁ exact principal_add_of_le_one ho₁ · refine fun a b hao hbo => lt_of_le_of_lt ?_ (ho (max_lt hao hbo) ho₂) @@ -298,7 +298,7 @@ theorem principal_add_of_principal_mul {o : Ordinal} (ho : Principal (· * ·) o theorem principal_mul_isLimit {o : Ordinal.{u}} (ho₂ : 2 < o) (ho : Principal (· * ·) o) : o.IsLimit := - principal_add_isLimit ((lt_succ 1).trans (by simpa using ho₂)) + principal_add_isLimit ((lt_succ 1).trans (succ_one ▸ ho₂)) (principal_add_of_principal_mul ho (ne_of_gt ho₂)) theorem principal_mul_iff_mul_left_eq {o : Ordinal} : @@ -307,8 +307,8 @@ theorem principal_mul_iff_mul_left_eq {o : Ordinal} : · cases' le_or_gt o 2 with ho ho · convert one_mul o apply le_antisymm - · have : a < succ 1 := hao.trans_le (by simpa using ho) - rwa [lt_succ_iff] at this + · rw [← lt_succ_iff, succ_one] + exact hao.trans_le ho · rwa [← succ_le_iff, succ_zero] at ha₀ · exact op_eq_self_of_principal hao (isNormal_mul_right ha₀) h (principal_mul_isLimit ho h) · rcases eq_or_ne a 0 with (rfl | ha) @@ -411,7 +411,7 @@ theorem mul_eq_opow_log_succ {a b : Ordinal.{u}} (ha : a ≠ 0) (hb : Principal · have hbl := principal_mul_isLimit hb₂ hb rw [← (isNormal_mul_right (Ordinal.pos_iff_ne_zero.2 ha)).bsup_eq hbl, bsup_le_iff] intro c hcb - have hb₁ : 1 < b := (lt_succ 1).trans (by rwa [succ_one]) + have hb₁ : 1 < b := one_lt_two.trans hb₂ have hbo₀ : b ^ log b a ≠ 0 := Ordinal.pos_iff_ne_zero.1 (opow_pos _ (zero_lt_one.trans hb₁)) apply (mul_le_mul_right' (le_of_lt (lt_mul_succ_div a hbo₀)) c).trans rw [mul_assoc, opow_succ] From 70ccaf2f33f634223bebbea330d2e91dc6cde5ef Mon Sep 17 00:00:00 2001 From: Kyle Miller Date: Tue, 15 Oct 2024 11:09:34 -0700 Subject: [PATCH 161/425] fixes --- Mathlib/Tactic/ApplyFun.lean | 9 ++++++--- Mathlib/Tactic/Convert.lean | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Mathlib/Tactic/ApplyFun.lean b/Mathlib/Tactic/ApplyFun.lean index 2b55685474bb7d..26fe30001d7f64 100644 --- a/Mathlib/Tactic/ApplyFun.lean +++ b/Mathlib/Tactic/ApplyFun.lean @@ -28,7 +28,8 @@ def applyFunHyp (f : Term) (using? : Option Term) (h : FVarId) (g : MVarId) : let d ← h.getDecl let (prf, newGoals) ← match (← whnfR (← instantiateMVars d.type)).getAppFnArgs with | (``Eq, #[_, lhs, rhs]) => do - let (eq', gs) ← withCollectingNewGoalsFrom (tagSuffix := `apply_fun) <| + let (eq', gs) ← + withCollectingNewGoalsFrom (parentTag := ← g.getTag) (tagSuffix := `apply_fun) <| withoutRecover <| runTermElab <| do let f ← Term.elabTerm f none let lhs' ← Term.elabAppArgs f #[] #[.expr lhs] none false false @@ -126,7 +127,8 @@ def applyFunTarget (f : Term) (using? : Option Term) (g : MVarId) : TacticM (Lis -- handle applying a two-argument theorem whose first argument is f let handle (thm : Name) : TacticM (List MVarId) := do let ng ← mkFreshExprMVar none - let (pf, gs) ← withCollectingNewGoalsFrom (tagSuffix := `apply_fun) <| + let (pf, gs) ← + withCollectingNewGoalsFrom (parentTag := ← g.getTag) (tagSuffix := `apply_fun) <| withoutRecover <| runTermElab do -- This coerces `f` to be a function as necessary: let pf ← Term.elabTermEnsuringType (← `($(mkIdent thm) $f $(← Term.exprToSyntax ng))) @@ -151,7 +153,8 @@ def applyFunTarget (f : Term) (using? : Option Term) (g : MVarId) : TacticM (Lis let ginj ← mkFreshExprSyntheticOpaqueMVar (← mkFreshTypeMVar) (appendTag (← g.getTag) `inj) -- `withCollectingNewGoalsFrom` does not expect the goal to be closed, so here is "the goal" let gDefer ← mkFreshExprMVar (← g.getType) - let (_, gs) ← withCollectingNewGoalsFrom (tagSuffix := `apply_fun) <| + let (_, gs) ← + withCollectingNewGoalsFrom (parentTag := ← g.getTag) (tagSuffix := `apply_fun) <| withoutRecover <| runTermElab do let inj ← Term.elabTerm (← ``(Function.Injective $f)) none _ ← isDefEq (← inferType ginj) inj diff --git a/Mathlib/Tactic/Convert.lean b/Mathlib/Tactic/Convert.lean index c0dcc20b97221b..17baa946a72000 100644 --- a/Mathlib/Tactic/Convert.lean +++ b/Mathlib/Tactic/Convert.lean @@ -126,7 +126,8 @@ Returns stuck metavariables as additional goals. -/ def elabTermForConvert (term : Syntax) (expectedType? : Option Expr) : TacticM (Expr × List MVarId) := do - withCollectingNewGoalsFrom (allowNaturalHoles := true) (tagSuffix := `convert) do + withCollectingNewGoalsFrom (parentTag := ← getMainTag) (tagSuffix := `convert) + (allowNaturalHoles := true) do -- Allow typeclass inference failures since these will be inferred by unification -- or else become new goals withTheReader Term.Context (fun ctx => { ctx with ignoreTCFailures := true }) do From 1836f7324e16a1630717f97997f16b930272e6f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Tue, 15 Oct 2024 20:17:27 +0000 Subject: [PATCH 162/425] feat(Data/List/Sort): `List.Sorted.cons` (#15914) If `a :: l` is sorted under a transitive relation `r` and `r b a`, then `b :: a :: l` is sorted too. --- Mathlib/Data/List/Sort.lean | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Mathlib/Data/List/Sort.lean b/Mathlib/Data/List/Sort.lean index de5be483d4ecfc..2b327d5d70ca36 100644 --- a/Mathlib/Data/List/Sort.lean +++ b/Mathlib/Data/List/Sort.lean @@ -88,6 +88,18 @@ theorem Sorted.tail {r : α → α → Prop} {l : List α} (h : Sorted r l) : So theorem rel_of_sorted_cons {a : α} {l : List α} : Sorted r (a :: l) → ∀ b ∈ l, r a b := rel_of_pairwise_cons +nonrec theorem Sorted.cons {r : α → α → Prop} [IsTrans α r] {l : List α} {a b : α} + (hab : r a b) (h : Sorted r (b :: l)) : Sorted r (a :: b :: l) := + h.cons <| forall_mem_cons.2 ⟨hab, fun _ hx => _root_.trans hab <| rel_of_sorted_cons h _ hx⟩ + +theorem sorted_cons_cons {r : α → α → Prop} [IsTrans α r] {l : List α} {a b : α} : + Sorted r (b :: a :: l) ↔ r b a ∧ Sorted r (a :: l) := by + constructor + · intro h + exact ⟨rel_of_sorted_cons h _ (mem_cons_self a _), h.of_cons⟩ + · rintro ⟨h, ha⟩ + exact ha.cons h + theorem Sorted.head!_le [Inhabited α] [Preorder α] {a : α} {l : List α} (h : Sorted (· < ·) l) (ha : a ∈ l) : l.head! ≤ a := by rw [← List.cons_head!_tail (List.ne_nil_of_mem ha)] at h ha From af9a9c9ca2d15cc943a98510094e76a55cd8d988 Mon Sep 17 00:00:00 2001 From: FordUniver Date: Tue, 15 Oct 2024 21:11:12 +0000 Subject: [PATCH 163/425] feat: weighted double counting (#17651) added weighted double counting as sum_sum_bipartiteAbove_eq_sum_sum_bipartiteBelow Co-authored-by: FordUniver <61389961+FordUniver@users.noreply.github.com> --- Mathlib/Combinatorics/Enumerative/DoubleCounting.lean | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Mathlib/Combinatorics/Enumerative/DoubleCounting.lean b/Mathlib/Combinatorics/Enumerative/DoubleCounting.lean index 3d913effaea150..b929f72e6e6263 100644 --- a/Mathlib/Combinatorics/Enumerative/DoubleCounting.lean +++ b/Mathlib/Combinatorics/Enumerative/DoubleCounting.lean @@ -66,10 +66,16 @@ theorem mem_bipartiteBelow {a : α} : a ∈ s.bipartiteBelow r b ↔ a ∈ s ∧ @[simp] theorem mem_bipartiteAbove {b : β} : b ∈ t.bipartiteAbove r a ↔ b ∈ t ∧ r a b := mem_filter +@[to_additive] +theorem prod_prod_bipartiteAbove_eq_prod_prod_bipartiteBelow + [CommMonoid R] (f : α → β → R) [∀ a b, Decidable (r a b)] : + ∏ a ∈ s, ∏ b ∈ t.bipartiteAbove r a, f a b = ∏ b ∈ t, ∏ a ∈ s.bipartiteBelow r b, f a b := by + simp_rw [bipartiteAbove, bipartiteBelow, prod_filter] + exact prod_comm + theorem sum_card_bipartiteAbove_eq_sum_card_bipartiteBelow [∀ a b, Decidable (r a b)] : (∑ a ∈ s, (t.bipartiteAbove r a).card) = ∑ b ∈ t, (s.bipartiteBelow r b).card := by - simp_rw [card_eq_sum_ones, bipartiteAbove, bipartiteBelow, sum_filter] - exact sum_comm + simp_rw [card_eq_sum_ones, sum_sum_bipartiteAbove_eq_sum_sum_bipartiteBelow] section OrderedSemiring variable [OrderedSemiring R] {m n : R} From 244c025036bbbb74adc16d44932b3516c3aa9c93 Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Tue, 15 Oct 2024 21:48:52 +0000 Subject: [PATCH 164/425] feat: add instance `SubringClass.nonUnitalSubringClass` (#16975) --- Mathlib/Algebra/Ring/Subring/Basic.lean | 4 ++++ Mathlib/Algebra/Ring/Subsemiring/Basic.lean | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/Mathlib/Algebra/Ring/Subring/Basic.lean b/Mathlib/Algebra/Ring/Subring/Basic.lean index 9de90d6c1a621a..1a971aa4e69f61 100644 --- a/Mathlib/Algebra/Ring/Subring/Basic.lean +++ b/Mathlib/Algebra/Ring/Subring/Basic.lean @@ -6,6 +6,7 @@ Authors: Ashvni Narayanan import Mathlib.Algebra.Field.Defs import Mathlib.Algebra.Group.Subgroup.Basic import Mathlib.Algebra.Ring.Subsemiring.Basic +import Mathlib.RingTheory.NonUnitalSubring.Basic /-! # Subrings @@ -80,6 +81,9 @@ instance (priority := 100) SubringClass.addSubgroupClass (S : Type*) (R : Type u [SetLike S R] [Ring R] [h : SubringClass S R] : AddSubgroupClass S R := { h with } +instance (priority := 100) SubringClass.nonUnitalSubringClass (S : Type*) (R : Type u) + [SetLike S R] [Ring R] [SubringClass S R] : NonUnitalSubringClass S R where + variable [SetLike S R] [hSR : SubringClass S R] (s : S) @[aesop safe apply (rule_sets := [SetLike])] diff --git a/Mathlib/Algebra/Ring/Subsemiring/Basic.lean b/Mathlib/Algebra/Ring/Subsemiring/Basic.lean index 3fd3c93c9cef4c..07801d0fb5814c 100644 --- a/Mathlib/Algebra/Ring/Subsemiring/Basic.lean +++ b/Mathlib/Algebra/Ring/Subsemiring/Basic.lean @@ -68,6 +68,11 @@ instance (priority := 100) SubsemiringClass.addSubmonoidWithOneClass (S : Type*) AddSubmonoidWithOneClass S R := { h with } +instance (priority := 100) SubsemiringClass.nonUnitalSubsemiringClass (S : Type*) + (R : Type u) [NonAssocSemiring R] [SetLike S R] [SubsemiringClass S R] : + NonUnitalSubsemiringClass S R where + mul_mem := mul_mem + variable [SetLike S R] [hSR : SubsemiringClass S R] (s : S) namespace SubsemiringClass From 341d9cfc9744f9c9f141db9b12d676a4ea8cba8f Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Tue, 15 Oct 2024 22:29:54 +0000 Subject: [PATCH 165/425] feat: use @[csimp] to use exponentiation by repeated squaring at runtime (#8885) Using a `@[csimp]` attribute we can replace `npowRec` at runtime with an algorithm that uses repeated squaring, without affecting the definitional properties of `npowRec`. The prototypical application is that ``` #eval (3 : ZMod 49999)^49998 ``` used to stack overflow, but now runs fine. (This is an output of the "Formalization and Computer Algebra Systems" group at https://aimath.org/workshops/upcoming/cyberinfrastructure/.) Co-authored-by: Scott Morrison Co-authored-by: Eric Wieser Co-authored-by: Matthew Ballard Co-authored-by: Matthew Robert Ballard <100034030+mattrobball@users.noreply.github.com> --- Mathlib/Algebra/Group/Defs.lean | 161 +++++++++++++++++++++++++++++++- test/zmod.lean | 15 +++ 2 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 test/zmod.lean diff --git a/Mathlib/Algebra/Group/Defs.lean b/Mathlib/Algebra/Group/Defs.lean index 7f7d7ece643cd8..6a522dad55e3f9 100644 --- a/Mathlib/Algebra/Group/Defs.lean +++ b/Mathlib/Algebra/Group/Defs.lean @@ -516,6 +516,165 @@ needed. These problems do not come up in practice, so most of the time we will n the `npow` field when defining multiplicative objects. -/ +/-- +Scalar multiplication by repeated self-addition, +the additive version of exponentation by repeated squaring. +-/ +-- Ideally this would be generated by `@[to_additive]` from `npowBinRec`. +def nsmulBinRec {M : Type*} [Zero M] [Add M] (k : ℕ) (m : M) : M := + go k 0 m +where + /-- Auxiliary tail-recursive implementation for `nsmulBinRec`-/ + go : ℕ → M → M → M + | 0, y, _ => y + | (k + 1), y, x => + let k' := (k + 1) >>> 1 + if k &&& 1 = 1 then + go k' y (x + x) + else + go k' (y + x) (x + x) + +/-- Exponentiation by repeated squaring. -/ +@[to_additive existing] +def npowBinRec {M : Type*} [One M] [Mul M] (k : ℕ) (m : M) : M := + go k 1 m +where + /-- Auxiliary tail-recursive implementation for `npowBinRec`-/ + go : ℕ → M → M → M + | 0, y, _ => y + | (k + 1), y, x => + let k' := (k + 1) >>> 1 + if k &&& 1 = 1 then + go k' y (x * x) + else + go k' (y * x) (x * x) + +attribute [to_additive existing] npowBinRec.go + +/-- +A variant of `npowRec` which is a semigroup homomorphisms from `ℕ₊` to `M`. +-/ +def npowRec' {M : Type*} [One M] [Mul M] : ℕ → M → M + | 0, _ => 1 + | 1, m => m + | k + 2, m => npowRec' (k + 1) m * m + +/-- +A variant of `nsmulRec` which is a semigroup homomorphisms from `ℕ₊` to `M`. +-/ +def nsmulRec' {M : Type*} [Zero M] [Add M] : ℕ → M → M + | 0, _ => 0 + | 1, m => m + | k + 2, m => nsmulRec' (k + 1) m + m + +attribute [to_additive existing] npowRec' + +@[to_additive] +theorem npowRec'_succ {M : Type*} [Semigroup M] [One M] (k : ℕ) (m : M) : + npowRec' (k + 2) m = npowRec' (k + 1) m * m := by + rfl + +@[to_additive] +theorem npowRec'_two_mul {M : Type*} [Semigroup M] [One M] (k : ℕ) (m : M) : + npowRec' (2 * k) m = npowRec' k (m * m) := by + induction k using Nat.strongRecOn with + | ind k' ih => + match k' with + | 0 => rfl + | 1 => simp [npowRec'] + | k + 2 => simp [npowRec', ← mul_assoc, ← ih] + +@[to_additive] +theorem npowRec'_mul_comm {M : Type*} [Semigroup M] [One M] (k : ℕ) (m : M) : + m * npowRec' (k + 1) m = npowRec' (k + 1) m * m := by + induction k using Nat.strongRecOn with + | ind k' ih => + match k' with + | 0 => rfl + | 1 => simp [npowRec', mul_assoc] + | k + 2 => simp [npowRec', ← mul_assoc, ih] + +@[to_additive] +theorem npowRec_eq {M : Type*} [Semigroup M] [One M] (k : ℕ) (m : M) : + npowRec (k + 1) m = 1 * npowRec' (k + 1) m := by + induction k using Nat.strongRecOn with + | ind k' ih => + match k' with + | 0 => rfl + | k + 1 => + rw [npowRec, npowRec'_succ, ← mul_assoc] + congr + simp [ih] + +@[to_additive] +theorem npowBinRec.go_spec {M : Type*} [Semigroup M] [One M] (k : ℕ) (m n : M) : + npowBinRec.go (k + 1) m n = m * npowRec' (k + 1) n := by + induction k using Nat.strongRecOn generalizing m n with + | ind k' ih => + cases k' with + | zero => simp [go, npowRec'] + | succ k' => + rw [go] + split <;> rename_i w <;> rw [(by omega : (k' + 1 + 1) >>> 1 = k' >>> 1 + 1)] + · rw [ih] + · congr 1 + rw [← npowRec'_two_mul] + congr 1 + rw [Nat.shiftRight_eq_div_pow, Nat.pow_one, Nat.mul_add, Nat.mul_div_cancel'] + simp only [Nat.and_one_is_mod] at w + omega + · omega + · rw [ih] + · rw [mul_assoc] + rw [← npowRec'_two_mul] + congr 1 + conv => + rhs + rw [npowRec'] + rw [← npowRec'_mul_comm] + congr 2 + · rw [Nat.shiftRight_eq_div_pow, Nat.pow_one] + simp only [Nat.and_one_is_mod] at w + omega + · omega +/-- +An abbreviation for `npowRec` with an additional typeclass assumption on associativity +so that we can use `@[csimp]` to replace it with an implementation by repeated squaring +in compiled code. +-/ +@[to_additive +"An abbreviation for `nsmulRec` with an additional typeclass assumptions on associativity +so that we can use `@[csimp]` to replace it with an implementation by repeated doubling in compiled +code as an automatic parameter."] +abbrev npowRecAuto {M : Type*} [Semigroup M] [One M] (k : ℕ) (m : M) : M := + npowRec k m + +/-- +An abbreviation for `npowBinRec` with an additional typeclass assumption on associativity +so that we can use it in `@[csimp]` for more performant code generation. +-/ +@[to_additive +"An abbreviation for `nsmulBinRec` with an additional typeclass assumption on associativity +so that we can use it in `@[csimp]` for more performant code generation +as an automatic parameter."] +abbrev npowBinRecAuto {M : Type*} [Semigroup M] [One M] (k : ℕ) (m : M) : M := + npowBinRec k m + +@[csimp] +theorem nsmulRec_eq_nsmulBinRec : @nsmulRecAuto = @nsmulBinRecAuto := by + funext M _ _ k m + rw [nsmulBinRecAuto, nsmulRecAuto, nsmulBinRec] + match k with + | 0 => rw [nsmulRec, nsmulBinRec.go] + | k + 1 => rw [nsmulBinRec.go_spec, nsmulRec_eq] + +@[csimp] +theorem npowRec_eq_npowBinRec : @npowRecAuto = @npowBinRecAuto := by + funext M _ _ k m + rw [npowBinRecAuto, npowRecAuto, npowBinRec] + match k with + | 0 => rw [npowRec, npowBinRec.go] + | k + 1 => rw [npowBinRec.go_spec, npowRec_eq] /-- 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 @@ -534,7 +693,7 @@ attribute [instance 50] AddZeroClass.toAdd @[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 := npowRec + protected npow : ℕ → M → M := npowRecAuto /-- Raising to the power `(0 : ℕ)` gives `1`. -/ protected npow_zero : ∀ x, npow 0 x = 1 := by intros; rfl /-- Raising to the power `(n + 1 : ℕ)` behaves as expected. -/ diff --git a/test/zmod.lean b/test/zmod.lean new file mode 100644 index 00000000000000..19fe7d3bb0c271 --- /dev/null +++ b/test/zmod.lean @@ -0,0 +1,15 @@ +import Mathlib.Data.ZMod.Defs + +-- A Mersenne exponent, chosen so the test below takes no more than a few seconds +-- but should be enough to trigger a stack overflow from a non-tail-recursive implementation +-- of exponentiation by repeated squaring. +def k := 11213 +def p := 2^k - 1 + +set_option exponentiation.threshold 100000 in +-- We ensure here that the `@[csimp]` attribute successfully replaces (at runtime) +-- the default value of `npowRec` for the exponentation operation in `Monoid` +-- with a tail-recursive implementation by repeated squaring. +/-- info: 1 -/ +#guard_msgs in +#eval (37 : ZMod p)^(p-1) From 1fdea42e1d5526ea8aba0dffa07325981190dcf1 Mon Sep 17 00:00:00 2001 From: Amos Turchet Date: Tue, 15 Oct 2024 22:29:55 +0000 Subject: [PATCH 166/425] feat(NumberTheory/Ostrowski): First step of the proof of the Archimedean case of Ostrowski's Theorem (#14442) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This proves the first step of the proof of the Archimedean case of Ostrowski's Theorem, namely that a rational absolute value `f : MulRingNorm ℚ` that is not bounded, i.e. such that, evaluated at an integer `n`, it attains a value greater than one, then `f n` is always greater than one, whenever `1 Co-authored-by: Fabrizio Barroero Co-authored-by: Laura Capuano Co-authored-by: Nirvana Coppola Co-authored-by: María Inés de Frutos Fernández Co-authored-by: Silvain Rideau-Kikuchi Co-authored-by: Sam van Gool Co-authored-by: Francesco Veneziano Co-authored-by: fbarroero Co-authored-by: Fabrizio Barroero Co-authored-by: Yaël Dillies --- Mathlib/Analysis/Normed/Ring/Seminorm.lean | 10 ++ Mathlib/NumberTheory/Ostrowski.lean | 145 +++++++++++++++++++-- 2 files changed, 141 insertions(+), 14 deletions(-) diff --git a/Mathlib/Analysis/Normed/Ring/Seminorm.lean b/Mathlib/Analysis/Normed/Ring/Seminorm.lean index 650ace74daac1e..f25dcea804efa6 100644 --- a/Mathlib/Analysis/Normed/Ring/Seminorm.lean +++ b/Mathlib/Analysis/Normed/Ring/Seminorm.lean @@ -421,3 +421,13 @@ def NormedField.toMulRingNorm (R : Type*) [NormedField R] : MulRingNorm R where map_mul' := norm_mul neg' := norm_neg eq_zero_of_map_eq_zero' x hx := by rw [← norm_eq_zero]; exact hx + +/-- Triangle inequality for `MulRingNorm` applied to a list. -/ +lemma mulRingNorm_sum_le_sum_mulRingNorm {R : Type*} [NonAssocRing R] (l : List R) + (f : MulRingNorm R) : f l.sum ≤ (l.map f).sum := by + induction l with + | nil => simp only [List.sum_nil, map_zero, List.map_nil, le_refl] + | cons head tail ih => + simp only [List.sum_cons, List.map_cons] + calc f (head + List.sum tail) ≤ f head + f (List.sum tail) := by apply f.add_le' + _ ≤ f head + List.sum (List.map f tail) := by simp only [add_le_add_iff_left, ih] diff --git a/Mathlib/NumberTheory/Ostrowski.lean b/Mathlib/NumberTheory/Ostrowski.lean index 31a0b280f41f19..cd549970b163ca 100644 --- a/Mathlib/NumberTheory/Ostrowski.lean +++ b/Mathlib/NumberTheory/Ostrowski.lean @@ -7,27 +7,54 @@ Francesco Veneziano -/ import Mathlib.Analysis.Normed.Field.Lemmas -import Mathlib.Analysis.SpecialFunctions.Log.Base -import Mathlib.Analysis.SpecialFunctions.Pow.Real import Mathlib.Analysis.Normed.Ring.Seminorm +import Mathlib.Analysis.SpecialFunctions.Log.Base +import Mathlib.Analysis.SpecialFunctions.Pow.Asymptotics +import Mathlib.Analysis.SpecialFunctions.Pow.Continuity import Mathlib.NumberTheory.Padics.PadicNorm /-! # Ostrowski’s Theorem -The goal of this file is to prove Ostrowski’s Theorem which gives a list of all the nontrivial -absolute values on a number field up to equivalence. (TODO) +Ostrowski's Theorem for the field `ℚ`: every absolute value on `ℚ` is equivalent to either a +`p`-adic absolute value or to the standard Archimedean (Euclidean) absolute value. + +## TODO + +Extend to arbitrary number fields. ## References -* [K. Conrad, *Ostroski's Theorem for Q*][conradQ] -* [K. Conrad, *Ostroski for number fields*][conradnumbfield] -* [J. W. S. Cassels, *Local fields*][cassels1986local] +* [K. Conrad, *Ostrowski's Theorem for Q*][conradQ] +* [K. Conrad, *Ostrowski for number fields*][conradnumbfield] +* [J. W. S. Cassels, *Local fields*][cassels1986local] ## Tags -ring_norm, ostrowski + +ring norm, ostrowski -/ +/- ## Preliminary lemmas on limits -/ + +open Filter Nat Real Topology + +-- For any `C > 0`, the limit of `C ^ (1/k)` is 1 as `k → ∞` +private lemma tendsto_root_atTop_nhds_one {C : ℝ} (hC : 0 < C) : + Tendsto (fun k : ℕ ↦ C ^ (k : ℝ)⁻¹) atTop (𝓝 1) := by + convert_to Tendsto ((fun k ↦ C ^ k) ∘ (fun k : ℝ ↦ k⁻¹) ∘ (Nat.cast)) + atTop (𝓝 1) + exact Tendsto.comp (Continuous.tendsto' (continuous_iff_continuousAt.2 + (fun a ↦ continuousAt_const_rpow hC.ne')) 0 1 (rpow_zero C)) + <| Tendsto.comp tendsto_inv_atTop_zero tendsto_natCast_atTop_atTop + +--extends the lemma `tendsto_rpow_div` when the function has natural input +private lemma tendsto_nat_rpow_div : + Tendsto (fun k : ℕ ↦ (k : ℝ) ^ (k : ℝ)⁻¹) atTop (𝓝 1) := by + convert_to Tendsto ((fun k : ℝ ↦ k ^ k⁻¹) ∘ Nat.cast) atTop (𝓝 1) + apply Tendsto.comp _ tendsto_natCast_atTop_atTop + simp_rw [← one_div] + exact tendsto_rpow_div + namespace Rat.MulRingNorm open Int @@ -53,15 +80,17 @@ lemma equiv_on_nat_iff_equiv : (∃ c : ℝ, 0 < c ∧ (∀ n : ℕ , (f n) ^ c f.equiv g := by refine ⟨fun ⟨c, hc, h⟩ ↦ ⟨c, ⟨hc, ?_⟩⟩, fun ⟨c, hc, h⟩ ↦ ⟨c, ⟨hc, fun n ↦ by rw [← h]⟩⟩⟩ ext x - rw [← Rat.num_div_den x, map_div₀, map_div₀, Real.div_rpow (apply_nonneg f _) - (apply_nonneg f _), h x.den, ← MulRingNorm.apply_natAbs_eq,← MulRingNorm.apply_natAbs_eq, - h (natAbs x.num)] + rw [← Rat.num_div_den x, map_div₀, map_div₀, div_rpow (by positivity) (by positivity), h x.den, + ← MulRingNorm.apply_natAbs_eq,← MulRingNorm.apply_natAbs_eq, h (natAbs x.num)] open Rat.MulRingNorm section Non_archimedean --- ## Non-archimedean case +/-! ## Non-archimedean case + +Every bounded absolute value is equivalent to a `p`-adic absolute value +-/ /-- The mulRingNorm corresponding to the p-adic norm on `ℚ`. -/ def mulRingNorm_padic (p : ℕ) [Fact p.Prime] : MulRingNorm ℚ := @@ -154,7 +183,7 @@ lemma mulRingNorm_eq_one_of_not_dvd {m : ℕ} (hpm : ¬ p ∣ m) : f m = 1 := by exact lt_add_of_le_of_pos (Nat.le_ceil (M.logb (1 / 2))) zero_lt_one _ ≤ x ^ x.logb (1 / 2) := by apply rpow_le_rpow_of_exponent_ge hx0 (le_of_lt hx1) - simp only [one_div, ← log_div_log, Real.log_inv, neg_div, ← div_neg, hM] + simp only [one_div, ← log_div_log, log_inv, neg_div, ← div_neg, hM] gcongr simp only [Left.neg_pos_iff] exact log_neg (lt_sup_iff.2 <| Or.inl hp0) (sup_lt_iff.2 ⟨hp1, hm⟩) @@ -185,7 +214,7 @@ lemma exists_pos_mulRingNorm_eq_pow_neg : ∃ t : ℝ, 0 < t ∧ f p = p ^ (-t) refine (rpow_logb (mod_cast pprime.pos) ?_ hp0).symm simp only [ne_eq, Nat.cast_eq_one,Nat.Prime.ne_one pprime, not_false_eq_true] --- ## Non-archimedean case: end goal +/-! ## Non-archimedean case: end goal -/ include hf_nontriv bdd in /-- If `f` is bounded and not trivial, then it is equivalent to a p-adic absolute value. -/ @@ -228,4 +257,92 @@ theorem mulRingNorm_equiv_padic_of_bounded : end Non_archimedean +section Archimedean + +/-! ## Archimedean case -/ + +/-! ## Preliminary result -/ + +/-- Given an two integers `n, m` with `m > 1` the mulRingNorm of `n` is bounded by +`m + m * f m + m * (f m) ^ 2 + ... + m * (f m) ^ d` where `d` is the number of digits of the +expansion of `n` in base `m`. -/ +lemma mulRingNorm_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' + -- 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 (MulRingNorm_nat_le_nat c f) (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 + _ ≤ (L'.map f).sum := mulRingNorm_sum_le_sum_mulRingNorm L' f + _ ≤ (L.mapIdx fun i _ ↦ m * (f m) ^ i).sum := ?_ + simp only [hL', List.mapIdx_eq_enum_map, List.map_map] + apply List.sum_le_sum + rintro ⟨i, a⟩ hia + dsimp [Function.uncurry] + replace hia := List.mem_enumFrom hia + push_cast + rw [map_mul, map_pow] + gcongr + simp only [zero_le, zero_add, tsub_zero, true_and] at hia + exact (hcoef (List.mem_iff_get.mpr ⟨⟨i, hia.1⟩, hia.2.symm⟩)).le + +/-! ## Step 1: if f is a MulRingNorm and f n > 1 for some natural n, then f n > 1 for all n ≥ 2 -/ + +/-- If `f n > 1` for some `n` then `f n > 1` for all `n ≥ 2` -/ +lemma one_lt_of_not_bounded (notbdd : ¬ ∀ n : ℕ, f n ≤ 1) {n₀ : ℕ} (hn₀ : 1 < n₀) : 1 < f n₀ := by + contrapose! notbdd with h + intro n + have h_ineq1 {m : ℕ} (hm : 1 ≤ m) : f m ≤ n₀ * (logb n₀ m + 1) := by + /- L is the string of digits of `n` in the base `n₀`-/ + set L := Nat.digits n₀ m + calc + f m ≤ (L.mapIdx fun i _ ↦ n₀ * f n₀ ^ i).sum := mulRingNorm_apply_le_sum_digits m hn₀ + _ ≤ (L.mapIdx fun _ _ ↦ (n₀ : ℝ)).sum := by + simp only [List.mapIdx_eq_enum_map, List.map_map] + apply List.sum_le_sum + rintro ⟨i, a⟩ _ + simp only [Function.comp_apply, Function.uncurry_apply_pair] + exact mul_le_of_le_of_le_one' (mod_cast le_refl n₀) (pow_le_one₀ (by positivity) h) + (by positivity) (by positivity) + _ = n₀ * (Nat.log n₀ m + 1) := by + rw [List.mapIdx_eq_enum_map, List.eq_replicate_of_mem (a := (n₀ : ℝ)) + (l := List.map (Function.uncurry fun _ _ ↦ n₀) (List.enum L)), + List.sum_replicate, List.length_map, List.enum_length, nsmul_eq_mul, mul_comm, + Nat.digits_len n₀ m hn₀ (not_eq_zero_of_lt hm), Nat.cast_add_one] + simp (config := { contextual := true }) + _ ≤ 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 only [CharP.cast_eq_zero, map_zero, zero_le_one] + 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.2 hn₀) (mod_cast Nat.one_le_of_lt h₀.bot_lt) + calc + f n = (f ↑(n ^ k)) ^ (k : ℝ)⁻¹ := by + rw [Nat.cast_pow, map_pow, ← rpow_natCast, rpow_rpow_inv (by positivity) (by positivity)] + _ ≤ (n₀ * (logb n₀ ↑(n ^ k) + 1)) ^ (k : ℝ)⁻¹ := by + gcongr + exact h_ineq1 <| one_le_pow₀ (one_le_iff_ne_zero.mpr h₀) + _ = (n₀ * (k * logb n₀ n + 1)) ^ (k : ℝ)⁻¹ := by + rw [Nat.cast_pow, logb_pow (mod_cast h₀.bot_lt)] + _ ≤ (n₀ * ( k * logb n₀ n + k)) ^ (k : ℝ)⁻¹ := by + gcongr + exact one_le_cast.mpr hk + _ = (n₀ * (logb n₀ n + 1)) ^ (k : ℝ)⁻¹ * k ^ (k : ℝ)⁻¹ := by + rw [← mul_rpow (by positivity) (by positivity), mul_assoc, add_mul, one_mul, + mul_comm _ (k : ℝ)] +-- For 0 < logb n₀ n below we also need to exclude n = 1. + rcases eq_or_ne n 1 with rfl | h₁; simp only [Nat.cast_one, map_one, le_refl] + refine le_of_tendsto_of_tendsto tendsto_const_nhds ?_ (eventually_atTop.2 ⟨1, h_ineq2⟩) + nth_rw 2 [← mul_one 1] + have : 0 < logb n₀ n := logb_pos (mod_cast hn₀) (by norm_cast; omega) + have hnlim : Tendsto (fun k : ℕ ↦ (n₀ * (logb n₀ n + 1)) ^ (k : ℝ)⁻¹) atTop (𝓝 1) := + tendsto_root_atTop_nhds_one (by positivity) + exact hnlim.mul tendsto_nat_rpow_div + +end Archimedean + end Rat.MulRingNorm From f44f4685b1b49b1b758312791ad27f07458cb569 Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Tue, 15 Oct 2024 22:29:56 +0000 Subject: [PATCH 167/425] refactor: migrate to dependent induction lemmas (#17543) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Many of the existing induction lemmas for subobjects (e.g., `Subsemigroup.closure_induction`) were written with a motive that does not depend on the induction argument (e.g., `x ∈ Subsemigroup.closure s`), like so: ```lean theorem Subsemigroup.closure_induction {M : Type u_1} [Mul M] {s : Set M} {p : M → Prop} {x : M} (h : x ∈ Subsemigroup.closure s) (mem : ∀ x ∈ s, p x) (mul : ∀ (x y : M), p x → p y → p (x * y)) : p x ``` This prevents Lean from correctly inferring the motive when applying the `induction` tactic. As such, these lemmas don't serve much purpose, and we gradually acquired their dependent counterparts as variations with a `'`, like this one: ```lean theorem Subsemigroup.closure_induction' {M : Type u_1} [Mul M] (s : Set M) {p : (x : M) → x ∈ Subsemigroup.closure s → Prop} (mem : ∀ (x : M) (h : x ∈ s), p x ⋯) (mul : ∀ (x : M) (hx : x ∈ Subsemigroup.closure s) (y : M) (hy : y ∈ Subsemigroup.closure s), p x hx → p y hy → p (x * y) (mul_mem hx hy)) {x : M} (hx : x ∈ Subsemigroup.closure s) : p x hx ``` This PR moves the primed versions to the un-primed names, and removes the non-dependent lemmas, while also ensuring the dependent versions exist and are uniform for all these various subobjects. Moves: - Subsemigroup.closure_induction' -> Subsemigroup.closure_induction - AddSubsemigroup.closure_induction' -> AddSubsemigroup.closure_induction - Submonoid.closure_induction' -> Submonoid.closure_induction - AddSubmonoid.closure_induction' -> AddSubmonoid.closure_induction - Subgroup.closure_induction' -> Subgroup.closure_induction - AddSubgroup.closure_induction' -> AddSubgroup.closure_induction - Submodule.span_induction' -> Submodule.span_induction - Submodule.closure_induction' -> Submodule.closure_induction - NonUnitalAlgebra.adjoin_induction' -> NonUnitalAlgebra.adjoin_induction - NonUnitalStarAlgebra.adjoin_induction' -> NonUnitalStarAlgebra.adjoin_induction - Subsemiring.closure_induction' -> Subsemiring.closure_induction - Subring.closure_induction' -> Subring.closure_induction - Algebra.adjoin_induction'' -> Algebra.adjoin_induction --- .../Algebra/Algebra/NonUnitalSubalgebra.lean | 143 +++++++------- .../Algebra/Algebra/Subalgebra/Pointwise.lean | 4 +- Mathlib/Algebra/Algebra/Tower.lean | 18 +- Mathlib/Algebra/DirectLimit.lean | 18 +- Mathlib/Algebra/Group/Subgroup/Basic.lean | 106 +++++----- Mathlib/Algebra/Group/Subgroup/Pointwise.lean | 4 +- Mathlib/Algebra/Group/Submonoid/Basic.lean | 78 +++++--- .../Algebra/Group/Submonoid/Membership.lean | 35 ++-- .../Algebra/Group/Submonoid/Operations.lean | 9 +- .../Algebra/Group/Submonoid/Pointwise.lean | 10 +- Mathlib/Algebra/Group/Subsemigroup/Basic.lean | 66 ++++--- .../Group/Subsemigroup/Membership.lean | 6 +- .../Group/Subsemigroup/Operations.lean | 6 +- Mathlib/Algebra/Lie/BaseChange.lean | 13 +- Mathlib/Algebra/Lie/Character.lean | 6 +- Mathlib/Algebra/Lie/IdealOperations.lean | 6 +- Mathlib/Algebra/Lie/TraceForm.lean | 9 +- Mathlib/Algebra/Lie/Weights/Chain.lean | 2 +- Mathlib/Algebra/Lie/Weights/Killing.lean | 2 +- .../Algebra/Module/Submodule/Bilinear.lean | 4 +- .../Algebra/Module/Submodule/Pointwise.lean | 2 +- Mathlib/Algebra/Order/Ring/Star.lean | 2 +- Mathlib/Algebra/Order/Star/Basic.lean | 18 +- Mathlib/Algebra/Ring/Subring/Basic.lean | 183 ++++++++++-------- Mathlib/Algebra/Ring/Subsemiring/Basic.lean | 121 ++++++------ Mathlib/Algebra/RingQuot.lean | 6 +- Mathlib/Algebra/Star/NonUnitalSubalgebra.lean | 16 +- Mathlib/Algebra/Star/Subalgebra.lean | 96 +++++---- .../Instances.lean | 8 +- Mathlib/Analysis/Fourier/AddCircle.lean | 4 +- .../Analysis/InnerProductSpace/StarOrder.lean | 4 +- Mathlib/FieldTheory/Finite/GaloisField.lean | 8 +- Mathlib/GroupTheory/Coxeter/Basic.lean | 3 +- Mathlib/GroupTheory/Nilpotent.lean | 7 +- Mathlib/GroupTheory/Perm/ClosureSwap.lean | 3 +- .../LinearAlgebra/CliffordAlgebra/Even.lean | 4 +- Mathlib/LinearAlgebra/FiniteSpan.lean | 4 +- Mathlib/LinearAlgebra/RootSystem/Defs.lean | 4 +- Mathlib/LinearAlgebra/Span.lean | 152 ++++++++------- .../TensorProduct/RightExactness.lean | 12 +- .../LinearAlgebra/TensorProduct/Tower.lean | 7 +- Mathlib/NumberTheory/Cyclotomic/Basic.lean | 26 +-- .../NumberField/CanonicalEmbedding/Basic.lean | 2 +- Mathlib/RingTheory/Adjoin/Basic.lean | 147 +++++++------- Mathlib/RingTheory/Adjoin/Tower.lean | 4 +- Mathlib/RingTheory/DedekindDomain/Ideal.lean | 6 +- Mathlib/RingTheory/Derivation/Basic.lean | 5 +- Mathlib/RingTheory/EssentialFiniteness.lean | 14 +- Mathlib/RingTheory/FinitePresentation.lean | 12 +- Mathlib/RingTheory/FiniteType.lean | 24 +-- Mathlib/RingTheory/Finiteness.lean | 2 +- .../RingTheory/FractionalIdeal/Extended.lean | 11 +- .../FractionalIdeal/Operations.lean | 12 +- Mathlib/RingTheory/Ideal/Maps.lean | 6 +- Mathlib/RingTheory/Ideal/Operations.lean | 12 +- .../IsIntegralClosure/Basic.lean | 4 +- Mathlib/RingTheory/Kaehler/Basic.lean | 18 +- .../RingTheory/Localization/Submodule.lean | 6 +- .../RingTheory/MvPolynomial/Localization.lean | 6 +- .../RingTheory/NonUnitalSubring/Basic.lean | 141 ++++++++------ .../NonUnitalSubsemiring/Basic.lean | 41 ++-- Mathlib/RingTheory/Polynomial/Basic.lean | 16 +- Mathlib/RingTheory/Polynomial/Bernstein.lean | 6 +- .../RingTheory/TwoSidedIdeal/Operations.lean | 4 +- Mathlib/Topology/Algebra/StarSubalgebra.lean | 11 +- .../Topology/ContinuousMap/StarOrdered.lean | 4 +- .../ContinuousMap/StoneWeierstrass.lean | 6 +- 67 files changed, 938 insertions(+), 817 deletions(-) diff --git a/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean b/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean index d7beda182c5492..d1fc4f0c9f0a55 100644 --- a/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean +++ b/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean @@ -523,16 +523,17 @@ def adjoin (s : Set A) : NonUnitalSubalgebra R A := @fun a b (ha : a ∈ Submodule.span R (NonUnitalSubsemiring.closure s : Set A)) (hb : b ∈ Submodule.span R (NonUnitalSubsemiring.closure s : Set A)) => show a * b ∈ Submodule.span R (NonUnitalSubsemiring.closure s : Set A) by - refine Submodule.span_induction ha ?_ ?_ ?_ ?_ - · refine Submodule.span_induction hb ?_ ?_ ?_ ?_ + refine Submodule.span_induction ?_ ?_ ?_ ?_ ha + · refine Submodule.span_induction ?_ ?_ ?_ ?_ hb · exact fun x (hx : x ∈ NonUnitalSubsemiring.closure s) y (hy : y ∈ NonUnitalSubsemiring.closure s) => Submodule.subset_span (mul_mem hy hx) · exact fun x _hx => (mul_zero x).symm ▸ Submodule.zero_mem _ - · exact fun x y hx hy z hz => (mul_add z x y).symm ▸ add_mem (hx z hz) (hy z hz) - · exact fun r x hx y hy => (mul_smul_comm r y x).symm ▸ SMulMemClass.smul_mem r (hx y hy) + · exact fun x y _ _ hx hy z hz => (mul_add z x y).symm ▸ add_mem (hx z hz) (hy z hz) + · exact fun r x _ hx y hy => + (mul_smul_comm r y x).symm ▸ SMulMemClass.smul_mem r (hx y hy) · exact (zero_mul b).symm ▸ Submodule.zero_mem _ - · exact fun x y => (add_mul x y b).symm ▸ add_mem - · exact fun r x hx => (smul_mul_assoc r x b).symm ▸ SMulMemClass.smul_mem r hx } + · exact fun x y _ _ => (add_mul x y b).symm ▸ add_mem + · exact fun r x _ hx => (smul_mul_assoc r x b).symm ▸ SMulMemClass.smul_mem r hx } theorem adjoin_toSubmodule (s : Set A) : (adjoin R s).toSubmodule = Submodule.span R (NonUnitalSubsemiring.closure s : Set A) := @@ -547,59 +548,6 @@ theorem self_mem_adjoin_singleton (x : A) : x ∈ adjoin R ({x} : Set A) := variable {R} -/-- If some predicate holds for all `x ∈ (s : Set A)` and this predicate is closed under the -`algebraMap`, addition, multiplication and star operations, then it holds for `a ∈ adjoin R s`. -/ -@[elab_as_elim] -theorem adjoin_induction {s : Set A} {p : A → Prop} {a : A} (h : a ∈ adjoin R s) - (mem : ∀ x ∈ s, p x) (add : ∀ x y, p x → p y → p (x + y)) (zero : p 0) - (mul : ∀ x y, p x → p y → p (x * y)) (smul : ∀ (r : R) x, p x → p (r • x)) : p a := - Submodule.span_induction h - (fun _a ha => NonUnitalSubsemiring.closure_induction ha mem zero add mul) zero add smul - -@[elab_as_elim] -theorem adjoin_induction₂ {s : Set A} {p : A → A → Prop} {a b : A} (ha : a ∈ adjoin R s) - (hb : b ∈ adjoin R s) (Hs : ∀ x ∈ s, ∀ y ∈ s, p x y) (H0_left : ∀ y, p 0 y) - (H0_right : ∀ x, p x 0) (Hadd_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ + x₂) y) - (Hadd_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ + y₂)) - (Hmul_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ * x₂) y) - (Hmul_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ * y₂)) - (Hsmul_left : ∀ (r : R) x y, p x y → p (r • x) y) - (Hsmul_right : ∀ (r : R) x y, p x y → p x (r • y)) : p a b := - Submodule.span_induction₂ ha hb - (fun _x hx _y hy => - NonUnitalSubsemiring.closure_induction₂ hx hy Hs H0_left H0_right Hadd_left Hadd_right - Hmul_left Hmul_right) - H0_left H0_right Hadd_left Hadd_right Hsmul_left Hsmul_right - -/-- The difference with `NonUnitalAlgebra.adjoin_induction` is that this acts on the subtype. -/ -@[elab_as_elim] -lemma adjoin_induction_subtype {s : Set A} {p : adjoin R s → Prop} (a : adjoin R s) - (mem : ∀ x (h : x ∈ s), p ⟨x, subset_adjoin R h⟩) - (add : ∀ x y, p x → p y → p (x + y)) (zero : p 0) - (mul : ∀ x y, p x → p y → p (x * y)) (smul : ∀ (r : R) x, p x → p (r • x)) : p a := - Subtype.recOn a fun b hb => by - refine Exists.elim ?_ (fun (hb : b ∈ adjoin R s) (hc : p ⟨b, hb⟩) => hc) - refine adjoin_induction hb ?_ ?_ ?_ ?_ ?_ - · exact fun x hx => ⟨subset_adjoin R hx, mem x hx⟩ - · exact fun x y hx hy => Exists.elim hx fun hx' hx => Exists.elim hy fun hy' hy => - ⟨add_mem hx' hy', add _ _ hx hy⟩ - · exact ⟨_, zero⟩ - · exact fun x y hx hy => Exists.elim hx fun hx' hx => Exists.elim hy fun hy' hy => - ⟨mul_mem hx' hy', mul _ _ hx hy⟩ - · exact fun r x hx => Exists.elim hx fun hx' hx => - ⟨SMulMemClass.smul_mem r hx', smul r _ hx⟩ - -/-- A dependent version of `NonUnitalAlgebra.adjoin_induction`. -/ -theorem adjoin_induction' {s : Set A} {p : ∀ x, x ∈ adjoin R s → Prop} - (mem : ∀ (x) (h : x ∈ s), p x (subset_adjoin R h)) - (add : ∀ x hx y hy, p x hx → p y hy → p (x + y) (add_mem ‹_› ‹_›)) - (zero : p 0 (zero_mem _)) - (mul : ∀ x hx y hy, p x hx → p y hy → p (x * y) (mul_mem ‹_› ‹_›)) - (smul : ∀ (r : R) (x hx), p x hx → p (r • x) (SMulMemClass.smul_mem _ ‹_›)) - {a} (ha : a ∈ adjoin R s) : p a ha := - adjoin_induction_subtype ⟨a, ha⟩ (p := fun x ↦ p x.1 x.2) mem (fun x y ↦ add x.1 x.2 y.1 y.2) - zero (fun x y ↦ mul x.1 x.2 y.1 y.2) (fun r x ↦ smul r x.1 x.2) - protected theorem gc : GaloisConnection (adjoin R : Set A → NonUnitalSubalgebra R A) (↑) := fun s S => ⟨fun H => (NonUnitalSubsemiring.subset_closure.trans Submodule.subset_span).trans H, @@ -629,21 +577,80 @@ theorem adjoin_union (s t : Set A) : adjoin R (s ∪ t) = adjoin R s ⊔ adjoin lemma adjoin_eq (s : NonUnitalSubalgebra R A) : adjoin R (s : Set A) = s := le_antisymm (adjoin_le le_rfl) (subset_adjoin R) +/-- If some predicate holds for all `x ∈ (s : Set A)` and this predicate is closed under the +`algebraMap`, addition, multiplication and star operations, then it holds for `a ∈ adjoin R s`. -/ +@[elab_as_elim] +theorem adjoin_induction {s : Set A} {p : (x : A) → x ∈ adjoin R s → Prop} + (mem : ∀ (x) (hx : x ∈ s), p x (subset_adjoin R hx)) + (add : ∀ x y hx hy, p x hx → p y hy → p (x + y) (add_mem hx hy)) (zero : p 0 (zero_mem _)) + (mul : ∀ x y hx hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) + (smul : ∀ r x hx, p x hx → p (r • x) (SMulMemClass.smul_mem r hx)) + {x} (hx : x ∈ adjoin R s) : p x hx := + let S : NonUnitalSubalgebra R A := + { carrier := { x | ∃ hx, p x hx } + mul_mem' := (Exists.elim · fun _ ha ↦ (Exists.elim · fun _ hb ↦ ⟨_, mul _ _ _ _ ha hb⟩)) + add_mem' := (Exists.elim · fun _ ha ↦ (Exists.elim · fun _ hb ↦ ⟨_, add _ _ _ _ ha hb⟩)) + smul_mem' := fun r ↦ (Exists.elim · fun _ hb ↦ ⟨_, smul r _ _ hb⟩) + zero_mem' := ⟨_, zero⟩ } + adjoin_le (S := S) (fun y hy ↦ ⟨subset_adjoin R hy, mem y hy⟩) hx |>.elim fun _ ↦ id + +@[deprecated adjoin_induction (since := "2024-10-10")] +alias adjoin_induction' := adjoin_induction + +@[elab_as_elim] +theorem adjoin_induction₂ {s : Set A} {p : ∀ x y, x ∈ adjoin R s → y ∈ adjoin R s → Prop} + (mem_mem : ∀ (x) (y) (hx : x ∈ s) (hy : y ∈ s), p x y (subset_adjoin R hx) (subset_adjoin R hy)) + (zero_left : ∀ x hx, p 0 x (zero_mem _) hx) (zero_right : ∀ x hx, p x 0 hx (zero_mem _)) + (add_left : ∀ x y z hx hy hz, p x z hx hz → p y z hy hz → p (x + y) z (add_mem hx hy) hz) + (add_right : ∀ x y z hx hy hz, p x y hx hy → p x z hx hz → p x (y + z) hx (add_mem hy hz)) + (mul_left : ∀ x y z hx hy hz, p x z hx hz → p y z hy hz → p (x * y) z (mul_mem hx hy) hz) + (mul_right : ∀ x y z hx hy hz, p x y hx hy → p x z hx hz → p x (y * z) hx (mul_mem hy hz)) + (smul_left : ∀ r x y hx hy, p x y hx hy → p (r • x) y (SMulMemClass.smul_mem r hx) hy) + (smul_right : ∀ r x y hx hy, p x y hx hy → p x (r • y) hx (SMulMemClass.smul_mem r hy)) + {x y : A} (hx : x ∈ adjoin R s) (hy : y ∈ adjoin R s) : + p x y hx hy := by + induction hy using adjoin_induction with + | mem z hz => + induction hx using adjoin_induction with + | mem _ h => exact mem_mem _ _ h hz + | zero => exact zero_left _ _ + | mul _ _ _ _ h₁ h₂ => exact mul_left _ _ _ _ _ _ h₁ h₂ + | add _ _ _ _ h₁ h₂ => exact add_left _ _ _ _ _ _ h₁ h₂ + | smul _ _ _ h => exact smul_left _ _ _ _ _ h + | zero => exact zero_right x hx + | mul _ _ _ _ h₁ h₂ => exact mul_right _ _ _ _ _ _ h₁ h₂ + | add _ _ _ _ h₁ h₂ => exact add_right _ _ _ _ _ _ h₁ h₂ + | smul _ _ _ h => exact smul_right _ _ _ _ _ h + +/-- The difference with `NonUnitalAlgebra.adjoin_induction` is that this acts on the subtype. -/ +@[elab_as_elim, deprecated adjoin_induction (since := "2024-10-11")] +lemma adjoin_induction_subtype {s : Set A} {p : adjoin R s → Prop} (a : adjoin R s) + (mem : ∀ x (h : x ∈ s), p ⟨x, subset_adjoin R h⟩) + (add : ∀ x y, p x → p y → p (x + y)) (zero : p 0) + (mul : ∀ x y, p x → p y → p (x * y)) (smul : ∀ (r : R) x, p x → p (r • x)) : p a := + Subtype.recOn a fun b hb => by + induction hb using adjoin_induction with + | mem _ h => exact mem _ h + | zero => exact zero + | mul _ _ _ _ h₁ h₂ => exact mul _ _ h₁ h₂ + | add _ _ _ _ h₁ h₂ => exact add _ _ h₁ h₂ + | smul _ _ _ h => exact smul _ _ h + open Submodule in lemma adjoin_eq_span (s : Set A) : (adjoin R s).toSubmodule = span R (Subsemigroup.closure s) := by apply le_antisymm · intro x hx - induction hx using adjoin_induction' with + induction hx using adjoin_induction with | mem x hx => exact subset_span <| Subsemigroup.subset_closure hx - | add x _ y _ hpx hpy => exact add_mem hpx hpy + | add x y _ _ hpx hpy => exact add_mem hpx hpy | zero => exact zero_mem _ - | mul x _ y _ hpx hpy => - apply span_induction₂ hpx hpy ?Hs (by simp) (by simp) ?Hadd_l ?Hadd_r ?Hsmul_l ?Hsmul_r - case Hs => exact fun x hx y hy ↦ subset_span <| mul_mem hx hy - case Hadd_l => exact fun x y z hxz hyz ↦ by simpa [add_mul] using add_mem hxz hyz - case Hadd_r => exact fun x y z hxz hyz ↦ by simpa [mul_add] using add_mem hxz hyz - case Hsmul_l => exact fun r x y hxy ↦ by simpa [smul_mul_assoc] using smul_mem _ _ hxy - case Hsmul_r => exact fun r x y hxy ↦ by simpa [mul_smul_comm] using smul_mem _ _ hxy + | mul x y _ _ hpx hpy => + apply span_induction₂ ?Hs (by simp) (by simp) ?Hadd_l ?Hadd_r ?Hsmul_l ?Hsmul_r hpx hpy + case Hs => exact fun x y hx hy ↦ subset_span <| mul_mem hx hy + case Hadd_l => exact fun x y z _ _ _ hxz hyz ↦ by simpa [add_mul] using add_mem hxz hyz + case Hadd_r => exact fun x y z _ _ _ hxz hyz ↦ by simpa [mul_add] using add_mem hxz hyz + case Hsmul_l => exact fun r x y _ _ hxy ↦ by simpa [smul_mul_assoc] using smul_mem _ _ hxy + case Hsmul_r => exact fun r x y _ _ hxy ↦ by simpa [mul_smul_comm] using smul_mem _ _ hxy | smul r x _ hpx => exact smul_mem _ _ hpx · apply span_le.2 _ show Subsemigroup.closure s ≤ (adjoin R s).toSubsemigroup diff --git a/Mathlib/Algebra/Algebra/Subalgebra/Pointwise.lean b/Mathlib/Algebra/Algebra/Subalgebra/Pointwise.lean index 6328cb01ad700a..5003f01d48ca5f 100644 --- a/Mathlib/Algebra/Algebra/Subalgebra/Pointwise.lean +++ b/Mathlib/Algebra/Algebra/Subalgebra/Pointwise.lean @@ -47,8 +47,8 @@ theorem mul_toSubmodule {R : Type*} {A : Type*} [CommSemiring R] [CommSemiring A refine le_antisymm (mul_toSubmodule_le _ _) ?_ rintro x (hx : x ∈ Algebra.adjoin R (S ∪ T : Set A)) refine - Algebra.adjoin_induction hx (fun x hx => ?_) (fun r => ?_) (fun _ _ => Submodule.add_mem _) - fun x y hx hy => ?_ + Algebra.adjoin_induction (fun x hx => ?_) (fun r => ?_) (fun _ _ _ _ => Submodule.add_mem _) + (fun x y _ _ hx hy => ?_) hx · rcases hx with hxS | hxT · rw [← mul_one x] exact Submodule.mul_mem_mul hxS (show (1 : A) ∈ T from one_mem T) diff --git a/Mathlib/Algebra/Algebra/Tower.lean b/Mathlib/Algebra/Algebra/Tower.lean index ab29e6a7c911bd..f973ed4d98f83b 100644 --- a/Mathlib/Algebra/Algebra/Tower.lean +++ b/Mathlib/Algebra/Algebra/Tower.lean @@ -240,7 +240,7 @@ variable [Module R M] [Module A M] [IsScalarTower R A M] theorem restrictScalars_span (hsur : Function.Surjective (algebraMap R A)) (X : Set M) : restrictScalars R (span A X) = span R X := by refine ((span_le_restrictScalars R A X).antisymm fun m hm => ?_).symm - refine span_induction hm subset_span (zero_mem _) (fun _ _ => add_mem) fun a m hm => ?_ + refine span_induction subset_span (zero_mem _) (fun _ _ _ _ => add_mem) (fun a m _ hm => ?_) hm obtain ⟨r, rfl⟩ := hsur a simpa [algebraMap_smul] using smul_mem _ r hm @@ -265,21 +265,21 @@ open IsScalarTower theorem smul_mem_span_smul_of_mem {s : Set S} {t : Set A} {k : S} (hks : k ∈ span R s) {x : A} (hx : x ∈ t) : k • x ∈ span R (s • t) := - span_induction hks (fun _ hc => subset_span <| Set.smul_mem_smul hc hx) + span_induction (fun _ hc => subset_span <| Set.smul_mem_smul hc hx) (by rw [zero_smul]; exact zero_mem _) - (fun c₁ c₂ ih₁ ih₂ => by rw [add_smul]; exact add_mem ih₁ ih₂) - fun b c hc => by rw [IsScalarTower.smul_assoc]; exact smul_mem _ _ hc + (fun c₁ c₂ _ _ ih₁ ih₂ => by rw [add_smul]; exact add_mem ih₁ ih₂) + (fun b c _ hc => by rw [IsScalarTower.smul_assoc]; exact smul_mem _ _ hc) hks theorem span_smul_of_span_eq_top {s : Set S} (hs : span R s = ⊤) (t : Set A) : span R (s • t) = (span S t).restrictScalars R := le_antisymm (span_le.2 fun _x ⟨p, _hps, _q, hqt, hpqx⟩ ↦ hpqx ▸ (span S t).smul_mem p (subset_span hqt)) - fun _ hp ↦ closure_induction hp (zero_mem _) (fun _ _ ↦ add_mem) fun s0 y hy ↦ by - refine span_induction (hs ▸ mem_top : s0 ∈ span R s) - (fun x hx ↦ subset_span ⟨x, hx, y, hy, rfl⟩) ?_ ?_ ?_ + fun _ hp ↦ closure_induction (hx := hp) (zero_mem _) (fun _ _ _ _ ↦ add_mem) fun s0 y hy ↦ by + refine span_induction (fun x hx ↦ subset_span <| by exact ⟨x, hx, y, hy, rfl⟩) ?_ ?_ ?_ + (hs ▸ mem_top : s0 ∈ span R s) · rw [zero_smul]; apply zero_mem - · intro _ _; rw [add_smul]; apply add_mem - · intro r s0 hy; rw [IsScalarTower.smul_assoc]; exact smul_mem _ r hy + · intro _ _ _ _; rw [add_smul]; apply add_mem + · intro r s0 _ hy; rw [IsScalarTower.smul_assoc]; exact smul_mem _ r hy -- The following two lemmas were originally used to prove `span_smul_of_span_eq_top` -- but are now not needed. diff --git a/Mathlib/Algebra/DirectLimit.lean b/Mathlib/Algebra/DirectLimit.lean index 06bfd7e4deaaf4..c5d8c1217f959d 100644 --- a/Mathlib/Algebra/DirectLimit.lean +++ b/Mathlib/Algebra/DirectLimit.lean @@ -292,7 +292,7 @@ theorem of.zero_exact_aux [∀ i (k : G i), Decidable (k ≠ 0)] [Nonempty ι] [ (∀ k ∈ x.support, k ≤ j) ∧ DirectSum.toModule R ι (G j) (fun i => totalize G f i j) x = (0 : G j) := Nonempty.elim (by infer_instance) fun ind : ι => - span_induction ((Quotient.mk_eq_zero _).1 H) + span_induction (hx := (Quotient.mk_eq_zero _).1 H) (fun x ⟨i, j, hij, y, hxy⟩ => let ⟨k, hik, hjk⟩ := exists_ge_ge i j ⟨k, by @@ -311,14 +311,14 @@ theorem of.zero_exact_aux [∀ i (k : G i), Decidable (k ≠ 0)] [Nonempty ι] [ simp [LinearMap.map_sub, totalize_of_le, hik, hjk, DirectedSystem.map_map, DirectSum.apply_eq_component, DirectSum.component.of]⟩) ⟨ind, fun _ h => (Finset.not_mem_empty _ h).elim, LinearMap.map_zero _⟩ - (fun x y ⟨i, hi, hxi⟩ ⟨j, hj, hyj⟩ => + (fun x y _ _ ⟨i, hi, hxi⟩ ⟨j, hj, hyj⟩ => let ⟨k, hik, hjk⟩ := exists_ge_ge i j ⟨k, fun _ hl => (Finset.mem_union.1 (DFinsupp.support_add hl)).elim (fun hl => le_trans (hi _ hl) hik) fun hl => le_trans (hj _ hl) hjk, by simp [LinearMap.map_add, hxi, hyj, toModule_totalize_of_le hik hi, toModule_totalize_of_le hjk hj]⟩) - fun a x ⟨i, hi, hxi⟩ => + fun a x _ ⟨i, hi, hxi⟩ => ⟨i, fun k hk => hi k (DirectSum.support_smul _ _ hk), by simp [LinearMap.map_smul, hxi]⟩ open Classical in @@ -664,7 +664,7 @@ theorem of.zero_exact_aux [Nonempty ι] [IsDirected ι (· ≤ ·)] {x : FreeCom ∀ [DecidablePred (· ∈ s)], lift (fun ix : s => f' ix.1.1 j (H ix ix.2) ix.1.2) (restriction s x) = (0 : G j) := by have := Classical.decEq - refine span_induction (Ideal.Quotient.eq_zero_iff_mem.1 H) ?_ ?_ ?_ ?_ + refine span_induction ?_ ?_ ?_ ?_ (Ideal.Quotient.eq_zero_iff_mem.1 H) · rintro x (⟨i, j, hij, x, rfl⟩ | ⟨i, rfl⟩ | ⟨i, x, y, rfl⟩ | ⟨i, x, y, rfl⟩) · refine ⟨j, {⟨i, x⟩, ⟨j, f' i j hij x⟩}, ?_, @@ -720,9 +720,8 @@ theorem of.zero_exact_aux [Nonempty ι] [IsDirected ι (· ≤ ·)] {x : FreeCom exacts [Or.inl rfl, Or.inr (Or.inr rfl), Or.inr (Or.inl rfl)] · refine Nonempty.elim (by infer_instance) fun ind : ι => ?_ refine ⟨ind, ∅, fun _ => False.elim, isSupported_zero, fun [_] => ?_⟩ - -- Porting note: `RingHom.map_zero` was `(restriction _).map_zero` - rw [RingHom.map_zero, (FreeCommRing.lift _).map_zero] - · intro x y ⟨i, s, hi, hxs, ihs⟩ ⟨j, t, hj, hyt, iht⟩ + rw [(restriction _).map_zero, (FreeCommRing.lift _).map_zero] + · intro x y _ _ ⟨i, s, hi, hxs, ihs⟩ ⟨j, t, hj, hyt, iht⟩ obtain ⟨k, hik, hjk⟩ := exists_ge_ge i j have : ∀ z : Σi, G i, z ∈ s ∪ t → z.1 ≤ k := by rintro z (hz | hz) @@ -732,12 +731,11 @@ theorem of.zero_exact_aux [Nonempty ι] [IsDirected ι (· ≤ ·)] {x : FreeCom ⟨k, s ∪ t, this, isSupported_add (isSupported_upwards hxs Set.subset_union_left) (isSupported_upwards hyt Set.subset_union_right), fun [_] => ?_⟩ - -- Porting note: was `(restriction _).map_add` - classical rw [RingHom.map_add, (FreeCommRing.lift _).map_add, ← + classical rw [(restriction _).map_add, (FreeCommRing.lift _).map_add, ← of.zero_exact_aux2 G f' hxs hi this hik Set.subset_union_left, ← of.zero_exact_aux2 G f' hyt hj this hjk Set.subset_union_right, ihs, (f' i k hik).map_zero, iht, (f' j k hjk).map_zero, zero_add] - · rintro x y ⟨j, t, hj, hyt, iht⟩ + · rintro x y - ⟨j, t, hj, hyt, iht⟩ rw [smul_eq_mul] rcases exists_finset_support x with ⟨s, hxs⟩ rcases (s.image Sigma.fst).exists_le with ⟨i, hi⟩ diff --git a/Mathlib/Algebra/Group/Subgroup/Basic.lean b/Mathlib/Algebra/Group/Subgroup/Basic.lean index 4fd2fb66654a41..4f1bb54083fb77 100644 --- a/Mathlib/Algebra/Group/Subgroup/Basic.lean +++ b/Mathlib/Algebra/Group/Subgroup/Basic.lean @@ -888,43 +888,47 @@ only require showing `p` is preserved by multiplication by elements in `k`. -/ See also `AddSubgroup.closure_induction_left` and `AddSubgroup.closure_induction_left` for versions that only require showing `p` is preserved by addition by elements in `k`."] -theorem closure_induction {p : G → Prop} {x} (h : x ∈ closure k) (mem : ∀ x ∈ k, p x) (one : p 1) - (mul : ∀ x y, p x → p y → p (x * y)) (inv : ∀ x, p x → p x⁻¹) : p x := - (@closure_le _ _ ⟨⟨⟨setOf p, fun {x y} ↦ mul x y⟩, one⟩, fun {x} ↦ inv x⟩ k).2 mem h - -/-- A dependent version of `Subgroup.closure_induction`. -/ -@[to_additive (attr := elab_as_elim) "A dependent version of `AddSubgroup.closure_induction`. "] -theorem closure_induction' {p : ∀ x, x ∈ closure k → Prop} - (mem : ∀ (x) (h : x ∈ k), p x (subset_closure h)) (one : p 1 (one_mem _)) - (mul : ∀ x hx y hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) - (inv : ∀ x hx, p x hx → p x⁻¹ (inv_mem hx)) {x} (hx : x ∈ closure k) : p x hx := by - refine Exists.elim ?_ fun (hx : x ∈ closure k) (hc : p x hx) => hc - exact - closure_induction hx (fun x hx => ⟨_, mem x hx⟩) ⟨_, one⟩ - (fun x y ⟨hx', hx⟩ ⟨hy', hy⟩ => ⟨_, mul _ _ _ _ hx hy⟩) fun x ⟨hx', hx⟩ => ⟨_, inv _ _ hx⟩ +theorem closure_induction {p : (g : G) → g ∈ closure k → Prop} + (mem : ∀ x (hx : x ∈ k), p x (subset_closure hx)) (one : p 1 (one_mem _)) + (mul : ∀ x y hx hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) + (inv : ∀ x hx, p x hx → p x⁻¹ (inv_mem hx)) {x} (hx : x ∈ closure k) : p x hx := + let K : Subgroup G := + { carrier := { x | ∃ hx, p x hx } + mul_mem' := fun ⟨_, ha⟩ ⟨_, hb⟩ ↦ ⟨_, mul _ _ _ _ ha hb⟩ + one_mem' := ⟨_, one⟩ + inv_mem' := fun ⟨_, hb⟩ ↦ ⟨_, inv _ _ hb⟩ } + closure_le (K := K) |>.mpr (fun y hy ↦ ⟨subset_closure hy, mem y hy⟩) hx |>.elim fun _ ↦ id + +@[deprecated closure_induction (since := "2024-10-10")] +alias closure_induction' := closure_induction /-- An induction principle for closure membership for predicates with two arguments. -/ @[to_additive (attr := elab_as_elim) "An induction principle for additive closure membership, for predicates with two arguments."] -theorem closure_induction₂ {p : G → G → Prop} {x} {y : G} (hx : x ∈ closure k) (hy : y ∈ closure k) - (Hk : ∀ x ∈ k, ∀ y ∈ k, p x y) (H1_left : ∀ x, p 1 x) (H1_right : ∀ x, p x 1) - (Hmul_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ * x₂) y) - (Hmul_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ * y₂)) (Hinv_left : ∀ x y, p x y → p x⁻¹ y) - (Hinv_right : ∀ x y, p x y → p x y⁻¹) : p x y := - closure_induction hx - (fun x xk => closure_induction hy (Hk x xk) (H1_right x) (Hmul_right x) (Hinv_right x)) - (H1_left y) (fun z z' => Hmul_left z z' y) fun z => Hinv_left z y +theorem closure_induction₂ {p : (x y : G) → x ∈ closure k → y ∈ closure k → Prop} + (mem : ∀ (x) (y) (hx : x ∈ k) (hy : y ∈ k), p x y (subset_closure hx) (subset_closure hy)) + (one_left : ∀ x hx, p 1 x (one_mem _) hx) (one_right : ∀ x hx, p x 1 hx (one_mem _)) + (mul_left : ∀ x y z hx hy hz, p x z hx hz → p y z hy hz → p (x * y) z (mul_mem hx hy) hz) + (mul_right : ∀ y z x hy hz hx, p x y hx hy → p x z hx hz → p x (y * z) hx (mul_mem hy hz)) + (inv_left : ∀ x y hx hy, p x y hx hy → p x⁻¹ y (inv_mem hx) hy) + (inv_right : ∀ x y hx hy, p x y hx hy → p x y⁻¹ hx (inv_mem hy)) + {x y : G} (hx : x ∈ closure k) (hy : y ∈ closure k) : p x y hx hy := by + induction hy using closure_induction with + | mem z hz => induction hx using closure_induction with + | mem _ h => exact mem _ _ h hz + | one => exact one_left _ (subset_closure hz) + | mul _ _ _ _ h₁ h₂ => exact mul_left _ _ _ _ _ _ h₁ h₂ + | inv _ _ h => exact inv_left _ _ _ _ h + | one => exact one_right x hx + | mul _ _ _ _ h₁ h₂ => exact mul_right _ _ _ _ _ hx h₁ h₂ + | inv _ _ h => exact inv_right _ _ _ _ h @[to_additive (attr := simp)] theorem closure_closure_coe_preimage {k : Set G} : closure (((↑) : closure k → G) ⁻¹' k) = ⊤ := - eq_top_iff.2 fun x => - Subtype.recOn x fun x hx _ => by - refine closure_induction' (fun g hg => ?_) ?_ (fun g₁ g₂ hg₁ hg₂ => ?_) (fun g hg => ?_) hx - · exact subset_closure hg - · exact one_mem _ - · exact mul_mem - · exact inv_mem + eq_top_iff.2 fun x _ ↦ Subtype.recOn x fun _ hx' ↦ + closure_induction (fun _ h ↦ subset_closure h) (one_mem _) (fun _ _ _ _ ↦ mul_mem) + (fun _ _ ↦ inv_mem) hx' /-- If all the elements of a set `s` commute, then `closure s` is a commutative group. -/ @[to_additive @@ -933,18 +937,19 @@ theorem closure_closure_coe_preimage {k : Set G} : closure (((↑) : closure k def closureCommGroupOfComm {k : Set G} (hcomm : ∀ x ∈ k, ∀ y ∈ k, x * y = y * x) : CommGroup (closure k) := { (closure k).toGroup with - mul_comm := fun x y => by + mul_comm := fun ⟨x, hx⟩ ⟨y, hy⟩ => by ext simp only [Subgroup.coe_mul] - refine - closure_induction₂ x.prop y.prop hcomm (fun x => by simp only [mul_one, one_mul]) - (fun x => by simp only [mul_one, one_mul]) - (fun x y z h₁ h₂ => by rw [mul_assoc, h₂, ← mul_assoc, h₁, mul_assoc]) - (fun x y z h₁ h₂ => by rw [← mul_assoc, h₁, mul_assoc, h₂, ← mul_assoc]) - (fun x y h => by - rw [inv_mul_eq_iff_eq_mul, ← mul_assoc, h, mul_assoc, mul_inv_cancel, mul_one]) - fun x y h => by - rw [mul_inv_eq_iff_eq_mul, mul_assoc, h, ← mul_assoc, inv_mul_cancel, one_mul] } + induction hx, hy using closure_induction₂ with + | mem x y hx hy => exact hcomm x hx y hy + | one_left x _ => exact Commute.one_left x + | one_right x _ => exact Commute.one_right x + | mul_left _ _ _ _ _ _ h₁ h₂ => exact Commute.mul_left h₁ h₂ + | mul_right _ _ _ _ _ _ h₁ h₂ => exact Commute.mul_right h₁ h₂ + | inv_left _ _ _ _ h => -- `Commute.inv_left` is not imported + rw [inv_mul_eq_iff_eq_mul, ← mul_assoc, h, mul_assoc, mul_inv_cancel, mul_one] + | inv_right _ _ _ _ h => + rw [mul_inv_eq_iff_eq_mul, mul_assoc, h, ← mul_assoc, inv_mul_cancel, one_mul] } variable (G) @@ -1005,15 +1010,15 @@ theorem iSup_eq_closure {ι : Sort*} (p : ι → Subgroup G) : natural number multiples of the element."] theorem mem_closure_singleton {x y : G} : y ∈ closure ({x} : Set G) ↔ ∃ n : ℤ, x ^ n = y := by refine - ⟨fun hy => closure_induction hy ?_ ?_ ?_ ?_, fun ⟨n, hn⟩ => + ⟨fun hy => closure_induction ?_ ?_ ?_ ?_ hy, fun ⟨n, hn⟩ => hn ▸ zpow_mem (subset_closure <| mem_singleton x) n⟩ · intro y hy rw [eq_of_mem_singleton hy] exact ⟨1, zpow_one x⟩ · exact ⟨0, zpow_zero x⟩ - · rintro _ _ ⟨n, rfl⟩ ⟨m, rfl⟩ + · rintro _ _ _ _ ⟨n, rfl⟩ ⟨m, rfl⟩ exact ⟨n + m, zpow_add x n m⟩ - rintro _ ⟨n, rfl⟩ + rintro _ _ ⟨n, rfl⟩ exact ⟨-n, zpow_neg x n⟩ @[to_additive] @@ -1039,12 +1044,12 @@ theorem mem_iSup_of_directed {ι} [hι : Nonempty ι] {K : ι → Subgroup G} (h refine ⟨?_, fun ⟨i, hi⟩ ↦ le_iSup K i hi⟩ suffices x ∈ closure (⋃ i, (K i : Set G)) → ∃ i, x ∈ K i by simpa only [closure_iUnion, closure_eq (K _)] using this - refine fun hx ↦ closure_induction hx (fun _ ↦ mem_iUnion.1) ?_ ?_ ?_ + refine fun hx ↦ closure_induction (fun _ ↦ mem_iUnion.1) ?_ ?_ ?_ hx · exact hι.elim fun i ↦ ⟨i, (K i).one_mem⟩ - · rintro x y ⟨i, hi⟩ ⟨j, hj⟩ + · rintro x y _ _ ⟨i, hi⟩ ⟨j, hj⟩ rcases hK i j with ⟨k, hki, hkj⟩ exact ⟨k, mul_mem (hki hi) (hkj hj)⟩ - · rintro _ ⟨i, hi⟩ + · rintro _ _ ⟨i, hi⟩ exact ⟨i, inv_mem hi⟩ @[to_additive] @@ -1884,7 +1889,8 @@ theorem le_normalClosure {H : Subgroup G} : H ≤ normalClosure ↑H := fun _ h /-- The normal closure of `s` is a normal subgroup. -/ instance normalClosure_normal : (normalClosure s).Normal := ⟨fun n h g => by - refine Subgroup.closure_induction h (fun x hx => ?_) ?_ (fun x y ihx ihy => ?_) fun x ihx => ?_ + refine Subgroup.closure_induction (fun x hx => ?_) ?_ (fun x y _ _ ihx ihy => ?_) + (fun x _ ihx => ?_) h · exact conjugatesOfSet_subset_normalClosure (conj_mem_conjugatesOfSet hx) · simpa using (normalClosure s).one_mem · rw [← conj_mul] @@ -1895,7 +1901,7 @@ instance normalClosure_normal : (normalClosure s).Normal := /-- The normal closure of `s` is the smallest normal subgroup containing `s`. -/ theorem normalClosure_le_normal {N : Subgroup G} [N.Normal] (h : s ⊆ N) : normalClosure s ≤ N := by intro a w - refine closure_induction w (fun x hx => ?_) ?_ (fun x y ihx ihy => ?_) fun x ihx => ?_ + refine closure_induction (fun x hx => ?_) ?_ (fun x y _ _ ihx ihy => ?_) (fun x _ ihx => ?_) w · exact conjugatesOfSet_subset h hx · exact one_mem _ · exact mul_mem ihx ihy @@ -2758,14 +2764,14 @@ variable {C : Type*} [CommGroup C] {s t : Subgroup C} {x : C} theorem mem_sup : x ∈ s ⊔ t ↔ ∃ y ∈ s, ∃ z ∈ t, y * z = x := ⟨fun h => by rw [sup_eq_closure] at h - refine Subgroup.closure_induction h ?_ ?_ ?_ ?_ + refine Subgroup.closure_induction ?_ ?_ ?_ ?_ h · rintro y (h | h) · exact ⟨y, h, 1, t.one_mem, by simp⟩ · exact ⟨1, s.one_mem, y, h, by simp⟩ · exact ⟨1, s.one_mem, 1, ⟨t.one_mem, mul_one 1⟩⟩ - · rintro _ _ ⟨y₁, hy₁, z₁, hz₁, rfl⟩ ⟨y₂, hy₂, z₂, hz₂, rfl⟩ + · rintro _ _ _ _ ⟨y₁, hy₁, z₁, hz₁, rfl⟩ ⟨y₂, hy₂, z₂, hz₂, rfl⟩ exact ⟨_, mul_mem hy₁ hy₂, _, mul_mem hz₁ hz₂, by simp [mul_assoc, mul_left_comm]⟩ - · rintro _ ⟨y, hy, z, hz, rfl⟩ + · rintro _ _ ⟨y, hy, z, hz, rfl⟩ exact ⟨_, inv_mem hy, _, inv_mem hz, mul_comm z y ▸ (mul_inv_rev z y).symm⟩, by rintro ⟨y, hy, z, hz, rfl⟩; exact mul_mem_sup hy hz⟩ diff --git a/Mathlib/Algebra/Group/Subgroup/Pointwise.lean b/Mathlib/Algebra/Group/Subgroup/Pointwise.lean index 48ad4a5c50a1d8..95c62df222f42b 100644 --- a/Mathlib/Algebra/Group/Subgroup/Pointwise.lean +++ b/Mathlib/Algebra/Group/Subgroup/Pointwise.lean @@ -68,9 +68,9 @@ theorem closure_toSubmonoid (S : Set G) : (closure S).toSubmonoid = Submonoid.closure (S ∪ S⁻¹) := by refine le_antisymm (fun x hx => ?_) (Submonoid.closure_le.2 ?_) · refine - closure_induction hx + closure_induction (fun x hx => Submonoid.closure_mono subset_union_left (Submonoid.subset_closure hx)) - (Submonoid.one_mem _) (fun x y hx hy => Submonoid.mul_mem _ hx hy) fun x hx => ?_ + (Submonoid.one_mem _) (fun x y _ _ hx hy => Submonoid.mul_mem _ hx hy) (fun x _ hx => ?_) hx rwa [← Submonoid.mem_closure_inv, Set.union_inv, inv_inv, Set.union_comm] · simp only [true_and, coe_toSubmonoid, union_subset_iff, subset_closure, inv_subset_closure] diff --git a/Mathlib/Algebra/Group/Submonoid/Basic.lean b/Mathlib/Algebra/Group/Submonoid/Basic.lean index 199f57b66d1fd8..9113ca59629d91 100644 --- a/Mathlib/Algebra/Group/Submonoid/Basic.lean +++ b/Mathlib/Algebra/Group/Submonoid/Basic.lean @@ -156,32 +156,35 @@ is preserved under multiplication, then `p` holds for all elements of the closur "An induction principle for additive closure membership. If `p` holds for `0` and all elements of `s`, and is preserved under addition, then `p` holds for all elements of the additive closure of `s`."] -theorem closure_induction {p : M → Prop} {x} (h : x ∈ closure s) (mem : ∀ x ∈ s, p x) (one : p 1) - (mul : ∀ x y, p x → p y → p (x * y)) : p x := - (@closure_le _ _ _ ⟨⟨p, mul _ _⟩, one⟩).2 mem h - -/-- A dependent version of `Submonoid.closure_induction`. -/ -@[to_additive (attr := elab_as_elim) "A dependent version of `AddSubmonoid.closure_induction`. "] -theorem closure_induction' (s : Set M) {p : ∀ x, x ∈ closure s → Prop} +theorem closure_induction {s : Set M} {p : (x : M) → x ∈ closure s → Prop} (mem : ∀ (x) (h : x ∈ s), p x (subset_closure h)) (one : p 1 (one_mem _)) - (mul : ∀ x hx y hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) {x} (hx : x ∈ closure s) : - p x hx := by - refine Exists.elim ?_ fun (hx : x ∈ closure s) (hc : p x hx) => hc - exact - closure_induction hx (fun x hx => ⟨_, mem x hx⟩) ⟨_, one⟩ fun x y ⟨hx', hx⟩ ⟨hy', hy⟩ => - ⟨_, mul _ _ _ _ hx hy⟩ + (mul : ∀ x y hx hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) {x} (hx : x ∈ closure s) : + p x hx := + let S : Submonoid M := + { carrier := { x | ∃ hx, p x hx } + one_mem' := ⟨_, one⟩ + mul_mem' := fun ⟨_, hpx⟩ ⟨_, hpy⟩ ↦ ⟨_, mul _ _ _ _ hpx hpy⟩ } + closure_le (S := S) |>.mpr (fun y hy ↦ ⟨subset_closure hy, mem y hy⟩) hx |>.elim fun _ ↦ id + +@[deprecated closure_induction (since := "2024-10-10")] +alias closure_induction' := closure_induction /-- An induction principle for closure membership for predicates with two arguments. -/ @[to_additive (attr := elab_as_elim) "An induction principle for additive closure membership for predicates with two arguments."] -theorem closure_induction₂ {p : M → M → Prop} {x} {y : M} (hx : x ∈ closure s) (hy : y ∈ closure s) - (Hs : ∀ x ∈ s, ∀ y ∈ s, p x y) (H1_left : ∀ x, p 1 x) (H1_right : ∀ x, p x 1) - (Hmul_left : ∀ x y z, p x z → p y z → p (x * y) z) - (Hmul_right : ∀ x y z, p z x → p z y → p z (x * y)) : p x y := - closure_induction hx - (fun x xs => - closure_induction hy (Hs x xs) (H1_right x) fun z _ h₁ h₂ => Hmul_right z _ _ h₁ h₂) - (H1_left y) fun _ _ h₁ h₂ => Hmul_left _ _ _ h₁ h₂ +theorem closure_induction₂ {p : (x y : M) → x ∈ closure s → y ∈ closure s → Prop} + (mem : ∀ (x) (y) (hx : x ∈ s) (hy : y ∈ s), p x y (subset_closure hx) (subset_closure hy)) + (one_left : ∀ x hx, p 1 x (one_mem _) hx) (one_right : ∀ x hx, p x 1 hx (one_mem _)) + (mul_left : ∀ x y z hx hy hz, p x z hx hz → p y z hy hz → p (x * y) z (mul_mem hx hy) hz) + (mul_right : ∀ x y z hx hy hz, p z x hz hx → p z y hz hy → p z (x * y) hz (mul_mem hx hy)) + {x y : M} (hx : x ∈ closure s) (hy : y ∈ closure s) : p x y hx hy := by + induction hy using closure_induction with + | mem z hz => induction hx using closure_induction with + | mem _ h => exact mem _ _ h hz + | one => exact one_left _ (subset_closure hz) + | mul _ _ _ _ h₁ h₂ => exact mul_left _ _ _ _ _ _ h₁ h₂ + | one => exact one_right x hx + | mul _ _ _ _ h₁ h₂ => exact mul_right _ _ _ _ _ hx h₁ h₂ /-- If `s` is a dense set in a monoid `M`, `Submonoid.closure s = ⊤`, then in order to prove that some predicate `p` holds for all `x : M` it suffices to verify `p x` for `x ∈ s`, verify `p 1`, @@ -190,18 +193,31 @@ and verify that `p x` and `p y` imply `p (x * y)`. -/ "If `s` is a dense set in an additive monoid `M`, `AddSubmonoid.closure s = ⊤`, then in order to prove that some predicate `p` holds for all `x : M` it suffices to verify `p x` for `x ∈ s`, verify `p 0`, and verify that `p x` and `p y` imply `p (x + y)`."] -theorem dense_induction {p : M → Prop} (x : M) {s : Set M} (hs : closure s = ⊤) - (mem : ∀ x ∈ s, p x) - (one : p 1) (mul : ∀ x y, p x → p y → p (x * y)) : p x := by - have : ∀ x ∈ closure s, p x := fun x hx => closure_induction hx mem one mul - simpa [hs] using this x +theorem dense_induction {p : M → Prop} (s : Set M) (closure : closure s = ⊤) (mem : ∀ x ∈ s, p x) + (one : p 1) (mul : ∀ x y, p x → p y → p (x * y)) (x : M) : p x := by + induction closure.symm ▸ mem_top x using closure_induction with + | mem _ h => exact mem _ h + | one => exact one + | mul _ _ _ _ h₁ h₂ => exact mul _ _ h₁ h₂ + +/- The argument `s : Set M` is explicit in `Submonoid.dense_induction` because the type of the +induction variable, namely `x : M`, does not reference `x`. Making `s` explicit allows the user +to apply the induction principle while deferring the proof of `closure s = ⊤` without creating +metavariables, as in the following example. -/ +example {p : M → Prop} (s : Set M) (closure : closure s = ⊤) (mem : ∀ x ∈ s, p x) + (one : p 1) (mul : ∀ x y, p x → p y → p (x * y)) (x : M) : p x := by + induction x using dense_induction s with + | closure => exact closure + | mem x hx => exact mem x hx + | one => exact one + | mul _ _ h₁ h₂ => exact mul _ _ h₁ h₂ /-- The `Submonoid.closure` of a set is the union of `{1}` and its `Subsemigroup.closure`. -/ lemma closure_eq_one_union (s : Set M) : closure s = {(1 : M)} ∪ (Subsemigroup.closure s : Set M) := by apply le_antisymm · intro x hx - induction hx using closure_induction' with + induction hx using closure_induction with | mem x hx => exact Or.inr <| Subsemigroup.subset_closure hx | one => exact Or.inl <| by simp | mul x hx y hy hx hy => @@ -341,8 +357,8 @@ def ofClosureMEqTopLeft {M N} [Monoid M] [Monoid N] {s : Set M} (f : M → N) (h toFun := f map_one' := h1 map_mul' x := - (dense_induction (p := _) x hs hmul fun y => by rw [one_mul, h1, one_mul]) fun a b ha hb y => by - rw [mul_assoc, ha, ha, hb, mul_assoc] + dense_induction (p := _) _ hs hmul fun y => by rw [one_mul, h1, one_mul] + (fun a b ha hb y => by rw [mul_assoc, ha, ha, hb, mul_assoc]) x @[to_additive (attr := simp, norm_cast)] theorem coe_ofClosureMEqTopLeft (f : M → N) (hs : closure s = ⊤) (h1 hmul) : @@ -362,9 +378,9 @@ def ofClosureMEqTopRight {M N} [Monoid M] [Monoid N] {s : Set M} (f : M → N) ( toFun := f map_one' := h1 map_mul' x y := - dense_induction y hs (fun y hy x => hmul x y hy) (by simp [h1]) + dense_induction _ hs (fun y hy x => hmul x y hy) (by simp [h1]) (fun y₁ y₂ (h₁ : ∀ _, f _ = f _ * f _) (h₂ : ∀ _, f _ = f _ * f _) x => by - simp [← mul_assoc, h₁, h₂]) x + simp [← mul_assoc, h₁, h₂]) y x @[to_additive (attr := simp, norm_cast)] theorem coe_ofClosureMEqTopRight (f : M → N) (hs : closure s = ⊤) (h1 hmul) : diff --git a/Mathlib/Algebra/Group/Submonoid/Membership.lean b/Mathlib/Algebra/Group/Submonoid/Membership.lean index b36aad9d57cb63..632e86eea4ba5f 100644 --- a/Mathlib/Algebra/Group/Submonoid/Membership.lean +++ b/Mathlib/Algebra/Group/Submonoid/Membership.lean @@ -175,9 +175,9 @@ theorem mem_iSup_of_directed {ι} [hι : Nonempty ι] {S : ι → Submonoid M} ( refine ⟨?_, fun ⟨i, hi⟩ ↦ le_iSup S i hi⟩ suffices x ∈ closure (⋃ 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) ?_ ?_ + refine closure_induction (fun _ ↦ mem_iUnion.1) ?_ ?_ · exact hι.elim fun i ↦ ⟨i, (S i).one_mem⟩ - · rintro x y ⟨i, hi⟩ ⟨j, hj⟩ + · rintro x y - - ⟨i, hi⟩ ⟨j, hj⟩ rcases hS i j with ⟨k, hki, hkj⟩ exact ⟨k, (S k).mul_mem (hki hi) (hkj hj)⟩ @@ -233,7 +233,7 @@ then it holds for all elements of the supremum of `S`. -/ theorem iSup_induction {ι : Sort*} (S : ι → Submonoid M) {C : M → Prop} {x : M} (hx : x ∈ ⨆ i, S i) (mem : ∀ (i), ∀ x ∈ S i, C x) (one : C 1) (mul : ∀ x y, C x → C y → C (x * y)) : C x := by rw [iSup_eq_closure] at hx - refine closure_induction hx (fun x hx => ?_) one mul + refine closure_induction (fun x hx => ?_) one (fun _ _ _ _ ↦ mul _ _) hx obtain ⟨i, hi⟩ := Set.mem_iUnion.mp hx exact mem _ _ hi @@ -504,9 +504,9 @@ def closureCommMonoidOfComm {s : Set M} (hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b mul_comm := fun x y => by ext simp only [Submonoid.coe_mul] - exact - closure_induction₂ x.prop y.prop hcomm Commute.one_left Commute.one_right - (fun x y z => Commute.mul_left) fun x y z => Commute.mul_right } + exact closure_induction₂ (fun _ _ h₁ h₂ ↦ hcomm _ h₁ _ h₂) (fun _ _ ↦ Commute.one_left _) + (fun _ _ ↦ Commute.one_right _) (fun _ _ _ _ _ _ ↦ Commute.mul_left) + (fun _ _ _ _ _ _ ↦ Commute.mul_right) x.prop y.prop } end Submonoid @@ -609,26 +609,19 @@ variable {R : Type*} [NonUnitalNonAssocSemiring R] [SetLike M R] [MulMemClass M and an element of `M` is contained in the additive closure of `M`. -/ theorem mul_right_mem_add_closure (ha : a ∈ AddSubmonoid.closure (S : Set R)) (hb : b ∈ S) : a * b ∈ AddSubmonoid.closure (S : Set R) := by - revert b - apply @AddSubmonoid.closure_induction _ _ _ - (fun z => ∀ (b : R), b ∈ S → z * b ∈ AddSubmonoid.closure S) _ ha <;> clear ha a - · exact fun r hr b hb => AddSubmonoid.mem_closure.mpr fun y hy => hy (mul_mem hr hb) - · exact fun b _ => by simp only [zero_mul, (AddSubmonoid.closure (S : Set R)).zero_mem] - · simp_rw [add_mul] - exact fun r s hr hs b hb => (AddSubmonoid.closure (S : Set R)).add_mem (hr _ hb) (hs _ hb) + induction ha using AddSubmonoid.closure_induction with + | mem r hr => exact AddSubmonoid.mem_closure.mpr fun y hy => hy (mul_mem hr hb) + | one => simp only [zero_mul, zero_mem _] + | mul r s _ _ hr hs => simpa only [add_mul] using add_mem hr hs /-- The product of two elements of the additive closure of a submonoid `M` is an element of the additive closure of `M`. -/ theorem mul_mem_add_closure (ha : a ∈ AddSubmonoid.closure (S : Set R)) (hb : b ∈ AddSubmonoid.closure (S : Set R)) : a * b ∈ AddSubmonoid.closure (S : Set R) := by - revert a - apply @AddSubmonoid.closure_induction _ _ _ - (fun z => ∀ {a : R}, a ∈ AddSubmonoid.closure ↑S → a * z ∈ AddSubmonoid.closure ↑S) - _ hb <;> clear hb b - · exact fun r hr b hb => MulMemClass.mul_right_mem_add_closure hb hr - · exact fun _ => by simp only [mul_zero, (AddSubmonoid.closure (S : Set R)).zero_mem] - · simp_rw [mul_add] - exact fun r s hr hs b hb => (AddSubmonoid.closure (S : Set R)).add_mem (hr hb) (hs hb) + induction hb using AddSubmonoid.closure_induction with + | mem r hr => exact MulMemClass.mul_right_mem_add_closure ha hr + | one => simp only [mul_zero, zero_mem _] + | mul r s _ _ hr hs => simpa only [mul_add] using add_mem hr hs /-- The product of an element of `S` and an element of the additive closure of a multiplicative submonoid `S` is contained in the additive closure of `S`. -/ diff --git a/Mathlib/Algebra/Group/Submonoid/Operations.lean b/Mathlib/Algebra/Group/Submonoid/Operations.lean index a08c3cc0ece0c7..300498e17328b7 100644 --- a/Mathlib/Algebra/Group/Submonoid/Operations.lean +++ b/Mathlib/Algebra/Group/Submonoid/Operations.lean @@ -587,13 +587,8 @@ theorem coe_equivMapOfInjective_apply (f : M →* N) (hf : Function.Injective f) @[to_additive (attr := simp)] theorem closure_closure_coe_preimage {s : Set M} : closure (((↑) : closure s → M) ⁻¹' s) = ⊤ := - eq_top_iff.2 fun x => - Subtype.recOn x fun x hx _ => by - refine closure_induction' - (p := fun y hy ↦ (⟨y, hy⟩ : closure s) ∈ closure (((↑) : closure s → M) ⁻¹' s)) - _ (fun g hg => subset_closure hg) ?_ (fun g₁ g₂ hg₁ hg₂ => ?_) hx - · exact Submonoid.one_mem _ - · exact Submonoid.mul_mem _ + 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`. -/ diff --git a/Mathlib/Algebra/Group/Submonoid/Pointwise.lean b/Mathlib/Algebra/Group/Submonoid/Pointwise.lean index 9434237fea0f10..9983f082743b8e 100644 --- a/Mathlib/Algebra/Group/Submonoid/Pointwise.lean +++ b/Mathlib/Algebra/Group/Submonoid/Pointwise.lean @@ -85,11 +85,11 @@ theorem sup_eq_closure_mul (H K : Submonoid M) : H ⊔ K = closure ((H : Set M) @[to_additive] theorem pow_smul_mem_closure_smul {N : Type*} [CommMonoid N] [MulAction M N] [IsScalarTower M N N] (r : M) (s : Set N) {x : N} (hx : x ∈ closure s) : ∃ n : ℕ, r ^ n • x ∈ closure (r • s) := by - refine @closure_induction N _ s (fun x : N => ∃ n : ℕ, r ^ n • x ∈ closure (r • s)) _ hx ?_ ?_ ?_ - · intro x hx - exact ⟨1, subset_closure ⟨_, hx, by rw [pow_one]⟩⟩ - · exact ⟨0, by simpa using one_mem _⟩ - · rintro x y ⟨nx, hx⟩ ⟨ny, hy⟩ + induction hx using closure_induction with + | mem x hx => exact ⟨1, subset_closure ⟨_, hx, by rw [pow_one]⟩⟩ + | one => exact ⟨0, by simpa using one_mem _⟩ + | mul x y _ _ hx hy => + obtain ⟨⟨nx, hx⟩, ⟨ny, hy⟩⟩ := And.intro hx hy use ny + nx rw [pow_add, mul_smul, ← smul_mul_assoc, mul_comm, ← smul_mul_assoc] exact mul_mem hy hx diff --git a/Mathlib/Algebra/Group/Subsemigroup/Basic.lean b/Mathlib/Algebra/Group/Subsemigroup/Basic.lean index fa82da88595fa6..31ab296bcc1c3a 100644 --- a/Mathlib/Algebra/Group/Subsemigroup/Basic.lean +++ b/Mathlib/Algebra/Group/Subsemigroup/Basic.lean @@ -141,30 +141,31 @@ is preserved under multiplication, then `p` holds for all elements of the closur @[to_additive (attr := elab_as_elim) "An induction principle for additive closure membership. If `p` holds for all elements of `s`, and is preserved under addition, then `p` holds for all elements of the additive closure of `s`."] -theorem closure_induction {p : M → Prop} {x} (h : x ∈ closure s) (mem : ∀ x ∈ s, p x) - (mul : ∀ x y, p x → p y → p (x * y)) : p x := - (@closure_le _ _ _ ⟨p, mul _ _⟩).2 mem h - -/-- A dependent version of `Subsemigroup.closure_induction`. -/ -@[to_additive (attr := elab_as_elim) "A dependent version of `AddSubsemigroup.closure_induction`. "] -theorem closure_induction' (s : Set M) {p : ∀ x, x ∈ closure s → Prop} +theorem closure_induction {p : (x : M) → x ∈ closure s → Prop} (mem : ∀ (x) (h : x ∈ s), p x (subset_closure h)) - (mul : ∀ x hx y hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) {x} (hx : x ∈ closure s) : - p x hx := by - refine Exists.elim ?_ fun (hx : x ∈ closure s) (hc : p x hx) => hc - exact - closure_induction hx (fun x hx => ⟨_, mem x hx⟩) fun x y ⟨hx', hx⟩ ⟨hy', hy⟩ => - ⟨_, mul _ _ _ _ hx hy⟩ + (mul : ∀ x y hx hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) {x} (hx : x ∈ closure s) : + p x hx := + let S : Subsemigroup M := + { carrier := { x | ∃ hx, p x hx } + mul_mem' := fun ⟨_, hpx⟩ ⟨_, hpy⟩ ↦ ⟨_, mul _ _ _ _ hpx hpy⟩ } + closure_le (S := S) |>.mpr (fun y hy ↦ ⟨subset_closure hy, mem y hy⟩) hx |>.elim fun _ ↦ id + +@[deprecated closure_induction (since := "2024-10-09")] +alias closure_induction' := closure_induction /-- An induction principle for closure membership for predicates with two arguments. -/ @[to_additive (attr := elab_as_elim) "An induction principle for additive closure membership for predicates with two arguments."] -theorem closure_induction₂ {p : M → M → Prop} {x} {y : M} (hx : x ∈ closure s) (hy : y ∈ closure s) - (Hs : ∀ x ∈ s, ∀ y ∈ s, p x y) (Hmul_left : ∀ x y z, p x z → p y z → p (x * y) z) - (Hmul_right : ∀ x y z, p z x → p z y → p z (x * y)) : p x y := - closure_induction hx - (fun x xs => closure_induction hy (Hs x xs) fun z _ h₁ h₂ => Hmul_right z _ _ h₁ h₂) - fun _ _ h₁ h₂ => Hmul_left _ _ _ h₁ h₂ +theorem closure_induction₂ {p : (x y : M) → x ∈ closure s → y ∈ closure s → Prop} + (mem : ∀ (x) (y) (hx : x ∈ s) (hy : y ∈ s), p x y (subset_closure hx) (subset_closure hy)) + (mul_left : ∀ x y z hx hy hz, p x z hx hz → p y z hy hz → p (x * y) z (mul_mem hx hy) hz) + (mul_right : ∀ x y z hx hy hz, p z x hz hx → p z y hz hy → p z (x * y) hz (mul_mem hx hy)) + {x y : M} (hx : x ∈ closure s) (hy : y ∈ closure s) : p x y hx hy := by + induction hx using closure_induction with + | mem z hz => induction hy using closure_induction with + | mem _ h => exact mem _ _ hz h + | mul _ _ _ _ h₁ h₂ => exact mul_right _ _ _ _ _ _ h₁ h₂ + | mul _ _ _ _ h₁ h₂ => exact mul_left _ _ _ _ _ hy h₁ h₂ /-- If `s` is a dense set in a magma `M`, `Subsemigroup.closure s = ⊤`, then in order to prove that some predicate `p` holds for all `x : M` it suffices to verify `p x` for `x ∈ s`, @@ -173,11 +174,24 @@ and verify that `p x` and `p y` imply `p (x * y)`. -/ `AddSubsemigroup.closure 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 x` and `p y` imply `p (x + y)`."] -theorem dense_induction {p : M → Prop} (x : M) {s : Set M} (hs : closure s = ⊤) - (mem : ∀ x ∈ s, p x) - (mul : ∀ x y, p x → p y → p (x * y)) : p x := by - have : ∀ x ∈ closure s, p x := fun x hx => closure_induction hx mem mul - simpa [hs] using this x +theorem dense_induction {p : M → Prop} (s : Set M) (closure : closure s = ⊤) + (mem : ∀ x ∈ s, p x) (mul : ∀ x y, p x → p y → p (x * y)) (x : M) : + p x := by + induction closure.symm ▸ mem_top x using closure_induction with + | mem _ h => exact mem _ h + | mul _ _ _ _ h₁ h₂ => exact mul _ _ h₁ h₂ + +/- The argument `s : Set M` is explicit in `Subsemigroup.dense_induction` because the type of the +induction variable, namely `x : M`, does not reference `x`. Making `s` explicit allows the user +to apply the induction principle while deferring the proof of `closure s = ⊤` without creating +metavariables, as in the following example. -/ +example {p : M → Prop} (s : Set M) (closure : closure s = ⊤) + (mem : ∀ x ∈ s, p x) (mul : ∀ x y, p x → p y → p (x * y)) (x : M) : + p x := by + induction x using dense_induction s with + | closure => exact closure + | mem x hx => exact mem x hx + | mul _ _ h₁ h₂ => exact mul _ _ h₁ h₂ variable (M) @@ -263,8 +277,8 @@ def ofDense {M N} [Semigroup M] [Semigroup N] {s : Set M} (f : M → N) (hs : cl M →ₙ* N where toFun := f map_mul' x y := - dense_induction y hs (fun y hy x => hmul x y hy) - (fun y₁ y₂ h₁ h₂ x => by simp only [← mul_assoc, h₁, h₂]) x + dense_induction _ hs (fun y hy x => hmul x y hy) + (fun y₁ y₂ h₁ h₂ x => by simp only [← mul_assoc, h₁, h₂]) y x /-- Let `s` be a subset of an additive semigroup `M` such that the closure of `s` is the whole semigroup. Then `AddHom.ofDense` defines an additive homomorphism from `M` asking for a proof diff --git a/Mathlib/Algebra/Group/Subsemigroup/Membership.lean b/Mathlib/Algebra/Group/Subsemigroup/Membership.lean index 0dd74bcae66544..c00916259db08d 100644 --- a/Mathlib/Algebra/Group/Subsemigroup/Membership.lean +++ b/Mathlib/Algebra/Group/Subsemigroup/Membership.lean @@ -47,8 +47,8 @@ theorem mem_iSup_of_directed {S : ι → Subsemigroup M} (hS : Directed (· ≤ refine ⟨?_, fun ⟨i, hi⟩ ↦ le_iSup S i hi⟩ suffices x ∈ closure (⋃ 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 y hy ↦ mem_iUnion.mp hy) ?_ - rintro x y ⟨i, hi⟩ ⟨j, hj⟩ + refine fun hx ↦ closure_induction (fun y hy ↦ mem_iUnion.mp hy) ?_ hx + rintro x y - - ⟨i, hi⟩ ⟨j, hj⟩ rcases hS i j with ⟨k, hki, hkj⟩ exact ⟨k, (S k).mul_mem (hki hi) (hkj hj)⟩ @@ -103,7 +103,7 @@ the supremum of `S`."] theorem iSup_induction (S : ι → Subsemigroup M) {C : M → Prop} {x₁ : M} (hx₁ : x₁ ∈ ⨆ i, S i) (mem : ∀ i, ∀ x₂ ∈ S i, C x₂) (mul : ∀ x y, C x → C y → C (x * y)) : C x₁ := by rw [iSup_eq_closure] at hx₁ - refine closure_induction hx₁ (fun x₂ hx₂ => ?_) mul + refine closure_induction (fun x₂ hx₂ => ?_) (fun x y _ _ ↦ mul x y) hx₁ obtain ⟨i, hi⟩ := Set.mem_iUnion.mp hx₂ exact mem _ _ hi diff --git a/Mathlib/Algebra/Group/Subsemigroup/Operations.lean b/Mathlib/Algebra/Group/Subsemigroup/Operations.lean index 85f523619d7ca3..533dcfa812d356 100644 --- a/Mathlib/Algebra/Group/Subsemigroup/Operations.lean +++ b/Mathlib/Algebra/Group/Subsemigroup/Operations.lean @@ -498,10 +498,8 @@ theorem coe_equivMapOfInjective_apply (f : M →ₙ* N) (hf : Function.Injective @[to_additive (attr := simp)] theorem closure_closure_coe_preimage {s : Set M} : closure ((Subtype.val : closure s → M) ⁻¹' s) = ⊤ := - eq_top_iff.2 fun x => - Subtype.recOn x fun _ hx' _ => closure_induction' - (p := fun y hy ↦ (⟨y, hy⟩ : closure s) ∈ closure (((↑) : closure s → M) ⁻¹' s)) - _ (fun _ hg => subset_closure hg) (fun _ _ _ _ => Subsemigroup.mul_mem _) hx' + eq_top_iff.2 fun x _ ↦ Subtype.recOn x fun _ hx' ↦ + closure_induction (fun _ h ↦ subset_closure h) (fun _ _ _ _ ↦ mul_mem) hx' /-- Given `Subsemigroup`s `s`, `t` of semigroups `M`, `N` respectively, `s × t` as a subsemigroup of `M × N`. -/ diff --git a/Mathlib/Algebra/Lie/BaseChange.lean b/Mathlib/Algebra/Lie/BaseChange.lean index 47f4ab1bcd2c5f..5ca3c13673a21a 100644 --- a/Mathlib/Algebra/Lie/BaseChange.lean +++ b/Mathlib/Algebra/Lie/BaseChange.lean @@ -223,25 +223,26 @@ lemma lie_baseChange {I : LieIdeal R L} {N : LieSubmodule R L M} : · rintro - ⟨x, hx, m, hm, rfl⟩ revert m apply Submodule.span_induction - (p := fun x' ↦ ∀ m' ∈ N.baseChange A, ⁅x', m'⁆ ∈ Submodule.span A s) hx + (p := fun x' _ ↦ ∀ m' ∈ N.baseChange A, ⁅x', m'⁆ ∈ Submodule.span A s) (hx := hx) · rintro _ ⟨y : L, hy : y ∈ I, rfl⟩ m hm - apply Submodule.span_induction (p := fun m' ↦ ⁅(1 : A) ⊗ₜ[R] y, m'⁆ ∈ Submodule.span A s) hm + apply Submodule.span_induction + (p := fun m' _ ↦ ⁅(1 : A) ⊗ₜ[R] y, m'⁆ ∈ Submodule.span A s) (hx := hm) · rintro - ⟨m', hm' : m' ∈ N, rfl⟩ rw [TensorProduct.mk_apply, LieAlgebra.ExtendScalars.bracket_tmul, mul_one] apply Submodule.subset_span exact ⟨y, hy, m', hm', rfl⟩ · simp - · intro u v hu hv + · intro u v _ _ hu hv rw [lie_add] exact Submodule.add_mem _ hu hv - · intro a u hu + · intro a u _ hu rw [lie_smul] exact Submodule.smul_mem _ a hu · simp - · intro x y hx hy m' hm' + · intro x y _ _ hx hy m' hm' rw [add_lie] exact Submodule.add_mem _ (hx _ hm') (hy _ hm') - · intro a x hx m' hm' + · intro a x _ hx m' hm' rw [smul_lie] exact Submodule.smul_mem _ a (hx _ hm') diff --git a/Mathlib/Algebra/Lie/Character.lean b/Mathlib/Algebra/Lie/Character.lean index 29b50665fe1db8..24978ce0250550 100644 --- a/Mathlib/Algebra/Lie/Character.lean +++ b/Mathlib/Algebra/Lie/Character.lean @@ -49,11 +49,11 @@ theorem lieCharacter_apply_of_mem_derived (χ : LieCharacter R L) {x : L} (h : x ∈ derivedSeries R L 1) : χ x = 0 := by rw [derivedSeries_def, derivedSeriesOfIdeal_succ, derivedSeriesOfIdeal_zero, ← LieSubmodule.mem_coeSubmodule, LieSubmodule.lieIdeal_oper_eq_linear_span] at h - refine Submodule.span_induction h ?_ ?_ ?_ ?_ + refine Submodule.span_induction ?_ ?_ ?_ ?_ h · rintro y ⟨⟨z, hz⟩, ⟨⟨w, hw⟩, rfl⟩⟩; apply lieCharacter_apply_lie · exact χ.map_zero - · intro y z hy hz; rw [LieHom.map_add, hy, hz, add_zero] - · intro t y hy; rw [LieHom.map_smul, hy, smul_zero] + · intro y z _ _ hy hz; rw [LieHom.map_add, hy, hz, add_zero] + · intro t y _ hy; rw [LieHom.map_smul, hy, smul_zero] /-- For an Abelian Lie algebra, characters are just linear forms. -/ @[simps! apply symm_apply] diff --git a/Mathlib/Algebra/Lie/IdealOperations.lean b/Mathlib/Algebra/Lie/IdealOperations.lean index bcd4cad1d3887b..75e9facacd878c 100644 --- a/Mathlib/Algebra/Lie/IdealOperations.lean +++ b/Mathlib/Algebra/Lie/IdealOperations.lean @@ -85,14 +85,14 @@ theorem lieIdeal_oper_eq_linear_span [LieModule R L M] : have aux : ∀ (y : L), ∀ m' ∈ Submodule.span R s, ⁅y, m'⁆ ∈ Submodule.span R s := by intro y m' hm' refine Submodule.span_induction (R := R) (M := M) (s := s) - (p := fun m' ↦ ⁅y, m'⁆ ∈ Submodule.span R s) hm' ?_ ?_ ?_ ?_ + (p := fun m' _ ↦ ⁅y, m'⁆ ∈ Submodule.span R s) ?_ ?_ ?_ ?_ hm' · rintro m'' ⟨x, n, hm''⟩; rw [← hm'', leibniz_lie] refine Submodule.add_mem _ ?_ ?_ <;> apply Submodule.subset_span · use ⟨⁅y, ↑x⁆, I.lie_mem x.property⟩, n · use x, ⟨⁅y, ↑n⁆, N.lie_mem n.property⟩ · simp only [lie_zero, Submodule.zero_mem] - · intro m₁ m₂ hm₁ hm₂; rw [lie_add]; exact Submodule.add_mem _ hm₁ hm₂ - · intro t m'' hm''; rw [lie_smul]; exact Submodule.smul_mem _ t hm'' + · intro m₁ m₂ _ _ hm₁ hm₂; rw [lie_add]; exact Submodule.add_mem _ hm₁ hm₂ + · intro t m'' _ hm''; rw [lie_smul]; exact Submodule.smul_mem _ t hm'' change _ ≤ ({ Submodule.span R s with lie_mem := fun hm' => aux _ _ hm' } : LieSubmodule R L M) rw [lieIdeal_oper_eq_span, lieSpan_le] exact Submodule.subset_span diff --git a/Mathlib/Algebra/Lie/TraceForm.lean b/Mathlib/Algebra/Lie/TraceForm.lean index bddebc215744c7..62c493ca9f4c7d 100644 --- a/Mathlib/Algebra/Lie/TraceForm.lean +++ b/Mathlib/Algebra/Lie/TraceForm.lean @@ -135,7 +135,7 @@ lemma traceForm_eq_zero_if_mem_lcs_of_mem_ucs {x y : L} (k : ℕ) rw [LieSubmodule.ucs_succ, LieSubmodule.mem_normalizer] at hy simp_rw [LieIdeal.lcs_succ, ← LieSubmodule.mem_coeSubmodule, LieSubmodule.lieIdeal_oper_eq_linear_span', LieSubmodule.mem_top, true_and] at hx - refine Submodule.span_induction hx ?_ ?_ (fun z w hz hw ↦ ?_) (fun t z hz ↦ ?_) + refine Submodule.span_induction ?_ ?_ (fun z w _ _ hz hw ↦ ?_) (fun t z _ hz ↦ ?_) hx · rintro - ⟨z, w, hw, rfl⟩ rw [← lie_skew, map_neg, LinearMap.neg_apply, neg_eq_zero, traceForm_apply_lie_apply] exact ih hw (hy _) @@ -192,9 +192,10 @@ lemma trace_toEnd_eq_zero_of_mem_lcs rw [lowerCentralSeries_succ, ← LieSubmodule.mem_coeSubmodule, LieSubmodule.lieIdeal_oper_eq_linear_span'] at hx simpa using hx - refine Submodule.span_induction (p := fun x ↦ trace R _ (toEnd R L M x) = 0) hx - (fun y ⟨u, v, huv⟩ ↦ ?_) ?_ (fun u v hu hv ↦ ?_) (fun t u hu ↦ ?_) - · simp [← huv] + refine Submodule.span_induction (p := fun x _ ↦ trace R _ (toEnd R L M x) = 0) + ?_ ?_ (fun u v _ _ hu hv ↦ ?_) (fun t u _ hu ↦ ?_) hx + · intro y ⟨u, v, huv⟩ + simp [← huv] · simp · simp [hu, hv] · simp [hu] diff --git a/Mathlib/Algebra/Lie/Weights/Chain.lean b/Mathlib/Algebra/Lie/Weights/Chain.lean index 428b6ff73884c9..4107e1e4cd27ff 100644 --- a/Mathlib/Algebra/Lie/Weights/Chain.lean +++ b/Mathlib/Algebra/Lie/Weights/Chain.lean @@ -160,7 +160,7 @@ lemma trace_toEnd_genWeightSpaceChain_eq_zero {x : H} (hx : x ∈ corootSpace α) : LinearMap.trace R _ (toEnd R H (genWeightSpaceChain M α χ p q) x) = 0 := by rw [LieAlgebra.mem_corootSpace'] at hx - induction hx using Submodule.span_induction' + induction hx using Submodule.span_induction · next u hu => obtain ⟨y, hy, z, hz, hyz⟩ := hu let f : Module.End R (genWeightSpaceChain M α χ p q) := diff --git a/Mathlib/Algebra/Lie/Weights/Killing.lean b/Mathlib/Algebra/Lie/Weights/Killing.lean index 80e8ca2ed6bf34..70df35ad7a1177 100644 --- a/Mathlib/Algebra/Lie/Weights/Killing.lean +++ b/Mathlib/Algebra/Lie/Weights/Killing.lean @@ -429,7 +429,7 @@ lemma traceForm_eq_zero_of_mem_ker_of_mem_span_coroot {α : Weight K H L} {x y : (hx : x ∈ α.ker) (hy : y ∈ K ∙ coroot α) : traceForm K H L x y = 0 := by rw [← coe_corootSpace_eq_span_singleton, LieSubmodule.mem_coeSubmodule, mem_corootSpace'] at hy - induction hy using Submodule.span_induction' with + induction hy using Submodule.span_induction with | mem z hz => obtain ⟨u, hu, v, -, huv⟩ := hz change killingForm K L (x : L) (z : L) = 0 diff --git a/Mathlib/Algebra/Module/Submodule/Bilinear.lean b/Mathlib/Algebra/Module/Submodule/Bilinear.lean index 4ec89546d980da..11fcc080a61120 100644 --- a/Mathlib/Algebra/Module/Submodule/Bilinear.lean +++ b/Mathlib/Algebra/Module/Submodule/Bilinear.lean @@ -55,10 +55,10 @@ 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 apply le_antisymm · rw [map₂_le] - apply @span_induction' R M _ _ _ s + apply @span_induction R M _ _ _ s on_goal 1 => intro a ha - apply @span_induction' R N _ _ _ t + apply @span_induction R N _ _ _ t · intro b hb exact subset_span ⟨_, ‹_›, _, ‹_›, rfl⟩ all_goals diff --git a/Mathlib/Algebra/Module/Submodule/Pointwise.lean b/Mathlib/Algebra/Module/Submodule/Pointwise.lean index c8d8a18665f393..7c97407ef44fc1 100644 --- a/Mathlib/Algebra/Module/Submodule/Pointwise.lean +++ b/Mathlib/Algebra/Module/Submodule/Pointwise.lean @@ -530,7 +530,7 @@ lemma coe_span_smul {R' M' : Type*} [CommSemiring R'] [AddCommMonoid M'] [Module (Ideal.span s : Set R') • N = s • N := set_smul_eq_of_le _ _ _ (by rintro r n hr hn - induction hr using Submodule.span_induction' with + induction hr using Submodule.span_induction with | mem _ h => exact mem_set_smul_of_mem_mem h hn | zero => rw [zero_smul]; exact Submodule.zero_mem _ | add _ _ _ _ ihr ihs => rw [add_smul]; exact Submodule.add_mem _ ihr ihs diff --git a/Mathlib/Algebra/Order/Ring/Star.lean b/Mathlib/Algebra/Order/Ring/Star.lean index 06f3ffa17e0cc6..8c80169e52db5c 100644 --- a/Mathlib/Algebra/Order/Ring/Star.lean +++ b/Mathlib/Algebra/Order/Ring/Star.lean @@ -35,7 +35,7 @@ argument in the instance below for `mul_le_mul_of_nonneg_right`. -/ private lemma mul_le_mul_of_nonneg_left {R : Type*} [CommSemiring R] [PartialOrder R] [StarRing R] [StarOrderedRing R] {a b c : R} (hab : a ≤ b) (hc : 0 ≤ c) : c * a ≤ c * b := by rw [StarOrderedRing.nonneg_iff] at hc - induction hc using AddSubmonoid.closure_induction' with + induction hc using AddSubmonoid.closure_induction with | mem _ h => obtain ⟨x, rfl⟩ := h simp_rw [mul_assoc, mul_comm x, ← mul_assoc] diff --git a/Mathlib/Algebra/Order/Star/Basic.lean b/Mathlib/Algebra/Order/Star/Basic.lean index b07145ac25911b..bcda0ea6851ab9 100644 --- a/Mathlib/Algebra/Order/Star/Basic.lean +++ b/Mathlib/Algebra/Order/Star/Basic.lean @@ -96,10 +96,10 @@ lemma of_le_iff [NonUnitalSemiring R] [PartialOrder R] [StarRing R] exact ⟨star p * p, AddSubmonoid.subset_closure ⟨p, rfl⟩, hp⟩ · rintro ⟨p, hp, hpxy⟩ revert x y hpxy - refine AddSubmonoid.closure_induction hp ?_ (fun x y h => add_zero x ▸ h.ge) ?_ + refine AddSubmonoid.closure_induction ?_ (fun x y h => add_zero x ▸ h.ge) ?_ hp · rintro _ ⟨s, rfl⟩ x y rfl exact (h_le_iff _ _).mpr ⟨s, rfl⟩ - · rintro a b ha hb x y rfl + · rintro _ _ _ _ ha hb x y rfl rw [← add_assoc] exact (ha _ _ rfl).trans (hb _ _ rfl) @@ -160,8 +160,8 @@ theorem mul_star_self_nonneg (r : R) : 0 ≤ r * star r := by @[aesop safe apply] theorem conjugate_nonneg {a : R} (ha : 0 ≤ a) (c : R) : 0 ≤ star c * a * c := by rw [StarOrderedRing.nonneg_iff] at ha - refine AddSubmonoid.closure_induction ha (fun x hx => ?_) - (by rw [mul_zero, zero_mul]) fun x y hx hy => ?_ + refine AddSubmonoid.closure_induction (fun x hx => ?_) + (by rw [mul_zero, zero_mul]) (fun x y _ _ hx hy => ?_) ha · obtain ⟨x, rfl⟩ := hx convert star_mul_self_nonneg (x * c) using 1 rw [star_mul, ← mul_assoc, mul_assoc _ _ c] @@ -302,12 +302,12 @@ lemma StarModule.smul_lt_smul_of_pos {a b : A} {c : R} (hab : a < b) (hc : 0 < c case le => have hab := le_of_lt hab rw [StarOrderedRing.nonneg_iff] at hab ⊢ - refine AddSubmonoid.closure_induction hab ?mem ?zero ?add + refine AddSubmonoid.closure_induction ?mem ?zero ?add hab case mem => intro x hx have hc := le_of_lt hc rw [StarOrderedRing.nonneg_iff] at hc - refine AddSubmonoid.closure_induction hc ?memc ?zeroc ?addc + refine AddSubmonoid.closure_induction ?memc ?zeroc ?addc hc case memc => intro c' hc' obtain ⟨z, hz⟩ := hc' @@ -316,9 +316,9 @@ lemma StarModule.smul_lt_smul_of_pos {a b : A} {c : R} (hab : a < b) (hc : 0 < c refine ⟨z • y, ?_⟩ simp only [star_smul, smul_mul_smul_comm, hz, hy] case zeroc => simpa only [zero_smul] using zero_mem _ - case addc => exact fun c' d ↦ by simpa only [add_smul] using add_mem + case addc => exact fun c' d _ _ ↦ by simpa only [add_smul] using add_mem case zero => simpa only [smul_zero] using zero_mem _ - case add => exact fun x y ↦ by simpa only [smul_add] using add_mem + case add => exact fun x y _ _ ↦ by simpa only [smul_add] using add_mem case ne => refine (smul_ne_zero ?_ ?_).symm · exact (ne_of_lt hc).symm @@ -339,7 +339,7 @@ lemma NonUnitalStarRingHom.map_le_map_of_map_star (f : R →⋆ₙ+* S) {x y : R obtain ⟨p, hp, rfl⟩ := hxy refine ⟨f p, ?_, map_add f _ _⟩ have hf : ∀ r, f (star r) = star (f r) := map_star _ - induction hp using AddSubmonoid.closure_induction' + induction hp using AddSubmonoid.closure_induction all_goals aesop instance (priority := 100) StarRingHomClass.instOrderHomClass [FunLike F R S] diff --git a/Mathlib/Algebra/Ring/Subring/Basic.lean b/Mathlib/Algebra/Ring/Subring/Basic.lean index 1a971aa4e69f61..781bbdda04c35c 100644 --- a/Mathlib/Algebra/Ring/Subring/Basic.lean +++ b/Mathlib/Algebra/Ring/Subring/Basic.lean @@ -758,105 +758,118 @@ theorem closure_eq_of_le {s : Set R} {t : Subring R} (h₁ : s ⊆ t) (h₂ : t of `s`, and is preserved under addition, negation, and multiplication, then `p` holds for all elements of the closure of `s`. -/ @[elab_as_elim] -theorem closure_induction {s : Set R} {p : R → Prop} {x} (h : x ∈ closure s) (Hs : ∀ x ∈ s, p x) - (zero : p 0) (one : p 1) (add : ∀ x y, p x → p y → p (x + y)) (neg : ∀ x : R, p x → p (-x)) - (mul : ∀ x y, p x → p y → p (x * y)) : p x := - (@closure_le _ _ _ ⟨⟨⟨⟨p, @mul⟩, one⟩, @add, zero⟩, @neg⟩).2 Hs h - -@[elab_as_elim] -theorem closure_induction' {s : Set R} {p : ∀ x, x ∈ closure s → Prop} - (mem : ∀ (x) (h : x ∈ s), p x (subset_closure h)) +theorem closure_induction {s : Set R} {p : (x : R) → x ∈ closure s → Prop} + (mem : ∀ (x) (hx : x ∈ s), p x (subset_closure hx)) (zero : p 0 (zero_mem _)) (one : p 1 (one_mem _)) - (add : ∀ x hx y hy, p x hx → p y hy → p (x + y) (add_mem hx hy)) + (add : ∀ x y hx hy, p x hx → p y hy → p (x + y) (add_mem hx hy)) (neg : ∀ x hx, p x hx → p (-x) (neg_mem hx)) - (mul : ∀ x hx y hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) - {a : R} (ha : a ∈ closure s) : p a ha := by - refine Exists.elim ?_ fun (ha : a ∈ closure s) (hc : p a ha) => hc - refine - closure_induction ha (fun m hm => ⟨subset_closure hm, mem m hm⟩) ⟨zero_mem _, zero⟩ - ⟨one_mem _, one⟩ ?_ (fun x hx => hx.elim fun hx' hx => ⟨neg_mem hx', neg _ _ hx⟩) ?_ - · exact (fun x y hx hy => hx.elim fun hx' hx => hy.elim fun hy' hy => - ⟨add_mem hx' hy', add _ _ _ _ hx hy⟩) - · exact (fun x y hx hy => hx.elim fun hx' hx => hy.elim fun hy' hy => - ⟨mul_mem hx' hy', mul _ _ _ _ hx hy⟩) + (mul : ∀ x y hx hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) + {x} (hx : x ∈ closure s) : p x hx := + let K : Subring R := + { carrier := { x | ∃ hx, p x hx } + mul_mem' := fun ⟨_, hpx⟩ ⟨_, hpy⟩ ↦ ⟨_, mul _ _ _ _ hpx hpy⟩ + add_mem' := fun ⟨_, hpx⟩ ⟨_, hpy⟩ ↦ ⟨_, add _ _ _ _ hpx hpy⟩ + neg_mem' := fun ⟨_, hpx⟩ ↦ ⟨_, neg _ _ hpx⟩ + zero_mem' := ⟨_, zero⟩ + one_mem' := ⟨_, one⟩ } + closure_le (t := K) |>.mpr (fun y hy ↦ ⟨subset_closure hy, mem y hy⟩) hx |>.elim fun _ ↦ id + +@[deprecated closure_induction (since := "2024-10-10")] +alias closure_induction' := closure_induction /-- An induction principle for closure membership, for predicates with two arguments. -/ @[elab_as_elim] -theorem closure_induction₂ {s : Set R} {p : R → R → Prop} {a b : R} (ha : a ∈ closure s) - (hb : b ∈ closure s) (Hs : ∀ x ∈ s, ∀ y ∈ s, p x y) (H0_left : ∀ x, p 0 x) - (H0_right : ∀ x, p x 0) (H1_left : ∀ x, p 1 x) (H1_right : ∀ x, p x 1) - (Hneg_left : ∀ x y, p x y → p (-x) y) (Hneg_right : ∀ x y, p x y → p x (-y)) - (Hadd_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ + x₂) y) - (Hadd_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ + y₂)) - (Hmul_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ * x₂) y) - (Hmul_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ * y₂)) : p a b := by - refine - closure_induction hb ?_ (H0_right _) (H1_right _) (Hadd_right a) (Hneg_right a) (Hmul_right a) - refine closure_induction ha Hs (fun x _ => H0_left x) (fun x _ => H1_left x) ?_ ?_ ?_ - · exact fun x y H₁ H₂ z zs => Hadd_left x y z (H₁ z zs) (H₂ z zs) - · exact fun x hx z zs => Hneg_left x z (hx z zs) - · exact fun x y H₁ H₂ z zs => Hmul_left x y z (H₁ z zs) (H₂ z zs) +theorem closure_induction₂ {s : Set R} {p : (x y : R) → x ∈ closure s → y ∈ closure s → Prop} + (mem_mem : ∀ (x) (y) (hx : x ∈ s) (hy : y ∈ s), p x y (subset_closure hx) (subset_closure hy)) + (zero_left : ∀ x hx, p 0 x (zero_mem _) hx) (zero_right : ∀ x hx, p x 0 hx (zero_mem _)) + (one_left : ∀ x hx, p 1 x (one_mem _) hx) (one_right : ∀ x hx, p x 1 hx (one_mem _)) + (neg_left : ∀ x y hx hy, p x y hx hy → p (-x) y (neg_mem hx) hy) + (neg_right : ∀ x y hx hy, p x y hx hy → p x (-y) hx (neg_mem hy)) + (add_left : ∀ x y z hx hy hz, p x z hx hz → p y z hy hz → p (x + y) z (add_mem hx hy) hz) + (add_right : ∀ x y z hx hy hz, p x y hx hy → p x z hx hz → p x (y + z) hx (add_mem hy hz)) + (mul_left : ∀ x y z hx hy hz, p x z hx hz → p y z hy hz → p (x * y) z (mul_mem hx hy) hz) + (mul_right : ∀ x y z hx hy hz, p x y hx hy → p x z hx hz → p x (y * z) hx (mul_mem hy hz)) + {x y : R} (hx : x ∈ closure s) (hy : y ∈ closure s) : + p x y hx hy := by + induction hy using closure_induction with + | mem z hz => induction hx using closure_induction with + | mem _ h => exact mem_mem _ _ h hz + | zero => exact zero_left _ _ + | one => exact one_left _ _ + | mul _ _ _ _ h₁ h₂ => exact mul_left _ _ _ _ _ _ h₁ h₂ + | add _ _ _ _ h₁ h₂ => exact add_left _ _ _ _ _ _ h₁ h₂ + | neg _ _ h => exact neg_left _ _ _ _ h + | zero => exact zero_right x hx + | one => exact one_right x hx + | mul _ _ _ _ h₁ h₂ => exact mul_right _ _ _ _ _ _ h₁ h₂ + | add _ _ _ _ h₁ h₂ => exact add_right _ _ _ _ _ _ h₁ h₂ + | neg _ _ h => exact neg_right _ _ _ _ h theorem mem_closure_iff {s : Set R} {x} : x ∈ closure s ↔ x ∈ AddSubgroup.closure (Submonoid.closure s : Set R) := - ⟨fun h => - closure_induction h (fun _ hx => AddSubgroup.subset_closure <| Submonoid.subset_closure hx) - (AddSubgroup.zero_mem _) - (AddSubgroup.subset_closure (Submonoid.one_mem (Submonoid.closure s))) - (fun _ _ hx hy => AddSubgroup.add_mem _ hx hy) (fun _ hx => AddSubgroup.neg_mem _ hx) - fun x _ hx hy => - AddSubgroup.closure_induction hy - (fun q hq => - AddSubgroup.closure_induction hx - (fun _ hp => AddSubgroup.subset_closure ((Submonoid.closure s).mul_mem hp hq)) - (by rw [zero_mul q]; apply AddSubgroup.zero_mem _) - (fun p₁ p₂ ihp₁ ihp₂ => by rw [add_mul p₁ p₂ q]; apply AddSubgroup.add_mem _ ihp₁ ihp₂) - fun x hx => by - have f : -x * q = -(x * q) := by simp - rw [f]; apply AddSubgroup.neg_mem _ hx) - (by rw [mul_zero x]; apply AddSubgroup.zero_mem _) - (fun q₁ q₂ ihq₁ ihq₂ => by rw [mul_add x q₁ q₂]; apply AddSubgroup.add_mem _ ihq₁ ihq₂) - fun z hz => by - have f : x * -z = -(x * z) := by simp - rw [f]; apply AddSubgroup.neg_mem _ hz, - fun h => - AddSubgroup.closure_induction (p := (· ∈ closure s)) h - (fun _ hx => - Submonoid.closure_induction hx (fun _ hx => subset_closure hx) (one_mem _) fun _ _ hx hy => - mul_mem hx hy) - (zero_mem _) (fun _ _ hx hy => add_mem hx hy) fun _ hx => neg_mem hx⟩ + ⟨fun h => by + induction h using closure_induction with + | mem _ hx => exact AddSubgroup.subset_closure (Submonoid.subset_closure hx) + | zero => exact zero_mem _ + | one => exact AddSubgroup.subset_closure (one_mem _) + | add _ _ _ _ hx hy => exact add_mem hx hy + | neg _ _ hx => exact neg_mem hx + | mul _ _ _hx _hy hx hy => + clear _hx _hy + induction hx, hy using AddSubgroup.closure_induction₂ with + | mem _ _ hx hy => exact AddSubgroup.subset_closure (mul_mem hx hy) + | one_left => simpa using zero_mem _ + | one_right => simpa using zero_mem _ + | mul_left _ _ _ _ _ _ h₁ h₂ => simpa [add_mul] using add_mem h₁ h₂ + | mul_right _ _ _ _ _ _ h₁ h₂ => simpa [mul_add] using add_mem h₁ h₂ + | inv_left _ _ _ _ h => simpa [neg_mul] using neg_mem h + | inv_right _ _ _ _ h => simpa [mul_neg] using neg_mem h, + fun h => by + induction h using AddSubgroup.closure_induction with + | mem x hx => + induction hx using Submonoid.closure_induction with + | mem _ h => exact subset_closure h + | one => exact one_mem _ + | mul _ _ _ _ h₁ h₂ => exact mul_mem h₁ h₂ + | one => exact zero_mem _ + | mul _ _ _ _ h₁ h₂ => exact add_mem h₁ h₂ + | inv _ _ h => exact neg_mem h⟩ /-- If all elements of `s : Set A` commute pairwise, then `closure s` is a commutative ring. -/ def closureCommRingOfComm {s : Set R} (hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a) : CommRing (closure s) := { (closure s).toRing with - mul_comm := fun x y => by + mul_comm := fun ⟨x, hx⟩ ⟨y, hy⟩ => by ext - simp only [Subring.coe_mul] - refine - closure_induction₂ x.prop y.prop hcomm (fun x => by simp only [mul_zero, zero_mul]) - (fun x => by simp only [mul_zero, zero_mul]) (fun x => by simp only [mul_one, one_mul]) - (fun x => by simp only [mul_one, one_mul]) - (fun x y hxy => by simp only [mul_neg, neg_mul, hxy]) - (fun x y hxy => by simp only [mul_neg, neg_mul, hxy]) - (fun x₁ x₂ y h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂]) - (fun x₁ x₂ y h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂]) - (fun x₁ x₂ y h₁ h₂ => by rw [← mul_assoc, ← h₁, mul_assoc x₁ y x₂, ← h₂, mul_assoc]) - fun x₁ x₂ y h₁ h₂ => by rw [← mul_assoc, h₁, mul_assoc, h₂, ← mul_assoc] } - -theorem exists_list_of_mem_closure {s : Set R} {x : R} (h : x ∈ closure s) : - ∃ L : List (List R), (∀ t ∈ L, ∀ y ∈ t, y ∈ s ∨ y = (-1 : R)) ∧ (L.map List.prod).sum = x := - AddSubgroup.closure_induction (G := R) - (p := (∃ L : List (List R), (∀ t ∈ L, ∀ y ∈ t, y ∈ s ∨ y = -1) ∧ (L.map List.prod).sum = ·)) - (mem_closure_iff.1 h) - (fun x hx => - let ⟨l, hl, h⟩ := Submonoid.exists_list_of_mem_closure hx - ⟨[l], by simp [h]; clear_aux_decl; tauto⟩) - ⟨[], by simp⟩ - (fun x y ⟨l, hl1, hl2⟩ ⟨m, hm1, hm2⟩ => - ⟨l ++ m, fun t ht => (List.mem_append.1 ht).elim (hl1 t) (hm1 t), by simp [hl2, hm2]⟩) - fun _ ⟨L, hL⟩ => - ⟨L.map (List.cons (-1)), + simp only [MulMemClass.mk_mul_mk] + induction hx, hy using closure_induction₂ with + | mem_mem x y hx hy => exact hcomm x hx y hy + | zero_left x _ => exact Commute.zero_left x + | zero_right x _ => exact Commute.zero_right x + | one_left x _ => exact Commute.one_left x + | one_right x _ => exact Commute.one_right x + | mul_left _ _ _ _ _ _ h₁ h₂ => exact Commute.mul_left h₁ h₂ + | mul_right _ _ _ _ _ _ h₁ h₂ => exact Commute.mul_right h₁ h₂ + | add_left _ _ _ _ _ _ h₁ h₂ => exact Commute.add_left h₁ h₂ + | add_right _ _ _ _ _ _ h₁ h₂ => exact Commute.add_right h₁ h₂ + | neg_left _ _ _ _ h => exact Commute.neg_left h + | neg_right _ _ _ _ h => exact Commute.neg_right h } + +theorem exists_list_of_mem_closure {s : Set R} {x : R} (hx : x ∈ closure s) : + ∃ L : List (List R), (∀ t ∈ L, ∀ y ∈ t, y ∈ s ∨ y = (-1 : R)) ∧ (L.map List.prod).sum = x := by + rw [mem_closure_iff] at hx + induction hx using AddSubgroup.closure_induction with + | mem _ hx => + obtain ⟨l, hl, h⟩ := Submonoid.exists_list_of_mem_closure hx + exact ⟨[l], by simp [h]; clear_aux_decl; tauto⟩ + | one => exact ⟨[], List.forall_mem_nil _, rfl⟩ + | mul _ _ _ _ hL hM => + obtain ⟨⟨L, HL1, HL2⟩, ⟨M, HM1, HM2⟩⟩ := And.intro hL hM + exact ⟨L ++ M, List.forall_mem_append.2 ⟨HL1, HM1⟩, by + rw [List.map_append, List.sum_append, HL2, HM2]⟩ + | inv _ _ hL => + obtain ⟨L, hL⟩ := hL + exact ⟨L.map (List.cons (-1)), List.forall_mem_map.2 fun j hj => List.forall_mem_cons.2 ⟨Or.inr rfl, hL.1 j hj⟩, hL.2 ▸ List.recOn L (by simp) diff --git a/Mathlib/Algebra/Ring/Subsemiring/Basic.lean b/Mathlib/Algebra/Ring/Subsemiring/Basic.lean index 07801d0fb5814c..a67f00afb054d6 100644 --- a/Mathlib/Algebra/Ring/Subsemiring/Basic.lean +++ b/Mathlib/Algebra/Ring/Subsemiring/Basic.lean @@ -746,61 +746,68 @@ theorem closure_addSubmonoid_closure {s : Set R} : of `s`, and is preserved under addition and multiplication, then `p` holds for all elements of the closure of `s`. -/ @[elab_as_elim] -theorem closure_induction {s : Set R} {p : R → Prop} {x} (h : x ∈ closure s) (mem : ∀ x ∈ s, p x) - (zero : p 0) (one : p 1) (add : ∀ x y, p x → p y → p (x + y)) - (mul : ∀ x y, p x → p y → p (x * y)) : p x := - (@closure_le _ _ _ ⟨⟨⟨p, @mul⟩, one⟩, @add, zero⟩).2 mem h - -@[elab_as_elim] -theorem closure_induction' {s : Set R} {p : ∀ x, x ∈ closure s → Prop} - (mem : ∀ (x) (h : x ∈ s), p x (subset_closure h)) +theorem closure_induction {s : Set R} {p : (x : R) → x ∈ closure s → Prop} + (mem : ∀ (x) (hx : x ∈ s), p x (subset_closure hx)) (zero : p 0 (zero_mem _)) (one : p 1 (one_mem _)) - (add : ∀ x hx y hy, p x hx → p y hy → p (x + y) (add_mem hx hy)) - (mul : ∀ x hx y hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) - {a : R} (ha : a ∈ closure s) : p a ha := by - refine Exists.elim ?_ fun (ha : a ∈ closure s) (hc : p a ha) => hc - refine - closure_induction ha (fun m hm => ⟨subset_closure hm, mem m hm⟩) ⟨zero_mem _, zero⟩ - ⟨one_mem _, one⟩ ?_ ?_ - · exact (fun x y hx hy => hx.elim fun hx' hx => hy.elim fun hy' hy => - ⟨add_mem hx' hy', add _ _ _ _ hx hy⟩) - · exact (fun x y hx hy => hx.elim fun hx' hx => hy.elim fun hy' hy => - ⟨mul_mem hx' hy', mul _ _ _ _ hx hy⟩) + (add : ∀ x y hx hy, p x hx → p y hy → p (x + y) (add_mem hx hy)) + (mul : ∀ x y hx hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) + {x} (hx : x ∈ closure s) : p x hx := + let K : Subsemiring R := + { carrier := { x | ∃ hx, p x hx } + mul_mem' := fun ⟨_, hpx⟩ ⟨_, hpy⟩ ↦ ⟨_, mul _ _ _ _ hpx hpy⟩ + add_mem' := fun ⟨_, hpx⟩ ⟨_, hpy⟩ ↦ ⟨_, add _ _ _ _ hpx hpy⟩ + one_mem' := ⟨_, one⟩ + zero_mem' := ⟨_, zero⟩ } + closure_le (t := K) |>.mpr (fun y hy ↦ ⟨subset_closure hy, mem y hy⟩) hx |>.elim fun _ ↦ id + +@[deprecated closure_induction (since := "2024-10-10")] +alias closure_induction' := closure_induction /-- An induction principle for closure membership for predicates with two arguments. -/ @[elab_as_elim] -theorem closure_induction₂ {s : Set R} {p : R → R → Prop} {x} {y : R} (hx : x ∈ closure s) - (hy : y ∈ closure s) (Hs : ∀ x ∈ s, ∀ y ∈ s, p x y) (H0_left : ∀ x, p 0 x) - (H0_right : ∀ x, p x 0) (H1_left : ∀ x, p 1 x) (H1_right : ∀ x, p x 1) - (Hadd_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ + x₂) y) - (Hadd_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ + y₂)) - (Hmul_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ * x₂) y) - (Hmul_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ * y₂)) : p x y := - closure_induction hx - (fun x₁ x₁s => - closure_induction hy (Hs x₁ x₁s) (H0_right x₁) (H1_right x₁) (Hadd_right x₁) (Hmul_right x₁)) - (H0_left y) (H1_left y) (fun z z' => Hadd_left z z' y) fun z z' => Hmul_left z z' y +theorem closure_induction₂ {s : Set R} {p : (x y : R) → x ∈ closure s → y ∈ closure s → Prop} + (mem_mem : ∀ (x) (y) (hx : x ∈ s) (hy : y ∈ s), p x y (subset_closure hx) (subset_closure hy)) + (zero_left : ∀ x hx, p 0 x (zero_mem _) hx) (zero_right : ∀ x hx, p x 0 hx (zero_mem _)) + (one_left : ∀ x hx, p 1 x (one_mem _) hx) (one_right : ∀ x hx, p x 1 hx (one_mem _)) + (add_left : ∀ x y z hx hy hz, p x z hx hz → p y z hy hz → p (x + y) z (add_mem hx hy) hz) + (add_right : ∀ x y z hx hy hz, p x y hx hy → p x z hx hz → p x (y + z) hx (add_mem hy hz)) + (mul_left : ∀ x y z hx hy hz, p x z hx hz → p y z hy hz → p (x * y) z (mul_mem hx hy) hz) + (mul_right : ∀ x y z hx hy hz, p x y hx hy → p x z hx hz → p x (y * z) hx (mul_mem hy hz)) + {x y : R} (hx : x ∈ closure s) (hy : y ∈ closure s) : + p x y hx hy := by + induction hy using closure_induction with + | mem z hz => induction hx using closure_induction with + | mem _ h => exact mem_mem _ _ h hz + | zero => exact zero_left _ _ + | one => exact one_left _ _ + | mul _ _ _ _ h₁ h₂ => exact mul_left _ _ _ _ _ _ h₁ h₂ + | add _ _ _ _ h₁ h₂ => exact add_left _ _ _ _ _ _ h₁ h₂ + | zero => exact zero_right x hx + | one => exact one_right x hx + | mul _ _ _ _ h₁ h₂ => exact mul_right _ _ _ _ _ _ h₁ h₂ + | add _ _ _ _ h₁ h₂ => exact add_right _ _ _ _ _ _ h₁ h₂ theorem mem_closure_iff_exists_list {R} [Semiring R] {s : Set R} {x} : x ∈ closure s ↔ ∃ L : List (List R), (∀ t ∈ L, ∀ y ∈ t, y ∈ s) ∧ (L.map List.prod).sum = x := by constructor · intro hx - -- Porting note: needed explicit `p` - let p : R → Prop := fun x => - ∃ (L : List (List R)), - (∀ (t : List R), t ∈ L → ∀ (y : R), y ∈ t → y ∈ s) ∧ (List.map List.prod L).sum = x - exact AddSubmonoid.closure_induction (p := p) (mem_closure_iff.1 hx) - (fun x hx => - suffices ∃ t : List R, (∀ y ∈ t, y ∈ s) ∧ t.prod = x from - let ⟨t, ht1, ht2⟩ := this - ⟨[t], List.forall_mem_singleton.2 ht1, by - rw [List.map_singleton, List.sum_singleton, ht2]⟩ - Submonoid.closure_induction hx - (fun x hx => ⟨[x], List.forall_mem_singleton.2 hx, List.prod_singleton⟩) - ⟨[], List.forall_mem_nil _, rfl⟩ fun x y ⟨t, ht1, ht2⟩ ⟨u, hu1, hu2⟩ => - ⟨t ++ u, List.forall_mem_append.2 ⟨ht1, hu1⟩, by rw [List.prod_append, ht2, hu2]⟩) - ⟨[], List.forall_mem_nil _, rfl⟩ fun x y ⟨L, HL1, HL2⟩ ⟨M, HM1, HM2⟩ => - ⟨L ++ M, List.forall_mem_append.2 ⟨HL1, HM1⟩, by + rw [mem_closure_iff] at hx + induction hx using AddSubmonoid.closure_induction with + | mem x hx => + suffices ∃ t : List R, (∀ y ∈ t, y ∈ s) ∧ t.prod = x from + let ⟨t, ht1, ht2⟩ := this + ⟨[t], List.forall_mem_singleton.2 ht1, by + rw [List.map_singleton, List.sum_singleton, ht2]⟩ + induction hx using Submonoid.closure_induction with + | mem x hx => exact ⟨[x], List.forall_mem_singleton.2 hx, List.prod_singleton⟩ + | one => exact ⟨[], List.forall_mem_nil _, rfl⟩ + | mul x y _ _ ht hu => + obtain ⟨⟨t, ht1, ht2⟩, ⟨u, hu1, hu2⟩⟩ := And.intro ht hu + exact ⟨t ++ u, List.forall_mem_append.2 ⟨ht1, hu1⟩, by rw [List.prod_append, ht2, hu2]⟩ + | one => exact ⟨[], List.forall_mem_nil _, rfl⟩ + | mul x y _ _ hL hM => + obtain ⟨⟨L, HL1, HL2⟩, ⟨M, HM1, HM2⟩⟩ := And.intro hL hM + exact ⟨L ++ M, List.forall_mem_append.2 ⟨HL1, HM1⟩, by rw [List.map_append, List.sum_append, HL2, HM2]⟩ · rintro ⟨L, HL1, HL2⟩ exact HL2 ▸ @@ -1200,17 +1207,19 @@ instance center.smulCommClass_right : SMulCommClass R' (center R') R' := def closureCommSemiringOfComm {s : Set R'} (hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a) : CommSemiring (closure s) := { (closure s).toSemiring with - mul_comm := fun x y => by + mul_comm := fun ⟨x, hx⟩ ⟨y, hy⟩ => by ext - simp only [Subsemiring.coe_mul] - refine - closure_induction₂ x.prop y.prop hcomm (fun x => by simp only [zero_mul, mul_zero]) - (fun x => by simp only [zero_mul, mul_zero]) (fun x => by simp only [one_mul, mul_one]) - (fun x => by simp only [one_mul, mul_one]) - (fun x y z h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂]) - (fun x y z h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂]) - (fun x y z h₁ h₂ => by rw [mul_assoc, h₂, ← mul_assoc, h₁, mul_assoc]) fun x y z h₁ h₂ => - by rw [← mul_assoc, h₁, mul_assoc, h₂, ← mul_assoc] } + simp only [MulMemClass.mk_mul_mk] + induction hx, hy using closure_induction₂ with + | mem_mem x y hx hy => exact hcomm x hx y hy + | zero_left x _ => exact Commute.zero_left x + | zero_right x _ => exact Commute.zero_right x + | one_left x _ => exact Commute.one_left x + | one_right x _ => exact Commute.one_right x + | mul_left _ _ _ _ _ _ h₁ h₂ => exact Commute.mul_left h₁ h₂ + | mul_right _ _ _ _ _ _ h₁ h₂ => exact Commute.mul_right h₁ h₂ + | add_left _ _ _ _ _ _ h₁ h₂ => exact Commute.add_left h₁ h₂ + | add_right _ _ _ _ _ _ h₁ h₂ => exact Commute.add_right h₁ h₂ } end Subsemiring diff --git a/Mathlib/Algebra/RingQuot.lean b/Mathlib/Algebra/RingQuot.lean index b524909addd9a2..e99c9cf2797443 100644 --- a/Mathlib/Algebra/RingQuot.lean +++ b/Mathlib/Algebra/RingQuot.lean @@ -495,15 +495,15 @@ theorem ringQuotToIdealQuotient_apply (r : B → B → Prop) (x : B) : def idealQuotientToRingQuot (r : B → B → Prop) : B ⧸ Ideal.ofRel r →+* RingQuot r := Ideal.Quotient.lift (Ideal.ofRel r) (mkRingHom r) (by - refine fun x h ↦ Submodule.span_induction h ?_ ?_ ?_ ?_ + refine fun x h ↦ Submodule.span_induction ?_ ?_ ?_ ?_ h · rintro y ⟨a, b, h, su⟩ symm at su rw [← sub_eq_iff_eq_add] at su rw [← su, RingHom.map_sub, mkRingHom_rel h, sub_self] · simp - · intro a b ha hb + · intro a b _ _ ha hb simp [ha, hb] - · intro a x hx + · intro a x _ hx simp [hx]) @[simp] diff --git a/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean b/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean index 9534d0d547a626..558c7dbee59ad9 100644 --- a/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean +++ b/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean @@ -645,18 +645,22 @@ theorem star_self_mem_adjoin_singleton (x : A) : star x ∈ adjoin R ({x} : Set star_mem <| self_mem_adjoin_singleton R x @[elab_as_elim] -lemma adjoin_induction' {s : Set A} {p : ∀ x, x ∈ adjoin R s → Prop} {a : A} - (ha : a ∈ adjoin R s) (mem : ∀ (x : A) (hx : x ∈ s), p x (subset_adjoin R s hx)) - (add : ∀ x hx y hy, p x hx → p y hy → p (x + y) (add_mem hx hy)) - (zero : p 0 (zero_mem _)) (mul : ∀ x hx y hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) +lemma adjoin_induction {s : Set A} {p : (x : A) → x ∈ adjoin R s → Prop} + (mem : ∀ (x : A) (hx : x ∈ s), p x (subset_adjoin R s hx)) + (add : ∀ x y hx hy, p x hx → p y hy → p (x + y) (add_mem hx hy)) + (zero : p 0 (zero_mem _)) (mul : ∀ x y hx hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) (smul : ∀ (r : R) x hx, p x hx → p (r • x) (SMulMemClass.smul_mem r hx)) - (star : ∀ x hx, p x hx → p (star x) (star_mem hx)) : p a ha := by - refine NonUnitalAlgebra.adjoin_induction' (fun x hx ↦ ?_) add zero mul smul ha + (star : ∀ x hx, p x hx → p (star x) (star_mem hx)) + {a : A} (ha : a ∈ adjoin R s) : p a ha := by + refine NonUnitalAlgebra.adjoin_induction (fun x hx ↦ ?_) add zero mul smul ha simp only [Set.mem_union, Set.mem_star] at hx obtain (hx | hx) := hx · exact mem x hx · simpa using star _ (NonUnitalAlgebra.subset_adjoin R (by simpa using Or.inl hx)) (mem _ hx) +@[deprecated adjoin_induction (since := "2024-10-10")] +alias adjoin_induction' := adjoin_induction + variable {R} protected theorem gc : GaloisConnection (adjoin R : Set A → NonUnitalStarSubalgebra R A) (↑) := by diff --git a/Mathlib/Algebra/Star/Subalgebra.lean b/Mathlib/Algebra/Star/Subalgebra.lean index bdcd995bb0c5f5..24e84fa477d779 100644 --- a/Mathlib/Algebra/Star/Subalgebra.lean +++ b/Mathlib/Algebra/Star/Subalgebra.lean @@ -440,56 +440,68 @@ theorem _root_.Subalgebra.starClosure_eq_adjoin (S : Subalgebra R A) : /-- If some predicate holds for all `x ∈ (s : Set A)` and this predicate is closed under the `algebraMap`, addition, multiplication and star operations, then it holds for `a ∈ adjoin R s`. -/ @[elab_as_elim] -theorem adjoin_induction {s : Set A} {p : A → Prop} {a : A} (h : a ∈ adjoin R s) - (mem : ∀ x : A, x ∈ s → p x) (algebraMap : ∀ r : R, p (algebraMap R A r)) - (add : ∀ x y : A, p x → p y → p (x + y)) (mul : ∀ x y : A, p x → p y → p (x * y)) - (star : ∀ x : A, p x → p (star x)) : p a := - Algebra.adjoin_induction h - (fun x hx => hx.elim (fun hx => mem x hx) fun hx => star_star x ▸ star _ (mem _ hx)) - algebraMap add mul +theorem adjoin_induction {s : Set A} {p : (x : A) → x ∈ adjoin R s → Prop} + (mem : ∀ (x) (h : x ∈ s), p x (subset_adjoin R s h)) + (algebraMap : ∀ r, p (_root_.algebraMap R _ r) (_root_.algebraMap_mem _ r)) + (add : ∀ x y hx hy, p x hx → p y hy → p (x + y) (add_mem hx hy)) + (mul : ∀ x y hx hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) + (star : ∀ x hx, p x hx → p (star x) (star_mem hx)) + {a : A} (ha : a ∈ adjoin R s) : p a ha := by + refine Algebra.adjoin_induction (fun x hx ↦ ?_) algebraMap add mul ha + simp only [Set.mem_union, Set.mem_star] at hx + obtain (hx | hx) := hx + · exact mem x hx + · simpa using star _ (Algebra.subset_adjoin (by simpa using Or.inl hx)) (mem _ hx) @[elab_as_elim] -theorem adjoin_induction₂ {s : Set A} {p : A → A → Prop} {a b : A} (ha : a ∈ adjoin R s) - (hb : b ∈ adjoin R s) (Hs : ∀ x : A, x ∈ s → ∀ y : A, y ∈ s → p x y) - (Halg : ∀ r₁ r₂ : R, p (algebraMap R A r₁) (algebraMap R A r₂)) - (Halg_left : ∀ (r : R) (x : A), x ∈ s → p (algebraMap R A r) x) - (Halg_right : ∀ (r : R) (x : A), x ∈ s → p x (algebraMap R A r)) - (Hadd_left : ∀ x₁ x₂ y : A, p x₁ y → p x₂ y → p (x₁ + x₂) y) - (Hadd_right : ∀ x y₁ y₂ : A, p x y₁ → p x y₂ → p x (y₁ + y₂)) - (Hmul_left : ∀ x₁ x₂ y : A, p x₁ y → p x₂ y → p (x₁ * x₂) y) - (Hmul_right : ∀ x y₁ y₂ : A, p x y₁ → p x y₂ → p x (y₁ * y₂)) - (Hstar : ∀ x y : A, p x y → p (star x) (star y)) (Hstar_left : ∀ x y : A, p x y → p (star x) y) - (Hstar_right : ∀ x y : A, p x y → p x (star y)) : p a b := by - refine - Algebra.adjoin_induction₂ ha hb (fun x hx y hy => ?_) Halg (fun r x hx => ?_) (fun r x hx => ?_) - Hadd_left Hadd_right Hmul_left Hmul_right - · cases' hx with hx hx <;> cases' hy with hy hy - · exact Hs x hx y hy - · exact star_star y ▸ Hstar_right _ _ (Hs _ hx _ hy) - · exact star_star x ▸ Hstar_left _ _ (Hs _ hx _ hy) - · exact star_star x ▸ star_star y ▸ Hstar _ _ (Hs _ hx _ hy) - · cases' hx with hx hx - · exact Halg_left _ _ hx - · exact star_star x ▸ Hstar_right _ _ (Halg_left r _ hx) - · cases' hx with hx hx - · exact Halg_right _ _ hx - · exact star_star x ▸ Hstar_left _ _ (Halg_right r _ hx) +theorem adjoin_induction₂ {s : Set A} {p : (x y : A) → x ∈ adjoin R s → y ∈ adjoin R s → Prop} + (mem_mem : ∀ (x) (y) (hx : x ∈ s) (hy : y ∈ s), p x y (subset_adjoin R s hx) + (subset_adjoin R s hy)) + (algebraMap_both : ∀ r₁ r₂, p (algebraMap R A r₁) (algebraMap R A r₂) + (_root_.algebraMap_mem _ r₁) (_root_.algebraMap_mem _ r₂)) + (algebraMap_left : ∀ (r) (x) (hx : x ∈ s), p (algebraMap R A r) x (_root_.algebraMap_mem _ r) + (subset_adjoin R s hx)) + (algebraMap_right : ∀ (r) (x) (hx : x ∈ s), p x (algebraMap R A r) (subset_adjoin R s hx) + (_root_.algebraMap_mem _ r)) + (add_left : ∀ x y z hx hy hz, p x z hx hz → p y z hy hz → p (x + y) z (add_mem hx hy) hz) + (add_right : ∀ x y z hx hy hz, p x y hx hy → p x z hx hz → p x (y + z) hx (add_mem hy hz)) + (mul_left : ∀ x y z hx hy hz, p x z hx hz → p y z hy hz → p (x * y) z (mul_mem hx hy) hz) + (mul_right : ∀ x y z hx hy hz, p x y hx hy → p x z hx hz → p x (y * z) hx (mul_mem hy hz)) + (star_left : ∀ x y hx hy, p x y hx hy → p (star x) y (star_mem hx) hy) + (star_right : ∀ x y hx hy, p x y hx hy → p x (star y) hx (star_mem hy)) + {a b : A} (ha : a ∈ adjoin R s) (hb : b ∈ adjoin R s) : + p a b ha hb := by + induction hb using adjoin_induction with + | mem z hz => induction ha using adjoin_induction with + | mem _ h => exact mem_mem _ _ h hz + | algebraMap _ => exact algebraMap_left _ _ hz + | mul _ _ _ _ h₁ h₂ => exact mul_left _ _ _ _ _ _ h₁ h₂ + | add _ _ _ _ h₁ h₂ => exact add_left _ _ _ _ _ _ h₁ h₂ + | star _ _ h => exact star_left _ _ _ _ h + | algebraMap r => + induction ha using adjoin_induction with + | mem _ h => exact algebraMap_right _ _ h + | algebraMap _ => exact algebraMap_both _ _ + | mul _ _ _ _ h₁ h₂ => exact mul_left _ _ _ _ _ _ h₁ h₂ + | add _ _ _ _ h₁ h₂ => exact add_left _ _ _ _ _ _ h₁ h₂ + | star _ _ h => exact star_left _ _ _ _ h + | mul _ _ _ _ h₁ h₂ => exact mul_right _ _ _ _ _ _ h₁ h₂ + | add _ _ _ _ h₁ h₂ => exact add_right _ _ _ _ _ _ h₁ h₂ + | star _ _ h => exact star_right _ _ _ _ h /-- The difference with `StarSubalgebra.adjoin_induction` is that this acts on the subtype. -/ @[elab_as_elim] -theorem adjoin_induction' {s : Set A} {p : adjoin R s → Prop} (a : adjoin R s) +theorem adjoin_induction_subtype {s : Set A} {p : adjoin R s → Prop} (a : adjoin R s) (mem : ∀ (x) (h : x ∈ s), p ⟨x, subset_adjoin R s h⟩) (algebraMap : ∀ r, p (algebraMap R _ r)) (add : ∀ x y, p x → p y → p (x + y)) (mul : ∀ x y, p x → p y → p (x * y)) (star : ∀ x, p x → p (star x)) : p a := Subtype.recOn a fun b hb => by - refine Exists.elim ?_ fun (hb : b ∈ adjoin R s) (hc : p ⟨b, hb⟩) => hc - refine adjoin_induction hb ?_ ?_ ?_ ?_ ?_ - exacts [fun x hx => ⟨subset_adjoin R s hx, mem x hx⟩, fun r => - ⟨StarSubalgebra.algebraMap_mem _ r, algebraMap r⟩, fun x y hx hy => - Exists.elim hx fun hx' hx => Exists.elim hy fun hy' hy => ⟨add_mem hx' hy', add _ _ hx hy⟩, - fun x y hx hy => - Exists.elim hx fun hx' hx => Exists.elim hy fun hy' hy => ⟨mul_mem hx' hy', mul _ _ hx hy⟩, - fun x hx => Exists.elim hx fun hx' hx => ⟨star_mem hx', star _ hx⟩] + induction hb using adjoin_induction with + | mem _ h => exact mem _ h + | algebraMap _ => exact algebraMap _ + | mul _ _ _ _ h₁ h₂ => exact mul _ _ h₁ h₂ + | add _ _ _ _ h₁ h₂ => exact add _ _ h₁ h₂ + | star _ _ h => exact star _ h variable (R) @@ -668,7 +680,7 @@ theorem ext_adjoin {s : Set A} [FunLike F (adjoin R s) B] [AlgHomClass F R (adjoin R s) B] [StarHomClass F (adjoin R s) B] {f g : F} (h : ∀ x : adjoin R s, (x : A) ∈ s → f x = g x) : f = g := by refine DFunLike.ext f g fun a => - adjoin_induction' (p := fun y => f y = g y) a (fun x hx => ?_) (fun r => ?_) + adjoin_induction_subtype (p := fun y => f y = g y) a (fun x hx => ?_) (fun r => ?_) (fun x y hx hy => ?_) (fun x y hx hy => ?_) fun x hx => ?_ · exact h ⟨x, subset_adjoin R s hx⟩ hx · simp only [AlgHomClass.commutes] diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Instances.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Instances.lean index 180ca90ca52884..50abcebd079d70 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Instances.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Instances.lean @@ -498,14 +498,14 @@ variable [NormedAlgebra ℂ A] [StarModule ℂ A] instance CStarAlgebra.instNonnegSpectrumClass : NonnegSpectrumClass ℝ A := .of_spectrum_nonneg fun a ha ↦ by rw [StarOrderedRing.nonneg_iff] at ha - induction ha using AddSubmonoid.closure_induction' with + induction ha using AddSubmonoid.closure_induction with | mem x hx => obtain ⟨b, rfl⟩ := hx exact spectrum_star_mul_self_nonneg | one => nontriviality A simp - | mul x x_mem y y_mem hx hy => + | mul x y x_mem y_mem hx hy => rw [← SpectrumRestricts.nnreal_iff] at hx hy ⊢ rw [← StarOrderedRing.nonneg_iff] at x_mem y_mem exact hx.nnreal_add (.of_nonneg x_mem) (.of_nonneg y_mem) hy @@ -557,7 +557,7 @@ lemma CStarAlgebra.spectralOrderedRing : @StarOrderedRing A _ (CStarAlgebra.spec · rintro ⟨p, hp, rfl⟩ suffices IsSelfAdjoint p ∧ SpectrumRestricts p ContinuousMap.realToNNReal from ⟨by simpa using this.1, by simpa using this.2⟩ - induction hp using AddSubmonoid.closure_induction' with + induction hp using AddSubmonoid.closure_induction with | mem x hx => obtain ⟨s, rfl⟩ := hx refine ⟨IsSelfAdjoint.star_mul_self s, ?_⟩ @@ -567,7 +567,7 @@ lemma CStarAlgebra.spectralOrderedRing : @StarOrderedRing A _ (CStarAlgebra.spec rw [SpectrumRestricts.nnreal_iff] nontriviality A simp - | mul x _ y _ hx hy => + | mul x y _ _ hx hy => exact ⟨hx.1.add hy.1, hx.2.nnreal_add hx.1 hy.1 hy.2⟩ } end SpectralOrder diff --git a/Mathlib/Analysis/Fourier/AddCircle.lean b/Mathlib/Analysis/Fourier/AddCircle.lean index d162af7712aca4..c874a54720ae82 100644 --- a/Mathlib/Analysis/Fourier/AddCircle.lean +++ b/Mathlib/Analysis/Fourier/AddCircle.lean @@ -196,9 +196,9 @@ theorem fourierSubalgebra_coe : apply adjoin_eq_span_of_subset refine Subset.trans ?_ Submodule.subset_span intro x hx - refine Submonoid.closure_induction hx (fun _ => id) ⟨0, ?_⟩ ?_ + refine Submonoid.closure_induction (fun _ => id) ⟨0, ?_⟩ ?_ hx · ext1 z; exact fourier_zero - · rintro _ _ ⟨m, rfl⟩ ⟨n, rfl⟩ + · rintro - - - - ⟨m, rfl⟩ ⟨n, rfl⟩ refine ⟨m + n, ?_⟩ ext1 z exact fourier_add diff --git a/Mathlib/Analysis/InnerProductSpace/StarOrder.lean b/Mathlib/Analysis/InnerProductSpace/StarOrder.lean index 7ed9ab6de0e4bf..cbf503358c95e9 100644 --- a/Mathlib/Analysis/InnerProductSpace/StarOrder.lean +++ b/Mathlib/Analysis/InnerProductSpace/StarOrder.lean @@ -63,12 +63,12 @@ lemma instStarOrderedRingRCLike exact AddSubmonoid.subset_closure ⟨p, by simp only [hp₁.star_eq, sq]⟩ · rintro ⟨p, hp, rfl⟩ rw [le_def, add_sub_cancel_left] - induction hp using AddSubmonoid.closure_induction' with + induction hp using AddSubmonoid.closure_induction with | mem _ hf => obtain ⟨f, rfl⟩ := hf simpa using ContinuousLinearMap.IsPositive.adjoint_conj isPositive_one f | one => exact isPositive_zero - | mul f _ g _ hf hg => exact hf.add hg + | mul f g _ _ hf hg => exact hf.add hg instance instStarOrderedRing {H : Type*} [NormedAddCommGroup H] [InnerProductSpace ℂ H] [CompleteSpace H] : StarOrderedRing (H →L[ℂ] H) := diff --git a/Mathlib/FieldTheory/Finite/GaloisField.lean b/Mathlib/FieldTheory/Finite/GaloisField.lean index 89b627d0328c83..adbca6dc2715e4 100644 --- a/Mathlib/FieldTheory/Finite/GaloisField.lean +++ b/Mathlib/FieldTheory/Finite/GaloisField.lean @@ -114,7 +114,7 @@ theorem finrank {n} (h : n ≠ 0) : Module.finrank (ZMod p) (GaloisField p n) = intro x hx -- We discharge the `p = 0` separately, to avoid typeclass issues on `ZMod p`. cases p; cases hp - refine Subring.closure_induction hx ?_ ?_ ?_ ?_ ?_ ?_ <;> simp_rw [mem_rootSet_of_ne aux] + refine Subring.closure_induction ?_ ?_ ?_ ?_ ?_ ?_ hx <;> simp_rw [mem_rootSet_of_ne aux] · rintro x (⟨r, rfl⟩ | hx) · simp only [g_poly, map_sub, map_pow, aeval_X] rw [← map_pow, ZMod.pow_card_pow, sub_self] @@ -127,14 +127,14 @@ theorem finrank {n} (h : n ≠ 0) : Module.finrank (ZMod p) (GaloisField p n) = exact Nat.not_lt_zero 1 (pow_eq_zero hn.symm ▸ hp) · simp [g_poly] · simp only [g_poly, aeval_X_pow, aeval_X, map_sub, add_pow_char_pow, sub_eq_zero] - intro x y hx hy + intro x y _ _ hx hy rw [hx, hy] - · intro x hx + · intro x _ hx simp only [g_poly, sub_eq_zero, aeval_X_pow, aeval_X, map_sub, sub_neg_eq_add] at * rw [neg_pow, hx, CharP.neg_one_pow_char_pow] simp · simp only [g_poly, aeval_X_pow, aeval_X, map_sub, mul_pow, sub_eq_zero] - intro x y hx hy + intro x y _ _ hx hy rw [hx, hy] theorem card (h : n ≠ 0) : Fintype.card (GaloisField p n) = p ^ n := by diff --git a/Mathlib/GroupTheory/Coxeter/Basic.lean b/Mathlib/GroupTheory/Coxeter/Basic.lean index fd14569331ee86..26d4fff4bda3cb 100644 --- a/Mathlib/GroupTheory/Coxeter/Basic.lean +++ b/Mathlib/GroupTheory/Coxeter/Basic.lean @@ -249,7 +249,8 @@ preserved under multiplication, then it holds for all elements of `W`. -/ theorem simple_induction {p : W → Prop} (w : W) (simple : ∀ i : B, p (s i)) (one : p 1) (mul : ∀ w w' : W, p w → p w' → p (w * w')) : p w := by have := cs.submonoid_closure_range_simple.symm ▸ Submonoid.mem_top w - exact Submonoid.closure_induction this (fun x ⟨i, hi⟩ ↦ hi ▸ simple i) one mul + exact Submonoid.closure_induction (fun x ⟨i, hi⟩ ↦ hi ▸ simple i) one (fun _ _ _ _ ↦ mul _ _) + this /-- If `p : W → Prop` holds for the identity and it is preserved under multiplying on the left by a simple reflection, then it holds for all elements of `W`. -/ diff --git a/Mathlib/GroupTheory/Nilpotent.lean b/Mathlib/GroupTheory/Nilpotent.lean index 90196dde628823..14008d09636c00 100644 --- a/Mathlib/GroupTheory/Nilpotent.lean +++ b/Mathlib/GroupTheory/Nilpotent.lean @@ -287,11 +287,12 @@ theorem lowerCentralSeries_antitone : Antitone (lowerCentralSeries G) := by simp only [mem_lowerCentralSeries_succ_iff, exists_prop, mem_top, exists_true_left, true_and] at hx refine - closure_induction hx ?_ (Subgroup.one_mem _) (@Subgroup.mul_mem _ _ _) (@Subgroup.inv_mem _ _ _) + closure_induction ?_ (Subgroup.one_mem _) (fun _ _ _ _ ↦ mul_mem) (fun _ _ ↦ inv_mem) hx rintro y ⟨z, hz, a, ha⟩ rw [← ha, mul_assoc, mul_assoc, ← mul_assoc a z⁻¹ a⁻¹] exact mul_mem hz (Normal.conj_mem (lowerCentralSeries_normal n) z⁻¹ (inv_mem hz) a) + /-- The lower central series of a group is a descending central series. -/ theorem lowerCentralSeries_isDescendingCentralSeries : IsDescendingCentralSeries (lowerCentralSeries G) := by @@ -449,8 +450,8 @@ theorem lowerCentralSeries.map {H : Type*} [Group H] (f : G →* H) (n : ℕ) : induction' n with d hd · simp · rintro a ⟨x, hx : x ∈ lowerCentralSeries G d.succ, rfl⟩ - refine closure_induction hx ?_ (by simp [f.map_one, Subgroup.one_mem _]) - (fun y z hy hz => by simp [MonoidHom.map_mul, Subgroup.mul_mem _ hy hz]) (fun y hy => by + refine closure_induction (hx := hx) ?_ (by simp [f.map_one, Subgroup.one_mem _]) + (fun y z _ _ hy hz => by simp [MonoidHom.map_mul, Subgroup.mul_mem _ hy hz]) (fun y _ hy => by rw [f.map_inv]; exact Subgroup.inv_mem _ hy) rintro a ⟨y, hy, z, ⟨-, rfl⟩⟩ apply mem_closure.mpr diff --git a/Mathlib/GroupTheory/Perm/ClosureSwap.lean b/Mathlib/GroupTheory/Perm/ClosureSwap.lean index 304cfc7bc7b788..df78783d8d70e4 100644 --- a/Mathlib/GroupTheory/Perm/ClosureSwap.lean +++ b/Mathlib/GroupTheory/Perm/ClosureSwap.lean @@ -31,7 +31,8 @@ then the support of every element in the group is finite. -/ theorem finite_compl_fixedBy_closure_iff {S : Set G} : (∀ g ∈ closure S, (fixedBy α g)ᶜ.Finite) ↔ ∀ g ∈ S, (fixedBy α g)ᶜ.Finite := ⟨fun h g hg ↦ h g (subset_closure hg), fun h g hg ↦ by - refine closure_induction hg h (by simp) (fun g g' hg hg' ↦ (hg.union hg').subset ?_) (by simp) + refine closure_induction h (by simp) (fun g g' _ _ hg hg' ↦ (hg.union hg').subset ?_) + (by simp) hg simp_rw [← compl_inter, compl_subset_compl, fixedBy_mul]⟩ /-- Given a symmetric generating set of a permutation group, if T is a nonempty proper subset of diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/Even.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/Even.lean index a94392b30fc066..c7ec32d1e1e44f 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/Even.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/Even.lean @@ -177,13 +177,13 @@ private theorem fFold_fFold (m : M) (x : A × S f) : fFold f m (fFold f m x) = Q rw [Algebra.smul_def, f.contract] · ext m₁ change f.bilin _ _ * g m = Q m • g m₁ - refine Submodule.span_induction' ?_ ?_ ?_ ?_ hg + refine Submodule.span_induction ?_ ?_ ?_ ?_ hg · rintro _ ⟨b, m₃, rfl⟩ change f.bilin _ _ * (f.bilin _ _ * b) = Q m • (f.bilin _ _ * b) rw [← smul_mul_assoc, ← mul_assoc, f.contract_mid] · change f.bilin m₁ m * 0 = Q m • (0 : A) -- Porting note: `•` now needs the type of `0` rw [mul_zero, smul_zero] - · rintro x _hx y _hy ihx ihy + · rintro x y _hx _hy ihx ihy rw [LinearMap.add_apply, LinearMap.add_apply, mul_add, smul_add, ihx, ihy] · rintro x hx _c ihx rw [LinearMap.smul_apply, LinearMap.smul_apply, mul_smul_comm, ihx, smul_comm] diff --git a/Mathlib/LinearAlgebra/FiniteSpan.lean b/Mathlib/LinearAlgebra/FiniteSpan.lean index 5e6065d494f51b..fb34823624e17c 100644 --- a/Mathlib/LinearAlgebra/FiniteSpan.lean +++ b/Mathlib/LinearAlgebra/FiniteSpan.lean @@ -29,8 +29,8 @@ lemma LinearEquiv.isOfFinOrder_of_finite_of_span_eq_top_of_mapsTo ext m have hm : m ∈ span R Φ := hΦ₂ ▸ Submodule.mem_top simp only [mul_left_iterate, mul_one, LinearEquiv.coe_one, id_eq] - refine Submodule.span_induction hm (fun x hx ↦ ?_) (by simp) - (fun x y hx hy ↦ by simp [map_add, hx, hy]) (fun t x hx ↦ by simp [map_smul, hx]) + refine Submodule.span_induction (fun x hx ↦ ?_) (by simp) + (fun x y _ _ hx hy ↦ by simp [map_add, hx, hy]) (fun t x _ hx ↦ by simp [map_smul, hx]) hm rw [LinearEquiv.pow_apply, ← he.1.coe_iterate_restrict ⟨x, hx⟩ k] replace hk : (e') ^ k = 1 := by simpa [IsPeriodicPt, IsFixedPt] using hk replace hk := Equiv.congr_fun hk ⟨x, hx⟩ diff --git a/Mathlib/LinearAlgebra/RootSystem/Defs.lean b/Mathlib/LinearAlgebra/RootSystem/Defs.lean index eac40333d52fc0..420de4b340130d 100644 --- a/Mathlib/LinearAlgebra/RootSystem/Defs.lean +++ b/Mathlib/LinearAlgebra/RootSystem/Defs.lean @@ -501,12 +501,12 @@ lemma reflection_perm_eq_reflection_perm_iff_of_span : P.reflection_perm i = P.reflection_perm j ↔ ∀ x ∈ span R (range P.root), P.reflection i x = P.reflection j x := by refine ⟨fun h x hx ↦ ?_, fun h ↦ ?_⟩ - · induction hx using Submodule.span_induction' with + · induction hx using Submodule.span_induction with | mem x hx => obtain ⟨k, rfl⟩ := hx simp only [← root_reflection_perm, h] | zero => simp - | add x _ y _ hx hy => simp [hx, hy] + | add x y _ _ hx hy => simp [hx, hy] | smul t x _ hx => simp [hx] · ext k apply P.root.injective diff --git a/Mathlib/LinearAlgebra/Span.lean b/Mathlib/LinearAlgebra/Span.lean index eff580c8d6d6d5..8e873cfc1c5336 100644 --- a/Mathlib/LinearAlgebra/Span.lean +++ b/Mathlib/LinearAlgebra/Span.lean @@ -157,82 +157,87 @@ theorem span_closure {s : Set M} : span R (AddSubmonoid.closure s : Set M) = spa preserved under addition and scalar multiplication, then `p` holds for all elements of the span of `s`. -/ @[elab_as_elim] -theorem span_induction {p : M → Prop} (h : x ∈ span R s) (mem : ∀ x ∈ s, p x) (zero : p 0) - (add : ∀ x y, p x → p y → p (x + y)) (smul : ∀ (a : R) (x), p x → p (a • x)) : p x := - ((@span_le (p := ⟨⟨⟨p, by intros x y; exact add x y⟩, zero⟩, smul⟩)) s).2 mem h - -/-- An induction principle for span membership. This is a version of `Submodule.span_induction` -for binary predicates. -/ -theorem span_induction₂ {p : M → M → Prop} {a b : M} (ha : a ∈ Submodule.span R s) - (hb : b ∈ Submodule.span R s) (mem_mem : ∀ x ∈ s, ∀ y ∈ s, p x y) - (zero_left : ∀ y, p 0 y) (zero_right : ∀ x, p x 0) - (add_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ + x₂) y) - (add_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ + y₂)) - (smul_left : ∀ (r : R) x y, p x y → p (r • x) y) - (smul_right : ∀ (r : R) x y, p x y → p x (r • y)) : p a b := - Submodule.span_induction ha - (fun x hx => Submodule.span_induction hb (mem_mem x hx) (zero_right x) (add_right x) fun r => - smul_right r x) - (zero_left b) (fun x₁ x₂ => add_left x₁ x₂ b) fun r x => smul_left r x b - -/-- A dependent version of `Submodule.span_induction`. -/ -@[elab_as_elim] -theorem span_induction' {p : ∀ x, x ∈ span R s → Prop} +theorem span_induction {p : (x : M) → x ∈ span R s → Prop} (mem : ∀ (x) (h : x ∈ s), p x (subset_span h)) (zero : p 0 (Submodule.zero_mem _)) - (add : ∀ x hx y hy, p x hx → p y hy → p (x + y) (Submodule.add_mem _ ‹_› ‹_›)) + (add : ∀ x y hx hy, p x hx → p y hy → p (x + y) (Submodule.add_mem _ ‹_› ‹_›)) (smul : ∀ (a : R) (x hx), p x hx → p (a • x) (Submodule.smul_mem _ _ ‹_›)) {x} (hx : x ∈ span R s) : p x hx := by - refine Exists.elim ?_ fun (hx : x ∈ span R s) (hc : p x hx) => hc - refine - span_induction hx (fun m hm => ⟨subset_span hm, mem m hm⟩) ⟨zero_mem _, zero⟩ - (fun x y hx hy => - Exists.elim hx fun hx' hx => - Exists.elim hy fun hy' hy => ⟨add_mem hx' hy', add _ _ _ _ hx hy⟩) - fun r x hx => Exists.elim hx fun hx' hx => ⟨smul_mem _ _ hx', smul r _ _ hx⟩ + let p : Submodule R M := + { carrier := { x | ∃ hx, p x hx } + add_mem' := fun ⟨_, hpx⟩ ⟨_, hpy⟩ ↦ ⟨_, add _ _ _ _ hpx hpy⟩ + zero_mem' := ⟨_, zero⟩ + smul_mem' := fun r ↦ fun ⟨_, hpx⟩ ↦ ⟨_, smul r _ _ hpx⟩ } + exact span_le (p := p) |>.mpr (fun y hy ↦ ⟨subset_span hy, mem y hy⟩) hx |>.elim fun _ ↦ id + +@[deprecated span_induction (since := "2024-10-10")] +alias span_induction' := span_induction + +/-- An induction principle for span membership. This is a version of `Submodule.span_induction` +for binary predicates. -/ +theorem span_induction₂ {p : (x y : M) → x ∈ span R s → y ∈ span R s → Prop} + (mem_mem : ∀ (x) (y) (hx : x ∈ s) (hy : y ∈ s), p x y (subset_span hx) (subset_span hy)) + (zero_left : ∀ y hy, p 0 y (zero_mem _) hy) (zero_right : ∀ x hx, p x 0 hx (zero_mem _)) + (add_left : ∀ x y z hx hy hz, p x z hx hz → p y z hy hz → p (x + y) z (add_mem hx hy) hz) + (add_right : ∀ x y z hx hy hz, p x y hx hy → p x z hx hz → p x (y + z) hx (add_mem hy hz)) + (smul_left : ∀ (r : R) x y hx hy, p x y hx hy → p (r • x) y (smul_mem _ r hx) hy) + (smul_right : ∀ (r : R) x y hx hy, p x y hx hy → p x (r • y) hx (smul_mem _ r hy)) + {a b : M} (ha : a ∈ Submodule.span R s) + (hb : b ∈ Submodule.span R s) : p a b ha hb := by + induction hb using span_induction with + | mem z hz => induction ha using span_induction with + | mem _ h => exact mem_mem _ _ h hz + | zero => exact zero_left _ _ + | add _ _ _ _ h₁ h₂ => exact add_left _ _ _ _ _ _ h₁ h₂ + | smul _ _ _ h => exact smul_left _ _ _ _ _ h + | zero => exact zero_right a ha + | add _ _ _ _ h₁ h₂ => exact add_right _ _ _ _ _ _ h₁ h₂ + | smul _ _ _ h => exact smul_right _ _ _ _ _ h open AddSubmonoid in theorem span_eq_closure {s : Set M} : (span R s).toAddSubmonoid = closure (@univ R • s) := by - refine le_antisymm - (fun x hx ↦ span_induction hx (fun x hx ↦ subset_closure ⟨1, trivial, x, hx, one_smul R x⟩) - (zero_mem _) (fun _ _ ↦ add_mem) fun r m hm ↦ closure_induction hm ?_ ?_ fun _ _ h h' ↦ ?_) - (closure_le.2 ?_) - · rintro _ ⟨r, -, m, hm, rfl⟩; exact smul_mem _ _ (subset_span hm) - · rintro _ ⟨r', -, m, hm, rfl⟩; exact subset_closure ⟨r * r', trivial, m, hm, mul_smul r r' m⟩ - · rw [smul_zero]; apply zero_mem - · rw [smul_add]; exact add_mem h h' + refine le_antisymm (fun x (hx : x ∈ span R s) ↦ ?of_mem_span) (fun x hx ↦ ?of_mem_closure) + case of_mem_span => + induction hx using span_induction with + | mem x hx => exact subset_closure ⟨1, trivial, x, hx, one_smul R x⟩ + | zero => exact zero_mem _ + | add _ _ _ _ h₁ h₂ => exact add_mem h₁ h₂ + | smul r₁ y _h hy => + clear _h + induction hy using AddSubmonoid.closure_induction with + | mem _ h => + obtain ⟨r₂, -, x, hx, rfl⟩ := h + exact subset_closure ⟨r₁ * r₂, trivial, x, hx, mul_smul ..⟩ + | one => simpa only [smul_zero] using zero_mem _ + | mul _ _ _ _ h₁ h₂ => simpa only [smul_add] using add_mem h₁ h₂ + case of_mem_closure => + refine closure_le.2 ?_ hx + rintro - ⟨r, -, x, hx, rfl⟩ + exact smul_mem _ _ (subset_span hx) +open AddSubmonoid in /-- A variant of `span_induction` that combines `∀ x ∈ s, p x` and `∀ r x, p x → p (r • x)` into a single condition `∀ r, ∀ x ∈ s, p (r • x)`, which can be easier to verify. -/ @[elab_as_elim] -theorem closure_induction {p : M → Prop} (h : x ∈ span R s) (zero : p 0) - (add : ∀ x y, p x → p y → p (x + y)) (smul_mem : ∀ r : R, ∀ x ∈ s, p (r • x)) : p x := by - rw [← mem_toAddSubmonoid, span_eq_closure] at h - refine AddSubmonoid.closure_induction h ?_ zero add - rintro _ ⟨r, -, m, hm, rfl⟩ - exact smul_mem r m hm - -/-- A dependent version of `Submodule.closure_induction`. -/ -@[elab_as_elim] -theorem closure_induction' {p : ∀ x, x ∈ span R s → Prop} +theorem closure_induction {p : (x : M) → x ∈ span R s → Prop} (zero : p 0 (Submodule.zero_mem _)) - (add : ∀ x hx y hy, p x hx → p y hy → p (x + y) (Submodule.add_mem _ ‹_› ‹_›)) + (add : ∀ x y hx hy, p x hx → p y hy → p (x + y) (Submodule.add_mem _ ‹_› ‹_›)) (smul_mem : ∀ (r x) (h : x ∈ s), p (r • x) (Submodule.smul_mem _ _ <| subset_span h)) {x} (hx : x ∈ span R s) : p x hx := by - refine Exists.elim ?_ fun (hx : x ∈ span R s) (hc : p x hx) ↦ hc - refine closure_induction hx ⟨zero_mem _, zero⟩ - (fun x y hx hy ↦ Exists.elim hx fun hx' hx ↦ - Exists.elim hy fun hy' hy ↦ ⟨add_mem hx' hy', add _ _ _ _ hx hy⟩) - fun r x hx ↦ ⟨Submodule.smul_mem _ _ (subset_span hx), smul_mem r x hx⟩ + have key {v} : v ∈ span R s ↔ v ∈ closure (@univ R • s) := by simp [← span_eq_closure] + refine AddSubmonoid.closure_induction (p := fun x hx ↦ p x (key.mpr hx)) + ?_ zero (by simpa only [key] using add) (key.mp hx) + rintro - ⟨r, -, x, hx, rfl⟩ + exact smul_mem r x hx + +@[deprecated closure_induction (since := "2024-10-10")] +alias closure_induction' := closure_induction @[simp] theorem span_span_coe_preimage : span R (((↑) : span R s → M) ⁻¹' s) = ⊤ := - eq_top_iff.2 fun x ↦ Subtype.recOn x fun x hx _ ↦ by - refine span_induction' (p := fun x hx ↦ (⟨x, hx⟩ : span R s) ∈ span R (Subtype.val ⁻¹' s)) - (fun x' hx' ↦ subset_span hx') ?_ (fun x _ y _ ↦ ?_) (fun r x _ ↦ ?_) hx - · exact zero_mem _ - · exact add_mem - · exact smul_mem _ _ + eq_top_iff.2 fun x _ ↦ Subtype.recOn x fun _ hx' ↦ + span_induction (fun _ h ↦ subset_span h) (zero_mem _) (fun _ _ _ _ ↦ add_mem) + (fun _ _ _ ↦ smul_mem _ _) hx' @[simp] lemma span_setOf_mem_eq_top : @@ -255,8 +260,8 @@ theorem span_int_eq_addSubgroup_closure {M : Type*} [AddCommGroup M] (s : Set M) (span ℤ s).toAddSubgroup = AddSubgroup.closure s := Eq.symm <| AddSubgroup.closure_eq_of_le _ subset_span fun _ hx => - span_induction hx (fun _ hx => AddSubgroup.subset_closure hx) (AddSubgroup.zero_mem _) - (fun _ _ => AddSubgroup.add_mem _) fun _ _ _ => AddSubgroup.zsmul_mem _ ‹_› _ + span_induction (fun _ hx => AddSubgroup.subset_closure hx) (AddSubgroup.zero_mem _) + (fun _ _ _ _ => AddSubgroup.add_mem _) (fun _ _ _ _ => AddSubgroup.zsmul_mem _ ‹_› _) hx @[simp] theorem span_int_eq {M : Type*} [AddCommGroup M] (s : AddSubgroup M) : @@ -377,15 +382,15 @@ variable {p p'} theorem mem_sup : x ∈ p ⊔ p' ↔ ∃ y ∈ p, ∃ z ∈ p', y + z = x := ⟨fun h => by rw [← span_eq p, ← span_eq p', ← span_union] at h - refine span_induction h ?_ ?_ ?_ ?_ + refine span_induction ?_ ?_ ?_ ?_ h · rintro y (h | h) · exact ⟨y, h, 0, by simp, by simp⟩ · exact ⟨0, by simp, y, h, by simp⟩ · exact ⟨0, by simp, 0, by simp⟩ - · rintro _ _ ⟨y₁, hy₁, z₁, hz₁, rfl⟩ ⟨y₂, hy₂, z₂, hz₂, rfl⟩ + · rintro _ _ - - ⟨y₁, hy₁, z₁, hz₁, rfl⟩ ⟨y₂, hy₂, z₂, hz₂, rfl⟩ exact ⟨_, add_mem hy₁ hy₂, _, add_mem hz₁ hz₂, by rw [add_assoc, add_assoc, ← add_assoc y₂, ← add_assoc z₁, add_comm y₂]⟩ - · rintro a _ ⟨y, hy, z, hz, rfl⟩ + · rintro a - _ ⟨y, hy, z, hz, rfl⟩ exact ⟨_, smul_mem _ a hy, _, smul_mem _ a hz, by simp [smul_add]⟩, by rintro ⟨y, hy, z, hz, rfl⟩ exact add_mem ((le_sup_left : p ≤ p ⊔ p') hy) ((le_sup_right : p' ≤ p ⊔ p') hz)⟩ @@ -430,13 +435,13 @@ theorem nontrivial_span_singleton {x : M} (h : x ≠ 0) : Nontrivial (R ∙ x) : theorem mem_span_singleton {y : M} : (x ∈ R ∙ y) ↔ ∃ a : R, a • y = x := ⟨fun h => by - refine span_induction h ?_ ?_ ?_ ?_ + refine span_induction ?_ ?_ ?_ ?_ h · rintro y (rfl | ⟨⟨_⟩⟩) exact ⟨1, by simp⟩ · exact ⟨0, by simp⟩ - · rintro _ _ ⟨a, rfl⟩ ⟨b, rfl⟩ + · rintro _ _ - - ⟨a, rfl⟩ ⟨b, rfl⟩ exact ⟨a + b, by simp [add_smul]⟩ - · rintro a _ ⟨b, rfl⟩ + · rintro a _ - ⟨b, rfl⟩ exact ⟨a * b, by simp [smul_smul]⟩, by rintro ⟨a, y, rfl⟩; exact smul_mem _ _ (subset_span <| by simp)⟩ @@ -603,17 +608,18 @@ theorem iSup_toAddSubmonoid {ι : Sort*} (p : ι → Submodule R M) : refine le_antisymm (fun x => ?_) (iSup_le fun i => toAddSubmonoid_mono <| le_iSup _ i) simp_rw [iSup_eq_span, AddSubmonoid.iSup_eq_closure, mem_toAddSubmonoid, coe_toAddSubmonoid] intro hx - refine Submodule.span_induction hx (fun x hx => ?_) ?_ (fun x y hx hy => ?_) fun r x hx => ?_ + refine Submodule.span_induction (fun x hx => ?_) ?_ (fun x y _ _ hx hy => ?_) + (fun r x _ hx => ?_) hx · exact AddSubmonoid.subset_closure hx · exact AddSubmonoid.zero_mem _ · exact AddSubmonoid.add_mem _ hx hy - · refine AddSubmonoid.closure_induction hx ?_ ?_ ?_ + · refine AddSubmonoid.closure_induction ?_ ?_ ?_ hx · rintro x ⟨_, ⟨i, rfl⟩, hix : x ∈ p i⟩ apply AddSubmonoid.subset_closure (Set.mem_iUnion.mpr ⟨i, _⟩) exact smul_mem _ r hix · rw [smul_zero] exact AddSubmonoid.zero_mem _ - · intro x y hx hy + · intro x y _ _ hx hy rw [smul_add] exact AddSubmonoid.add_mem _ hx hy @@ -703,20 +709,20 @@ such that the element is contained in the span of the subset. -/ theorem mem_span_finite_of_mem_span {S : Set M} {x : M} (hx : x ∈ span R S) : ∃ T : Finset M, ↑T ⊆ S ∧ x ∈ span R (T : Set M) := by classical - refine span_induction hx (fun x hx => ?_) ?_ ?_ ?_ + refine span_induction (fun x hx => ?_) ?_ ?_ ?_ hx · refine ⟨{x}, ?_, ?_⟩ · rwa [Finset.coe_singleton, Set.singleton_subset_iff] · rw [Finset.coe_singleton] exact Submodule.mem_span_singleton_self x · use ∅ simp - · rintro x y ⟨X, hX, hxX⟩ ⟨Y, hY, hyY⟩ + · rintro x y - - ⟨X, hX, hxX⟩ ⟨Y, hY, hyY⟩ refine ⟨X ∪ Y, ?_, ?_⟩ · rw [Finset.coe_union] exact Set.union_subset hX hY rw [Finset.coe_union, span_union, mem_sup] exact ⟨x, hxX, y, hyY, rfl⟩ - · rintro a x ⟨T, hT, h2⟩ + · rintro a x - ⟨T, hT, h2⟩ exact ⟨T, hT, smul_mem _ _ h2⟩ end diff --git a/Mathlib/LinearAlgebra/TensorProduct/RightExactness.lean b/Mathlib/LinearAlgebra/TensorProduct/RightExactness.lean index 14d7396e79842e..c55c56caf1c8ee 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/RightExactness.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/RightExactness.lean @@ -524,7 +524,7 @@ lemma Ideal.map_includeLeft_eq (I : Ideal A) : Submodule.mem_toAddSubmonoid, Submodule.restrictScalars_mem, LinearMap.mem_range] intro hx rw [Ideal.map, ← submodule_span_eq] at hx - refine Submodule.span_induction hx ?_ ?_ ?_ ?_ + refine Submodule.span_induction ?_ ?_ ?_ ?_ hx · intro x simp only [includeLeft_apply, Set.mem_image, SetLike.mem_coe] rintro ⟨y, hy, rfl⟩ @@ -532,10 +532,10 @@ lemma Ideal.map_includeLeft_eq (I : Ideal A) : rfl · use 0 simp only [map_zero] - · rintro x y ⟨x, hx, rfl⟩ ⟨y, hy, rfl⟩ + · rintro x y - - ⟨x, hx, rfl⟩ ⟨y, hy, rfl⟩ use x + y simp only [map_add] - · rintro a x ⟨x, hx, rfl⟩ + · rintro a x - ⟨x, hx, rfl⟩ induction a with | zero => use 0 @@ -592,7 +592,7 @@ lemma Ideal.map_includeRight_eq (I : Ideal B) : Submodule.mem_toAddSubmonoid, Submodule.restrictScalars_mem, LinearMap.mem_range] intro hx rw [Ideal.map, ← submodule_span_eq] at hx - refine Submodule.span_induction hx ?_ ?_ ?_ ?_ + refine Submodule.span_induction ?_ ?_ ?_ ?_ hx · intro x simp only [includeRight_apply, Set.mem_image, SetLike.mem_coe] rintro ⟨y, hy, rfl⟩ @@ -600,10 +600,10 @@ lemma Ideal.map_includeRight_eq (I : Ideal B) : rfl · use 0 simp only [map_zero] - · rintro x y ⟨x, hx, rfl⟩ ⟨y, hy, rfl⟩ + · rintro x y - - ⟨x, hx, rfl⟩ ⟨y, hy, rfl⟩ use x + y simp only [map_add] - · rintro a x ⟨x, hx, rfl⟩ + · rintro a x - ⟨x, hx, rfl⟩ induction a with | zero => use 0 diff --git a/Mathlib/LinearAlgebra/TensorProduct/Tower.lean b/Mathlib/LinearAlgebra/TensorProduct/Tower.lean index 5ed4fbb0c5ba5b..9634e23fe06da7 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/Tower.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/Tower.lean @@ -489,14 +489,15 @@ lemma baseChange_span (s : Set M) : simp only [baseChange, map_coe] refine le_antisymm (span_le.mpr ?_) (span_mono <| Set.image_subset _ subset_span) rintro - ⟨m : M, hm : m ∈ span R s, rfl⟩ - apply span_induction (p := fun m' ↦ (1 : A) ⊗ₜ[R] m' ∈ span A (TensorProduct.mk R A M 1 '' s)) hm + apply span_induction (p := fun m' _ ↦ (1 : A) ⊗ₜ[R] m' ∈ span A (TensorProduct.mk R A M 1 '' s)) + (hx := hm) · intro m hm exact subset_span ⟨m, hm, rfl⟩ · simp - · intro m₁ m₂ hm₁ hm₂ + · intro m₁ m₂ _ _ hm₁ hm₂ rw [tmul_add] exact Submodule.add_mem _ hm₁ hm₂ - · intro r m' hm' + · intro r m' _ hm' rw [tmul_smul, ← one_smul A ((1 : A) ⊗ₜ[R] m'), ← smul_assoc] exact smul_mem _ (r • 1) hm' diff --git a/Mathlib/NumberTheory/Cyclotomic/Basic.lean b/Mathlib/NumberTheory/Cyclotomic/Basic.lean index 3c95d15cc13eea..8140cd702670ff 100644 --- a/Mathlib/NumberTheory/Cyclotomic/Basic.lean +++ b/Mathlib/NumberTheory/Cyclotomic/Basic.lean @@ -129,9 +129,10 @@ theorem trans (C : Type w) [CommRing C] [Algebra A C] [Algebra B C] [IsScalarTow refine ⟨algebraMap B C b, ?_⟩ exact hb.map_of_injective h · exact ((isCyclotomicExtension_iff _ _ _).1 hT).1 hn - · refine adjoin_induction (((isCyclotomicExtension_iff T B _).1 hT).2 x) + · refine adjoin_induction (hx := ((isCyclotomicExtension_iff T B _).1 hT).2 x) (fun c ⟨n, hn⟩ => subset_adjoin ⟨n, Or.inr hn.1, hn.2⟩) (fun b => ?_) - (fun x y hx hy => Subalgebra.add_mem _ hx hy) fun x y hx hy => Subalgebra.mul_mem _ hx hy + (fun x y _ _ hx hy => Subalgebra.add_mem _ hx hy) + fun x y _ _ hx hy => Subalgebra.mul_mem _ hx hy let f := IsScalarTower.toAlgHom A B C have hb : f b ∈ (adjoin A {b : B | ∃ a : ℕ+, a ∈ S ∧ b ^ (a : ℕ) = 1}).map f := ⟨b, ((isCyclotomicExtension_iff _ _ _).1 hS).2 b, rfl⟩ @@ -386,11 +387,11 @@ theorem _root_.IsPrimitiveRoot.adjoin_isCyclotomicExtension {ζ : B} {n : ℕ+} rw [Set.mem_singleton_iff] at hi refine ⟨⟨ζ, subset_adjoin <| Set.mem_singleton ζ⟩, ?_⟩ rwa [← IsPrimitiveRoot.coe_submonoidClass_iff, Subtype.coe_mk, hi] - adjoin_roots := fun x => by + adjoin_roots := fun ⟨x, hx⟩ => by refine - adjoin_induction' - (x := x) (fun b hb => ?_) (fun a => ?_) (fun b₁ b₂ hb₁ hb₂ => ?_) - (fun b₁ b₂ hb₁ hb₂ => ?_) + adjoin_induction + (hx := hx) (fun b hb => ?_) (fun a => ?_) (fun b₁ b₂ _ _ hb₁ hb₂ => ?_) + (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] @@ -614,8 +615,10 @@ instance isCyclotomicExtension [IsFractionRing A K] [NeZero ((n : ℕ) : A)] : rwa [← isRoot_cyclotomic_iff] at hμ · rwa [← IsPrimitiveRoot.coe_submonoidClass_iff, Subtype.coe_mk] adjoin_roots x := by + obtain ⟨x, hx⟩ := x refine - adjoin_induction' (fun y hy => ?_) (fun a => ?_) (fun y z hy hz => ?_) (fun y z hy hz => ?_) x + 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] rwa [← Subalgebra.coe_eq_one, Subalgebra.coe_pow, Subtype.coe_mk] @@ -634,9 +637,8 @@ instance [IsFractionRing A K] [IsDomain A] [NeZero ((n : ℕ) : A)] : letI : NeZero ((n : ℕ) : K) := NeZero.nat_of_injective (IsFractionRing.injective A K) refine Algebra.adjoin_induction - (((IsCyclotomicExtension.iff_singleton n K (CyclotomicField n K)).1 - (CyclotomicField.isCyclotomicExtension n K)).2 - x) + (hx := ((IsCyclotomicExtension.iff_singleton n K (CyclotomicField n K)).1 + (CyclotomicField.isCyclotomicExtension n K)).2 x) (fun y hy => ?_) (fun k => ?_) ?_ ?_ -- Porting note: the last goal was `by simpa` that now fails. · exact ⟨⟨⟨y, subset_adjoin hy⟩, 1⟩, by simp; rfl⟩ @@ -650,12 +652,12 @@ instance [IsFractionRing A K] [IsDomain A] [NeZero ((n : ℕ) : A)] : rw [← IsScalarTower.algebraMap_apply, ← IsScalarTower.algebraMap_apply, @IsScalarTower.algebraMap_apply A K _ _ _ _ _ (_root_.CyclotomicField.algebra n K) _ _ w, ← RingHom.map_mul, hw, ← IsScalarTower.algebraMap_apply] - · rintro y z ⟨a, ha⟩ ⟨b, hb⟩ + · rintro y z - - ⟨a, ha⟩ ⟨b, hb⟩ refine ⟨⟨a.1 * b.2 + b.1 * a.2, a.2 * b.2, mul_mem_nonZeroDivisors.2 ⟨a.2.2, b.2.2⟩⟩, ?_⟩ rw [RingHom.map_mul, add_mul, ← mul_assoc, ha, mul_comm ((algebraMap (CyclotomicRing n A K) _) ↑a.2), ← mul_assoc, hb] simp only [map_add, map_mul] - · rintro y z ⟨a, ha⟩ ⟨b, hb⟩ + · rintro y z - - ⟨a, ha⟩ ⟨b, hb⟩ refine ⟨⟨a.1 * b.1, a.2 * b.2, mul_mem_nonZeroDivisors.2 ⟨a.2.2, b.2.2⟩⟩, ?_⟩ rw [RingHom.map_mul, mul_comm ((algebraMap (CyclotomicRing n A K) _) ↑a.2), mul_assoc, ← mul_assoc z, hb, ← mul_comm ((algebraMap (CyclotomicRing n A K) _) ↑a.2), ← mul_assoc, ha] diff --git a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean index c62e465bc30d54..73c8984828756c 100644 --- a/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/CanonicalEmbedding/Basic.lean @@ -57,7 +57,7 @@ that `conj x_φ = x_(conj φ)` for all `∀ φ : K →+* ℂ`. -/ theorem conj_apply {x : ((K →+* ℂ) → ℂ)} (φ : K →+* ℂ) (hx : x ∈ Submodule.span ℝ (Set.range (canonicalEmbedding K))) : conj (x φ) = x (ComplexEmbedding.conjugate φ) := by - refine Submodule.span_induction hx ?_ ?_ (fun _ _ hx hy => ?_) (fun a _ hx => ?_) + refine Submodule.span_induction ?_ ?_ (fun _ _ _ _ hx hy => ?_) (fun a _ _ hx => ?_) hx · rintro _ ⟨x, rfl⟩ rw [apply_at, apply_at, ComplexEmbedding.conjugate_coe_eq] · rw [Pi.zero_apply, Pi.zero_apply, map_zero] diff --git a/Mathlib/RingTheory/Adjoin/Basic.lean b/Mathlib/RingTheory/Adjoin/Basic.lean index 83e58942dce2b5..9daf1551d86722 100644 --- a/Mathlib/RingTheory/Adjoin/Basic.lean +++ b/Mathlib/RingTheory/Adjoin/Basic.lean @@ -69,66 +69,71 @@ theorem adjoin_attach_biUnion [DecidableEq A] {α : Type*} {s : Finset α} (f : adjoin R (s.attach.biUnion f : Set A) = ⨆ x, adjoin R (f x) := by simp [adjoin_iUnion] @[elab_as_elim] -theorem adjoin_induction {p : A → Prop} {x : A} (h : x ∈ adjoin R s) (mem : ∀ x ∈ s, p x) - (algebraMap : ∀ r, p (algebraMap R A r)) (add : ∀ x y, p x → p y → p (x + y)) - (mul : ∀ x y, p x → p y → p (x * y)) : p x := +theorem adjoin_induction {p : (x : A) → x ∈ adjoin R s → Prop} + (mem : ∀ (x) (hx : x ∈ s), p x (subset_adjoin hx)) + (algebraMap : ∀ r, p (algebraMap R A r) (algebraMap_mem _ r)) + (add : ∀ x y hx hy, p x hx → p y hy → p (x + y) (add_mem hx hy)) + (mul : ∀ x y hx hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) + {x : A} (hx : x ∈ adjoin R s) : p x hx := let S : Subalgebra R A := - { carrier := p - mul_mem' := mul _ _ - add_mem' := add _ _ - algebraMap_mem' := algebraMap } - adjoin_le (show s ≤ S from mem) h + { carrier := { x | ∃ hx, p x hx } + mul_mem' := by rintro _ _ ⟨_, hpx⟩ ⟨_, hpy⟩; exact ⟨_, mul _ _ _ _ hpx hpy⟩ + add_mem' := by rintro _ _ ⟨_, hpx⟩ ⟨_, hpy⟩; exact ⟨_, add _ _ _ _ hpx hpy⟩ + algebraMap_mem' := fun r ↦ ⟨_, algebraMap r⟩ } + adjoin_le (S := S) (fun y hy ↦ ⟨subset_adjoin hy, mem y hy⟩) hx |>.elim fun _ ↦ _root_.id + +@[deprecated adjoin_induction (since := "2024-10-10")] +alias adjoin_induction'' := adjoin_induction /-- Induction principle for the algebra generated by a set `s`: show that `p x y` holds for any `x y ∈ adjoin R s` given that it holds for `x y ∈ s` and that it satisfies a number of natural properties. -/ @[elab_as_elim] -theorem adjoin_induction₂ {p : A → A → Prop} {a b : A} (ha : a ∈ adjoin R s) (hb : b ∈ adjoin R s) - (Hs : ∀ x ∈ s, ∀ y ∈ s, p x y) (Halg : ∀ r₁ r₂, p (algebraMap R A r₁) (algebraMap R A r₂)) - (Halg_left : ∀ (r), ∀ x ∈ s, p (algebraMap R A r) x) - (Halg_right : ∀ (r), ∀ x ∈ s, p x (algebraMap R A r)) - (Hadd_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ + x₂) y) - (Hadd_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ + y₂)) - (Hmul_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ * x₂) y) - (Hmul_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ * y₂)) : p a b := by - refine adjoin_induction hb ?_ (fun r => ?_) (Hadd_right a) (Hmul_right a) - · exact adjoin_induction ha Hs Halg_left - (fun x y Hx Hy z hz => Hadd_left x y z (Hx z hz) (Hy z hz)) - fun x y Hx Hy z hz => Hmul_left x y z (Hx z hz) (Hy z hz) - · exact adjoin_induction ha (Halg_right r) (fun r' => Halg r' r) - (fun x y => Hadd_left x y ((algebraMap R A) r)) - fun x y => Hmul_left x y ((algebraMap R A) r) +theorem adjoin_induction₂ {s : Set A} {p : (x y : A) → x ∈ adjoin R s → y ∈ adjoin R s → Prop} + (mem_mem : ∀ (x) (y) (hx : x ∈ s) (hy : y ∈ s), p x y (subset_adjoin hx) (subset_adjoin hy)) + (algebraMap_both : ∀ r₁ r₂, p (algebraMap R A r₁) (algebraMap R A r₂) (algebraMap_mem _ r₁) + (algebraMap_mem _ r₂)) + (algebraMap_left : ∀ (r) (x) (hx : x ∈ s), p (algebraMap R A r) x (algebraMap_mem _ r) + (subset_adjoin hx)) + (algebraMap_right : ∀ (r) (x) (hx : x ∈ s), p x (algebraMap R A r) (subset_adjoin hx) + (algebraMap_mem _ r)) + (add_left : ∀ x y z hx hy hz, p x z hx hz → p y z hy hz → p (x + y) z (add_mem hx hy) hz) + (add_right : ∀ x y z hx hy hz, p x y hx hy → p x z hx hz → p x (y + z) hx (add_mem hy hz)) + (mul_left : ∀ x y z hx hy hz, p x z hx hz → p y z hy hz → p (x * y) z (mul_mem hx hy) hz) + (mul_right : ∀ x y z hx hy hz, p x y hx hy → p x z hx hz → p x (y * z) hx (mul_mem hy hz)) + {x y : A} (hx : x ∈ adjoin R s) (hy : y ∈ adjoin R s) : + p x y hx hy := by + induction hy using adjoin_induction with + | mem z hz => induction hx using adjoin_induction with + | mem _ h => exact mem_mem _ _ h hz + | algebraMap _ => exact algebraMap_left _ _ hz + | mul _ _ _ _ h₁ h₂ => exact mul_left _ _ _ _ _ _ h₁ h₂ + | add _ _ _ _ h₁ h₂ => exact add_left _ _ _ _ _ _ h₁ h₂ + | algebraMap r => + induction hx using adjoin_induction with + | mem _ h => exact algebraMap_right _ _ h + | algebraMap _ => exact algebraMap_both _ _ + | mul _ _ _ _ h₁ h₂ => exact mul_left _ _ _ _ _ _ h₁ h₂ + | add _ _ _ _ h₁ h₂ => exact add_left _ _ _ _ _ _ h₁ h₂ + | mul _ _ _ _ h₁ h₂ => exact mul_right _ _ _ _ _ _ h₁ h₂ + | add _ _ _ _ h₁ h₂ => exact add_right _ _ _ _ _ _ h₁ h₂ /-- The difference with `Algebra.adjoin_induction` is that this acts on the subtype. -/ -@[elab_as_elim] +@[elab_as_elim, deprecated adjoin_induction (since := "2024-10-11")] theorem adjoin_induction' {p : adjoin R s → Prop} (mem : ∀ (x) (h : x ∈ s), p ⟨x, subset_adjoin h⟩) (algebraMap : ∀ r, p (algebraMap R _ r)) (add : ∀ x y, p x → p y → p (x + y)) (mul : ∀ x y, p x → p y → p (x * y)) (x : adjoin R s) : p x := Subtype.recOn x fun x hx => by - refine Exists.elim ?_ fun (hx : x ∈ adjoin R s) (hc : p ⟨x, hx⟩) => hc - exact adjoin_induction hx (fun x hx => ⟨subset_adjoin hx, mem x hx⟩) - (fun r => ⟨Subalgebra.algebraMap_mem _ r, algebraMap r⟩) - (fun x y hx hy => - Exists.elim hx fun hx' hx => - Exists.elim hy fun hy' hy => ⟨Subalgebra.add_mem _ hx' hy', add _ _ hx hy⟩) - fun x y hx hy => - Exists.elim hx fun hx' hx => - Exists.elim hy fun hy' hy => ⟨Subalgebra.mul_mem _ hx' hy', mul _ _ hx hy⟩ - -@[elab_as_elim] -theorem adjoin_induction'' {x : A} (hx : x ∈ adjoin R s) - {p : (x : A) → x ∈ adjoin R s → Prop} (mem : ∀ x (h : x ∈ s), p x (subset_adjoin h)) - (algebraMap : ∀ (r : R), p (algebraMap R A r) (algebraMap_mem _ r)) - (add : ∀ x hx y hy, p x hx → p y hy → p (x + y) (add_mem hx hy)) - (mul : ∀ x hx y hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) : - p x hx := by - refine adjoin_induction' mem algebraMap ?_ ?_ ⟨x, hx⟩ (p := fun x : adjoin R s ↦ p x.1 x.2) - exacts [fun x y ↦ add x.1 x.2 y.1 y.2, fun x y ↦ mul x.1 x.2 y.1 y.2] + induction hx using adjoin_induction with + | mem _ h => exact mem _ h + | algebraMap _ => exact algebraMap _ + | mul _ _ _ _ h₁ h₂ => exact mul _ _ h₁ h₂ + | add _ _ _ _ h₁ h₂ => exact add _ _ h₁ h₂ @[simp] theorem adjoin_adjoin_coe_preimage {s : Set A} : adjoin R (((↑) : adjoin R s → A) ⁻¹' s) = ⊤ := by - refine eq_top_iff.2 fun x ↦ - adjoin_induction' (fun a ha ↦ ?_) (fun r ↦ ?_) (fun _ _ ↦ ?_) (fun _ _ ↦ ?_) x + refine eq_top_iff.2 fun ⟨x, hx⟩ ↦ + adjoin_induction (fun a ha ↦ ?_) (fun r ↦ ?_) (fun _ _ _ _ ↦ ?_) (fun _ _ _ _ ↦ ?_) hx · exact subset_adjoin ha · exact Subalgebra.algebraMap_mem _ r · exact Subalgebra.add_mem _ @@ -219,16 +224,16 @@ theorem adjoin_prod_le (s : Set A) (t : Set B) : theorem mem_adjoin_of_map_mul {s} {x : A} {f : A →ₗ[R] B} (hf : ∀ a₁ a₂, f (a₁ * a₂) = f a₁ * f a₂) (h : x ∈ adjoin R s) : f x ∈ adjoin R (f '' (s ∪ {1})) := by - refine - @adjoin_induction R A _ _ _ _ (fun a => f a ∈ adjoin R (f '' (s ∪ {1}))) x h - (fun a ha => subset_adjoin ⟨a, ⟨Set.subset_union_left ha, rfl⟩⟩) (fun r => ?_) - (fun y z hy hz => by simpa [hy, hz] using Subalgebra.add_mem _ hy hz) fun y z hy hz => by - simpa [hy, hz, hf y z] using Subalgebra.mul_mem _ hy hz - have : f 1 ∈ adjoin R (f '' (s ∪ {1})) := - subset_adjoin ⟨1, ⟨Set.subset_union_right <| Set.mem_singleton 1, rfl⟩⟩ - convert Subalgebra.smul_mem (adjoin R (f '' (s ∪ {1}))) this r - rw [algebraMap_eq_smul_one] - exact f.map_smul _ _ + induction h using adjoin_induction with + | mem a ha => exact subset_adjoin ⟨a, ⟨Set.subset_union_left ha, rfl⟩⟩ + | algebraMap r => + have : f 1 ∈ adjoin R (f '' (s ∪ {1})) := + subset_adjoin ⟨1, ⟨Set.subset_union_right <| Set.mem_singleton 1, rfl⟩⟩ + convert Subalgebra.smul_mem (adjoin R (f '' (s ∪ {1}))) this r + rw [algebraMap_eq_smul_one] + exact f.map_smul _ _ + | add y z _ _ hy hz => simpa [hy, hz] using Subalgebra.add_mem _ hy hz + | mul y z _ _ hy hz => simpa [hf, hy, hz] using Subalgebra.mul_mem _ hy hz theorem adjoin_inl_union_inr_eq_prod (s) (t) : adjoin R (LinearMap.inl R A B '' (s ∪ {1}) ∪ LinearMap.inr R A B '' (t ∪ {1})) = @@ -255,23 +260,29 @@ semiring. -/ def adjoinCommSemiringOfComm {s : Set A} (hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a) : CommSemiring (adjoin R s) := { (adjoin R s).toSemiring with - mul_comm := fun x y => by + mul_comm := fun ⟨x, hx⟩ ⟨y, hy⟩ => by ext - simp only [Subalgebra.coe_mul] - exact adjoin_induction₂ x.prop y.prop hcomm (fun _ _ => by rw [commutes]) - (fun r x _hx => commutes r x) (fun r x _hx => (commutes r x).symm) - (fun _ _ _ h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂]) - (fun _ _ _ h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂]) - (fun x₁ x₂ y₁ h₁ h₂ => by rw [mul_assoc, h₂, ← mul_assoc y₁, ← h₁, mul_assoc x₁]) - fun x₁ x₂ y₁ h₁ h₂ => by rw [mul_assoc x₂, ← h₂, ← mul_assoc x₂, ← h₁, ← mul_assoc] } + simp only [MulMemClass.mk_mul_mk] + induction hx, hy using adjoin_induction₂ with + | mem_mem x y hx hy => exact hcomm x hx y hy + | algebraMap_both r₁ r₂ => exact commutes r₁ <| algebraMap R A r₂ + | algebraMap_left r x _ => exact commutes r x + | algebraMap_right r x _ => exact commutes r x |>.symm + | mul_left _ _ _ _ _ _ h₁ h₂ => exact Commute.mul_left h₁ h₂ + | mul_right _ _ _ _ _ _ h₁ h₂ => exact Commute.mul_right h₁ h₂ + | add_left _ _ _ _ _ _ h₁ h₂ => exact Commute.add_left h₁ h₂ + | add_right _ _ _ _ _ _ h₁ h₂ => exact Commute.add_right h₁ h₂ } variable {R} lemma commute_of_mem_adjoin_of_forall_mem_commute {a b : A} {s : Set A} (hb : b ∈ adjoin R s) (h : ∀ b ∈ s, Commute a b) : - Commute a b := - adjoin_induction hb h (fun r ↦ commute_algebraMap_right r a) (fun _ _ ↦ Commute.add_right) - (fun _ _ ↦ Commute.mul_right) + Commute a b := by + induction hb using adjoin_induction with + | mem x hx => exact h x hx + | algebraMap r => exact commutes r a |>.symm + | add y z _ _ hy hz => exact hy.add_right hz + | mul y z _ _ hy hz => exact hy.mul_right hz lemma commute_of_mem_adjoin_singleton_of_commute {a b c : A} (hc : c ∈ adjoin R {b}) (h : Commute a b) : @@ -388,8 +399,8 @@ variable [Algebra R A] {s t : Set A} theorem mem_adjoin_iff {s : Set A} {x : A} : x ∈ adjoin R s ↔ x ∈ Subring.closure (Set.range (algebraMap R A) ∪ s) := ⟨fun hx => - Subsemiring.closure_induction hx Subring.subset_closure (Subring.zero_mem _) (Subring.one_mem _) - (fun _ _ => Subring.add_mem _) fun _ _ => Subring.mul_mem _, + Subsemiring.closure_induction Subring.subset_closure (Subring.zero_mem _) (Subring.one_mem _) + (fun _ _ _ _ => Subring.add_mem _) (fun _ _ _ _ => Subring.mul_mem _) hx, suffices Subring.closure (Set.range (algebraMap R A) ∪ s) ≤ (adjoin R s).toSubring from (show (_ : Set A) ⊆ _ from this) (a := x) -- Porting note: Lean doesn't seem to recognize the defeq between the order on subobjects and diff --git a/Mathlib/RingTheory/Adjoin/Tower.lean b/Mathlib/RingTheory/Adjoin/Tower.lean index 131178ee351d32..c916d295726485 100644 --- a/Mathlib/RingTheory/Adjoin/Tower.lean +++ b/Mathlib/RingTheory/Adjoin/Tower.lean @@ -126,8 +126,8 @@ theorem exists_subalgebra_of_fg (hAC : (⊤ : Subalgebra A C).FG) (hBC : (⊤ : rw [restrictScalars_top, eq_top_iff, ← Algebra.top_toSubmodule, ← hx, Algebra.adjoin_eq_span, span_le] refine fun r hr => - Submonoid.closure_induction hr (fun c hc => hxy c hc) (subset_span <| mem_insert_self _ _) - fun p q hp hq => hyy <| Submodule.mul_mem_mul hp hq + Submonoid.closure_induction (fun c hc => hxy c hc) (subset_span <| mem_insert_self _ _) + (fun p q _ _ hp hq => hyy <| Submodule.mul_mem_mul hp hq) hr end Semiring diff --git a/Mathlib/RingTheory/DedekindDomain/Ideal.lean b/Mathlib/RingTheory/DedekindDomain/Ideal.lean index c730c6a9168db2..1865cebc778f35 100644 --- a/Mathlib/RingTheory/DedekindDomain/Ideal.lean +++ b/Mathlib/RingTheory/DedekindDomain/Ideal.lean @@ -763,11 +763,11 @@ theorem Ideal.exist_integer_multiples_not_mem {J : Ideal A} (hJ : J ≠ ⊤) {ι · contrapose! hpI -- And if all `a`-multiples of `I` are an element of `J`, -- then `a` is actually an element of `J / I`, contradiction. - refine (mem_div_iff_of_nonzero hI0).mpr fun y hy => Submodule.span_induction hy ?_ ?_ ?_ ?_ + refine (mem_div_iff_of_nonzero hI0).mpr fun y hy => Submodule.span_induction ?_ ?_ ?_ ?_ hy · rintro _ ⟨i, hi, rfl⟩; exact hpI i hi · rw [mul_zero]; exact Submodule.zero_mem _ - · intro x y hx hy; rw [mul_add]; exact Submodule.add_mem _ hx hy - · intro b x hx; rw [mul_smul_comm]; exact Submodule.smul_mem _ b hx + · intro x y _ _ hx hy; rw [mul_add]; exact Submodule.add_mem _ hx hy + · intro b x _ hx; rw [mul_smul_comm]; exact Submodule.smul_mem _ b hx -- To show the inclusion of `J / I` into `I⁻¹ = 1 / I`, note that `J < I`. calc ↑J / I = ↑J * I⁻¹ := div_eq_mul_inv (↑J) I diff --git a/Mathlib/RingTheory/Derivation/Basic.lean b/Mathlib/RingTheory/Derivation/Basic.lean index 51dccf2f460eaa..6ff64b463c8401 100644 --- a/Mathlib/RingTheory/Derivation/Basic.lean +++ b/Mathlib/RingTheory/Derivation/Basic.lean @@ -152,8 +152,9 @@ theorem map_aeval (P : R[X]) (x : A) : · simp [mul_smul, ← Nat.cast_smul_eq_nsmul A] theorem eqOn_adjoin {s : Set A} (h : Set.EqOn D1 D2 s) : Set.EqOn D1 D2 (adjoin R s) := fun _ hx => - Algebra.adjoin_induction hx h (fun r => (D1.map_algebraMap r).trans (D2.map_algebraMap r).symm) - (fun x y hx hy => by simp only [map_add, *]) fun x y hx hy => by simp only [leibniz, *] + Algebra.adjoin_induction (hx := hx) h + (fun r => (D1.map_algebraMap r).trans (D2.map_algebraMap r).symm) + (fun x y _ _ hx hy => by simp only [map_add, *]) fun x y _ _ hx hy => by simp only [leibniz, *] /-- If adjoin of a set is the whole algebra, then any two derivations equal on this set are equal on the whole algebra. -/ diff --git a/Mathlib/RingTheory/EssentialFiniteness.lean b/Mathlib/RingTheory/EssentialFiniteness.lean index c23b4328ea0fb1..195e86ad43bdf0 100644 --- a/Mathlib/RingTheory/EssentialFiniteness.lean +++ b/Mathlib/RingTheory/EssentialFiniteness.lean @@ -109,7 +109,7 @@ lemma EssFiniteType.aux (σ : Subalgebra R S) (hσ : ∀ s : S, ∃ t ∈ σ, IsUnit t ∧ s * t ∈ σ) (τ : Set T) (t : T) (ht : t ∈ Algebra.adjoin S τ) : ∃ s ∈ σ, IsUnit s ∧ s • t ∈ σ.map (IsScalarTower.toAlgHom R S T) ⊔ Algebra.adjoin R τ := by - refine Algebra.adjoin_induction ht ?_ ?_ ?_ ?_ + refine Algebra.adjoin_induction ?_ ?_ ?_ ?_ ht · intro t ht exact ⟨1, Subalgebra.one_mem _, isUnit_one, (one_smul S t).symm ▸ Algebra.mem_sup_right (Algebra.subset_adjoin ht)⟩ @@ -118,13 +118,13 @@ lemma EssFiniteType.aux (σ : Subalgebra R S) refine ⟨_, hs₁, hs₂, Algebra.mem_sup_left ?_⟩ rw [Algebra.smul_def, ← map_mul, mul_comm] exact ⟨_, hs₃, rfl⟩ - · rintro x y ⟨sx, hsx, hsx', hsx''⟩ ⟨sy, hsy, hsy', hsy''⟩ + · rintro x y - - ⟨sx, hsx, hsx', hsx''⟩ ⟨sy, hsy, hsy', hsy''⟩ refine ⟨_, σ.mul_mem hsx hsy, hsx'.mul hsy', ?_⟩ rw [smul_add, mul_smul, mul_smul, Algebra.smul_def sx (sy • y), smul_comm, Algebra.smul_def sy (sx • x)] apply add_mem (mul_mem _ hsx'') (mul_mem _ hsy'') <;> exact Algebra.mem_sup_left ⟨_, ‹_›, rfl⟩ - · rintro x y ⟨sx, hsx, hsx', hsx''⟩ ⟨sy, hsy, hsy', hsy''⟩ + · rintro x y - - ⟨sx, hsx, hsx', hsx''⟩ ⟨sy, hsy, hsy', hsy''⟩ refine ⟨_, σ.mul_mem hsx hsy, hsx'.mul hsy', ?_⟩ rw [mul_smul, ← smul_eq_mul, smul_comm sy x, ← smul_assoc, smul_eq_mul] exact mul_mem hsx'' hsy'' @@ -212,12 +212,12 @@ lemma EssFiniteType.algHom_ext [EssFiniteType R S] ext; exact AlgHom.congr_fun this _ apply AlgHom.ext_of_adjoin_eq_top (s := { x | x.1 ∈ finset R S }) · rw [← top_le_iff] - rintro x _ - refine Algebra.adjoin_induction' ?_ ?_ ?_ ?_ x + rintro ⟨x, hx⟩ _ + refine Algebra.adjoin_induction ?_ ?_ ?_ ?_ hx · intro x hx; exact Algebra.subset_adjoin hx · intro r; exact Subalgebra.algebraMap_mem _ _ - · intro x y hx hy; exact add_mem hx hy - · intro x y hx hy; exact mul_mem hx hy + · intro x y _ _ hx hy; exact add_mem hx hy + · intro x y _ _ hx hy; exact mul_mem hx hy · rintro ⟨x, hx⟩ hx'; exact H x hx' end Algebra diff --git a/Mathlib/RingTheory/FinitePresentation.lean b/Mathlib/RingTheory/FinitePresentation.lean index b5f8a9e4728c85..7aac5e956cc7e7 100644 --- a/Mathlib/RingTheory/FinitePresentation.lean +++ b/Mathlib/RingTheory/FinitePresentation.lean @@ -261,7 +261,7 @@ theorem of_restrict_scalars_finitePresentation [Algebra A B] [IsScalarTower R A (Ideal.span s₀).toAddSubmonoid := by have : x ∈ (⊤ : Subalgebra R AX) := trivial rw [← ht''] at this - refine adjoin_induction this ?_ ?_ ?_ ?_ + refine adjoin_induction ?_ ?_ ?_ ?_ this · rintro _ (⟨x, hx, rfl⟩ | ⟨i, rfl⟩) · rw [MvPolynomial.algebraMap_eq, ← sub_add_cancel (MvPolynomial.C x) (map (algebraMap R A) (t' ⟨x, hx⟩)), add_comm] @@ -275,9 +275,9 @@ theorem of_restrict_scalars_finitePresentation [Algebra A B] [IsScalarTower R A · intro r apply AddSubmonoid.mem_sup_left exact ⟨C r, map_C _ _⟩ - · intro _ _ h₁ h₂ + · intro _ _ _ _ h₁ h₂ exact add_mem h₁ h₂ - · intro x₁ x₂ h₁ h₂ + · intro x₁ x₂ _ _ h₁ h₂ obtain ⟨_, ⟨p₁, rfl⟩, q₁, hq₁, rfl⟩ := AddSubmonoid.mem_sup.mp h₁ obtain ⟨_, ⟨p₂, rfl⟩, q₂, hq₂, rfl⟩ := AddSubmonoid.mem_sup.mp h₂ rw [add_mul, mul_add, add_assoc, ← map_mul] @@ -340,7 +340,7 @@ theorem ker_fg_of_mvPolynomial {n : ℕ} (f : MvPolynomial (Fin n) R →ₐ[R] A have : x ∈ adjoin R (Set.range X : Set RXn) := by rw [adjoin_range_X] trivial - refine adjoin_induction this ?_ ?_ ?_ ?_ + refine adjoin_induction ?_ ?_ ?_ ?_ this · rintro _ ⟨i, rfl⟩ rw [← sub_add_cancel (X i) (aeval h (g i)), add_comm] apply AddSubmonoid.add_mem_sup @@ -351,9 +351,9 @@ theorem ker_fg_of_mvPolynomial {n : ℕ} (f : MvPolynomial (Fin n) R →ₐ[R] A · intro r apply AddSubmonoid.mem_sup_left exact ⟨C r, aeval_C _ _⟩ - · intro _ _ h₁ h₂ + · intro _ _ _ _ h₁ h₂ exact add_mem h₁ h₂ - · intro p₁ p₂ h₁ h₂ + · intro p₁ p₂ _ _ h₁ h₂ obtain ⟨_, ⟨x₁, rfl⟩, y₁, hy₁, rfl⟩ := AddSubmonoid.mem_sup.mp h₁ obtain ⟨_, ⟨x₂, rfl⟩, y₂, hy₂, rfl⟩ := AddSubmonoid.mem_sup.mp h₂ rw [mul_add, add_mul, add_assoc, ← map_mul] diff --git a/Mathlib/RingTheory/FiniteType.lean b/Mathlib/RingTheory/FiniteType.lean index ed78e1a416de73..8eb4df96ddf807 100644 --- a/Mathlib/RingTheory/FiniteType.lean +++ b/Mathlib/RingTheory/FiniteType.lean @@ -403,10 +403,10 @@ theorem mvPolynomial_aeval_of_surjective_of_closure [AddCommMonoid M] [CommSemir intro f induction' f using induction_on with m f g ihf ihg r f ih · have : m ∈ closure S := hS.symm ▸ mem_top _ - refine AddSubmonoid.closure_induction this (fun m hm => ?_) ?_ ?_ + refine AddSubmonoid.closure_induction (fun m hm => ?_) ?_ ?_ this · exact ⟨MvPolynomial.X ⟨m, hm⟩, MvPolynomial.aeval_X _ _⟩ · exact ⟨1, map_one _⟩ - · rintro m₁ m₂ ⟨P₁, hP₁⟩ ⟨P₂, hP₂⟩ + · rintro m₁ m₂ _ _ ⟨P₁, hP₁⟩ ⟨P₂, hP₂⟩ exact ⟨P₁ * P₂, by rw [map_mul, hP₁, hP₂, of_apply, of_apply, of_apply, single_mul_single, @@ -428,10 +428,10 @@ theorem freeAlgebra_lift_of_surjective_of_closure [CommSemiring R] {S : Set M} intro f induction' f using induction_on with m f g ihf ihg r f ih · have : m ∈ closure S := hS.symm ▸ mem_top _ - refine AddSubmonoid.closure_induction this (fun m hm => ?_) ?_ ?_ + refine AddSubmonoid.closure_induction (fun m hm => ?_) ?_ ?_ this · exact ⟨FreeAlgebra.ι R ⟨m, hm⟩, FreeAlgebra.lift_ι_apply _ _⟩ · exact ⟨1, map_one _⟩ - · rintro m₁ m₂ ⟨P₁, hP₁⟩ ⟨P₂, hP₂⟩ + · rintro m₁ m₂ _ _ ⟨P₁, hP₁⟩ ⟨P₂, hP₂⟩ exact ⟨P₁ * P₂, by rw [map_mul, hP₁, hP₂, of_apply, of_apply, of_apply, single_mul_single, @@ -571,10 +571,10 @@ theorem mvPolynomial_aeval_of_surjective_of_closure [CommMonoid M] [CommSemiring intro f induction' f using induction_on with m f g ihf ihg r f ih · have : m ∈ closure S := hS.symm ▸ mem_top _ - refine Submonoid.closure_induction this (fun m hm => ?_) ?_ ?_ + refine Submonoid.closure_induction (fun m hm => ?_) ?_ ?_ this · exact ⟨MvPolynomial.X ⟨m, hm⟩, MvPolynomial.aeval_X _ _⟩ · exact ⟨1, map_one _⟩ - · rintro m₁ m₂ ⟨P₁, hP₁⟩ ⟨P₂, hP₂⟩ + · rintro m₁ m₂ _ _ ⟨P₁, hP₁⟩ ⟨P₂, hP₂⟩ exact ⟨P₁ * P₂, by rw [map_mul, hP₁, hP₂, of_apply, of_apply, of_apply, single_mul_single, one_mul]⟩ @@ -595,10 +595,10 @@ theorem freeAlgebra_lift_of_surjective_of_closure [CommSemiring R] {S : Set M} intro f induction' f using induction_on with m f g ihf ihg r f ih · have : m ∈ closure S := hS.symm ▸ mem_top _ - refine Submonoid.closure_induction this (fun m hm => ?_) ?_ ?_ + refine Submonoid.closure_induction (fun m hm => ?_) ?_ ?_ this · exact ⟨FreeAlgebra.ι R ⟨m, hm⟩, FreeAlgebra.lift_ι_apply _ _⟩ · exact ⟨1, map_one _⟩ - · rintro m₁ m₂ ⟨P₁, hP₁⟩ ⟨P₂, hP₂⟩ + · rintro m₁ m₂ _ _ ⟨P₁, hP₁⟩ ⟨P₂, hP₂⟩ exact ⟨P₁ * P₂, by rw [map_mul, hP₁, hP₂, of_apply, of_apply, of_apply, single_mul_single, one_mul]⟩ @@ -682,7 +682,7 @@ instance (priority := 100) CommRing.orzechProperty ((f.restrictScalars A).restrict fun x hx ↦ ?_ : N' →ₗ[A] M') (fun _ _ h ↦ injective_subtype _ (hi congr(($h).1))) fun ⟨x, hx⟩ ↦ ?_) ⟨n, (subset_span (by simp))⟩ (Subtype.val_injective hn)).1) - · induction hx using span_induction' with + · induction hx using span_induction with | mem x hx => change i x ∈ M' simp only [Set.singleton_union, Set.mem_insert_iff, Set.mem_range] at hx @@ -701,7 +701,7 @@ instance (priority := 100) CommRing.orzechProperty | zero => simp | add x _ y _ hx hy => rw [map_add]; exact add_mem hx hy | smul a x _ hx => rw [map_smul]; exact smul_mem _ _ hx - · induction hx using span_induction' with + · induction hx using span_induction with | mem x hx => change f x ∈ M' simp only [Set.singleton_union, Set.mem_insert_iff, Set.mem_range] at hx @@ -714,12 +714,12 @@ instance (priority := 100) CommRing.orzechProperty suffices x ∈ LinearMap.range ((f.restrictScalars A).domRestrict N') by obtain ⟨a, ha⟩ := this exact ⟨a, Subtype.val_injective ha⟩ - induction hx using span_induction' with + induction hx using span_induction with | mem x hx => obtain ⟨j, rfl⟩ := hx exact ⟨⟨nj j, subset_span (by simp)⟩, hnj j⟩ | zero => exact zero_mem _ - | add x _ y _ hx hy => exact add_mem hx hy + | add x y _ _ hx hy => exact add_mem hx hy | smul a x _ hx => exact smul_mem _ a hx end Orzech diff --git a/Mathlib/RingTheory/Finiteness.lean b/Mathlib/RingTheory/Finiteness.lean index 9b6993825be281..1425279d2a6741 100644 --- a/Mathlib/RingTheory/Finiteness.lean +++ b/Mathlib/RingTheory/Finiteness.lean @@ -630,7 +630,7 @@ theorem Module.End.isNilpotent_iff_of_finite {R M : Type*} [CommSemiring R] [Add use Finset.sup S g ext m have hm : m ∈ Submodule.span R S := by simp [hS] - induction hm using Submodule.span_induction' with + induction hm using Submodule.span_induction with | mem x hx => exact LinearMap.pow_map_zero_of_le (Finset.le_sup hx) (hg x) | zero => simp | add => simp_all diff --git a/Mathlib/RingTheory/FractionalIdeal/Extended.lean b/Mathlib/RingTheory/FractionalIdeal/Extended.lean index c2dcadde7c9b57..f3b9bc6f622889 100644 --- a/Mathlib/RingTheory/FractionalIdeal/Extended.lean +++ b/Mathlib/RingTheory/FractionalIdeal/Extended.lean @@ -45,8 +45,8 @@ def extended (I : FractionalIdeal M K) : FractionalIdeal N L where property := by have ⟨a, ha, frac⟩ := I.isFractional refine ⟨f a, hf ha, fun b hb ↦ ?_⟩ - refine span_induction hb (fun x hx ↦ ?_) ⟨0, by simp⟩ - (fun x y hx hy ↦ smul_add (f a) x y ▸ isInteger_add hx hy) (fun b c hc ↦ ?_) + refine span_induction (fun x hx ↦ ?_) ⟨0, by simp⟩ + (fun x y _ _ hx hy ↦ smul_add (f a) x y ▸ isInteger_add hx hy) (fun b c _ hc ↦ ?_) hb · rcases hx with ⟨k, kI, rfl⟩ obtain ⟨c, hc⟩ := frac k kI exact ⟨f c, by simp [← IsLocalization.map_smul, ← hc]⟩ @@ -69,8 +69,8 @@ theorem extended_zero : extended L hf (0 : FractionalIdeal M K) = 0 := @[simp] theorem extended_one : extended L hf (1 : FractionalIdeal M K) = 1 := by - refine coeToSubmodule_injective <| Submodule.ext fun x ↦ ⟨fun hx ↦ span_induction hx - ?_ (zero_mem _) (fun y z hy hz ↦ add_mem hy hz) (fun b y hy ↦ smul_mem _ b hy), ?_⟩ + refine coeToSubmodule_injective <| Submodule.ext fun x ↦ ⟨fun hx ↦ span_induction + ?_ (zero_mem _) (fun y z _ _ hy hz ↦ add_mem hy hz) (fun b y _ hy ↦ smul_mem _ b hy) hx, ?_⟩ · rintro ⟨b, _, rfl⟩ rw [Algebra.linearMap_apply, Algebra.algebraMap_eq_smul_one] exact smul_mem _ _ <| subset_span ⟨1, by simp [one_mem_one]⟩ @@ -98,7 +98,8 @@ theorem extended_mul : (I * J).extended L hf = (I.extended L hf) * (J.extended L · rcases h with ⟨x, hx, rfl⟩ replace hx : x ∈ (I : Submodule A K) * (J : Submodule A K) := coe_mul I J ▸ hx rw [Submodule.mul_eq_span_mul_set] at hx - refine span_induction hx (fun y hy ↦ ?_) (by simp) (fun y z hy hz ↦ ?_) (fun a y hy ↦ ?_) + refine span_induction (fun y hy ↦ ?_) (by simp) (fun y z _ _ hy hz ↦ ?_) + (fun a y _ hy ↦ ?_) hx · rcases Set.mem_mul.mp hy with ⟨i, hi, j, hj, rfl⟩ exact subset_span <| Set.mem_mul.mpr ⟨map_f i, ⟨i, hi, by simp [hi]⟩, map_f j, ⟨j, hj, by simp [hj]⟩, by simp⟩ diff --git a/Mathlib/RingTheory/FractionalIdeal/Operations.lean b/Mathlib/RingTheory/FractionalIdeal/Operations.lean index 5f88258c9e20ac..75d74307abf32d 100644 --- a/Mathlib/RingTheory/FractionalIdeal/Operations.lean +++ b/Mathlib/RingTheory/FractionalIdeal/Operations.lean @@ -155,14 +155,14 @@ theorem isFractional_span_iff {s : Set P} : IsFractional S (span R s) ↔ ∃ a ∈ S, ∀ b : P, b ∈ s → IsInteger R (a • b) := ⟨fun ⟨a, a_mem, h⟩ => ⟨a, a_mem, fun b hb => h b (subset_span hb)⟩, fun ⟨a, a_mem, h⟩ => ⟨a, a_mem, fun _ hb => - span_induction hb h + span_induction (hx := hb) h (by rw [smul_zero] exact isInteger_zero) - (fun x y hx hy => by + (fun x y _ _ hx hy => by rw [smul_add] exact isInteger_add hx hy) - fun s x hx => by + fun s x _ hx => by rw [smul_comm] exact isInteger_smul hx⟩⟩ @@ -516,15 +516,15 @@ variable (R₁) def spanFinset {ι : Type*} (s : Finset ι) (f : ι → K) : FractionalIdeal R₁⁰ K := ⟨Submodule.span R₁ (f '' s), by obtain ⟨a', ha'⟩ := IsLocalization.exist_integer_multiples R₁⁰ s f - refine ⟨a', a'.2, fun x hx => Submodule.span_induction hx ?_ ?_ ?_ ?_⟩ + refine ⟨a', a'.2, fun x hx => Submodule.span_induction ?_ ?_ ?_ ?_ hx⟩ · rintro _ ⟨i, hi, rfl⟩ exact ha' i hi · rw [smul_zero] exact IsLocalization.isInteger_zero - · intro x y hx hy + · intro x y _ _ hx hy rw [smul_add] exact IsLocalization.isInteger_add hx hy - · intro c x hx + · intro c x _ hx rw [smul_comm] exact IsLocalization.isInteger_smul hx⟩ diff --git a/Mathlib/RingTheory/Ideal/Maps.lean b/Mathlib/RingTheory/Ideal/Maps.lean index 6a3982baf6a298..687a565ce36b9d 100644 --- a/Mathlib/RingTheory/Ideal/Maps.lean +++ b/Mathlib/RingTheory/Ideal/Maps.lean @@ -294,10 +294,10 @@ theorem map_iInf_comap_of_surjective (K : ι → Ideal S) : (⨅ i, (K i).comap (giMapComap f hf).l_iInf_u _ theorem mem_image_of_mem_map_of_surjective {I : Ideal R} {y} (H : y ∈ map f I) : y ∈ f '' I := - Submodule.span_induction H (fun _ => id) ⟨0, I.zero_mem, map_zero f⟩ - (fun _ _ ⟨x1, hx1i, hxy1⟩ ⟨x2, hx2i, hxy2⟩ => + Submodule.span_induction (hx := H) (fun _ => id) ⟨0, I.zero_mem, map_zero f⟩ + (fun _ _ _ _ ⟨x1, hx1i, hxy1⟩ ⟨x2, hx2i, hxy2⟩ => ⟨x1 + x2, I.add_mem hx1i hx2i, hxy1 ▸ hxy2 ▸ map_add f _ _⟩) - fun c _ ⟨x, hxi, hxy⟩ => + fun c _ _ ⟨x, hxi, hxy⟩ => let ⟨d, hdc⟩ := hf c ⟨d * x, I.mul_mem_left _ hxi, hdc ▸ hxy ▸ map_mul f _ _⟩ diff --git a/Mathlib/RingTheory/Ideal/Operations.lean b/Mathlib/RingTheory/Ideal/Operations.lean index fcedd7484f3131..8a4763f3a510b9 100644 --- a/Mathlib/RingTheory/Ideal/Operations.lean +++ b/Mathlib/RingTheory/Ideal/Operations.lean @@ -81,13 +81,13 @@ theorem mem_annihilator_span (s : Set M) (r : R) : · intro h n exact h _ (Submodule.subset_span n.prop) · intro h n hn - refine Submodule.span_induction hn ?_ ?_ ?_ ?_ + refine Submodule.span_induction ?_ ?_ ?_ ?_ hn · intro x hx exact h ⟨x, hx⟩ · exact smul_zero _ - · intro x y hx hy + · intro x y _ _ hx hy rw [smul_add, hx, hy, zero_add] - · intro a x hx + · intro a x _ hx rw [smul_comm, hx, smul_zero] theorem mem_annihilator_span_singleton (g : M) (r : R) : @@ -304,7 +304,7 @@ theorem mem_ideal_smul_span_iff_exists_sum {ι : Type*} (f : ι → M) (x : M) : constructor; swap · rintro ⟨a, ha, rfl⟩ exact Submodule.sum_mem _ fun c _ => smul_mem_smul (ha c) <| subset_span <| Set.mem_range_self _ - refine fun hx => span_induction (mem_smul_span.mp hx) ?_ ?_ ?_ ?_ + refine fun hx => span_induction ?_ ?_ ?_ ?_ (mem_smul_span.mp hx) · simp only [Set.mem_iUnion, Set.mem_range, Set.mem_singleton_iff] rintro x ⟨y, hy, x, ⟨i, rfl⟩, rfl⟩ refine ⟨Finsupp.single i y, fun j => ?_, ?_⟩ @@ -316,10 +316,10 @@ theorem mem_ideal_smul_span_iff_exists_sum {ι : Type*} (f : ι → M) (x : M) : refine @Finsupp.sum_single_index ι R M _ _ i _ (fun i y => y • f i) ?_ simp · exact ⟨0, fun _ => I.zero_mem, Finsupp.sum_zero_index⟩ - · rintro x y ⟨ax, hax, rfl⟩ ⟨ay, hay, rfl⟩ + · rintro x y - - ⟨ax, hax, rfl⟩ ⟨ay, hay, rfl⟩ refine ⟨ax + ay, fun i => I.add_mem (hax i) (hay i), Finsupp.sum_add_index' ?_ ?_⟩ <;> intros <;> simp only [zero_smul, add_smul] - · rintro c x ⟨a, ha, rfl⟩ + · rintro c x - ⟨a, ha, rfl⟩ refine ⟨c • a, fun i => I.mul_mem_left c (ha i), ?_⟩ rw [Finsupp.sum_smul_index, Finsupp.smul_sum] <;> intros <;> simp only [zero_smul, mul_smul] diff --git a/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean b/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean index 146fc3d8f12a98..5c9727459cf1a4 100644 --- a/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean +++ b/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean @@ -142,8 +142,8 @@ theorem RingHom.IsIntegralElem.of_mul_unit (x y : S) (r : R) (hr : f r * y = 1) /-- Generalization of `IsIntegral.of_mem_closure` bootstrapped up from that lemma -/ theorem IsIntegral.of_mem_closure' (G : Set A) (hG : ∀ x ∈ G, IsIntegral R x) : ∀ x ∈ Subring.closure G, IsIntegral R x := fun _ hx ↦ - Subring.closure_induction hx hG isIntegral_zero isIntegral_one (fun _ _ ↦ IsIntegral.add) - (fun _ ↦ IsIntegral.neg) fun _ _ ↦ IsIntegral.mul + Subring.closure_induction hG isIntegral_zero isIntegral_one (fun _ _ _ _ ↦ IsIntegral.add) + (fun _ _ ↦ IsIntegral.neg) (fun _ _ _ _ ↦ IsIntegral.mul) hx theorem IsIntegral.of_mem_closure'' {S : Type*} [CommRing S] {f : R →+* S} (G : Set S) (hG : ∀ x ∈ G, f.IsIntegralElem x) : ∀ x ∈ Subring.closure G, f.IsIntegralElem x := fun x hx => diff --git a/Mathlib/RingTheory/Kaehler/Basic.lean b/Mathlib/RingTheory/Kaehler/Basic.lean index daf09320aeba75..5492f105c9f9bf 100644 --- a/Mathlib/RingTheory/Kaehler/Basic.lean +++ b/Mathlib/RingTheory/Kaehler/Basic.lean @@ -229,14 +229,14 @@ theorem KaehlerDifferential.span_range_derivation : suffices ∃ hx, (KaehlerDifferential.ideal R S).toCotangent ⟨x, hx⟩ ∈ Submodule.span S (Set.range <| KaehlerDifferential.D R S) by exact this.choose_spec - refine Submodule.span_induction this ?_ ?_ ?_ ?_ + refine Submodule.span_induction ?_ ?_ ?_ ?_ this · rintro _ ⟨x, rfl⟩ refine ⟨KaehlerDifferential.one_smul_sub_smul_one_mem_ideal R x, ?_⟩ apply Submodule.subset_span exact ⟨x, KaehlerDifferential.DLinearMap_apply R S x⟩ · exact ⟨zero_mem _, Submodule.zero_mem _⟩ - · rintro x y ⟨hx₁, hx₂⟩ ⟨hy₁, hy₂⟩; exact ⟨add_mem hx₁ hy₁, Submodule.add_mem _ hx₂ hy₂⟩ - · rintro r x ⟨hx₁, hx₂⟩ + · rintro x y - - ⟨hx₁, hx₂⟩ ⟨hy₁, hy₂⟩; exact ⟨add_mem hx₁ hy₁, Submodule.add_mem _ hx₂ hy₂⟩ + · rintro r x - ⟨hx₁, hx₂⟩ exact ⟨((KaehlerDifferential.ideal R S).restrictScalars S).smul_mem r hx₁, Submodule.smul_mem _ r hx₂⟩ @@ -291,11 +291,11 @@ theorem Derivation.liftKaehlerDifferential_unique (f f' : Ω[S⁄R] →ₗ[S] M) intro x have : x ∈ Submodule.span S (Set.range <| KaehlerDifferential.D R S) := by rw [KaehlerDifferential.span_range_derivation]; trivial - refine Submodule.span_induction this ?_ ?_ ?_ ?_ + refine Submodule.span_induction ?_ ?_ ?_ ?_ this · rintro _ ⟨x, rfl⟩; exact congr_arg (fun D : Derivation R S M => D x) hf · rw [map_zero, map_zero] - · intro x y hx hy; rw [map_add, map_add, hx, hy] - · intro a x e; simp [e] + · intro x y _ _ hx hy; rw [map_add, map_add, hx, hy] + · intro a x _ e; simp [e] variable (R S) @@ -471,11 +471,11 @@ instance KaehlerDifferential.finite [EssFiniteType R S] : have : ∀ x ∈ adjoin R (EssFiniteType.finset R S).toSet, .D _ _ x ∈ Submodule.span S s.toSet := by intro x hx - refine adjoin_induction hx ?_ ?_ ?_ ?_ + refine adjoin_induction ?_ ?_ ?_ ?_ hx · exact fun x hx ↦ Submodule.subset_span (Finset.mem_image_of_mem _ hx) · simp - · exact fun x y hx hy ↦ (D R S).map_add x y ▸ add_mem hx hy - · intro x y hx hy + · exact fun x y _ _ hx hy ↦ (D R S).map_add x y ▸ add_mem hx hy + · intro x y _ _ hx hy simp only [Derivation.leibniz] exact add_mem (Submodule.smul_mem _ _ hy) (Submodule.smul_mem _ _ hx) obtain ⟨t, ht, ht', hxt⟩ := (essFiniteType_cond_iff R S (EssFiniteType.finset R S)).mp diff --git a/Mathlib/RingTheory/Localization/Submodule.lean b/Mathlib/RingTheory/Localization/Submodule.lean index b1cda5e8116b6c..64d723f0fd50de 100644 --- a/Mathlib/RingTheory/Localization/Submodule.lean +++ b/Mathlib/RingTheory/Localization/Submodule.lean @@ -120,11 +120,11 @@ theorem mem_span_iff {N : Type*} [AddCommGroup N] [Module R N] [Module S N] [IsS x ∈ Submodule.span S a ↔ ∃ y ∈ Submodule.span R a, ∃ z : M, x = mk' S 1 z • y := by constructor · intro h - refine Submodule.span_induction h ?_ ?_ ?_ ?_ + refine Submodule.span_induction ?_ ?_ ?_ ?_ h · rintro x hx exact ⟨x, Submodule.subset_span hx, 1, by rw [mk'_one, map_one, one_smul]⟩ · exact ⟨0, Submodule.zero_mem _, 1, by rw [mk'_one, map_one, one_smul]⟩ - · rintro _ _ ⟨y, hy, z, rfl⟩ ⟨y', hy', z', rfl⟩ + · rintro _ _ _ _ ⟨y, hy, z, rfl⟩ ⟨y', hy', z', rfl⟩ refine ⟨(z' : R) • y + (z : R) • y', Submodule.add_mem _ (Submodule.smul_mem _ _ hy) (Submodule.smul_mem _ _ hy'), z * z', ?_⟩ @@ -133,7 +133,7 @@ theorem mem_span_iff {N : Type*} [AddCommGroup N] [Module R N] [Module S N] [IsS congr 1 · rw [← mul_one (1 : R), mk'_mul, mul_assoc, mk'_spec, map_one, mul_one, mul_one] · rw [← mul_one (1 : R), mk'_mul, mul_right_comm, mk'_spec, map_one, mul_one, one_mul] - · rintro a _ ⟨y, hy, z, rfl⟩ + · rintro a _ _ ⟨y, hy, z, rfl⟩ obtain ⟨y', z', rfl⟩ := mk'_surjective M a refine ⟨y' • y, Submodule.smul_mem _ _ hy, z' * z, ?_⟩ rw [← IsScalarTower.algebraMap_smul S y', smul_smul, ← mk'_mul, smul_smul, diff --git a/Mathlib/RingTheory/MvPolynomial/Localization.lean b/Mathlib/RingTheory/MvPolynomial/Localization.lean index 9f1b0b51970ce1..0eb65b979682de 100644 --- a/Mathlib/RingTheory/MvPolynomial/Localization.lean +++ b/Mathlib/RingTheory/MvPolynomial/Localization.lean @@ -91,13 +91,13 @@ private noncomputable def auxHom : (MvPolynomial Unit R) ⧸ (Ideal.span { C r * X () - 1 }) →ₐ[R] S := Ideal.Quotient.liftₐ (Ideal.span { C r * X () - 1}) (aeval (fun _ ↦ invSelf r)) <| by intro p hp - refine Submodule.span_induction hp ?_ ?_ ?_ ?_ + refine Submodule.span_induction ?_ ?_ ?_ ?_ hp · rintro p ⟨q, rfl⟩ simp · simp - · intro p q hp hq + · intro p q _ _ hp hq simp [hp, hq] - · intro a x hx + · intro a x _ hx simp [hx] @[simp] diff --git a/Mathlib/RingTheory/NonUnitalSubring/Basic.lean b/Mathlib/RingTheory/NonUnitalSubring/Basic.lean index e1b12c0376adc2..0833ddfb38894c 100644 --- a/Mathlib/RingTheory/NonUnitalSubring/Basic.lean +++ b/Mathlib/RingTheory/NonUnitalSubring/Basic.lean @@ -671,89 +671,104 @@ theorem closure_eq_of_le {s : Set R} {t : NonUnitalSubring R} (h₁ : s ⊆ t) ( of `s`, and is preserved under addition, negation, and multiplication, then `p` holds for all elements of the closure of `s`. -/ @[elab_as_elim] -theorem closure_induction {s : Set R} {p : R → Prop} {x} (h : x ∈ closure s) (mem : ∀ x ∈ s, p x) - (zero : p 0) (add : ∀ x y, p x → p y → p (x + y)) (neg : ∀ x : R, p x → p (-x)) - (mul : ∀ x y, p x → p y → p (x * y)) : p x := - (@closure_le _ _ _ ⟨⟨⟨⟨p, add _ _⟩, zero⟩, mul _ _⟩, neg _⟩).2 mem h +theorem closure_induction {s : Set R} {p : (x : R) → x ∈ closure s → Prop} + (mem : ∀ (x) (hx : x ∈ s), p x (subset_closure hx)) (zero : p 0 (zero_mem _)) + (add : ∀ x y hx hy, p x hx → p y hy → p (x + y) (add_mem hx hy)) + (neg : ∀ x hx, p x hx → p (-x) (neg_mem hx)) + (mul : ∀ x y hx hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) + {x} (hx : x ∈ closure s) : p x hx := + let K : NonUnitalSubring R := + { carrier := { x | ∃ hx, p x hx } + mul_mem' := fun ⟨_, hpx⟩ ⟨_, hpy⟩ ↦ ⟨_, mul _ _ _ _ hpx hpy⟩ + add_mem' := fun ⟨_, hpx⟩ ⟨_, hpy⟩ ↦ ⟨_, add _ _ _ _ hpx hpy⟩ + neg_mem' := fun ⟨_, hpx⟩ ↦ ⟨_, neg _ _ hpx⟩ + zero_mem' := ⟨_, zero⟩ } + closure_le (t := K) |>.mpr (fun y hy ↦ ⟨subset_closure hy, mem y hy⟩) hx |>.elim fun _ ↦ id /-- The difference with `NonUnitalSubring.closure_induction` is that this acts on the subtype. -/ -@[elab_as_elim] +@[elab_as_elim, deprecated closure_induction (since := "2024-10-11")] theorem closure_induction' {s : Set R} {p : closure s → Prop} (a : closure s) (mem : ∀ (x) (hx : x ∈ s), p ⟨x, subset_closure hx⟩) (zero : p 0) (add : ∀ x y, p x → p y → p (x + y)) (neg : ∀ x, p x → p (-x)) (mul : ∀ x y, p x → p y → p (x * y)) : p a := Subtype.recOn a fun b hb => by - refine Exists.elim ?_ fun (hb : b ∈ closure s) (hc : p ⟨b, hb⟩) => hc - refine - closure_induction hb (fun x hx => ⟨subset_closure hx, mem x hx⟩) - ⟨zero_mem (closure s), zero⟩ ?_ ?_ ?_ - · rintro x y ⟨hx, hpx⟩ ⟨hy, hpy⟩ - exact ⟨add_mem hx hy, add _ _ hpx hpy⟩ - · rintro x ⟨hx, hpx⟩ - exact ⟨neg_mem hx, neg _ hpx⟩ - · rintro x y ⟨hx, hpx⟩ ⟨hy, hpy⟩ - exact ⟨mul_mem hx hy, mul _ _ hpx hpy⟩ + induction hb using closure_induction with + | mem x hx => exact mem x hx + | zero => exact zero + | add x y hx hy h₁ h₂ => exact add _ _ h₁ h₂ + | neg x hx h => exact neg _ h + | mul x y hx hy h₁ h₂ => exact mul _ _ h₁ h₂ /-- An induction principle for closure membership, for predicates with two arguments. -/ @[elab_as_elim] -theorem closure_induction₂ {s : Set R} {p : R → R → Prop} {a b : R} (ha : a ∈ closure s) - (hb : b ∈ closure s) (Hs : ∀ x ∈ s, ∀ y ∈ s, p x y) (H0_left : ∀ x, p 0 x) - (H0_right : ∀ x, p x 0) (Hneg_left : ∀ x y, p x y → p (-x) y) - (Hneg_right : ∀ x y, p x y → p x (-y)) (Hadd_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ + x₂) y) - (Hadd_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ + y₂)) - (Hmul_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ * x₂) y) - (Hmul_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ * y₂)) : p a b := by - refine closure_induction hb ?_ (H0_right _) (Hadd_right a) (Hneg_right a) (Hmul_right a) - refine closure_induction ha Hs (fun x _ => H0_left x) ?_ ?_ ?_ - · exact fun x y H₁ H₂ z zs => Hadd_left x y z (H₁ z zs) (H₂ z zs) - · exact fun x hx z zs => Hneg_left x z (hx z zs) - · exact fun x y H₁ H₂ z zs => Hmul_left x y z (H₁ z zs) (H₂ z zs) +theorem closure_induction₂ {s : Set R} {p : (x y : R) → x ∈ closure s → y ∈ closure s → Prop} + (mem_mem : ∀ (x) (y) (hx : x ∈ s) (hy : y ∈ s), p x y (subset_closure hx) (subset_closure hy)) + (zero_left : ∀ x hx, p 0 x (zero_mem _) hx) (zero_right : ∀ x hx, p x 0 hx (zero_mem _)) + (neg_left : ∀ x y hx hy, p x y hx hy → p (-x) y (neg_mem hx) hy) + (neg_right : ∀ x y hx hy, p x y hx hy → p x (-y) hx (neg_mem hy)) + (add_left : ∀ x y z hx hy hz, p x z hx hz → p y z hy hz → p (x + y) z (add_mem hx hy) hz) + (add_right : ∀ x y z hx hy hz, p x y hx hy → p x z hx hz → p x (y + z) hx (add_mem hy hz)) + (mul_left : ∀ x y z hx hy hz, p x z hx hz → p y z hy hz → p (x * y) z (mul_mem hx hy) hz) + (mul_right : ∀ x y z hx hy hz, p x y hx hy → p x z hx hz → p x (y * z) hx (mul_mem hy hz)) + {x y : R} (hx : x ∈ closure s) (hy : y ∈ closure s) : + p x y hx hy := by + induction hy using closure_induction with + | mem z hz => induction hx using closure_induction with + | mem _ h => exact mem_mem _ _ h hz + | zero => exact zero_left _ _ + | mul _ _ _ _ h₁ h₂ => exact mul_left _ _ _ _ _ _ h₁ h₂ + | add _ _ _ _ h₁ h₂ => exact add_left _ _ _ _ _ _ h₁ h₂ + | neg _ _ h => exact neg_left _ _ _ _ h + | zero => exact zero_right x hx + | mul _ _ _ _ h₁ h₂ => exact mul_right _ _ _ _ _ _ h₁ h₂ + | add _ _ _ _ h₁ h₂ => exact add_right _ _ _ _ _ _ h₁ h₂ + | neg _ _ h => exact neg_right _ _ _ _ h theorem mem_closure_iff {s : Set R} {x} : x ∈ closure s ↔ x ∈ AddSubgroup.closure (Subsemigroup.closure s : Set R) := - ⟨fun h => - closure_induction h (fun _ hx => AddSubgroup.subset_closure <| Subsemigroup.subset_closure hx) - (AddSubgroup.zero_mem _) (fun _ _ hx hy => AddSubgroup.add_mem _ hx hy) - (fun _ hx => AddSubgroup.neg_mem _ hx) fun x _ hx hy => - AddSubgroup.closure_induction hy - (fun q hq => - AddSubgroup.closure_induction hx - (fun _ hp => AddSubgroup.subset_closure ((Subsemigroup.closure s).mul_mem hp hq)) - (by rw [zero_mul q]; apply AddSubgroup.zero_mem _) - (fun p₁ p₂ ihp₁ ihp₂ => by rw [add_mul p₁ p₂ q]; apply AddSubgroup.add_mem _ ihp₁ ihp₂) - fun x hx => by - have f : -x * q = -(x * q) := by simp - rw [f]; apply AddSubgroup.neg_mem _ hx) - (by rw [mul_zero x]; apply AddSubgroup.zero_mem _) - (fun q₁ q₂ ihq₁ ihq₂ => by rw [mul_add x q₁ q₂]; apply AddSubgroup.add_mem _ ihq₁ ihq₂) - fun z hz => by - have f : x * -z = -(x * z) := by simp - rw [f]; apply AddSubgroup.neg_mem _ hz, - fun h => - AddSubgroup.closure_induction h - (fun _ hx => - Subsemigroup.closure_induction hx (fun _ hx => subset_closure hx) fun _ _ hx hy => - mul_mem hx hy) - (zero_mem _) (fun _ _ hx hy => add_mem hx hy) fun _ hx => neg_mem hx⟩ + ⟨fun h => by + induction h using closure_induction with + | mem _ hx => exact AddSubgroup.subset_closure (Subsemigroup.subset_closure hx) + | zero => exact zero_mem _ + | add _ _ _ _ hx hy => exact add_mem hx hy + | neg x _ hx => exact neg_mem hx + | mul _ _ _hx _hy hx hy => + clear _hx _hy + induction hx, hy using AddSubgroup.closure_induction₂ with + | mem _ _ hx hy => exact AddSubgroup.subset_closure (mul_mem hx hy) + | one_left => simpa using zero_mem _ + | one_right => simpa using zero_mem _ + | mul_left _ _ _ _ _ _ h₁ h₂ => simpa [add_mul] using add_mem h₁ h₂ + | mul_right _ _ _ _ _ _ h₁ h₂ => simpa [mul_add] using add_mem h₁ h₂ + | inv_left _ _ _ _ h => simpa [neg_mul] using neg_mem h + | inv_right _ _ _ _ h => simpa [mul_neg] using neg_mem h, + fun h => by + induction h using AddSubgroup.closure_induction with + | mem _ hx => induction hx using Subsemigroup.closure_induction with + | mem _ h => exact subset_closure h + | mul _ _ _ _ h₁ h₂ => exact mul_mem h₁ h₂ + | one => exact zero_mem _ + | mul _ _ _ _ h₁ h₂ => exact add_mem h₁ h₂ + | inv _ _ h => exact neg_mem h⟩ /-- If all elements of `s : Set A` commute pairwise, then `closure s` is a commutative ring. -/ def closureNonUnitalCommRingOfComm {R : Type u} [NonUnitalRing R] {s : Set R} (hcomm : ∀ a ∈ s, ∀ b ∈ s, a * b = b * a) : NonUnitalCommRing (closure s) := { (closure s).toNonUnitalRing with - mul_comm := fun x y => by + mul_comm := fun ⟨x, hx⟩ ⟨y, hy⟩ => by ext - simp only [NonUnitalSubring.val_mul] - refine - closure_induction₂ x.prop y.prop hcomm - (fun x => by simp only [mul_zero, zero_mul]) - (fun x => by simp only [mul_zero, zero_mul]) - (fun x y hxy => by simp only [mul_neg, neg_mul, hxy]) - (fun x y hxy => by simp only [mul_neg, neg_mul, hxy]) - (fun x₁ x₂ y h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂]) - (fun x₁ x₂ y h₁ h₂ => by simp only [add_mul, mul_add, h₁, h₂]) - (fun x₁ x₂ y h₁ h₂ => by rw [← mul_assoc, ← h₁, mul_assoc x₁ y x₂, ← h₂, mul_assoc]) - fun x₁ x₂ y h₁ h₂ => by rw [← mul_assoc, h₁, mul_assoc, h₂, ← mul_assoc] } + simp only [MulMemClass.mk_mul_mk] + induction hx, hy using closure_induction₂ with + | mem_mem x y hx hy => exact hcomm x hx y hy + | zero_left x _ => exact Commute.zero_left x + | zero_right x _ => exact Commute.zero_right x + | mul_left _ _ _ _ _ _ h₁ h₂ => exact Commute.mul_left h₁ h₂ + | mul_right _ _ _ _ _ _ h₁ h₂ => exact Commute.mul_right h₁ h₂ + | add_left _ _ _ _ _ _ h₁ h₂ => exact Commute.add_left h₁ h₂ + | add_right _ _ _ _ _ _ h₁ h₂ => exact Commute.add_right h₁ h₂ + | neg_left _ _ _ _ h => exact Commute.neg_left h + | neg_right _ _ _ _ h => exact Commute.neg_right h } variable (R) diff --git a/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean b/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean index 891e01b70140c6..c2104c2b98ebbd 100644 --- a/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean +++ b/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean @@ -621,21 +621,38 @@ theorem closure_addSubmonoid_closure {s : Set R} : of `s`, and is preserved under addition and multiplication, then `p` holds for all elements of the closure of `s`. -/ @[elab_as_elim] -theorem closure_induction {s : Set R} {p : R → Prop} {x} (h : x ∈ closure s) (mem : ∀ x ∈ s, p x) - (zero : p 0) (add : ∀ x y, p x → p y → p (x + y)) (mul : ∀ x y, p x → p y → p (x * y)) : p x := - (@closure_le _ _ _ ⟨⟨⟨p, fun {a b} => add a b⟩, zero⟩, fun {a b} => mul a b⟩).2 mem h +theorem closure_induction {s : Set R} {p : (x : R) → x ∈ closure s → Prop} + (mem : ∀ (x) (hx : x ∈ s), p x (subset_closure hx)) (zero : p 0 (zero_mem _)) + (add : ∀ x y hx hy, p x hx → p y hy → p (x + y) (add_mem hx hy)) + (mul : ∀ x y hx hy, p x hx → p y hy → p (x * y) (mul_mem hx hy)) + {x} (hx : x ∈ closure s) : p x hx := + let K : NonUnitalSubsemiring R := + { carrier := { x | ∃ hx, p x hx } + mul_mem' := fun ⟨_, hpx⟩ ⟨_, hpy⟩ ↦ ⟨_, mul _ _ _ _ hpx hpy⟩ + add_mem' := fun ⟨_, hpx⟩ ⟨_, hpy⟩ ↦ ⟨_, add _ _ _ _ hpx hpy⟩ + zero_mem' := ⟨_, zero⟩ } + closure_le (t := K) |>.mpr (fun y hy ↦ ⟨subset_closure hy, mem y hy⟩) hx |>.elim fun _ ↦ id /-- An induction principle for closure membership for predicates with two arguments. -/ @[elab_as_elim] -theorem closure_induction₂ {s : Set R} {p : R → R → Prop} {x} {y : R} (hx : x ∈ closure s) - (hy : y ∈ closure s) (Hs : ∀ x ∈ s, ∀ y ∈ s, p x y) (H0_left : ∀ x, p 0 x) - (H0_right : ∀ x, p x 0) (Hadd_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ + x₂) y) - (Hadd_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ + y₂)) - (Hmul_left : ∀ x₁ x₂ y, p x₁ y → p x₂ y → p (x₁ * x₂) y) - (Hmul_right : ∀ x y₁ y₂, p x y₁ → p x y₂ → p x (y₁ * y₂)) : p x y := - closure_induction hx - (fun x₁ x₁s => closure_induction hy (Hs x₁ x₁s) (H0_right x₁) (Hadd_right x₁) (Hmul_right x₁)) - (H0_left y) (fun z z' => Hadd_left z z' y) fun z z' => Hmul_left z z' y +theorem closure_induction₂ {s : Set R} {p : (x y : R) → x ∈ closure s → y ∈ closure s → Prop} + (mem_mem : ∀ (x) (hx : x ∈ s) (y) (hy : y ∈ s), p x y (subset_closure hx) (subset_closure hy)) + (zero_left : ∀ x hx, p 0 x (zero_mem _) hx) (zero_right : ∀ x hx, p x 0 hx (zero_mem _)) + (add_left : ∀ x y z hx hy hz, p x z hx hz → p y z hy hz → p (x + y) z (add_mem hx hy) hz) + (add_right : ∀ x y z hx hy hz, p x y hx hy → p x z hx hz → p x (y + z) hx (add_mem hy hz)) + (mul_left : ∀ x y z hx hy hz, p x z hx hz → p y z hy hz → p (x * y) z (mul_mem hx hy) hz) + (mul_right : ∀ x y z hx hy hz, p x y hx hy → p x z hx hz → p x (y * z) hx (mul_mem hy hz)) + {x y : R} (hx : x ∈ closure s) (hy : y ∈ closure s) : + p x y hx hy := by + induction hy using closure_induction with + | mem z hz => induction hx using closure_induction with + | mem _ h => exact mem_mem _ h _ hz + | zero => exact zero_left _ _ + | mul _ _ _ _ h₁ h₂ => exact mul_left _ _ _ _ _ _ h₁ h₂ + | add _ _ _ _ h₁ h₂ => exact add_left _ _ _ _ _ _ h₁ h₂ + | zero => exact zero_right x hx + | mul _ _ _ _ h₁ h₂ => exact mul_right _ _ _ _ _ _ h₁ h₂ + | add _ _ _ _ h₁ h₂ => exact add_right _ _ _ _ _ _ h₁ h₂ variable (R) diff --git a/Mathlib/RingTheory/Polynomial/Basic.lean b/Mathlib/RingTheory/Polynomial/Basic.lean index 2c47e070c61a3e..16082eba5ec132 100644 --- a/Mathlib/RingTheory/Polynomial/Basic.lean +++ b/Mathlib/RingTheory/Polynomial/Basic.lean @@ -581,7 +581,7 @@ theorem mem_map_C_iff {I : Ideal R} {f : R[X]} : f ∈ (Ideal.map (C : R →+* R[X]) I : Ideal R[X]) ↔ ∀ n : ℕ, f.coeff n ∈ I := by constructor · intro hf - apply @Submodule.span_induction _ _ _ _ _ f _ _ hf + refine Submodule.span_induction ?_ ?_ ?_ ?_ hf · intro f hf n cases' (Set.mem_image _ _ _).mp hf with x hx rw [← hx.right, coeff_C] @@ -589,8 +589,8 @@ theorem mem_map_C_iff {I : Ideal R} {f : R[X]} : · simpa [h] using hx.left · 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 => ?_ + · exact fun f g _ _ hf hg n => by simp [I.add_mem (hf n) (hg n)] + · refine fun 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 @@ -920,8 +920,8 @@ protected theorem Polynomial.isNoetherianRing [inst : IsNoetherianRing R] : IsNo this ⟨HN ▸ I.leadingCoeffNth_mono (le_of_lt h), fun H => hxm (H hx)⟩ have hs2 : ∀ {x}, x ∈ I.degreeLE N → x ∈ Ideal.span (↑s : Set R[X]) := hs ▸ fun hx => - Submodule.span_induction hx (fun _ hx => Ideal.subset_span hx) (Ideal.zero_mem _) - (fun _ _ => Ideal.add_mem _) fun c f hf => f.C_mul' c ▸ Ideal.mul_mem_left _ _ hf + Submodule.span_induction (hx := hx) (fun _ hx => Ideal.subset_span hx) (Ideal.zero_mem _) + (fun _ _ _ _ => Ideal.add_mem _) fun c f _ hf => f.C_mul' c ▸ Ideal.mul_mem_left _ _ hf ⟨s, le_antisymm (Ideal.span_le.2 fun x hx => have : x ∈ I.degreeLE N := hs ▸ Submodule.subset_span hx this.2) <| by @@ -1183,7 +1183,7 @@ theorem mem_map_C_iff {I : Ideal R} {f : MvPolynomial σ R} : classical constructor · intro hf - apply @Submodule.span_induction _ _ _ _ Semiring.toModule f _ _ hf + refine Submodule.span_induction ?_ ?_ ?_ ?_ hf · intro f hf n cases' (Set.mem_image _ _ _).mp hf with x hx rw [← hx.right, coeff_C] @@ -1191,8 +1191,8 @@ theorem mem_map_C_iff {I : Ideal R} {f : MvPolynomial σ R} : · simpa [h] using hx.left · 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 => ?_ + · exact fun f g _ _ hf hg n => by simp [I.add_mem (hf n) (hg n)] + · refine fun 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/RingTheory/Polynomial/Bernstein.lean b/Mathlib/RingTheory/Polynomial/Bernstein.lean index 8cae9a4f38a0d8..640f8b722b5e60 100644 --- a/Mathlib/RingTheory/Polynomial/Bernstein.lean +++ b/Mathlib/RingTheory/Polynomial/Bernstein.lean @@ -246,13 +246,13 @@ theorem linearIndependent_aux (n k : ℕ) (h : k ≤ n + 1) : suffices (Polynomial.derivative^[n - k] p).eval 1 = 0 by rw [this] exact (iterate_derivative_at_1_ne_zero ℚ n k h).symm - refine span_induction m ?_ ?_ ?_ ?_ + refine span_induction ?_ ?_ ?_ ?_ m · simp only [Set.mem_range, forall_exists_index, forall_apply_eq_imp_iff] rintro ⟨a, w⟩; simp only [Fin.val_mk] rw [iterate_derivative_at_1_eq_zero_of_lt ℚ n ((tsub_lt_tsub_iff_left_of_le h).mpr w)] · simp - · intro x y hx hy; simp [hx, hy] - · intro a x h; simp [h] + · intro x y _ _ hx hy; simp [hx, hy] + · intro a x _ h; simp [h] /-- The Bernstein polynomials are linearly independent. diff --git a/Mathlib/RingTheory/TwoSidedIdeal/Operations.lean b/Mathlib/RingTheory/TwoSidedIdeal/Operations.lean index 78ccd01d0a2170..85fa3d54475595 100644 --- a/Mathlib/RingTheory/TwoSidedIdeal/Operations.lean +++ b/Mathlib/RingTheory/TwoSidedIdeal/Operations.lean @@ -141,10 +141,10 @@ lemma mem_span_iff_mem_addSubgroup_closure_absorbing {s : Set R} induction principle for `AddSubgroup`, we must also have `z ∈ J`. -/ case mem_ideal_of_subset => simp only [I, SetLike.mem_coe, mem_mk'] at hz - induction hz using closure_induction' with + induction hz using closure_induction with | mem x hx => exact hJ hx | one => exact zero_mem _ - | mul x _ y _ hx hy => exact J.add_mem hx hy + | mul x y _ _ hx hy => exact J.add_mem hx hy | inv x _ hx => exact J.neg_mem hx open Pointwise Set diff --git a/Mathlib/Topology/Algebra/StarSubalgebra.lean b/Mathlib/Topology/Algebra/StarSubalgebra.lean index 0703fc47530132..a8dd137d03c23c 100644 --- a/Mathlib/Topology/Algebra/StarSubalgebra.lean +++ b/Mathlib/Topology/Algebra/StarSubalgebra.lean @@ -229,27 +229,24 @@ theorem induction_on {x y : A} P y hy := by apply closure (adjoin R {x} : Set A) subset_closure (fun y hy ↦ ?_) y hy rw [SetLike.mem_coe, ← mem_toSubalgebra, adjoin_toSubalgebra] at hy - induction hy using Algebra.adjoin_induction'' with + induction hy using Algebra.adjoin_induction with | mem u hu => obtain ((rfl : u = x) | (hu : star u = x)) := by simpa using hu · exact self · simp_rw [← hu, star_star] at star_self exact star_self | algebraMap r => exact algebraMap r - | add u hu_mem v hv_mem hu hv => + | add u v hu_mem hv_mem hu hv => exact add u (subset_closure hu_mem) v (subset_closure hv_mem) (hu hu_mem) (hv hv_mem) - | mul u hu_mem v hv_mem hu hv => + | 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) theorem starAlgHomClass_ext [T2Space B] {F : Type*} {a : A} [FunLike F (elementalStarAlgebra R a) B] [AlgHomClass F R _ B] [StarHomClass F _ B] {φ ψ : F} (hφ : Continuous φ) (hψ : Continuous ψ) (h : φ ⟨a, self_mem R a⟩ = ψ ⟨a, self_mem R a⟩) : φ = ψ := by - -- Note: help with unfolding `elementalStarAlgebra` - have : StarHomClass F (↥(topologicalClosure (adjoin R {a}))) B := - inferInstanceAs (StarHomClass F (elementalStarAlgebra R a) B) refine StarAlgHomClass.ext_topologicalClosure hφ hψ fun x => ?_ - refine adjoin_induction' x ?_ ?_ ?_ ?_ ?_ + refine adjoin_induction_subtype x ?_ ?_ ?_ ?_ ?_ exacts [fun y hy => by simpa only [Set.mem_singleton_iff.mp hy] using h, fun r => by simp only [AlgHomClass.commutes], fun x y hx hy => by simp only [map_add, hx, hy], fun x y hx hy => by simp only [map_mul, hx, hy], fun x hx => by simp only [map_star, hx]] diff --git a/Mathlib/Topology/ContinuousMap/StarOrdered.lean b/Mathlib/Topology/ContinuousMap/StarOrdered.lean index b894be96cbeb13..3b07ebe1a70871 100644 --- a/Mathlib/Topology/ContinuousMap/StarOrdered.lean +++ b/Mathlib/Topology/ContinuousMap/StarOrdered.lean @@ -92,12 +92,12 @@ instance instStarOrderedRing {R : Type*} refine ⟨star s' * s' + p', ?_, by rw [add_assoc]⟩ exact add_mem (AddSubmonoid.subset_closure ⟨s', rfl⟩) hp'_mem · rintro ⟨p, hp, rfl⟩ - induction hp using AddSubmonoid.closure_induction' generalizing f with + induction hp using AddSubmonoid.closure_induction generalizing f with | mem s s_mem => obtain ⟨s, rfl⟩ := s_mem exact fun x ↦ le_add_of_nonneg_right (star_mul_self_nonneg (s x)) | one => simp - | mul g₁ _ g₂ _ h₁ h₂ => calc + | mul g₁ g₂ _ _ h₁ h₂ => calc f ≤ f + g₁ := h₁ f _ ≤ (f + g₁) + g₂ := h₂ (f + g₁) _ = f + (g₁ + g₂) := add_assoc _ _ _ diff --git a/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean b/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean index 643b6ad6595d6a..0bb2fd98c0bd21 100644 --- a/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean +++ b/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean @@ -486,13 +486,13 @@ lemma nonUnitalStarAlgebraAdjoin_id_subset_ker_evalStarAlgHom {s : Set 𝕜} (h0 (adjoin 𝕜 {restrict s (.id 𝕜)} : Set C(s, 𝕜)) ⊆ RingHom.ker (evalStarAlgHom 𝕜 𝕜 (⟨0, h0⟩ : s)) := by intro f hf - induction hf using adjoin_induction' with + induction hf using adjoin_induction with | mem f hf => obtain rfl := Set.mem_singleton_iff.mp hf rfl - | add f _ g _ hf hg => exact add_mem hf hg + | add f g _ _ hf hg => exact add_mem hf hg | zero => exact zero_mem _ - | mul f _ g _ _ hg => exact Ideal.mul_mem_left _ f hg + | mul f g _ _ _ hg => exact Ideal.mul_mem_left _ f hg | smul r f _ hf => rw [SetLike.mem_coe, RingHom.mem_ker] at hf ⊢ rw [map_smul, hf, smul_zero] From 0299ddda3e48f4fe1b7c6fbfa640abc40d6ba114 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 09:33:56 +1100 Subject: [PATCH 168/425] lint / test --- Mathlib/Data/List/Join.lean | 6 +++--- test/LibrarySearch/basic.lean | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/Data/List/Join.lean b/Mathlib/Data/List/Join.lean index 0db25d1afe7e5b..8c6ed6907be8b1 100644 --- a/Mathlib/Data/List/Join.lean +++ b/Mathlib/Data/List/Join.lean @@ -19,8 +19,6 @@ variable {α β : Type*} namespace List -@[deprecated (since := "2024-02-25")] alias join_filter_isEmpty_eq_false := join_filter_not_isEmpty - /-- See `List.length_flatten` for the corresponding statement using `List.sum`. -/ lemma length_flatten' (L : List (List α)) : length (flatten L) = Nat.sum (map length L) := by induction L <;> [rfl; simp only [*, flatten, map, Nat.sum_cons, length_append]] @@ -134,6 +132,8 @@ theorem append_flatten_map_append (L : List (List α)) (x : List α) : @[deprecated (since := "2024-10-15")] alias append_join_map_append := append_flatten_map_append -@[deprecated (since := "2024-08-15")] alias sublist_join := sublist_join_of_mem +@[deprecated (since := "2024-08-15")] theorem sublist_join {l} {L : List (List α)} (h : l ∈ L) : + l <+ L.flatten := + sublist_flatten_of_mem h end List diff --git a/test/LibrarySearch/basic.lean b/test/LibrarySearch/basic.lean index ba5f6e37241720..72ef6d57a743f2 100644 --- a/test/LibrarySearch/basic.lean +++ b/test/LibrarySearch/basic.lean @@ -169,7 +169,7 @@ axiom F (a b : ℕ) : f a ≤ f b ↔ a ≤ b #guard_msgs in example (a b : ℕ) (h : a ≤ b) : f a ≤ f b := by apply? -/-- info: Try this: exact L.join -/ +/-- info: Try this: exact L.flatten -/ #guard_msgs in example (L _M : List (List ℕ)) : List ℕ := by apply? using L From 7ca047f4fa340d89a8f535c148e6b27a94451c74 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Tue, 15 Oct 2024 23:21:30 +0000 Subject: [PATCH 169/425] chore: move `Init.Logic` and its remaining dependencies to `Deprecated` (#17771) The results in this file have been deprecated for a while and none seem to be used in Mathlib except for other deprecated results that aren't used either. So let's move everything to the `Deprecated` folder in order to empty out the `Init` folder. --- Mathlib.lean | 3 ++- Mathlib/{Init => Deprecated}/Logic.lean | 8 +++---- Mathlib/Deprecated/MinMax.lean | 28 +++++++++++++++++++++++++ Mathlib/Order/MinMax.lean | 15 ------------- scripts/noshake.json | 1 + 5 files changed, 34 insertions(+), 21 deletions(-) rename Mathlib/{Init => Deprecated}/Logic.lean (97%) create mode 100644 Mathlib/Deprecated/MinMax.lean diff --git a/Mathlib.lean b/Mathlib.lean index 26c0f12b2cf585..cb70468444f2ac 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2657,6 +2657,8 @@ import Mathlib.Deprecated.Combinator import Mathlib.Deprecated.Equiv import Mathlib.Deprecated.Group import Mathlib.Deprecated.HashMap +import Mathlib.Deprecated.Logic +import Mathlib.Deprecated.MinMax import Mathlib.Deprecated.NatLemmas import Mathlib.Deprecated.RelClasses import Mathlib.Deprecated.Ring @@ -2927,7 +2929,6 @@ import Mathlib.GroupTheory.Torsion import Mathlib.GroupTheory.Transfer import Mathlib.InformationTheory.Hamming import Mathlib.Init -import Mathlib.Init.Logic import Mathlib.Lean.CoreM import Mathlib.Lean.Elab.Tactic.Basic import Mathlib.Lean.Elab.Term diff --git a/Mathlib/Init/Logic.lean b/Mathlib/Deprecated/Logic.lean similarity index 97% rename from Mathlib/Init/Logic.lean rename to Mathlib/Deprecated/Logic.lean index 5fae3e24758092..1d6275f397fbfc 100644 --- a/Mathlib/Init/Logic.lean +++ b/Mathlib/Deprecated/Logic.lean @@ -6,12 +6,10 @@ Authors: Leonardo de Moura, Jeremy Avigad, Floris van Doorn import Batteries.Tactic.Alias /-! -# Note about `Mathlib/Init/` -The files in `Mathlib/Init` are leftovers from the port from Mathlib3. -(They contain content moved from lean3 itself that Mathlib needed but was not moved to lean4.) +# Note about deprecated files -We intend to move all the content of these files out into the main `Mathlib` directory structure. -Contributions assisting with this are appreciated. +This file is deprecated, and is no longer imported by anything in mathlib other than other +deprecated files, and test files. You should not need to import it. -/ set_option linter.deprecated false diff --git a/Mathlib/Deprecated/MinMax.lean b/Mathlib/Deprecated/MinMax.lean new file mode 100644 index 00000000000000..1263096222aef3 --- /dev/null +++ b/Mathlib/Deprecated/MinMax.lean @@ -0,0 +1,28 @@ +/- +Copyright (c) 2017 Mario Carneiro. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Mario Carneiro +-/ +import Mathlib.Deprecated.Logic +import Mathlib.Order.MinMax +/-! +# Note about deprecated files + +This file is deprecated, and is no longer imported by anything in mathlib other than other +deprecated files, and test files. You should not need to import it. +-/ + +universe u + +variable {α : Type u} [LinearOrder α] + +set_option linter.deprecated false + +@[deprecated instCommutativeMax (since := "2024-09-12")] +theorem max_commutative : Commutative (α := α) max := max_comm +@[deprecated instAssociativeMax (since := "2024-09-12")] +theorem max_associative : Associative (α := α) max := max_assoc +@[deprecated instCommutativeMin (since := "2024-09-12")] +theorem min_commutative : Commutative (α := α) min := min_comm +@[deprecated instAssociativeMin (since := "2024-09-12")] +theorem min_associative : Associative (α := α) min := min_assoc diff --git a/Mathlib/Order/MinMax.lean b/Mathlib/Order/MinMax.lean index f815d61f448166..d43fc960d2020c 100644 --- a/Mathlib/Order/MinMax.lean +++ b/Mathlib/Order/MinMax.lean @@ -3,7 +3,6 @@ Copyright (c) 2017 Mario Carneiro. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Mario Carneiro -/ -import Mathlib.Init.Logic import Mathlib.Logic.OpClass import Mathlib.Order.Lattice @@ -244,18 +243,4 @@ instance instAssociativeMin : Std.Associative (α := α) min where assoc := min_ theorem max_left_commutative : LeftCommutative (max : α → α → α) := ⟨max_left_comm⟩ theorem min_left_commutative : LeftCommutative (min : α → α → α) := ⟨min_left_comm⟩ -section deprecated -set_option linter.deprecated false - -@[deprecated instCommutativeMax (since := "2024-09-12")] -theorem max_commutative : Commutative (α := α) max := max_comm -@[deprecated instAssociativeMax (since := "2024-09-12")] -theorem max_associative : Associative (α := α) max := max_assoc -@[deprecated instCommutativeMin (since := "2024-09-12")] -theorem min_commutative : Commutative (α := α) min := min_comm -@[deprecated instAssociativeMin (since := "2024-09-12")] -theorem min_associative : Associative (α := α) min := min_assoc - -end deprecated - end diff --git a/scripts/noshake.json b/scripts/noshake.json index 44d4594c37546d..681e7f87ee2b5b 100644 --- a/scripts/noshake.json +++ b/scripts/noshake.json @@ -351,6 +351,7 @@ "Mathlib.Geometry.Manifold.PoincareConjecture": ["Mathlib.AlgebraicTopology.FundamentalGroupoid.SimplyConnected", "Mathlib.Util.Superscript"], + "Mathlib.Deprecated.MinMax": ["Mathlib.Order.MinMax"], "Mathlib.Data.Vector.Basic": ["Mathlib.Control.Applicative"], "Mathlib.Data.Set.Image": ["Batteries.Tactic.Congr"], "Mathlib.Data.Seq.Parallel": ["Mathlib.Init.Data.Prod"], From c63a0ac5dcbcea2165fdbbbe8be00cdf3b2a731c Mon Sep 17 00:00:00 2001 From: Robin Carlier <57142648+robin-carlier@users.noreply.github.com> Date: Tue, 15 Oct 2024 23:57:41 +0000 Subject: [PATCH 170/425] chore(CategoryTheory/ChosenFiniteProducts): port some simp lemmas from CategoryTheory/Limits/Shapes/BinaryProducts (#17733) --- .../CategoryTheory/ChosenFiniteProducts.lean | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Mathlib/CategoryTheory/ChosenFiniteProducts.lean b/Mathlib/CategoryTheory/ChosenFiniteProducts.lean index a41ef978ef9887..03e72e08d751c4 100644 --- a/Mathlib/CategoryTheory/ChosenFiniteProducts.lean +++ b/Mathlib/CategoryTheory/ChosenFiniteProducts.lean @@ -118,6 +118,15 @@ lemma hom_ext {T X Y : C} (f g : T ⟶ X ⊗ Y) f = g := (product X Y).isLimit.hom_ext fun ⟨j⟩ => j.recOn h_fst h_snd +-- Similarly to `CategoryTheory.Limits.prod.comp_lift`, we do not make the `assoc` version a simp +-- lemma +@[reassoc, simp] +lemma comp_lift {V W X Y : C} (f : V ⟶ W) (g : W ⟶ X) (h : W ⟶ Y) : + f ≫ lift g h = lift (f ≫ g) (f ≫ h) := by ext <;> simp + +@[simp] +lemma lift_fst_snd {X Y : C} : lift (fst X Y) (snd X Y) = 𝟙 (X ⊗ Y) := by ext <;> simp + @[reassoc (attr := simp)] lemma tensorHom_fst {X₁ X₂ Y₁ Y₂ : C} (f : X₁ ⟶ X₂) (g : Y₁ ⟶ Y₂) : (f ⊗ g) ≫ fst _ _ = fst _ _ ≫ f := lift_fst _ _ @@ -126,6 +135,14 @@ lemma tensorHom_fst {X₁ X₂ Y₁ Y₂ : C} (f : X₁ ⟶ X₂) (g : Y₁ ⟶ lemma tensorHom_snd {X₁ X₂ Y₁ Y₂ : C} (f : X₁ ⟶ X₂) (g : Y₁ ⟶ Y₂) : (f ⊗ g) ≫ snd _ _ = snd _ _ ≫ g := lift_snd _ _ +@[reassoc (attr := simp)] +lemma lift_map {V W X Y Z : C} (f : V ⟶ W) (g : V ⟶ X) (h : W ⟶ Y) (k : X ⟶ Z) : + lift f g ≫ (h ⊗ k) = lift (f ≫ h) (g ≫ k) := by ext <;> simp + +@[simp] +lemma lift_fst_comp_snd_comp {W X Y Z : C} (g : W ⟶ X) (g' : Y ⟶ Z) : + lift (fst _ _ ≫ g) (snd _ _ ≫ g') = g ⊗ g' := by ext <;> simp + @[reassoc (attr := simp)] lemma whiskerLeft_fst (X : C) {Y₁ Y₂ : C} (g : Y₁ ⟶ Y₂) : (X ◁ g) ≫ fst _ _ = fst _ _ := From 2ae1eb8bb18eb00a62dae319aaef09bc2ae5ed8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Wed, 16 Oct 2024 00:08:45 +0000 Subject: [PATCH 171/425] feat(SetTheory/Cardinal/Aleph): add notation for `aleph` and `beth` (#17671) --- Mathlib/SetTheory/Cardinal/Aleph.lean | 73 ++++++++++++++--------- Mathlib/SetTheory/Cardinal/Continuum.lean | 8 +-- 2 files changed, 49 insertions(+), 32 deletions(-) diff --git a/Mathlib/SetTheory/Cardinal/Aleph.lean b/Mathlib/SetTheory/Cardinal/Aleph.lean index cfb20ec7268ad7..c1fc5cb463cb7e 100644 --- a/Mathlib/SetTheory/Cardinal/Aleph.lean +++ b/Mathlib/SetTheory/Cardinal/Aleph.lean @@ -21,6 +21,14 @@ import Mathlib.SetTheory.Ordinal.Arithmetic * The function `Cardinal.beth` enumerates the Beth cardinals. `beth 0 = ℵ₀`, `beth (succ o) = 2 ^ beth o`, and for a limit ordinal `o`, `beth o` is the supremum of `beth a` for `a < o`. + +## Notation + +The following notation is scoped to the `Cardinal` namespace. + +- `ℵ_ o` is notation for `aleph o`. `ℵ₁` is notation for `ℵ_ 1`. +- `ℶ_ o` is notation for `beth o`. The value `ℶ_ 1` equals the continuum `𝔠`, which is defined in + `Mathlib.SetTheory.Cardinal.Continuum`. -/ assert_not_exists Module @@ -205,30 +213,36 @@ For a version including finite cardinals, see `Cardinal.aleph'`. -/ def aleph : Ordinal ↪o Cardinal := (OrderEmbedding.addLeft ω).trans aleph'.toOrderEmbedding -theorem aleph_eq_aleph' (o : Ordinal) : aleph o = aleph' (ω + o) := +@[inherit_doc] +scoped notation "ℵ_ " => aleph + +/-- `ℵ₁` is the first uncountable ordinal. -/ +scoped notation "ℵ₁" => ℵ_ 1 + +theorem aleph_eq_aleph' (o : Ordinal) : ℵ_ o = aleph' (ω + o) := rfl -theorem aleph_lt {o₁ o₂ : Ordinal} : aleph o₁ < aleph o₂ ↔ o₁ < o₂ := +theorem aleph_lt {o₁ o₂ : Ordinal} : ℵ_ o₁ < ℵ_ o₂ ↔ o₁ < o₂ := aleph.lt_iff_lt -theorem aleph_le {o₁ o₂ : Ordinal} : aleph o₁ ≤ aleph o₂ ↔ o₁ ≤ o₂ := +theorem aleph_le {o₁ o₂ : Ordinal} : ℵ_ o₁ ≤ ℵ_ o₂ ↔ o₁ ≤ o₂ := aleph.le_iff_le -theorem aleph_max (o₁ o₂ : Ordinal) : aleph (max o₁ o₂) = max (aleph o₁) (aleph o₂) := +theorem aleph_max (o₁ o₂ : Ordinal) : ℵ_ (max o₁ o₂) = max (ℵ_ o₁) (ℵ_ o₂) := aleph.monotone.map_max @[deprecated aleph_max (since := "2024-08-28")] -theorem max_aleph_eq (o₁ o₂ : Ordinal) : max (aleph o₁) (aleph o₂) = aleph (max o₁ o₂) := +theorem max_aleph_eq (o₁ o₂ : Ordinal) : max (ℵ_ o₁) (ℵ_ o₂) = ℵ_ (max o₁ o₂) := (aleph_max o₁ o₂).symm @[simp] -theorem aleph_succ (o : Ordinal) : aleph (succ o) = succ (aleph o) := by +theorem aleph_succ (o : Ordinal) : ℵ_ (succ o) = succ (ℵ_ o) := by rw [aleph_eq_aleph', add_succ, aleph'_succ, aleph_eq_aleph'] @[simp] -theorem aleph_zero : aleph 0 = ℵ₀ := by rw [aleph_eq_aleph', add_zero, aleph'_omega0] +theorem aleph_zero : ℵ_ 0 = ℵ₀ := by rw [aleph_eq_aleph', add_zero, aleph'_omega0] -theorem aleph_limit {o : Ordinal} (ho : o.IsLimit) : aleph o = ⨆ a : Iio o, aleph a := by +theorem aleph_limit {o : Ordinal} (ho : o.IsLimit) : ℵ_ o = ⨆ a : Iio o, ℵ_ a := by apply le_antisymm _ (ciSup_le' _) · rw [aleph_eq_aleph', aleph'_limit (ho.add _)] refine ciSup_mono' (bddAbove_of_small _) ?_ @@ -252,21 +266,21 @@ theorem aleph_pos (o : Ordinal) : 0 < aleph o := aleph0_pos.trans_le (aleph0_le_aleph o) @[simp] -theorem aleph_toNat (o : Ordinal) : toNat (aleph o) = 0 := +theorem aleph_toNat (o : Ordinal) : toNat (ℵ_ o) = 0 := toNat_apply_of_aleph0_le <| aleph0_le_aleph o @[simp] -theorem aleph_toPartENat (o : Ordinal) : toPartENat (aleph o) = ⊤ := +theorem aleph_toPartENat (o : Ordinal) : toPartENat (ℵ_ o) = ⊤ := toPartENat_apply_of_aleph0_le <| aleph0_le_aleph o -instance nonempty_toType_aleph (o : Ordinal) : Nonempty (aleph o).ord.toType := by +instance nonempty_toType_aleph (o : Ordinal) : Nonempty (ℵ_ o).ord.toType := by rw [toType_nonempty_iff_ne_zero, ← ord_zero] exact fun h => (ord_injective h).not_gt (aleph_pos o) -theorem ord_aleph_isLimit (o : Ordinal) : (aleph o).ord.IsLimit := +theorem ord_aleph_isLimit (o : Ordinal) : (ℵ_ o).ord.IsLimit := ord_isLimit <| aleph0_le_aleph _ -instance (o : Ordinal) : NoMaxOrder (aleph o).ord.toType := +instance (o : Ordinal) : NoMaxOrder (ℵ_ o).ord.toType := toType_noMax_of_succ_lt (ord_aleph_isLimit o).2 theorem exists_aleph {c : Cardinal} : ℵ₀ ≤ c ↔ ∃ o, c = aleph o := @@ -283,13 +297,13 @@ theorem aleph'_isNormal : IsNormal (ord ∘ aleph') := theorem aleph_isNormal : IsNormal (ord ∘ aleph) := aleph'_isNormal.trans <| isNormal_add_right ω -theorem succ_aleph0 : succ ℵ₀ = aleph 1 := by rw [← aleph_zero, ← aleph_succ, Ordinal.succ_zero] +theorem succ_aleph0 : succ ℵ₀ = ℵ₁ := by rw [← aleph_zero, ← aleph_succ, Ordinal.succ_zero] -theorem aleph0_lt_aleph_one : ℵ₀ < aleph 1 := by +theorem aleph0_lt_aleph_one : ℵ₀ < ℵ₁ := by rw [← succ_aleph0] apply lt_succ -theorem countable_iff_lt_aleph_one {α : Type*} (s : Set α) : s.Countable ↔ #s < aleph 1 := by +theorem countable_iff_lt_aleph_one {α : Type*} (s : Set α) : s.Countable ↔ #s < ℵ₁ := by rw [← succ_aleph0, lt_succ_iff, le_aleph0_iff_set_countable] section deprecated @@ -321,7 +335,7 @@ theorem ord_card_unbounded' : Unbounded (· < ·) { b : Ordinal | b.card.ord = b @[deprecated (since := "2024-09-24")] theorem eq_aleph_of_eq_card_ord {o : Ordinal} (ho : o.card.ord = o) (ho' : ω ≤ o) : - ∃ a, (aleph a).ord = o := by + ∃ a, (ℵ_ a).ord = o := by cases' eq_aleph'_of_eq_card_ord ho with a ha use a - ω rwa [aleph_eq_aleph', Ordinal.add_sub_cancel_of_le] @@ -331,23 +345,26 @@ end deprecated /-! ### Beth cardinals -/ -/-- Beth numbers are defined so that `beth 0 = ℵ₀`, `beth (succ o) = 2 ^ (beth o)`, and when `o` is +/-- Beth numbers are defined so that `beth 0 = ℵ₀`, `beth (succ o) = 2 ^ beth o`, and when `o` is a limit ordinal, `beth o` is the supremum of `beth o'` for `o' < o`. Assuming the generalized continuum hypothesis, which is undecidable in ZFC, `beth o = aleph o` for every `o`. -/ def beth (o : Ordinal.{u}) : Cardinal.{u} := - limitRecOn o aleph0 (fun _ x => (2 : Cardinal) ^ x) fun a _ IH => ⨆ b : Iio a, IH b.1 b.2 + limitRecOn o ℵ₀ (fun _ x => 2 ^ x) fun a _ IH => ⨆ b : Iio a, IH b.1 b.2 + +@[inherit_doc] +scoped notation "ℶ_ " => beth @[simp] -theorem beth_zero : beth 0 = aleph0 := +theorem beth_zero : ℶ_ 0 = ℵ₀ := limitRecOn_zero _ _ _ @[simp] -theorem beth_succ (o : Ordinal) : beth (succ o) = 2 ^ beth o := +theorem beth_succ (o : Ordinal) : ℶ_ (succ o) = 2 ^ beth o := limitRecOn_succ _ _ _ _ -theorem beth_limit {o : Ordinal} : o.IsLimit → beth o = ⨆ a : Iio o, beth a := +theorem beth_limit {o : Ordinal} : o.IsLimit → ℶ_ o = ⨆ a : Iio o, ℶ_ a := limitRecOn_limit _ _ _ _ theorem beth_strictMono : StrictMono beth := by @@ -370,14 +387,14 @@ theorem beth_mono : Monotone beth := beth_strictMono.monotone @[simp] -theorem beth_lt {o₁ o₂ : Ordinal} : beth o₁ < beth o₂ ↔ o₁ < o₂ := +theorem beth_lt {o₁ o₂ : Ordinal} : ℶ_ o₁ < ℶ_ o₂ ↔ o₁ < o₂ := beth_strictMono.lt_iff_lt @[simp] -theorem beth_le {o₁ o₂ : Ordinal} : beth o₁ ≤ beth o₂ ↔ o₁ ≤ o₂ := +theorem beth_le {o₁ o₂ : Ordinal} : ℶ_ o₁ ≤ ℶ_ o₂ ↔ o₁ ≤ o₂ := beth_strictMono.le_iff_le -theorem aleph_le_beth (o : Ordinal) : aleph o ≤ beth o := by +theorem aleph_le_beth (o : Ordinal) : ℵ_ o ≤ ℶ_ o := by induction o using limitRecOn with | H₁ => simp | H₂ o h => @@ -387,13 +404,13 @@ theorem aleph_le_beth (o : Ordinal) : aleph o ≤ beth o := by rw [aleph_limit ho, beth_limit ho] exact ciSup_mono (bddAbove_of_small _) fun x => IH x.1 x.2 -theorem aleph0_le_beth (o : Ordinal) : ℵ₀ ≤ beth o := +theorem aleph0_le_beth (o : Ordinal) : ℵ₀ ≤ ℶ_ o := (aleph0_le_aleph o).trans <| aleph_le_beth o -theorem beth_pos (o : Ordinal) : 0 < beth o := +theorem beth_pos (o : Ordinal) : 0 < ℶ_ o := aleph0_pos.trans_le <| aleph0_le_beth o -theorem beth_ne_zero (o : Ordinal) : beth o ≠ 0 := +theorem beth_ne_zero (o : Ordinal) : ℶ_ o ≠ 0 := (beth_pos o).ne' theorem isNormal_beth : IsNormal (ord ∘ beth) := by diff --git a/Mathlib/SetTheory/Cardinal/Continuum.lean b/Mathlib/SetTheory/Cardinal/Continuum.lean index fa8694e0661e53..b05977809225dc 100644 --- a/Mathlib/SetTheory/Cardinal/Continuum.lean +++ b/Mathlib/SetTheory/Cardinal/Continuum.lean @@ -23,14 +23,14 @@ universe u v open Cardinal -/-- Cardinality of continuum. -/ +/-- Cardinality of the continuum. -/ def continuum : Cardinal.{u} := 2 ^ ℵ₀ scoped notation "𝔠" => Cardinal.continuum @[simp] -theorem two_power_aleph0 : 2 ^ aleph0.{u} = continuum.{u} := +theorem two_power_aleph0 : 2 ^ ℵ₀ = 𝔠 := rfl @[simp] @@ -65,7 +65,7 @@ theorem aleph0_le_continuum : ℵ₀ ≤ 𝔠 := aleph0_lt_continuum.le @[simp] -theorem beth_one : beth 1 = 𝔠 := by simpa using beth_succ 0 +theorem beth_one : ℶ_ 1 = 𝔠 := by simpa using beth_succ 0 theorem nat_lt_continuum (n : ℕ) : ↑n < 𝔠 := (nat_lt_aleph0 n).trans aleph0_lt_continuum @@ -78,7 +78,7 @@ theorem continuum_pos : 0 < 𝔠 := theorem continuum_ne_zero : 𝔠 ≠ 0 := continuum_pos.ne' -theorem aleph_one_le_continuum : aleph 1 ≤ 𝔠 := by +theorem aleph_one_le_continuum : ℵ₁ ≤ 𝔠 := by rw [← succ_aleph0] exact Order.succ_le_of_lt aleph0_lt_continuum From df631d9d3f786aa5dce9791a5005dd4aaa40a3c5 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 11:11:58 +1100 Subject: [PATCH 172/425] test --- test/RewriteSearch/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/RewriteSearch/Basic.lean b/test/RewriteSearch/Basic.lean index 8b701417188323..d6125c11d7d6b7 100644 --- a/test/RewriteSearch/Basic.lean +++ b/test/RewriteSearch/Basic.lean @@ -56,7 +56,7 @@ example {a b c : Int} : a + b = c + b + (a - c) := by /-- info: ["(", "[", "5", ",", "3", "]", ",", "4", "+", "(", "2", "*", "1", ")", ")"] -/ #guard_msgs in open Mathlib.Tactic.RewriteSearch in -#eval ("([5, 3], 4 + (2 * 1))".splitOn.map splitDelimiters).join +#eval ("([5, 3], 4 + (2 * 1))".splitOn.map splitDelimiters).flatten -- Function that always constructs `[0]`. Used in the following example. def makeSingleton : Nat → List Nat From ae07e34de6c0d150ecb0e6195b6e2fbac4bedfab Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 11:21:42 +1100 Subject: [PATCH 173/425] shake --- Mathlib/Data/List/Indexes.lean | 2 +- Mathlib/Data/Nat/Digits.lean | 1 - Mathlib/Data/Option/NAry.lean | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Mathlib/Data/List/Indexes.lean b/Mathlib/Data/List/Indexes.lean index 3d8da0f6ca7895..a1b935a65e0cc1 100644 --- a/Mathlib/Data/List/Indexes.lean +++ b/Mathlib/Data/List/Indexes.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Jannis Limperg -/ import Mathlib.Data.List.OfFn -import Mathlib.Data.List.Zip +import Mathlib.Data.List.Basic /-! # Lemmas about List.*Idx functions. diff --git a/Mathlib/Data/Nat/Digits.lean b/Mathlib/Data/Nat/Digits.lean index 23cd40d657cba6..2a0f7928876c97 100644 --- a/Mathlib/Data/Nat/Digits.lean +++ b/Mathlib/Data/Nat/Digits.lean @@ -8,7 +8,6 @@ import Mathlib.Algebra.BigOperators.Ring.List import Mathlib.Data.Int.ModEq import Mathlib.Data.Nat.Bits import Mathlib.Data.Nat.Log -import Mathlib.Data.List.Indexes import Mathlib.Data.List.Palindrome import Mathlib.Tactic.IntervalCases import Mathlib.Tactic.Linarith diff --git a/Mathlib/Data/Option/NAry.lean b/Mathlib/Data/Option/NAry.lean index 855ae63c32d0ac..08680cd5e870ef 100644 --- a/Mathlib/Data/Option/NAry.lean +++ b/Mathlib/Data/Option/NAry.lean @@ -3,8 +3,8 @@ 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.Logic.Function.Defs import Batteries.Tactic.Init +import Batteries.Logic /-! # Binary map of options From 3174fbee6f7dc53148bd08e523551ebe4972f5c1 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 11:22:36 +1100 Subject: [PATCH 174/425] fix shake --- Mathlib/Data/Option/NAry.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Data/Option/NAry.lean b/Mathlib/Data/Option/NAry.lean index 08680cd5e870ef..2b79c2496cf35f 100644 --- a/Mathlib/Data/Option/NAry.lean +++ b/Mathlib/Data/Option/NAry.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Yaël Dillies -/ import Batteries.Tactic.Init -import Batteries.Logic +import Mathlib.Logic.Function.Defs /-! # Binary map of options From 7ff7b1d1139c9e19dddcfd1fcf4e94713e40f7d7 Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Wed, 16 Oct 2024 00:37:54 +0000 Subject: [PATCH 175/425] Trigger CI for https://github.com/leanprover/lean4/pull/5720 --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 8f8f129413a594..8a9c020e31faa1 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "0ff2d7ddbdfba09d910317fda5103a826dfd9ccb", + "rev": "770554a6f5a9c7e1ffe666257dd4964068ca85af", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "lean-pr-testing-5720", From 36bb3d003e48d0b7aef637b5e35e36f2389310e1 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 00:54:40 +0000 Subject: [PATCH 176/425] fix: speedcenter robustness (#17794) --- scripts/bench/temci-config.run.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bench/temci-config.run.yml b/scripts/bench/temci-config.run.yml index 9fdeceaa83cda7..679eb6a0e6d8f9 100644 --- a/scripts/bench/temci-config.run.yml +++ b/scripts/bench/temci-config.run.yml @@ -7,7 +7,7 @@ rusage_properties: ['maxrss'] cmd: | # use build cache for proofwidgets, but not for anything else - bash -c 'set -eo pipefail; lake clean 1>&2 && LEAN_PATH=$(lean --print-libdir) lake build proofwidgets 1>&2 && rm .lake/packages/batteries/.lake/build/bin/runLinter 1>&2 && lake build --no-cache -v --lean ./scripts/bench/fake-root/bin/lean | ./scripts/bench/accumulate_profile.py | grep -v took' + bash -c 'set -eo pipefail; lake clean 1>&2 && LEAN_PATH=$(lean --print-libdir) lake build proofwidgets 1>&2 && rm -f .lake/packages/batteries/.lake/build/bin/runLinter 1>&2 && lake build --no-cache -v --lean ./scripts/bench/fake-root/bin/lean | ./scripts/bench/accumulate_profile.py | grep -v took' parse_output: true runs: 1 - attributes: From a003b0ef2191b8227f791b3c40cdec1c77ef7bb4 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 01:59:13 +0000 Subject: [PATCH 177/425] chore: bump Batteries (upstreamed DList) (#17791) --- Mathlib.lean | 2 -- Mathlib/Data/DList/Basic.lean | 38 -------------------- Mathlib/Data/DList/Defs.lean | 59 ------------------------------- Mathlib/Data/DList/Instances.lean | 2 +- Mathlib/Data/Seq/WSeq.lean | 2 +- lake-manifest.json | 2 +- 6 files changed, 3 insertions(+), 102 deletions(-) delete mode 100644 Mathlib/Data/DList/Basic.lean delete mode 100644 Mathlib/Data/DList/Defs.lean diff --git a/Mathlib.lean b/Mathlib.lean index cb70468444f2ac..87442538c13ed7 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2156,8 +2156,6 @@ import Mathlib.Data.DFinsupp.NeLocus import Mathlib.Data.DFinsupp.Notation import Mathlib.Data.DFinsupp.Order import Mathlib.Data.DFinsupp.WellFounded -import Mathlib.Data.DList.Basic -import Mathlib.Data.DList.Defs import Mathlib.Data.DList.Instances import Mathlib.Data.ENNReal.Basic import Mathlib.Data.ENNReal.Inv diff --git a/Mathlib/Data/DList/Basic.lean b/Mathlib/Data/DList/Basic.lean deleted file mode 100644 index 050f7d8838807f..00000000000000 --- a/Mathlib/Data/DList/Basic.lean +++ /dev/null @@ -1,38 +0,0 @@ -/- -Copyright (c) 2018 Simon Hudon. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Simon Hudon --/ -import Mathlib.Data.DList.Defs -import Mathlib.Tactic.TypeStar - -/-! -# Difference list - -This file provides a few results about `DList`, which is defined in `Batteries`. - -A difference list is a function that, given a list, returns the original content of the -difference list prepended to the given list. It is useful to represent elements of a given type -as `a₁ + ... + aₙ` where `+ : α → α → α` is any operation, without actually computing. - -This structure supports `O(1)` `append` and `push` operations on lists, making it -useful for append-heavy uses such as logging and pretty printing. --/ - -namespace Batteries - -/-- Concatenates a list of difference lists to form a single difference list. Similar to -`List.join`. -/ -def DList.join {α : Type*} : List (DList α) → DList α - | [] => DList.empty - | x :: xs => x ++ DList.join xs - -@[simp] -theorem DList_singleton {α : Type*} {a : α} : DList.singleton a = DList.lazy_ofList [a] := - rfl - -@[simp] -theorem DList_lazy {α : Type*} {l : List α} : DList.lazy_ofList l = Batteries.DList.ofList l := - rfl - -end Batteries diff --git a/Mathlib/Data/DList/Defs.lean b/Mathlib/Data/DList/Defs.lean deleted file mode 100644 index 408fa448595bd1..00000000000000 --- a/Mathlib/Data/DList/Defs.lean +++ /dev/null @@ -1,59 +0,0 @@ -/- -Copyright (c) 2017 Microsoft Corporation. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Leonardo de Moura --/ -import Batteries.Data.DList - -/-! -# Difference list - -This file provides a few results about `DList`, which is defined in `Batteries`. - -A difference list is a function that, given a list, returns the original content of the -difference list prepended to the given list. It is useful to represent elements of a given type -as `a₁ + ... + aₙ` where `+ : α → α → α` is any operation, without actually computing. - -This structure supports `O(1)` `append` and `push` operations on lists, making it -useful for append-heavy uses such as logging and pretty printing. --/ - -universe u - -namespace Batteries.DList - -open Function - -variable {α : Type u} - -/-- Convert a lazily-evaluated `List` to a `DList` -/ -def lazy_ofList (l : Thunk (List α)) : DList α := - ⟨fun xs => l.get ++ xs, fun t => by simp⟩ - -attribute [local simp] Function.comp - -attribute [local simp] ofList toList empty singleton cons push append - -theorem toList_ofList (l : List α) : DList.toList (DList.ofList l) = l := by - cases l; rfl; simp only [DList.toList, DList.ofList, List.cons_append, List.append_nil] - -theorem ofList_toList (l : DList α) : DList.ofList (DList.toList l) = l := by - obtain ⟨app, inv⟩ := l - simp only [ofList, toList, mk.injEq] - funext x - rw [(inv x)] - -theorem toList_empty : toList (@empty α) = [] := by simp - -theorem toList_singleton (x : α) : toList (singleton x) = [x] := by simp - -theorem toList_append (l₁ l₂ : DList α) : toList (l₁ ++ l₂) = toList l₁ ++ toList l₂ := by - obtain ⟨_, l₁_invariant⟩ := l₁; cases l₂; simp; rw [l₁_invariant] - -theorem toList_cons (x : α) (l : DList α) : toList (cons x l) = x :: toList l := by - cases l; simp - -theorem toList_push (x : α) (l : DList α) : toList (push l x) = toList l ++ [x] := by - obtain ⟨_, l_invariant⟩ := l; simp; rw [l_invariant] - -end Batteries.DList diff --git a/Mathlib/Data/DList/Instances.lean b/Mathlib/Data/DList/Instances.lean index 58f56d5bb12ace..5a4d14e1b26f56 100644 --- a/Mathlib/Data/DList/Instances.lean +++ b/Mathlib/Data/DList/Instances.lean @@ -3,7 +3,7 @@ Copyright (c) 2018 Simon Hudon. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Simon Hudon -/ -import Mathlib.Data.DList.Defs +import Batteries.Data.DList.Lemmas import Mathlib.Control.Traversable.Equiv import Mathlib.Control.Traversable.Instances diff --git a/Mathlib/Data/Seq/WSeq.lean b/Mathlib/Data/Seq/WSeq.lean index 750b2d1d1eda16..d6bd6ad6701cad 100644 --- a/Mathlib/Data/Seq/WSeq.lean +++ b/Mathlib/Data/Seq/WSeq.lean @@ -6,7 +6,7 @@ Authors: Mario Carneiro import Mathlib.Logic.Relation import Mathlib.Data.Option.Basic import Mathlib.Data.Seq.Seq -import Batteries.Data.DList +import Batteries.Data.DList.Basic /-! # Partially defined possibly infinite lists diff --git a/lake-manifest.json b/lake-manifest.json index 0fb978e09f267a..eedfc9ff53b9ba 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "9efd9c267ad7a71c5e3a83e8fbbd446fe61ef119", + "rev": "b731e84cb99d738b8d9710a0ba02bf8ec8d7fd26", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 9727486bc885d03a2435255dbb46b3b03599793e Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Wed, 16 Oct 2024 02:20:17 +0000 Subject: [PATCH 178/425] refactor: turn `posPart` into a notation class again (#17426) --- Mathlib.lean | 1 + Mathlib/Algebra/Notation.lean | 49 ++++++++++++++++++++++++ Mathlib/Algebra/Order/Group/PosPart.lean | 43 +++++++++------------ Mathlib/Tactic/Positivity/Basic.lean | 12 ++++-- Mathlib/Tactic/ToAdditive/Frontend.lean | 2 + 5 files changed, 79 insertions(+), 28 deletions(-) create mode 100644 Mathlib/Algebra/Notation.lean diff --git a/Mathlib.lean b/Mathlib.lean index 87442538c13ed7..12f5574a94d70c 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -543,6 +543,7 @@ import Mathlib.Algebra.MvPolynomial.Rename import Mathlib.Algebra.MvPolynomial.Supported import Mathlib.Algebra.MvPolynomial.Variables import Mathlib.Algebra.NeZero +import Mathlib.Algebra.Notation import Mathlib.Algebra.Opposites import Mathlib.Algebra.Order.AbsoluteValue import Mathlib.Algebra.Order.AddGroupWithTop diff --git a/Mathlib/Algebra/Notation.lean b/Mathlib/Algebra/Notation.lean new file mode 100644 index 00000000000000..0ea472b668eb9b --- /dev/null +++ b/Mathlib/Algebra/Notation.lean @@ -0,0 +1,49 @@ +/- +Copyright (c) 2024 Jireh Loreaux. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jireh Loreaux +-/ +import Mathlib.Tactic.ToAdditive + +/-! +# Notations for operations involving order and algebraic structure + +## Notations + +* `a⁺ᵐ = a ⊔ 1`: *Positive component* of an element `a` of a multiplicative lattice ordered group +* `a⁻ᵐ = a⁻¹ ⊔ 1`: *Negative component* of an element `a` of a multiplicative lattice ordered group +* `a⁺ = a ⊔ 0`: *Positive component* of an element `a` of a lattice ordered group +* `a⁻ = (-a) ⊔ 0`: *Negative component* of an element `a` of a lattice ordered group +-/ + +/-- A notation class for the *positive part* function: `a⁺`. -/ +class PosPart (α : Type*) where + /-- The *positive part* of an element `a`. -/ + posPart : α → α + +/-- A notation class for the *positive part* function (multiplicative version): `a⁺ᵐ`. -/ +@[to_additive] +class OneLePart (α : Type*) where + /-- The *positive part* of an element `a`. -/ + oneLePart : α → α + +/-- A notation class for the *negative part* function: `a⁻`. -/ +class NegPart (α : Type*) where + /-- The *negative part* of an element `a`. -/ + negPart : α → α + +/-- A notation class for the *negative part* function (multiplicative version): `a⁻ᵐ`. -/ +@[to_additive] +class LeOnePart (α : Type*) where + /-- The *negative part* of an element `a`. -/ + leOnePart : α → α + +export OneLePart (oneLePart) +export LeOnePart (leOnePart) +export PosPart (posPart) +export NegPart (negPart) + +@[inherit_doc] postfix:max "⁺ᵐ " => OneLePart.oneLePart +@[inherit_doc] postfix:max "⁻ᵐ" => LeOnePart.leOnePart +@[inherit_doc] postfix:max "⁺" => PosPart.posPart +@[inherit_doc] postfix:max "⁻" => NegPart.negPart diff --git a/Mathlib/Algebra/Order/Group/PosPart.lean b/Mathlib/Algebra/Order/Group/PosPart.lean index 219b8fc413d442..085e56c1b0be23 100644 --- a/Mathlib/Algebra/Order/Group/PosPart.lean +++ b/Mathlib/Algebra/Order/Group/PosPart.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Christopher Hoskin, Yaël Dillies -/ import Mathlib.Algebra.Order.Group.Unbundled.Abs +import Mathlib.Algebra.Notation /-! # Positive & negative parts @@ -12,8 +13,8 @@ Mathematical structures possessing an absolute value often also possess a unique elements into "positive" and "negative" parts which are in some sense "disjoint" (e.g. the Jordan decomposition of a measure). -This file defines `posPart` and `negPart`, the positive and negative parts of an element in a -lattice ordered group. +This file provides instances of `PosPart` and `NegPart`, the positive and negative parts of an +element in a lattice ordered group. ## Main statements @@ -21,13 +22,6 @@ lattice ordered group. positive and negative parts. * `posPart_inf_negPart_eq_zero`: The positive and negative parts are coprime. -## Notations - -* `a⁺ᵐ = a ⊔ 1`: *Positive component* of an element `a` of a multiplicative lattice ordered group -* `a⁻ᵐ = a⁻¹ ⊔ 1`: *Negative component* of an element `a` of a multiplicative lattice ordered group -* `a⁺ = a ⊔ 0`: *Positive component* of an element `a` of a lattice ordered group -* `a⁻ = (-a) ⊔ 0`: *Negative component* of an element `a` of a lattice ordered group - ## References * [Birkhoff, Lattice-ordered Groups][birkhoff1942] @@ -54,20 +48,21 @@ variable [Group α] {a b : α} /-- The *positive part* of an element `a` in a lattice ordered group is `a ⊔ 1`, denoted `a⁺ᵐ`. -/ @[to_additive "The *positive part* of an element `a` in a lattice ordered group is `a ⊔ 0`, denoted `a⁺`."] -def oneLePart (a : α) : α := a ⊔ 1 +instance instOneLePart : OneLePart α where + oneLePart a := a ⊔ 1 /-- The *negative part* of an element `a` in a lattice ordered group is `a⁻¹ ⊔ 1`, denoted `a⁻ᵐ `. -/ @[to_additive "The *negative part* of an element `a` in a lattice ordered group is `(-a) ⊔ 0`, denoted `a⁻`."] -def leOnePart (a : α) : α := a⁻¹ ⊔ 1 +instance instLeOnePart : LeOnePart α where + leOnePart a := a⁻¹ ⊔ 1 + +@[to_additive] lemma leOnePart_def (a : α) : a⁻ᵐ = a⁻¹ ⊔ 1 := rfl -@[inherit_doc] postfix:max "⁺ᵐ " => oneLePart -@[inherit_doc] postfix:max "⁻ᵐ" => leOnePart -@[inherit_doc] postfix:max "⁺" => posPart -@[inherit_doc] postfix:max "⁻" => negPart +@[to_additive] lemma oneLePart_def (a : α) : a⁺ᵐ = a ⊔ 1 := rfl -@[to_additive] lemma oneLePart_mono : Monotone (oneLePart : α → α) := +@[to_additive] lemma oneLePart_mono : Monotone (·⁺ᵐ : α → α) := fun _a _b hab ↦ sup_le_sup_right hab _ @[to_additive (attr := simp)] lemma oneLePart_one : (1 : α)⁺ᵐ = 1 := sup_idem _ @@ -124,8 +119,8 @@ lemma leOnePart_eq_one : a⁻ᵐ = 1 ↔ 1 ≤ a := by simp [leOnePart_eq_one'] -- Bourbaki A.VI.12 Prop 9 a) @[to_additive (attr := simp)] lemma oneLePart_div_leOnePart (a : α) : a⁺ᵐ / a⁻ᵐ = a := by - rw [div_eq_mul_inv, mul_inv_eq_iff_eq_mul, leOnePart, mul_sup, mul_one, mul_inv_cancel, sup_comm, - oneLePart] + rw [div_eq_mul_inv, mul_inv_eq_iff_eq_mul, leOnePart_def, mul_sup, mul_one, mul_inv_cancel, + sup_comm, oneLePart_def] @[to_additive (attr := simp)] lemma leOnePart_div_oneLePart (a : α) : a⁻ᵐ / a⁺ᵐ = a⁻¹ := by rw [← inv_div, oneLePart_div_leOnePart] @@ -148,16 +143,16 @@ variable [CovariantClass α α (swap (· * ·)) (· ≤ ·)] @[to_additive] lemma leOnePart_eq_inv_inf_one (a : α) : a⁻ᵐ = (a ⊓ 1)⁻¹ := by - rw [leOnePart, ← inv_inj, inv_sup, inv_inv, inv_inv, inv_one] + rw [leOnePart_def, ← inv_inj, inv_sup, inv_inv, inv_inv, inv_one] -- Bourbaki A.VI.12 Prop 9 d) @[to_additive] lemma oneLePart_mul_leOnePart (a : α) : a⁺ᵐ * a⁻ᵐ = |a|ₘ := by - rw [oneLePart, sup_mul, one_mul, leOnePart, mul_sup, mul_one, mul_inv_cancel, sup_assoc, + rw [oneLePart_def, sup_mul, one_mul, leOnePart_def, mul_sup, mul_one, mul_inv_cancel, sup_assoc, ← sup_assoc a, sup_eq_right.2 le_sup_right] exact sup_eq_left.2 <| one_le_mabs a @[to_additive] lemma leOnePart_mul_oneLePart (a : α) : a⁻ᵐ * a⁺ᵐ = |a|ₘ := by - rw [oneLePart, mul_sup, mul_one, leOnePart, sup_mul, one_mul, inv_mul_cancel, sup_assoc, + rw [oneLePart_def, mul_sup, mul_one, leOnePart_def, sup_mul, one_mul, inv_mul_cancel, sup_assoc, ← @sup_assoc _ _ a, sup_eq_right.2 le_sup_right] exact sup_eq_left.2 <| one_le_mabs a @@ -213,14 +208,14 @@ section LinearOrder variable [LinearOrder α] [Group α] {a b : α} @[to_additive] lemma oneLePart_eq_ite : a⁺ᵐ = if 1 ≤ a then a else 1 := by - rw [oneLePart, ← maxDefault, ← sup_eq_maxDefault]; simp_rw [sup_comm] + rw [oneLePart_def, ← maxDefault, ← sup_eq_maxDefault]; simp_rw [sup_comm] @[to_additive (attr := simp) posPart_pos_iff] lemma one_lt_oneLePart_iff : 1 < a⁺ᵐ ↔ 1 < a := lt_iff_lt_of_le_iff_le <| (one_le_oneLePart _).le_iff_eq.trans oneLePart_eq_one @[to_additive posPart_eq_of_posPart_pos] lemma oneLePart_of_one_lt_oneLePart (ha : 1 < a⁺ᵐ) : a⁺ᵐ = a := by - rw [oneLePart, right_lt_sup, not_le] at ha; exact oneLePart_eq_self.2 ha.le + rw [oneLePart_def, right_lt_sup, not_le] at ha; exact oneLePart_eq_self.2 ha.le @[to_additive (attr := simp)] lemma oneLePart_lt : a⁺ᵐ < b ↔ a < b ∧ 1 < b := sup_lt_iff @@ -228,7 +223,7 @@ section covariantmul variable [CovariantClass α α (· * ·) (· ≤ ·)] @[to_additive] lemma leOnePart_eq_ite : a⁻ᵐ = if a ≤ 1 then a⁻¹ else 1 := by - simp_rw [← one_le_inv']; rw [leOnePart, ← maxDefault, ← sup_eq_maxDefault]; simp_rw [sup_comm] + simp_rw [← one_le_inv']; rw [leOnePart_def, ← maxDefault, ← sup_eq_maxDefault]; simp_rw [sup_comm] @[to_additive (attr := simp) negPart_pos_iff] lemma one_lt_ltOnePart_iff : 1 < a⁻ᵐ ↔ a < 1 := lt_iff_lt_of_le_iff_le <| (one_le_leOnePart _).le_iff_eq.trans leOnePart_eq_one diff --git a/Mathlib/Tactic/Positivity/Basic.lean b/Mathlib/Tactic/Positivity/Basic.lean index 44f3d57c3fec72..d8eeaa14347fa2 100644 --- a/Mathlib/Tactic/Positivity/Basic.lean +++ b/Mathlib/Tactic/Positivity/Basic.lean @@ -500,9 +500,11 @@ def evalRatDen : PositivityExt where eval {u α} _ _ e := do /-- Extension for `posPart`. `a⁺` is always nonegative, and positive if `a` is. -/ @[positivity _⁺] -def evalPosPart : PositivityExt where eval zα pα e := do +def evalPosPart : PositivityExt where eval {u α} zα pα e := do match e with - | ~q(@posPart _ $instαlat $instαgrp $a) => + | ~q(@posPart _ $instαpospart $a) => + let _instαlat ← synthInstanceQ q(Lattice $α) + let _instαgrp ← synthInstanceQ q(AddGroup $α) assertInstancesCommute -- FIXME: There seems to be a bug in `Positivity.core` that makes it fail (instead of returning -- `.none`) here sometimes. See eg the first test for `posPart`. This is why we need `catchNone` @@ -513,9 +515,11 @@ def evalPosPart : PositivityExt where eval zα pα e := do /-- Extension for `negPart`. `a⁻` is always nonegative. -/ @[positivity _⁻] -def evalNegPart : PositivityExt where eval _ _ e := do +def evalNegPart : PositivityExt where eval {u α} _ _ e := do match e with - | ~q(@negPart _ $instαlat $instαgrp $a) => + | ~q(@negPart _ $instαnegpart $a) => + let _instαlat ← synthInstanceQ q(Lattice $α) + let _instαgrp ← synthInstanceQ q(AddGroup $α) assertInstancesCommute return .nonnegative q(negPart_nonneg $a) | _ => throwError "not `negPart`" diff --git a/Mathlib/Tactic/ToAdditive/Frontend.lean b/Mathlib/Tactic/ToAdditive/Frontend.lean index bdc528a2940732..277e01a289f6b3 100644 --- a/Mathlib/Tactic/ToAdditive/Frontend.lean +++ b/Mathlib/Tactic/ToAdditive/Frontend.lean @@ -1048,6 +1048,8 @@ def fixAbbreviation : List String → List String => "function" :: "_" :: "semiconj" :: fixAbbreviation s | "function" :: "_" :: "add" :: "Commute" :: s => "function" :: "_" :: "commute" :: fixAbbreviation s + | "Zero" :: "Le" :: "Part" :: s => "PosPart" :: fixAbbreviation s + | "Le" :: "Zero" :: "Part" :: s => "NegPart" :: fixAbbreviation s | "zero" :: "Le" :: "Part" :: s => "posPart" :: fixAbbreviation s | "le" :: "Zero" :: "Part" :: s => "negPart" :: fixAbbreviation s | "Division" :: "Add" :: "Monoid" :: s => "SubtractionMonoid" :: fixAbbreviation s From cd2b4684c8a90c3d0cd975765404b95e2c997c2a Mon Sep 17 00:00:00 2001 From: damiano Date: Wed, 16 Oct 2024 03:00:33 +0000 Subject: [PATCH 179/425] feat: the header linter (#16574) This syntax linter checks that * the copyright statement is correctly formatted; * `Mathlib.Tactic` is not imported; * makes sure that the module docs are the first non-import command of each file. The linter is off by default on projects downstream of mathlib, but it is on by default on mathlib. This subsumes the corresponding text-based linters. These will be removed in a future PR. Co-authored-by: Michael Rothgang Co-authored-by: grunweg --- Mathlib.lean | 1 + Mathlib/Init.lean | 1 + Mathlib/Order/Filter/Basic.lean | 2 +- Mathlib/Tactic.lean | 1 + Mathlib/Tactic/Linter/Header.lean | 304 ++++++++++++++++++++++++++ Mathlib/Tactic/Linter/TextBased.lean | 4 +- lakefile.lean | 1 + scripts/mk_all.lean | 2 + scripts/nolints-style.txt | 4 + test/Header.lean | 308 +++++++++++++++++++++++++++ 10 files changed, 626 insertions(+), 2 deletions(-) create mode 100644 Mathlib/Tactic/Linter/Header.lean create mode 100644 test/Header.lean diff --git a/Mathlib.lean b/Mathlib.lean index 12f5574a94d70c..a321756d00024d 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4351,6 +4351,7 @@ import Mathlib.Tactic.Linter.FlexibleLinter import Mathlib.Tactic.Linter.GlobalAttributeIn import Mathlib.Tactic.Linter.HashCommandLinter import Mathlib.Tactic.Linter.HaveLetLinter +import Mathlib.Tactic.Linter.Header import Mathlib.Tactic.Linter.Lint import Mathlib.Tactic.Linter.MinImports import Mathlib.Tactic.Linter.OldObtain diff --git a/Mathlib/Init.lean b/Mathlib/Init.lean index dff297db373ea4..bffb68e9d48315 100644 --- a/Mathlib/Init.lean +++ b/Mathlib/Init.lean @@ -1,6 +1,7 @@ import Mathlib.Tactic.Linter.DocPrime import Mathlib.Tactic.Linter.HashCommandLinter import Mathlib.Tactic.Linter.GlobalAttributeIn +import Mathlib.Tactic.Linter.Header -- This file imports Batteries.Tactic.Lint, where the `env_linter` attribute is defined. import Mathlib.Tactic.Linter.Lint import Mathlib.Tactic.Linter.OldObtain diff --git a/Mathlib/Order/Filter/Basic.lean b/Mathlib/Order/Filter/Basic.lean index c0377331e71f58..84c4397e07ac66 100644 --- a/Mathlib/Order/Filter/Basic.lean +++ b/Mathlib/Order/Filter/Basic.lean @@ -2645,4 +2645,4 @@ lemma compl_mem_comk {p : Set α → Prop} {he hmono hunion s} : end Filter -set_option linter.style.longFile 3000 +set_option linter.style.longFile 2800 diff --git a/Mathlib/Tactic.lean b/Mathlib/Tactic.lean index 46952152d3576d..c8d7b7ae274942 100644 --- a/Mathlib/Tactic.lean +++ b/Mathlib/Tactic.lean @@ -140,6 +140,7 @@ import Mathlib.Tactic.Linter.FlexibleLinter import Mathlib.Tactic.Linter.GlobalAttributeIn import Mathlib.Tactic.Linter.HashCommandLinter import Mathlib.Tactic.Linter.HaveLetLinter +import Mathlib.Tactic.Linter.Header import Mathlib.Tactic.Linter.Lint import Mathlib.Tactic.Linter.MinImports import Mathlib.Tactic.Linter.OldObtain diff --git a/Mathlib/Tactic/Linter/Header.lean b/Mathlib/Tactic/Linter/Header.lean new file mode 100644 index 00000000000000..bcc44a5ae56ade --- /dev/null +++ b/Mathlib/Tactic/Linter/Header.lean @@ -0,0 +1,304 @@ +/- +Copyright (c) 2024 Damiano Testa. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Michael Rothgang, Damiano Testa +-/ +import Lean.Elab.Command + +/-! +# The "header" linter + +The "header" style linter checks that a file starts with +``` +/- +Copyright ... +Apache ... +Authors ... +-/ + +import statements* +module doc-string* +remaining file +``` +It emits a warning if +* the copyright statement is malformed; +* `Mathlib.Tactic` is imported; +* any import in `Lake` is present; +* the first non-`import` command is not a module doc-string. + +The linter allows `import`-only files and does not require a copyright statement in `Mathlib.Init`. + +## Implementation +The strategy used by the linter is as follows. +The linter computes the end position of the first module doc-string of the file, +resorting to the end of the file, if there is no module doc-string. +Next, the linter tries to parse the file up to the position determined above. + +If the parsing is successful, the linter checks the resulting `Syntax` and behaves accordingly. + +If the parsing is not successful, this already means there is some "problematic" command +after the imports. In particular, there is a command that is not a module doc-string +immediately following the last import: the file should be flagged by the linter. +Hence, the linter then falls back to parsing the header of the file, adding a spurious `section` +after it. +This makes it possible for the linter to check the entire header of the file, emit warnings that +could arise from this part and also flag that the file should contain a module doc-string after +the `import` statements. +-/ + +open Lean Elab Command + +namespace Mathlib.Linter + +/-- +`firstNonImport? stx` assumes that the input `Syntax` is of kind `Lean.Parser.Module.module`. +It returns +* `none`, if `stx` consists only of `import` statements, +* the first non-`import` command in `stx`, otherwise. + +The intended use-case is to use the output of `testParseModule` as the input of +`firstNonImport?`. +-/ +def firstNonImport? : Syntax → Option Syntax + | .node _ ``Lean.Parser.Module.module #[_header, .node _ `null args] => args[0]? + | _=> some .missing -- this is unreachable, if the input comes from `testParseModule` + +/-- `getImportIds s` takes as input `s : Syntax`. +It returns the array of all `import` identifiers in `s`. -/ +-- We cannot use `importsOf` instead, as +-- - that function is defined in the `ImportGraph` project; we would like to minimise imports +-- to Mathlib.Init (where this linter is imported) +-- - that function does not return the Syntax corresponding to each import, +-- which we use to log more precise warnings. +partial +def getImportIds (s : Syntax) : Array Syntax := + let rest : Array Syntax := (s.getArgs.map getImportIds).flatten + if s.isOfKind ``Lean.Parser.Module.import then + rest.push (s.getArgs.getD 2 default) + else + rest + +/-- +`parseUpToHere pos post` takes as input `pos : String.Pos` and the optional `post : String`. +It parses the current file from the beginning until `pos`, appending `post` at the end. +It returns a syntax node of kind `Lean.Parser.Module.module`. +The option of appending a final string to the text gives more control to avoid syntax errors, +for instance in the presence of `#guard_msgs in` or `set_option ... in`. + +Note that this parsing will *not* be successful on every file. However, if the linter is +parsing the file linearly, it will only need to parse +* the imports (that are always parseable) and +* the first non-import command that is supposed to be a module doc-string (so again always + parseable). + +In conclusion, either the parsing is successful, and the linter can continue with its analysis, +or the parsing is not successful and the linter will flag a missing module doc-string! +-/ +def parseUpToHere (pos : String.Pos) (post : String := "") : CommandElabM Syntax := do + let upToHere : Substring := { str := (← getFileMap).source, startPos := ⟨0⟩, stopPos := pos } + -- Append a further string after the content of `upToHere`. + Parser.testParseModule (← getEnv) "linter.style.header" (upToHere.toString ++ post) + +/-- `toSyntax s pattern` converts the two input strings into a `Syntax`, assuming that `pattern` +is a substring of `s`: +the syntax is an atom with value `pattern` whose the range is the range of `pattern` in `s`. -/ +def toSyntax (s pattern : String) (offset : String.Pos := 0) : Syntax := + let beg := ((s.splitOn pattern).getD 0 "").endPos + offset + let fin := (((s.splitOn pattern).getD 0 "") ++ pattern).endPos + offset + mkAtomFrom (.ofRange ⟨beg, fin⟩) pattern + +/-- Return if `line` looks like a correct authors line in a copyright header. + +The `offset` input is used to shift the position information of the `Syntax` that the command +produces. +`authorsLineChecks` computes a position for its warning *relative to `line`*. +The `offset` input passes on the starting position of `line` in the whole file. +-/ +def authorsLineChecks (line : String) (offset : String.Pos) : Array (Syntax × String) := + Id.run do + -- We cannot reasonably validate the author names, so we look only for a few common mistakes: + -- the line starting wrongly, double spaces, using ' and ' between names, + -- and ending the line with a period. + let mut stxs := #[] + if !line.startsWith "Authors: " then + stxs := stxs.push + (toSyntax line (line.take "Authors: ".length) offset, + s!"The authors line should begin with 'Authors: '") + if (line.splitOn " ").length != 1 then + stxs := stxs.push (toSyntax line " " offset, s!"Double spaces are not allowed.") + if (line.splitOn " and ").length != 1 then + stxs := stxs.push (toSyntax line " and " offset, s!"Please, do not use 'and'; use ',' instead.") + if line.back == '.' then + stxs := stxs.push + (toSyntax line "." offset, + s!"Please, do not end the authors' line with a period.") + return stxs + +/-- The main function to validate the copyright string. +The input is the copyright string, the output is an array of `Syntax × String` encoding: +* the `Syntax` factors are atoms whose ranges are "best guesses" for where the changes should + take place; the embedded string is the current text that the linter flagged; +* the `String` factor is the linter message. + +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 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. +-/ +def copyrightHeaderChecks (copyright : 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. + let preprocessCopyright := (copyright.replace ",\n " ", ").replace ",\n" "," + -- Filter out everything after the first isolated `-/`. + let pieces := preprocessCopyright.splitOn "\n-/" + let copyright := (pieces.getD 0 "") ++ "\n-/" + let stdText (s : String) := + s!"Malformed or missing copyright header: `{s}` should be alone on its own line." + let mut output := #[] + if (pieces.getD 1 "\n").take 1 != "\n" then + output := output.push (toSyntax copyright "-/", s!"{stdText "-/"}") + let lines := copyright.splitOn "\n" + let closeComment := lines.getLastD "" + match lines with + | openComment :: copyrightAuthor :: license :: authorsLines => + -- The header should start and end with blank comments. + match openComment, closeComment with + | "/-", "-/" => output := output + | "/-", _ => + output := output.push (toSyntax copyright closeComment, s!"{stdText "-/"}") + | _, _ => + output := output.push (toSyntax copyright openComment, s!"{stdText ("/".push '-')}") + -- Validate the first copyright line. + let copStart := "Copyright (c) 20" + let copStop := ". All rights reserved." + if !copyrightAuthor.startsWith copStart then + output := output.push + (toSyntax copyright (copyrightAuthor.take copStart.length), + s!"Copyright line should start with 'Copyright (c) YYYY'") + if !copyrightAuthor.endsWith copStop then + output := output.push + (toSyntax copyright (copyrightAuthor.takeRight copStop.length), + s!"Copyright line should end with '. All rights reserved.'") + -- Validate the authors line(s). The last line is the closing comment: trim that off right away. + let authorsLines := authorsLines.dropLast + -- Complain about a missing authors line. + if authorsLines.length == 0 then + output := output.push (toSyntax copyright "-/", s!"Copyright too short!") + else + -- If the list of authors spans multiple lines, all but the last line should end with a trailing + -- comma. This excludes e.g. other comments in the copyright header. + let authorsLine := "\n".intercalate authorsLines + let authorsStart := (("\n".intercalate [openComment, copyrightAuthor, license, ""])).endPos + if authorsLines.length > 1 && !authorsLines.dropLast.all (·.endsWith ",") then + output := output.push ((toSyntax copyright authorsLine), + "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}\"") + | _ => + output := output.push (toSyntax copyright "-/", s!"Copyright too short!") + return output + +/-- Check the `Syntax` `imports` for broad imports: either `Mathlib.Tactic` or any import +starting with `Lake`. -/ +def broadImportsCheck (imports : Array Syntax) : Array (Syntax × String) := Id.run do + let mut output := #[] + for i in imports do + match i.getId with + | `Mathlib.Tactic => + output := output.push (i, s!"Files in mathlib cannot import the whole tactic folder.") + | modName => + if modName.getRoot == `Lake then + output := output.push (i, + s!"In the past, importing 'Lake' in mathlib has led to dramatic slow-downs of the linter \ + (see e.g. mathlib4#13779). Please consider carefully if this import is useful and \ + make sure to benchmark it. If this is fine, feel free to allow this linter.") + return output + +/-- +The "header" style linter checks that a file starts with +``` +/- +Copyright ... +Apache ... +Authors ... +-/ + +import statements* +module doc-string* +remaining file +``` +It emits a warning if +* the copyright statement is malformed; +* `Mathlib.Tactic` is imported; +* any import in `Lake` is present; +* the first non-`import` command is not a module doc-string. + +The linter allows `import`-only files and does not require a copyright statement in `Mathlib.Init`. +-/ +register_option linter.style.header : Bool := { + defValue := false + descr := "enable the header style linter" +} + +namespace Style.header + +@[inherit_doc Mathlib.Linter.linter.style.header] +def headerLinter : Linter where run := withSetOptionIn fun stx ↦ do + unless Linter.getLinterValue linter.style.header (← getOptions) do + return + if (← get).messages.hasErrors then + return + let mainModule ← getMainModule + -- `Mathlib.lean` imports `Mathlib.Tactic`, which the broad imports check below would flag. + -- Since that file is imports-only, we can simply skip linting it. + if mainModule == `Mathlib then return + let fm ← getFileMap + let md := (getMainModuleDoc (← getEnv)).toArray + -- The end of the first module doc-string, or the end of the file if there is none. + let firstDocModPos := match md[0]? with + | none => fm.positions.back + | some doc => fm.ofPosition doc.declarationRange.endPos + unless stx.getTailPos? == some firstDocModPos do + return + -- We try to parse the file up to `firstDocModPos`. + let upToStx ← parseUpToHere firstDocModPos <|> (do + -- If parsing failed, there is some command which is not a module docstring. + -- In that case, we parse until the end of the imports and add an extra `section` afterwards, + -- so we trigger a "no module doc-string" warning. + let fil ← getFileName + let (stx, _) ← Parser.parseHeader { input := fm.source, fileName := fil, fileMap := fm } + parseUpToHere (stx.getTailPos?.getD default) "\nsection") + let importIds := getImportIds upToStx + -- Report on broad imports. + for (imp, msg) in broadImportsCheck importIds do + Linter.logLint linter.style.header imp msg + let afterImports := firstNonImport? upToStx + if afterImports.isNone then return + let copyright := match upToStx.getHeadInfo with + | .original lead .. => lead.toString + | _ => "" + -- Report any errors about the copyright line. + if mainModule != `Mathlib.Init then + for (stx, m) in copyrightHeaderChecks copyright do + Linter.logLint linter.style.header stx m!"* '{stx.getAtomVal}':\n{m}\n" + -- Report a missing module doc-string. + match afterImports with + | none => return + | some (.node _ ``Lean.Parser.Command.moduleDoc _) => return + | some rest => + Linter.logLint linter.style.header rest + m!"The module doc-string for a file should be the first command after the imports.\n\ + Please, add a module doc-string before `{stx}`." + +initialize addLinter headerLinter + +end Style.header + +end Mathlib.Linter diff --git a/Mathlib/Tactic/Linter/TextBased.lean b/Mathlib/Tactic/Linter/TextBased.lean index b4556c694d0814..81ddc7216b3800 100644 --- a/Mathlib/Tactic/Linter/TextBased.lean +++ b/Mathlib/Tactic/Linter/TextBased.lean @@ -147,8 +147,10 @@ def compare (existing new : ErrorContext) : ComparisonResult := -- Generally, comparable errors must have equal `StyleError`s, but there are some exceptions. else match (existing.error, new.error) with -- We do *not* care about the *kind* of wrong copyright, - -- nor about the particular length of a too long line. + -- nor about the kind or line number of a duplicate import. | (StyleError.copyright _, StyleError.copyright _) => ComparisonResult.Comparable true + | (StyleError.duplicateImport _ _, StyleError.duplicateImport _ _) => + ComparisonResult.Comparable true -- In all other cases, `StyleErrors` must compare equal. | (a, b) => if a == b then ComparisonResult.Comparable true else ComparisonResult.Different diff --git a/lakefile.lean b/lakefile.lean index 59b2eae8ed37f9..e0fe819c339706 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -31,6 +31,7 @@ abbrev mathlibOnlyLinters : Array LeanOption := #[ ⟨`linter.refine, true⟩, ⟨`linter.style.cdot, true⟩, ⟨`linter.style.dollarSyntax, true⟩, + ⟨`linter.style.header, true⟩, ⟨`linter.style.lambdaSyntax, true⟩, ⟨`linter.style.longLine, true⟩, ⟨`linter.style.longFile, .ofNat 1500⟩, diff --git a/scripts/mk_all.lean b/scripts/mk_all.lean index 309a4bf49d2c4c..f58f7491c65e67 100644 --- a/scripts/mk_all.lean +++ b/scripts/mk_all.lean @@ -7,6 +7,8 @@ import Cli.Basic import Lake.CLI.Main import Mathlib.Util.GetAllModules +-- The `style.header` linter flags `import Lake.CLI.Main` as a potential performance issue. +set_option linter.style.header false /-! # Script to create a file importing all files from a folder diff --git a/scripts/nolints-style.txt b/scripts/nolints-style.txt index 9467ae24e56508..b1dbf8c926f9d5 100644 --- a/scripts/nolints-style.txt +++ b/scripts/nolints-style.txt @@ -32,3 +32,7 @@ Mathlib/Tactic/Linter/TextBased.lean : line 84 : ERR_ADN : Found the string "Ada Mathlib/Tactic/Linter/TextBased.lean : line 274 : ERR_ADN : Found the string "Adaptation note:", please use the #adaptation_note command instead Mathlib/Tactic/Linter/TextBased.lean : line 279 : ERR_ADN : Found the string "Adaptation note:", please use the #adaptation_note command instead Mathlib/Tactic/Linter/TextBased.lean : line 280 : ERR_ADN : Found the string "Adaptation note:", please use the #adaptation_note command instead + +-- The "duplicate imports" linter fires on this line inside a multi-line module docstring, +-- which says 'import statements': this is a false positive. +Mathlib/Tactic/Linter/Header.lean : line 228 : ERR_DIMP : Duplicate imports: import statements* (already imported on line 19) diff --git a/test/Header.lean b/test/Header.lean new file mode 100644 index 00000000000000..f1b9352eb94043 --- /dev/null +++ b/test/Header.lean @@ -0,0 +1,308 @@ +/- +Copyright (c) 2024 Damiano Testa. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Damiano Testa +-/ + +import Mathlib.Tactic.Linter.Header +import Lake +import /- -/ Mathlib.Tactic -- the `TextBased` linter does not flag this `broadImport` + +/-- +warning: In the past, importing 'Lake' in mathlib has led to dramatic slow-downs of the linter (see e.g. mathlib4#13779). Please consider carefully if this import is useful and make sure to benchmark it. If this is fine, feel free to allow this linter. +note: this linter can be disabled with `set_option linter.style.header false` +--- +warning: Files in mathlib cannot import the whole tactic folder. +note: this linter can be disabled with `set_option linter.style.header false` +--- +warning: The module doc-string for a file should be the first command after the imports. +Please, add a module doc-string before `/-!# Tests for the `docModule` linter +-/ +`. +note: this linter can be disabled with `set_option linter.style.header false` +-/ +#guard_msgs in +set_option linter.style.header true in + +/-! +# Tests for the `docModule` linter +-/ + +/-- +A convenience function that replaces `/` with `|`. +This converts `/-` and `-/` into `|-` and `-|` that no longer interfere with the ending of the +`#guard_msgs` doc-string. +-/ +def replaceMultilineComments (s : String) : String := + s.replace "/" "|" + +open Lean Elab Command in +/-- +`#check_copyright cop` takes as input the `String` `cop`, expected to be a copyright statement. +It logs details of what the linter would report if the `cop` is "malformed". +-/ +elab "#check_copyright " cop:str : command => do + let cop := cop.getString + for (s, m) in Mathlib.Linter.copyrightHeaderChecks cop do + if let some rg := s.getRange? then + logInfo + m!"Text: `{replaceMultilineComments s.getAtomVal}`\n\ + Range: {(rg.start, rg.stop)}\n\ + Message: '{replaceMultilineComments m}'" + +-- well-formed +#check_copyright +"/- +Copyright (c) 2024 Damiano Testa. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Name LastName, Name LastName, +Name LastName, + Name LastName, + Name LastName +-/ +" + +/-- +info: Text: ` |-` +Range: (0, 3) +Message: 'Malformed or missing copyright header: `|-` should be alone on its own line.' +-/ +#guard_msgs in +#check_copyright +" /- +Copyright (c) 2024 Damiano Testa. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Name LastName +-/ +" + +-- The last line does not end with a newline. +/-- +info: Text: `-|` +Range: (149, 151) +Message: 'Malformed or missing copyright header: `-|` should be alone on its own line.' +-/ +#guard_msgs in +#check_copyright +"/- +Copyright (c) 2024 Damiano Testa. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Name LastName +-/" + +/-- +info: Text: `Authors: Name LastName + +Here comes an implicit docstring which doesn't belong here!` +Range: (126, 209) +Message: 'If an authors line spans multiple lines, each line but the last must end with a trailing comma' +-/ +#guard_msgs in +#check_copyright +"/- +Copyright (c) 2024 Damiano Testa. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Name LastName + +Here comes an implicit docstring which doesn't belong here! +-/ +" + +/-- +info: Text: `Authors: Name LastName +Here comes an implicit docstring which shouldn't be here!` +Range: (126, 206) +Message: 'If an authors line spans multiple lines, each line but the last must end with a trailing comma' +-/ +#guard_msgs in +#check_copyright +"/- +Copyright (c) 2024 Damiano Testa. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Name LastName +Here comes an implicit docstring which shouldn't be here! +-/ +" + +/-- +info: Text: `-|` +Range: (126, 128) +Message: 'Copyright too short!' +-/ +#guard_msgs in +#check_copyright +"/- +Copyright (c) 2024 Damiano Testa. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +-/ +" + +/-- +info: Text: `-|` +Range: (1, 3) +Message: 'Copyright too short!' +-/ +#guard_msgs in +#check_copyright "" + +/-- +info: Text: `-|` +Range: (1, 3) +Message: 'Copyright too short!' +-/ +#guard_msgs in +#check_copyright "" + +/-- +info: Text: `Cpyright (c) 202` +Range: (3, 19) +Message: 'Copyright line should start with 'Copyright (c) YYYY'' +-/ +#guard_msgs in +#check_copyright +"/- +Cpyright (c) 2024 Damiano Testa. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Name LastName +-/ +" + +/-- +info: Text: `a. All rights reserve.` +Range: (34, 56) +Message: 'Copyright line should end with '. All rights reserved.'' +-/ +#guard_msgs in +#check_copyright +"/- +Copyright (c) 2024 Damiano Testa. All rights reserve. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Name LastName +-/ +" + +/-- +info: Text: `Rleased under Apache 2.0 license as described in the file LICENSE.` +Range: (58, 124) +Message: 'Second copyright line should be +"Released under Apache 2.0 license as described in the file LICENSE."' +-/ +#guard_msgs in +#check_copyright +"/- +Copyright (c) 2024 Damiano Testa. All rights reserved. +Rleased under Apache 2.0 license as described in the file LICENSE. +Authors: Name LastName +-/ +" + +/-- +info: Text: `A uthors:` +Range: (126, 135) +Message: 'The authors line should begin with 'Authors: '' +-/ +#guard_msgs in +#check_copyright +"/- +Copyright (c) 2024 Damiano Testa. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +A uthors: Name LastName +-/ +" + +/-- +info: Text: ` ` +Range: (139, 141) +Message: 'Double spaces are not allowed.' +-/ +#guard_msgs in +#check_copyright +"/- +Copyright (c) 2024 Damiano Testa. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Name LastName +-/ +" + +/-- +info: Text: `.` +Range: (148, 149) +Message: 'Please, do not end the authors' line with a period.' +-/ +#guard_msgs in +#check_copyright +"/- +Copyright (c) 2024 Damiano Testa. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Name LastName. +-/ +" + +/-- +info: Text: ` ` +Range: (149, 151) +Message: 'Double spaces are not allowed.' +-/ +#guard_msgs in +#check_copyright +"/- +Copyright (c) 2024 Damiano Testa. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Name LastName, + Name LastName +-/ +" + +-- The `Copyright` and `Authors` lines are allowed to overflow. +#check_copyright +"/- +Copyright (c) 2019 Reid Barton, Johan Commelin, Jesse Michael Han, Chris Hughes, Robert Y. Lewis, +Patrick Massot. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Reid Barton, Johan Commelin, Jesse Michael Han, Chris Hughes, Robert Y. Lewis, + Patrick Massot +-/ +" + +-- However, in this case the wrapped lines must end with a comma. +/-- +info: Text: `(c) 2024 Damiano Testa` +Range: (13, 35) +Message: 'Copyright line should end with '. All rights reserved.'' +--- +info: Text: `Released under Apache 2.0 license as described in the file LICENSE. +Authors: Name LastName + and others.` +Range: (83, 187) +Message: 'If an authors line spans multiple lines, each line but the last must end with a trailing comma' +--- +info: Text: `Released ` +Range: (83, 92) +Message: 'The authors line should begin with 'Authors: '' +--- +info: Text: ` ` +Range: (174, 176) +Message: 'Double spaces are not allowed.' +--- +info: Text: ` and ` +Range: (175, 180) +Message: 'Please, do not use 'and'; use ',' instead.' +--- +info: Text: `.` +Range: (106, 107) +Message: 'Please, do not end the authors' line with a period.' +--- +info: Text: ` and many other authors. All rights reserved.` +Range: (36, 82) +Message: 'Second copyright line should be "Released under Apache 2.0 license as described in the file LICENSE."' +-/ +#guard_msgs in +#check_copyright +"/- +Copyright (c) 2024 Damiano Testa + and many other authors. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Name LastName + and others. +-/ +" From 62acab6618ba88ba29fbdae73622912e2bc59e31 Mon Sep 17 00:00:00 2001 From: damiano Date: Wed, 16 Oct 2024 03:00:35 +0000 Subject: [PATCH 180/425] fix: make the long file linter reject "too large" values (#17309) Reported [here](https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/Splitting.20Mathlib.2FData.2FFinset.2FBasic/near/473746566). The PR corrects the checks to only allow "small" increases to the value of the option. Co-authored-by: Michael Rothgang --- Mathlib/Data/List/Basic.lean | 2 +- Mathlib/SetTheory/Ordinal/Arithmetic.lean | 2 +- Mathlib/Tactic/Linter/Lint.lean | 16 +++- test/LongFile.lean | 98 ++++++++++++++++++----- 4 files changed, 94 insertions(+), 24 deletions(-) diff --git a/Mathlib/Data/List/Basic.lean b/Mathlib/Data/List/Basic.lean index 0d8e6a7b48ee42..2d8dc25390035e 100644 --- a/Mathlib/Data/List/Basic.lean +++ b/Mathlib/Data/List/Basic.lean @@ -2283,4 +2283,4 @@ end lookup end List -set_option linter.style.longFile 2700 +set_option linter.style.longFile 2400 diff --git a/Mathlib/SetTheory/Ordinal/Arithmetic.lean b/Mathlib/SetTheory/Ordinal/Arithmetic.lean index 7c37366aa8dd13..65ed7c402f75f1 100644 --- a/Mathlib/SetTheory/Ordinal/Arithmetic.lean +++ b/Mathlib/SetTheory/Ordinal/Arithmetic.lean @@ -2462,4 +2462,4 @@ theorem rank_strictAnti [Preorder α] [WellFoundedGT α] : end WellFounded -set_option linter.style.longFile 2700 +set_option linter.style.longFile 2600 diff --git a/Mathlib/Tactic/Linter/Lint.lean b/Mathlib/Tactic/Linter/Lint.lean index 6d00f05354ddea..4c0a8fb5df9a44 100644 --- a/Mathlib/Tactic/Linter/Lint.lean +++ b/Mathlib/Tactic/Linter/Lint.lean @@ -311,7 +311,7 @@ The "longFile" linter emits a warning on files which are longer than a certain n /-- The "longFile" linter emits a warning on files which are longer than a certain number of lines -(1500 by default on mathlib, no limit for downstream projects). +(`linter.style.longFileDefValue` by default on mathlib, no limit for downstream projects). If this option is set to `N` lines, the linter warns once a file has more than `N` lines. A value of `0` silences the linter entirely. -/ @@ -354,6 +354,7 @@ def longFileLinter : Linter where run := withSetOptionIn fun stx ↦ do if let some init := stx.getTailPos? then -- the last line: we subtract 1, since the last line is expected to be empty let lastLine := ((← getFileMap).toPosition init).line + -- In this case, the file has an allowed length, and the linter option is unnecessarily set. if lastLine ≤ defValue && defValue < linterBound then logWarningAt stx <| .tagged linter.style.longFile.name m!"The default value of the `longFile` linter is {defValue}.\n\ @@ -365,12 +366,23 @@ def longFileLinter : Linter where run := withSetOptionIn fun stx ↦ do -- `candidate` is necessarily bigger than `lastLine` and hence bigger than `defValue` let candidate := (lastLine / 100) * 100 + 200 let candidate := max candidate defValue - if linterBound < lastLine then + -- In this case, the file is longer than the default and also than what the option says. + if defValue ≤ linterBound && linterBound < lastLine then logWarningAt stx <| .tagged linter.style.longFile.name m!"This file is {lastLine} lines long, but the limit is {linterBound}.\n\n\ You can extend the allowed length of the file using \ `set_option linter.style.longFile {candidate}`.\n\ You can completely disable this linter by setting the length limit to `0`." + else + -- Finally, the file exceeds the default value, but not the option: we only allow the value + -- of the option to be `candidate` or `candidate + 100`. + -- In particular, this flags any option that is set to an unnecessarily high value. + if linterBound == candidate || linterBound + 100 == candidate then return + else + logWarningAt stx <| .tagged linter.style.longFile.name + m!"This file is {lastLine} lines long. \ + The current limit is {linterBound}, but it is expected to be {candidate}:\n\ + `set_option linter.style.longFile {candidate}`." initialize addLinter longFileLinter diff --git a/test/LongFile.lean b/test/LongFile.lean index faec16c404806c..635f2ab485c30d 100644 --- a/test/LongFile.lean +++ b/test/LongFile.lean @@ -5,7 +5,8 @@ import Mathlib.Tactic.Linter.Lint Things to note: * `set_option linter.style.longFile 0` disables the linter, allowing us to set a value smaller than - `1500` without triggering the warning for setting a small value for the option; + `linter.style.longFileDefValue` without triggering the warning for setting a small value + for the option; * `guard_msgs ... in #exit` and `set_option ... in #exit` allow processing of the file *beyond* `#exit`, since they wrap `#exit` inside an anonymous section, making Lean active again *after* that anonymous section. @@ -20,49 +21,106 @@ The current value of 1500 does not exceed the allowed bound. Please, remove the `set_option linter.style.longFile 1500`. -/ #guard_msgs in --- Do not allow setting a "small" `longFile` linter option +-- Do not allow setting a `longFile` linter option if the file does not exceed the `defValue` set_option linter.style.longFile 1500 /-- warning: using 'exit' to interrupt Lean --- -warning: The default value of the `longFile` linter is 1500. -This file is 36 lines long which does not exceed the allowed bound. -Please, remove the `set_option linter.style.longFile 1600`. +warning: The default value of the `longFile` linter is 50. +This file is 38 lines long which does not exceed the allowed bound. +Please, remove the `set_option linter.style.longFile 60`. -/ #guard_msgs in -- Do not allow unnecessarily increasing the `longFile` linter option -set_option linter.style.longFile 1600 in +set_option linter.style.longFileDefValue 50 in +set_option linter.style.longFile 60 in #exit /-- warning: using 'exit' to interrupt Lean --- -warning: This file is 51 lines long, but the limit is 10. +warning: This file is 52 lines long, but the limit is 20. -You can extend the allowed length of the file using `set_option linter.style.longFile 1500`. +You can extend the allowed length of the file using `set_option linter.style.longFile 200`. You can completely disable this linter by setting the length limit to `0`. -/ #guard_msgs in --- First, we silence the linter, so that we can set a default value smaller than 1500. -set_option linter.style.longFile 0 in --- Next, we test that the `longFile` linter warns when a file exceeds the allowed value. -set_option linter.style.longFile 10 in +-- We test that the `longFile` linter warns when a file exceeds the allowed value. +set_option linter.style.longFileDefValue 10 in +set_option linter.style.longFile 20 in +#exit + +/-- warning: using 'exit' to interrupt Lean -/ +#guard_msgs in +-- Check that the `candidate` value is allowed +set_option linter.style.longFileDefValue 10 in +set_option linter.style.longFile 200 in +#exit + +/-- warning: using 'exit' to interrupt Lean -/ +#guard_msgs in +-- Check that the `candidate - 100` value is allowed +set_option linter.style.longFileDefValue 10 in +set_option linter.style.longFile 100 in #exit /-- warning: using 'exit' to interrupt Lean --- -warning: The default value of the `longFile` linter is 1500. -This file is 66 lines long which does not exceed the allowed bound. -Please, remove the `set_option linter.style.longFile 1700`. +warning: This file is 78 lines long. The current limit is 101, but it is expected to be 200: +`set_option linter.style.longFile 200`. -/ #guard_msgs in --- First, we silence the linter, so that we can set a default value smaller than 1500. -set_option linter.style.longFile 0 in --- If we set the allowed bound for the `longFile` linter that is too large, --- the linter tells us to use a smaller bound. -set_option linter.style.longFile 1700 in +-- Check that a value different from `candidate` or `candidate - 100` value is not allowed +set_option linter.style.longFileDefValue 10 in +set_option linter.style.longFile 101 in #exit +-- The following test is a little artificial: it follows a path in the code that should only +-- be accessible after modifying the linter options appropriately. +-- Specifically, in the line `if lastLine ≤ defValue && defValue < linterBound then`, the failure +-- of *only* the second condition would produce the error message below +set_option linter.style.longFileDefValue 400 +set_option linter.style.longFile 500 +set_option linter.style.longFileDefValue 1000 +/-- +warning: using 'exit' to interrupt Lean +--- +warning: This file is 94 lines long. The current limit is 500, but it is expected to be 1000: +`set_option linter.style.longFile 1000`. +-/ +#guard_msgs in +#exit +/- +warning: using 'exit' to interrupt Lean +--- +warning: The default value of the `longFile` linter is 1000. +This file is 95 lines long which does not exceed the allowed bound. +Please, remove the `set_option linter.style.longFile 500`. +-/ + +set_option linter.style.longFileDefValue 2000 +/-- +warning: The default value of the `longFile` linter is 2000. +The current value of 1999 does not exceed the allowed bound. +Please, remove the `set_option linter.style.longFile 1999`. +-/ +#guard_msgs in +-- Do not allow setting a `longFile` linter option if the file does not exceed the `defValue` +set_option linter.style.longFile 1999 + end longFile + +set_option linter.style.longFileDefValue 400 + +/-- +warning: using 'exit' to interrupt Lean +--- +warning: The default value of the `longFile` linter is 400. +This file is 126 lines long which does not exceed the allowed bound. +Please, remove the `set_option linter.style.longFile 5000`. +-/ +#guard_msgs in +set_option linter.style.longFile 5000 in +#exit From ee226537119c803ac2a107a458a136994addf4d6 Mon Sep 17 00:00:00 2001 From: Johan Commelin Date: Wed, 16 Oct 2024 03:40:38 +0000 Subject: [PATCH 181/425] chore: remove CI check from adaptation PR script (#17534) Since we now pass an explicit commit hash to the script, pointing to a commit on `nightly-testing` that we want to use, there is no point in checking whether the HEAD of `nightly-testing` is still running CI. --- scripts/create-adaptation-pr.sh | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/scripts/create-adaptation-pr.sh b/scripts/create-adaptation-pr.sh index c64a006cbf1a37..dedae3ef45b500 100755 --- a/scripts/create-adaptation-pr.sh +++ b/scripts/create-adaptation-pr.sh @@ -72,24 +72,6 @@ if ! command -v gh &> /dev/null; then exit 1 fi -# Check the CI status of the latest commit on the 'nightly-testing' branch -status=$(gh run list --branch nightly-testing | grep -m1 . | awk '{print $1}') -if [ "$status" != "completed" ]; then - if [ "$status" != "in_progress" ]; then - echo "The latest commit on the 'nightly-testing' branch did not pass CI. Please fix the issues and try again." - gh run list --branch nightly-testing - exit 1 - else - if [ "$AUTO" = "yes" ]; then - echo "Auto mode enabled. Bailing out because the latest commit on 'nightly-testing' is still running CI." - exit 1 - else - echo "The latest commit on 'nightly-testing' is still running CI." - read -p "Press enter to continue, or ctrl-C if you'd prefer to wait for CI." - fi - fi -fi - echo "### Creating a PR for the nightly adaptation for $NIGHTLYDATE" echo From 90f515bcc5e411e49589e0c9c93c372ae520efb3 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 03:49:50 +0000 Subject: [PATCH 182/425] chore: move List.permutations material out of List.Perm (#17795) This moves some material off the longest pole. --- Mathlib/Algebra/BigOperators/Group/List.lean | 1 + .../SimpleGraph/Hamiltonian.lean | 5 +- Mathlib/Data/Fintype/List.lean | 1 + Mathlib/Data/Fintype/Perm.lean | 1 + Mathlib/Data/List/Perm.lean | 306 +----------------- Mathlib/Data/List/Permutation.lean | 292 ++++++++++++++++- Mathlib/GroupTheory/FreeGroup/Basic.lean | 1 - 7 files changed, 300 insertions(+), 307 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Group/List.lean b/Mathlib/Algebra/BigOperators/Group/List.lean index 7eb37c116a4055..42ca241b7d835a 100644 --- a/Mathlib/Algebra/BigOperators/Group/List.lean +++ b/Mathlib/Algebra/BigOperators/Group/List.lean @@ -13,6 +13,7 @@ import Mathlib.Data.List.ProdSigma import Mathlib.Data.List.Range import Mathlib.Data.List.Rotate import Mathlib.Data.List.Pairwise +import Mathlib.Data.List.Join /-! # Sums and products from lists diff --git a/Mathlib/Combinatorics/SimpleGraph/Hamiltonian.lean b/Mathlib/Combinatorics/SimpleGraph/Hamiltonian.lean index c5f35dfab6814d..3e0b8b7c61e0dc 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Hamiltonian.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Hamiltonian.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Bhavik Mehta, Rishi Mehta, Linus Sommer -/ import Mathlib.Algebra.Order.Ring.Nat +import Mathlib.Data.List.Count import Mathlib.Combinatorics.SimpleGraph.Path /-! @@ -78,9 +79,7 @@ lemma IsHamiltonianCycle.map {H : SimpleGraph β} (f : G →g H) (hf : Bijective (hp : p.IsHamiltonianCycle) : (p.map f).IsHamiltonianCycle where toIsCycle := hp.isCycle.map hf.injective isHamiltonian_tail := by - simp only [IsHamiltonian, support_tail, support_map, ne_eq, List.map_eq_nil_iff, support_ne_nil, - not_false_eq_true, List.count_tail, List.head_map, beq_iff_eq, hf.surjective.forall, - hf.injective, List.count_map_of_injective] + simp only [IsHamiltonian, hf.surjective.forall] intro x rcases p with (_ | ⟨y, p⟩) · cases hp.ne_nil rfl diff --git a/Mathlib/Data/Fintype/List.lean b/Mathlib/Data/Fintype/List.lean index 11d79be8c6f449..a93c79912ed442 100644 --- a/Mathlib/Data/Fintype/List.lean +++ b/Mathlib/Data/Fintype/List.lean @@ -5,6 +5,7 @@ Authors: Yakov Pechersky -/ import Mathlib.Data.Fintype.Basic import Mathlib.Data.Finset.Powerset +import Mathlib.Data.List.Permutation /-! diff --git a/Mathlib/Data/Fintype/Perm.lean b/Mathlib/Data/Fintype/Perm.lean index 47dbd625b6d70e..a37481050a9efe 100644 --- a/Mathlib/Data/Fintype/Perm.lean +++ b/Mathlib/Data/Fintype/Perm.lean @@ -6,6 +6,7 @@ Authors: Mario Carneiro import Mathlib.Data.Fintype.Card import Mathlib.GroupTheory.Perm.Basic import Mathlib.Tactic.Ring +import Mathlib.Data.Nat.Factorial.Basic /-! # `Fintype` instances for `Equiv` and `Perm` diff --git a/Mathlib/Data/List/Perm.lean b/Mathlib/Data/List/Perm.lean index be40ad9d20e430..8f5cb1997dd64e 100644 --- a/Mathlib/Data/List/Perm.lean +++ b/Mathlib/Data/List/Perm.lean @@ -3,20 +3,14 @@ Copyright (c) 2015 Microsoft Corporation. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Leonardo de Moura, Jeremy Avigad, Mario Carneiro -/ -import Mathlib.Data.List.Count import Mathlib.Data.List.Dedup -import Mathlib.Data.List.Duplicate -import Mathlib.Data.List.InsertNth import Mathlib.Data.List.Lattice -import Mathlib.Data.List.Permutation -import Mathlib.Data.Nat.Factorial.Basic import Batteries.Data.List.Perm /-! # List Permutations -This file introduces the `List.Perm` relation, which is true if two lists are permutations of one -another. +This file develops theory about the `List.Perm` relation. ## Notation @@ -36,13 +30,9 @@ instance : Trans (@List.Perm α) (@List.Perm α) List.Perm where open Perm (swap) -attribute [refl] Perm.refl - lemma perm_rfl : l ~ l := Perm.refl _ --- Porting note: used rec_on in mathlib3; lean4 eqn compiler still doesn't like it attribute [symm] Perm.symm - attribute [trans] Perm.trans theorem Perm.subset_congr_left {l₁ l₂ l₃ : List α} (h : l₁ ~ l₂) : l₁ ⊆ l₃ ↔ l₂ ⊆ l₃ := @@ -109,10 +99,6 @@ end Rel section Subperm - - -attribute [refl] Subperm.refl - attribute [trans] Subperm.trans end Subperm @@ -170,13 +156,15 @@ theorem Perm.foldr_op_eq {l₁ l₂ : List α} {a : α} (h : l₁ ~ l₂) : l₁ end -theorem perm_option_to_list {o₁ o₂ : Option α} : o₁.toList ~ o₂.toList ↔ o₁ = o₂ := by +theorem perm_option_toList {o₁ o₂ : Option α} : o₁.toList ~ o₂.toList ↔ o₁ = o₂ := by refine ⟨fun p => ?_, fun e => e ▸ Perm.refl _⟩ cases' o₁ with a <;> cases' o₂ with b; · rfl · cases p.length_eq · cases p.length_eq · exact Option.mem_toList.1 (p.symm.subset <| by simp) +@[deprecated (since := "2024-10-16")] alias perm_option_to_list := perm_option_toList + alias ⟨subperm.of_cons, subperm.cons⟩ := subperm_cons -- Porting note: commented out @@ -359,290 +347,4 @@ theorem Perm.dropSlice_inter [DecidableEq α] {xs ys : List α} (n m : ℕ) (h : · exact Perm.append (Perm.take_inter _ h h') (Perm.drop_inter _ h h') · exact disjoint_take_drop h₂ this --- enumerating permutations -section Permutations - -theorem perm_of_mem_permutationsAux : - ∀ {ts is l : List α}, l ∈ permutationsAux ts is → l ~ ts ++ is := by - show ∀ (ts is l : List α), l ∈ permutationsAux ts is → l ~ ts ++ is - refine permutationsAux.rec (by simp) ?_ - introv IH1 IH2 m - rw [permutationsAux_cons, permutations, mem_foldr_permutationsAux2] at m - rcases m with (m | ⟨l₁, l₂, m, _, rfl⟩) - · exact (IH1 _ m).trans perm_middle - · have p : l₁ ++ l₂ ~ is := by - simp only [mem_cons] at m - cases' m with e m - · simp [e] - exact is.append_nil ▸ IH2 _ m - exact ((perm_middle.trans (p.cons _)).append_right _).trans (perm_append_comm.cons _) - -theorem perm_of_mem_permutations {l₁ l₂ : List α} (h : l₁ ∈ permutations l₂) : l₁ ~ l₂ := - (eq_or_mem_of_mem_cons h).elim (fun e => e ▸ Perm.refl _) fun m => - append_nil l₂ ▸ perm_of_mem_permutationsAux m - -theorem length_permutationsAux : - ∀ ts is : List α, length (permutationsAux ts is) + is.length ! = (length ts + length is)! := by - refine permutationsAux.rec (by simp) ?_ - intro t ts is IH1 IH2 - have IH2 : length (permutationsAux is nil) + 1 = is.length ! := by simpa using IH2 - simp only [factorial, Nat.mul_comm, add_eq] at IH1 - rw [permutationsAux_cons, - length_foldr_permutationsAux2' _ _ _ _ _ fun l m => (perm_of_mem_permutations m).length_eq, - permutations, length, length, IH2, Nat.succ_add, Nat.factorial_succ, Nat.mul_comm (_ + 1), - ← Nat.succ_eq_add_one, ← IH1, Nat.add_comm (_ * _), Nat.add_assoc, Nat.mul_succ, Nat.mul_comm] - -theorem length_permutations (l : List α) : length (permutations l) = (length l)! := - length_permutationsAux l [] - -theorem mem_permutations_of_perm_lemma {is l : List α} - (H : l ~ [] ++ is → (∃ (ts' : _) (_ : ts' ~ []), l = ts' ++ is) ∨ l ∈ permutationsAux is []) : - l ~ is → l ∈ permutations is := by simpa [permutations, perm_nil] using H - -theorem mem_permutationsAux_of_perm : - ∀ {ts is l : List α}, - l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is := by - show ∀ (ts is l : List α), - l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is - refine permutationsAux.rec (by simp) ?_ - intro t ts is IH1 IH2 l p - rw [permutationsAux_cons, mem_foldr_permutationsAux2] - rcases IH1 _ (p.trans perm_middle) with (⟨is', p', e⟩ | m) - · clear p - subst e - rcases append_of_mem (p'.symm.subset (mem_cons_self _ _)) with ⟨l₁, l₂, e⟩ - subst is' - have p := (perm_middle.symm.trans p').cons_inv - cases' l₂ with a l₂' - · exact Or.inl ⟨l₁, by simpa using p⟩ - · exact Or.inr (Or.inr ⟨l₁, a :: l₂', mem_permutations_of_perm_lemma (IH2 _) p, by simp⟩) - · exact Or.inr (Or.inl m) - -@[simp] -theorem mem_permutations {s t : List α} : s ∈ permutations t ↔ s ~ t := - ⟨perm_of_mem_permutations, mem_permutations_of_perm_lemma mem_permutationsAux_of_perm⟩ - --- Porting note: temporary theorem to solve diamond issue -private theorem DecEq_eq [DecidableEq α] : - List.instBEq = @instBEqOfDecidableEq (List α) instDecidableEqList := - congr_arg BEq.mk <| by - funext l₁ l₂ - show (l₁ == l₂) = _ - rw [Bool.eq_iff_iff, @beq_iff_eq _ (_), decide_eq_true_iff] - -theorem perm_permutations'Aux_comm (a b : α) (l : List α) : - (permutations'Aux a l).bind (permutations'Aux b) ~ - (permutations'Aux b l).bind (permutations'Aux a) := by - induction' l with c l ih - · simp [swap] - simp only [permutations'Aux, bind_cons, map_cons, map_map, cons_append] - apply Perm.swap' - have : - ∀ a b, - (map (cons c) (permutations'Aux a l)).bind (permutations'Aux b) ~ - map (cons b ∘ cons c) (permutations'Aux a l) ++ - map (cons c) ((permutations'Aux a l).bind (permutations'Aux b)) := by - intros a' b' - simp only [bind_map, permutations'Aux] - show List.bind (permutations'Aux _ l) (fun a => ([b' :: c :: a] ++ - map (cons c) (permutations'Aux _ a))) ~ _ - refine (bind_append_perm _ (fun x => [b' :: c :: x]) _).symm.trans ?_ - rw [← map_eq_bind, ← map_bind] - exact Perm.refl _ - refine (((this _ _).append_left _).trans ?_).trans ((this _ _).append_left _).symm - rw [← append_assoc, ← append_assoc] - exact perm_append_comm.append (ih.map _) - -theorem Perm.permutations' {s t : List α} (p : s ~ t) : permutations' s ~ permutations' t := by - induction p with - | nil => simp - | cons _ _ IH => exact IH.bind_right _ - | swap => - dsimp - rw [bind_assoc, bind_assoc] - apply Perm.bind_left - intro l' _ - apply perm_permutations'Aux_comm - | trans _ _ IH₁ IH₂ => exact IH₁.trans IH₂ - -theorem permutations_perm_permutations' (ts : List α) : ts.permutations ~ ts.permutations' := by - obtain ⟨n, h⟩ : ∃ n, length ts < n := ⟨_, Nat.lt_succ_self _⟩ - induction' n with n IH generalizing ts; · cases h - refine List.reverseRecOn ts (fun _ => ?_) (fun ts t _ h => ?_) h; · simp [permutations] - rw [← concat_eq_append, length_concat, Nat.succ_lt_succ_iff] at h - have IH₂ := (IH ts.reverse (by rwa [length_reverse])).trans (reverse_perm _).permutations' - simp only [permutations_append, foldr_permutationsAux2, permutationsAux_nil, - permutationsAux_cons, append_nil] - refine - (perm_append_comm.trans ((IH₂.bind_right _).append ((IH _ h).map _))).trans - (Perm.trans ?_ perm_append_comm.permutations') - rw [map_eq_bind, singleton_append, permutations'] - refine (bind_append_perm _ _ _).trans ?_ - refine Perm.of_eq ?_ - congr - funext _ - rw [permutations'Aux_eq_permutationsAux2, permutationsAux2_append] - -@[simp] -theorem mem_permutations' {s t : List α} : s ∈ permutations' t ↔ s ~ t := - (permutations_perm_permutations' _).symm.mem_iff.trans mem_permutations - -theorem Perm.permutations {s t : List α} (h : s ~ t) : permutations s ~ permutations t := - (permutations_perm_permutations' _).trans <| - h.permutations'.trans (permutations_perm_permutations' _).symm - -@[simp] -theorem perm_permutations_iff {s t : List α} : permutations s ~ permutations t ↔ s ~ t := - ⟨fun h => mem_permutations.1 <| h.mem_iff.1 <| mem_permutations.2 (Perm.refl _), - Perm.permutations⟩ - -@[simp] -theorem perm_permutations'_iff {s t : List α} : permutations' s ~ permutations' t ↔ s ~ t := - ⟨fun h => mem_permutations'.1 <| h.mem_iff.1 <| mem_permutations'.2 (Perm.refl _), - Perm.permutations'⟩ - -theorem getElem_permutations'Aux (s : List α) (x : α) (n : ℕ) - (hn : n < length (permutations'Aux x s)) : - (permutations'Aux x s)[n] = s.insertNth n x := by - induction' s with y s IH generalizing n - · simp only [length, Nat.zero_add, Nat.lt_one_iff] at hn - simp [hn] - · cases n - · simp [get] - · simpa [get] using IH _ _ - -theorem get_permutations'Aux (s : List α) (x : α) (n : ℕ) - (hn : n < length (permutations'Aux x s)) : - (permutations'Aux x s).get ⟨n, hn⟩ = s.insertNth n x := by - simp [getElem_permutations'Aux] - -theorem count_permutations'Aux_self [DecidableEq α] (l : List α) (x : α) : - count (x :: l) (permutations'Aux x l) = length (takeWhile (x = ·) l) + 1 := by - induction' l with y l IH generalizing x - · simp [takeWhile, count] - · rw [permutations'Aux, count_cons_self] - by_cases hx : x = y - · subst hx - simpa [takeWhile, Nat.succ_inj', DecEq_eq] using IH _ - · rw [takeWhile] - simp only [mem_map, cons.injEq, Ne.symm hx, false_and, and_false, exists_false, - not_false_iff, count_eq_zero_of_not_mem, Nat.zero_add, hx, decide_False, length_nil] - -@[simp] -theorem length_permutations'Aux (s : List α) (x : α) : - length (permutations'Aux x s) = length s + 1 := by - induction' s with y s IH - · simp - · simpa using IH - -@[deprecated (since := "2024-06-12")] -theorem permutations'Aux_get_zero (s : List α) (x : α) - (hn : 0 < length (permutations'Aux x s) := (by simp)) : - (permutations'Aux x s).get ⟨0, hn⟩ = x :: s := - get_permutations'Aux _ _ _ _ - -theorem injective_permutations'Aux (x : α) : Function.Injective (permutations'Aux x) := by - intro s t h - apply insertNth_injective s.length x - have hl : s.length = t.length := by simpa using congr_arg length h - rw [← get_permutations'Aux s x s.length (by simp), - ← get_permutations'Aux t x s.length (by simp [hl])] - simp only [get_eq_getElem, h, hl] - -theorem nodup_permutations'Aux_of_not_mem (s : List α) (x : α) (hx : x ∉ s) : - Nodup (permutations'Aux x s) := by - induction' s with y s IH - · simp - · simp only [not_or, mem_cons] at hx - simp only [permutations'Aux, nodup_cons, mem_map, cons.injEq, exists_eq_right_right, not_and] - refine ⟨fun _ => Ne.symm hx.left, ?_⟩ - rw [nodup_map_iff] - · exact IH hx.right - · simp - -theorem nodup_permutations'Aux_iff {s : List α} {x : α} : Nodup (permutations'Aux x s) ↔ x ∉ s := by - refine ⟨fun h H ↦ ?_, nodup_permutations'Aux_of_not_mem _ _⟩ - obtain ⟨⟨k, hk⟩, hk'⟩ := get_of_mem H - rw [nodup_iff_injective_get] at h - apply k.succ_ne_self.symm - have kl : k < (permutations'Aux x s).length := by simpa [Nat.lt_succ_iff] using hk.le - have k1l : k + 1 < (permutations'Aux x s).length := by simpa using hk - rw [← @Fin.mk.inj_iff _ _ _ kl k1l]; apply h - rw [get_permutations'Aux, get_permutations'Aux] - have hl : length (insertNth k x s) = length (insertNth (k + 1) x s) := by - rw [length_insertNth _ _ hk.le, length_insertNth _ _ (Nat.succ_le_of_lt hk)] - refine ext_get hl fun n hn hn' => ?_ - rcases lt_trichotomy n k with (H | rfl | H) - · rw [get_insertNth_of_lt _ _ _ _ H (H.trans hk), - get_insertNth_of_lt _ _ _ _ (H.trans (Nat.lt_succ_self _))] - · rw [get_insertNth_self _ _ _ hk.le, get_insertNth_of_lt _ _ _ _ (Nat.lt_succ_self _) hk, hk'] - · rcases (Nat.succ_le_of_lt H).eq_or_lt with (rfl | H') - · rw [get_insertNth_self _ _ _ (Nat.succ_le_of_lt hk)] - convert hk' using 1 - exact get_insertNth_add_succ _ _ _ 0 _ - · obtain ⟨m, rfl⟩ := Nat.exists_eq_add_of_lt H' - rw [length_insertNth _ _ hk.le, Nat.succ_lt_succ_iff, Nat.succ_add] at hn - rw [get_insertNth_add_succ] - · convert get_insertNth_add_succ s x k m.succ (by simpa using hn) using 2 - · simp [Nat.add_assoc, Nat.add_left_comm] - · simp [Nat.add_left_comm, Nat.add_comm] - · simpa [Nat.succ_add] using hn - -theorem nodup_permutations (s : List α) (hs : Nodup s) : Nodup s.permutations := by - rw [(permutations_perm_permutations' s).nodup_iff] - induction' hs with x l h h' IH - · simp - · rw [permutations'] - rw [nodup_bind] - constructor - · intro ys hy - rw [mem_permutations'] at hy - rw [nodup_permutations'Aux_iff, hy.mem_iff] - exact fun H => h x H rfl - · refine IH.pairwise_of_forall_ne fun as ha bs hb H => ?_ - rw [disjoint_iff_ne] - rintro a ha' b hb' rfl - obtain ⟨⟨n, hn⟩, hn'⟩ := get_of_mem ha' - obtain ⟨⟨m, hm⟩, hm'⟩ := get_of_mem hb' - rw [mem_permutations'] at ha hb - have hl : as.length = bs.length := (ha.trans hb.symm).length_eq - simp only [Nat.lt_succ_iff, length_permutations'Aux] at hn hm - rw [get_permutations'Aux] at hn' hm' - have hx : - (insertNth n x as)[m]'(by rwa [length_insertNth _ _ hn, Nat.lt_succ_iff, hl]) = x := by - simp [hn', ← hm', hm] - have hx' : - (insertNth m x bs)[n]'(by rwa [length_insertNth _ _ hm, Nat.lt_succ_iff, ← hl]) = x := by - simp [hm', ← hn', hn] - rcases lt_trichotomy n m with (ht | ht | ht) - · suffices x ∈ bs by exact h x (hb.subset this) rfl - rw [← hx', getElem_insertNth_of_lt _ _ _ _ ht (ht.trans_le hm)] - exact get_mem _ _ _ - · simp only [ht] at hm' hn' - rw [← hm'] at hn' - exact H (insertNth_injective _ _ hn') - · suffices x ∈ as by exact h x (ha.subset this) rfl - rw [← hx, getElem_insertNth_of_lt _ _ _ _ ht (ht.trans_le hn)] - exact get_mem _ _ _ - -lemma permutations_take_two (x y : α) (s : List α) : - (x :: y :: s).permutations.take 2 = [x :: y :: s, y :: x :: s] := by - induction s <;> simp only [take, permutationsAux, permutationsAux.rec, permutationsAux2, id_eq] - -@[simp] -theorem nodup_permutations_iff {s : List α} : Nodup s.permutations ↔ Nodup s := by - refine ⟨?_, nodup_permutations s⟩ - contrapose - rw [← exists_duplicate_iff_not_nodup] - intro ⟨x, hs⟩ - rw [duplicate_iff_sublist] at hs - obtain ⟨l, ht⟩ := List.Sublist.exists_perm_append hs - rw [List.Perm.nodup_iff (List.Perm.permutations ht), ← exists_duplicate_iff_not_nodup] - use x :: x :: l - rw [List.duplicate_iff_sublist, ← permutations_take_two] - exact take_sublist 2 _ - --- TODO: `count s s.permutations = (zipWith count s s.tails).prod` -end Permutations - end List diff --git a/Mathlib/Data/List/Permutation.lean b/Mathlib/Data/List/Permutation.lean index a08663b6819164..f03f62f158c499 100644 --- a/Mathlib/Data/List/Permutation.lean +++ b/Mathlib/Data/List/Permutation.lean @@ -4,6 +4,14 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Parikshit Khanna, Jeremy Avigad, Leonardo de Moura, Floris van Doorn, Mario Carneiro -/ import Mathlib.Data.List.Join +import Mathlib.Data.Nat.Factorial.Basic +import Mathlib.Data.List.Count +import Mathlib.Data.List.Dedup +import Mathlib.Data.List.Duplicate +import Mathlib.Data.List.InsertNth +import Mathlib.Data.List.Lattice +import Mathlib.Data.List.Perm +import Batteries.Data.List.Perm /-! # Permutations of a list @@ -45,7 +53,7 @@ Show that `l.Nodup → l.permutations.Nodup`. See `Data.Fintype.List`. -- Make sure we don't import algebra assert_not_exists Monoid -open Nat +open Nat Function variable {α β : Type*} @@ -241,4 +249,286 @@ theorem permutations_append (is ts : List α) : permutations (is ++ ts) = (permutations is).map (· ++ ts) ++ permutationsAux ts is.reverse := by simp [permutations, permutationsAux_append] +theorem perm_of_mem_permutationsAux : + ∀ {ts is l : List α}, l ∈ permutationsAux ts is → l ~ ts ++ is := by + show ∀ (ts is l : List α), l ∈ permutationsAux ts is → l ~ ts ++ is + refine permutationsAux.rec (by simp) ?_ + introv IH1 IH2 m + rw [permutationsAux_cons, permutations, mem_foldr_permutationsAux2] at m + rcases m with (m | ⟨l₁, l₂, m, _, rfl⟩) + · exact (IH1 _ m).trans perm_middle + · have p : l₁ ++ l₂ ~ is := by + simp only [mem_cons] at m + cases' m with e m + · simp [e] + exact is.append_nil ▸ IH2 _ m + exact ((perm_middle.trans (p.cons _)).append_right _).trans (perm_append_comm.cons _) + +theorem perm_of_mem_permutations {l₁ l₂ : List α} (h : l₁ ∈ permutations l₂) : l₁ ~ l₂ := + (eq_or_mem_of_mem_cons h).elim (fun e => e ▸ Perm.refl _) fun m => + append_nil l₂ ▸ perm_of_mem_permutationsAux m + +theorem length_permutationsAux : + ∀ ts is : List α, length (permutationsAux ts is) + is.length ! = (length ts + length is)! := by + refine permutationsAux.rec (by simp) ?_ + intro t ts is IH1 IH2 + have IH2 : length (permutationsAux is nil) + 1 = is.length ! := by simpa using IH2 + simp only [factorial, Nat.mul_comm, add_eq] at IH1 + rw [permutationsAux_cons, + length_foldr_permutationsAux2' _ _ _ _ _ fun l m => (perm_of_mem_permutations m).length_eq, + permutations, length, length, IH2, Nat.succ_add, Nat.factorial_succ, Nat.mul_comm (_ + 1), + ← Nat.succ_eq_add_one, ← IH1, Nat.add_comm (_ * _), Nat.add_assoc, Nat.mul_succ, Nat.mul_comm] + +theorem length_permutations (l : List α) : length (permutations l) = (length l)! := + length_permutationsAux l [] + +theorem mem_permutations_of_perm_lemma {is l : List α} + (H : l ~ [] ++ is → (∃ (ts' : _) (_ : ts' ~ []), l = ts' ++ is) ∨ l ∈ permutationsAux is []) : + l ~ is → l ∈ permutations is := by simpa [permutations, perm_nil] using H + +theorem mem_permutationsAux_of_perm : + ∀ {ts is l : List α}, + l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is := by + show ∀ (ts is l : List α), + l ~ is ++ ts → (∃ (is' : _) (_ : is' ~ is), l = is' ++ ts) ∨ l ∈ permutationsAux ts is + refine permutationsAux.rec (by simp) ?_ + intro t ts is IH1 IH2 l p + rw [permutationsAux_cons, mem_foldr_permutationsAux2] + rcases IH1 _ (p.trans perm_middle) with (⟨is', p', e⟩ | m) + · clear p + subst e + rcases append_of_mem (p'.symm.subset (mem_cons_self _ _)) with ⟨l₁, l₂, e⟩ + subst is' + have p := (perm_middle.symm.trans p').cons_inv + cases' l₂ with a l₂' + · exact Or.inl ⟨l₁, by simpa using p⟩ + · exact Or.inr (Or.inr ⟨l₁, a :: l₂', mem_permutations_of_perm_lemma (IH2 _) p, by simp⟩) + · exact Or.inr (Or.inl m) + +@[simp] +theorem mem_permutations {s t : List α} : s ∈ permutations t ↔ s ~ t := + ⟨perm_of_mem_permutations, mem_permutations_of_perm_lemma mem_permutationsAux_of_perm⟩ + +-- Porting note: temporary theorem to solve diamond issue +private theorem DecEq_eq [DecidableEq α] : + List.instBEq = @instBEqOfDecidableEq (List α) instDecidableEqList := + congr_arg BEq.mk <| by + funext l₁ l₂ + show (l₁ == l₂) = _ + rw [Bool.eq_iff_iff, @beq_iff_eq _ (_), decide_eq_true_iff] + +theorem perm_permutations'Aux_comm (a b : α) (l : List α) : + (permutations'Aux a l).bind (permutations'Aux b) ~ + (permutations'Aux b l).bind (permutations'Aux a) := by + induction' l with c l ih + · exact Perm.swap [a, b] [b, a] [] + simp only [permutations'Aux, bind_cons, map_cons, map_map, cons_append] + apply Perm.swap' + have : + ∀ a b, + (map (cons c) (permutations'Aux a l)).bind (permutations'Aux b) ~ + map (cons b ∘ cons c) (permutations'Aux a l) ++ + map (cons c) ((permutations'Aux a l).bind (permutations'Aux b)) := by + intros a' b' + simp only [bind_map, permutations'Aux] + show List.bind (permutations'Aux _ l) (fun a => ([b' :: c :: a] ++ + map (cons c) (permutations'Aux _ a))) ~ _ + refine (bind_append_perm _ (fun x => [b' :: c :: x]) _).symm.trans ?_ + rw [← map_eq_bind, ← map_bind] + exact Perm.refl _ + refine (((this _ _).append_left _).trans ?_).trans ((this _ _).append_left _).symm + rw [← append_assoc, ← append_assoc] + exact perm_append_comm.append (ih.map _) + +theorem Perm.permutations' {s t : List α} (p : s ~ t) : permutations' s ~ permutations' t := by + induction p with + | nil => simp + | cons _ _ IH => exact IH.bind_right _ + | swap => + dsimp + rw [bind_assoc, bind_assoc] + apply Perm.bind_left + intro l' _ + apply perm_permutations'Aux_comm + | trans _ _ IH₁ IH₂ => exact IH₁.trans IH₂ + +theorem permutations_perm_permutations' (ts : List α) : ts.permutations ~ ts.permutations' := by + obtain ⟨n, h⟩ : ∃ n, length ts < n := ⟨_, Nat.lt_succ_self _⟩ + induction' n with n IH generalizing ts; · cases h + refine List.reverseRecOn ts (fun _ => ?_) (fun ts t _ h => ?_) h; · simp [permutations] + rw [← concat_eq_append, length_concat, Nat.succ_lt_succ_iff] at h + have IH₂ := (IH ts.reverse (by rwa [length_reverse])).trans (reverse_perm _).permutations' + simp only [permutations_append, foldr_permutationsAux2, permutationsAux_nil, + permutationsAux_cons, append_nil] + refine + (perm_append_comm.trans ((IH₂.bind_right _).append ((IH _ h).map _))).trans + (Perm.trans ?_ perm_append_comm.permutations') + rw [map_eq_bind, singleton_append, permutations'] + refine (bind_append_perm _ _ _).trans ?_ + refine Perm.of_eq ?_ + congr + funext _ + rw [permutations'Aux_eq_permutationsAux2, permutationsAux2_append] + +@[simp] +theorem mem_permutations' {s t : List α} : s ∈ permutations' t ↔ s ~ t := + (permutations_perm_permutations' _).symm.mem_iff.trans mem_permutations + +theorem Perm.permutations {s t : List α} (h : s ~ t) : permutations s ~ permutations t := + (permutations_perm_permutations' _).trans <| + h.permutations'.trans (permutations_perm_permutations' _).symm + +@[simp] +theorem perm_permutations_iff {s t : List α} : permutations s ~ permutations t ↔ s ~ t := + ⟨fun h => mem_permutations.1 <| h.mem_iff.1 <| mem_permutations.2 (Perm.refl _), + Perm.permutations⟩ + +@[simp] +theorem perm_permutations'_iff {s t : List α} : permutations' s ~ permutations' t ↔ s ~ t := + ⟨fun h => mem_permutations'.1 <| h.mem_iff.1 <| mem_permutations'.2 (Perm.refl _), + Perm.permutations'⟩ + +theorem getElem_permutations'Aux (s : List α) (x : α) (n : ℕ) + (hn : n < length (permutations'Aux x s)) : + (permutations'Aux x s)[n] = s.insertNth n x := by + induction' s with y s IH generalizing n + · simp only [length, Nat.zero_add, Nat.lt_one_iff] at hn + simp [hn] + · cases n + · simp [get] + · simpa [get] using IH _ _ + +theorem get_permutations'Aux (s : List α) (x : α) (n : ℕ) + (hn : n < length (permutations'Aux x s)) : + (permutations'Aux x s).get ⟨n, hn⟩ = s.insertNth n x := by + simp [getElem_permutations'Aux] + +theorem count_permutations'Aux_self [DecidableEq α] (l : List α) (x : α) : + count (x :: l) (permutations'Aux x l) = length (takeWhile (x = ·) l) + 1 := by + induction' l with y l IH generalizing x + · simp [takeWhile, count] + · rw [permutations'Aux, count_cons_self] + by_cases hx : x = y + · subst hx + simpa [takeWhile, Nat.succ_inj', DecEq_eq] using IH _ + · rw [takeWhile] + simp only [mem_map, cons.injEq, Ne.symm hx, false_and, and_false, exists_false, + not_false_iff, count_eq_zero_of_not_mem, Nat.zero_add, hx, decide_False, length_nil] + +@[simp] +theorem length_permutations'Aux (s : List α) (x : α) : + length (permutations'Aux x s) = length s + 1 := by + induction' s with y s IH + · simp + · simpa using IH + +@[deprecated (since := "2024-06-12")] +theorem permutations'Aux_get_zero (s : List α) (x : α) + (hn : 0 < length (permutations'Aux x s) := (by simp)) : + (permutations'Aux x s).get ⟨0, hn⟩ = x :: s := + get_permutations'Aux _ _ _ _ + +theorem injective_permutations'Aux (x : α) : Function.Injective (permutations'Aux x) := by + intro s t h + apply insertNth_injective s.length x + have hl : s.length = t.length := by simpa using congr_arg length h + rw [← get_permutations'Aux s x s.length (by simp), + ← get_permutations'Aux t x s.length (by simp [hl])] + simp only [get_eq_getElem, h, hl] + +theorem nodup_permutations'Aux_of_not_mem (s : List α) (x : α) (hx : x ∉ s) : + Nodup (permutations'Aux x s) := by + induction' s with y s IH + · simp + · simp only [not_or, mem_cons] at hx + simp only [permutations'Aux, nodup_cons, mem_map, cons.injEq, exists_eq_right_right, not_and] + refine ⟨fun _ => Ne.symm hx.left, ?_⟩ + rw [nodup_map_iff] + · exact IH hx.right + · simp + +theorem nodup_permutations'Aux_iff {s : List α} {x : α} : Nodup (permutations'Aux x s) ↔ x ∉ s := by + refine ⟨fun h H ↦ ?_, nodup_permutations'Aux_of_not_mem _ _⟩ + obtain ⟨⟨k, hk⟩, hk'⟩ := get_of_mem H + rw [nodup_iff_injective_get] at h + apply k.succ_ne_self.symm + have kl : k < (permutations'Aux x s).length := by simpa [Nat.lt_succ_iff] using hk.le + have k1l : k + 1 < (permutations'Aux x s).length := by simpa using hk + rw [← @Fin.mk.inj_iff _ _ _ kl k1l]; apply h + rw [get_permutations'Aux, get_permutations'Aux] + have hl : length (insertNth k x s) = length (insertNth (k + 1) x s) := by + rw [length_insertNth _ _ hk.le, length_insertNth _ _ (Nat.succ_le_of_lt hk)] + refine ext_get hl fun n hn hn' => ?_ + rcases lt_trichotomy n k with (H | rfl | H) + · rw [get_insertNth_of_lt _ _ _ _ H (H.trans hk), + get_insertNth_of_lt _ _ _ _ (H.trans (Nat.lt_succ_self _))] + · rw [get_insertNth_self _ _ _ hk.le, get_insertNth_of_lt _ _ _ _ (Nat.lt_succ_self _) hk, hk'] + · rcases (Nat.succ_le_of_lt H).eq_or_lt with (rfl | H') + · rw [get_insertNth_self _ _ _ (Nat.succ_le_of_lt hk)] + convert hk' using 1 + exact get_insertNth_add_succ _ _ _ 0 _ + · obtain ⟨m, rfl⟩ := Nat.exists_eq_add_of_lt H' + rw [length_insertNth _ _ hk.le, Nat.succ_lt_succ_iff, Nat.succ_add] at hn + rw [get_insertNth_add_succ] + · convert get_insertNth_add_succ s x k m.succ (by simpa using hn) using 2 + · simp [Nat.add_assoc, Nat.add_left_comm] + · simp [Nat.add_left_comm, Nat.add_comm] + · simpa [Nat.succ_add] using hn + +theorem nodup_permutations (s : List α) (hs : Nodup s) : Nodup s.permutations := by + rw [(permutations_perm_permutations' s).nodup_iff] + induction' hs with x l h h' IH + · simp + · rw [permutations'] + rw [nodup_bind] + constructor + · intro ys hy + rw [mem_permutations'] at hy + rw [nodup_permutations'Aux_iff, hy.mem_iff] + exact fun H => h x H rfl + · refine IH.pairwise_of_forall_ne fun as ha bs hb H => ?_ + rw [disjoint_iff_ne] + rintro a ha' b hb' rfl + obtain ⟨⟨n, hn⟩, hn'⟩ := get_of_mem ha' + obtain ⟨⟨m, hm⟩, hm'⟩ := get_of_mem hb' + rw [mem_permutations'] at ha hb + have hl : as.length = bs.length := (ha.trans hb.symm).length_eq + simp only [Nat.lt_succ_iff, length_permutations'Aux] at hn hm + rw [get_permutations'Aux] at hn' hm' + have hx : + (insertNth n x as)[m]'(by rwa [length_insertNth _ _ hn, Nat.lt_succ_iff, hl]) = x := by + simp [hn', ← hm', hm] + have hx' : + (insertNth m x bs)[n]'(by rwa [length_insertNth _ _ hm, Nat.lt_succ_iff, ← hl]) = x := by + simp [hm', ← hn', hn] + rcases lt_trichotomy n m with (ht | ht | ht) + · suffices x ∈ bs by exact h x (hb.subset this) rfl + rw [← hx', getElem_insertNth_of_lt _ _ _ _ ht (ht.trans_le hm)] + exact get_mem _ _ _ + · simp only [ht] at hm' hn' + rw [← hm'] at hn' + exact H (insertNth_injective _ _ hn') + · suffices x ∈ as by exact h x (ha.subset this) rfl + rw [← hx, getElem_insertNth_of_lt _ _ _ _ ht (ht.trans_le hn)] + exact get_mem _ _ _ + +lemma permutations_take_two (x y : α) (s : List α) : + (x :: y :: s).permutations.take 2 = [x :: y :: s, y :: x :: s] := by + induction s <;> simp only [take, permutationsAux, permutationsAux.rec, permutationsAux2, id_eq] + +@[simp] +theorem nodup_permutations_iff {s : List α} : Nodup s.permutations ↔ Nodup s := by + refine ⟨?_, nodup_permutations s⟩ + contrapose + rw [← exists_duplicate_iff_not_nodup] + intro ⟨x, hs⟩ + rw [duplicate_iff_sublist] at hs + obtain ⟨l, ht⟩ := List.Sublist.exists_perm_append hs + rw [List.Perm.nodup_iff (List.Perm.permutations ht), ← exists_duplicate_iff_not_nodup] + use x :: x :: l + rw [List.duplicate_iff_sublist, ← permutations_take_two] + exact take_sublist 2 _ + +-- TODO: `count s s.permutations = (zipWith count s s.tails).prod` + end List diff --git a/Mathlib/GroupTheory/FreeGroup/Basic.lean b/Mathlib/GroupTheory/FreeGroup/Basic.lean index 390e31eeb995b3..fea26c87878b21 100644 --- a/Mathlib/GroupTheory/FreeGroup/Basic.lean +++ b/Mathlib/GroupTheory/FreeGroup/Basic.lean @@ -6,7 +6,6 @@ Authors: Kenny Lau import Mathlib.Algebra.Group.Subgroup.Basic import Mathlib.Data.Fintype.Basic import Mathlib.Data.List.Sublists -import Mathlib.Data.List.InsertNth /-! # Free groups From 429ffd90a5d54e7a9c3463d91b9e48dc50c46a84 Mon Sep 17 00:00:00 2001 From: Johan Commelin Date: Wed, 16 Oct 2024 03:49:51 +0000 Subject: [PATCH 183/425] chore: remove porting notes about dangerous_instance linter (#17798) This is now handled by the "cannot find synthesization order" error. See the explanation at #12094 for more details. --- Mathlib/Algebra/AddTorsor.lean | 3 --- Mathlib/Algebra/Ring/CompTypeclasses.lean | 3 --- Mathlib/Analysis/RCLike/Lemmas.lean | 2 -- Mathlib/Topology/Algebra/Module/Basic.lean | 4 ---- Mathlib/Topology/Algebra/Valued/ValuationTopology.lean | 3 --- 5 files changed, 15 deletions(-) diff --git a/Mathlib/Algebra/AddTorsor.lean b/Mathlib/Algebra/AddTorsor.lean index ed65a54d0f15f9..38aff47034d893 100644 --- a/Mathlib/Algebra/AddTorsor.lean +++ b/Mathlib/Algebra/AddTorsor.lean @@ -54,9 +54,6 @@ class AddTorsor (G : outParam Type*) (P : Type*) [AddGroup G] extends AddAction -- Porting note(#12096): removed `nolint instance_priority`; lint not ported yet attribute [instance 100] AddTorsor.nonempty --- Porting note(#12094): removed nolint; dangerous_instance linter not ported yet ---attribute [nolint dangerous_instance] AddTorsor.toVSub - /-- An `AddGroup G` is a torsor for itself. -/ -- Porting note(#12096): linter not ported yet --@[nolint instance_priority] diff --git a/Mathlib/Algebra/Ring/CompTypeclasses.lean b/Mathlib/Algebra/Ring/CompTypeclasses.lean index e6fce8299f6a43..7ab747f493635e 100644 --- a/Mathlib/Algebra/Ring/CompTypeclasses.lean +++ b/Mathlib/Algebra/Ring/CompTypeclasses.lean @@ -156,9 +156,6 @@ theorem RingHom.surjective (σ : R₁ →+* R₂) [t : RingHomSurjective σ] : F namespace RingHomSurjective --- The linter gives a false positive, since `σ₂` is an out_param --- Porting note(#12094): removed nolint; dangerous_instance linter not ported yet --- @[nolint dangerous_instance] instance (priority := 100) invPair {σ₁ : R₁ →+* R₂} {σ₂ : R₂ →+* R₁} [RingHomInvPair σ₁ σ₂] : RingHomSurjective σ₁ := ⟨fun x => ⟨σ₂ x, RingHomInvPair.comp_apply_eq₂⟩⟩ diff --git a/Mathlib/Analysis/RCLike/Lemmas.lean b/Mathlib/Analysis/RCLike/Lemmas.lean index 9c307a9be695f0..0603a4fda4c16a 100644 --- a/Mathlib/Analysis/RCLike/Lemmas.lean +++ b/Mathlib/Analysis/RCLike/Lemmas.lean @@ -31,8 +31,6 @@ This instance generates a type-class problem with a metavariable `?m` that shoul `RCLike ?m`. Since this can only be satisfied by `ℝ` or `ℂ`, this does not cause problems. -/ /-- An `RCLike` field is finite-dimensional over `ℝ`, since it is spanned by `{1, I}`. -/ --- Porting note(#12094): removed nolint; dangerous_instance linter not ported yet --- @[nolint dangerous_instance] instance rclike_to_real : FiniteDimensional ℝ K := ⟨{1, I}, by suffices ∀ x : K, ∃ a b : ℝ, a • 1 + b • I = x by diff --git a/Mathlib/Topology/Algebra/Module/Basic.lean b/Mathlib/Topology/Algebra/Module/Basic.lean index a1479380641d59..c5fd7f2684f753 100644 --- a/Mathlib/Topology/Algebra/Module/Basic.lean +++ b/Mathlib/Topology/Algebra/Module/Basic.lean @@ -245,10 +245,6 @@ class ContinuousSemilinearMapClass (F : Type*) {R S : outParam Type*} [Semiring [Module S M₂] [FunLike F M M₂] extends SemilinearMapClass F σ M M₂, ContinuousMapClass F M M₂ : Prop --- `σ`, `R` and `S` become metavariables, but they are all outparams so it's OK --- Porting note(#12094): removed nolint; dangerous_instance linter not ported yet --- attribute [nolint dangerous_instance] ContinuousSemilinearMapClass.toContinuousMapClass - /-- `ContinuousLinearMapClass F R M M₂` asserts `F` is a type of bundled continuous `R`-linear maps `M → M₂`. This is an abbreviation for `ContinuousSemilinearMapClass F (RingHom.id R) M M₂`. -/ diff --git a/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean b/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean index 22bb1f84d63f67..8cdff99b6d7feb 100644 --- a/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean +++ b/Mathlib/Topology/Algebra/Valued/ValuationTopology.lean @@ -89,9 +89,6 @@ class Valued (R : Type u) [Ring R] (Γ₀ : outParam (Type v)) v : Valuation R Γ₀ is_topological_valuation : ∀ s, s ∈ 𝓝 (0 : R) ↔ ∃ γ : Γ₀ˣ, { x : R | v x < γ } ⊆ s --- Porting note(#12094): removed nolint; dangerous_instance linter not ported yet ---attribute [nolint dangerous_instance] Valued.toUniformSpace - namespace Valued /-- Alternative `Valued` constructor for use when there is no preferred `UniformSpace` structure. -/ From 264cb92bc96c0f0e1a92ea20524a1de270b3f008 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 15:26:50 +1100 Subject: [PATCH 184/425] shake --update --- scripts/noshake.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/noshake.json b/scripts/noshake.json index 681e7f87ee2b5b..75da1806f1ee3e 100644 --- a/scripts/noshake.json +++ b/scripts/noshake.json @@ -344,20 +344,21 @@ "Mathlib.Lean.Meta": ["Batteries.Logic"], "Mathlib.Lean.Expr.ExtraRecognizers": ["Mathlib.Data.Set.Operations"], "Mathlib.Lean.Expr.Basic": ["Batteries.Logic"], - "Mathlib.Deprecated.NatLemmas": ["Batteries.Data.Nat.Lemmas", "Batteries.WF"], "Mathlib.GroupTheory.MonoidLocalization.Basic": ["Mathlib.Init.Data.Prod"], "Mathlib.Geometry.Manifold.Sheaf.Smooth": ["Mathlib.CategoryTheory.Sites.Whiskering"], "Mathlib.Geometry.Manifold.PoincareConjecture": ["Mathlib.AlgebraicTopology.FundamentalGroupoid.SimplyConnected", "Mathlib.Util.Superscript"], + "Mathlib.Deprecated.NatLemmas": ["Batteries.Data.Nat.Lemmas", "Batteries.WF"], "Mathlib.Deprecated.MinMax": ["Mathlib.Order.MinMax"], "Mathlib.Data.Vector.Basic": ["Mathlib.Control.Applicative"], "Mathlib.Data.Set.Image": ["Batteries.Tactic.Congr"], "Mathlib.Data.Seq.Parallel": ["Mathlib.Init.Data.Prod"], "Mathlib.Data.PEquiv": ["Batteries.Tactic.Congr"], "Mathlib.Data.Ordmap.Ordnode": ["Mathlib.Data.Option.Basic"], - "Mathlib.Data.Option.NAry": ["Batteries.Tactic.Init"], + "Mathlib.Data.Option.NAry": + ["Batteries.Tactic.Init", "Mathlib.Logic.Function.Defs"], "Mathlib.Data.Nat.Find": ["Batteries.WF"], "Mathlib.Data.Multiset.Bind": ["Mathlib.Algebra.GroupWithZero.Action.Defs"], "Mathlib.Data.List.TFAE": ["Batteries.Tactic.Classical"], From cd420019adaa2bae41db808baa9cbe8ecb11215e Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Wed, 16 Oct 2024 04:28:20 +0000 Subject: [PATCH 185/425] Trigger CI for https://github.com/leanprover/lean4/pull/5694 --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 6dc97077d66899..7ca16287fbf192 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "5742b12a435f2a3074de2620bc839905a5b7ae6a", + "rev": "e8c146e77ce3c575c3966766f9d4f9ca4366f566", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "lean-pr-testing-5694", From e13443845247e3decf89be779cfead9ba7f6dafb Mon Sep 17 00:00:00 2001 From: Jz Pan Date: Wed, 16 Oct 2024 04:43:22 +0000 Subject: [PATCH 186/425] feat: add `[s|i]sup_toXXX` for intermediate fields and subalgebras (#15088) - `IntermediateField.[s|i]sup_toSubfield` which states that the `sup`, `sSup` and `iSup` for `IntermediateField` is the same as for `Subfield`. - `Algebra.[s|i]sup_toSubsemiring` which states that the `sup`, `sSup` and `iSup` for `Subalgebra` is the same as for `Subsemiring`. - Also add a missing `Algebra.iInf_toSubsemiring`. --- Mathlib/Algebra/Algebra/Subalgebra/Basic.lean | 41 +++++++++++++++++++ Mathlib/FieldTheory/Adjoin.lean | 39 ++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean b/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean index 9f3d2d832688e6..8e6c9f2dc91ced 100644 --- a/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean +++ b/Mathlib/Algebra/Algebra/Subalgebra/Basic.lean @@ -614,6 +614,7 @@ variable (R : Type u) {A : Type v} {B : Type w} variable [CommSemiring R] [Semiring A] [Algebra R A] [Semiring B] [Algebra R B] /-- The minimal subalgebra that includes `s`. -/ +@[simps toSubsemiring] def adjoin (s : Set A) : Subalgebra R A := { Subsemiring.closure (Set.range (algebraMap R A) ∪ s) with algebraMap_mem' := fun r => Subsemiring.subset_closure <| Or.inl ⟨r, rfl⟩ } @@ -637,6 +638,10 @@ instance : CompleteLattice (Subalgebra R A) where bot := (Algebra.ofId R A).range bot_le _S := fun _a ⟨_r, hr⟩ => hr ▸ algebraMap_mem _ _ +theorem sup_def (S T : Subalgebra R A) : S ⊔ T = adjoin R (S ∪ T : Set A) := rfl + +theorem sSup_def (S : Set (Subalgebra R A)) : sSup S = adjoin R (⋃₀ (SetLike.coe '' S)) := rfl + @[simp] theorem coe_top : (↑(⊤ : Subalgebra R A) : Set A) = Set.univ := rfl @@ -697,6 +702,16 @@ theorem inf_toSubsemiring (S T : Subalgebra R A) : (S ⊓ T).toSubsemiring = S.toSubsemiring ⊓ T.toSubsemiring := rfl +@[simp] +theorem sup_toSubsemiring (S T : Subalgebra R A) : + (S ⊔ T).toSubsemiring = S.toSubsemiring ⊔ T.toSubsemiring := by + rw [← S.toSubsemiring.closure_eq, ← T.toSubsemiring.closure_eq, ← Subsemiring.closure_union] + simp_rw [sup_def, adjoin_toSubsemiring, Subalgebra.coe_toSubsemiring] + congr 1 + rw [Set.union_eq_right] + rintro _ ⟨x, rfl⟩ + exact Set.mem_union_left _ (algebraMap_mem S x) + @[simp, norm_cast] theorem coe_sInf (S : Set (Subalgebra R A)) : (↑(sInf S) : Set A) = ⋂ s ∈ S, ↑s := sInf_image @@ -714,6 +729,22 @@ theorem sInf_toSubsemiring (S : Set (Subalgebra R A)) : (sInf S).toSubsemiring = sInf (Subalgebra.toSubsemiring '' S) := SetLike.coe_injective <| by simp +open Subalgebra in +@[simp] +theorem sSup_toSubsemiring (S : Set (Subalgebra R A)) (hS : S.Nonempty) : + (sSup S).toSubsemiring = sSup (toSubsemiring '' S) := by + have h : toSubsemiring '' S = Subsemiring.closure '' (SetLike.coe '' S) := by + rw [Set.image_image] + congr! with x + exact x.toSubsemiring.closure_eq.symm + rw [h, sSup_image, ← Subsemiring.closure_sUnion, sSup_def, adjoin_toSubsemiring] + congr 1 + rw [Set.union_eq_right] + rintro _ ⟨x, rfl⟩ + obtain ⟨y, hy⟩ := hS + simp only [Set.mem_sUnion, Set.mem_image, exists_exists_and_eq_and, SetLike.mem_coe] + exact ⟨y, hy, algebraMap_mem y x⟩ + @[simp, norm_cast] theorem coe_iInf {ι : Sort*} {S : ι → Subalgebra R A} : (↑(⨅ i, S i) : Set A) = ⋂ i, S i := by simp [iInf] @@ -732,6 +763,16 @@ theorem iInf_toSubmodule {ι : Sort*} (S : ι → Subalgebra R A) : toSubmodule (⨅ i, S i) = ⨅ i, toSubmodule (S i) := SetLike.coe_injective <| by simp +@[simp] +theorem iInf_toSubsemiring {ι : Sort*} (S : ι → Subalgebra R A) : + (iInf S).toSubsemiring = ⨅ i, (S i).toSubsemiring := by + simp only [iInf, sInf_toSubsemiring, ← Set.range_comp, Function.comp_def] + +@[simp] +theorem iSup_toSubsemiring {ι : Sort*} [Nonempty ι] (S : ι → Subalgebra R A) : + (iSup S).toSubsemiring = ⨆ i, (S i).toSubsemiring := by + simp only [iSup, Set.range_nonempty, sSup_toSubsemiring, ← Set.range_comp, Function.comp_def] + instance : Inhabited (Subalgebra R A) := ⟨⊥⟩ theorem mem_bot {x : A} : x ∈ (⊥ : Subalgebra R A) ↔ x ∈ Set.range (algebraMap R A) := Iff.rfl diff --git a/Mathlib/FieldTheory/Adjoin.lean b/Mathlib/FieldTheory/Adjoin.lean index 204fdd29bf1e46..3fa951422ab8a5 100644 --- a/Mathlib/FieldTheory/Adjoin.lean +++ b/Mathlib/FieldTheory/Adjoin.lean @@ -42,6 +42,10 @@ def adjoin : IntermediateField F E := { Subfield.closure (Set.range (algebraMap F E) ∪ S) with algebraMap_mem' := fun x => Subfield.subset_closure (Or.inl (Set.mem_range_self x)) } +@[simp] +theorem adjoin_toSubfield : + (adjoin F S).toSubfield = Subfield.closure (Set.range (algebraMap F E) ∪ S) := rfl + variable {S} theorem mem_adjoin_iff (x : E) : @@ -90,6 +94,11 @@ instance : CompleteLattice (IntermediateField F E) where inv_mem' := by rintro x ⟨r, rfl⟩; exact ⟨r⁻¹, map_inv₀ _ _⟩ } bot_le x := (bot_le : ⊥ ≤ x.toSubalgebra) +theorem sup_def (S T : IntermediateField F E) : S ⊔ T = adjoin F (S ∪ T : Set E) := rfl + +theorem sSup_def (S : Set (IntermediateField F E)) : + sSup S = adjoin F (⋃₀ (SetLike.coe '' S)) := rfl + instance : Inhabited (IntermediateField F E) := ⟨⊤⟩ @@ -139,6 +148,16 @@ theorem inf_toSubfield (S T : IntermediateField F E) : (S ⊓ T).toSubfield = S.toSubfield ⊓ T.toSubfield := rfl +@[simp] +theorem sup_toSubfield (S T : IntermediateField F E) : + (S ⊔ T).toSubfield = S.toSubfield ⊔ T.toSubfield := by + rw [← S.toSubfield.closure_eq, ← T.toSubfield.closure_eq, ← Subfield.closure_union] + simp_rw [sup_def, adjoin_toSubfield, coe_toSubfield] + congr 1 + rw [Set.union_eq_right] + rintro _ ⟨x, rfl⟩ + exact Set.mem_union_left _ (algebraMap_mem S x) + @[simp, norm_cast] theorem coe_sInf (S : Set (IntermediateField F E)) : (↑(sInf S) : Set E) = sInf ((fun (x : IntermediateField F E) => (x : Set E)) '' S) := @@ -154,6 +173,21 @@ theorem sInf_toSubfield (S : Set (IntermediateField F E)) : (sInf S).toSubfield = sInf (toSubfield '' S) := SetLike.coe_injective <| by simp [Set.sUnion_image] +@[simp] +theorem sSup_toSubfield (S : Set (IntermediateField F E)) (hS : S.Nonempty) : + (sSup S).toSubfield = sSup (toSubfield '' S) := by + have h : toSubfield '' S = Subfield.closure '' (SetLike.coe '' S) := by + rw [Set.image_image] + congr! with x + exact x.toSubfield.closure_eq.symm + rw [h, sSup_image, ← Subfield.closure_sUnion, sSup_def, adjoin_toSubfield] + congr 1 + rw [Set.union_eq_right] + rintro _ ⟨x, rfl⟩ + obtain ⟨y, hy⟩ := hS + simp only [Set.mem_sUnion, Set.mem_image, exists_exists_and_eq_and, SetLike.mem_coe] + exact ⟨y, hy, algebraMap_mem y x⟩ + @[simp, norm_cast] theorem coe_iInf {ι : Sort*} (S : ι → IntermediateField F E) : (↑(iInf S) : Set E) = ⋂ i, S i := by simp [iInf] @@ -168,6 +202,11 @@ theorem iInf_toSubfield {ι : Sort*} (S : ι → IntermediateField F E) : (iInf S).toSubfield = ⨅ i, (S i).toSubfield := SetLike.coe_injective <| by simp [iInf] +@[simp] +theorem iSup_toSubfield {ι : Sort*} [Nonempty ι] (S : ι → IntermediateField F E) : + (iSup S).toSubfield = ⨆ i, (S i).toSubfield := by + simp only [iSup, Set.range_nonempty, sSup_toSubfield, ← Set.range_comp, Function.comp_def] + /-- Construct an algebra isomorphism from an equality of intermediate fields -/ @[simps! apply] def equivOfEq {S T : IntermediateField F E} (h : S = T) : S ≃ₐ[F] T := From 66d4c59d16a2dc822498b144b744dfaa6823f3e0 Mon Sep 17 00:00:00 2001 From: Dagur Asgeirsson Date: Wed, 16 Oct 2024 04:43:24 +0000 Subject: [PATCH 187/425] feat(Condensed): colimit characterization of discrete condensed sets (#15566) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR provides the necessary API to prove that a condensed set `X` is discrete if and only if for every profinite set `S = limᵢSᵢ`, `X(S) ≅ colimᵢX(Sᵢ)`, and the analogous result for light condensed sets. --- Mathlib.lean | 1 + Mathlib/Condensed/Discrete/Colimit.lean | 571 ++++++++++++++++++++++++ 2 files changed, 572 insertions(+) create mode 100644 Mathlib/Condensed/Discrete/Colimit.lean diff --git a/Mathlib.lean b/Mathlib.lean index a321756d00024d..77a38608ac99e6 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2075,6 +2075,7 @@ import Mathlib.Computability.TuringMachine import Mathlib.Condensed.Basic import Mathlib.Condensed.CartesianClosed import Mathlib.Condensed.Discrete.Basic +import Mathlib.Condensed.Discrete.Colimit import Mathlib.Condensed.Discrete.LocallyConstant import Mathlib.Condensed.Discrete.Module import Mathlib.Condensed.Epi diff --git a/Mathlib/Condensed/Discrete/Colimit.lean b/Mathlib/Condensed/Discrete/Colimit.lean new file mode 100644 index 00000000000000..2e2de66d0a095a --- /dev/null +++ b/Mathlib/Condensed/Discrete/Colimit.lean @@ -0,0 +1,571 @@ +/- +Copyright (c) 2024 Dagur Asgeirsson. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Dagur Asgeirsson +-/ +import Mathlib.Condensed.Discrete.LocallyConstant +import Mathlib.Condensed.Equivalence +import Mathlib.Topology.Category.LightProfinite.Extend +/-! + +# The condensed set given by left Kan extension from `FintypeCat` to `Profinite`. + +This file provides the necessary API to prove that a condensed set `X` is discrete if and only if +for every profinite set `S = limᵢSᵢ`, `X(S) ≅ colimᵢX(Sᵢ)`, and the analogous result for light +condensed sets. +-/ + +universe u + +noncomputable section + +open CategoryTheory Functor Limits FintypeCat CompHausLike.LocallyConstant + +attribute [local instance] ConcreteCategory.instFunLike + +namespace Condensed + +section LocallyConstantAsColimit + +variable {I : Type u} [Category.{u} I] [IsCofiltered I] {F : I ⥤ FintypeCat.{u}} + (c : Cone <| F ⋙ toProfinite) (X : Type (u+1)) + +/-- The presheaf on `Profinite` of locally constant functions to `X`. -/ +abbrev locallyConstantPresheaf : Profinite.{u}ᵒᵖ ⥤ Type (u+1) := + CompHausLike.LocallyConstant.functorToPresheaves.{u, u+1}.obj X + +/-- +The functor `locallyConstantPresheaf` takes cofiltered limits of finite sets with surjective +projection maps to colimits. +-/ +noncomputable def isColimitLocallyConstantPresheaf (hc : IsLimit c) [∀ i, Epi (c.π.app i)] : + IsColimit <| (locallyConstantPresheaf X).mapCocone c.op := by + refine Types.FilteredColimit.isColimitOf _ _ ?_ ?_ + · intro (f : LocallyConstant c.pt X) + obtain ⟨j, h⟩ := Profinite.exists_locallyConstant.{_, u} c hc f + exact ⟨⟨j⟩, h⟩ + · intro ⟨i⟩ ⟨j⟩ (fi : LocallyConstant _ _) (fj : LocallyConstant _ _) + (h : fi.comap (c.π.app i) = fj.comap (c.π.app j)) + obtain ⟨k, ki, kj, _⟩ := IsCofilteredOrEmpty.cone_objs i j + refine ⟨⟨k⟩, ki.op, kj.op, ?_⟩ + dsimp only [comp_obj, op_obj, functorToPresheaves_obj_obj, CompHausLike.coe_of, + Functor.comp_map, op_map, Quiver.Hom.unop_op, functorToPresheaves_obj_map] + -- Note: we might want to remove the `simps` attribute from `FintypeCat.toProfinite`; keeping + -- `toProfinite_obj` in the `dsimp` block above causes the following `ext` to fail. + ext x + obtain ⟨x, hx⟩ := ((Profinite.epi_iff_surjective (c.π.app k)).mp inferInstance) x + rw [← hx] + change fi ((c.π.app k ≫ (F ⋙ toProfinite).map _) x) = + fj ((c.π.app k ≫ (F ⋙ toProfinite).map _) x) + have h := LocallyConstant.congr_fun h x + rwa [c.w, c.w] + +@[simp] +lemma isColimitLocallyConstantPresheaf_desc_apply (hc : IsLimit c) [∀ i, Epi (c.π.app i)] + (s : Cocone ((F ⋙ toProfinite).op ⋙ locallyConstantPresheaf X)) + (i : I) (f : LocallyConstant (toProfinite.obj (F.obj i)) X) : + (isColimitLocallyConstantPresheaf c X hc).desc s (f.comap (c.π.app i)) = s.ι.app ⟨i⟩ f := by + change ((((locallyConstantPresheaf X).mapCocone c.op).ι.app ⟨i⟩) ≫ + (isColimitLocallyConstantPresheaf c X hc).desc s) _ = _ + rw [(isColimitLocallyConstantPresheaf c X hc).fac] + +/-- `isColimitLocallyConstantPresheaf` in the case of `S.asLimit`. -/ +noncomputable def isColimitLocallyConstantPresheafDiagram (S : Profinite) : + IsColimit <| (locallyConstantPresheaf X).mapCocone S.asLimitCone.op := + isColimitLocallyConstantPresheaf _ _ S.asLimit + +@[simp] +lemma isColimitLocallyConstantPresheafDiagram_desc_apply (S : Profinite) + (s : Cocone (S.diagram.op ⋙ locallyConstantPresheaf X)) + (i : DiscreteQuotient S) (f : LocallyConstant (S.diagram.obj i) X) : + (isColimitLocallyConstantPresheafDiagram X S).desc s (f.comap (S.asLimitCone.π.app i)) = + s.ι.app ⟨i⟩ f := + isColimitLocallyConstantPresheaf_desc_apply S.asLimitCone X S.asLimit s i f + +end LocallyConstantAsColimit + +/-- +Given a presheaf `F` on `Profinite`, `lanPresheaf F` is the left Kan extension of its +restriction to finite sets along the inclusion functor of finite sets into `Profinite`. +-/ +abbrev lanPresheaf (F : Profinite.{u}ᵒᵖ ⥤ Type (u+1)) : Profinite.{u}ᵒᵖ ⥤ Type (u+1) := + pointwiseLeftKanExtension toProfinite.op (toProfinite.op ⋙ F) + +/-- +To presheaves on `Profinite` whose restrictions to finite sets are isomorphic have isomorphic left +Kan extensions. +-/ +def lanPresheafExt {F G : Profinite.{u}ᵒᵖ ⥤ Type (u+1)} + (i : toProfinite.op ⋙ F ≅ toProfinite.op ⋙ G) : lanPresheaf F ≅ lanPresheaf G := + leftKanExtensionUniqueOfIso _ (pointwiseLeftKanExtensionUnit _ _) i _ + (pointwiseLeftKanExtensionUnit _ _) + +@[simp] +lemma lanPresheafExt_hom {F G : Profinite.{u}ᵒᵖ ⥤ Type (u+1)} (S : Profinite.{u}ᵒᵖ) + (i : toProfinite.op ⋙ F ≅ toProfinite.op ⋙ G) : (lanPresheafExt i).hom.app S = + colimMap (whiskerLeft (CostructuredArrow.proj toProfinite.op S) i.hom) := by + simp only [lanPresheaf, pointwiseLeftKanExtension_obj, lanPresheafExt, + leftKanExtensionUniqueOfIso_hom, pointwiseLeftKanExtension_desc_app] + apply colimit.hom_ext + aesop + +@[simp] +lemma lanPresheafExt_inv {F G : Profinite.{u}ᵒᵖ ⥤ Type (u+1)} (S : Profinite.{u}ᵒᵖ) + (i : toProfinite.op ⋙ F ≅ toProfinite.op ⋙ G) : (lanPresheafExt i).inv.app S = + colimMap (whiskerLeft (CostructuredArrow.proj toProfinite.op S) i.inv) := by + simp only [lanPresheaf, pointwiseLeftKanExtension_obj, lanPresheafExt, + leftKanExtensionUniqueOfIso_inv, pointwiseLeftKanExtension_desc_app] + apply colimit.hom_ext + aesop + +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 + +/-- +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. +-/ +def lanPresheafIso (hF : IsColimit <| F.mapCocone S.asLimitCone.op) : + (lanPresheaf F).obj ⟨S⟩ ≅ F.obj ⟨S⟩ := + (Functor.Final.colimitIso (Profinite.Extend.functorOp S.asLimitCone) _).symm ≪≫ + (colimit.isColimit _).coconePointUniqueUpToIso hF + +@[simp] +lemma lanPresheafIso_hom (hF : IsColimit <| F.mapCocone S.asLimitCone.op) : + (lanPresheafIso hF).hom = colimit.desc _ (Profinite.Extend.cocone _ _) := by + simp [lanPresheafIso, Final.colimitIso] + rfl + +/-- `lanPresheafIso` is natural in `S`. -/ +def lanPresheafNatIso (hF : ∀ S : Profinite, IsColimit <| F.mapCocone S.asLimitCone.op) : + lanPresheaf F ≅ F := + NatIso.ofComponents (fun ⟨S⟩ ↦ (lanPresheafIso (hF S))) + fun _ ↦ (by simpa using colimit.hom_ext fun _ ↦ (by simp)) + +@[simp] +lemma lanPresheafNatIso_hom_app (hF : ∀ S : Profinite, IsColimit <| F.mapCocone S.asLimitCone.op) + (S : Profiniteᵒᵖ) : (lanPresheafNatIso hF).hom.app S = + colimit.desc _ (Profinite.Extend.cocone _ _) := by + simp [lanPresheafNatIso] + +/-- +`lanPresheaf (locallyConstantPresheaf X)` is a sheaf for the coherent topology on `Profinite`. +-/ +def lanSheafProfinite (X : Type (u+1)) : Sheaf (coherentTopology Profinite.{u}) (Type (u+1)) where + val := lanPresheaf (locallyConstantPresheaf X) + cond := by + rw [Presheaf.isSheaf_of_iso_iff (lanPresheafNatIso + fun _ ↦ isColimitLocallyConstantPresheafDiagram _ _)] + exact ((CompHausLike.LocallyConstant.functor.{u, u+1} + (hs := fun _ _ _ ↦ ((Profinite.effectiveEpi_tfae _).out 0 2).mp)).obj X).cond + +/-- `lanPresheaf (locallyConstantPresheaf X)` as a condensed set. -/ +def lanCondensedSet (X : Type (u+1)) : CondensedSet.{u} := + (ProfiniteCompHaus.equivalence _).functor.obj (lanSheafProfinite X) + +variable (F : Profinite.{u}ᵒᵖ ⥤ Type (u+1)) + +/-- +The functor which takes a finite set to the set of maps into `F(*)` for a presheaf `F` on +`Profinite`. +-/ +@[simps] +def finYoneda : FintypeCat.{u}ᵒᵖ ⥤ Type (u+1) where + obj X := X.unop → F.obj (toProfinite.op.obj ⟨of PUnit.{u+1}⟩) + map f g := g ∘ f.unop + +/-- `locallyConstantPresheaf` restricted to finite sets is isomorphic to `finYoneda F`. -/ +@[simps! hom_app] +def locallyConstantIsoFinYoneda : + toProfinite.op ⋙ (locallyConstantPresheaf (F.obj (toProfinite.op.obj ⟨of PUnit.{u+1}⟩))) ≅ + finYoneda F := + NatIso.ofComponents fun Y ↦ { + hom := fun f ↦ f.1 + inv := fun f ↦ ⟨f, @IsLocallyConstant.of_discrete _ _ _ ⟨rfl⟩ _⟩ } + +/-- A finite set as a coproduct cocone in `Profinite` over itself. -/ +def fintypeCatAsCofan (X : Profinite) : + Cofan (fun (_ : X) ↦ (Profinite.of (PUnit.{u+1}))) := + Cofan.mk X (fun x ↦ (ContinuousMap.const _ x)) + +/-- A finite set is the coproduct of its points in `Profinite`. -/ +def fintypeCatAsCofanIsColimit (X : Profinite) [Fintype X] : + IsColimit (fintypeCatAsCofan X) := by + refine mkCofanColimit _ (fun t ↦ ⟨fun x ↦ t.inj x PUnit.unit, ?_⟩) ?_ + (fun _ _ h ↦ by ext x; exact ContinuousMap.congr_fun (h x) _) + · convert continuous_bot + exact (inferInstanceAs (DiscreteTopology X)).1 + · aesop + +variable [PreservesFiniteProducts F] + +noncomputable instance (X : Profinite) [Fintype X] : + PreservesLimitsOfShape (Discrete X) F := + let X' := (Countable.toSmall.{0} X).equiv_small.choose + let e : X ≃ X' := (Countable.toSmall X).equiv_small.choose_spec.some + have : Fintype X' := Fintype.ofEquiv X e + preservesLimitsOfShapeOfEquiv (Discrete.equivalence e.symm) F + +/-- Auxiliary definition for `isoFinYoneda`. -/ +def isoFinYonedaComponents (X : Profinite.{u}) [Fintype X] : + F.obj ⟨X⟩ ≅ (X → F.obj ⟨Profinite.of PUnit.{u+1}⟩) := + (isLimitFanMkObjOfIsLimit F _ _ + (Cofan.IsColimit.op (fintypeCatAsCofanIsColimit X))).conePointUniqueUpToIso + (Types.productLimitCone.{u, u+1} fun _ ↦ F.obj ⟨Profinite.of PUnit.{u+1}⟩).2 + +lemma isoFinYonedaComponents_hom_apply (X : Profinite.{u}) [Fintype X] (y : F.obj ⟨X⟩) (x : X) : + (isoFinYonedaComponents F X).hom y x = F.map ((Profinite.of PUnit.{u+1}).const x).op y := rfl + +lemma isoFinYonedaComponents_inv_comp {X Y : Profinite.{u}} [Fintype X] [Fintype Y] + (f : Y → F.obj ⟨Profinite.of PUnit⟩) (g : X ⟶ Y) : + (isoFinYonedaComponents F X).inv (f ∘ g) = F.map g.op ((isoFinYonedaComponents F Y).inv f) := by + apply injective_of_mono (isoFinYonedaComponents F X).hom + simp only [CategoryTheory.inv_hom_id_apply] + ext x + rw [isoFinYonedaComponents_hom_apply] + simp only [← FunctorToTypes.map_comp_apply, ← op_comp, CompHausLike.const_comp, + ← isoFinYonedaComponents_hom_apply, CategoryTheory.inv_hom_id_apply, Function.comp_apply] + +/-- +The restriction of a finite product preserving presheaf `F` on `Profinite` to the category of +finite sets is isomorphic to `finYoneda F`. +-/ +@[simps!] +def isoFinYoneda : toProfinite.op ⋙ F ≅ finYoneda F := + NatIso.ofComponents (fun X ↦ isoFinYonedaComponents F (toProfinite.obj X.unop)) fun _ ↦ by + simp only [comp_obj, op_obj, finYoneda_obj, Functor.comp_map, op_map] + ext + simp only [toProfinite_obj, types_comp_apply, isoFinYonedaComponents_hom_apply, finYoneda_map, + op_obj, Function.comp_apply, ← FunctorToTypes.map_comp_apply] + rfl + +/-- +A presheaf `F`, which takes a profinite set written as a cofiltered limit to the corresponding +colimit, is isomorphic to the presheaf `LocallyConstant - F(*)`. +-/ +def isoLocallyConstantOfIsColimit + (hF : ∀ S : Profinite, IsColimit <| F.mapCocone S.asLimitCone.op) : + F ≅ (locallyConstantPresheaf (F.obj (toProfinite.op.obj ⟨of PUnit.{u+1}⟩))) := + (lanPresheafNatIso hF).symm ≪≫ + lanPresheafExt (isoFinYoneda F ≪≫ (locallyConstantIsoFinYoneda F).symm) ≪≫ + lanPresheafNatIso fun _ ↦ isColimitLocallyConstantPresheafDiagram _ _ + +lemma isoLocallyConstantOfIsColimit_inv (X : Profinite.{u}ᵒᵖ ⥤ Type (u+1)) + [PreservesFiniteProducts X] + (hX : ∀ S : Profinite.{u}, (IsColimit <| X.mapCocone S.asLimitCone.op)) : + (isoLocallyConstantOfIsColimit X hX).inv = + (CompHausLike.LocallyConstant.counitApp.{u, u+1} X) := by + dsimp [isoLocallyConstantOfIsColimit] + simp only [Category.assoc] + rw [Iso.inv_comp_eq] + ext S : 2 + apply colimit.hom_ext + intro ⟨Y, _, g⟩ + simp? [locallyConstantIsoFinYoneda, isoFinYoneda, counitApp] says + simp only [comp_obj, CostructuredArrow.proj_obj, op_obj, toProfinite_obj, + functorToPresheaves_obj_obj, CompHausLike.coe_of, isoFinYoneda, locallyConstantIsoFinYoneda, + finYoneda_obj, LocallyConstant.toFun_eq_coe, NatTrans.comp_app, pointwiseLeftKanExtension_obj, + lanPresheafExt_inv, Iso.trans_inv, Iso.symm_inv, whiskerLeft_comp, lanPresheafNatIso_hom_app, + Opposite.op_unop, colimit.map_desc, id_eq, Functor.comp_map, op_map, colimit.ι_desc, + Cocones.precompose_obj_pt, Profinite.Extend.cocone_pt, Cocones.precompose_obj_ι, + Category.assoc, const_obj_obj, whiskerLeft_app, NatIso.ofComponents_hom_app, + NatIso.ofComponents_inv_app, Profinite.Extend.cocone_ι_app, counitApp, colimit.ι_desc_assoc] + erw [(counitApp.{u, u+1} X).naturality] + simp only [← Category.assoc] + congr + ext f + simp only [types_comp_apply, isoFinYoneda_inv_app, counitApp_app] + apply presheaf_ext.{u, u+1} (X := X) (Y := X) (f := f) + intro x + erw [incl_of_counitAppApp] + simp only [counitAppAppImage, CompHausLike.coe_of] + letI : Fintype (fiber.{u, u+1} f x) := + Fintype.ofInjective (sigmaIncl.{u, u+1} f x).1 Subtype.val_injective + apply injective_of_mono (isoFinYonedaComponents X (fiber.{u, u+1} f x)).hom + ext y + simp only [isoFinYonedaComponents_hom_apply, ← FunctorToTypes.map_comp_apply, ← op_comp] + rw [show (Profinite.of PUnit.{u+1}).const y ≫ IsTerminal.from _ (fiber f x) = 𝟙 _ from rfl] + simp only [op_comp, FunctorToTypes.map_comp_apply, op_id, FunctorToTypes.map_id_apply] + rw [← isoFinYonedaComponents_inv_comp X _ (sigmaIncl.{u, u+1} f x)] + simpa [← isoFinYonedaComponents_hom_apply] using x.map_eq_image f y + +end Condensed + +namespace LightCondensed + +section LocallyConstantAsColimit + +variable {F : ℕᵒᵖ ⥤ FintypeCat.{u}} (c : Cone <| F ⋙ toLightProfinite) (X : Type u) + +/-- The presheaf on `LightProfinite` of locally constant functions to `X`. -/ +abbrev locallyConstantPresheaf : LightProfiniteᵒᵖ ⥤ Type u := + CompHausLike.LocallyConstant.functorToPresheaves.{u, u}.obj X + +/-- +The functor `locallyConstantPresheaf` takes sequential limits of finite sets with surjective +projection maps to colimits. +-/ +noncomputable def isColimitLocallyConstantPresheaf (hc : IsLimit c) [∀ i, Epi (c.π.app i)] : + IsColimit <| (locallyConstantPresheaf X).mapCocone c.op := by + refine Types.FilteredColimit.isColimitOf _ _ ?_ ?_ + · intro (f : LocallyConstant c.pt X) + obtain ⟨j, h⟩ := Profinite.exists_locallyConstant.{_, 0} (lightToProfinite.mapCone c) + (isLimitOfPreserves lightToProfinite hc) f + exact ⟨⟨j⟩, h⟩ + · intro ⟨i⟩ ⟨j⟩ (fi : LocallyConstant _ _) (fj : LocallyConstant _ _) + (h : fi.comap (c.π.app i) = fj.comap (c.π.app j)) + obtain ⟨k, ki, kj, _⟩ := IsCofilteredOrEmpty.cone_objs i j + refine ⟨⟨k⟩, ki.op, kj.op, ?_⟩ + dsimp only [comp_obj, op_obj, functorToPresheaves_obj_obj, CompHausLike.coe_of, + Functor.comp_map, op_map, Quiver.Hom.unop_op, functorToPresheaves_obj_map] + ext x + obtain ⟨x, hx⟩ := ((LightProfinite.epi_iff_surjective (c.π.app k)).mp inferInstance) x + rw [← hx] + change fi ((c.π.app k ≫ (F ⋙ toLightProfinite).map _) x) = + fj ((c.π.app k ≫ (F ⋙ toLightProfinite).map _) x) + have h := LocallyConstant.congr_fun h x + rwa [c.w, c.w] + +@[simp] +lemma isColimitLocallyConstantPresheaf_desc_apply (hc : IsLimit c) [∀ i, Epi (c.π.app i)] + (s : Cocone ((F ⋙ toLightProfinite).op ⋙ locallyConstantPresheaf X)) + (n : ℕᵒᵖ) (f : LocallyConstant (toLightProfinite.obj (F.obj n)) X) : + (isColimitLocallyConstantPresheaf c X hc).desc s (f.comap (c.π.app n)) = s.ι.app ⟨n⟩ f := by + change ((((locallyConstantPresheaf X).mapCocone c.op).ι.app ⟨n⟩) ≫ + (isColimitLocallyConstantPresheaf c X hc).desc s) _ = _ + rw [(isColimitLocallyConstantPresheaf c X hc).fac] + +/-- `isColimitLocallyConstantPresheaf` in the case of `S.asLimit`. -/ +noncomputable def isColimitLocallyConstantPresheafDiagram (S : LightProfinite) : + IsColimit <| (locallyConstantPresheaf X).mapCocone (coconeRightOpOfCone S.asLimitCone) := + (Functor.Final.isColimitWhiskerEquiv (opOpEquivalence ℕ).inverse _).symm + (isColimitLocallyConstantPresheaf _ _ S.asLimit) + +@[simp] +lemma isColimitLocallyConstantPresheafDiagram_desc_apply (S : LightProfinite) + (s : Cocone (S.diagram.rightOp ⋙ locallyConstantPresheaf X)) + (n : ℕ) (f : LocallyConstant (S.diagram.obj ⟨n⟩) X) : + (isColimitLocallyConstantPresheafDiagram X S).desc s (f.comap (S.asLimitCone.π.app ⟨n⟩)) = + s.ι.app n f := by + change ((((locallyConstantPresheaf X).mapCocone (coconeRightOpOfCone S.asLimitCone)).ι.app n) ≫ + (isColimitLocallyConstantPresheafDiagram X S).desc s) _ = _ + rw [(isColimitLocallyConstantPresheafDiagram X S).fac] + +end LocallyConstantAsColimit + +instance (S : LightProfinite.{u}ᵒᵖ) : + HasColimitsOfShape (CostructuredArrow toLightProfinite.op S) (Type u) := + hasColimitsOfShape_of_equivalence (asEquivalence (CostructuredArrow.pre Skeleton.incl.op _ S)) + +/-- +Given a presheaf `F` on `LightProfinite`, `lanPresheaf F` is the left Kan extension of its +restriction to finite sets along the inclusion functor of finite sets into `Profinite`. +-/ +abbrev lanPresheaf (F : LightProfinite.{u}ᵒᵖ ⥤ Type u) : LightProfinite.{u}ᵒᵖ ⥤ Type u := + pointwiseLeftKanExtension toLightProfinite.op (toLightProfinite.op ⋙ F) + +/-- +To presheaves on `LightProfinite` whose restrictions to finite sets are isomorphic have isomorphic +left Kan extensions. +-/ +def lanPresheafExt {F G : LightProfinite.{u}ᵒᵖ ⥤ Type u} + (i : toLightProfinite.op ⋙ F ≅ toLightProfinite.op ⋙ G) : lanPresheaf F ≅ lanPresheaf G := + leftKanExtensionUniqueOfIso _ (pointwiseLeftKanExtensionUnit _ _) i _ + (pointwiseLeftKanExtensionUnit _ _) + +@[simp] +lemma lanPresheafExt_hom {F G : LightProfinite.{u}ᵒᵖ ⥤ Type u} (S : LightProfinite.{u}ᵒᵖ) + (i : toLightProfinite.op ⋙ F ≅ toLightProfinite.op ⋙ G) : (lanPresheafExt i).hom.app S = + colimMap (whiskerLeft (CostructuredArrow.proj toLightProfinite.op S) i.hom) := by + simp only [lanPresheaf, pointwiseLeftKanExtension_obj, lanPresheafExt, + leftKanExtensionUniqueOfIso_hom, pointwiseLeftKanExtension_desc_app] + apply colimit.hom_ext + aesop + +@[simp] +lemma lanPresheafExt_inv {F G : LightProfinite.{u}ᵒᵖ ⥤ Type u} (S : LightProfinite.{u}ᵒᵖ) + (i : toLightProfinite.op ⋙ F ≅ toLightProfinite.op ⋙ G) : (lanPresheafExt i).inv.app S = + colimMap (whiskerLeft (CostructuredArrow.proj toLightProfinite.op S) i.inv) := by + simp only [lanPresheaf, pointwiseLeftKanExtension_obj, lanPresheafExt, + leftKanExtensionUniqueOfIso_inv, pointwiseLeftKanExtension_desc_app] + apply colimit.hom_ext + aesop + +variable {S : LightProfinite.{u}} {F : LightProfinite.{u}ᵒᵖ ⥤ Type u} + +instance : Final <| LightProfinite.Extend.functorOp S.asLimitCone := + LightProfinite.Extend.functorOp_final S.asLimitCone S.asLimit + +/-- +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. +-/ +def lanPresheafIso (hF : IsColimit <| F.mapCocone (coconeRightOpOfCone S.asLimitCone)) : + (lanPresheaf F).obj ⟨S⟩ ≅ F.obj ⟨S⟩ := + (Functor.Final.colimitIso (LightProfinite.Extend.functorOp S.asLimitCone) _).symm ≪≫ + (colimit.isColimit _).coconePointUniqueUpToIso hF + +@[simp] +lemma lanPresheafIso_hom (hF : IsColimit <| F.mapCocone (coconeRightOpOfCone S.asLimitCone)) : + (lanPresheafIso hF).hom = colimit.desc _ (LightProfinite.Extend.cocone _ _) := by + simp [lanPresheafIso, Final.colimitIso] + rfl + +/-- `lanPresheafIso` is natural in `S`. -/ +def lanPresheafNatIso + (hF : ∀ S : LightProfinite, IsColimit <| F.mapCocone (coconeRightOpOfCone S.asLimitCone)) : + lanPresheaf F ≅ F := by + refine NatIso.ofComponents + (fun ⟨S⟩ ↦ (lanPresheafIso (hF S))) fun _ ↦ ?_ + simp only [lanPresheaf, pointwiseLeftKanExtension_obj, pointwiseLeftKanExtension_map, + lanPresheafIso_hom, Opposite.op_unop] + exact colimit.hom_ext fun _ ↦ (by simp) + +@[simp] +lemma lanPresheafNatIso_hom_app + (hF : ∀ S : LightProfinite, IsColimit <| F.mapCocone (coconeRightOpOfCone S.asLimitCone)) + (S : LightProfiniteᵒᵖ) : (lanPresheafNatIso hF).hom.app S = + colimit.desc _ (LightProfinite.Extend.cocone _ _) := by + simp [lanPresheafNatIso] + +/-- +`lanPresheaf (locallyConstantPresheaf X)` as a light condensed set. +-/ +def lanLightCondSet (X : Type u) : LightCondSet.{u} where + val := lanPresheaf (locallyConstantPresheaf X) + cond := by + rw [Presheaf.isSheaf_of_iso_iff (lanPresheafNatIso + fun _ ↦ isColimitLocallyConstantPresheafDiagram _ _)] + exact (CompHausLike.LocallyConstant.functor.{u, u} + (hs := fun _ _ _ ↦ ((LightProfinite.effectiveEpi_iff_surjective _).mp)).obj X).cond + +variable (F : LightProfinite.{u}ᵒᵖ ⥤ Type u) + +/-- +The functor which takes a finite set to the set of maps into `F(*)` for a presheaf `F` on +`LightProfinite`. +-/ +@[simps] +def finYoneda : FintypeCat.{u}ᵒᵖ ⥤ Type u where + obj X := X.unop → F.obj (toLightProfinite.op.obj ⟨of PUnit.{u+1}⟩) + map f g := g ∘ f.unop + +/-- `locallyConstantPresheaf` restricted to finite sets is isomorphic to `finYoneda F`. -/ +def locallyConstantIsoFinYoneda : toLightProfinite.op ⋙ + (locallyConstantPresheaf (F.obj (toLightProfinite.op.obj ⟨of PUnit.{u+1}⟩))) ≅ finYoneda F := + NatIso.ofComponents fun Y ↦ { + hom := fun f ↦ f.1 + inv := fun f ↦ ⟨f, @IsLocallyConstant.of_discrete _ _ _ ⟨rfl⟩ _⟩ } + +/-- A finite set as a coproduct cocone in `LightProfinite` over itself. -/ +def fintypeCatAsCofan (X : LightProfinite) : + Cofan (fun (_ : X) ↦ (LightProfinite.of (PUnit.{u+1}))) := + Cofan.mk X (fun x ↦ (ContinuousMap.const _ x)) + +/-- A finite set is the coproduct of its points in `LightProfinite`. -/ +def fintypeCatAsCofanIsColimit (X : LightProfinite) [Fintype X] : + IsColimit (fintypeCatAsCofan X) := by + refine mkCofanColimit _ (fun t ↦ ⟨fun x ↦ t.inj x PUnit.unit, ?_⟩) ?_ + (fun _ _ h ↦ by ext x; exact ContinuousMap.congr_fun (h x) _) + · convert continuous_bot + exact (inferInstanceAs (DiscreteTopology X)).1 + · aesop + +variable [PreservesFiniteProducts F] + +noncomputable instance (X : FintypeCat.{u}) : PreservesLimitsOfShape (Discrete X) F := + let X' := (Countable.toSmall.{0} X).equiv_small.choose + let e : X ≃ X' := (Countable.toSmall X).equiv_small.choose_spec.some + have : Fintype X' := Fintype.ofEquiv X e + preservesLimitsOfShapeOfEquiv (Discrete.equivalence e.symm) F + +/-- Auxiliary definition for `isoFinYoneda`. -/ +def isoFinYonedaComponents (X : LightProfinite.{u}) [Fintype X] : + F.obj ⟨X⟩ ≅ (X → F.obj ⟨LightProfinite.of PUnit.{u+1}⟩) := + (isLimitFanMkObjOfIsLimit F _ _ + (Cofan.IsColimit.op (fintypeCatAsCofanIsColimit X))).conePointUniqueUpToIso + (Types.productLimitCone.{u, u} fun _ ↦ F.obj ⟨LightProfinite.of PUnit.{u+1}⟩).2 + +lemma isoFinYonedaComponents_hom_apply (X : LightProfinite.{u}) [Fintype X] (y : F.obj ⟨X⟩) + (x : X) : (isoFinYonedaComponents F X).hom y x = + F.map ((LightProfinite.of PUnit.{u+1}).const x).op y := rfl + +lemma isoFinYonedaComponents_inv_comp {X Y : LightProfinite.{u}} [Fintype X] [Fintype Y] + (f : Y → F.obj ⟨LightProfinite.of PUnit⟩) (g : X ⟶ Y) : + (isoFinYonedaComponents F X).inv (f ∘ g) = F.map g.op ((isoFinYonedaComponents F Y).inv f) := by + apply injective_of_mono (isoFinYonedaComponents F X).hom + simp only [CategoryTheory.inv_hom_id_apply] + ext x + rw [isoFinYonedaComponents_hom_apply] + simp only [← FunctorToTypes.map_comp_apply, ← op_comp, CompHausLike.const_comp, + ← isoFinYonedaComponents_hom_apply, CategoryTheory.inv_hom_id_apply, Function.comp_apply] + +/-- +The restriction of a finite product preserving presheaf `F` on `Profinite` to the category of +finite sets is isomorphic to `finYoneda F`. +-/ +@[simps!] +def isoFinYoneda : toLightProfinite.op ⋙ F ≅ finYoneda F := + NatIso.ofComponents (fun X ↦ isoFinYonedaComponents F (toLightProfinite.obj X.unop)) fun _ ↦ by + simp only [comp_obj, op_obj, finYoneda_obj, Functor.comp_map, op_map] + ext + simp only [types_comp_apply, isoFinYonedaComponents_hom_apply, finYoneda_map, op_obj, + Function.comp_apply, Types.productLimitCone, const_obj_obj, fintypeCatAsCofan, Cofan.mk_pt, + cofan_mk_inj, Fan.mk_pt, Fan.mk_π_app, ← FunctorToTypes.map_comp_apply] + rfl + +/-- +A presheaf `F`, which takes a light profinite set written as a sequential limit to the corresponding +colimit, is isomorphic to the presheaf `LocallyConstant - F(*)`. +-/ +def isoLocallyConstantOfIsColimit (hF : ∀ S : LightProfinite, IsColimit <| + F.mapCocone (coconeRightOpOfCone S.asLimitCone)) : + F ≅ (locallyConstantPresheaf + (F.obj (toLightProfinite.op.obj ⟨of PUnit.{u+1}⟩))) := + (lanPresheafNatIso hF).symm ≪≫ + lanPresheafExt (isoFinYoneda F ≪≫ (locallyConstantIsoFinYoneda F).symm) ≪≫ + lanPresheafNatIso fun _ ↦ isColimitLocallyConstantPresheafDiagram _ _ + +lemma isoLocallyConstantOfIsColimit_inv (X : LightProfinite.{u}ᵒᵖ ⥤ Type u) + [PreservesFiniteProducts X] (hX : ∀ S : LightProfinite.{u}, (IsColimit <| + X.mapCocone (coconeRightOpOfCone S.asLimitCone))) : + (isoLocallyConstantOfIsColimit X hX).inv = + (CompHausLike.LocallyConstant.counitApp.{u, u} X) := by + dsimp [isoLocallyConstantOfIsColimit] + simp only [Category.assoc] + rw [Iso.inv_comp_eq] + ext S : 2 + apply colimit.hom_ext + intro ⟨Y, _, g⟩ + simp? [locallyConstantIsoFinYoneda, isoFinYoneda, counitApp] says + simp only [comp_obj, CostructuredArrow.proj_obj, op_obj, functorToPresheaves_obj_obj, + toLightProfinite_obj_toTop_α, isoFinYoneda, locallyConstantIsoFinYoneda, finYoneda_obj, + LocallyConstant.toFun_eq_coe, NatTrans.comp_app, pointwiseLeftKanExtension_obj, + lanPresheafExt_inv, Iso.trans_inv, Iso.symm_inv, whiskerLeft_comp, lanPresheafNatIso_hom_app, + Opposite.op_unop, colimit.map_desc, id_eq, Functor.comp_map, op_map, colimit.ι_desc, + Cocones.precompose_obj_pt, LightProfinite.Extend.cocone_pt, Cocones.precompose_obj_ι, + Category.assoc, const_obj_obj, whiskerLeft_app, NatIso.ofComponents_hom_app, + NatIso.ofComponents_inv_app, LightProfinite.Extend.cocone_ι_app, counitApp, + colimit.ι_desc_assoc] + erw [(counitApp.{u, u} X).naturality] + simp only [← Category.assoc] + congr + ext f + simp only [types_comp_apply, isoFinYoneda_inv_app, counitApp_app] + apply presheaf_ext.{u, u} (X := X) (Y := X) (f := f) + intro x + erw [incl_of_counitAppApp] + simp only [counitAppAppImage, CompHausLike.coe_of] + letI : Fintype (fiber.{u, u} f x) := + Fintype.ofInjective (sigmaIncl.{u, u} f x).1 Subtype.val_injective + apply injective_of_mono (isoFinYonedaComponents X (fiber.{u, u} f x)).hom + ext y + simp only [isoFinYonedaComponents_hom_apply, ← FunctorToTypes.map_comp_apply, ← op_comp] + rw [show (LightProfinite.of PUnit.{u+1}).const y ≫ IsTerminal.from _ (fiber f x) = 𝟙 _ from rfl] + simp only [op_comp, FunctorToTypes.map_comp_apply, op_id, FunctorToTypes.map_id_apply] + rw [← isoFinYonedaComponents_inv_comp X _ (sigmaIncl.{u, u} f x)] + simpa [← isoFinYonedaComponents_hom_apply] using x.map_eq_image f y + +end LightCondensed From 7994a4b98496b02bc23745676fe3bf64dcb15bce Mon Sep 17 00:00:00 2001 From: Daniel Weber Date: Wed, 16 Oct 2024 04:43:26 +0000 Subject: [PATCH 188/425] refactor(RingTheory/Multiplicity): split to Nat-valued `multiplicity` and ENat-valued `emultiplicity` (#16881) Also rename a bunch of stuff, and move most results outside of the `multiplicity` namespace. Moves (note that the definition of many of these has changed slightly): - multiplicity -> emultiplicity - multiplicity.finite_def -> multiplicity.Finite.def - multiplicity.not_dvd_one_of_finite_one_right -> multiplicity.Finite.not_dvd_of_one_right - multiplicity.Int.natCast_multiplicity -> Int.natCast_emultiplicity - multiplicity.not_finite_iff_forall -> multiplicity.Finite.not_iff_forall - multiplicity.not_unit_of_finite -> multiplicity.Finite.not_unit - multiplicity.finite_of_finite_mul_right -> multiplicity.Finite.mul_left - multiplicity.pow_dvd_of_le_multiplicity -> pow_dvd_of_le_emultiplicity - multiplicity.pow_multiplicity_dvd -> pow_multiplicity_dvd - multiplicity.is_greatest -> not_pow_dvd_of_emultiplicity_lt - multiplicity.is_greatest' -> multiplicity.Finite.not_pow_dvd_of_multiplicity_lt - multiplicity.pos_of_dvd -> emultiplicity_pos_of_dvd - multiplicity.unique -> emultiplicity_eq_of_dvd_of_not_dvd - multiplicity.unique' -> multiplicity_eq_of_dvd_of_not_dvd - multiplicity.le_multiplicity_of_pow_dvd -> le_emultiplicity_of_pow_dvd - multiplicity.pow_dvd_iff_le_multiplicity -> pow_dvd_iff_le_emultiplicity - multiplicity.multiplicity_lt_iff_not_dvd -> emultiplicity_lt_iff_not_dvd - multiplicity.eq_coe_iff -> emultiplicity_eq_coe - multiplicity.eq_top_iff -> emultiplicity_eq_top - multiplicity.isUnit_left -> multiplicity.Finite.not_of_isUnit_left - multiplicity.one_left -> emultiplicity_one_left - multiplicity.get_one_right -> multiplicity.Finite.one_right - multiplicity.unit_left -> multiplicity.Finite.not_of_unit_left - multiplicity.multiplicity_eq_zero -> emultiplicity_eq_zero - multiplicity.multiplicity_ne_zero -> emultiplicity_ne_zero - multiplicity.eq_top_iff_not_finite -> emultiplicity_eq_top - multiplicity.ne_top_iff_finite -> finite_iff_emultiplicity_ne_top - multiplicity.lt_top_iff_finite -> emultiplicity_lt_top - multiplicity.exists_eq_pow_mul_and_not_dvd -> multiplicity.Finite.exists_eq_pow_mul_and_not_dvd - multiplicity.multiplicity_le_multiplicity_iff -> emultiplicity_le_emultiplicity_iff - multiplicity.multiplicity_eq_multiplicity_iff -> emultiplicity_eq_emultiplicity_iff - multiplicity.le_multiplicity_map -> le_emultiplicity_map - multiplicity.multiplicity_map_eq -> emultiplicity_map_eq - multiplicity.multiplicity_le_multiplicity_of_dvd_right -> emultiplicity_le_emultiplicity_of_dvd_right - multiplicity.eq_of_associated_right -> emultiplicity_eq_of_associated_right - multiplicity.dvd_of_multiplicity_pos -> dvd_of_emultiplicity_pos - multiplicity.dvd_iff_multiplicity_pos -> dvd_iff_emultiplicity_pos - multiplicity.finite_nat_iff -> Nat.multiplicity_finite_iff - has_dvd.dvd.multiplicity_pos -> Dvd.multiplicity_pos - multiplicity.finite_of_finite_mul_left -> multiplicity.Finite.mul_right - multiplicity.isUnit_right -> emultiplicity_of_isUnit_right - multiplicity.one_right -> emultiplicity_of_one_right - multiplicity.unit_right -> emultiplicity_of_unit_right - multiplicity.multiplicity_le_multiplicity_of_dvd_left -> emultiplicity_le_emultiplicity_of_dvd_left - multiplicity.eq_of_associated_left -> emultiplicity_eq_of_associated_left - multiplicity.ne_zero_of_finite -> multiplicity.Finite.ne_zero - multiplicity.zero -> emultiplicity_zero - multiplicity.multiplicity_zero_eq_zero_of_ne_zero -> emultiplicity_zero_eq_zero_of_ne_zero - multiplicity.multiplicity_mk_eq_multiplicity -> emultiplicity_mk_eq_emultiplicity - multiplicity.min_le_multiplicity_add -> min_le_emultiplicity_add - multiplicity.neg -> emultiplicity_neg - multiplicity.Int.natAbs -> Int.emultiplicity_natAbs - multiplicity.multiplicity_add_of_gt -> emultiplicity_add_of_gt - multiplicity.multiplicity_sub_of_gt -> emultiplicity_sub_of_gt - multiplicity.multiplicity_add_eq_min -> emultiplicity_add_eq_min - multiplicity.finite_mul -> Prime.multiplicity_finite_mul - multiplicity.finite_mul_iff -> multiplicity.Finite.mul_iff - multiplicity.finite_pow -> multiplicity.Finite.pow - multiplicity.multiplicity_self -> multiplicity_self - multiplicity.get_multiplicity_self -> multiplicity.Finite.emultiplicity_self - multiplicity.mul' -> multiplicity_mul - multiplicity.mul -> emultiplicity_mul - multiplicity.Finset.prod -> Finset.emultiplicity_prod - multiplicity.pow' -> multiplicity.Finite.multiplicity_pow - multiplicity.pow -> emultiplicity_pow - multiplicity.multiplicity_pow_self -> emultiplicity_pow_self - multiplicity.multiplicity_pow_self_of_prime -> emultiplicity_pow_self_of_prime - multiplicity.finite_int_iff_natAbs_finite -> Int.multiplicity_finite_iff_natAbs_finite - multiplicity.finite_int_iff -> Int.multiplicity_finite_int_iff - multiplicity.squarefree_iff_multiplicity_le_one -> multiplicity.squarefree_iff_emultiplicity_le_one - Nat.multiplicity_eq_card_pow_dvd -> Nat.emultiplicity_eq_card_pow_dvd - Nat.Prime.multiplicity_one -> Nat.Prime.emultiplicity_one - Nat.Prime.multiplicity_mul -> Nat.Prime.emultiplicity_mul - Nat.Prime.multiplicity_pow -> Nat.Prime.emultiplicity_pow - Nat.Prime.multiplicity_self -> Nat.Prime.emultiplicity_self - Nat.Prime.multiplicity_pow_self -> Nat.Prime.emultiplicity_pow_self - Nat.Prime.multiplicity_factorial -> Nat.Prime.emultiplicity_factorial - Nat.Prime.multiplicity_factorial_mul_succ -> Nat.Prime.emultiplicity_factorial_mul_succ - Nat.Prime.multiplicity_factorial_mul -> Nat.Prime.emultiplicity_factorial_mul - Nat.Prime.multiplicity_choose' -> Nat.Prime.emultiplicity_choose' - Nat.Prime.multiplicity_choose -> Nat.Prime.emultiplicity_choose - Nat.Prime.multiplicity_le_multiplicity_choose_add -> Nat.Prime.emultiplicity_le_emultiplicity_choose_add - Nat.Prime.multiplicity_choose_prime_pow_add_multiplicity -> Nat.Prime.emultiplicity_choose_prime_pow_add_emultiplicity - Nat.Prime.multiplicity_choose_prime_pow -> Nat.Prime.emultiplicity_choose_prime_pow - Nat.Prime.multiplicity_two_factorial_lt -> Nat.Prime.emultiplicity_two_factorial_lt - Polynomial.multiplicity_le_one_of_separable -> Polynomial.emultiplicity_le_one_of_separable - KummerDedekind.multiplicity_factors_map_eq_multiplicity -> KummerDedekind.emultiplicity_factors_map_eq_emultiplicity - padicValNat.maxPowDiv_eq_multiplicity -> padicValNat.maxPowDiv_eq_emultiplicity - padicValNat.maxPowDiv_eq_multiplicity_get -> padicValNat.maxPowDiv_eq_multiplicity - le_multiplicity_iff_replicate_subperm_primeFactorsList -> le_emultiplicity_iff_replicate_subperm_primeFactorsList - multiplicity_prime_le_multiplicity_image_by_factor_orderIso -> emultiplicity_prime_le_emultiplicity_image_by_factor_orderIso - multiplicity_prime_eq_multiplicity_image_by_factor_orderIso -> emultiplicity_prime_eq_emultiplicity_image_by_factor_orderIso - multiplicity_factor_dvd_iso_eq_multiplicity_of_mem_normalizedFactors -> emultiplicity_factor_dvd_iso_eq_emultiplicity_of_mem_normalizedFactors - normalizedFactorsEquivOfQuotEquiv_multiplicity_eq_multiplicity -> normalizedFactorsEquivOfQuotEquiv_emultiplicity_eq_emultiplicity - multiplicity_eq_multiplicity_span -> emultiplicity_eq_emultiplicity_span - multiplicity_normalizedFactorsEquivSpanNormalizedFactors_eq_multiplicity -> emultiplicity_normalizedFactorsEquivSpanNormalizedFactors_eq_emultiplicity - multiplicity_normalizedFactorsEquivSpanNormalizedFactors_symm_eq_multiplicity -> emultiplicity_normalizedFactorsEquivSpanNormalizedFactors_symm_eq_emultiplicity - PowerSeries.order_eq_multiplicity_X -> PowerSeries.order_eq_emultiplicity_X - UniqueFactorizationMonoid.le_multiplicity_iff_replicate_le_normalizedFactors -> UniqueFactorizationMonoid.le_emultiplicity_iff_replicate_le_normalizedFactors - UniqueFactorizationMonoid.multiplicity_eq_count_normalizedFactors -> UniqueFactorizationMonoid.emultiplicity_eq_count_normalizedFactors - multiplicity.addValuation -> multiplicity_addValuation - multiplicity.addValuation_apply -> multiplicity_addValuation_apply Deletions: - multiplicity.finite_iff_dom - multiplicity.decidableNat - multiplicity.decidableInt Co-authored-by: Daniel Weber <55664973+Command-Master@users.noreply.github.com> --- Archive/Imo/Imo2019Q4.lean | 14 +- .../Wiedijk100Theorems/PerfectNumbers.lean | 8 +- Mathlib/Algebra/Polynomial/Div.lean | 34 +- Mathlib/Algebra/Polynomial/RingDivision.lean | 10 +- Mathlib/Algebra/Squarefree/Basic.lean | 22 +- Mathlib/Data/Nat/Choose/Factorization.lean | 9 +- Mathlib/Data/Nat/Factorization/Basic.lean | 3 +- Mathlib/Data/Nat/Multiplicity.lean | 195 ++-- Mathlib/Data/Nat/Squarefree.lean | 8 +- Mathlib/Data/Real/Irrational.lean | 11 +- Mathlib/FieldTheory/Separable.lean | 21 +- Mathlib/FieldTheory/SeparableDegree.lean | 4 +- Mathlib/NumberTheory/FLT/Three.lean | 74 +- Mathlib/NumberTheory/KummerDedekind.lean | 16 +- Mathlib/NumberTheory/Multiplicity.lean | 108 +- Mathlib/NumberTheory/Padics/PadicNorm.lean | 9 +- .../NumberTheory/Padics/PadicVal/Basic.lean | 140 ++- .../NumberTheory/Padics/PadicVal/Defs.lean | 43 +- Mathlib/RingTheory/ChainOfDivisors.lean | 38 +- Mathlib/RingTheory/DedekindDomain/Ideal.lean | 77 +- .../DiscreteValuationRing/Basic.lean | 24 +- Mathlib/RingTheory/Multiplicity.lean | 921 +++++++++++------- Mathlib/RingTheory/PowerSeries/Inverse.lean | 8 +- Mathlib/RingTheory/PowerSeries/Order.lean | 42 +- Mathlib/RingTheory/RootsOfUnity/Basic.lean | 6 +- Mathlib/RingTheory/RootsOfUnity/Minpoly.lean | 6 +- .../RingTheory/UniqueFactorizationDomain.lean | 28 +- .../Valuation/PrimeMultiplicity.lean | 14 +- Mathlib/RingTheory/WittVector/Frobenius.lean | 40 +- 29 files changed, 1041 insertions(+), 892 deletions(-) diff --git a/Archive/Imo/Imo2019Q4.lean b/Archive/Imo/Imo2019Q4.lean index e9b0ff74200d4e..ddf0040f14bd9e 100644 --- a/Archive/Imo/Imo2019Q4.lean +++ b/Archive/Imo/Imo2019Q4.lean @@ -37,14 +37,14 @@ namespace Imo2019Q4 theorem upper_bound {k n : ℕ} (hk : k > 0) (h : (k ! : ℤ) = ∏ i ∈ range n, ((2:ℤ) ^ n - (2:ℤ) ^ i)) : n < 6 := by have h2 : ∑ i ∈ range n, i < k := by - suffices multiplicity 2 (k ! : ℤ) = ↑(∑ i ∈ range n, i : ℕ) by - rw [← PartENat.coe_lt_coe, ← this]; change multiplicity ((2 : ℕ) : ℤ) _ < _ - simp_rw [Int.natCast_multiplicity, multiplicity_two_factorial_lt hk.lt.ne.symm] - rw [h, multiplicity.Finset.prod Int.prime_two, Nat.cast_sum] + suffices emultiplicity 2 (k ! : ℤ) = ↑(∑ i ∈ range n, i : ℕ) by + rw [← Nat.cast_lt (α := ℕ∞), ← this]; change emultiplicity ((2 : ℕ) : ℤ) _ < _ + simp_rw [Int.natCast_emultiplicity, emultiplicity_two_factorial_lt hk.lt.ne.symm] + rw [h, Finset.emultiplicity_prod Int.prime_two, Nat.cast_sum] apply sum_congr rfl; intro i hi - rw [multiplicity_sub_of_gt, multiplicity_pow_self_of_prime Int.prime_two] - rwa [multiplicity_pow_self_of_prime Int.prime_two, multiplicity_pow_self_of_prime Int.prime_two, - PartENat.coe_lt_coe, ← mem_range] + rw [emultiplicity_sub_of_gt, emultiplicity_pow_self_of_prime Int.prime_two] + rwa [emultiplicity_pow_self_of_prime Int.prime_two, + emultiplicity_pow_self_of_prime Int.prime_two, Nat.cast_lt, ← mem_range] rw [← not_le]; intro hn apply _root_.ne_of_gt _ h calc ∏ i ∈ range n, ((2:ℤ) ^ n - (2:ℤ) ^ i) ≤ ∏ __ ∈ range n, (2:ℤ) ^ n := ?_ diff --git a/Archive/Wiedijk100Theorems/PerfectNumbers.lean b/Archive/Wiedijk100Theorems/PerfectNumbers.lean index e23628d48b3e34..27d3179b650515 100644 --- a/Archive/Wiedijk100Theorems/PerfectNumbers.lean +++ b/Archive/Wiedijk100Theorems/PerfectNumbers.lean @@ -55,12 +55,12 @@ theorem even_two_pow_mul_mersenne_of_prime (k : ℕ) (pr : (mersenne (k + 1)).Pr Even (2 ^ k * mersenne (k + 1)) := by simp [ne_zero_of_prime_mersenne k pr, parity_simps] theorem eq_two_pow_mul_odd {n : ℕ} (hpos : 0 < n) : ∃ k m : ℕ, n = 2 ^ k * m ∧ ¬Even m := by - have h := multiplicity.finite_nat_iff.2 ⟨Nat.prime_two.ne_one, hpos⟩ - cases' multiplicity.pow_multiplicity_dvd h with m hm - use (multiplicity 2 n).get h, m + have h := Nat.multiplicity_finite_iff.2 ⟨Nat.prime_two.ne_one, hpos⟩ + cases' pow_multiplicity_dvd 2 n with m hm + use multiplicity 2 n, m refine ⟨hm, ?_⟩ rw [even_iff_two_dvd] - have hg := multiplicity.is_greatest' h (Nat.lt_succ_self _) + have hg := h.not_pow_dvd_of_multiplicity_lt (Nat.lt_succ_self _) contrapose! hg rcases hg with ⟨k, rfl⟩ apply Dvd.intro k diff --git a/Mathlib/Algebra/Polynomial/Div.lean b/Mathlib/Algebra/Polynomial/Div.lean index 7ac2f94a0beb8a..50f666e013f114 100644 --- a/Mathlib/Algebra/Polynomial/Div.lean +++ b/Mathlib/Algebra/Polynomial/Div.lean @@ -502,11 +502,17 @@ theorem rootMultiplicity_eq_nat_find_of_nonzero [DecidableEq R] {p : R[X]} (p0 : cases Subsingleton.elim ‹DecidableEq R› (Classical.decEq R) rw [dif_neg p0] -theorem rootMultiplicity_eq_multiplicity [DecidableEq R] [@DecidableRel R[X] (· ∣ ·)] +theorem rootMultiplicity_eq_multiplicity [DecidableEq R] (p : R[X]) (a : R) : rootMultiplicity a p = - if h0 : p = 0 then 0 else (multiplicity (X - C a) p).get (multiplicity_X_sub_C_finite a h0) := - by simp only [rootMultiplicity, multiplicity, PartENat.find_get]; congr; funext; congr + if p = 0 then 0 else multiplicity (X - C a) p := by + simp only [rootMultiplicity, multiplicity, emultiplicity] + split + · rfl + rename_i h + simp only [multiplicity_X_sub_C_finite a h, ↓reduceDIte] + rw [← ENat.some_eq_coe, WithTop.untop'_coe] + congr @[simp] theorem rootMultiplicity_zero {x : R} : rootMultiplicity x 0 = 0 := @@ -521,15 +527,14 @@ theorem rootMultiplicity_C (r a : R) : rootMultiplicity a (C r) = 0 := by split_ifs with hr · rfl have h : natDegree (C r) < natDegree (X - C a) := by simp - simp_rw [multiplicity.multiplicity_eq_zero.mpr ((monic_X_sub_C a).not_dvd_of_natDegree_lt hr h), - PartENat.get_zero] + simp_rw [multiplicity_eq_zero.mpr ((monic_X_sub_C a).not_dvd_of_natDegree_lt hr h)] theorem pow_rootMultiplicity_dvd (p : R[X]) (a : R) : (X - C a) ^ rootMultiplicity a p ∣ p := letI := Classical.decEq R if h : p = 0 then by simp [h] else by classical - rw [rootMultiplicity_eq_multiplicity, dif_neg h]; exact multiplicity.pow_multiplicity_dvd _ + rw [rootMultiplicity_eq_multiplicity, if_neg 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 @@ -542,8 +547,8 @@ 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, dif_neg hp] - apply multiplicity.exists_eq_pow_mul_and_not_dvd + rw [rootMultiplicity_eq_multiplicity, if_neg hp] + apply (multiplicity_X_sub_C_finite a hp).exists_eq_pow_mul_and_not_dvd end multiplicity @@ -618,8 +623,8 @@ theorem ker_evalRingHom (x : R) : RingHom.ker (evalRingHom x) = Ideal.span {X - theorem rootMultiplicity_eq_zero_iff {p : R[X]} {x : R} : rootMultiplicity x p = 0 ↔ IsRoot p x → p = 0 := by classical - simp only [rootMultiplicity_eq_multiplicity, dite_eq_left_iff, PartENat.get_eq_iff_eq_coe, - Nat.cast_zero, multiplicity.multiplicity_eq_zero, dvd_iff_isRoot, not_imp_not] + simp only [rootMultiplicity_eq_multiplicity, ite_eq_left_iff, + Nat.cast_zero, multiplicity_eq_zero, dvd_iff_isRoot, not_imp_not] theorem rootMultiplicity_eq_zero {p : R[X]} {x : R} (h : ¬IsRoot p x) : rootMultiplicity x p = 0 := rootMultiplicity_eq_zero_iff.2 fun h' => (h h').elim @@ -640,12 +645,11 @@ 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, dif_neg hp] at this + rw [hq, ← mul_assoc, ← pow_succ, rootMultiplicity_eq_multiplicity, if_neg hp] at this exact - multiplicity.is_greatest' - (multiplicity_finite_of_degree_pos_of_monic - (show (0 : WithBot ℕ) < degree (X - C a) by rw [degree_X_sub_C]; decide) - (monic_X_sub_C _) hp) + (multiplicity_finite_of_degree_pos_of_monic + (show (0 : WithBot ℕ) < degree (X - C a) by rw [degree_X_sub_C]; decide) + (monic_X_sub_C _) hp).not_pow_dvd_of_multiplicity_lt (Nat.lt_succ_self _) (dvd_of_mul_right_eq _ this) /-- See `Polynomial.mul_right_modByMonic` for the other multiplication order. This version, unlike diff --git a/Mathlib/Algebra/Polynomial/RingDivision.lean b/Mathlib/Algebra/Polynomial/RingDivision.lean index 2cd957ced397df..b93ceffe37ce4b 100644 --- a/Mathlib/Algebra/Polynomial/RingDivision.lean +++ b/Mathlib/Algebra/Polynomial/RingDivision.lean @@ -450,9 +450,9 @@ theorem rootMultiplicity_eq_rootMultiplicity {p : R[X]} {t : R} : p.rootMultiplicity t = (p.comp (X + C t)).rootMultiplicity 0 := by classical simp_rw [rootMultiplicity_eq_multiplicity, comp_X_add_C_eq_zero_iff] - congr; ext; congr 1 + congr 1 rw [C_0, sub_zero] - convert (multiplicity.multiplicity_map_eq <| algEquivAevalXAddC t).symm using 2 + convert (multiplicity_map_eq <| algEquivAevalXAddC t).symm using 2 simp [C_eq_algebraMap] theorem rootMultiplicity_eq_natTrailingDegree' {p : R[X]} : @@ -736,9 +736,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), dif_neg hpq, rootMultiplicity_eq_multiplicity p, - dif_neg hp, rootMultiplicity_eq_multiplicity q, dif_neg hq, - multiplicity.mul' (prime_X_sub_C x)] + 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) (multiplicity_X_sub_C_finite _ hpq)] open Multiset in set_option linter.unusedVariables false in diff --git a/Mathlib/Algebra/Squarefree/Basic.lean b/Mathlib/Algebra/Squarefree/Basic.lean index 2ae3fd080cb056..935cf00ec3b268 100644 --- a/Mathlib/Algebra/Squarefree/Basic.lean +++ b/Mathlib/Algebra/Squarefree/Basic.lean @@ -17,8 +17,8 @@ Results about squarefree natural numbers are proved in `Data.Nat.Squarefree`. - `Squarefree r` indicates that `r` is only divisible by `x * x` if `x` is a unit. ## Main Results - - `multiplicity.squarefree_iff_multiplicity_le_one`: `x` is `Squarefree` iff for every `y`, either - `multiplicity y x ≤ 1` or `IsUnit y`. + - `multiplicity.squarefree_iff_emultiplicity_le_one`: `x` is `Squarefree` iff for every `y`, either + `emultiplicity y x ≤ 1` or `IsUnit y`. - `UniqueFactorizationMonoid.squarefree_iff_nodup_factors`: A nonzero element `x` of a unique factorization monoid is squarefree iff `factors x` has no duplicate factors. @@ -101,15 +101,15 @@ namespace multiplicity section CommMonoid -variable [CommMonoid R] [DecidableRel (Dvd.dvd : R → R → Prop)] +variable [CommMonoid R] -theorem squarefree_iff_multiplicity_le_one (r : R) : - Squarefree r ↔ ∀ x : R, multiplicity x r ≤ 1 ∨ IsUnit x := by +theorem squarefree_iff_emultiplicity_le_one (r : R) : + Squarefree r ↔ ∀ x : R, emultiplicity x r ≤ 1 ∨ IsUnit x := by refine forall_congr' fun a => ?_ - rw [← sq, pow_dvd_iff_le_multiplicity, or_iff_not_imp_left, not_le, imp_congr _ Iff.rfl] + rw [← sq, pow_dvd_iff_le_emultiplicity, or_iff_not_imp_left, not_le, imp_congr _ Iff.rfl] norm_cast rw [← one_add_one_eq_two] - simpa using PartENat.add_one_le_iff_lt (PartENat.natCast_ne_top 1) + exact Order.add_one_le_iff_of_not_isMax (by simp) end CommMonoid @@ -260,14 +260,14 @@ lemma _root_.exists_squarefree_dvd_pow_of_ne_zero {x : R} (hx : x ≠ 0) : theorem squarefree_iff_nodup_normalizedFactors [NormalizationMonoid R] {x : R} (x0 : x ≠ 0) : Squarefree x ↔ Multiset.Nodup (normalizedFactors x) := by classical - rw [multiplicity.squarefree_iff_multiplicity_le_one, Multiset.nodup_iff_count_le_one] + rw [multiplicity.squarefree_iff_emultiplicity_le_one, Multiset.nodup_iff_count_le_one] haveI := nontrivial_of_ne x 0 x0 constructor <;> intro h a · by_cases hmem : a ∈ normalizedFactors x · have ha := irreducible_of_normalized_factor _ hmem rcases h a with (h | h) · rw [← normalize_normalized_factor _ hmem] - rw [multiplicity_eq_count_normalizedFactors ha x0] at h + rw [emultiplicity_eq_count_normalizedFactors ha x0] at h assumption_mod_cast · have := ha.1 contradiction @@ -277,8 +277,8 @@ theorem squarefree_iff_nodup_normalizedFactors [NormalizationMonoid R] {x : R} rcases eq_or_ne a 0 with rfl | h0 · simp [x0] rcases WfDvdMonoid.exists_irreducible_factor hu h0 with ⟨b, hib, hdvd⟩ - apply le_trans (multiplicity.multiplicity_le_multiplicity_of_dvd_left hdvd) - rw [multiplicity_eq_count_normalizedFactors hib x0] + apply le_trans (emultiplicity_le_emultiplicity_of_dvd_left hdvd) + rw [emultiplicity_eq_count_normalizedFactors hib x0] exact_mod_cast h (normalize b) end UniqueFactorizationMonoid diff --git a/Mathlib/Data/Nat/Choose/Factorization.lean b/Mathlib/Data/Nat/Choose/Factorization.lean index 258c4eb897817c..0c80076046db86 100644 --- a/Mathlib/Data/Nat/Choose/Factorization.lean +++ b/Mathlib/Data/Nat/Choose/Factorization.lean @@ -39,8 +39,10 @@ theorem factorization_choose_le_log : (choose n k).factorization p ≤ log p n : refine le_of_not_lt fun hnk => h ?_ simp [choose_eq_zero_of_lt hnk] rw [factorization_def _ hp, @padicValNat_def _ ⟨hp⟩ _ (choose_pos hkn)] - simp only [hp.multiplicity_choose hkn (lt_add_one _), PartENat.get_natCast] + rw [← Nat.cast_le (α := ℕ∞), ← multiplicity.Finite.emultiplicity_eq_multiplicity] + simp only [hp.emultiplicity_choose hkn (lt_add_one _), Nat.cast_le] exact (Finset.card_filter_le _ _).trans (le_of_eq (Nat.card_Ico _ _)) + apply Nat.multiplicity_finite_iff.2 ⟨hp.ne_one, choose_pos hkn⟩ /-- A `pow` form of `Nat.factorization_choose_le` -/ theorem pow_factorization_choose_le (hn : 0 < n) : p ^ (choose n k).factorization p ≤ n := @@ -59,8 +61,9 @@ theorem factorization_choose_of_lt_three_mul (hp' : p ≠ 2) (hk : p ≤ k) (hk' · exact factorization_eq_zero_of_non_prime (choose n k) hp cases' lt_or_le n k with hnk hkn · simp [choose_eq_zero_of_lt hnk] - rw [factorization_def _ hp, @padicValNat_def _ ⟨hp⟩ _ (choose_pos hkn)] - simp only [hp.multiplicity_choose hkn (lt_add_one _), PartENat.get_natCast, Finset.card_eq_zero, + rw [factorization_def _ hp, @padicValNat_def _ ⟨hp⟩ _ (choose_pos hkn), + ← emultiplicity_eq_zero_iff_multiplicity_eq_zero] + simp only [hp.emultiplicity_choose hkn (lt_add_one _), cast_eq_zero, Finset.card_eq_zero, Finset.filter_eq_empty_iff, not_le] intro i hi rcases eq_or_lt_of_le (Finset.mem_Ico.mp hi).1 with (rfl | hi) diff --git a/Mathlib/Data/Nat/Factorization/Basic.lean b/Mathlib/Data/Nat/Factorization/Basic.lean index 27ddcf0d3a424a..17af0fffcfa82d 100644 --- a/Mathlib/Data/Nat/Factorization/Basic.lean +++ b/Mathlib/Data/Nat/Factorization/Basic.lean @@ -235,8 +235,7 @@ and `n'` such that `n'` is not divisible by `p` and `n = p^e * n'`. -/ theorem exists_eq_pow_mul_and_not_dvd {n : ℕ} (hn : n ≠ 0) (p : ℕ) (hp : p ≠ 1) : ∃ e n' : ℕ, ¬p ∣ n' ∧ n = p ^ e * n' := let ⟨a', h₁, h₂⟩ := - multiplicity.exists_eq_pow_mul_and_not_dvd - (multiplicity.finite_nat_iff.mpr ⟨hp, Nat.pos_of_ne_zero hn⟩) + (Nat.multiplicity_finite_iff.mpr ⟨hp, Nat.pos_of_ne_zero hn⟩).exists_eq_pow_mul_and_not_dvd ⟨_, a', h₂, h₁⟩ /-- Any nonzero natural number is the product of an odd part `m` and a power of diff --git a/Mathlib/Data/Nat/Multiplicity.lean b/Mathlib/Data/Nat/Multiplicity.lean index 2c3b620821b988..e86d693f824f58 100644 --- a/Mathlib/Data/Nat/Multiplicity.lean +++ b/Mathlib/Data/Nat/Multiplicity.lean @@ -56,58 +56,62 @@ namespace Nat /-- The multiplicity of `m` in `n` is the number of positive natural numbers `i` such that `m ^ i` divides `n`. This set is expressed by filtering `Ico 1 b` where `b` is any bound greater than `log m n`. -/ -theorem multiplicity_eq_card_pow_dvd {m n b : ℕ} (hm : m ≠ 1) (hn : 0 < n) (hb : log m n < b) : - multiplicity m n = ↑((Finset.Ico 1 b).filter fun i => m ^ i ∣ n).card := +theorem emultiplicity_eq_card_pow_dvd {m n b : ℕ} (hm : m ≠ 1) (hn : 0 < n) (hb : log m n < b) : + emultiplicity m n = ↑((Finset.Ico 1 b).filter fun i => m ^ i ∣ n).card := + have fin := Nat.multiplicity_finite_iff.2 ⟨hm, hn⟩ calc - multiplicity m n = ↑(Ico 1 <| (multiplicity m n).get (finite_nat_iff.2 ⟨hm, hn⟩) + 1).card := by - simp + emultiplicity m n = ↑(Ico 1 <| multiplicity m n + 1).card := by + simp [fin.emultiplicity_eq_multiplicity] _ = ↑((Finset.Ico 1 b).filter fun i => m ^ i ∣ n).card := congr_arg _ <| congr_arg card <| Finset.ext fun i => by - rw [mem_filter, mem_Ico, mem_Ico, Nat.lt_succ_iff, ← @PartENat.coe_le_coe i, - PartENat.natCast_get, ← pow_dvd_iff_le_multiplicity, and_right_comm] - refine (and_iff_left_of_imp fun h => lt_of_le_of_lt ?_ hb).symm + simp only [mem_Ico, Nat.lt_succ_iff, + fin.pow_dvd_iff_le_multiplicity, mem_filter, + and_assoc, and_congr_right_iff, iff_and_self] + intro hi h + rw [← fin.pow_dvd_iff_le_multiplicity] at h cases' m with m · rw [zero_pow, zero_dvd_iff] at h - exacts [(hn.ne' h.2).elim, one_le_iff_ne_zero.1 h.1] + exacts [(hn.ne' h).elim, one_le_iff_ne_zero.1 hi] + refine LE.le.trans_lt ?_ hb exact le_log_of_pow_le (one_lt_iff_ne_zero_and_ne_one.2 ⟨m.succ_ne_zero, hm⟩) - (le_of_dvd hn h.2) + (le_of_dvd hn h) namespace Prime -theorem multiplicity_one {p : ℕ} (hp : p.Prime) : multiplicity p 1 = 0 := - multiplicity.one_right hp.prime.not_unit +theorem emultiplicity_one {p : ℕ} (hp : p.Prime) : emultiplicity p 1 = 0 := + emultiplicity_of_one_right hp.prime.not_unit -theorem multiplicity_mul {p m n : ℕ} (hp : p.Prime) : - multiplicity p (m * n) = multiplicity p m + multiplicity p n := - multiplicity.mul hp.prime +theorem emultiplicity_mul {p m n : ℕ} (hp : p.Prime) : + emultiplicity p (m * n) = emultiplicity p m + emultiplicity p n := + _root_.emultiplicity_mul hp.prime -theorem multiplicity_pow {p m n : ℕ} (hp : p.Prime) : - multiplicity p (m ^ n) = n • multiplicity p m := - multiplicity.pow hp.prime +theorem emultiplicity_pow {p m n : ℕ} (hp : p.Prime) : + emultiplicity p (m ^ n) = n * emultiplicity p m := + _root_.emultiplicity_pow hp.prime -theorem multiplicity_self {p : ℕ} (hp : p.Prime) : multiplicity p p = 1 := - multiplicity.multiplicity_self hp.prime.not_unit hp.ne_zero +theorem emultiplicity_self {p : ℕ} (hp : p.Prime) : emultiplicity p p = 1 := + (Nat.multiplicity_finite_iff.2 ⟨hp.ne_one, hp.pos⟩).emultiplicity_self -theorem multiplicity_pow_self {p n : ℕ} (hp : p.Prime) : multiplicity p (p ^ n) = n := - multiplicity.multiplicity_pow_self hp.ne_zero hp.prime.not_unit n +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 /-- **Legendre's Theorem** The multiplicity of a prime in `n!` is the sum of the quotients `n / p ^ i`. This sum is expressed over the finset `Ico 1 b` where `b` is any bound greater than `log p n`. -/ -theorem multiplicity_factorial {p : ℕ} (hp : p.Prime) : - ∀ {n b : ℕ}, log p n < b → multiplicity p n ! = (∑ i ∈ Ico 1 b, n / p ^ i : ℕ) - | 0, b, _ => by simp [Ico, hp.multiplicity_one] +theorem emultiplicity_factorial {p : ℕ} (hp : p.Prime) : + ∀ {n b : ℕ}, log p n < b → emultiplicity p n ! = (∑ i ∈ Ico 1 b, n / p ^ i : ℕ) + | 0, b, _ => by simp [Ico, hp.emultiplicity_one] | n + 1, b, hb => calc - multiplicity p (n + 1)! = multiplicity p n ! + multiplicity p (n + 1) := by - rw [factorial_succ, hp.multiplicity_mul, add_comm] + emultiplicity p (n + 1)! = emultiplicity p n ! + emultiplicity p (n + 1) := by + rw [factorial_succ, hp.emultiplicity_mul, add_comm] _ = (∑ i ∈ Ico 1 b, n / p ^ i : ℕ) + ((Finset.Ico 1 b).filter fun i => p ^ i ∣ n + 1).card := by - rw [multiplicity_factorial hp ((log_mono_right <| le_succ _).trans_lt hb), ← - multiplicity_eq_card_pow_dvd hp.ne_one (succ_pos _) hb] + rw [emultiplicity_factorial hp ((log_mono_right <| le_succ _).trans_lt hb), ← + emultiplicity_eq_card_pow_dvd hp.ne_one (succ_pos _) hb] _ = (∑ i ∈ Ico 1 b, (n / p ^ i + if p ^ i ∣ n + 1 then 1 else 0) : ℕ) := by rw [sum_add_distrib, sum_boole] simp @@ -117,44 +121,44 @@ theorem multiplicity_factorial {p : ℕ} (hp : p.Prime) : /-- For a prime number `p`, taking `(p - 1)` times the multiplicity of `p` in `n!` equals `n` minus the sum of base `p` digits of `n`. -/ theorem sub_one_mul_multiplicity_factorial {n p : ℕ} (hp : p.Prime) : - (p - 1) * (multiplicity p n !).get (finite_nat_iff.mpr ⟨hp.ne_one, factorial_pos n⟩) = + (p - 1) * multiplicity p n ! = n - (p.digits n).sum := by - simp only [multiplicity_factorial hp <| lt_succ_of_lt <| lt.base (log p n), - ← Finset.sum_Ico_add' _ 0 _ 1, Ico_zero_eq_range, - ← sub_one_mul_sum_log_div_pow_eq_sub_sum_digits] - rfl + simp only [multiplicity_eq_of_emultiplicity_eq_some <| + emultiplicity_factorial hp <| lt_succ_of_lt <| lt.base (log p n), + ← Finset.sum_Ico_add' _ 0 _ 1, Ico_zero_eq_range, ← + sub_one_mul_sum_log_div_pow_eq_sub_sum_digits] /-- The multiplicity of `p` in `(p * (n + 1))!` is one more than the sum of the multiplicities of `p` in `(p * n)!` and `n + 1`. -/ -theorem multiplicity_factorial_mul_succ {n p : ℕ} (hp : p.Prime) : - multiplicity p (p * (n + 1))! = multiplicity p (p * n)! + multiplicity p (n + 1) + 1 := by +theorem emultiplicity_factorial_mul_succ {n p : ℕ} (hp : p.Prime) : + emultiplicity p (p * (n + 1))! = emultiplicity p (p * n)! + emultiplicity p (n + 1) + 1 := by have hp' := hp.prime have h0 : 2 ≤ p := hp.two_le have h1 : 1 ≤ p * n + 1 := Nat.le_add_left _ _ have h2 : p * n + 1 ≤ p * (n + 1) := by linarith have h3 : p * n + 1 ≤ p * (n + 1) + 1 := by omega - have hm : multiplicity p (p * n)! ≠ ⊤ := by - rw [Ne, eq_top_iff_not_finite, Classical.not_not, finite_nat_iff] + have hm : emultiplicity p (p * n)! ≠ ⊤ := by + rw [Ne, emultiplicity_eq_top, Classical.not_not, Nat.multiplicity_finite_iff] exact ⟨hp.ne_one, factorial_pos _⟩ revert hm - have h4 : ∀ m ∈ Ico (p * n + 1) (p * (n + 1)), multiplicity p m = 0 := by + have h4 : ∀ m ∈ Ico (p * n + 1) (p * (n + 1)), emultiplicity p m = 0 := by intro m hm - rw [multiplicity_eq_zero, ← not_dvd_iff_between_consec_multiples _ hp.pos] + rw [emultiplicity_eq_zero, ← not_dvd_iff_between_consec_multiples _ hp.pos] rw [mem_Ico] at hm exact ⟨n, lt_of_succ_le hm.1, hm.2⟩ - simp_rw [← prod_Ico_id_eq_factorial, multiplicity.Finset.prod hp', ← sum_Ico_consecutive _ h1 h3, + simp_rw [← prod_Ico_id_eq_factorial, Finset.emultiplicity_prod hp', ← sum_Ico_consecutive _ h1 h3, add_assoc] intro h - rw [PartENat.add_left_cancel_iff h, sum_Ico_succ_top h2, multiplicity.mul hp', - hp.multiplicity_self, sum_congr rfl h4, sum_const_zero, zero_add, add_comm (1 : PartENat)] + rw [WithTop.add_left_cancel_iff h, sum_Ico_succ_top h2, hp.emultiplicity_mul, + hp.emultiplicity_self, sum_congr rfl h4, sum_const_zero, zero_add, add_comm 1] /-- The multiplicity of `p` in `(p * n)!` is `n` more than that of `n!`. -/ -theorem multiplicity_factorial_mul {n p : ℕ} (hp : p.Prime) : - multiplicity p (p * n)! = multiplicity p n ! + n := by +theorem emultiplicity_factorial_mul {n p : ℕ} (hp : p.Prime) : + emultiplicity p (p * n)! = emultiplicity p n ! + n := by induction' n with n ih · simp - · simp only [succ_eq_add_one, multiplicity.mul, hp, hp.prime, ih, multiplicity_factorial_mul_succ, - ← add_assoc, Nat.cast_one, Nat.cast_add, factorial_succ] + · simp only [hp, emultiplicity_factorial_mul_succ, ih, factorial_succ, emultiplicity_mul, + cast_add, cast_one, ← add_assoc] congr 1 rw [add_comm, add_assoc] @@ -162,11 +166,13 @@ theorem multiplicity_factorial_mul {n p : ℕ} (hp : p.Prime) : 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 [← PartENat.coe_le_coe, ← hp.multiplicity_factorial hbn, ← pow_dvd_iff_le_multiplicity] + rw [← WithTop.coe_le_coe, ENat.some_eq_coe, ← hp.emultiplicity_factorial hbn, + pow_dvd_iff_le_emultiplicity] -theorem multiplicity_factorial_le_div_pred {p : ℕ} (hp : p.Prime) (n : ℕ) : - multiplicity p n ! ≤ (n / (p - 1) : ℕ) := by - rw [hp.multiplicity_factorial (lt_succ_self _), PartENat.coe_le_coe] +theorem emultiplicity_factorial_le_div_pred {p : ℕ} (hp : p.Prime) (n : ℕ) : + emultiplicity p n ! ≤ (n / (p - 1) : ℕ) := by + rw [hp.emultiplicity_factorial (lt_succ_self _)] + apply WithTop.coe_mono exact Nat.geom_sum_Ico_le hp.two_le _ _ theorem multiplicity_choose_aux {p n b k : ℕ} (hp : p.Prime) (hkn : k ≤ n) : @@ -184,50 +190,50 @@ theorem multiplicity_choose_aux {p n b k : ℕ} (hp : p.Prime) (hkn : k ≤ n) : /-- The multiplicity of `p` in `choose (n + k) k` is the number of carries when `k` and `n` are added in base `p`. The set is expressed by filtering `Ico 1 b` where `b` is any bound greater than `log p (n + k)`. -/ -theorem multiplicity_choose' {p n k b : ℕ} (hp : p.Prime) (hnb : log p (n + k) < b) : - multiplicity p (choose (n + k) k) = +theorem emultiplicity_choose' {p n k b : ℕ} (hp : p.Prime) (hnb : log p (n + k) < b) : + emultiplicity p (choose (n + k) k) = ((Ico 1 b).filter fun i => p ^ i ≤ k % p ^ i + n % p ^ i).card := by have h₁ : - multiplicity p (choose (n + k) k) + multiplicity p (k ! * n !) = + emultiplicity p (choose (n + k) k) + emultiplicity p (k ! * n !) = ((Finset.Ico 1 b).filter fun i => p ^ i ≤ k % p ^ i + n % p ^ i).card + - multiplicity p (k ! * n !) := by - rw [← hp.multiplicity_mul, ← mul_assoc] + emultiplicity p (k ! * n !) := by + rw [← hp.emultiplicity_mul, ← mul_assoc] have := (add_tsub_cancel_right n k) ▸ choose_mul_factorial_mul_factorial (le_add_left k n) - rw [this, hp.multiplicity_factorial hnb, hp.multiplicity_mul, - hp.multiplicity_factorial ((log_mono_right (le_add_left k n)).trans_lt hnb), - hp.multiplicity_factorial ((log_mono_right (le_add_left n k)).trans_lt + rw [this, hp.emultiplicity_factorial hnb, hp.emultiplicity_mul, + hp.emultiplicity_factorial ((log_mono_right (le_add_left k n)).trans_lt hnb), + hp.emultiplicity_factorial ((log_mono_right (le_add_left n k)).trans_lt (add_comm n k ▸ hnb)), multiplicity_choose_aux hp (le_add_left k n)] simp [add_comm] - refine (PartENat.add_right_cancel_iff ?_).1 h₁ - apply PartENat.ne_top_iff_dom.2 - exact finite_nat_iff.2 ⟨hp.ne_one, mul_pos (factorial_pos k) (factorial_pos n)⟩ + refine (WithTop.add_right_cancel_iff ?_).1 h₁ + apply finite_iff_emultiplicity_ne_top.1 + exact Nat.multiplicity_finite_iff.2 ⟨hp.ne_one, mul_pos (factorial_pos k) (factorial_pos n)⟩ /-- The multiplicity of `p` in `choose n k` is the number of carries when `k` and `n - k` are added in base `p`. The set is expressed by filtering `Ico 1 b` where `b` is any bound greater than `log p n`. -/ -theorem multiplicity_choose {p n k b : ℕ} (hp : p.Prime) (hkn : k ≤ n) (hnb : log p n < b) : - multiplicity p (choose n k) = +theorem emultiplicity_choose {p n k b : ℕ} (hp : p.Prime) (hkn : k ≤ n) (hnb : log p n < b) : + emultiplicity p (choose n k) = ((Ico 1 b).filter fun i => p ^ i ≤ k % p ^ i + (n - k) % p ^ i).card := by have := Nat.sub_add_cancel hkn - convert @multiplicity_choose' p (n - k) k b hp _ + convert @emultiplicity_choose' p (n - k) k b hp _ · rw [this] exact this.symm ▸ hnb /-- A lower bound on the multiplicity of `p` in `choose n k`. -/ -theorem multiplicity_le_multiplicity_choose_add {p : ℕ} (hp : p.Prime) : - ∀ n k : ℕ, multiplicity p n ≤ multiplicity p (choose n k) + multiplicity p k +theorem emultiplicity_le_emultiplicity_choose_add {p : ℕ} (hp : p.Prime) : + ∀ n k : ℕ, emultiplicity p n ≤ emultiplicity p (choose n k) + emultiplicity p k | _, 0 => by simp | 0, _ + 1 => by simp | n + 1, k + 1 => by - rw [← hp.multiplicity_mul] - refine multiplicity_le_multiplicity_of_dvd_right ?_ + rw [← hp.emultiplicity_mul] + refine emultiplicity_le_emultiplicity_of_dvd_right ?_ rw [← succ_mul_choose_eq] exact dvd_mul_right _ _ variable {p n k : ℕ} -theorem multiplicity_choose_prime_pow_add_multiplicity (hp : p.Prime) (hkn : k ≤ p ^ n) - (hk0 : k ≠ 0) : multiplicity p (choose (p ^ n) k) + multiplicity p k = n := +theorem emultiplicity_choose_prime_pow_add_emultiplicity (hp : p.Prime) (hkn : k ≤ p ^ n) + (hk0 : k ≠ 0) : emultiplicity p (choose (p ^ n) k) + emultiplicity p k = n := le_antisymm (by have hdisj : @@ -235,28 +241,32 @@ theorem multiplicity_choose_prime_pow_add_multiplicity (hp : p.Prime) (hkn : k ((Ico 1 n.succ).filter fun i => p ^ i ∣ k) := by simp (config := { contextual := true }) [disjoint_right, *, dvd_iff_mod_eq_zero, Nat.mod_lt _ (pow_pos hp.pos _)] - rw [multiplicity_choose hp hkn (lt_succ_self _), - multiplicity_eq_card_pow_dvd (ne_of_gt hp.one_lt) hk0.bot_lt + rw [emultiplicity_choose hp hkn (lt_succ_self _), + emultiplicity_eq_card_pow_dvd (ne_of_gt hp.one_lt) hk0.bot_lt (lt_succ_of_le (log_mono_right hkn)), - ← Nat.cast_add, PartENat.coe_le_coe, log_pow hp.one_lt, ← card_union_of_disjoint hdisj, - filter_union_right] + ← Nat.cast_add] + apply WithTop.coe_mono + rw [log_pow hp.one_lt, ← card_union_of_disjoint hdisj, filter_union_right] have filter_le_Ico := (Ico 1 n.succ).card_filter_le fun x => p ^ x ≤ k % p ^ x + (p ^ n - k) % p ^ x ∨ p ^ x ∣ k rwa [card_Ico 1 n.succ] at filter_le_Ico) - (by rw [← hp.multiplicity_pow_self]; exact multiplicity_le_multiplicity_choose_add hp _ _) + (by rw [← hp.emultiplicity_pow_self]; exact emultiplicity_le_emultiplicity_choose_add hp _ _) -theorem multiplicity_choose_prime_pow {p n k : ℕ} (hp : p.Prime) (hkn : k ≤ p ^ n) (hk0 : k ≠ 0) : - multiplicity p (choose (p ^ n) k) = - ↑(n - (multiplicity p k).get (finite_nat_iff.2 ⟨hp.ne_one, hk0.bot_lt⟩)) := - PartENat.eq_natCast_sub_of_add_eq_natCast <| - multiplicity_choose_prime_pow_add_multiplicity hp hkn hk0 +theorem emultiplicity_choose_prime_pow {p n k : ℕ} (hp : p.Prime) (hkn : k ≤ p ^ n) (hk0 : k ≠ 0) : + emultiplicity p (choose (p ^ n) k) = ↑(n - multiplicity p k) := by + push_cast + rw [← emultiplicity_choose_prime_pow_add_emultiplicity hp hkn hk0, + (multiplicity_finite_iff.2 ⟨hp.ne_one, Nat.pos_of_ne_zero hk0⟩).emultiplicity_eq_multiplicity, + (multiplicity_finite_iff.2 ⟨hp.ne_one, choose_pos hkn⟩).emultiplicity_eq_multiplicity] + norm_cast + rw [Nat.add_sub_cancel_right] theorem dvd_choose_pow (hp : Prime p) (hk : k ≠ 0) (hkp : k ≠ p ^ n) : p ∣ (p ^ n).choose k := by obtain hkp | hkp := hkp.symm.lt_or_lt · simp [choose_eq_zero_of_lt hkp] - refine multiplicity_ne_zero.1 fun h => hkp.not_le <| Nat.le_of_dvd hk.bot_lt ?_ - have H := hp.multiplicity_choose_prime_pow_add_multiplicity hkp.le hk - rw [h, zero_add, eq_coe_iff] at H + refine emultiplicity_ne_zero.1 fun h => hkp.not_le <| Nat.le_of_dvd hk.bot_lt ?_ + have H := hp.emultiplicity_choose_prime_pow_add_emultiplicity hkp.le hk + rw [h, zero_add, emultiplicity_eq_coe] at H exact H.1 theorem dvd_choose_pow_iff (hp : Prime p) : p ∣ (p ^ n).choose k ↔ k ≠ 0 ∧ k ≠ p ^ n := by @@ -265,7 +275,7 @@ theorem dvd_choose_pow_iff (hp : Prime p) : p ∣ (p ^ n).choose k ↔ k ≠ 0 end Prime -theorem multiplicity_two_factorial_lt : ∀ {n : ℕ} (_ : n ≠ 0), multiplicity 2 n ! < n := by +theorem emultiplicity_two_factorial_lt : ∀ {n : ℕ} (_ : n ≠ 0), emultiplicity 2 n ! < n := by have h2 := prime_two.prime refine binaryRec ?_ ?_ · exact fun h => False.elim <| h rfl @@ -274,19 +284,20 @@ theorem multiplicity_two_factorial_lt : ∀ {n : ℕ} (_ : n ≠ 0), multiplicit · subst hn simp only [ne_eq, bit_eq_zero, true_and, Bool.not_eq_false] at h simp only [h, bit_true, factorial, mul_one, Nat.isUnit_iff, cast_one] - rw [Prime.multiplicity_one] + rw [Prime.emultiplicity_one] · simp [zero_lt_one] · decide - have : multiplicity 2 (2 * n)! < (2 * n : ℕ) := by - rw [prime_two.multiplicity_factorial_mul] - refine (PartENat.add_lt_add_right (ih hn) (PartENat.natCast_ne_top _)).trans_le ?_ + have : emultiplicity 2 (2 * n)! < (2 * n : ℕ) := by + rw [prime_two.emultiplicity_factorial_mul] rw [two_mul] - norm_cast + push_cast + apply WithTop.add_lt_add_right _ (ih hn) + exact Ne.symm nofun cases b · simpa - · suffices multiplicity 2 (2 * n + 1) + multiplicity 2 (2 * n)! < ↑(2 * n) + 1 by - simpa [multiplicity.mul, h2, prime_two, bit, factorial] - rw [multiplicity_eq_zero.2 (two_not_dvd_two_mul_add_one n), zero_add] + · suffices emultiplicity 2 (2 * n + 1) + emultiplicity 2 (2 * n)! < ↑(2 * n) + 1 by + simpa [emultiplicity_mul, h2, prime_two, bit, factorial] + rw [emultiplicity_eq_zero.2 (two_not_dvd_two_mul_add_one n), zero_add] refine this.trans ?_ exact mod_cast lt_succ_self _ diff --git a/Mathlib/Data/Nat/Squarefree.lean b/Mathlib/Data/Nat/Squarefree.lean index d11d0033439342..8e1569f7118845 100644 --- a/Mathlib/Data/Nat/Squarefree.lean +++ b/Mathlib/Data/Nat/Squarefree.lean @@ -49,12 +49,12 @@ theorem _root_.Squarefree.natFactorization_le_one {n : ℕ} (p : ℕ) (hn : Squa n.factorization p ≤ 1 := by rcases eq_or_ne n 0 with (rfl | hn') · simp - rw [multiplicity.squarefree_iff_multiplicity_le_one] at hn + rw [multiplicity.squarefree_iff_emultiplicity_le_one] at hn by_cases hp : p.Prime · have := hn p - simp only [multiplicity_eq_factorization hp hn', Nat.isUnit_iff, hp.ne_one, or_false] - at this - exact mod_cast this + rw [← multiplicity_eq_factorization hp hn'] + simp only [Nat.isUnit_iff, hp.ne_one, or_false] at this + exact multiplicity_le_of_emultiplicity_le this · rw [factorization_eq_zero_of_non_prime _ hp] exact zero_le_one diff --git a/Mathlib/Data/Real/Irrational.lean b/Mathlib/Data/Real/Irrational.lean index 666201507c599b..62ea491e087231 100644 --- a/Mathlib/Data/Real/Irrational.lean +++ b/Mathlib/Data/Real/Irrational.lean @@ -68,24 +68,23 @@ theorem irrational_nrt_of_notint_nrt {x : ℝ} (n : ℕ) (m : ℤ) (hxr : x ^ n is irrational. -/ theorem irrational_nrt_of_n_not_dvd_multiplicity {x : ℝ} (n : ℕ) {m : ℤ} (hm : m ≠ 0) (p : ℕ) [hp : Fact p.Prime] (hxr : x ^ n = m) - (hv : (multiplicity (p : ℤ) m).get (finite_int_iff.2 ⟨hp.1.ne_one, hm⟩) % n ≠ 0) : + (hv : multiplicity (p : ℤ) m % n ≠ 0) : Irrational x := by rcases Nat.eq_zero_or_pos n with (rfl | hnpos) · rw [eq_comm, pow_zero, ← Int.cast_one, Int.cast_inj] at hxr - simp [hxr, multiplicity.one_right (mt isUnit_iff_dvd_one.1 + simp [hxr, multiplicity_of_one_right (mt isUnit_iff_dvd_one.1 (mt Int.natCast_dvd_natCast.1 hp.1.not_dvd_one)), Nat.zero_mod] at hv refine irrational_nrt_of_notint_nrt _ _ hxr ?_ hnpos rintro ⟨y, rfl⟩ rw [← Int.cast_pow, Int.cast_inj] at hxr subst m have : y ≠ 0 := by rintro rfl; rw [zero_pow hnpos.ne'] at hm; exact hm rfl - rw [multiplicity.pow' (Nat.prime_iff_prime_int.1 hp.1) (finite_int_iff.2 ⟨hp.1.ne_one, this⟩), - Nat.mul_mod_right] at hv + rw [(Int.multiplicity_finite_iff.2 ⟨by simp [hp.1.ne_one], this⟩).multiplicity_pow + (Nat.prime_iff_prime_int.1 hp.1), Nat.mul_mod_right] at hv exact hv rfl theorem irrational_sqrt_of_multiplicity_odd (m : ℤ) (hm : 0 < m) (p : ℕ) [hp : Fact p.Prime] - (Hpv : - (multiplicity (p : ℤ) m).get (finite_int_iff.2 ⟨hp.1.ne_one, (ne_of_lt hm).symm⟩) % 2 = 1) : + (Hpv : multiplicity (p : ℤ) m % 2 = 1) : Irrational (√m) := @irrational_nrt_of_n_not_dvd_multiplicity _ 2 _ (Ne.symm (ne_of_lt hm)) p hp (sq_sqrt (Int.cast_nonneg.2 <| le_of_lt hm)) (by rw [Hpv]; exact one_ne_zero) diff --git a/Mathlib/FieldTheory/Separable.lean b/Mathlib/FieldTheory/Separable.lean index 8060298a804950..edc1ae86fabce9 100644 --- a/Mathlib/FieldTheory/Separable.lean +++ b/Mathlib/FieldTheory/Separable.lean @@ -167,16 +167,13 @@ theorem isUnit_of_self_mul_dvd_separable {p q : R[X]} (hp : p.Separable) (hq : q ring exact IsCoprime.of_mul_right_left (IsCoprime.of_mul_left_left this) -theorem multiplicity_le_one_of_separable [DecidableRel fun (x : R[X]) x_1 ↦ x ∣ x_1] - {p q : R[X]} (hq : ¬IsUnit q) (hsep : Separable p) : - multiplicity q p ≤ 1 := by +theorem emultiplicity_le_one_of_separable {p q : R[X]} (hq : ¬IsUnit q) (hsep : Separable p) : + emultiplicity q p ≤ 1 := by contrapose! hq apply isUnit_of_self_mul_dvd_separable hsep rw [← sq] - apply multiplicity.pow_dvd_of_le_multiplicity - have h : ⟨Part.Dom 1 ∧ Part.Dom 1, fun _ ↦ 2⟩ ≤ multiplicity q p := PartENat.add_one_le_of_lt hq - rw [and_self] at h - exact h + apply pow_dvd_of_le_emultiplicity + exact Order.add_one_le_of_lt hq /-- A separable polynomial is square-free. @@ -184,8 +181,8 @@ See `PerfectField.separable_iff_squarefree` for the converse when the coefficien field. -/ theorem Separable.squarefree {p : R[X]} (hsep : Separable p) : Squarefree p := by classical - rw [multiplicity.squarefree_iff_multiplicity_le_one p] - exact fun f => or_iff_not_imp_right.mpr fun hunit => multiplicity_le_one_of_separable hunit hsep + rw [multiplicity.squarefree_iff_emultiplicity_le_one p] + exact fun f => or_iff_not_imp_right.mpr fun hunit => emultiplicity_le_one_of_separable hunit hsep end CommSemiring @@ -261,9 +258,9 @@ 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, dif_neg hp, ← PartENat.coe_le_coe, PartENat.natCast_get, - Nat.cast_one] - exact multiplicity_le_one_of_separable (not_isUnit_X_sub_C _) hsep + rw [rootMultiplicity_eq_multiplicity, if_neg hp, ← Nat.cast_le (α := ℕ∞), + Nat.cast_one, ← (multiplicity_X_sub_C_finite x hp).emultiplicity_eq_multiplicity] + apply emultiplicity_le_one_of_separable (not_isUnit_X_sub_C _) hsep end CommRing diff --git a/Mathlib/FieldTheory/SeparableDegree.lean b/Mathlib/FieldTheory/SeparableDegree.lean index fb1ec8ab2843c4..bc340b3686eefb 100644 --- a/Mathlib/FieldTheory/SeparableDegree.lean +++ b/Mathlib/FieldTheory/SeparableDegree.lean @@ -564,9 +564,9 @@ theorem eq_X_pow_char_pow_sub_C_pow_of_natSepDegree_eq_one (q : ℕ) [ExpChar F obtain ⟨n, y, H, hp⟩ := hM.eq_X_pow_char_pow_sub_C_of_natSepDegree_eq_one_of_irreducible q hI hD have hF := multiplicity_finite_of_degree_pos_of_monic (degree_pos_of_irreducible hI) hM hm.ne_zero classical - have hne := (multiplicity.pos_of_dvd hF hf).ne' + have hne := (multiplicity_pos_of_dvd hf).ne' refine ⟨_, n, y, hne, H, ?_⟩ - obtain ⟨c, hf, H⟩ := multiplicity.exists_eq_pow_mul_and_not_dvd hF + obtain ⟨c, hf, H⟩ := hF.exists_eq_pow_mul_and_not_dvd rw [hf, natSepDegree_mul_of_isCoprime _ c <| IsCoprime.pow_left <| (hI.coprime_or_dvd c).resolve_right H, natSepDegree_pow_of_ne_zero _ hne, hD, add_right_eq_self, natSepDegree_eq_zero_iff] at h diff --git a/Mathlib/NumberTheory/FLT/Three.lean b/Mathlib/NumberTheory/FLT/Three.lean index 555bad3224e64b..05013ac559c40a 100644 --- a/Mathlib/NumberTheory/FLT/Three.lean +++ b/Mathlib/NumberTheory/FLT/Three.lean @@ -215,21 +215,20 @@ lemma Solution'.multiplicity_lambda_c_finite : section DecidableRel -variable [DecidableRel fun (a b : 𝓞 K) ↦ a ∣ b] - /-- Given `S' : Solution'`, `S'.multiplicity` is the multiplicity of `λ` in `S'.c`, as a natural number. -/ -def Solution'.multiplicity := - (_root_.multiplicity (hζ.toInteger - 1) S'.c).get (multiplicity_lambda_c_finite S') +noncomputable def Solution'.multiplicity := + _root_.multiplicity (hζ.toInteger - 1) S'.c /-- Given `S : Solution`, `S.multiplicity` is the multiplicity of `λ` in `S.c`, as a natural number. -/ -def Solution.multiplicity := S.toSolution'.multiplicity +noncomputable def Solution.multiplicity := S.toSolution'.multiplicity /-- We say that `S : Solution` is minimal if for all `S₁ : Solution`, the multiplicity of `λ` in `S.c` is less or equal than the multiplicity in `S₁.c`. -/ def Solution.isMinimal : Prop := ∀ (S₁ : Solution hζ), S.multiplicity ≤ S₁.multiplicity +omit [NumberField K] [IsCyclotomicExtension {3} ℚ K] in include S in /-- If there is a solution then there is a minimal one. -/ lemma Solution.exists_minimal : ∃ (S₁ : Solution hζ), S₁.isMinimal := by @@ -281,29 +280,25 @@ lemma lambda_pow_four_dvd_c_cube : λ ^ 4 ∣ S'.c ^ 3 := by section DecidableRel -variable [DecidableRel fun (a b : 𝓞 K) ↦ a ∣ b] - /-- Given `S' : Solution'`, we have that `λ ^ 2` divides `S'.c`. -/ lemma lambda_sq_dvd_c : λ ^ 2 ∣ S'.c := by have hm := S'.multiplicity_lambda_c_finite - suffices 2 ≤ (multiplicity ((hζ.toInteger - 1)) S'.c).get hm by - obtain ⟨x, hx⟩ := multiplicity.pow_multiplicity_dvd hm - refine ⟨λ ^ ((multiplicity ((hζ.toInteger - 1)) S'.c).get hm - 2) * x, ?_⟩ + suffices 2 ≤ multiplicity (hζ.toInteger - 1) S'.c by + obtain ⟨x, hx⟩ := pow_multiplicity_dvd (hζ.toInteger - 1) S'.c + refine ⟨λ ^ (multiplicity (hζ.toInteger - 1) S'.c - 2) * x, ?_⟩ rw [← mul_assoc, ← pow_add] convert hx using 3 simp [this] have := lambda_pow_four_dvd_c_cube S' - have hm1 : (multiplicity (hζ.toInteger - 1) (S'.c ^ 3)).get - (multiplicity.finite_pow hζ.zeta_sub_one_prime' hm) = - multiplicity (hζ.toInteger - 1) (S'.c ^ 3) := by simp - rw [multiplicity.pow_dvd_iff_le_multiplicity, ← hm1, multiplicity.pow' hζ.zeta_sub_one_prime' hm, - Nat.cast_ofNat, Nat.ofNat_le_cast] at this + rw [pow_dvd_iff_le_emultiplicity, emultiplicity_pow hζ.zeta_sub_one_prime', + hm.emultiplicity_eq_multiplicity] at this + norm_cast at this omega /-- Given `S' : Solution'`, we have that `2 ≤ S'.multiplicity`. -/ lemma Solution'.two_le_multiplicity : 2 ≤ S'.multiplicity := by - simpa [← PartENat.coe_le_coe, Solution'.multiplicity] using - multiplicity.le_multiplicity_of_pow_dvd (lambda_sq_dvd_c S') + simpa [Solution'.multiplicity] using + S'.multiplicity_lambda_c_finite.le_multiplicity_of_pow_dvd (lambda_sq_dvd_c S') /-- Given `S : Solution`, we have that `2 ≤ S.multiplicity`. -/ lemma Solution.two_le_multiplicity : 2 ≤ S.multiplicity := @@ -333,28 +328,25 @@ lemma lambda_sq_dvd_or_dvd_or_dvd : λ ^ 2 ∣ S'.a + S'.b ∨ λ ^ 2 ∣ S'.a + η * S'.b ∨ λ ^ 2 ∣ S'.a + η ^ 2 * S'.b := by by_contra! h rcases h with ⟨h1, h2, h3⟩ - rw [← multiplicity.multiplicity_lt_iff_not_dvd] at h1 h2 h3 + rw [← emultiplicity_lt_iff_not_dvd] at h1 h2 h3 have h1' : multiplicity.Finite (hζ.toInteger - 1) (S'.a + S'.b) := - multiplicity.ne_top_iff_finite.1 (fun ht ↦ by simp [ht] at h1) + finite_iff_emultiplicity_ne_top.2 (fun ht ↦ by simp [ht] at h1) have h2' : multiplicity.Finite (hζ.toInteger - 1) (S'.a + η * S'.b) := by - refine multiplicity.ne_top_iff_finite.1 (fun ht ↦ ?_) + refine finite_iff_emultiplicity_ne_top.2 (fun ht ↦ ?_) rw [coe_eta] at ht simp [ht] at h2 have h3' : multiplicity.Finite (hζ.toInteger - 1) (S'.a + η ^ 2 * S'.b) := by - refine multiplicity.ne_top_iff_finite.1 (fun ht ↦ ?_) + refine finite_iff_emultiplicity_ne_top.2 (fun ht ↦ ?_) rw [coe_eta] at ht simp [ht] at h3 - replace h1' : (multiplicity (hζ.toInteger - 1) (S'.a + S'.b)).get h1' = - multiplicity (hζ.toInteger - 1) (S'.a + S'.b) := by simp - replace h2' : (multiplicity (hζ.toInteger - 1) (S'.a + η * S'.b)).get h2' = - multiplicity (hζ.toInteger - 1) (S'.a + η * S'.b) := by simp - replace h3' : (multiplicity (hζ.toInteger - 1) (S'.a + η ^ 2 * S'.b)).get h3' = - multiplicity (hζ.toInteger - 1) (S'.a + η ^ 2 * S'.b) := by simp - rw [← h1', coe_lt_coe] at h1; rw [← h2', coe_lt_coe] at h2; rw [← h3', coe_lt_coe] at h3 + rw [h1'.emultiplicity_eq_multiplicity, Nat.cast_lt] at h1 + rw [h2'.emultiplicity_eq_multiplicity, Nat.cast_lt] at h2 + rw [h3'.emultiplicity_eq_multiplicity, Nat.cast_lt] at h3 have := (pow_dvd_pow_of_dvd (lambda_sq_dvd_c S') 3).mul_left S'.u - rw [← pow_mul, ← S'.H, a_cube_add_b_cube_eq_mul, multiplicity.pow_dvd_iff_le_multiplicity, - multiplicity.mul hζ.zeta_sub_one_prime', multiplicity.mul hζ.zeta_sub_one_prime', ← h1', ← h2', - ← h3', ← Nat.cast_add, ← Nat.cast_add, coe_le_coe] at this + rw [← pow_mul, ← S'.H, a_cube_add_b_cube_eq_mul, pow_dvd_iff_le_emultiplicity, + emultiplicity_mul hζ.zeta_sub_one_prime', emultiplicity_mul hζ.zeta_sub_one_prime', + h1'.emultiplicity_eq_multiplicity, h2'.emultiplicity_eq_multiplicity, + h3'.emultiplicity_eq_multiplicity, ← Nat.cast_add, ← Nat.cast_add, Nat.cast_le] at this omega open Units in @@ -501,11 +493,9 @@ private lemma lambda_not_dvd_z : ¬ λ ∣ S.z := fun h ↦ by section DecidableRel -variable [DecidableRel fun (a b : 𝓞 K) ↦ a ∣ b] - /-- We have that `λ ^ (3*S.multiplicity-2)` divides `S.a + S.b`. -/ private lemma lambda_pow_dvd_a_add_b : λ ^ (3 * S.multiplicity - 2) ∣ S.a + S.b := by - have h : λ ^ S.multiplicity ∣ S.c := multiplicity.pow_multiplicity_dvd _ + have h : λ ^ S.multiplicity ∣ S.c := pow_multiplicity_dvd _ _ replace h : (λ ^ multiplicity S) ^ 3 ∣ S.u * S.c ^ 3 := by simp [h] rw [← S.H, a_cube_add_b_cube_eq_mul, ← pow_mul, mul_comm, y_spec, z_spec] at h apply hζ.zeta_sub_one_prime'.pow_dvd_of_dvd_mul_left _ S.lambda_not_dvd_z @@ -524,13 +514,14 @@ private lemma x_spec : S.a + S.b = λ ^ (3 * S.multiplicity - 2) * S.x := /-- Given `S : Solution`, we let `S.w` be any element such that `S.c = λ ^ S.multiplicity * S.w` -/ private noncomputable def w := - (multiplicity.pow_multiplicity_dvd S.toSolution'.multiplicity_lambda_c_finite).choose + (pow_multiplicity_dvd (hζ.toInteger - 1) S.c).choose +omit [NumberField K] [IsCyclotomicExtension {3} ℚ K] in private lemma w_spec : S.c = λ ^ S.multiplicity * S.w := - (multiplicity.pow_multiplicity_dvd S.toSolution'.multiplicity_lambda_c_finite).choose_spec + (pow_multiplicity_dvd (hζ.toInteger - 1) S.c).choose_spec private lemma lambda_not_dvd_w : ¬ λ ∣ S.w := fun h ↦ by - refine multiplicity.is_greatest' S.toSolution'.multiplicity_lambda_c_finite + refine S.toSolution'.multiplicity_lambda_c_finite.not_pow_dvd_of_multiplicity_lt (lt_add_one S.multiplicity) ?_ rw [pow_succ', mul_comm] exact S.w_spec ▸ (mul_dvd_mul_left (λ ^ S.multiplicity) h) @@ -574,8 +565,6 @@ private lemma isCoprime_y_z : IsCoprime S.y S.z := (associated_of_dvd_a_add_eta_mul_b_of_dvd_a_add_eta_sq_mul_b S) (fun hq ↦ y_spec S ▸ hq.mul_left _) (fun hq ↦ z_spec S ▸ hq.mul_left _) -variable [DecidableRel fun (a b : 𝓞 K) ↦ a ∣ b] - private lemma x_mul_y_mul_z_eq_u_mul_w_cube : S.x * S.y * S.z = S.u * S.w ^ 3 := by suffices hh : λ ^ (3 * S.multiplicity - 2) * S.x * λ * S.y * λ * S.z = S.u * λ ^ (3 * S.multiplicity) * S.w ^ 3 by @@ -595,7 +584,7 @@ private lemma x_mul_y_mul_z_eq_u_mul_w_cube : S.x * S.y * S.z = S.u * S.w ^ 3 := private lemma exists_cube_associated : (∃ X, Associated (X ^ 3) S.x) ∧ (∃ Y, Associated (Y ^ 3) S.y) ∧ - ∃ Z, Associated (Z ^ 3) S.z := by + ∃ Z, Associated (Z ^ 3) S.z := by classical 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]⟩ @@ -734,7 +723,8 @@ noncomputable def Solution'_descent : Solution' hζ where /-- We have that `S.Solution'_descent.multiplicity = S.multiplicity - 1`. -/ lemma Solution'_descent_multiplicity : S.Solution'_descent.multiplicity = S.multiplicity - 1 := by - refine (multiplicity.unique' (by simp [Solution'_descent]) (fun h ↦ S.lambda_not_dvd_X ?_)).symm + refine multiplicity_eq_of_dvd_of_not_dvd + (by simp [Solution'_descent]) (fun h ↦ S.lambda_not_dvd_X ?_) obtain ⟨k, hk : λ^(S.multiplicity-1)*S.X=λ^(S.multiplicity-1+1)*k⟩ := h rw [pow_succ, mul_assoc] at hk simp only [mul_eq_mul_left_iff, pow_eq_zero_iff', hζ.zeta_sub_one_prime'.ne_zero, ne_eq, @@ -750,7 +740,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 + ∃ S₁ : Solution hζ, S₁.multiplicity < S.multiplicity := by classical obtain ⟨S', hS'⟩ := exists_Solution_of_Solution' (Solution'_descent S) exact ⟨S', hS' ▸ Solution'_descent_multiplicity_lt S⟩ diff --git a/Mathlib/NumberTheory/KummerDedekind.lean b/Mathlib/NumberTheory/KummerDedekind.lean index b93799f8bfa38d..f3827e812c3096 100644 --- a/Mathlib/NumberTheory/KummerDedekind.lean +++ b/Mathlib/NumberTheory/KummerDedekind.lean @@ -258,16 +258,16 @@ noncomputable def normalizedFactorsMapEquivNormalizedFactorsMinPolyMk (hI : IsMa open Classical in /-- The second half of the **Kummer-Dedekind Theorem** in the monogenic case, stating that the bijection `FactorsEquiv'` defined in the first half preserves multiplicities. -/ -theorem multiplicity_factors_map_eq_multiplicity +theorem emultiplicity_factors_map_eq_emultiplicity (hI : IsMaximal I) (hI' : I ≠ ⊥) (hx : (conductor R x).comap (algebraMap R S) ⊔ I = ⊤) (hx' : IsIntegral R x) {J : Ideal S} (hJ : J ∈ normalizedFactors (I.map (algebraMap R S))) : - multiplicity J (I.map (algebraMap R S)) = - multiplicity (↑(normalizedFactorsMapEquivNormalizedFactorsMinPolyMk hI hI' hx hx' ⟨J, hJ⟩)) + 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 rw [normalizedFactorsMapEquivNormalizedFactorsMinPolyMk, Equiv.coe_trans, Function.comp_apply, - multiplicity_normalizedFactorsEquivSpanNormalizedFactors_symm_eq_multiplicity, - normalizedFactorsEquivOfQuotEquiv_multiplicity_eq_multiplicity] + emultiplicity_normalizedFactorsEquivSpanNormalizedFactors_symm_eq_emultiplicity, + normalizedFactorsEquivOfQuotEquiv_emultiplicity_eq_emultiplicity] open Classical in /-- The **Kummer-Dedekind Theorem**. -/ @@ -288,10 +288,10 @@ theorem normalizedFactors_ideal_map_eq_normalizedFactors_min_poly_mk_map (hI : I exact hJ ((normalizedFactorsMapEquivNormalizedFactorsMinPolyMk hI hI' hx hx').symm J').prop -- Then we just have to compare the multiplicities, which we already proved are equal. - have := multiplicity_factors_map_eq_multiplicity hI hI' hx hx' hJ - rw [multiplicity_eq_count_normalizedFactors, multiplicity_eq_count_normalizedFactors, + have := emultiplicity_factors_map_eq_emultiplicity hI hI' hx hx' hJ + rw [emultiplicity_eq_count_normalizedFactors, emultiplicity_eq_count_normalizedFactors, UniqueFactorizationMonoid.normalize_normalized_factor _ hJ, - UniqueFactorizationMonoid.normalize_normalized_factor, PartENat.natCast_inj] at this + UniqueFactorizationMonoid.normalize_normalized_factor, Nat.cast_inj] at this · refine this.trans ?_ -- Get rid of the `map` by applying the equiv to both sides. generalize hJ' : diff --git a/Mathlib/NumberTheory/Multiplicity.lean b/Mathlib/NumberTheory/Multiplicity.lean index 43de4a819a5272..119163114c7bf6 100644 --- a/Mathlib/NumberTheory/Multiplicity.lean +++ b/Mathlib/NumberTheory/Multiplicity.lean @@ -143,19 +143,19 @@ namespace multiplicity section IntegralDomain -variable [IsDomain R] [@DecidableRel R (· ∣ ·)] +variable [IsDomain R] theorem pow_sub_pow_of_prime {p : R} (hp : Prime p) {x y : R} (hxy : p ∣ x - y) (hx : ¬p ∣ x) - {n : ℕ} (hn : ¬p ∣ n) : multiplicity p (x ^ n - y ^ n) = multiplicity p (x - y) := by - rw [← geom_sum₂_mul, multiplicity.mul hp, multiplicity_eq_zero.2 (not_dvd_geom_sum₂ hp hxy hx hn), - zero_add] + {n : ℕ} (hn : ¬p ∣ n) : emultiplicity p (x ^ n - y ^ n) = emultiplicity p (x - y) := by + rw [← geom_sum₂_mul, emultiplicity_mul hp, + emultiplicity_eq_zero.2 (not_dvd_geom_sum₂ hp hxy hx hn), zero_add] variable (hp : Prime (p : R)) (hp1 : Odd p) (hxy : ↑p ∣ x - y) (hx : ¬↑p ∣ x) include hp hp1 hxy hx -theorem geom_sum₂_eq_one : multiplicity (↑p) (∑ i ∈ range p, x ^ i * y ^ (p - 1 - i)) = 1 := by +theorem geom_sum₂_eq_one : emultiplicity (↑p) (∑ i ∈ range p, x ^ i * y ^ (p - 1 - i)) = 1 := by rw [← Nat.cast_one] - refine multiplicity.eq_coe_iff.2 ⟨?_, ?_⟩ + refine emultiplicity_eq_coe.2 ⟨?_, ?_⟩ · rw [pow_one] exact dvd_geom_sum₂_self hxy rw [dvd_iff_dvd_of_dvd_sub hxy] at hx @@ -166,11 +166,11 @@ theorem geom_sum₂_eq_one : multiplicity (↑p) (∑ i ∈ range p, x ^ i * y ^ exact mt hp.dvd_of_dvd_pow hx theorem pow_prime_sub_pow_prime : - multiplicity (↑p) (x ^ p - y ^ p) = multiplicity (↑p) (x - y) + 1 := by - rw [← geom_sum₂_mul, multiplicity.mul hp, geom_sum₂_eq_one hp hp1 hxy hx, add_comm] + emultiplicity (↑p) (x ^ p - y ^ p) = emultiplicity (↑p) (x - y) + 1 := by + rw [← geom_sum₂_mul, emultiplicity_mul hp, geom_sum₂_eq_one hp hp1 hxy hx, add_comm] theorem pow_prime_pow_sub_pow_prime_pow (a : ℕ) : - multiplicity (↑p) (x ^ p ^ a - y ^ p ^ a) = multiplicity (↑p) (x - y) + a := by + emultiplicity (↑p) (x ^ p ^ a - y ^ p ^ a) = emultiplicity (↑p) (x - y) + a := by induction' a with a h_ind · rw [Nat.cast_zero, add_zero, pow_zero, pow_one, pow_one] rw [Nat.cast_add, Nat.cast_one, ← add_assoc, ← h_ind, pow_succ, pow_mul, pow_mul] @@ -188,15 +188,16 @@ include hp hp1 /-- **Lifting the exponent lemma** for odd primes. -/ theorem Int.pow_sub_pow {x y : ℤ} (hxy : ↑p ∣ x - y) (hx : ¬↑p ∣ x) (n : ℕ) : - multiplicity (↑p) (x ^ n - y ^ n) = multiplicity (↑p) (x - y) + multiplicity p n := by + emultiplicity (↑p) (x ^ n - y ^ n) = emultiplicity (↑p) (x - y) + emultiplicity p n := by cases' n with n - · simp only [multiplicity.zero, add_top, pow_zero, sub_self] - have h : (multiplicity _ _).Dom := finite_nat_iff.mpr ⟨hp.ne_one, n.succ_pos⟩ + · simp only [emultiplicity_zero, add_top, pow_zero, sub_self] + have h : Finite _ _ := Nat.multiplicity_finite_iff.mpr ⟨hp.ne_one, n.succ_pos⟩ simp only [Nat.succ_eq_add_one] at h - rcases eq_coe_iff.mp (PartENat.natCast_get h).symm with ⟨⟨k, hk⟩, hpn⟩ + rcases emultiplicity_eq_coe.mp h.emultiplicity_eq_multiplicity with ⟨⟨k, hk⟩, hpn⟩ conv_lhs => rw [hk, pow_mul, pow_mul] rw [Nat.prime_iff_prime_int] at hp - rw [pow_sub_pow_of_prime hp, pow_prime_pow_sub_pow_prime_pow hp hp1 hxy hx, PartENat.natCast_get] + rw [pow_sub_pow_of_prime hp, pow_prime_pow_sub_pow_prime_pow hp hp1 hxy hx, + h.emultiplicity_eq_multiplicity] · rw [← geom_sum₂_mul] exact dvd_mul_of_dvd_right hxy _ · exact fun h => hx (hp.dvd_of_dvd_pow h) @@ -206,27 +207,26 @@ theorem Int.pow_sub_pow {x y : ℤ} (hxy : ↑p ∣ x - y) (hx : ¬↑p ∣ x) ( rwa [pow_succ, mul_assoc] theorem Int.pow_add_pow {x y : ℤ} (hxy : ↑p ∣ x + y) (hx : ¬↑p ∣ x) {n : ℕ} (hn : Odd n) : - multiplicity (↑p) (x ^ n + y ^ n) = multiplicity (↑p) (x + y) + multiplicity p n := by + emultiplicity (↑p) (x ^ n + y ^ n) = emultiplicity (↑p) (x + y) + emultiplicity p n := by rw [← sub_neg_eq_add] at hxy rw [← sub_neg_eq_add, ← sub_neg_eq_add, ← Odd.neg_pow hn] exact Int.pow_sub_pow hp hp1 hxy hx n theorem Nat.pow_sub_pow {x y : ℕ} (hxy : p ∣ x - y) (hx : ¬p ∣ x) (n : ℕ) : - multiplicity p (x ^ n - y ^ n) = multiplicity p (x - y) + multiplicity p n := by + emultiplicity p (x ^ n - y ^ n) = emultiplicity p (x - y) + emultiplicity p n := by obtain hyx | hyx := le_total y x - · iterate 2 rw [← Int.natCast_multiplicity] + · iterate 2 rw [← Int.natCast_emultiplicity] rw [Int.ofNat_sub (Nat.pow_le_pow_left hyx n)] rw [← Int.natCast_dvd_natCast] at hxy hx rw [Int.natCast_sub hyx] at * push_cast at * exact Int.pow_sub_pow hp hp1 hxy hx n - · simp only [Nat.sub_eq_zero_iff_le.mpr hyx, - Nat.sub_eq_zero_iff_le.mpr (Nat.pow_le_pow_left hyx n), multiplicity.zero, - PartENat.top_add] + · simp only [Nat.sub_eq_zero_iff_le.mpr (Nat.pow_le_pow_left hyx n), emultiplicity_zero, + Nat.sub_eq_zero_iff_le.mpr hyx, top_add] theorem Nat.pow_add_pow {x y : ℕ} (hxy : p ∣ x + y) (hx : ¬p ∣ x) {n : ℕ} (hn : Odd n) : - multiplicity p (x ^ n + y ^ n) = multiplicity p (x + y) + multiplicity p n := by - iterate 2 rw [← Int.natCast_multiplicity] + emultiplicity p (x ^ n + y ^ n) = emultiplicity p (x + y) + emultiplicity p n := by + iterate 2 rw [← Int.natCast_emultiplicity] rw [← Int.natCast_dvd_natCast] at hxy hx push_cast at * exact Int.pow_add_pow hp hp1 hxy hx hn @@ -256,11 +256,11 @@ theorem Int.sq_mod_four_eq_one_of_odd {x : ℤ} : Odd x → x ^ 2 % 4 = 1 := by decide theorem Int.two_pow_two_pow_add_two_pow_two_pow {x y : ℤ} (hx : ¬2 ∣ x) (hxy : 4 ∣ x - y) (i : ℕ) : - multiplicity 2 (x ^ 2 ^ i + y ^ 2 ^ i) = ↑(1 : ℕ) := by + emultiplicity 2 (x ^ 2 ^ i + y ^ 2 ^ i) = ↑(1 : ℕ) := by have hx_odd : Odd x := by rwa [← Int.not_even_iff_odd, even_iff_two_dvd] have hxy_even : Even (x - y) := even_iff_two_dvd.mpr (dvd_trans (by decide) hxy) have hy_odd : Odd y := by simpa using hx_odd.sub_even hxy_even - refine multiplicity.eq_coe_iff.mpr ⟨?_, ?_⟩ + refine emultiplicity_eq_coe.mpr ⟨?_, ?_⟩ · rw [pow_one, ← even_iff_two_dvd] exact hx_odd.pow.add_odd hy_odd.pow cases' i with i @@ -280,24 +280,25 @@ theorem Int.two_pow_two_pow_add_two_pow_two_pow {x y : ℤ} (hx : ¬2 ∣ x) (hx rw [pow_succ', mul_comm, pow_mul, Int.sq_mod_four_eq_one_of_odd hx.pow] theorem Int.two_pow_two_pow_sub_pow_two_pow {x y : ℤ} (n : ℕ) (hxy : 4 ∣ x - y) (hx : ¬2 ∣ x) : - multiplicity 2 (x ^ 2 ^ n - y ^ 2 ^ n) = multiplicity 2 (x - y) + n := by - simp only [pow_two_pow_sub_pow_two_pow n, multiplicity.mul Int.prime_two, - multiplicity.Finset.prod Int.prime_two, add_comm, Nat.cast_one, Finset.sum_const, + emultiplicity 2 (x ^ 2 ^ n - y ^ 2 ^ n) = emultiplicity 2 (x - y) + n := by + simp only [pow_two_pow_sub_pow_two_pow n, emultiplicity_mul Int.prime_two, + Finset.emultiplicity_prod Int.prime_two, add_comm, Nat.cast_one, Finset.sum_const, Finset.card_range, nsmul_one, Int.two_pow_two_pow_add_two_pow_two_pow hx hxy] theorem Int.two_pow_sub_pow' {x y : ℤ} (n : ℕ) (hxy : 4 ∣ x - y) (hx : ¬2 ∣ x) : - multiplicity 2 (x ^ n - y ^ n) = multiplicity 2 (x - y) + multiplicity (2 : ℤ) n := by + emultiplicity 2 (x ^ n - y ^ n) = emultiplicity 2 (x - y) + emultiplicity (2 : ℤ) n := by have hx_odd : Odd x := by rwa [← Int.not_even_iff_odd, even_iff_two_dvd] have hxy_even : Even (x - y) := even_iff_two_dvd.mpr (dvd_trans (by decide) hxy) have hy_odd : Odd y := by simpa using hx_odd.sub_even hxy_even cases' n with n - · simp only [pow_zero, sub_self, multiplicity.zero, Int.ofNat_zero, add_top] - have h : (multiplicity 2 n.succ).Dom := multiplicity.finite_nat_iff.mpr ⟨by norm_num, n.succ_pos⟩ + · simp only [pow_zero, sub_self, emultiplicity_zero, Int.ofNat_zero, add_top] + have h : multiplicity.Finite 2 n.succ := Nat.multiplicity_finite_iff.mpr ⟨by norm_num, n.succ_pos⟩ simp only [Nat.succ_eq_add_one] at h - rcases multiplicity.eq_coe_iff.mp (PartENat.natCast_get h).symm with ⟨⟨k, hk⟩, hpn⟩ + rcases emultiplicity_eq_coe.mp h.emultiplicity_eq_multiplicity with ⟨⟨k, hk⟩, hpn⟩ rw [hk, pow_mul, pow_mul, multiplicity.pow_sub_pow_of_prime, - Int.two_pow_two_pow_sub_pow_two_pow _ hxy hx, ← hk, PartENat.natCast_get] + Int.two_pow_two_pow_sub_pow_two_pow _ hxy hx, ← hk] · norm_cast + rw [h.emultiplicity_eq_multiplicity] · exact Int.prime_two · simpa only [even_iff_two_dvd] using hx_odd.pow.sub_odd hy_odd.pow · simpa only [even_iff_two_dvd, ← Int.not_even_iff_odd] using hx_odd.pow @@ -310,8 +311,8 @@ theorem Int.two_pow_sub_pow' {x y : ℤ} (n : ℕ) (hxy : 4 ∣ x - y) (hx : ¬2 /-- **Lifting the exponent lemma** for `p = 2` -/ theorem Int.two_pow_sub_pow {x y : ℤ} {n : ℕ} (hxy : 2 ∣ x - y) (hx : ¬2 ∣ x) (hn : Even n) : - multiplicity 2 (x ^ n - y ^ n) + 1 = - multiplicity 2 (x + y) + multiplicity 2 (x - y) + multiplicity (2 : ℤ) n := by + emultiplicity 2 (x ^ n - y ^ n) + 1 = + emultiplicity 2 (x + y) + emultiplicity 2 (x - y) + emultiplicity (2 : ℤ) n := by have hy : Odd y := by rw [← even_iff_two_dvd, Int.not_even_iff_odd] at hx replace hxy := (@even_neg _ _ (x - y)).mpr (even_iff_two_dvd.mpr hxy) @@ -325,33 +326,32 @@ theorem Int.two_pow_sub_pow {x y : ℤ} {n : ℕ} (hxy : 2 ∣ x - y) (hx : ¬2 Int.sq_mod_four_eq_one_of_odd hy] · norm_num · simp only [← Int.not_even_iff_odd, even_iff_two_dvd, hx, not_false_iff] - rw [Int.two_pow_sub_pow' d hxy4 _, sq_sub_sq, ← Int.ofNat_mul_out, multiplicity.mul Int.prime_two, - multiplicity.mul Int.prime_two] - · suffices multiplicity (2 : ℤ) ↑(2 : ℕ) = 1 by rw [this, add_comm (1 : PartENat), ← add_assoc] + rw [Int.two_pow_sub_pow' d hxy4 _, sq_sub_sq, ← Int.ofNat_mul_out, + emultiplicity_mul Int.prime_two, emultiplicity_mul Int.prime_two] + · suffices emultiplicity (2 : ℤ) ↑(2 : ℕ) = 1 by rw [this, add_comm 1, ← add_assoc] norm_cast - rw [multiplicity.multiplicity_self _ _] - · apply Prime.not_unit - simp only [← Nat.prime_iff, Nat.prime_two] - · exact two_ne_zero + rw [multiplicity.Finite.emultiplicity_self] + rw [Nat.multiplicity_finite_iff] + decide · rw [← even_iff_two_dvd, Int.not_even_iff_odd] apply Odd.pow simp only [← Int.not_even_iff_odd, even_iff_two_dvd, hx, not_false_iff] theorem Nat.two_pow_sub_pow {x y : ℕ} (hxy : 2 ∣ x - y) (hx : ¬2 ∣ x) {n : ℕ} (hn : Even n) : - multiplicity 2 (x ^ n - y ^ n) + 1 = - multiplicity 2 (x + y) + multiplicity 2 (x - y) + multiplicity 2 n := by + emultiplicity 2 (x ^ n - y ^ n) + 1 = + emultiplicity 2 (x + y) + emultiplicity 2 (x - y) + emultiplicity 2 n := by obtain hyx | hyx := le_total y x - · iterate 3 rw [← multiplicity.Int.natCast_multiplicity] + · iterate 3 rw [← Int.natCast_emultiplicity] simp only [Int.ofNat_sub hyx, Int.ofNat_sub (pow_le_pow_left' hyx _), Int.ofNat_add, Int.natCast_pow] rw [← Int.natCast_dvd_natCast] at hx rw [← Int.natCast_dvd_natCast, Int.ofNat_sub hyx] at hxy convert Int.two_pow_sub_pow hxy hx hn using 2 - rw [← multiplicity.Int.natCast_multiplicity] + rw [← Int.natCast_emultiplicity] rfl · simp only [Nat.sub_eq_zero_iff_le.mpr hyx, - Nat.sub_eq_zero_iff_le.mpr (pow_le_pow_left' hyx n), multiplicity.zero, - PartENat.top_add, PartENat.add_top] + Nat.sub_eq_zero_iff_le.mpr (pow_le_pow_left' hyx n), emultiplicity_zero, + top_add, add_top] namespace padicValNat @@ -361,9 +361,9 @@ theorem pow_two_sub_pow (hyx : y < x) (hxy : 2 ∣ x - y) (hx : ¬2 ∣ x) {n : (hneven : Even n) : padicValNat 2 (x ^ n - y ^ n) + 1 = padicValNat 2 (x + y) + padicValNat 2 (x - y) + padicValNat 2 n := by - simp only [← PartENat.natCast_inj, Nat.cast_add] - iterate 4 rw [padicValNat_def, PartENat.natCast_get] - · convert Nat.two_pow_sub_pow hxy hx hneven using 2 + simp only [← Nat.cast_inj (R := ℕ∞), Nat.cast_add] + iterate 4 rw [padicValNat_eq_emultiplicity] + · exact Nat.two_pow_sub_pow hxy hx hneven · exact hn.bot_lt · exact Nat.sub_pos_of_lt hyx · omega @@ -374,8 +374,8 @@ include hp hp1 theorem pow_sub_pow (hyx : y < x) (hxy : p ∣ x - y) (hx : ¬p ∣ x) {n : ℕ} (hn : n ≠ 0) : padicValNat p (x ^ n - y ^ n) = padicValNat p (x - y) + padicValNat p n := by - rw [← PartENat.natCast_inj, Nat.cast_add] - iterate 3 rw [padicValNat_def, PartENat.natCast_get] + rw [← Nat.cast_inj (R := ℕ∞), Nat.cast_add] + iterate 3 rw [padicValNat_eq_emultiplicity] · exact multiplicity.Nat.pow_sub_pow hp.out hp1 hxy hx n · exact hn.bot_lt · exact Nat.sub_pos_of_lt hyx @@ -385,8 +385,8 @@ theorem pow_add_pow (hxy : p ∣ x + y) (hx : ¬p ∣ x) {n : ℕ} (hn : Odd n) padicValNat p (x ^ n + y ^ n) = padicValNat p (x + y) + padicValNat p n := by cases' y with y · contradiction - rw [← PartENat.natCast_inj, Nat.cast_add] - iterate 3 rw [padicValNat_def, PartENat.natCast_get] + rw [← Nat.cast_inj (R := ℕ∞), Nat.cast_add] + iterate 3 rw [padicValNat_eq_emultiplicity] · exact multiplicity.Nat.pow_add_pow hp.out hp1 hxy hx hn · exact Odd.pos hn · simp only [add_pos_iff, Nat.succ_pos', or_true] diff --git a/Mathlib/NumberTheory/Padics/PadicNorm.lean b/Mathlib/NumberTheory/Padics/PadicNorm.lean index 311b2e21e81be0..06bf72812b275b 100644 --- a/Mathlib/NumberTheory/Padics/PadicNorm.lean +++ b/Mathlib/NumberTheory/Padics/PadicNorm.lean @@ -228,10 +228,11 @@ theorem dvd_iff_norm_le {n : ℕ} {z : ℤ} : ↑(p ^ n) ∣ z ↔ padicNorm p z · rw [zpow_le_zpow_iff_right₀, neg_le_neg_iff, padicValRat.of_int, padicValInt.of_ne_one_ne_zero hp.1.ne_one _] · norm_cast - rw [← PartENat.coe_le_coe, PartENat.natCast_get, ← multiplicity.pow_dvd_iff_le_multiplicity, - Nat.cast_pow] - exact mod_cast hz - · exact mod_cast hp.1.one_lt + rw [← multiplicity.Finite.pow_dvd_iff_le_multiplicity] + · norm_cast + · apply Int.multiplicity_finite_iff.2 ⟨by simp [hp.out.ne_one], mod_cast hz⟩ + · exact_mod_cast hz + · exact_mod_cast hp.out.one_lt /-- The `p`-adic norm of an integer `m` is one iff `p` doesn't divide `m`. -/ theorem int_eq_one_iff (m : ℤ) : padicNorm p m = 1 ↔ ¬(p : ℤ) ∣ m := by diff --git a/Mathlib/NumberTheory/Padics/PadicVal/Basic.lean b/Mathlib/NumberTheory/Padics/PadicVal/Basic.lean index a50d9d73886f60..6ddb55a0ed27f6 100644 --- a/Mathlib/NumberTheory/Padics/PadicVal/Basic.lean +++ b/Mathlib/NumberTheory/Padics/PadicVal/Basic.lean @@ -76,34 +76,31 @@ variable {p : ℕ} /-- If `p ≠ 0` and `p ≠ 1`, then `padicValNat p p` is `1`. -/ @[simp] theorem self (hp : 1 < p) : padicValNat p p = 1 := by - have neq_one : ¬p = 1 ↔ True := iff_of_true hp.ne' trivial - have eq_zero_false : p = 0 ↔ False := iff_false_intro (zero_lt_one.trans hp).ne' - simp [padicValNat, neq_one, eq_zero_false] + simp [padicValNat_def', zero_lt_one.trans hp, hp.ne'] theorem eq_zero_of_not_dvd {n : ℕ} (h : ¬p ∣ n) : padicValNat p n = 0 := eq_zero_iff.2 <| Or.inr <| Or.inr h open Nat.maxPowDiv -theorem maxPowDiv_eq_multiplicity {p n : ℕ} (hp : 1 < p) (hn : 0 < n) : - p.maxPowDiv n = multiplicity p n := by - apply multiplicity.unique <| pow_dvd p n +theorem maxPowDiv_eq_emultiplicity {p n : ℕ} (hp : 1 < p) (hn : 0 < n) : + p.maxPowDiv n = emultiplicity p n := by + apply (emultiplicity_eq_of_dvd_of_not_dvd (pow_dvd p n) _).symm intro h apply Nat.not_lt.mpr <| le_of_dvd hp hn h simp -theorem maxPowDiv_eq_multiplicity_get {p n : ℕ} (hp : 1 < p) (hn : 0 < n) (h : Finite p n) : - p.maxPowDiv n = (multiplicity p n).get h := by - rw [PartENat.get_eq_iff_eq_coe.mpr] - apply maxPowDiv_eq_multiplicity hp hn|>.symm +theorem maxPowDiv_eq_multiplicity {p n : ℕ} (hp : 1 < p) (hn : 0 < n) (h : Finite p n) : + p.maxPowDiv n = multiplicity p n := by + exact_mod_cast h.emultiplicity_eq_multiplicity ▸ maxPowDiv_eq_emultiplicity hp hn /-- Allows for more efficient code for `padicValNat` -/ @[csimp] theorem padicValNat_eq_maxPowDiv : @padicValNat = @maxPowDiv := by ext p n by_cases h : 1 < p ∧ 0 < n - · dsimp [padicValNat] - rw [dif_pos ⟨Nat.ne_of_gt h.1,h.2⟩, maxPowDiv_eq_multiplicity_get h.1 h.2] + · rw [padicValNat_def' h.1.ne' h.2, maxPowDiv_eq_multiplicity h.1 h.2] + exact Nat.multiplicity_finite_iff.2 ⟨h.1.ne', h.2⟩ · simp only [not_and_or,not_gt_eq,Nat.le_zero] at h apply h.elim · intro h @@ -128,13 +125,9 @@ open multiplicity variable {p : ℕ} theorem of_ne_one_ne_zero {z : ℤ} (hp : p ≠ 1) (hz : z ≠ 0) : - padicValInt p z = - (multiplicity (p : ℤ) z).get - (by - apply multiplicity.finite_int_iff.2 - simp [hp, hz]) := by - rw [padicValInt, padicValNat, dif_pos (And.intro hp (Int.natAbs_pos.mpr hz))] - simp only [multiplicity.Int.natAbs p z] + padicValInt p z = multiplicity (p : ℤ) z:= by + rw [padicValInt, padicValNat_def' hp (Int.natAbs_pos.mpr hz)] + apply Int.multiplicity_natAbs /-- `padicValInt p 0` is `0` for any `p`. -/ @[simp] @@ -152,8 +145,9 @@ theorem of_nat {n : ℕ} : padicValInt p n = padicValNat p n := by simp [padicVa theorem self (hp : 1 < p) : padicValInt p p = 1 := by simp [padicValNat.self hp] theorem eq_zero_of_not_dvd {z : ℤ} (h : ¬(p : ℤ) ∣ z) : padicValInt p z = 0 := by - rw [padicValInt, padicValNat] - split_ifs <;> simp [multiplicity.Int.natAbs, multiplicity_eq_zero.2 h] + rw [padicValInt, padicValNat.eq_zero_iff] + right; right + rwa [← Int.ofNat_dvd_left] end padicValInt @@ -191,19 +185,13 @@ theorem of_int {z : ℤ} : padicValRat p z = padicValInt p z := by simp [padicVa /-- The `p`-adic value of an integer `z ≠ 0` is the multiplicity of `p` in `z`. -/ theorem of_int_multiplicity {z : ℤ} (hp : p ≠ 1) (hz : z ≠ 0) : - padicValRat p (z : ℚ) = (multiplicity (p : ℤ) z).get (finite_int_iff.2 ⟨hp, hz⟩) := by + padicValRat p (z : ℚ) = multiplicity (p : ℤ) z := by rw [of_int, padicValInt.of_ne_one_ne_zero hp hz] theorem multiplicity_sub_multiplicity {q : ℚ} (hp : p ≠ 1) (hq : q ≠ 0) : - padicValRat p q = - (multiplicity (p : ℤ) q.num).get (finite_int_iff.2 ⟨hp, Rat.num_ne_zero.2 hq⟩) - - (multiplicity p q.den).get - (by - rw [← finite_iff_dom, finite_nat_iff] - exact ⟨hp, q.pos⟩) := by - rw [padicValRat, padicValInt.of_ne_one_ne_zero hp, padicValNat, dif_pos] - · exact ⟨hp, q.pos⟩ - · exact Rat.num_ne_zero.2 hq + padicValRat p q = multiplicity (p : ℤ) q.num - multiplicity p q.den := by + rw [padicValRat, padicValInt.of_ne_one_ne_zero hp (Rat.num_ne_zero.2 hq), + padicValNat_def' hp q.pos] /-- The `p`-adic value of an integer `z ≠ 0` is its `p`-adic value as a rational. -/ @[simp] @@ -231,8 +219,8 @@ theorem padicValNat_self [Fact p.Prime] : padicValNat p p = 1 := by theorem one_le_padicValNat_of_dvd {n : ℕ} [hp : Fact p.Prime] (hn : 0 < n) (div : p ∣ n) : 1 ≤ padicValNat p n := by - rwa [← PartENat.coe_le_coe, padicValNat_def' hp.out.ne_one hn, ← pow_dvd_iff_le_multiplicity, - pow_one] + rwa [← WithTop.coe_le_coe, ENat.some_eq_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 := @@ -249,28 +237,23 @@ variable {p : ℕ} [hp : Fact p.Prime] /-- The multiplicity of `p : ℕ` in `a : ℤ` is finite exactly when `a ≠ 0`. -/ theorem finite_int_prime_iff {a : ℤ} : Finite (p : ℤ) a ↔ a ≠ 0 := by - simp [finite_int_iff, hp.1.ne_one] + simp [Int.multiplicity_finite_iff, hp.1.ne_one] /-- A rewrite lemma for `padicValRat p q` when `q` is expressed in terms of `Rat.mk`. -/ protected theorem defn (p : ℕ) [hp : Fact p.Prime] {q : ℚ} {n d : ℤ} (hqz : q ≠ 0) (qdf : q = n /. d) : - padicValRat p q = - (multiplicity (p : ℤ) n).get - (finite_int_iff.2 ⟨hp.1.ne_one, fun hn => by simp_all⟩) - - (multiplicity (p : ℤ) d).get - (finite_int_iff.2 ⟨hp.1.ne_one, fun hd => by simp_all⟩) := by + padicValRat p q = multiplicity (p : ℤ) n - multiplicity (p : ℤ) d := by have hd : d ≠ 0 := Rat.mk_denom_ne_zero_of_ne_zero hqz qdf let ⟨c, hc1, hc2⟩ := Rat.num_den_mk hd qdf rw [padicValRat.multiplicity_sub_multiplicity hp.1.ne_one hqz] simp only [Nat.isUnit_iff, hc1, hc2] - rw [multiplicity.mul' (Nat.prime_iff_prime_int.1 hp.1), - multiplicity.mul' (Nat.prime_iff_prime_int.1 hp.1)] - rw [Nat.cast_add, Nat.cast_add] - simp_rw [Int.natCast_multiplicity p q.den] - ring - -- Porting note: was - -- simp only [hc1, hc2, multiplicity.mul' (Nat.prime_iff_prime_int.1 hp.1), - -- hp.1.ne_one, hqz, pos_iff_ne_zero, Int.natCast_multiplicity p q.den + rw [multiplicity_mul (Nat.prime_iff_prime_int.1 hp.1), + multiplicity_mul (Nat.prime_iff_prime_int.1 hp.1)] + · rw [Nat.cast_add, Nat.cast_add] + simp_rw [Int.natCast_multiplicity p q.den] + ring + · simpa [finite_int_prime_iff, hc2] using hd + · simpa [finite_int_prime_iff, hqz, hc2] using hd /-- A rewrite lemma for `padicValRat p (q * r)` with conditions `q ≠ 0`, `r ≠ 0`. -/ protected theorem mul {q r : ℚ} (hq : q ≠ 0) (hr : r ≠ 0) : @@ -283,10 +266,10 @@ protected theorem mul {q r : ℚ} (hq : q ≠ 0) (hr : r ≠ 0) : rw [padicValRat.defn p (mul_ne_zero hq hr) this] conv_rhs => rw [← q.num_divInt_den, padicValRat.defn p hq', ← r.num_divInt_den, padicValRat.defn p hr'] - rw [multiplicity.mul' hp', multiplicity.mul' hp', Nat.cast_add, Nat.cast_add] - ring - -- Porting note: was - -- simp [add_comm, add_left_comm, sub_eq_add_neg] + rw [multiplicity_mul hp', multiplicity_mul hp', Nat.cast_add, Nat.cast_add] + · ring + · 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 : ℕ} : @@ -320,9 +303,9 @@ theorem padicValRat_le_padicValRat_iff {n₁ n₂ d₁ d₂ : ℤ} (hn₁ : n₁ padicValRat.defn p (Rat.divInt_ne_zero_of_ne_zero hn₂ hd₂) rfl, sub_le_iff_le_add', ← add_sub_assoc, _root_.le_sub_iff_add_le] norm_cast - rw [← multiplicity.mul' (Nat.prime_iff_prime_int.1 hp.1) hf1, add_comm, ← - multiplicity.mul' (Nat.prime_iff_prime_int.1 hp.1) hf2, PartENat.get_le_get, - multiplicity_le_multiplicity_iff] + rw [← multiplicity_mul (Nat.prime_iff_prime_int.1 hp.1) hf1, add_comm, + ← multiplicity_mul (Nat.prime_iff_prime_int.1 hp.1) hf2, + hf1.multiplicity_le_multiplicity_iff hf2] /-- Sufficient conditions to show that the `p`-adic valuation of `q` is less than or equal to the `p`-adic valuation of `q + r`. -/ @@ -340,22 +323,21 @@ theorem le_padicValRat_add_of_le {q r : ℚ} (hqr : q + r ≠ 0) have hqrd : q.num * r.den + q.den * r.num ≠ 0 := Rat.mk_num_ne_zero_of_ne_zero hqr hqreq conv_lhs => rw [← q.num_divInt_den] rw [hqreq, padicValRat_le_padicValRat_iff hqn hqrd hqd (mul_ne_zero hqd hrd), ← - multiplicity_le_multiplicity_iff, mul_left_comm, - multiplicity.mul (Nat.prime_iff_prime_int.1 hp.1), add_mul] + emultiplicity_le_emultiplicity_iff, mul_left_comm, + emultiplicity_mul (Nat.prime_iff_prime_int.1 hp.1), add_mul] rw [← q.num_divInt_den, ← r.num_divInt_den, padicValRat_le_padicValRat_iff hqn hrn hqd hrd, ← - multiplicity_le_multiplicity_iff] at h + emultiplicity_le_emultiplicity_iff] at h calc _ ≤ - min (multiplicity (↑p) (q.num * r.den * q.den)) - (multiplicity (↑p) (↑q.den * r.num * ↑q.den)) := + min (emultiplicity (↑p) (q.num * r.den * q.den)) + (emultiplicity (↑p) (↑q.den * r.num * ↑q.den)) := le_min - (by rw [@multiplicity.mul _ _ _ _ (_ * _) _ (Nat.prime_iff_prime_int.1 hp.1), add_comm]) + (by rw [emultiplicity_mul (a :=_ * _) (Nat.prime_iff_prime_int.1 hp.1), add_comm]) (by rw [mul_assoc, - @multiplicity.mul _ _ _ _ (q.den : ℤ) (_ * _) - (Nat.prime_iff_prime_int.1 hp.1)] + emultiplicity_mul (b := _ * _) (Nat.prime_iff_prime_int.1 hp.1)] exact add_le_add_left h _) - _ ≤ _ := min_le_multiplicity_add + _ ≤ _ := min_le_emultiplicity_add /-- The minimum of the valuations of `q` and `r` is at most the valuation of `q + r`. -/ theorem min_le_padicValRat_add {q r : ℚ} (hqr : q + r ≠ 0) : @@ -476,11 +458,13 @@ theorem dvd_of_one_le_padicValNat {n : ℕ} (hp : 1 ≤ padicValNat p n) : p ∣ theorem pow_padicValNat_dvd {n : ℕ} : p ^ padicValNat p n ∣ n := by rcases n.eq_zero_or_pos with (rfl | hn); · simp rcases eq_or_ne p 1 with (rfl | hp); · simp - rw [multiplicity.pow_dvd_iff_le_multiplicity, padicValNat_def'] <;> assumption + apply pow_dvd_of_le_multiplicity + rw [padicValNat_def'] <;> assumption theorem padicValNat_dvd_iff_le [hp : Fact p.Prime] {a n : ℕ} (ha : a ≠ 0) : p ^ n ∣ a ↔ n ≤ padicValNat p a := by - rw [pow_dvd_iff_le_multiplicity, ← padicValNat_def' hp.out.ne_one ha.bot_lt, PartENat.coe_le_coe] + rw [pow_dvd_iff_le_emultiplicity, ← padicValNat_eq_emultiplicity (Nat.pos_of_ne_zero ha), + Nat.cast_le] theorem padicValNat_dvd_iff (n : ℕ) [hp : Fact p.Prime] (a : ℕ) : p ^ n ∣ a ↔ a = 0 ∨ n ≤ padicValNat p a := by @@ -569,10 +553,10 @@ theorem range_pow_padicValNat_subset_divisors' {n : ℕ} [hp : Fact p.Prime] : /-- The `p`-adic valuation of `(p * n)!` is `n` more than that of `n!`. -/ theorem padicValNat_factorial_mul (n : ℕ) [hp : Fact p.Prime] : padicValNat p (p * n) ! = padicValNat p n ! + n := by - refine PartENat.natCast_inj.mp ?_ - rw [padicValNat_def' (Nat.Prime.ne_one hp.out) <| factorial_pos (p * n), Nat.cast_add, - padicValNat_def' (Nat.Prime.ne_one hp.out) <| factorial_pos n] - exact Prime.multiplicity_factorial_mul hp.out + apply Nat.cast_injective (R := ℕ∞) + rw [padicValNat_eq_emultiplicity <| factorial_pos (p * n), Nat.cast_add, + padicValNat_eq_emultiplicity <| factorial_pos n] + exact Prime.emultiplicity_factorial_mul hp.out /-- The `p`-adic valuation of `m` equals zero if it is between `p * k` and `p * (k + 1)` for some `k`. -/ @@ -604,9 +588,9 @@ largest multiple of `p` below `n`, i.e. `(p * ⌊n / p⌋)!`. -/ The `p`-adic valuation of `n!` is the sum of the quotients `n / p ^ i`. This sum is expressed over the finset `Ico 1 b` where `b` is any bound greater than `log p n`. -/ theorem padicValNat_factorial {n b : ℕ} [hp : Fact p.Prime] (hnb : log p n < b) : - padicValNat p (n !) = ∑ i ∈ Finset.Ico 1 b, n / p ^ i := - PartENat.natCast_inj.mp ((padicValNat_def' (Nat.Prime.ne_one hp.out) <| factorial_pos _) ▸ - Prime.multiplicity_factorial hp.out hnb) + padicValNat p (n !) = ∑ i ∈ Finset.Ico 1 b, n / p ^ i := by + exact_mod_cast ((padicValNat_eq_emultiplicity (p := p) <| factorial_pos _) ▸ + Prime.emultiplicity_factorial hp.out hnb) /-- **Legendre's Theorem** @@ -626,9 +610,9 @@ in base `p`. This sum is expressed over the finset `Ico 1 b` where `b` is any bo `log p n`. -/ theorem padicValNat_choose {n k b : ℕ} [hp : Fact p.Prime] (hkn : k ≤ n) (hnb : log p n < b) : padicValNat p (choose n k) = - ((Finset.Ico 1 b).filter fun i => p ^ i ≤ k % p ^ i + (n - k) % p ^ i).card := - PartENat.natCast_inj.mp <| (padicValNat_def' (Nat.Prime.ne_one hp.out) <| choose_pos hkn) ▸ - Prime.multiplicity_choose hp.out hkn hnb + ((Finset.Ico 1 b).filter fun i => p ^ i ≤ k % p ^ i + (n - k) % p ^ i).card := by + exact_mod_cast (padicValNat_eq_emultiplicity (p := p) <| choose_pos hkn) ▸ + Prime.emultiplicity_choose hp.out hkn hnb /-- **Kummer's Theorem** @@ -637,9 +621,9 @@ in base `p`. This sum is expressed over the finset `Ico 1 b` where `b` is any bo `log p (n + k)`. -/ theorem padicValNat_choose' {n k b : ℕ} [hp : Fact p.Prime] (hnb : log p (n + k) < b) : padicValNat p (choose (n + k) k) = - ((Finset.Ico 1 b).filter fun i => p ^ i ≤ k % p ^ i + n % p ^ i).card := - PartENat.natCast_inj.mp <| (padicValNat_def' (Nat.Prime.ne_one hp.out) <| choose_pos <| - Nat.le_add_left k n)▸ Prime.multiplicity_choose' hp.out hnb + ((Finset.Ico 1 b).filter fun i => p ^ i ≤ k % p ^ i + n % p ^ i).card := by + exact_mod_cast (padicValNat_eq_emultiplicity (p := p) <| choose_pos <| + Nat.le_add_left k n)▸ Prime.emultiplicity_choose' hp.out hnb /-- **Kummer's Theorem** Taking (`p - 1`) times the `p`-adic valuation of the binomial `n + k` over `k` equals the sum of the diff --git a/Mathlib/NumberTheory/Padics/PadicVal/Defs.lean b/Mathlib/NumberTheory/Padics/PadicVal/Defs.lean index 1a6910baae3ae6..cba87c009c504f 100644 --- a/Mathlib/NumberTheory/Padics/PadicVal/Defs.lean +++ b/Mathlib/NumberTheory/Padics/PadicVal/Defs.lean @@ -29,16 +29,25 @@ variable {p : ℕ} /-- For `p ≠ 1`, the `p`-adic valuation of a natural `n ≠ 0` is the largest natural number `k` such that `p^k` divides `n`. If `n = 0` or `p = 1`, then `padicValNat p q` defaults to `0`. -/ def padicValNat (p : ℕ) (n : ℕ) : ℕ := - if h : p ≠ 1 ∧ 0 < n then (multiplicity p n).get (multiplicity.finite_nat_iff.2 h) else 0 + if h : p ≠ 1 ∧ 0 < n then Nat.find (multiplicity_finite_iff.2 h) else 0 + +theorem padicValNat_def' {n : ℕ} (hp : p ≠ 1) (hn : 0 < n) : + padicValNat p n = multiplicity p n := by + simp [padicValNat, hp, hn, multiplicity, emultiplicity, multiplicity_finite_iff.2 ⟨hp, hn⟩] + convert (WithTop.untop'_coe ..).symm /-- A simplification of `padicValNat` when one input is prime, by analogy with `padicValRat_def`. -/ theorem padicValNat_def [hp : Fact p.Prime] {n : ℕ} (hn : 0 < n) : - padicValNat p n = (multiplicity p n).get (multiplicity.finite_nat_iff.2 ⟨hp.out.ne_one, hn⟩) := - dif_pos ⟨hp.out.ne_one, hn⟩ + padicValNat p n = multiplicity p n := + padicValNat_def' hp.out.ne_one hn -theorem padicValNat_def' {n : ℕ} (hp : p ≠ 1) (hn : 0 < n) : - ↑(padicValNat p n) = multiplicity p n := by simp [padicValNat, hp, hn] +/-- A simplification of `padicValNat` when one input is prime, by analogy with +`padicValRat_def`. -/ +theorem padicValNat_eq_emultiplicity [hp : Fact p.Prime] {n : ℕ} (hn : 0 < n) : + padicValNat p n = emultiplicity p n := by + rw [(multiplicity_finite_iff.2 ⟨hp.out.ne_one, hn⟩).emultiplicity_eq_multiplicity] + exact_mod_cast padicValNat_def hn namespace padicValNat @@ -52,36 +61,34 @@ protected theorem zero : padicValNat p 0 = 0 := by simp [padicValNat] /-- `padicValNat p 1` is `0` for any `p`. -/ @[simp] -protected theorem one : padicValNat p 1 = 0 := by - unfold padicValNat - split_ifs - · simp - · rfl +protected theorem one : padicValNat p 1 = 0 := by simp [padicValNat] @[simp] theorem eq_zero_iff {n : ℕ} : padicValNat p n = 0 ↔ p = 1 ∨ n = 0 ∨ ¬p ∣ n := by - simp only [padicValNat, dite_eq_right_iff, PartENat.get_eq_iff_eq_coe, Nat.cast_zero, - multiplicity_eq_zero, and_imp, pos_iff_ne_zero, Ne, ← or_iff_not_imp_left] + simp only [padicValNat, ne_eq, pos_iff_ne_zero, dite_eq_right_iff, find_eq_zero, zero_add, + pow_one, and_imp, ← or_iff_not_imp_left] end padicValNat open List -theorem le_multiplicity_iff_replicate_subperm_primeFactorsList {a b : ℕ} {n : ℕ} (ha : a.Prime) +theorem le_emultiplicity_iff_replicate_subperm_primeFactorsList {a b : ℕ} {n : ℕ} (ha : a.Prime) (hb : b ≠ 0) : - ↑n ≤ multiplicity a b ↔ replicate n a <+~ b.primeFactorsList := + ↑n ≤ emultiplicity a b ↔ replicate n a <+~ b.primeFactorsList := (replicate_subperm_primeFactorsList_iff ha hb).trans - multiplicity.pow_dvd_iff_le_multiplicity |>.symm + pow_dvd_iff_le_emultiplicity |>.symm @[deprecated (since := "2024-07-17")] alias le_multiplicity_iff_replicate_subperm_factors := - le_multiplicity_iff_replicate_subperm_primeFactorsList + le_emultiplicity_iff_replicate_subperm_primeFactorsList theorem le_padicValNat_iff_replicate_subperm_primeFactorsList {a b : ℕ} {n : ℕ} (ha : a.Prime) (hb : b ≠ 0) : n ≤ padicValNat a b ↔ replicate n a <+~ b.primeFactorsList := by - rw [← le_multiplicity_iff_replicate_subperm_primeFactorsList ha hb, - ← padicValNat_def' ha.ne_one (Nat.pos_of_ne_zero hb), Nat.cast_le] + rw [← le_emultiplicity_iff_replicate_subperm_primeFactorsList ha hb, + Nat.multiplicity_finite_iff.2 ⟨ha.ne_one, Nat.pos_of_ne_zero hb⟩ + |>.emultiplicity_eq_multiplicity, ← padicValNat_def' ha.ne_one (Nat.pos_of_ne_zero hb), + Nat.cast_le] @[deprecated (since := "2024-07-17")] alias le_padicValNat_iff_replicate_subperm_factors := diff --git a/Mathlib/RingTheory/ChainOfDivisors.lean b/Mathlib/RingTheory/ChainOfDivisors.lean index 684edca6086c91..c188aa8e7b4974 100644 --- a/Mathlib/RingTheory/ChainOfDivisors.lean +++ b/Mathlib/RingTheory/ChainOfDivisors.lean @@ -302,32 +302,28 @@ theorem mem_normalizedFactors_factor_orderIso_of_mem_normalizedFactors {m p : As rw [associated_iff_eq] at hq' rwa [hq'] -variable [DecidableRel ((· ∣ ·) : M → M → Prop)] [DecidableRel ((· ∣ ·) : N → N → Prop)] - -theorem multiplicity_prime_le_multiplicity_image_by_factor_orderIso {m p : Associates M} +theorem emultiplicity_prime_le_emultiplicity_image_by_factor_orderIso {m p : Associates M} {n : Associates N} (hp : p ∈ normalizedFactors m) (d : Set.Iic m ≃o Set.Iic n) : - multiplicity p m ≤ multiplicity (↑(d ⟨p, dvd_of_mem_normalizedFactors hp⟩)) n := by + emultiplicity p m ≤ emultiplicity (↑(d ⟨p, dvd_of_mem_normalizedFactors hp⟩)) n := by by_cases hn : n = 0 · simp [hn] by_cases hm : m = 0 · simp [hm] at hp - rw [← - PartENat.natCast_get - (finite_iff_dom.1 <| finite_prime_left (prime_of_normalized_factor p hp) hm), - ← pow_dvd_iff_le_multiplicity] - exact pow_image_of_prime_by_factor_orderIso_dvd hn hp d (pow_multiplicity_dvd _) + rw [(finite_prime_left (prime_of_normalized_factor p hp) hm).emultiplicity_eq_multiplicity, + ← pow_dvd_iff_le_emultiplicity] + apply pow_image_of_prime_by_factor_orderIso_dvd hn hp d (pow_multiplicity_dvd ..) -theorem multiplicity_prime_eq_multiplicity_image_by_factor_orderIso {m p : Associates M} +theorem emultiplicity_prime_eq_emultiplicity_image_by_factor_orderIso {m p : Associates M} {n : Associates N} (hn : n ≠ 0) (hp : p ∈ normalizedFactors m) (d : Set.Iic m ≃o Set.Iic n) : - multiplicity p m = multiplicity (↑(d ⟨p, dvd_of_mem_normalizedFactors hp⟩)) n := by - refine le_antisymm (multiplicity_prime_le_multiplicity_image_by_factor_orderIso hp d) ?_ - suffices multiplicity (↑(d ⟨p, dvd_of_mem_normalizedFactors hp⟩)) n ≤ - multiplicity (↑(d.symm (d ⟨p, dvd_of_mem_normalizedFactors hp⟩))) m by + emultiplicity p m = emultiplicity (↑(d ⟨p, dvd_of_mem_normalizedFactors hp⟩)) n := by + refine le_antisymm (emultiplicity_prime_le_emultiplicity_image_by_factor_orderIso hp d) ?_ + suffices emultiplicity (↑(d ⟨p, dvd_of_mem_normalizedFactors hp⟩)) n ≤ + 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) simpa only [Subtype.coe_eta] using - multiplicity_prime_le_multiplicity_image_by_factor_orderIso + emultiplicity_prime_le_emultiplicity_image_by_factor_orderIso (mem_normalizedFactors_factor_orderIso_of_mem_normalizedFactors hn hp d) d.symm end @@ -401,17 +397,15 @@ theorem mem_normalizedFactors_factor_dvd_iso_of_mem_normalizedFactors {m p : M} (mk_le_mk_of_dvd (dvd_of_mem_normalizedFactors hp)) simpa only [associated_iff_eq.mp hq', associatesEquivOfUniqueUnits_symm_apply] using hq -variable [DecidableRel ((· ∣ ·) : M → M → Prop)] [DecidableRel ((· ∣ ·) : N → N → Prop)] - -theorem multiplicity_factor_dvd_iso_eq_multiplicity_of_mem_normalizedFactors {m p : M} {n : N} +theorem emultiplicity_factor_dvd_iso_eq_emultiplicity_of_mem_normalizedFactors {m p : M} {n : N} (hm : m ≠ 0) (hn : n ≠ 0) (hp : p ∈ normalizedFactors m) {d : { l : M // l ∣ m } ≃ { l : N // l ∣ n }} (hd : ∀ l l', (d l : N) ∣ d l' ↔ (l : M) ∣ l') : - multiplicity (d ⟨p, dvd_of_mem_normalizedFactors hp⟩ : N) n = multiplicity p m := by + emultiplicity (d ⟨p, dvd_of_mem_normalizedFactors hp⟩ : N) n = emultiplicity p m := by apply Eq.symm - suffices multiplicity (Associates.mk p) (Associates.mk m) = multiplicity (Associates.mk + suffices emultiplicity (Associates.mk p) (Associates.mk m) = emultiplicity (Associates.mk ↑(d ⟨associatesEquivOfUniqueUnits (associatesEquivOfUniqueUnits.symm p), by simp [dvd_of_mem_normalizedFactors hp]⟩)) (Associates.mk n) by - simpa only [multiplicity_mk_eq_multiplicity, associatesEquivOfUniqueUnits_symm_apply, + simpa only [emultiplicity_mk_eq_emultiplicity, associatesEquivOfUniqueUnits_symm_apply, associatesEquivOfUniqueUnits_apply, out_mk, normalize_eq] using this have : Associates.mk (d ⟨associatesEquivOfUniqueUnits (associatesEquivOfUniqueUnits.symm p), by simp only [dvd_of_mem_normalizedFactors hp, associatesEquivOfUniqueUnits_symm_apply, @@ -422,7 +416,7 @@ theorem multiplicity_factor_dvd_iso_eq_multiplicity_of_mem_normalizedFactors {m rw [mkFactorOrderIsoOfFactorDvdEquiv_apply_coe] rw [this] refine - multiplicity_prime_eq_multiplicity_image_by_factor_orderIso (mk_ne_zero.mpr hn) ?_ + emultiplicity_prime_eq_emultiplicity_image_by_factor_orderIso (mk_ne_zero.mpr hn) ?_ (mkFactorOrderIsoOfFactorDvdEquiv hd) obtain ⟨q, hq, hq'⟩ := exists_mem_normalizedFactors_of_dvd (mk_ne_zero.mpr hm) diff --git a/Mathlib/RingTheory/DedekindDomain/Ideal.lean b/Mathlib/RingTheory/DedekindDomain/Ideal.lean index 1865cebc778f35..3fae07bf9f31ef 100644 --- a/Mathlib/RingTheory/DedekindDomain/Ideal.lean +++ b/Mathlib/RingTheory/DedekindDomain/Ideal.lean @@ -897,24 +897,27 @@ theorem irreducible_pow_sup [DecidableEq (Ideal T)] (hI : I ≠ ⊥) (hJ : Irred rw [sup_eq_prod_inf_factors (pow_ne_zero n hJ.ne_zero) hI, min_comm, normalizedFactors_of_irreducible_pow hJ, normalize_eq J, replicate_inter, prod_replicate] -theorem irreducible_pow_sup_of_le [DecidableRel fun (x : Ideal T) x_1 ↦ x ∣ x_1] - (hJ : Irreducible J) (n : ℕ) (hn : ↑n ≤ multiplicity J I) : +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] - rwa [multiplicity_eq_count_normalizedFactors hJ hI, PartENat.coe_le_coe, normalize_eq J] at hn + rw [emultiplicity_eq_count_normalizedFactors hJ hI, normalize_eq J] at hn + exact_mod_cast hn -theorem irreducible_pow_sup_of_ge [DecidableRel fun (x : Ideal T) x_1 ↦ x ∣ x_1] - (hI : I ≠ ⊥) (hJ : Irreducible J) (n : ℕ) (hn : multiplicity J I ≤ n) : - J ^ n ⊔ I = J ^ (multiplicity J I).get (PartENat.dom_of_le_natCast hn) := by +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 [← PartENat.natCast_inj, PartENat.natCast_get, - multiplicity_eq_count_normalizedFactors hJ hI, normalize_eq J] - · rwa [multiplicity_eq_count_normalizedFactors hJ hI, PartENat.coe_le_coe, normalize_eq J] at hn + rw [← Nat.cast_inj (R := ℕ∞), ← multiplicity.Finite.emultiplicity_eq_multiplicity, + emultiplicity_eq_count_normalizedFactors hJ hI, normalize_eq J] + rw [← emultiplicity_lt_top] + apply hn.trans_lt + simp + · rw [emultiplicity_eq_count_normalizedFactors hJ hI, normalize_eq J] at hn + exact_mod_cast hn theorem Ideal.eq_prime_pow_mul_coprime [DecidableEq (Ideal T)] {I : Ideal T} (hI : I ≠ ⊥) (P : Ideal T) [hpm : P.IsMaximal] : @@ -1119,15 +1122,12 @@ theorem normalizedFactorsEquivOfQuotEquiv_symm (hI : I ≠ ⊥) (hJ : J ≠ ⊥) (normalizedFactorsEquivOfQuotEquiv f hI hJ).symm = normalizedFactorsEquivOfQuotEquiv f.symm hJ hI := rfl -variable [DecidableRel ((· ∣ ·) : Ideal R → Ideal R → Prop)] -variable [DecidableRel ((· ∣ ·) : Ideal A → Ideal A → Prop)] - /-- The map `normalizedFactorsEquivOfQuotEquiv` preserves multiplicities. -/ -theorem normalizedFactorsEquivOfQuotEquiv_multiplicity_eq_multiplicity (hI : I ≠ ⊥) (hJ : J ≠ ⊥) +theorem normalizedFactorsEquivOfQuotEquiv_emultiplicity_eq_emultiplicity (hI : I ≠ ⊥) (hJ : J ≠ ⊥) (L : Ideal R) (hL : L ∈ normalizedFactors I) : - multiplicity (↑(normalizedFactorsEquivOfQuotEquiv f hI hJ ⟨L, hL⟩)) J = multiplicity L I := by + emultiplicity (↑(normalizedFactorsEquivOfQuotEquiv f hI hJ ⟨L, hL⟩)) J = emultiplicity L I := by rw [normalizedFactorsEquivOfQuotEquiv, Equiv.coe_fn_mk, Subtype.coe_mk] - refine multiplicity_factor_dvd_iso_eq_multiplicity_of_mem_normalizedFactors hI hJ hL + refine emultiplicity_factor_dvd_iso_eq_emultiplicity_of_mem_normalizedFactors hI hJ hL (d := (idealFactorsEquivOfQuotEquiv f).toEquiv) ?_ exact fun ⟨l, hl⟩ ⟨l', hl'⟩ => idealFactorsEquivOfQuotEquiv_is_dvd_iso f hl hl' @@ -1341,23 +1341,20 @@ theorem singleton_span_mem_normalizedFactors_of_mem_normalizedFactors [Normaliza · by_contra h exact (prime_of_normalized_factor a ha).ne_zero (span_singleton_eq_bot.mp h) -theorem multiplicity_eq_multiplicity_span [DecidableRel ((· ∣ ·) : R → R → Prop)] - [DecidableRel ((· ∣ ·) : Ideal R → Ideal R → Prop)] {a b : R} : - multiplicity (Ideal.span {a}) (Ideal.span ({b} : Set R)) = multiplicity a b := by +theorem emultiplicity_eq_emultiplicity_span {a b : R} : + emultiplicity (Ideal.span {a}) (Ideal.span ({b} : Set R)) = emultiplicity a b := by by_cases h : Finite a b - · rw [← PartENat.natCast_get (finite_iff_dom.mp h)] - refine (multiplicity.unique - (show Ideal.span {a} ^ (multiplicity a b).get h ∣ Ideal.span {b} from ?_) ?_).symm <;> + · rw [h.emultiplicity_eq_multiplicity] + apply emultiplicity_eq_of_dvd_of_not_dvd <;> rw [Ideal.span_singleton_pow, span_singleton_dvd_span_singleton_iff_dvd] - · exact pow_multiplicity_dvd h - · exact multiplicity.is_greatest - ((PartENat.lt_coe_iff _ _).mpr (Exists.intro (finite_iff_dom.mp h) (Nat.lt_succ_self _))) + · exact pow_multiplicity_dvd a b + · apply h.not_pow_dvd_of_multiplicity_lt + apply lt_add_one · suffices ¬Finite (Ideal.span ({a} : Set R)) (Ideal.span ({b} : Set R)) by - rw [finite_iff_dom, PartENat.not_dom_iff_eq_top] at h this - rw [h, this] - exact not_finite_iff_forall.mpr fun n => by + rw [emultiplicity_eq_top.2 h, emultiplicity_eq_top.2 this] + exact Finite.not_iff_forall.mpr fun n => by rw [Ideal.span_singleton_pow, span_singleton_dvd_span_singleton_iff_dvd] - exact not_finite_iff_forall.mp h n + exact Finite.not_iff_forall.mp h n section NormalizationMonoid variable [NormalizationMonoid R] @@ -1389,29 +1386,27 @@ noncomputable def normalizedFactorsEquivSpanNormalizedFactors {r : R} (hr : r ((show Ideal.span {r} ≤ i from dvd_iff_le.mp (dvd_of_mem_normalizedFactors hi)) (mem_span_singleton.mpr (dvd_refl r))) -variable [DecidableRel ((· ∣ ·) : R → R → Prop)] [DecidableRel ((· ∣ ·) : Ideal R → Ideal R → Prop)] - /-- 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`.-/ -theorem multiplicity_normalizedFactorsEquivSpanNormalizedFactors_eq_multiplicity {r d : R} +theorem emultiplicity_normalizedFactorsEquivSpanNormalizedFactors_eq_emultiplicity {r d : R} (hr : r ≠ 0) (hd : d ∈ normalizedFactors r) : - multiplicity d r = - multiplicity (normalizedFactorsEquivSpanNormalizedFactors hr ⟨d, hd⟩ : Ideal R) + emultiplicity d r = + emultiplicity (normalizedFactorsEquivSpanNormalizedFactors hr ⟨d, hd⟩ : Ideal R) (Ideal.span {r}) := by - simp only [normalizedFactorsEquivSpanNormalizedFactors, multiplicity_eq_multiplicity_span, + simp only [normalizedFactorsEquivSpanNormalizedFactors, emultiplicity_eq_emultiplicity_span, Subtype.coe_mk, Equiv.ofBijective_apply] /-- The bijection `normalized_factors_equiv_span_normalized_factors.symm` between the set of prime factors of the ideal `⟨r⟩` and the set of prime factors of `r` preserves multiplicities. -/ -theorem multiplicity_normalizedFactorsEquivSpanNormalizedFactors_symm_eq_multiplicity {r : R} +theorem emultiplicity_normalizedFactorsEquivSpanNormalizedFactors_symm_eq_emultiplicity {r : R} (hr : r ≠ 0) (I : { I : Ideal R | I ∈ normalizedFactors (Ideal.span ({r} : Set R)) }) : - multiplicity ((normalizedFactorsEquivSpanNormalizedFactors hr).symm I : R) r = - multiplicity (I : Ideal R) (Ideal.span {r}) := by + emultiplicity ((normalizedFactorsEquivSpanNormalizedFactors hr).symm I : R) r = + emultiplicity (I : Ideal R) (Ideal.span {r}) := by obtain ⟨x, hx⟩ := (normalizedFactorsEquivSpanNormalizedFactors hr).surjective I obtain ⟨a, ha⟩ := x rw [hx.symm, Equiv.symm_apply_apply, Subtype.coe_mk, - multiplicity_normalizedFactorsEquivSpanNormalizedFactors_eq_multiplicity hr ha] + emultiplicity_normalizedFactorsEquivSpanNormalizedFactors_eq_emultiplicity hr ha] variable [DecidableEq R] [DecidableEq (Ideal R)] @@ -1422,9 +1417,9 @@ variable [DecidableEq R] [DecidableEq (Ideal R)] theorem count_span_normalizedFactors_eq {r X : R} (hr : r ≠ 0) (hX : Prime X) : Multiset.count (Ideal.span {X} : Ideal R) (normalizedFactors (Ideal.span {r})) = Multiset.count (normalize X) (normalizedFactors r) := by - have := multiplicity_eq_multiplicity_span (R := R) (a := X) (b := r) - rw [multiplicity_eq_count_normalizedFactors (Prime.irreducible hX) hr, - multiplicity_eq_count_normalizedFactors (Prime.irreducible ?_), normalize_apply, + have := emultiplicity_eq_emultiplicity_span (R := R) (a := X) (b := r) + rw [emultiplicity_eq_count_normalizedFactors (Prime.irreducible hX) hr, + emultiplicity_eq_count_normalizedFactors (Prime.irreducible ?_), normalize_apply, normUnit_eq_one, Units.val_one, one_eq_top, mul_top, Nat.cast_inj] at this · simp only [normalize_apply, this] · simp only [Submodule.zero_eq_bot, ne_eq, span_singleton_eq_bot, hr, not_false_eq_true] diff --git a/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean b/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean index 214213dcd11a6c..74b2f5eeab2faf 100644 --- a/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean +++ b/Mathlib/RingTheory/DiscreteValuationRing/Basic.lean @@ -365,21 +365,20 @@ theorem unit_mul_pow_congr_unit {ϖ : R} (hirr : Irreducible ϖ) (u v : Rˣ) (m /-! ## The additive valuation on a DVR -/ -open multiplicity open Classical in -/-- The `PartENat`-valued additive valuation on a DVR. -/ +/-- The `ℕ∞`-valued additive valuation on a DVR. -/ noncomputable def addVal (R : Type u) [CommRing R] [IsDomain R] [DiscreteValuationRing R] : - AddValuation R PartENat := - addValuation (Classical.choose_spec (exists_prime R)) + AddValuation R ℕ∞ := + multiplicity_addValuation (Classical.choose_spec (exists_prime R)) theorem addVal_def (r : R) (u : Rˣ) {ϖ : R} (hϖ : Irreducible ϖ) (n : ℕ) (hr : r = u * ϖ ^ n) : addVal R r = n := by classical - rw [addVal, addValuation_apply, hr, eq_of_associated_left + rw [addVal, multiplicity_addValuation_apply, hr, emultiplicity_eq_of_associated_left (associated_of_irreducible R hϖ (Classical.choose_spec (exists_prime R)).irreducible), - eq_of_associated_right (Associated.symm ⟨u, mul_comm _ _⟩), - multiplicity_pow_self_of_prime (irreducible_iff_prime.1 hϖ)] + emultiplicity_eq_of_associated_right (Associated.symm ⟨u, mul_comm _ _⟩), + emultiplicity_pow_self_of_prime (irreducible_iff_prime.1 hϖ)] theorem addVal_def' (u : Rˣ) {ϖ : R} (hϖ : Irreducible ϖ) (n : ℕ) : addVal R ((u : R) * ϖ ^ n) = n := @@ -418,7 +417,7 @@ theorem addVal_eq_top_iff {a : R} : addVal R a = ⊤ ↔ a = 0 := by obtain ⟨n, ha⟩ := associated_pow_irreducible h hi obtain ⟨u, rfl⟩ := ha.symm rw [mul_comm, addVal_def' u hi n] - exact PartENat.natCast_ne_top _ + nofun · rintro rfl exact addVal_zero @@ -431,10 +430,11 @@ theorem addVal_le_iff_dvd {a b : R} : addVal R a ≤ addVal R b ↔ a ∣ b := b rw [h] apply dvd_zero obtain ⟨n, ha⟩ := associated_pow_irreducible ha0 hp.irreducible - rw [addVal, addValuation_apply, addValuation_apply, multiplicity_le_multiplicity_iff] at h + rw [addVal, multiplicity_addValuation_apply, multiplicity_addValuation_apply, + emultiplicity_le_emultiplicity_iff] at h exact ha.dvd.trans (h n ha.symm.dvd) - · rw [addVal, addValuation_apply, addValuation_apply] - exact multiplicity_le_multiplicity_of_dvd_right h + · rw [addVal, multiplicity_addValuation_apply, multiplicity_addValuation_apply] + exact emultiplicity_le_emultiplicity_of_dvd_right h theorem addVal_add {a b : R} : min (addVal R a) (addVal R b) ≤ addVal R (a + b) := (addVal R).map_add _ _ @@ -447,7 +447,7 @@ instance (R : Type*) [CommRing R] [IsDomain R] [DiscreteValuationRing R] : 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, PartENat.eq_top_iff_forall_le] + rwa [← addVal_eq_top_iff, ← WithTop.forall_ge_iff_eq_top] end DiscreteValuationRing diff --git a/Mathlib/RingTheory/Multiplicity.lean b/Mathlib/RingTheory/Multiplicity.lean index 1ae9ede282f648..42f7495bb32f16 100644 --- a/Mathlib/RingTheory/Multiplicity.lean +++ b/Mathlib/RingTheory/Multiplicity.lean @@ -1,13 +1,12 @@ /- Copyright (c) 2018 Robert Y. Lewis. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Robert Y. Lewis, Chris Hughes +Authors: Robert Y. Lewis, Chris Hughes, Daniel Weber -/ import Mathlib.Algebra.Associated.Basic import Mathlib.Algebra.BigOperators.Group.Finset -import Mathlib.Algebra.SMulWithZero -import Mathlib.Data.Nat.PartENat import Mathlib.Tactic.Linarith +import Mathlib.Data.ENat.Basic /-! # Multiplicity of a divisor @@ -17,237 +16,388 @@ several basic results on it. ## Main definitions -* `multiplicity a b`: for two elements `a` and `b` of a commutative monoid returns the largest +* `emultiplicity a b`: for two elements `a` and `b` of a commutative monoid returns the largest number `n` such that `a ^ n ∣ b` or infinity, written `⊤`, if `a ^ n ∣ b` for all natural numbers `n`. +* `multiplicity a b`: a `ℕ`-valued version of `multiplicity`, defaulting for `1` instead of `⊤`. + The reason for using `1` as a default value instead of `0` is to have `multiplicity_eq_zero_iff`. * `multiplicity.Finite a b`: a predicate denoting that the multiplicity of `a` in `b` is finite. -/ variable {α β : Type*} -open Nat Part +open Nat -/-- `multiplicity a b` returns the largest natural number `n` such that - `a ^ n ∣ b`, as a `PartENat` or natural with infinity. If `∀ n, a ^ n ∣ b`, - then it returns `⊤`-/ -def multiplicity [Monoid α] [DecidableRel ((· ∣ ·) : α → α → Prop)] (a b : α) : PartENat := - PartENat.find fun n => ¬a ^ (n + 1) ∣ b +/-- `multiplicity.Finite a b` indicates that the multiplicity of `a` in `b` is finite. -/ +abbrev multiplicity.Finite [Monoid α] (a b : α) : Prop := + ∃ n : ℕ, ¬a ^ (n + 1) ∣ b + +open scoped Classical in +/-- `emultiplicity a b` returns the largest natural number `n` such that + `a ^ n ∣ b`, as an `ℕ∞`. If `∀ n, a ^ n ∣ b` then it returns `⊤`. -/ +noncomputable def emultiplicity [Monoid α] (a b : α) : ℕ∞ := + if h : multiplicity.Finite a b then Nat.find h else ⊤ -namespace multiplicity +/-- A `ℕ`-valued version of `emultiplicity`, returning `1` instead of `⊤`. -/ +noncomputable def multiplicity [Monoid α] (a b : α) : ℕ := + (emultiplicity a b).untop' 1 + +open multiplicity section Monoid -variable [Monoid α] [Monoid β] +variable [Monoid α] [Monoid β] {a b : α} -/-- `multiplicity.Finite a b` indicates that the multiplicity of `a` in `b` is finite. -/ -abbrev Finite (a b : α) : Prop := - ∃ n : ℕ, ¬a ^ (n + 1) ∣ b +@[simp] +theorem emultiplicity_eq_top : + emultiplicity a b = ⊤ ↔ ¬Finite a b := by + simp [emultiplicity] + +theorem emultiplicity_lt_top {a b : α} : emultiplicity a b < ⊤ ↔ Finite a b := by + simp [lt_top_iff_ne_top, emultiplicity_eq_top] + +theorem finite_iff_emultiplicity_ne_top : + Finite a b ↔ emultiplicity a b ≠ ⊤ := by simp + +alias ⟨Finite.emultiplicity_ne_top, _⟩ := finite_iff_emultiplicity_ne_top + +theorem finite_of_emultiplicity_eq_natCast {n : ℕ} (h : emultiplicity a b = n) : + Finite a b := by + by_contra! nh + rw [← emultiplicity_eq_top, h] at nh + trivial + +theorem multiplicity_eq_of_emultiplicity_eq_some {n : ℕ} (h : emultiplicity a b = n) : + multiplicity a b = n := by + simp [multiplicity, h] + rfl + +theorem emultiplicity_ne_of_multiplicity_ne {n : ℕ} : + multiplicity a b ≠ n → emultiplicity a b ≠ n := + mt multiplicity_eq_of_emultiplicity_eq_some + +theorem multiplicity.Finite.emultiplicity_eq_multiplicity (h : Finite a b) : + emultiplicity a b = multiplicity a b := by + cases hm : emultiplicity a b + · simp [h] at hm + rw [multiplicity_eq_of_emultiplicity_eq_some hm] + +theorem multiplicity.Finite.emultiplicity_eq_iff_multiplicity_eq {n : ℕ} (h : Finite a b) : + emultiplicity a b = n ↔ multiplicity a b = n := by + simp [h.emultiplicity_eq_multiplicity] + +theorem emultiplicity_eq_iff_multiplicity_eq_of_ne_one {n : ℕ} (h : n ≠ 1) : + emultiplicity a b = n ↔ multiplicity a b = n := by + constructor + · exact multiplicity_eq_of_emultiplicity_eq_some + · intro h₂ + simpa [multiplicity, WithTop.untop'_eq_iff, h] using h₂ + +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 -theorem finite_iff_dom [DecidableRel ((· ∣ ·) : α → α → Prop)] {a b : α} : - Finite a b ↔ (multiplicity a b).Dom := - Iff.rfl +@[simp] +theorem multiplicity_eq_one_of_not_finite (h : ¬Finite a b) : + multiplicity a b = 1 := by + simp [multiplicity, emultiplicity_eq_top.2 h] + +@[simp] +theorem multiplicity_le_emultiplicity : + multiplicity a b ≤ emultiplicity a b := by + by_cases hf : Finite a b + · simp [hf.emultiplicity_eq_multiplicity] + · simp [hf, emultiplicity_eq_top.2] -theorem finite_def {a b : α} : Finite a b ↔ ∃ n : ℕ, ¬a ^ (n + 1) ∣ b := +@[simp] +theorem multiplicity_eq_of_emultiplicity_eq {c d : β} + (h : emultiplicity a b = emultiplicity c d) : multiplicity a b = multiplicity c d := by + unfold multiplicity + rw [h] + +theorem multiplicity_le_of_emultiplicity_le {n : ℕ} (h : emultiplicity a b ≤ n) : + multiplicity a b ≤ n := by + exact_mod_cast multiplicity_le_emultiplicity.trans h + +theorem multiplicity.Finite.emultiplicity_le_of_multiplicity_le (hfin : Finite a b) + {n : ℕ} (h : multiplicity a b ≤ n) : emultiplicity a b ≤ n := by + rw [emultiplicity_eq_multiplicity hfin] + assumption_mod_cast + +theorem le_emultiplicity_of_le_multiplicity {n : ℕ} (h : n ≤ multiplicity a b) : + n ≤ emultiplicity a b := by + exact_mod_cast (WithTop.coe_mono h).trans multiplicity_le_emultiplicity + +theorem multiplicity.Finite.le_multiplicity_of_le_emultiplicity (hfin : Finite a b) + {n : ℕ} (h : n ≤ emultiplicity a b) : n ≤ multiplicity a b := by + rw [emultiplicity_eq_multiplicity hfin] at h + assumption_mod_cast + +theorem multiplicity_lt_of_emultiplicity_lt {n : ℕ} (h : emultiplicity a b < n) : + multiplicity a b < n := by + exact_mod_cast multiplicity_le_emultiplicity.trans_lt h + +theorem multiplicity.Finite.emultiplicity_lt_of_multiplicity_lt (hfin : Finite a b) + {n : ℕ} (h : multiplicity a b < n) : emultiplicity a b < n := by + rw [emultiplicity_eq_multiplicity hfin] + assumption_mod_cast + +theorem lt_emultiplicity_of_lt_multiplicity {n : ℕ} (h : n < multiplicity a b) : + n < emultiplicity a b := by + exact_mod_cast (WithTop.coe_strictMono h).trans_le multiplicity_le_emultiplicity + +theorem multiplicity.Finite.lt_multiplicity_of_lt_emultiplicity (hfin : Finite a b) + {n : ℕ} (h : n < emultiplicity a b) : n < multiplicity a b := by + rw [emultiplicity_eq_multiplicity hfin] at h + assumption_mod_cast + +theorem emultiplicity_pos_iff : + 0 < emultiplicity a b ↔ 0 < multiplicity a b := by + simp [pos_iff_ne_zero, pos_iff_ne_zero, emultiplicity_eq_zero_iff_multiplicity_eq_zero] + +theorem multiplicity.Finite.def : Finite a b ↔ ∃ n : ℕ, ¬a ^ (n + 1) ∣ b := Iff.rfl -theorem not_dvd_one_of_finite_one_right {a : α} : Finite a 1 → ¬a ∣ 1 := fun ⟨n, hn⟩ ⟨d, hd⟩ => +theorem multiplicity.Finite.not_dvd_of_one_right : Finite a 1 → ¬a ∣ 1 := fun ⟨n, hn⟩ ⟨d, hd⟩ => hn ⟨d ^ (n + 1), (pow_mul_pow_eq_one (n + 1) hd.symm).symm⟩ @[norm_cast] -theorem Int.natCast_multiplicity (a b : ℕ) : multiplicity (a : ℤ) (b : ℤ) = multiplicity a b := by - apply Part.ext' - · rw [← @finite_iff_dom ℕ, @finite_def ℕ, ← @finite_iff_dom ℤ, @finite_def ℤ] - norm_cast - · intro h1 h2 - apply _root_.le_antisymm <;> - · apply Nat.find_mono - norm_cast - simp +theorem Int.natCast_emultiplicity (a b : ℕ) : + emultiplicity (a : ℤ) (b : ℤ) = emultiplicity a b := by + unfold emultiplicity multiplicity.Finite + congr! <;> norm_cast + +@[norm_cast] +theorem Int.natCast_multiplicity (a b : ℕ) : multiplicity (a : ℤ) (b : ℤ) = multiplicity a b := + multiplicity_eq_of_emultiplicity_eq (natCast_emultiplicity a b) @[deprecated (since := "2024-04-05")] alias Int.coe_nat_multiplicity := Int.natCast_multiplicity -theorem not_finite_iff_forall {a b : α} : ¬Finite a b ↔ ∀ n : ℕ, a ^ n ∣ b := +theorem multiplicity.Finite.not_iff_forall : ¬Finite a b ↔ ∀ n : ℕ, a ^ n ∣ b := ⟨fun h n => Nat.casesOn n (by rw [_root_.pow_zero] exact one_dvd _) - (by simpa [Finite, Classical.not_not] using h), - by simp [Finite, multiplicity, Classical.not_not]; tauto⟩ + (by simpa [multiplicity.Finite, Classical.not_not] using h), + by simp [multiplicity.Finite, multiplicity, Classical.not_not]; tauto⟩ -theorem not_unit_of_finite {a b : α} (h : Finite a b) : ¬IsUnit a := +theorem multiplicity.Finite.not_unit (h : Finite a b) : ¬IsUnit a := let ⟨n, hn⟩ := h hn ∘ IsUnit.dvd ∘ IsUnit.pow (n + 1) -theorem finite_of_finite_mul_right {a b c : α} : Finite a (b * c) → Finite a b := fun ⟨n, hn⟩ => +theorem multiplicity.Finite.mul_left {c : α} : Finite a (b * c) → Finite a b := fun ⟨n, hn⟩ => ⟨n, fun h => hn (h.trans (dvd_mul_right _ _))⟩ -variable [DecidableRel ((· ∣ ·) : α → α → Prop)] [DecidableRel ((· ∣ ·) : β → β → Prop)] - -theorem pow_dvd_of_le_multiplicity {a b : α} {k : ℕ} : - (k : PartENat) ≤ multiplicity a b → a ^ k ∣ b := by - rw [← PartENat.some_eq_natCast] - exact - Nat.casesOn k - (fun _ => by - rw [_root_.pow_zero] - exact one_dvd _) - fun k ⟨_, h₂⟩ => by_contradiction fun hk => Nat.find_min _ (lt_of_succ_le (h₂ ⟨k, hk⟩)) hk - -theorem pow_multiplicity_dvd {a b : α} (h : Finite a b) : a ^ get (multiplicity a b) h ∣ b := - pow_dvd_of_le_multiplicity (by rw [PartENat.natCast_get]) +theorem pow_dvd_of_le_emultiplicity {k : ℕ} (hk : k ≤ emultiplicity a b) : + a ^ k ∣ b := by classical + cases k + · simp + unfold emultiplicity at hk + split at hk + · norm_cast at hk + simpa using (Nat.find_min _ (lt_of_succ_le hk)) + · apply Finite.not_iff_forall.mp ‹_› -theorem is_greatest {a b : α} {m : ℕ} (hm : multiplicity a b < m) : ¬a ^ m ∣ b := fun h => by - rw [PartENat.lt_coe_iff] at hm; exact Nat.find_spec hm.fst ((pow_dvd_pow _ hm.snd).trans h) +theorem pow_dvd_of_le_multiplicity {k : ℕ} (hk : k ≤ multiplicity a b) : + a ^ k ∣ b := pow_dvd_of_le_emultiplicity (le_emultiplicity_of_le_multiplicity hk) -theorem is_greatest' {a b : α} {m : ℕ} (h : Finite a b) (hm : get (multiplicity a b) h < m) : - ¬a ^ m ∣ b := - is_greatest (by rwa [← PartENat.coe_lt_coe, PartENat.natCast_get] at hm) - -theorem pos_of_dvd {a b : α} (hfin : Finite a b) (hdiv : a ∣ b) : - 0 < (multiplicity a b).get hfin := by +@[simp] +theorem pow_multiplicity_dvd (a b : α) : a ^ (multiplicity a b) ∣ b := + pow_dvd_of_le_multiplicity le_rfl + +theorem not_pow_dvd_of_emultiplicity_lt {m : ℕ} (hm : emultiplicity a b < m) : + ¬a ^ m ∣ b := fun nh => by + unfold emultiplicity at hm + split at hm + · simp only [cast_lt, find_lt_iff] at hm + obtain ⟨n, hn1, hn2⟩ := hm + exact hn2 ((pow_dvd_pow _ hn1).trans nh) + · simp at hm + +theorem multiplicity.Finite.not_pow_dvd_of_multiplicity_lt (hf : Finite a b) {m : ℕ} + (hm : multiplicity a b < m) : ¬a ^ m ∣ b := by + apply not_pow_dvd_of_emultiplicity_lt + rw [hf.emultiplicity_eq_multiplicity] + norm_cast + +theorem multiplicity_pos_of_dvd (hdiv : a ∣ b) : 0 < multiplicity a b := by refine zero_lt_iff.2 fun h => ?_ - simpa [hdiv] using is_greatest' hfin (lt_one_iff.mpr h) - -theorem unique {a b : α} {k : ℕ} (hk : a ^ k ∣ b) (hsucc : ¬a ^ (k + 1) ∣ b) : - (k : PartENat) = multiplicity a b := - le_antisymm (le_of_not_gt fun hk' => is_greatest hk' hk) <| by - have : Finite a b := ⟨k, hsucc⟩ - rw [PartENat.le_coe_iff] - exact ⟨this, Nat.find_min' _ hsucc⟩ - -theorem unique' {a b : α} {k : ℕ} (hk : a ^ k ∣ b) (hsucc : ¬a ^ (k + 1) ∣ b) : - k = get (multiplicity a b) ⟨k, hsucc⟩ := by - rw [← PartENat.natCast_inj, PartENat.natCast_get, unique hk hsucc] - -theorem le_multiplicity_of_pow_dvd {a b : α} {k : ℕ} (hk : a ^ k ∣ b) : - (k : PartENat) ≤ multiplicity a b := - le_of_not_gt fun hk' => is_greatest hk' hk - -theorem pow_dvd_iff_le_multiplicity {a b : α} {k : ℕ} : - a ^ k ∣ b ↔ (k : PartENat) ≤ multiplicity a b := - ⟨le_multiplicity_of_pow_dvd, pow_dvd_of_le_multiplicity⟩ + simpa [hdiv] using Finite.not_pow_dvd_of_multiplicity_lt + (by by_contra! nh; simp [nh] at h) (lt_one_iff.mpr h) + +theorem emultiplicity_pos_of_dvd (hdiv : a ∣ b) : 0 < emultiplicity a b := + lt_emultiplicity_of_lt_multiplicity (multiplicity_pos_of_dvd hdiv) + +theorem emultiplicity_eq_of_dvd_of_not_dvd {k : ℕ} (hk : a ^ k ∣ b) (hsucc : ¬a ^ (k + 1) ∣ b) : + emultiplicity a b = k := by classical + have : Finite a b := ⟨k, hsucc⟩ + simp only [emultiplicity, this, ↓reduceDIte, Nat.cast_inj, find_eq_iff, hsucc, not_false_eq_true, + Decidable.not_not, true_and] + exact fun n hn ↦ (pow_dvd_pow _ hn).trans hk + +theorem multiplicity_eq_of_dvd_of_not_dvd {k : ℕ} (hk : a ^ k ∣ b) (hsucc : ¬a ^ (k + 1) ∣ b) : + multiplicity a b = k := + multiplicity_eq_of_emultiplicity_eq_some (emultiplicity_eq_of_dvd_of_not_dvd hk hsucc) + +theorem le_emultiplicity_of_pow_dvd {k : ℕ} (hk : a ^ k ∣ b) : + k ≤ emultiplicity a b := + le_of_not_gt fun hk' => not_pow_dvd_of_emultiplicity_lt hk' hk + +theorem multiplicity.Finite.le_multiplicity_of_pow_dvd (hf : Finite a b) {k : ℕ} (hk : a ^ k ∣ b) : + k ≤ multiplicity a b := + hf.le_multiplicity_of_le_emultiplicity (le_emultiplicity_of_pow_dvd hk) + +theorem pow_dvd_iff_le_emultiplicity {k : ℕ} : + a ^ k ∣ b ↔ k ≤ emultiplicity a b := + ⟨le_emultiplicity_of_pow_dvd, pow_dvd_of_le_emultiplicity⟩ + +theorem multiplicity.Finite.pow_dvd_iff_le_multiplicity (hf : Finite a b) {k : ℕ} : + a ^ k ∣ b ↔ k ≤ multiplicity a b := by + exact_mod_cast hf.emultiplicity_eq_multiplicity ▸ pow_dvd_iff_le_emultiplicity + +theorem emultiplicity_lt_iff_not_dvd {k : ℕ} : + emultiplicity a b < k ↔ ¬a ^ k ∣ b := by rw [pow_dvd_iff_le_emultiplicity, not_le] + +theorem multiplicity.Finite.multiplicity_lt_iff_not_dvd {k : ℕ} (hf : Finite a b) : + multiplicity a b < k ↔ ¬a ^ k ∣ b := by rw [hf.pow_dvd_iff_le_multiplicity, not_le] + +theorem emultiplicity_eq_coe {n : ℕ} : + emultiplicity a b = n ↔ a ^ n ∣ b ∧ ¬a ^ (n + 1) ∣ b := by + constructor + · intro h + constructor + · apply pow_dvd_of_le_emultiplicity + simp [h] + · apply not_pow_dvd_of_emultiplicity_lt + rw [h] + norm_cast + simp + · rw [and_imp] + apply emultiplicity_eq_of_dvd_of_not_dvd -theorem multiplicity_lt_iff_not_dvd {a b : α} {k : ℕ} : - multiplicity a b < (k : PartENat) ↔ ¬a ^ k ∣ b := by rw [pow_dvd_iff_le_multiplicity, not_le] - -theorem eq_coe_iff {a b : α} {n : ℕ} : - multiplicity a b = (n : PartENat) ↔ a ^ n ∣ b ∧ ¬a ^ (n + 1) ∣ b := by - rw [← PartENat.some_eq_natCast] - exact - ⟨fun h => - let ⟨h₁, h₂⟩ := eq_some_iff.1 h - h₂ ▸ ⟨pow_multiplicity_dvd _, is_greatest (by - rw [PartENat.lt_coe_iff] - exact ⟨h₁, lt_succ_self _⟩)⟩, - fun h => eq_some_iff.2 ⟨⟨n, h.2⟩, Eq.symm <| unique' h.1 h.2⟩⟩ - -theorem eq_top_iff {a b : α} : multiplicity a b = ⊤ ↔ ∀ n : ℕ, a ^ n ∣ b := - (PartENat.find_eq_top_iff _).trans <| by - simp only [Classical.not_not] - exact - ⟨fun h n => - Nat.casesOn n - (by - rw [_root_.pow_zero] - exact one_dvd _) - fun n => h _, - fun h n => h _⟩ +theorem multiplicity.Finite.multiplicity_eq_iff (hf : Finite a b) {n : ℕ} : + multiplicity a b = n ↔ a ^ n ∣ b ∧ ¬a ^ (n + 1) ∣ b := by + simp [← emultiplicity_eq_coe, hf.emultiplicity_eq_multiplicity] @[simp] -theorem isUnit_left {a : α} (b : α) (ha : IsUnit a) : multiplicity a b = ⊤ := - eq_top_iff.2 fun _ => IsUnit.dvd (ha.pow _) +theorem multiplicity.Finite.not_of_isUnit_left (b : α) (ha : IsUnit a) : ¬Finite a b := + (·.not_unit ha) --- @[simp] Porting note (#10618): simp can prove this -theorem one_left (b : α) : multiplicity 1 b = ⊤ := - isUnit_left b isUnit_one +theorem multiplicity.Finite.not_of_one_left (b : α) : ¬ Finite 1 b := by simp @[simp] -theorem get_one_right {a : α} (ha : Finite a 1) : get (multiplicity a 1) ha = 0 := by - rw [PartENat.get_eq_iff_eq_coe, eq_coe_iff, _root_.pow_zero] - simp [not_dvd_one_of_finite_one_right ha] - --- @[simp] Porting note (#10618): simp can prove this -theorem unit_left (a : α) (u : αˣ) : multiplicity (u : α) a = ⊤ := - isUnit_left a u.isUnit - -theorem multiplicity_eq_zero {a b : α} : multiplicity a b = 0 ↔ ¬a ∣ b := by - rw [← Nat.cast_zero, eq_coe_iff] - simp only [_root_.pow_zero, isUnit_one, IsUnit.dvd, zero_add, pow_one, true_and] - -theorem multiplicity_ne_zero {a b : α} : multiplicity a b ≠ 0 ↔ a ∣ b := - multiplicity_eq_zero.not_left - -theorem eq_top_iff_not_finite {a b : α} : multiplicity a b = ⊤ ↔ ¬Finite a b := - Part.eq_none_iff' - -theorem ne_top_iff_finite {a b : α} : multiplicity a b ≠ ⊤ ↔ Finite a b := by - rw [Ne, eq_top_iff_not_finite, Classical.not_not] +theorem emultiplicity_one_left (b : α) : emultiplicity 1 b = ⊤ := + emultiplicity_eq_top.2 (Finite.not_of_one_left _) -theorem lt_top_iff_finite {a b : α} : multiplicity a b < ⊤ ↔ Finite a b := by - rw [lt_top_iff_ne_top, ne_top_iff_finite] - -theorem exists_eq_pow_mul_and_not_dvd {a b : α} (hfin : Finite a b) : - ∃ c : α, b = a ^ (multiplicity a b).get hfin * c ∧ ¬a ∣ c := by - obtain ⟨c, hc⟩ := multiplicity.pow_multiplicity_dvd hfin +@[simp] +theorem multiplicity.Finite.one_right (ha : Finite a 1) : multiplicity a 1 = 0 := by + simp [ha.multiplicity_eq_iff, ha.not_dvd_of_one_right] + +theorem multiplicity.Finite.not_of_unit_left (a : α) (u : αˣ) : ¬ Finite (u : α) a := + Finite.not_of_isUnit_left a u.isUnit + +theorem emultiplicity_eq_zero : + emultiplicity a b = 0 ↔ ¬a ∣ b := by + by_cases hf : Finite a b + · rw [← ENat.coe_zero, emultiplicity_eq_coe] + simp + · simpa [emultiplicity_eq_top.2 hf] using Finite.not_iff_forall.1 hf 1 + +theorem multiplicity_eq_zero : + multiplicity a b = 0 ↔ ¬a ∣ b := + (emultiplicity_eq_iff_multiplicity_eq_of_ne_one zero_ne_one).symm.trans emultiplicity_eq_zero + +theorem emultiplicity_ne_zero : + emultiplicity a b ≠ 0 ↔ a ∣ b := by + simp [emultiplicity_eq_zero] + +theorem multiplicity_ne_zero : + multiplicity a b ≠ 0 ↔ a ∣ b := by + simp [multiplicity_eq_zero] + +theorem multiplicity.Finite.exists_eq_pow_mul_and_not_dvd (hfin : Finite a b) : + ∃ c : α, b = a ^ multiplicity a b * c ∧ ¬a ∣ c := by + obtain ⟨c, hc⟩ := pow_multiplicity_dvd a b refine ⟨c, hc, ?_⟩ rintro ⟨k, hk⟩ rw [hk, ← mul_assoc, ← _root_.pow_succ] at hc - have h₁ : a ^ ((multiplicity a b).get hfin + 1) ∣ b := ⟨k, hc⟩ - exact (multiplicity.eq_coe_iff.1 (by simp)).2 h₁ - -theorem multiplicity_le_multiplicity_iff {a b : α} {c d : β} : - multiplicity a b ≤ multiplicity c d ↔ ∀ n : ℕ, a ^ n ∣ b → c ^ n ∣ d := - ⟨fun h _ hab => pow_dvd_of_le_multiplicity (le_trans (le_multiplicity_of_pow_dvd hab) h), fun h => - letI := Classical.dec (Finite a b) - if hab : Finite a b then by - rw [← PartENat.natCast_get (finite_iff_dom.1 hab)] - exact le_multiplicity_of_pow_dvd (h _ (pow_multiplicity_dvd _)) - else by - have : ∀ n : ℕ, c ^ n ∣ d := fun n => h n (not_finite_iff_forall.1 hab _) - rw [eq_top_iff_not_finite.2 hab, eq_top_iff_not_finite.2 (not_finite_iff_forall.2 this)]⟩ - -theorem multiplicity_eq_multiplicity_iff {a b : α} {c d : β} : - multiplicity a b = multiplicity c d ↔ ∀ n : ℕ, a ^ n ∣ b ↔ c ^ n ∣ d := + have h₁ : a ^ (multiplicity a b + 1) ∣ b := ⟨k, hc⟩ + exact (hfin.multiplicity_eq_iff.1 (by simp)).2 h₁ + +theorem emultiplicity_le_emultiplicity_iff {c d : β} : + emultiplicity a b ≤ emultiplicity c d ↔ ∀ n : ℕ, a ^ n ∣ b → c ^ n ∣ d := by classical + constructor + · exact fun h n hab ↦ pow_dvd_of_le_emultiplicity (le_trans (le_emultiplicity_of_pow_dvd hab) h) + · intro h + unfold emultiplicity + -- aesop? says + split + next h_1 => + obtain ⟨w, h_1⟩ := h_1 + split + next h_2 => + simp_all only [cast_le, le_find_iff, lt_find_iff, Decidable.not_not, le_refl, + not_true_eq_false, not_false_eq_true, implies_true] + 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] + +theorem multiplicity.Finite.multiplicity_le_multiplicity_iff {c d : β} (hab : Finite a b) + (hcd : Finite 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] + apply emultiplicity_le_emultiplicity_iff + +theorem emultiplicity_eq_emultiplicity_iff {c d : β} : + emultiplicity a b = emultiplicity c d ↔ ∀ n : ℕ, a ^ n ∣ b ↔ c ^ n ∣ d := ⟨fun h n => - ⟨multiplicity_le_multiplicity_iff.mp h.le n, multiplicity_le_multiplicity_iff.mp h.ge n⟩, - fun h => - le_antisymm (multiplicity_le_multiplicity_iff.mpr fun n => (h n).mp) - (multiplicity_le_multiplicity_iff.mpr fun n => (h n).mpr)⟩ + ⟨emultiplicity_le_emultiplicity_iff.1 h.le n, emultiplicity_le_emultiplicity_iff.1 h.ge n⟩, + fun h => le_antisymm (emultiplicity_le_emultiplicity_iff.2 fun n => (h n).mp) + (emultiplicity_le_emultiplicity_iff.2 fun n => (h n).mpr)⟩ -theorem le_multiplicity_map {F : Type*} [FunLike F α β] [MonoidHomClass F α β] - (f : F) {a b : α} : multiplicity a b ≤ multiplicity (f a) (f b) := - multiplicity_le_multiplicity_iff.mpr fun n ↦ by rw [← map_pow]; exact map_dvd f +theorem le_emultiplicity_map {F : Type*} [FunLike F α β] [MonoidHomClass F α β] + (f : F) {a b : α} : + emultiplicity a b ≤ emultiplicity (f a) (f b) := + emultiplicity_le_emultiplicity_iff.2 fun n ↦ by rw [← map_pow]; exact map_dvd f + +theorem emultiplicity_map_eq {F : Type*} [EquivLike F α β] [MulEquivClass F α β] + (f : F) {a b : α} : emultiplicity (f a) (f b) = emultiplicity a b := by + simp [emultiplicity_eq_emultiplicity_iff, ← map_pow, map_dvd_iff] theorem multiplicity_map_eq {F : Type*} [EquivLike F α β] [MulEquivClass F α β] (f : F) {a b : α} : multiplicity (f a) (f b) = multiplicity a b := - multiplicity_eq_multiplicity_iff.mpr fun n ↦ by rw [← map_pow]; exact map_dvd_iff f + multiplicity_eq_of_emultiplicity_eq (emultiplicity_map_eq f) + +theorem emultiplicity_le_emultiplicity_of_dvd_right {a b c : α} (h : b ∣ c) : + emultiplicity a b ≤ emultiplicity a c := + emultiplicity_le_emultiplicity_iff.2 fun _ hb => hb.trans h -theorem multiplicity_le_multiplicity_of_dvd_right {a b c : α} (h : b ∣ c) : - multiplicity a b ≤ multiplicity a c := - multiplicity_le_multiplicity_iff.2 fun _ hb => hb.trans h +theorem emultiplicity_eq_of_associated_right {a b c : α} (h : Associated b c) : + emultiplicity a b = emultiplicity a c := + le_antisymm (emultiplicity_le_emultiplicity_of_dvd_right h.dvd) + (emultiplicity_le_emultiplicity_of_dvd_right h.symm.dvd) -theorem eq_of_associated_right {a b c : α} (h : Associated b c) : +theorem multiplicity_eq_of_associated_right {a b c : α} (h : Associated b c) : multiplicity a b = multiplicity a c := - le_antisymm (multiplicity_le_multiplicity_of_dvd_right h.dvd) - (multiplicity_le_multiplicity_of_dvd_right h.symm.dvd) - -theorem dvd_of_multiplicity_pos {a b : α} (h : (0 : PartENat) < multiplicity a b) : a ∣ b := by - rw [← pow_one a] - apply pow_dvd_of_le_multiplicity - simpa only [Nat.cast_one, PartENat.pos_iff_one_le] using h - -theorem dvd_iff_multiplicity_pos {a b : α} : (0 : PartENat) < multiplicity a b ↔ a ∣ b := - ⟨dvd_of_multiplicity_pos, fun hdvd => - lt_of_le_of_ne (zero_le _) fun heq => - is_greatest - (show multiplicity a b < ↑1 by - simpa only [heq, Nat.cast_zero] using PartENat.coe_lt_coe.mpr zero_lt_one) - (by rwa [pow_one a])⟩ - -theorem finite_nat_iff {a b : ℕ} : Finite a b ↔ a ≠ 1 ∧ 0 < b := by - rw [← not_iff_not, not_finite_iff_forall, not_and_or, Ne, Classical.not_not, not_lt, + multiplicity_eq_of_emultiplicity_eq (emultiplicity_eq_of_associated_right h) + +theorem dvd_of_emultiplicity_pos {a b : α} (h : 0 < emultiplicity a b) : a ∣ b := + pow_one a ▸ pow_dvd_of_le_emultiplicity (Order.add_one_le_of_lt h) + +theorem dvd_of_multiplicity_pos {a b : α} (h : 0 < multiplicity a b) : a ∣ b := + dvd_of_emultiplicity_pos (lt_emultiplicity_of_lt_multiplicity h) + +theorem dvd_iff_multiplicity_pos {a b : α} : 0 < multiplicity a b ↔ a ∣ b := + ⟨dvd_of_multiplicity_pos, fun hdvd => Nat.pos_of_ne_zero (by simpa [multiplicity_eq_zero])⟩ + +theorem dvd_iff_emultiplicity_pos {a b : α} : 0 < emultiplicity a b ↔ a ∣ b := + emultiplicity_pos_iff.trans dvd_iff_multiplicity_pos + +theorem Nat.multiplicity_finite_iff {a b : ℕ} : Finite a b ↔ a ≠ 1 ∧ 0 < b := by + rw [← not_iff_not, Finite.not_iff_forall, not_and_or, Ne, Classical.not_not, not_lt, Nat.le_zero] exact ⟨fun h => @@ -263,7 +413,7 @@ theorem finite_nat_iff {a b : ℕ} : Finite a b ↔ a ≠ 1 ∧ 0 < b := by not_lt_of_ge (le_of_dvd (Nat.pos_of_ne_zero hb) (h b)) (lt_pow_self ha_gt_one b), fun h => by cases h <;> simp [*]⟩ -alias ⟨_, _root_.has_dvd.dvd.multiplicity_pos⟩ := dvd_iff_multiplicity_pos +alias ⟨_, Dvd.multiplicity_pos⟩ := dvd_iff_multiplicity_pos end Monoid @@ -271,36 +421,45 @@ section CommMonoid variable [CommMonoid α] -theorem finite_of_finite_mul_left {a b c : α} : Finite a (b * c) → Finite a c := by - rw [mul_comm]; exact finite_of_finite_mul_right +theorem multiplicity.Finite.mul_right {a b c : α} (hf : Finite a (b * c)) : Finite a c := + (mul_comm b c ▸ hf).mul_left + +theorem emultiplicity_of_isUnit_right {a b : α} (ha : ¬IsUnit a) + (hb : IsUnit b) : emultiplicity a b = 0 := + emultiplicity_eq_zero.mpr fun h ↦ ha (isUnit_of_dvd_unit h hb) + +theorem multiplicity_of_isUnit_right {a b : α} (ha : ¬IsUnit a) + (hb : IsUnit b) : multiplicity a b = 0 := + multiplicity_eq_zero.mpr fun h ↦ ha (isUnit_of_dvd_unit h hb) -variable [DecidableRel ((· ∣ ·) : α → α → Prop)] +theorem emultiplicity_of_one_right {a : α} (ha : ¬IsUnit a) : emultiplicity a 1 = 0 := + emultiplicity_of_isUnit_right ha isUnit_one -theorem isUnit_right {a b : α} (ha : ¬IsUnit a) (hb : IsUnit b) : multiplicity a b = 0 := - eq_coe_iff.2 - ⟨show a ^ 0 ∣ b by simp only [_root_.pow_zero, one_dvd], by - rw [pow_one] - exact fun h => mt (isUnit_of_dvd_unit h) ha hb⟩ +theorem multiplicity_of_one_right {a : α} (ha : ¬IsUnit a) : multiplicity a 1 = 0 := + multiplicity_of_isUnit_right ha isUnit_one -theorem one_right {a : α} (ha : ¬IsUnit a) : multiplicity a 1 = 0 := - isUnit_right ha isUnit_one +theorem emultiplicity_of_unit_right {a : α} (ha : ¬IsUnit a) (u : αˣ) : emultiplicity a u = 0 := + emultiplicity_of_isUnit_right ha u.isUnit -theorem unit_right {a : α} (ha : ¬IsUnit a) (u : αˣ) : multiplicity a u = 0 := - isUnit_right ha u.isUnit +theorem multiplicity_of_unit_right {a : α} (ha : ¬IsUnit a) (u : αˣ) : multiplicity a u = 0 := + multiplicity_of_isUnit_right ha u.isUnit -open scoped Classical +theorem emultiplicity_le_emultiplicity_of_dvd_left {a b c : α} (hdvd : a ∣ b) : + emultiplicity b c ≤ emultiplicity a c := + emultiplicity_le_emultiplicity_iff.2 fun n h => (pow_dvd_pow_of_dvd hdvd n).trans h -theorem multiplicity_le_multiplicity_of_dvd_left {a b c : α} (hdvd : a ∣ b) : - multiplicity b c ≤ multiplicity a c := - multiplicity_le_multiplicity_iff.2 fun n h => (pow_dvd_pow_of_dvd hdvd n).trans h +theorem emultiplicity_eq_of_associated_left {a b c : α} (h : Associated a b) : + emultiplicity b c = emultiplicity a c := + le_antisymm (emultiplicity_le_emultiplicity_of_dvd_left h.dvd) + (emultiplicity_le_emultiplicity_of_dvd_left h.symm.dvd) -theorem eq_of_associated_left {a b c : α} (h : Associated a b) : +theorem multiplicity_eq_of_associated_left {a b c : α} (h : Associated a b) : multiplicity b c = multiplicity a c := - le_antisymm (multiplicity_le_multiplicity_of_dvd_left h.dvd) - (multiplicity_le_multiplicity_of_dvd_left h.symm.dvd) + multiplicity_eq_of_emultiplicity_eq (emultiplicity_eq_of_associated_left h) --- Porting note: this was doing nothing in mathlib3 also --- alias dvd_iff_multiplicity_pos ↔ _ _root_.has_dvd.dvd.multiplicity_pos +theorem emultiplicity_mk_eq_emultiplicity {a b : α} : + emultiplicity (Associates.mk a) (Associates.mk b) = emultiplicity a b := by + simp [emultiplicity_eq_emultiplicity_iff, ← Associates.mk_pow, Associates.mk_dvd_mk] end CommMonoid @@ -308,111 +467,124 @@ section MonoidWithZero variable [MonoidWithZero α] -theorem ne_zero_of_finite {a b : α} (h : Finite a b) : b ≠ 0 := +theorem multiplicity.Finite.ne_zero {a b : α} (h : Finite a b) : b ≠ 0 := let ⟨n, hn⟩ := h fun hb => by simp [hb] at hn -variable [DecidableRel ((· ∣ ·) : α → α → Prop)] +@[simp] +theorem emultiplicity_zero (a : α) : emultiplicity a 0 = ⊤ := + emultiplicity_eq_top.2 (fun v ↦ v.ne_zero rfl) @[simp] -protected theorem zero (a : α) : multiplicity a 0 = ⊤ := - Part.eq_none_iff.2 fun _ ⟨⟨_, hk⟩, _⟩ => hk (dvd_zero _) +theorem emultiplicity_zero_eq_zero_of_ne_zero (a : α) (ha : a ≠ 0) : emultiplicity 0 a = 0 := + emultiplicity_eq_zero.2 <| mt zero_dvd_iff.1 ha @[simp] theorem multiplicity_zero_eq_zero_of_ne_zero (a : α) (ha : a ≠ 0) : multiplicity 0 a = 0 := - multiplicity.multiplicity_eq_zero.2 <| mt zero_dvd_iff.1 ha + multiplicity_eq_zero.2 <| mt zero_dvd_iff.1 ha end MonoidWithZero -section CommMonoidWithZero - -variable [CommMonoidWithZero α] -variable [DecidableRel ((· ∣ ·) : α → α → Prop)] - -theorem multiplicity_mk_eq_multiplicity - [DecidableRel ((· ∣ ·) : Associates α → Associates α → Prop)] {a b : α} : - multiplicity (Associates.mk a) (Associates.mk b) = multiplicity a b := by - by_cases h : Finite a b - · rw [← PartENat.natCast_get (finite_iff_dom.mp h)] - refine - (multiplicity.unique - (show Associates.mk a ^ (multiplicity a b).get h ∣ Associates.mk b from ?_) ?_).symm <;> - rw [← Associates.mk_pow, Associates.mk_dvd_mk] - · exact pow_multiplicity_dvd h - · exact is_greatest - ((PartENat.lt_coe_iff _ _).mpr (Exists.intro (finite_iff_dom.mp h) (Nat.lt_succ_self _))) - · suffices ¬Finite (Associates.mk a) (Associates.mk b) by - rw [finite_iff_dom, PartENat.not_dom_iff_eq_top] at h this - rw [h, this] - refine - not_finite_iff_forall.mpr fun n => by - rw [← Associates.mk_pow, Associates.mk_dvd_mk] - exact not_finite_iff_forall.mp h n - -end CommMonoidWithZero - section Semiring -variable [Semiring α] [DecidableRel ((· ∣ ·) : α → α → Prop)] +variable [Semiring α] -theorem min_le_multiplicity_add {p a b : α} : - min (multiplicity p a) (multiplicity p b) ≤ multiplicity p (a + b) := - (le_total (multiplicity p a) (multiplicity p b)).elim - (fun h ↦ by - rw [min_eq_left h, multiplicity_le_multiplicity_iff] - exact fun n hn => dvd_add hn (multiplicity_le_multiplicity_iff.1 h n hn)) - fun h ↦ by - rw [min_eq_right h, multiplicity_le_multiplicity_iff] - exact fun n hn => dvd_add (multiplicity_le_multiplicity_iff.1 h n hn) hn +theorem multiplicity.Finite.or_of_add {p a b : α} (hf : Finite p (a + b)) : + Finite p a ∨ Finite p b := by + by_contra! nh + obtain ⟨c, hc⟩ := hf + simp_all [dvd_add] + +theorem min_le_emultiplicity_add {p a b : α} : + min (emultiplicity p a) (emultiplicity p b) ≤ emultiplicity p (a + b) := by + cases hm : min (emultiplicity p a) (emultiplicity p b) + · simp only [top_le_iff, min_eq_top, emultiplicity_eq_top] at hm ⊢ + contrapose hm + simp only [not_and_or, not_not] at hm ⊢ + exact hm.or_of_add + · apply le_emultiplicity_of_pow_dvd + simp [dvd_add, pow_dvd_of_le_emultiplicity, ← hm] end Semiring section Ring -variable [Ring α] [DecidableRel ((· ∣ ·) : α → α → Prop)] +variable [Ring α] @[simp] -protected theorem neg (a b : α) : multiplicity a (-b) = multiplicity a b := - Part.ext' (by simp only [multiplicity, PartENat.find, dvd_neg]) fun h₁ h₂ => - PartENat.natCast_inj.1 (by - rw [PartENat.natCast_get] - exact Eq.symm - (unique (pow_multiplicity_dvd _).neg_right - (mt dvd_neg.1 (is_greatest' _ (lt_succ_self _))))) - -theorem Int.natAbs (a : ℕ) (b : ℤ) : multiplicity a b.natAbs = multiplicity (a : ℤ) b := by - cases' Int.natAbs_eq b with h h <;> conv_rhs => rw [h] - · rw [Int.natCast_multiplicity] - · rw [multiplicity.neg, Int.natCast_multiplicity] - -theorem multiplicity_add_of_gt {p a b : α} (h : multiplicity p b < multiplicity p a) : - multiplicity p (a + b) = multiplicity p b := by - apply le_antisymm - · apply PartENat.le_of_lt_add_one - cases' PartENat.ne_top_iff.mp (PartENat.ne_top_of_lt h) with k hk - rw [hk] - rw_mod_cast [multiplicity_lt_iff_not_dvd, dvd_add_right] - · intro h_dvd - apply multiplicity.is_greatest _ h_dvd - rw [hk, ← Nat.succ_eq_add_one] - norm_cast - apply Nat.lt_succ_self k - · rw [pow_dvd_iff_le_multiplicity, Nat.cast_add, ← hk, Nat.cast_one] - exact PartENat.add_one_le_of_lt h - · have := @min_le_multiplicity_add α _ _ p a b - rwa [← min_eq_right (le_of_lt h)] +theorem multiplicity.Finite.neg_iff {a b : α} : Finite a (-b) ↔ Finite a b := by + unfold Finite + congr! 3 + simp only [dvd_neg] -theorem multiplicity_sub_of_gt {p a b : α} (h : multiplicity p b < multiplicity p a) : - multiplicity p (a - b) = multiplicity p b := by - rw [sub_eq_add_neg, multiplicity_add_of_gt] <;> rw [multiplicity.neg]; assumption +alias ⟨_, multiplicity.Finite.neg⟩ := Finite.neg_iff -theorem multiplicity_add_eq_min {p a b : α} (h : multiplicity p a ≠ multiplicity p b) : +@[simp] +theorem emultiplicity_neg (a b : α) : emultiplicity a (-b) = emultiplicity a b := by + rw [emultiplicity_eq_emultiplicity_iff] + simp + +@[simp] +theorem multiplicity_neg (a b : α) : multiplicity a (-b) = multiplicity a b := + multiplicity_eq_of_emultiplicity_eq (emultiplicity_neg a b) + +theorem Int.emultiplicity_natAbs (a : ℕ) (b : ℤ) : + emultiplicity a b.natAbs = emultiplicity (a : ℤ) b := by + cases' Int.natAbs_eq b with h h <;> conv_rhs => rw [h] + · rw [Int.natCast_emultiplicity] + · rw [emultiplicity_neg, Int.natCast_emultiplicity] + +theorem Int.multiplicity_natAbs (a : ℕ) (b : ℤ) : + multiplicity a b.natAbs = multiplicity (a : ℤ) b := + multiplicity_eq_of_emultiplicity_eq (Int.emultiplicity_natAbs a b) + +theorem emultiplicity_add_of_gt {p a b : α} (h : emultiplicity p b < emultiplicity p a) : + emultiplicity p (a + b) = emultiplicity p b := by + have : Finite p b := finite_iff_emultiplicity_ne_top.2 (by simp [·] at h) + rw [this.emultiplicity_eq_multiplicity] at * + apply emultiplicity_eq_of_dvd_of_not_dvd + · apply dvd_add + · apply pow_dvd_of_le_emultiplicity + exact h.le + · simp + · rw [dvd_add_right] + · apply this.not_pow_dvd_of_multiplicity_lt + simp + apply pow_dvd_of_le_emultiplicity + exact Order.add_one_le_of_lt h + +theorem multiplicity.Finite.multiplicity_add_of_gt {p a b : α} (hf : Finite p b) + (h : multiplicity p b < multiplicity p a) : + multiplicity p (a + b) = multiplicity p b := + multiplicity_eq_of_emultiplicity_eq <| emultiplicity_add_of_gt (hf.emultiplicity_eq_multiplicity ▸ + (WithTop.coe_strictMono h).trans_le multiplicity_le_emultiplicity) + +theorem emultiplicity_sub_of_gt {p a b : α} (h : emultiplicity p b < emultiplicity p a) : + emultiplicity p (a - b) = emultiplicity p b := by + rw [sub_eq_add_neg, emultiplicity_add_of_gt] <;> rw [emultiplicity_neg]; assumption + +theorem multiplicity_sub_of_gt {p a b : α} (h : multiplicity p b < multiplicity p a) + (hfin : Finite p b) : multiplicity p (a - b) = multiplicity p b := by + rw [sub_eq_add_neg, hfin.neg.multiplicity_add_of_gt] <;> rw [multiplicity_neg]; assumption + +theorem emultiplicity_add_eq_min {p a b : α} + (h : emultiplicity p a ≠ emultiplicity p b) : + emultiplicity p (a + b) = min (emultiplicity p a) (emultiplicity p b) := by + rcases lt_trichotomy (emultiplicity p a) (emultiplicity p b) with (hab | _ | hab) + · rw [add_comm, emultiplicity_add_of_gt hab, min_eq_left] + exact le_of_lt hab + · contradiction + · rw [emultiplicity_add_of_gt hab, min_eq_right] + exact le_of_lt hab + +theorem multiplicity_add_eq_min {p a b : α} (ha : Finite p a) (hb : Finite p b) + (h : multiplicity p a ≠ multiplicity p b) : multiplicity p (a + b) = min (multiplicity p a) (multiplicity p b) := by - rcases lt_trichotomy (multiplicity p a) (multiplicity p b) with (hab | hab | hab) - · rw [add_comm, multiplicity_add_of_gt hab, min_eq_left] + rcases lt_trichotomy (multiplicity p a) (multiplicity p b) with (hab | _ | hab) + · rw [add_comm, ha.multiplicity_add_of_gt hab, min_eq_left] exact le_of_lt hab · contradiction - · rw [multiplicity_add_of_gt hab, min_eq_right] + · rw [hb.multiplicity_add_of_gt hab, min_eq_right] exact le_of_lt hab end Ring @@ -423,7 +595,7 @@ variable [CancelCommMonoidWithZero α] /- Porting note: Pulled a b intro parameters since Lean parses that more easily -/ -theorem finite_mul_aux {p : α} (hp : Prime p) {a b : α} : +theorem multiplicity.finite_mul_aux {p : α} (hp : Prime p) {a b : α} : ∀ {n m : ℕ}, ¬p ^ (n + 1) ∣ a → ¬p ^ (m + 1) ∣ b → ¬p ^ (n + m + 1) ∣ a * b | n, m => fun ha hb ⟨s, hs⟩ => have : p ∣ a * b := ⟨p ^ (n + m) * s, by simp [hs, pow_add, mul_comm, mul_assoc, mul_left_comm]⟩ @@ -455,102 +627,97 @@ theorem finite_mul_aux {p : α} (hp : Prime p) {a b : α} : rw [add_assoc, tsub_add_cancel_of_le (succ_le_of_lt hm0)] simp_all [mul_comm, mul_assoc, mul_left_comm, pow_add])⟩ -theorem finite_mul {p a b : α} (hp : Prime p) : Finite p a → Finite p b → Finite p (a * b) := +theorem Prime.multiplicity_finite_mul {p a b : α} (hp : Prime p) : + Finite p a → Finite p b → Finite p (a * b) := fun ⟨n, hn⟩ ⟨m, hm⟩ => ⟨n + m, finite_mul_aux hp hn hm⟩ -theorem finite_mul_iff {p a b : α} (hp : Prime p) : Finite p (a * b) ↔ Finite p a ∧ Finite p b := - ⟨fun h => ⟨finite_of_finite_mul_right h, finite_of_finite_mul_left h⟩, fun h => - finite_mul hp h.1 h.2⟩ +theorem multiplicity.Finite.mul_iff {p a b : α} (hp : Prime p) : + Finite p (a * b) ↔ Finite p a ∧ Finite p b := + ⟨fun h => ⟨h.mul_left, h.mul_right⟩, fun h => + hp.multiplicity_finite_mul h.1 h.2⟩ -theorem finite_pow {p a : α} (hp : Prime p) : ∀ {k : ℕ} (_ : Finite p a), Finite p (a ^ k) +theorem multiplicity.Finite.pow {p a : α} (hp : Prime p) + (hfin : Finite p a) {k : ℕ} : Finite p (a ^ k) := + match k, hfin with | 0, _ => ⟨0, by simp [mt isUnit_iff_dvd_one.2 hp.2.1]⟩ - | k + 1, ha => by rw [_root_.pow_succ']; exact finite_mul hp ha (finite_pow hp ha) - -variable [DecidableRel ((· ∣ ·) : α → α → Prop)] + | k + 1, ha => by rw [_root_.pow_succ']; exact hp.multiplicity_finite_mul ha (ha.pow hp) @[simp] -theorem multiplicity_self {a : α} (ha : ¬IsUnit a) (ha0 : a ≠ 0) : multiplicity a a = 1 := by - rw [← Nat.cast_one] - exact eq_coe_iff.2 ⟨by simp, fun ⟨b, hb⟩ => ha (isUnit_iff_dvd_one.2 - ⟨b, mul_left_cancel₀ ha0 <| by simpa [_root_.pow_succ, mul_assoc] using hb⟩)⟩ +theorem multiplicity_self {a : α} : multiplicity a a = 1 := by + by_cases ha : Finite a a + · rw [ha.multiplicity_eq_iff] + simp only [pow_one, dvd_refl, reduceAdd, true_and] + rintro ⟨v, hv⟩ + nth_rw 1 [← mul_one a] at hv + simp only [sq, mul_assoc, mul_eq_mul_left_iff] at hv + obtain hv | rfl := hv + · have : IsUnit a := isUnit_of_mul_eq_one a v hv.symm + simpa [this] using ha.not_unit + · simpa using ha.ne_zero + · simp [ha] @[simp] -theorem get_multiplicity_self {a : α} (ha : Finite a a) : get (multiplicity a a) ha = 1 := - PartENat.get_eq_iff_eq_coe.2 - (eq_coe_iff.2 - ⟨by simp, fun ⟨b, hb⟩ => by - rw [← mul_one a, pow_add, pow_one, mul_assoc, mul_assoc, - mul_right_inj' (ne_zero_of_finite ha)] at hb - exact mt isUnit_iff_dvd_one.2 (not_unit_of_finite ha) ⟨b, by simp_all⟩⟩) - -protected theorem mul' {p a b : α} (hp : Prime p) (h : (multiplicity p (a * b)).Dom) : - get (multiplicity p (a * b)) h = - get (multiplicity p a) ((finite_mul_iff hp).1 h).1 + - get (multiplicity p b) ((finite_mul_iff hp).1 h).2 := by - have hdiva : p ^ get (multiplicity p a) ((finite_mul_iff hp).1 h).1 ∣ a := pow_multiplicity_dvd _ - have hdivb : p ^ get (multiplicity p b) ((finite_mul_iff hp).1 h).2 ∣ b := pow_multiplicity_dvd _ - have hpoweq : - p ^ (get (multiplicity p a) ((finite_mul_iff hp).1 h).1 + - get (multiplicity p b) ((finite_mul_iff hp).1 h).2) = - p ^ get (multiplicity p a) ((finite_mul_iff hp).1 h).1 * - p ^ get (multiplicity p b) ((finite_mul_iff hp).1 h).2 := by - simp [pow_add] - have hdiv : - p ^ (get (multiplicity p a) ((finite_mul_iff hp).1 h).1 + - get (multiplicity p b) ((finite_mul_iff hp).1 h).2) ∣ - a * b := by - rw [hpoweq]; apply mul_dvd_mul <;> assumption - have hsucc : - ¬p ^ (get (multiplicity p a) ((finite_mul_iff hp).1 h).1 + - get (multiplicity p b) ((finite_mul_iff hp).1 h).2 + - 1) ∣ - a * b := +theorem multiplicity.Finite.emultiplicity_self {a : α} (hfin : Finite a a) : + emultiplicity a a = 1 := by + simp [hfin.emultiplicity_eq_multiplicity] + +theorem multiplicity_mul {p a b : α} (hp : Prime p) (hfin : Finite p (a * b)) : + multiplicity p (a * b) = multiplicity p a + multiplicity p b := by + have hdiva : p ^ multiplicity p a ∣ a := pow_multiplicity_dvd .. + have hdivb : p ^ multiplicity p b ∣ b := pow_multiplicity_dvd .. + have hdiv : p ^ (multiplicity p a + multiplicity p b) ∣ a * b := by + rw [pow_add]; apply mul_dvd_mul <;> assumption + have hsucc : ¬p ^ (multiplicity p a + multiplicity p b + 1) ∣ a * b := fun h => - not_or_intro (is_greatest' _ (lt_succ_self _)) (is_greatest' _ (lt_succ_self _)) + not_or_intro (hfin.mul_left.not_pow_dvd_of_multiplicity_lt (lt_succ_self _)) + (hfin.mul_right.not_pow_dvd_of_multiplicity_lt (lt_succ_self _)) (_root_.succ_dvd_or_succ_dvd_of_succ_sum_dvd_mul hp hdiva hdivb h) - rw [← PartENat.natCast_inj, PartENat.natCast_get, eq_coe_iff]; exact ⟨hdiv, hsucc⟩ - -open scoped Classical - -protected theorem mul {p a b : α} (hp : Prime p) : - multiplicity p (a * b) = multiplicity p a + multiplicity p b := - if h : Finite p a ∧ Finite p b then by - rw [← PartENat.natCast_get (finite_iff_dom.1 h.1), ← - PartENat.natCast_get (finite_iff_dom.1 h.2), ← - PartENat.natCast_get (finite_iff_dom.1 (finite_mul hp h.1 h.2)), ← Nat.cast_add, - PartENat.natCast_inj, multiplicity.mul' hp] - else by - rw [eq_top_iff_not_finite.2 (mt (finite_mul_iff hp).1 h)] - cases' not_and_or.1 h with h h <;> simp [eq_top_iff_not_finite.2 h] - -theorem Finset.prod {β : Type*} {p : α} (hp : Prime p) (s : Finset β) (f : β → α) : - multiplicity p (∏ x ∈ s, f x) = ∑ x ∈ s, multiplicity p (f x) := by - classical + rw [hfin.multiplicity_eq_iff] + exact ⟨hdiv, hsucc⟩ + +theorem emultiplicity_mul {p a b : α} (hp : Prime p) : + emultiplicity p (a * b) = emultiplicity p a + emultiplicity p b := by + by_cases hfin : Finite p (a * b) + · rw [hfin.emultiplicity_eq_multiplicity, hfin.mul_left.emultiplicity_eq_multiplicity, + 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, + emultiplicity_eq_top] + simpa only [Finite.mul_iff hp, not_and_or] using hfin + +theorem Finset.emultiplicity_prod {β : Type*} {p : α} (hp : Prime p) (s : Finset β) (f : β → α) : + emultiplicity p (∏ x ∈ s, f x) = ∑ x ∈ s, emultiplicity p (f x) := by classical induction' s using Finset.induction with a s has ih h · simp only [Finset.sum_empty, Finset.prod_empty] - convert one_right hp.not_unit - · simpa [has, ← ih] using multiplicity.mul hp + exact emultiplicity_of_one_right hp.not_unit + · simpa [has, ← ih] using emultiplicity_mul hp --- Porting note: with protected could not use pow' k in the succ branch -protected theorem pow' {p a : α} (hp : Prime p) (ha : Finite p a) : - ∀ {k : ℕ}, get (multiplicity p (a ^ k)) (finite_pow hp ha) = k * get (multiplicity p a) ha := by - intro k +theorem emultiplicity_pow {p a : α} (hp : Prime p) {k : ℕ} : + emultiplicity p (a ^ k) = k * emultiplicity p a := by induction' k with k hk - · simp [one_right hp.not_unit] - · have : multiplicity p (a ^ (k + 1)) = multiplicity p (a * a ^ k) := by rw [_root_.pow_succ'] - rw [get_eq_get_of_eq _ _ this, - multiplicity.mul' hp, hk, add_mul, one_mul, add_comm] + · simp [emultiplicity_of_one_right hp.not_unit] + · simp [pow_succ, emultiplicity_mul hp, hk, add_mul] -theorem pow {p a : α} (hp : Prime p) : ∀ {k : ℕ}, multiplicity p (a ^ k) = k • multiplicity p a - | 0 => by simp [one_right hp.not_unit] - | succ k => by simp [_root_.pow_succ, succ_nsmul, pow hp, multiplicity.mul hp] +protected theorem multiplicity.Finite.multiplicity_pow {p a : α} (hp : Prime p) + (ha : Finite p a) {k : ℕ} : multiplicity p (a ^ k) = k * multiplicity p a := by + exact_mod_cast (ha.pow hp).emultiplicity_eq_multiplicity ▸ + ha.emultiplicity_eq_multiplicity ▸ emultiplicity_pow hp + +theorem emultiplicity_pow_self {p : α} (h0 : p ≠ 0) (hu : ¬IsUnit p) (n : ℕ) : + emultiplicity p (p ^ n) = n := by + apply emultiplicity_eq_of_dvd_of_not_dvd + · rfl + · rw [pow_dvd_pow_iff h0 hu] + apply Nat.not_succ_le_self theorem multiplicity_pow_self {p : α} (h0 : p ≠ 0) (hu : ¬IsUnit p) (n : ℕ) : - multiplicity p (p ^ n) = n := by - rw [eq_coe_iff] - use dvd_rfl - rw [pow_dvd_pow_iff h0 hu] - apply Nat.not_succ_le_self + multiplicity p (p ^ n) = n := + multiplicity_eq_of_emultiplicity_eq_some (emultiplicity_pow_self h0 hu 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 theorem multiplicity_pow_self_of_prime {p : α} (hp : Prime p) (n : ℕ) : multiplicity p (p ^ n) = n := @@ -558,36 +725,32 @@ theorem multiplicity_pow_self_of_prime {p : α} (hp : Prime p) (n : ℕ) : end CancelCommMonoidWithZero -end multiplicity - section Nat open multiplicity theorem multiplicity_eq_zero_of_coprime {p a b : ℕ} (hp : p ≠ 1) (hle : multiplicity p a ≤ multiplicity p b) (hab : Nat.Coprime a b) : multiplicity p a = 0 := by - rw [multiplicity_le_multiplicity_iff] at hle - rw [← nonpos_iff_eq_zero, ← not_lt, PartENat.pos_iff_one_le, ← Nat.cast_one, ← - pow_dvd_iff_le_multiplicity] - intro h - have := Nat.dvd_gcd h (hle _ h) - rw [Coprime.gcd_eq_one hab, Nat.dvd_one, pow_one] at this + apply Nat.eq_zero_of_not_pos + intro nh + have da : p ∣ a := by simpa [multiplicity_eq_zero] using nh.ne.symm + have db : p ∣ b := by simpa [multiplicity_eq_zero] using (nh.trans_le hle).ne.symm + have := Nat.dvd_gcd da db + rw [Coprime.gcd_eq_one hab, Nat.dvd_one] at this exact hp this end Nat -namespace multiplicity - -theorem finite_int_iff_natAbs_finite {a b : ℤ} : Finite a b ↔ Finite a.natAbs b.natAbs := by - simp only [finite_def, ← Int.natAbs_dvd_natAbs, Int.natAbs_pow] - -theorem finite_int_iff {a b : ℤ} : Finite a b ↔ a.natAbs ≠ 1 ∧ b ≠ 0 := by - rw [finite_int_iff_natAbs_finite, finite_nat_iff, pos_iff_ne_zero, Int.natAbs_ne_zero] +theorem Int.multiplicity_finite_iff_natAbs_finite {a b : ℤ} : + Finite a b ↔ Finite a.natAbs b.natAbs := by + simp only [Finite.def, ← Int.natAbs_dvd_natAbs, Int.natAbs_pow] -instance decidableNat : DecidableRel fun a b : ℕ => (multiplicity a b).Dom := fun _ _ => - decidable_of_iff _ finite_nat_iff.symm +theorem Int.multiplicity_finite_iff {a b : ℤ} : Finite a b ↔ a.natAbs ≠ 1 ∧ b ≠ 0 := by + rw [multiplicity_finite_iff_natAbs_finite, Nat.multiplicity_finite_iff, + pos_iff_ne_zero, Int.natAbs_ne_zero] -instance decidableInt : DecidableRel fun a b : ℤ => (multiplicity a b).Dom := fun _ _ => - decidable_of_iff _ finite_int_iff.symm +instance Nat.decidableMultiplicityFinite : DecidableRel fun a b : ℕ => Finite a b := fun _ _ => + decidable_of_iff' _ Nat.multiplicity_finite_iff -end multiplicity +instance Int.decidableMultiplicityFinite : DecidableRel fun a b : ℤ => Finite a b := fun _ _ => + decidable_of_iff' _ Int.multiplicity_finite_iff diff --git a/Mathlib/RingTheory/PowerSeries/Inverse.lean b/Mathlib/RingTheory/PowerSeries/Inverse.lean index b08f4125a38a02..aec805253fd3db 100644 --- a/Mathlib/RingTheory/PowerSeries/Inverse.lean +++ b/Mathlib/RingTheory/PowerSeries/Inverse.lean @@ -352,10 +352,10 @@ theorem normalized_count_X_eq_of_coe {P : k[X]} (hP : P ≠ 0) : Multiset.count PowerSeries.X (normalizedFactors (P : k⟦X⟧)) = Multiset.count Polynomial.X (normalizedFactors P) := by apply eq_of_forall_le_iff - simp only [← PartENat.coe_le_coe] - rw [X_eq_normalize, PowerSeries.X_eq_normalizeX, ← multiplicity_eq_count_normalizedFactors - irreducible_X hP, ← multiplicity_eq_count_normalizedFactors X_irreducible] <;> - simp only [← multiplicity.pow_dvd_iff_le_multiplicity, Polynomial.X_pow_dvd_iff, + simp only [← Nat.cast_le (α := ℕ∞)] + rw [X_eq_normalize, PowerSeries.X_eq_normalizeX, ← emultiplicity_eq_count_normalizedFactors + irreducible_X hP, ← emultiplicity_eq_count_normalizedFactors X_irreducible] <;> + simp only [← pow_dvd_iff_le_emultiplicity, Polynomial.X_pow_dvd_iff, PowerSeries.X_pow_dvd_iff, Polynomial.coeff_coe P, implies_true, ne_eq, coe_eq_zero_iff, hP, not_false_eq_true] diff --git a/Mathlib/RingTheory/PowerSeries/Order.lean b/Mathlib/RingTheory/PowerSeries/Order.lean index cec9d16a7d726b..ab2aa878e65852 100644 --- a/Mathlib/RingTheory/PowerSeries/Order.lean +++ b/Mathlib/RingTheory/PowerSeries/Order.lean @@ -7,6 +7,7 @@ Authors: Johan Commelin, Kenny Lau import Mathlib.Algebra.CharP.Defs import Mathlib.RingTheory.Multiplicity import Mathlib.RingTheory.PowerSeries.Basic +import Mathlib.Data.Nat.PartENat /-! # Formal power series (in one variable) - Order @@ -249,27 +250,30 @@ theorem X_pow_order_dvd (h : (order φ).Dom) : X ^ (order φ).get h ∣ φ := by refine coeff_of_lt_order _ ?_ simpa [PartENat.coe_lt_iff] using fun _ => hn -theorem order_eq_multiplicity_X {R : Type*} [Semiring R] [@DecidableRel R⟦X⟧ (· ∣ ·)] (φ : R⟦X⟧) : - order φ = multiplicity X φ := by +theorem order_eq_emultiplicity_X {R : Type*} [Semiring R] (φ : R⟦X⟧) : + order φ = emultiplicity X φ := by classical rcases eq_or_ne φ 0 with (rfl | hφ) · simp induction' ho : order φ using PartENat.casesOn with n · simp [hφ] at ho have hn : φ.order.get (order_finite_iff_ne_zero.mpr hφ) = n := by simp [ho] - rw [← hn] - refine - le_antisymm (le_multiplicity_of_pow_dvd <| X_pow_order_dvd (order_finite_iff_ne_zero.mpr hφ)) - (PartENat.find_le _ _ ?_) - rintro ⟨ψ, H⟩ - have := congr_arg (coeff R n) H - rw [← (ψ.commute_X.pow_right _).eq, coeff_mul_of_lt_order, ← hn] at this - · exact coeff_order _ this - · rw [X_pow_eq, order_monomial] - split_ifs - · exact PartENat.natCast_lt_top _ - · rw [← hn, PartENat.coe_lt_coe] - exact Nat.lt_succ_self _ + rw [← hn, ← PartENat.ofENat_coe, eq_comm] + congr 1 + apply le_antisymm _ + · apply le_emultiplicity_of_pow_dvd + apply X_pow_order_dvd + · apply Order.le_of_lt_add_one + rw [← not_le, ← Nat.cast_one, ← Nat.cast_add, ← pow_dvd_iff_le_emultiplicity] + rintro ⟨ψ, H⟩ + have := congr_arg (coeff R n) H + rw [← (ψ.commute_X.pow_right _).eq, coeff_mul_of_lt_order, ← hn] at this + · exact coeff_order _ this + · rw [X_pow_eq, order_monomial] + split_ifs + · exact PartENat.natCast_lt_top _ + · rw [← hn, PartENat.coe_lt_coe] + exact Nat.lt_succ_self _ /-- Given a non-zero power series `f`, `divided_by_X_pow_order f` is the power series obtained by dividing out the largest power of X that divides `f`, that is its order -/ @@ -321,8 +325,12 @@ variable [CommRing R] [IsDomain R] is the sum of their orders. -/ theorem order_mul (φ ψ : R⟦X⟧) : order (φ * ψ) = order φ + order ψ := by classical - simp_rw [order_eq_multiplicity_X] - exact multiplicity.mul X_prime + simp_rw [order_eq_emultiplicity_X] + change PartENat.withTopAddEquiv.symm _ = + PartENat.withTopAddEquiv.symm _ + PartENat.withTopAddEquiv.symm _ + rw [← map_add] + congr 1 + exact emultiplicity_mul X_prime -- Dividing `X` by the maximal power of `X` dividing it leaves `1`. @[simp] diff --git a/Mathlib/RingTheory/RootsOfUnity/Basic.lean b/Mathlib/RingTheory/RootsOfUnity/Basic.lean index fbfd625bc62c1d..a0b4d08c4b85dd 100644 --- a/Mathlib/RingTheory/RootsOfUnity/Basic.lean +++ b/Mathlib/RingTheory/RootsOfUnity/Basic.lean @@ -583,10 +583,10 @@ theorem primitiveRoots_one : primitiveRoots 1 R = {(1 : R)} := by theorem neZero' {n : ℕ+} (hζ : IsPrimitiveRoot ζ n) : NeZero ((n : ℕ) : R) := by let p := ringChar R - have hfin := multiplicity.finite_nat_iff.2 ⟨CharP.char_ne_one R p, n.pos⟩ - obtain ⟨m, hm⟩ := multiplicity.exists_eq_pow_mul_and_not_dvd hfin + have hfin := Nat.multiplicity_finite_iff.2 ⟨CharP.char_ne_one R p, n.pos⟩ + obtain ⟨m, hm⟩ := hfin.exists_eq_pow_mul_and_not_dvd by_cases hp : p ∣ n - · obtain ⟨k, hk⟩ := Nat.exists_eq_succ_of_ne_zero (multiplicity.pos_of_dvd hfin hp).ne' + · obtain ⟨k, hk⟩ := Nat.exists_eq_succ_of_ne_zero (multiplicity_pos_of_dvd hp).ne' haveI : NeZero p := NeZero.of_pos (Nat.pos_of_dvd_of_pos hp n.pos) haveI hpri : Fact p.Prime := CharP.char_is_prime_of_pos R p have := hζ.pow_eq_one diff --git a/Mathlib/RingTheory/RootsOfUnity/Minpoly.lean b/Mathlib/RingTheory/RootsOfUnity/Minpoly.lean index fddcf3946281c9..fb0735bdeb50be 100644 --- a/Mathlib/RingTheory/RootsOfUnity/Minpoly.lean +++ b/Mathlib/RingTheory/RootsOfUnity/Minpoly.lean @@ -143,13 +143,13 @@ theorem minpoly_eq_pow {p : ℕ} [hprime : Fact p.Prime] (hdiv : ¬p ∣ n) : have habs : map (Int.castRingHom (ZMod p)) P ^ 2 ∣ map (Int.castRingHom (ZMod p)) P ^ 2 * R := by use R replace habs := - lt_of_lt_of_le (PartENat.coe_lt_coe.2 one_lt_two) - (multiplicity.le_multiplicity_of_pow_dvd (dvd_trans habs prod)) + lt_of_lt_of_le (Nat.cast_lt.2 one_lt_two) + (le_emultiplicity_of_pow_dvd (dvd_trans habs prod)) have hfree : Squarefree (X ^ n - 1 : (ZMod p)[X]) := (separable_X_pow_sub_C 1 (fun h => hdiv <| (ZMod.natCast_zmod_eq_zero_iff_dvd n p).1 h) one_ne_zero).squarefree cases' - (multiplicity.squarefree_iff_multiplicity_le_one (X ^ n - 1)).1 hfree + (multiplicity.squarefree_iff_emultiplicity_le_one (X ^ n - 1)).1 hfree (map (Int.castRingHom (ZMod p)) P) with hle hunit · rw [Nat.cast_one] at habs; exact hle.not_lt habs diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain.lean b/Mathlib/RingTheory/UniqueFactorizationDomain.lean index a439e8e8833c89..e144f86f1433b6 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain.lean @@ -923,15 +923,14 @@ section multiplicity variable [NormalizationMonoid R] -open multiplicity Multiset +open Multiset section -variable [DecidableRel (Dvd.dvd : R → R → Prop)] -theorem le_multiplicity_iff_replicate_le_normalizedFactors {a b : R} {n : ℕ} (ha : Irreducible a) +theorem le_emultiplicity_iff_replicate_le_normalizedFactors {a b : R} {n : ℕ} (ha : Irreducible a) (hb : b ≠ 0) : - ↑n ≤ multiplicity a b ↔ replicate n (normalize a) ≤ normalizedFactors b := by - rw [← pow_dvd_iff_le_multiplicity] + ↑n ≤ emultiplicity a b ↔ replicate n (normalize a) ≤ normalizedFactors b := by + rw [← pow_dvd_iff_le_emultiplicity] revert b induction' n with n ih; · simp intro b hb @@ -952,14 +951,14 @@ the normalized factor occurs in the `normalizedFactors`. See also `count_normalizedFactors_eq` which expands the definition of `multiplicity` to produce a specification for `count (normalizedFactors _) _`.. -/ -theorem multiplicity_eq_count_normalizedFactors [DecidableEq R] {a b : R} (ha : Irreducible a) - (hb : b ≠ 0) : multiplicity a b = (normalizedFactors b).count (normalize a) := by +theorem emultiplicity_eq_count_normalizedFactors [DecidableEq R] {a b : R} (ha : Irreducible a) + (hb : b ≠ 0) : emultiplicity a b = (normalizedFactors b).count (normalize a) := by apply le_antisymm - · apply PartENat.le_of_lt_add_one + · apply Order.le_of_lt_add_one rw [← Nat.cast_one, ← Nat.cast_add, lt_iff_not_ge, ge_iff_le, - le_multiplicity_iff_replicate_le_normalizedFactors ha hb, ← le_count_iff_replicate_le] + le_emultiplicity_iff_replicate_le_normalizedFactors ha hb, ← le_count_iff_replicate_le] simp - rw [le_multiplicity_iff_replicate_le_normalizedFactors ha hb, ← le_count_iff_replicate_le] + rw [le_emultiplicity_iff_replicate_le_normalizedFactors ha hb, ← le_count_iff_replicate_le] end @@ -970,14 +969,13 @@ See also `multiplicity_eq_count_normalizedFactors` if `n` is given by `multiplic -/ theorem count_normalizedFactors_eq [DecidableEq R] {p x : R} (hp : Irreducible p) (hnorm : normalize p = p) {n : ℕ} (hle : p ^ n ∣ x) (hlt : ¬p ^ (n + 1) ∣ x) : - (normalizedFactors x).count p = n := by - letI : DecidableRel ((· ∣ ·) : R → R → Prop) := fun _ _ => Classical.propDecidable _ + (normalizedFactors x).count p = n := by classical by_cases hx0 : x = 0 · simp [hx0] at hlt - rw [← PartENat.natCast_inj] - convert (multiplicity_eq_count_normalizedFactors hp hx0).symm + apply Nat.cast_injective (R := ℕ∞) + convert (emultiplicity_eq_count_normalizedFactors hp hx0).symm · exact hnorm.symm - exact (multiplicity.eq_coe_iff.mpr ⟨hle, hlt⟩).symm + exact (emultiplicity_eq_coe.mpr ⟨hle, hlt⟩).symm /-- The number of times an irreducible factor `p` appears in `normalizedFactors x` is defined by the number of times it divides `x`. This is a slightly more general version of diff --git a/Mathlib/RingTheory/Valuation/PrimeMultiplicity.lean b/Mathlib/RingTheory/Valuation/PrimeMultiplicity.lean index 53376819d6002e..835372b91040ea 100644 --- a/Mathlib/RingTheory/Valuation/PrimeMultiplicity.lean +++ b/Mathlib/RingTheory/Valuation/PrimeMultiplicity.lean @@ -10,14 +10,14 @@ import Mathlib.RingTheory.Valuation.Basic # `multiplicity` of a prime in an integral domain as an additive valuation -/ -variable {R : Type*} [CommRing R] [IsDomain R] {p : R} [DecidableRel (Dvd.dvd : R → R → Prop)] +variable {R : Type*} [CommRing R] [IsDomain R] {p : R} -/-- `multiplicity` of a prime in an integral domain as an additive valuation to `PartENat`. -/ -noncomputable def multiplicity.addValuation (hp : Prime p) : AddValuation R PartENat := - AddValuation.of (multiplicity p) (multiplicity.zero _) (one_right hp.not_unit) - (fun _ _ => min_le_multiplicity_add) fun _ _ => multiplicity.mul hp +/-- `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 @[simp] -theorem multiplicity.addValuation_apply {hp : Prime p} {r : R} : - addValuation hp r = multiplicity p r := +theorem multiplicity_addValuation_apply {hp : Prime p} {r : R} : + multiplicity_addValuation hp r = emultiplicity p r := rfl diff --git a/Mathlib/RingTheory/WittVector/Frobenius.lean b/Mathlib/RingTheory/WittVector/Frobenius.lean index 3a15c88d7c9d50..91f21547ab8394 100644 --- a/Mathlib/RingTheory/WittVector/Frobenius.lean +++ b/Mathlib/RingTheory/WittVector/Frobenius.lean @@ -70,12 +70,7 @@ theorem bind₁_frobeniusPolyRat_wittPolynomial (n : ℕ) : delta frobeniusPolyRat rw [← bind₁_bind₁, bind₁_xInTermsOfW_wittPolynomial, bind₁_X_right, Function.comp_apply] -/-- An auxiliary definition, to avoid an excessive amount of finiteness proofs -for `multiplicity p n`. -/ -private def pnat_multiplicity (n : ℕ+) : ℕ := - (multiplicity p n).get <| multiplicity.finite_nat_iff.mpr <| ⟨ne_of_gt hp.1.one_lt, n.2⟩ - -local notation "v" => pnat_multiplicity +local notation "v" => multiplicity /-- An auxiliary polynomial over the integers, that satisfies `p * (frobeniusPolyAux p n) + X n ^ p = frobeniusPoly p n`. @@ -86,16 +81,17 @@ noncomputable def frobeniusPolyAux : ℕ → MvPolynomial ℕ ℤ ∑ j ∈ range (p ^ (n - i)), (((X (i : ℕ) ^ p) ^ (p ^ (n - (i : ℕ)) - (j + 1)) : MvPolynomial ℕ ℤ) * (frobeniusPolyAux i) ^ (j + 1)) * - C (((p ^ (n - i)).choose (j + 1) / (p ^ (n - i - v p ⟨j + 1, Nat.succ_pos j⟩)) - * ↑p ^ (j - v p ⟨j + 1, Nat.succ_pos j⟩) : ℕ) : ℤ) + C (((p ^ (n - i)).choose (j + 1) / (p ^ (n - i - v p (j + 1))) + * ↑p ^ (j - v p (j + 1)) : ℕ) : ℤ) +omit hp in theorem frobeniusPolyAux_eq (n : ℕ) : frobeniusPolyAux p n = X (n + 1) - ∑ i ∈ range n, ∑ j ∈ range (p ^ (n - i)), (X i ^ p) ^ (p ^ (n - i) - (j + 1)) * frobeniusPolyAux p i ^ (j + 1) * - C ↑((p ^ (n - i)).choose (j + 1) / p ^ (n - i - v p ⟨j + 1, Nat.succ_pos j⟩) * - ↑p ^ (j - v p ⟨j + 1, Nat.succ_pos j⟩) : ℕ) := by + C ↑((p ^ (n - i)).choose (j + 1) / p ^ (n - i - v p (j + 1)) * + ↑p ^ (j - v p (j + 1)) : ℕ) := by rw [frobeniusPolyAux, ← Fin.sum_univ_eq_sum_range] /-- The polynomials that give the coefficients of `frobenius x`, @@ -114,20 +110,19 @@ and then using the following two key facts at the right point. -/ /-- A key divisibility fact for the proof of `WittVector.map_frobeniusPoly`. -/ theorem map_frobeniusPoly.key₁ (n j : ℕ) (hj : j < p ^ n) : - p ^ (n - v p ⟨j + 1, j.succ_pos⟩) ∣ (p ^ n).choose (j + 1) := by - apply multiplicity.pow_dvd_of_le_multiplicity - rw [hp.out.multiplicity_choose_prime_pow hj j.succ_ne_zero] - rfl + p ^ (n - v p (j + 1)) ∣ (p ^ n).choose (j + 1) := by + apply pow_dvd_of_le_emultiplicity + rw [hp.out.emultiplicity_choose_prime_pow hj j.succ_ne_zero] /-- A key numerical identity needed for the proof of `WittVector.map_frobeniusPoly`. -/ theorem map_frobeniusPoly.key₂ {n i j : ℕ} (hi : i ≤ n) (hj : j < p ^ (n - i)) : - j - v p ⟨j + 1, j.succ_pos⟩ + n = i + j + (n - i - v p ⟨j + 1, j.succ_pos⟩) := by - generalize h : v p ⟨j + 1, j.succ_pos⟩ = m + j - v p (j + 1) + n = i + j + (n - i - v p (j + 1)) := by + generalize h : v p (j + 1) = m rsuffices ⟨h₁, h₂⟩ : m ≤ n - i ∧ m ≤ j · rw [tsub_add_eq_add_tsub h₂, add_comm i j, add_tsub_assoc_of_le (h₁.trans (Nat.sub_le n i)), add_assoc, tsub_right_comm, add_comm i, tsub_add_cancel_of_le (le_tsub_of_add_le_right ((le_tsub_iff_left hi).mp h₁))] - have hle : p ^ m ≤ j + 1 := h ▸ Nat.le_of_dvd j.succ_pos (multiplicity.pow_multiplicity_dvd _) + have hle : p ^ m ≤ j + 1 := h ▸ Nat.le_of_dvd j.succ_pos (pow_multiplicity_dvd _ _) exact ⟨(pow_le_pow_iff_right hp.1.one_lt).1 (hle.trans hj), Nat.le_of_lt_succ ((Nat.lt_pow_self hp.1.one_lt m).trans_le hle)⟩ @@ -173,9 +168,9 @@ theorem map_frobeniusPoly (n : ℕ) : rw [Rat.natCast_div _ _ (map_frobeniusPoly.key₁ p (n - i) j hj)] simp only [Nat.cast_pow, pow_add, pow_one] suffices - (((p ^ (n - i)).choose (j + 1) : ℚ) * (p : ℚ) ^ (j - v p ⟨j + 1, j.succ_pos⟩) * p * (p ^ n : ℚ)) + (((p ^ (n - i)).choose (j + 1) : ℚ) * (p : ℚ) ^ (j - v p (j + 1)) * p * (p ^ n : ℚ)) = (p : ℚ) ^ j * p * ↑((p ^ (n - i)).choose (j + 1) * p ^ i) * - (p : ℚ) ^ (n - i - v p ⟨j + 1, j.succ_pos⟩) by + (p : ℚ) ^ (n - i - v p (j + 1)) by have aux : ∀ k : ℕ, (p : ℚ)^ k ≠ 0 := by intro; apply pow_ne_zero; exact mod_cast hp.1.ne_zero simpa [aux, -one_div, -pow_eq_zero_iff', field_simps] using this.symm @@ -202,6 +197,7 @@ variable {p} def frobeniusFun (x : 𝕎 R) : 𝕎 R := mk p fun n => MvPolynomial.aeval x.coeff (frobeniusPoly p n) +omit hp in theorem coeff_frobeniusFun (x : 𝕎 R) (n : ℕ) : coeff (frobeniusFun x) n = MvPolynomial.aeval x.coeff (frobeniusPoly p n) := by rw [frobeniusFun, coeff_mk] @@ -212,7 +208,7 @@ variable (p) See also `frobenius_isPoly`. -/ -- Porting note: replaced `@[is_poly]` with `instance`. -instance frobeniusFun_isPoly : IsPoly p fun R _Rcr => @frobeniusFun p R _ _Rcr := +instance frobeniusFun_isPoly : IsPoly p fun R _ Rcr => @frobeniusFun p R _ Rcr := ⟨⟨frobeniusPoly p, by intros; funext n; apply coeff_frobeniusFun⟩⟩ variable {p} @@ -246,8 +242,8 @@ def frobenius : 𝕎 R →+* 𝕎 R where (@IsPoly.comp p _ _ WittVector.oneIsPoly (frobeniusFun_isPoly p)) ?_ _ 0 simp only [Function.comp_apply, map_one, forall_const] ghost_simp - map_add' := by ghost_calc _ _; ghost_simp - map_mul' := by ghost_calc _ _; ghost_simp + map_add' := by dsimp only; ghost_calc _ _; ghost_simp + map_mul' := by dsimp only; ghost_calc _ _; ghost_simp theorem coeff_frobenius (x : 𝕎 R) (n : ℕ) : coeff (frobenius x) n = MvPolynomial.aeval x.coeff (frobeniusPoly p n) := From 52ec24b8cf5efb48492a6047c352a222452d9c2d Mon Sep 17 00:00:00 2001 From: Jz Pan Date: Wed, 16 Oct 2024 04:43:27 +0000 Subject: [PATCH 189/425] feat(AlgebraicGeometry/EllipticCurve/J): further properties of j-invariants of elliptic curves (#17431) Currently there is only one new result: - `EllipticCurve.exists_variableChange_of_j_eq`: if `E` and `E'` are elliptic curves with the same `j`-invariants defined over a separably closed field, then there exists a change of variables over that field which change `E` into `E'`. For convenience, a few new results for normal forms are added to `EllipticCurve` namespace, parallel to that of `WeierstrassCurve`. Also added some convenience auxiliary results used in this PR: - `Algebra/CharP/Defs`: `CharP.cast_ne_zero_of_ne_of_prime` - `FieldTheory/Separable`: `Polynomial.separable_C_mul_X_pow_add_C_mul_X_add_C[']` - `FieldTheory/IsSepClosed`: `IsSepClosed.exists_root_C_mul_X_pow_add_C_mul_X_add_C[']` --- Mathlib.lean | 1 + Mathlib/Algebra/CharP/Defs.lean | 11 + .../AlgebraicGeometry/EllipticCurve/J.lean | 350 ++++++++++++++++++ .../EllipticCurve/NormalForms.lean | 56 ++- Mathlib/FieldTheory/IsSepClosed.lean | 29 ++ Mathlib/FieldTheory/Separable.lean | 25 ++ 6 files changed, 470 insertions(+), 2 deletions(-) create mode 100644 Mathlib/AlgebraicGeometry/EllipticCurve/J.lean diff --git a/Mathlib.lean b/Mathlib.lean index 77a38608ac99e6..d7d054e934aae7 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -843,6 +843,7 @@ import Mathlib.AlgebraicGeometry.EllipticCurve.Affine import Mathlib.AlgebraicGeometry.EllipticCurve.DivisionPolynomial.Basic import Mathlib.AlgebraicGeometry.EllipticCurve.DivisionPolynomial.Degree import Mathlib.AlgebraicGeometry.EllipticCurve.Group +import Mathlib.AlgebraicGeometry.EllipticCurve.J import Mathlib.AlgebraicGeometry.EllipticCurve.Jacobian import Mathlib.AlgebraicGeometry.EllipticCurve.NormalForms import Mathlib.AlgebraicGeometry.EllipticCurve.Projective diff --git a/Mathlib/Algebra/CharP/Defs.lean b/Mathlib/Algebra/CharP/Defs.lean index 4a4cc50bbda1f9..3f42840a6923c9 100644 --- a/Mathlib/Algebra/CharP/Defs.lean +++ b/Mathlib/Algebra/CharP/Defs.lean @@ -307,6 +307,17 @@ lemma false_of_nontrivial_of_char_one [Nontrivial R] [CharP R 1] : False := by have : Subsingleton R := CharOne.subsingleton exact false_of_nontrivial_of_subsingleton R +variable (R) in +/-- If a ring `R` is of characteristic `p`, then for any prime number `q` different from `p`, +it is not zero in `R`. -/ +lemma cast_ne_zero_of_ne_of_prime [Nontrivial R] + {p q : ℕ} [CharP R p] (hq : q.Prime) (hneq : p ≠ q) : (q : R) ≠ 0 := fun h ↦ by + rw [cast_eq_zero_iff R p q] at h + rcases hq.eq_one_or_self_of_dvd _ h with h | h + · subst h + exact false_of_nontrivial_of_char_one (R := R) + · exact hneq h + lemma ringChar_ne_one [Nontrivial R] : ringChar R ≠ 1 := by intro h apply zero_ne_one' R diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/J.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/J.lean new file mode 100644 index 00000000000000..3a9bbae95d05dd --- /dev/null +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/J.lean @@ -0,0 +1,350 @@ +/- +Copyright (c) 2024 Jz Pan. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jz Pan +-/ +import Mathlib.AlgebraicGeometry.EllipticCurve.NormalForms +import Mathlib.FieldTheory.IsSepClosed + +/-! + +# Further properties of j-invariants of elliptic curves + +This file states some further properties of j-invariants of elliptic curves. + +## Main results + +- `EllipticCurve.exists_variableChange_of_j_eq`: if `E` and `E'` are elliptic curves with the same + `j`-invariants defined over a separably closed field, then there exists a change of variables + over that field which change `E` into `E'`. + +-/ + +open WeierstrassCurve Polynomial + +variable {F : Type*} [Field F] [IsSepClosed F] + +namespace EllipticCurve + +variable (E E' : EllipticCurve F) + +section CharTwo + +variable [CharP F 2] + +private lemma exists_variableChange_of_char_two_of_j_ne_zero + [E.IsCharTwoJNeZeroNF] [E'.IsCharTwoJNeZeroNF] (heq : E.a₆ = E'.a₆) : + ∃ C : WeierstrassCurve.VariableChange F, E.variableChange C = E' := by + obtain ⟨s, hs⟩ := IsSepClosed.exists_root_C_mul_X_pow_add_C_mul_X_add_C' 2 2 + 1 1 (E.a₂ + E'.a₂) (by norm_num) (by norm_num) one_ne_zero + use ⟨1, 0, s, 0⟩ + ext + · simp_rw [variableChange_a₁, inv_one, Units.val_one, a₁_of_isCharTwoJNeZeroNF] + linear_combination s * CharP.cast_eq_zero F 2 + · simp_rw [variableChange_a₂, inv_one, Units.val_one, a₁_of_isCharTwoJNeZeroNF] + linear_combination -hs + E.a₂ * CharP.cast_eq_zero F 2 + · simp_rw [variableChange_a₃, inv_one, Units.val_one, a₃_of_isCharTwoJNeZeroNF] + ring1 + · simp_rw [variableChange_a₄, inv_one, Units.val_one, a₃_of_isCharTwoJNeZeroNF, + a₄_of_isCharTwoJNeZeroNF] + ring1 + · simp_rw [variableChange_a₆, inv_one, Units.val_one, heq] + ring1 + +private lemma exists_variableChange_of_char_two_of_j_eq_zero + [E.IsCharTwoJEqZeroNF] [E'.IsCharTwoJEqZeroNF] : + ∃ C : WeierstrassCurve.VariableChange F, E.variableChange C = E' := by + have ha₃ := E.Δ'.ne_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 + 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 + obtain ⟨s, hs⟩ := IsSepClosed.exists_root_C_mul_X_pow_add_C_mul_X_add_C' 2 4 + 1 _ (E.a₄ - u ^ 4 * E'.a₄) (by norm_num) (by norm_num) ha₃ + obtain ⟨t, ht⟩ := IsSepClosed.exists_root_C_mul_X_pow_add_C_mul_X_add_C' 2 2 + 1 _ (s ^ 6 + E.a₄ * s ^ 2 + E.a₆ - u ^ 6 * E'.a₆) (by norm_num) (by norm_num) ha₃ + have hu0 : u ≠ 0 := by + rw [← pow_ne_zero_iff three_ne_zero, hu, div_ne_zero_iff] + exact ⟨ha₃, ha₃'⟩ + use ⟨Units.mk0 u hu0, s ^ 2, s, t⟩ + ext + · simp_rw [variableChange_a₁, a₁_of_isCharTwoJEqZeroNF, + show (2 : F) = 0 from CharP.cast_eq_zero F 2] + ring1 + · simp_rw [variableChange_a₂, a₁_of_isCharTwoJEqZeroNF, a₂_of_isCharTwoJEqZeroNF, + show (3 : F) = 1 by linear_combination CharP.cast_eq_zero F 2] + ring1 + · simp_rw [variableChange_a₃, Units.val_inv_eq_inv_val, Units.val_mk0, inv_pow, inv_mul_eq_div, + hu, a₁_of_isCharTwoJEqZeroNF, show (2 : F) = 0 from CharP.cast_eq_zero F 2] + field_simp + · field_simp [variableChange_a₄, a₁_of_isCharTwoJEqZeroNF, a₂_of_isCharTwoJEqZeroNF] + linear_combination hs + (s ^ 4 - s * t - E.a₃ * s) * CharP.cast_eq_zero F 2 + · field_simp [variableChange_a₄, a₁_of_isCharTwoJEqZeroNF, a₂_of_isCharTwoJEqZeroNF] + linear_combination ht - (t ^ 2 + E.a₃ * t) * CharP.cast_eq_zero F 2 + +private lemma exists_variableChange_of_char_two (heq : E.j = E'.j) : + ∃ C : WeierstrassCurve.VariableChange F, E.variableChange C = E' := by + obtain ⟨C, _ | _⟩ := E.exists_variableChange_isCharTwoNF + · obtain ⟨C', _ | _⟩ := E'.exists_variableChange_isCharTwoNF + · simp_rw [← variableChange_j E C, ← variableChange_j E' C', + j_of_isCharTwoJNeZeroNF_of_char_two, one_div, inv_inj] at heq + obtain ⟨C'', hC⟩ := exists_variableChange_of_char_two_of_j_ne_zero _ _ heq + use (C'.inv.comp C'').comp C + rw [variableChange_comp, variableChange_comp, hC, ← variableChange_comp, + WeierstrassCurve.VariableChange.comp_left_inv, variableChange_id] + · have h := (E.variableChange C).j_ne_zero_of_isCharTwoJNeZeroNF_of_char_two + rw [variableChange_j, heq, ← variableChange_j E' C', + j_of_isCharTwoJEqZeroNF_of_char_two] at h + exact False.elim (h rfl) + · obtain ⟨C', _ | _⟩ := E'.exists_variableChange_isCharTwoNF + · have h := (E'.variableChange C').j_ne_zero_of_isCharTwoJNeZeroNF_of_char_two + rw [variableChange_j, ← heq, ← variableChange_j E C, + j_of_isCharTwoJEqZeroNF_of_char_two] at h + exact False.elim (h rfl) + · obtain ⟨C'', hC⟩ := exists_variableChange_of_char_two_of_j_eq_zero + (E.variableChange C) (E'.variableChange C') + use (C'.inv.comp C'').comp C + rw [variableChange_comp, variableChange_comp, hC, ← variableChange_comp, + WeierstrassCurve.VariableChange.comp_left_inv, variableChange_id] + +end CharTwo + +section CharThree + +variable [CharP F 3] + +private lemma exists_variableChange_of_char_three_of_j_ne_zero + [E.IsCharThreeJNeZeroNF] [E'.IsCharThreeJNeZeroNF] (heq : E.j = E'.j) : + ∃ C : WeierstrassCurve.VariableChange F, E.variableChange C = E' := by + have h := E.Δ'.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 + have h := E'.Δ'.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 + 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 + have hu0 : u ≠ 0 := by + rw [← pow_ne_zero_iff two_ne_zero, hu, div_ne_zero_iff] + exact ⟨ha₂, ha₂'⟩ + use ⟨Units.mk0 u hu0, 0, 0, 0⟩ + ext + · simp_rw [variableChange_a₁, a₁_of_isCharThreeJNeZeroNF] + ring1 + · simp_rw [variableChange_a₂, a₁_of_isCharThreeJNeZeroNF, Units.val_inv_eq_inv_val, + Units.val_mk0, inv_pow, inv_mul_eq_div, hu] + field_simp + · simp_rw [variableChange_a₃, a₁_of_isCharThreeJNeZeroNF, a₃_of_isCharThreeJNeZeroNF] + ring1 + · simp_rw [variableChange_a₄, a₁_of_isCharThreeJNeZeroNF, a₃_of_isCharThreeJNeZeroNF, + a₄_of_isCharThreeJNeZeroNF] + ring1 + · simp_rw [j_of_isCharThreeJNeZeroNF_of_char_three, div_eq_div_iff ha₆ ha₆'] at heq + simp_rw [variableChange_a₆, a₁_of_isCharThreeJNeZeroNF, a₃_of_isCharThreeJNeZeroNF, + a₄_of_isCharThreeJNeZeroNF, Units.val_inv_eq_inv_val, Units.val_mk0, + inv_pow, inv_mul_eq_div, pow_mul u 2 3, hu] + field_simp + linear_combination heq + +private lemma exists_variableChange_of_char_three_of_j_eq_zero + [E.IsShortNF] [E'.IsShortNF] : + ∃ C : WeierstrassCurve.VariableChange F, E.variableChange C = E' := by + 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₄ + 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 + 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 + obtain ⟨r, hr⟩ := IsSepClosed.exists_root_C_mul_X_pow_add_C_mul_X_add_C' 3 3 + 1 _ (E.a₆ - u ^ 6 * E'.a₆) (by norm_num) (by norm_num) ha₄ + have hu0 : u ≠ 0 := by + rw [← pow_ne_zero_iff four_ne_zero, hu, div_ne_zero_iff] + exact ⟨ha₄, ha₄'⟩ + use ⟨Units.mk0 u hu0, r, 0, 0⟩ + ext + · simp_rw [variableChange_a₁, a₁_of_isShortNF] + ring1 + · simp_rw [variableChange_a₂, a₁_of_isShortNF, a₂_of_isShortNF, + show (3 : F) = 0 from CharP.cast_eq_zero F 3] + ring1 + · simp_rw [variableChange_a₃, a₁_of_isShortNF, a₃_of_isShortNF] + ring1 + · simp_rw [variableChange_a₄, a₁_of_isShortNF, a₂_of_isShortNF, a₃_of_isShortNF, + Units.val_inv_eq_inv_val, Units.val_mk0, inv_pow, inv_mul_eq_div, hu, + show (3 : F) = 0 from CharP.cast_eq_zero F 3] + field_simp + · simp_rw [variableChange_a₆, a₁_of_isShortNF, a₂_of_isShortNF, a₃_of_isShortNF, + Units.val_inv_eq_inv_val, Units.val_mk0, inv_pow, inv_mul_eq_div] + field_simp + linear_combination hr + +private lemma exists_variableChange_of_char_three (heq : E.j = E'.j) : + ∃ C : WeierstrassCurve.VariableChange F, E.variableChange C = E' := by + obtain ⟨C, _ | _⟩ := E.exists_variableChange_isCharThreeNF + · obtain ⟨C', _ | _⟩ := E'.exists_variableChange_isCharThreeNF + · rw [← variableChange_j E C, ← variableChange_j E' C'] at heq + obtain ⟨C'', hC⟩ := exists_variableChange_of_char_three_of_j_ne_zero _ _ heq + use (C'.inv.comp C'').comp C + rw [variableChange_comp, variableChange_comp, hC, ← variableChange_comp, + WeierstrassCurve.VariableChange.comp_left_inv, variableChange_id] + · have h := (E.variableChange C).j_ne_zero_of_isCharThreeJNeZeroNF_of_char_three + rw [variableChange_j, heq, ← variableChange_j E' C', j_of_isShortNF_of_char_three] at h + exact False.elim (h rfl) + · obtain ⟨C', _ | _⟩ := E'.exists_variableChange_isCharThreeNF + · have h := (E'.variableChange C').j_ne_zero_of_isCharThreeJNeZeroNF_of_char_three + rw [variableChange_j, ← heq, ← variableChange_j E C, j_of_isShortNF_of_char_three] at h + exact False.elim (h rfl) + · obtain ⟨C'', hC⟩ := exists_variableChange_of_char_three_of_j_eq_zero + (E.variableChange C) (E'.variableChange C') + use (C'.inv.comp C'').comp C + rw [variableChange_comp, variableChange_comp, hC, ← variableChange_comp, + WeierstrassCurve.VariableChange.comp_left_inv, variableChange_id] + +end CharThree + +section CharNeTwoOrThree + +private lemma exists_variableChange_of_char_ne_two_or_three + {p : ℕ} [CharP F p] (hchar2 : p ≠ 2) (hchar3 : p ≠ 3) (heq : E.j = E'.j) : + ∃ C : WeierstrassCurve.VariableChange F, E.variableChange C = 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 := pow_ne_zero 2 hchar2 + norm_num1 at this + exact this + haveI : 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 + wlog _ : E.IsShortNF generalizing E + · obtain ⟨C, hE⟩ := E.exists_variableChange_isShortNF + rw [← variableChange_j E C] at heq + obtain ⟨C', hC⟩ := this _ heq hE + exact ⟨C'.comp C, by rwa [variableChange_comp]⟩ + wlog _ : E'.IsShortNF generalizing E' + · obtain ⟨C, hE'⟩ := E'.exists_variableChange_isShortNF + rw [← variableChange_j E' C] at heq + obtain ⟨C', hC⟩ := this _ heq hE' + exact ⟨C.inv.comp C', by rw [variableChange_comp, hC, ← variableChange_comp, + WeierstrassCurve.VariableChange.comp_left_inv, variableChange_id]⟩ + 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 + have := mul_ne_zero (pow_ne_zero 16 hchar2) (pow_ne_zero 6 hchar3) + norm_num1 at this + exact this + rw [← mul_right_inj_of_invertible (47775744 : F)] + linear_combination heq + by_cases ha₄ : E.a₄ = 0 + · have ha₆ := E.Δ'.ne_zero + rw [coe_Δ', Δ_of_isShortNF, ha₄, zero_pow three_ne_zero, mul_zero, zero_add, ← mul_assoc, + mul_ne_zero_iff, pow_ne_zero_iff two_ne_zero] at ha₆ + replace ha₆ := ha₆.2 + have ha₄' : E'.a₄ = 0 := by + rw [ha₄, zero_pow three_ne_zero, zero_mul, zero_eq_mul] at heq + exact (pow_eq_zero_iff three_ne_zero).1 <| heq.resolve_right <| pow_ne_zero 2 ha₆ + have ha₆' := E'.Δ'.ne_zero + rw [coe_Δ', Δ_of_isShortNF, ha₄', zero_pow three_ne_zero, mul_zero, zero_add, ← mul_assoc, + mul_ne_zero_iff, pow_ne_zero_iff two_ne_zero] at ha₆' + replace ha₆' := ha₆'.2 + obtain ⟨u, hu⟩ := IsSepClosed.exists_pow_nat_eq (E.a₆ / E'.a₆) 6 + have hu0 : u ≠ 0 := by + rw [← pow_ne_zero_iff (Nat.succ_ne_zero 5), hu, div_ne_zero_iff] + exact ⟨ha₆, ha₆'⟩ + use ⟨Units.mk0 u hu0, 0, 0, 0⟩ + ext + · simp + · simp + · simp + · simp [ha₄, ha₄'] + · simp_rw [variableChange_a₆, a₁_of_isShortNF, a₂_of_isShortNF, a₃_of_isShortNF, + ha₄, Units.val_inv_eq_inv_val, Units.val_mk0, inv_pow, inv_mul_eq_div, hu] + field_simp + by_cases ha₆ : E.a₆ = 0 + · have ha₄ := E.Δ'.ne_zero + rw [coe_Δ', Δ_of_isShortNF, ha₆, zero_pow two_ne_zero, mul_zero, add_zero, ← mul_assoc, + mul_ne_zero_iff, pow_ne_zero_iff three_ne_zero] at ha₄ + replace ha₄ := ha₄.2 + have ha₆' : E'.a₆ = 0 := by + rw [ha₆, zero_pow two_ne_zero, mul_zero, mul_eq_zero] at heq + exact (pow_eq_zero_iff two_ne_zero).1 <| heq.resolve_left <| pow_ne_zero 3 ha₄ + have ha₄' := E'.Δ'.ne_zero + rw [coe_Δ', Δ_of_isShortNF, ha₆', zero_pow two_ne_zero, mul_zero, add_zero, ← mul_assoc, + mul_ne_zero_iff, pow_ne_zero_iff three_ne_zero] at ha₄' + replace ha₄' := ha₄'.2 + obtain ⟨u, hu⟩ := IsSepClosed.exists_pow_nat_eq (E.a₄ / E'.a₄) 4 + have hu0 : u ≠ 0 := by + rw [← pow_ne_zero_iff four_ne_zero, hu, div_ne_zero_iff] + exact ⟨ha₄, ha₄'⟩ + use ⟨Units.mk0 u hu0, 0, 0, 0⟩ + ext + · simp + · simp + · simp + · simp_rw [variableChange_a₄, a₁_of_isShortNF, a₂_of_isShortNF, a₃_of_isShortNF, + Units.val_inv_eq_inv_val, Units.val_mk0, inv_pow, inv_mul_eq_div, hu] + field_simp + · simp [ha₆, ha₆'] + have ha₄' : E'.a₄ ≠ 0 := fun h ↦ by + rw [h, zero_pow three_ne_zero, zero_mul, mul_eq_zero, + pow_eq_zero_iff two_ne_zero, pow_eq_zero_iff three_ne_zero] at heq + simpa [E'.coe_Δ', Δ_of_isShortNF, h, heq.resolve_left ha₄] using E'.Δ'.ne_zero + have ha₆' : E'.a₆ ≠ 0 := fun h ↦ by + rw [h, zero_pow two_ne_zero, mul_zero, zero_eq_mul, + pow_eq_zero_iff two_ne_zero, pow_eq_zero_iff three_ne_zero] at heq + tauto + obtain ⟨u, hu⟩ := IsSepClosed.exists_pow_nat_eq (E.a₆ / E'.a₆ / (E.a₄ / E'.a₄)) 2 + have hu4 : u ^ 4 = E.a₄ / E'.a₄ := by + rw [pow_mul u 2 2, hu] + field_simp + linear_combination -heq + have hu6 : u ^ 6 = E.a₆ / E'.a₆ := by + rw [pow_mul u 2 3, hu] + field_simp + linear_combination -E.a₆ * E'.a₆ * heq + have hu0 : u ≠ 0 := by + rw [← pow_ne_zero_iff four_ne_zero, hu4, div_ne_zero_iff] + exact ⟨ha₄, ha₄'⟩ + use ⟨Units.mk0 u hu0, 0, 0, 0⟩ + ext + · simp + · simp + · simp + · simp_rw [variableChange_a₄, a₁_of_isShortNF, a₂_of_isShortNF, a₃_of_isShortNF, + Units.val_inv_eq_inv_val, Units.val_mk0, inv_pow, inv_mul_eq_div, hu4] + field_simp + · simp_rw [variableChange_a₆, a₁_of_isShortNF, a₂_of_isShortNF, a₃_of_isShortNF, + Units.val_inv_eq_inv_val, Units.val_mk0, inv_pow, inv_mul_eq_div, hu6] + field_simp + +end CharNeTwoOrThree + +/-- If there are two elliptic curves with the same `j`-invariants defined over a +separably closed field, then there exists a change of variables over that field which change +one curve into another. -/ +theorem exists_variableChange_of_j_eq (heq : E.j = E'.j) : + ∃ C : WeierstrassCurve.VariableChange F, E.variableChange C = E' := by + obtain ⟨p, _⟩ := CharP.exists F + by_cases hchar2 : p = 2 + · subst hchar2 + exact exists_variableChange_of_char_two _ _ heq + by_cases hchar3 : p = 3 + · subst hchar3 + exact exists_variableChange_of_char_three _ _ heq + exact exists_variableChange_of_char_ne_two_or_three _ _ hchar2 hchar3 heq + +end EllipticCurve diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/NormalForms.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/NormalForms.lean index 565f29a05b7f17..23a9a69744985d 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/NormalForms.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/NormalForms.lean @@ -156,7 +156,7 @@ end Quantity section VariableChange -variable [Invertible (2 : R)] +variable (E : EllipticCurve R) [Invertible (2 : R)] /-- There is an explicit change of variables of a `WeierstrassCurve` to a normal form of characteristic ≠ 2, provided that 2 is invertible in the ring. -/ @@ -170,6 +170,14 @@ theorem exists_variableChange_isCharNeTwoNF : ∃ C : VariableChange R, (W.variableChange C).IsCharNeTwoNF := ⟨_, W.toCharNeTwoNF_spec⟩ +instance _root_.EllipticCurve.toCharNeTwoNF_spec : + (E.variableChange E.toCharNeTwoNF).IsCharNeTwoNF := + E.toWeierstrassCurve.toCharNeTwoNF_spec + +theorem _root_.EllipticCurve.exists_variableChange_isCharNeTwoNF : + ∃ C : VariableChange R, (E.variableChange C).IsCharNeTwoNF := + ⟨_, E.toCharNeTwoNF_spec⟩ + end VariableChange /-! ### Short normal form -/ @@ -258,7 +266,7 @@ end Quantity section VariableChange -variable [Invertible (2 : R)] [Invertible (3 : R)] +variable (E : EllipticCurve R) [Invertible (2 : R)] [Invertible (3 : R)] /-- There is an explicit change of variables of a `WeierstrassCurve` to a short normal form, provided that 2 and 3 are invertible in the ring. @@ -274,6 +282,13 @@ theorem exists_variableChange_isShortNF : ∃ C : VariableChange R, (W.variableChange C).IsShortNF := ⟨_, W.toShortNF_spec⟩ +instance _root_.EllipticCurve.toShortNF_spec : (E.variableChange E.toShortNF).IsShortNF := + E.toWeierstrassCurve.toShortNF_spec + +theorem _root_.EllipticCurve.exists_variableChange_isShortNF : + ∃ C : VariableChange R, (E.variableChange C).IsShortNF := + ⟨_, E.toShortNF_spec⟩ + end VariableChange /-! ### Normal forms of characteristic = 3 and j ≠ 0 -/ @@ -405,6 +420,10 @@ theorem toShortNFOfCharThree_spec (hb₂ : W.b₂ = 0) : have H := W.toCharNeTwoNF_spec exact ⟨H.a₁, hb₂ ▸ W.toShortNFOfCharThree_a₂, H.a₃⟩ +theorem _root_.EllipticCurve.toShortNFOfCharThree_spec (E : EllipticCurve R) (hb₂ : E.b₂ = 0) : + (E.variableChange E.toShortNFOfCharThree).IsShortNF := + E.toWeierstrassCurve.toShortNFOfCharThree_spec hb₂ + variable (W : WeierstrassCurve F) /-- For a `WeierstrassCurve` defined over a field of characteristic = 3, @@ -436,6 +455,14 @@ theorem toCharThreeNF_spec_of_b₂_eq_zero (hb₂ : W.b₂ = 0) : VariableChange.id_comp] exact W.toShortNFOfCharThree_spec hb₂ +theorem _root_.EllipticCurve.toCharThreeNF_spec_of_b₂_ne_zero (hb₂ : E.b₂ ≠ 0) : + (E.variableChange E.toCharThreeNF).IsCharThreeJNeZeroNF := + E.toWeierstrassCurve.toCharThreeNF_spec_of_b₂_ne_zero hb₂ + +theorem _root_.EllipticCurve.toCharThreeNF_spec_of_b₂_eq_zero (hb₂ : E.b₂ = 0) : + (E.variableChange E.toCharThreeNF).IsShortNF := + E.toWeierstrassCurve.toCharThreeNF_spec_of_b₂_eq_zero hb₂ + instance toCharThreeNF_spec : (W.variableChange W.toCharThreeNF).IsCharThreeNF := by by_cases hb₂ : W.b₂ = 0 · haveI := W.toCharThreeNF_spec_of_b₂_eq_zero hb₂ @@ -447,6 +474,14 @@ theorem exists_variableChange_isCharThreeNF : ∃ C : VariableChange F, (W.variableChange C).IsCharThreeNF := ⟨_, W.toCharThreeNF_spec⟩ +instance _root_.EllipticCurve.toCharThreeNF_spec : + (E.variableChange E.toCharThreeNF).IsCharThreeNF := + E.toWeierstrassCurve.toCharThreeNF_spec + +theorem _root_.EllipticCurve.exists_variableChange_isCharThreeNF : + ∃ C : VariableChange F, (E.variableChange C).IsCharThreeNF := + ⟨_, E.toCharThreeNF_spec⟩ + end VariableChange /-! ### Normal forms of characteristic = 2 and j ≠ 0 -/ @@ -663,6 +698,10 @@ theorem toCharTwoJEqZeroNF_spec (ha₁ : W.a₁ = 0) : · simp_rw [toCharTwoJEqZeroNF, variableChange_a₂, inv_one, Units.val_one] linear_combination 2 * W.a₂ * CharP.cast_eq_zero R 2 +theorem _root_.EllipticCurve.toCharTwoJEqZeroNF_spec (E : EllipticCurve R) (ha₁ : E.a₁ = 0) : + (E.variableChange E.toCharTwoJEqZeroNF).IsCharTwoJEqZeroNF := + E.toWeierstrassCurve.toCharTwoJEqZeroNF_spec ha₁ + variable (W : WeierstrassCurve F) /-- For a `WeierstrassCurve` defined over a field of characteristic = 2, @@ -680,6 +719,10 @@ theorem toCharTwoJNeZeroNF_spec (ha₁ : W.a₁ ≠ 0) : · field_simp [toCharTwoJNeZeroNF] linear_combination (W.a₁ ^ 4 * W.a₃ ^ 2 + W.a₁ ^ 5 * W.a₃ * W.a₂) * CharP.cast_eq_zero F 2 +theorem _root_.EllipticCurve.toCharTwoJNeZeroNF_spec (ha₁ : E.a₁ ≠ 0) : + (E.variableChange (E.toCharTwoJNeZeroNF ha₁)).IsCharTwoJNeZeroNF := + E.toWeierstrassCurve.toCharTwoJNeZeroNF_spec ha₁ + /-- For a `WeierstrassCurve` defined over a field of characteristic = 2, there is an explicit change of variables of it to `WeierstrassCurve.IsCharTwoNF`, that is, $Y^2 + XY = X^3 + a_2X^2 + a_6$ (`WeierstrassCurve.IsCharTwoJNeZeroNF`) or @@ -701,6 +744,15 @@ theorem exists_variableChange_isCharTwoNF : classical exact ⟨_, W.toCharTwoNF_spec⟩ +instance _root_.EllipticCurve.toCharTwoNF_spec [DecidableEq F] : + (E.variableChange E.toCharTwoNF).IsCharTwoNF := + E.toWeierstrassCurve.toCharTwoNF_spec + +theorem _root_.EllipticCurve.exists_variableChange_isCharTwoNF : + ∃ C : VariableChange F, (E.variableChange C).IsCharTwoNF := by + classical + exact ⟨_, E.toCharTwoNF_spec⟩ + end VariableChange end WeierstrassCurve diff --git a/Mathlib/FieldTheory/IsSepClosed.lean b/Mathlib/FieldTheory/IsSepClosed.lean index 8e15662dae680e..d7d9c870dda5af 100644 --- a/Mathlib/FieldTheory/IsSepClosed.lean +++ b/Mathlib/FieldTheory/IsSepClosed.lean @@ -92,6 +92,35 @@ theorem exists_root [IsSepClosed k] (p : k[X]) (hp : p.degree ≠ 0) (hsep : p.S ∃ x, IsRoot p x := exists_root_of_splits _ (IsSepClosed.splits_of_separable p hsep) hp +/-- If `n ≥ 2` equals zero in a separably closed field `k`, `b ≠ 0`, +then there exists `x` in `k` such that `a * x ^ n + b * x + c = 0`. -/ +theorem exists_root_C_mul_X_pow_add_C_mul_X_add_C + [IsSepClosed k] {n : ℕ} (a b c : k) (hn : (n : k) = 0) (hn' : 2 ≤ n) (hb : b ≠ 0) : + ∃ x, a * x ^ n + b * x + c = 0 := by + let f : k[X] := C a * X ^ n + C b * X + C c + have hdeg : f.degree ≠ 0 := degree_ne_of_natDegree_ne <| by + by_cases ha : a = 0 + · suffices f.natDegree = 1 from this ▸ one_ne_zero + simp_rw [f, ha, map_zero, zero_mul, zero_add] + compute_degree! + · suffices f.natDegree = n from this ▸ (lt_of_lt_of_le zero_lt_two hn').ne' + simp_rw [f] + have h0 : n ≠ 0 := by linarith only [hn'] + have h1 : n ≠ 1 := by linarith only [hn'] + have : 1 ≤ n := le_trans one_le_two hn' + compute_degree! + simp [h0, h1, ha] + have hsep : f.Separable := separable_C_mul_X_pow_add_C_mul_X_add_C a b c hn hb.isUnit + obtain ⟨x, hx⟩ := exists_root f hdeg hsep + exact ⟨x, by simpa [f] using hx⟩ + +/-- If a separably closed field `k` is of characteristic `p`, `n ≥ 2` is such that `p ∣ n`, `b ≠ 0`, +then there exists `x` in `k` such that `a * x ^ n + b * x + c = 0`. -/ +theorem exists_root_C_mul_X_pow_add_C_mul_X_add_C' + [IsSepClosed k] (p n : ℕ) (a b c : k) [CharP k p] (hn : p ∣ n) (hn' : 2 ≤ n) (hb : b ≠ 0) : + ∃ x, a * x ^ n + b * x + c = 0 := + exists_root_C_mul_X_pow_add_C_mul_X_add_C a b c ((CharP.cast_eq_zero_iff k p n).2 hn) hn' hb + variable (k) in /-- A separably closed perfect field is also algebraically closed. -/ instance (priority := 100) isAlgClosed_of_perfectField [IsSepClosed k] [PerfectField k] : diff --git a/Mathlib/FieldTheory/Separable.lean b/Mathlib/FieldTheory/Separable.lean index edc1ae86fabce9..63d3ad68e42f22 100644 --- a/Mathlib/FieldTheory/Separable.lean +++ b/Mathlib/FieldTheory/Separable.lean @@ -253,6 +253,26 @@ theorem separable_X_pow_sub_C_unit {n : ℕ} (u : Rˣ) (hn : IsUnit (n : R)) : simp only [Units.inv_mul, hn', C.map_one, mul_one, ← pow_succ', Nat.sub_add_cancel (show 1 ≤ n from hpos), sub_add_cancel] +/-- If `n = 0` in `R` and `b` is a unit, then `a * X ^ n + b * X + c` is separable. -/ +theorem separable_C_mul_X_pow_add_C_mul_X_add_C + {n : ℕ} (a b c : R) (hn : (n : R) = 0) (hb : IsUnit b) : + (C a * X ^ n + C b * X + C c).Separable := by + set f := C a * X ^ n + C b * X + C c + have hderiv : derivative f = C b := by + simp_rw [f, map_add derivative, derivative_C] + simp [hn] + obtain ⟨e, hb⟩ := hb.exists_left_inv + refine ⟨-derivative f, f + C e, ?_⟩ + rw [hderiv, right_distrib, ← add_assoc, neg_mul, mul_comm, neg_add_cancel, zero_add, + ← map_mul, hb, map_one] + +/-- If `R` is of characteristic `p`, `p ∣ n` and `b` is a unit, +then `a * X ^ n + b * X + c` is separable. -/ +theorem separable_C_mul_X_pow_add_C_mul_X_add_C' + (p n : ℕ) (a b c : R) [CharP R p] (hn : p ∣ n) (hb : IsUnit b) : + (C a * X ^ n + C b * X + C c).Separable := + separable_C_mul_X_pow_add_C_mul_X_add_C a b c ((CharP.cast_eq_zero_iff R p n).2 hn) hb + theorem rootMultiplicity_le_one_of_separable [Nontrivial R] {p : R[X]} (hsep : Separable p) (x : R) : rootMultiplicity x p ≤ 1 := by classical @@ -403,6 +423,11 @@ theorem separable_X_pow_sub_C {n : ℕ} (a : F) (hn : (n : F) ≠ 0) (ha : a ≠ Separable (X ^ n - C a) := separable_X_pow_sub_C_unit (Units.mk0 a ha) (IsUnit.mk0 (n : F) hn) +/-- If `F` is of characteristic `p` and `p ∤ n`, then `X ^ n - a` is separable for any `a ≠ 0`. -/ +theorem separable_X_pow_sub_C' (p n : ℕ) (a : F) [CharP F p] (hn : ¬p ∣ n) (ha : a ≠ 0) : + Separable (X ^ n - C a) := + separable_X_pow_sub_C a (by rwa [← CharP.cast_eq_zero_iff F p n] at hn) ha + -- this can possibly be strengthened to making `separable_X_pow_sub_C_unit` a -- bi-implication, but it is nontrivial! /-- In a field `F`, `X ^ n - 1` is separable iff `↑n ≠ 0`. -/ From e11ad74a0019789ce11354c1f71b7c44fb8fa6c7 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 04:43:28 +0000 Subject: [PATCH 190/425] chore: split Data.Finite.Basic (#17796) --- Mathlib.lean | 5 ++ Mathlib/CategoryTheory/FintypeCat.lean | 2 +- .../CategoryTheory/Galois/Decomposition.lean | 1 + Mathlib/CategoryTheory/Limits/FintypeCat.lean | 2 + Mathlib/Combinatorics/HalesJewett.lean | 1 + .../Data/Fin/Tuple/BubbleSortInduction.lean | 1 + Mathlib/Data/Fin/Tuple/Sort.lean | 1 + Mathlib/Data/Finite/Basic.lean | 66 +------------------ Mathlib/Data/Finite/Powerset.lean | 20 ++++++ Mathlib/Data/Finite/Prod.lean | 45 +++++++++++++ Mathlib/Data/Finite/Sigma.lean | 25 +++++++ Mathlib/Data/Finite/Sum.lean | 27 ++++++++ Mathlib/Data/Finite/Vector.lean | 15 +++++ Mathlib/Data/Finset/Preimage.lean | 1 + Mathlib/Data/FunLike/Fintype.lean | 2 +- Mathlib/Data/Set/Finite.lean | 9 ++- Mathlib/GroupTheory/Abelianization.lean | 1 + Mathlib/GroupTheory/GroupAction/Quotient.lean | 1 + Mathlib/GroupTheory/Perm/Finite.lean | 1 + Mathlib/GroupTheory/Perm/Sign.lean | 1 + .../GroupTheory/SpecificGroups/Dihedral.lean | 1 + Mathlib/LinearAlgebra/Matrix/ToLin.lean | 1 + Mathlib/ModelTheory/DirectLimit.lean | 1 + 23 files changed, 162 insertions(+), 68 deletions(-) create mode 100644 Mathlib/Data/Finite/Powerset.lean create mode 100644 Mathlib/Data/Finite/Prod.lean create mode 100644 Mathlib/Data/Finite/Sigma.lean create mode 100644 Mathlib/Data/Finite/Sum.lean create mode 100644 Mathlib/Data/Finite/Vector.lean diff --git a/Mathlib.lean b/Mathlib.lean index d7d054e934aae7..e2a1e20cdd35a5 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2184,7 +2184,12 @@ import Mathlib.Data.FinEnum import Mathlib.Data.Finite.Basic import Mathlib.Data.Finite.Card import Mathlib.Data.Finite.Defs +import Mathlib.Data.Finite.Powerset +import Mathlib.Data.Finite.Prod import Mathlib.Data.Finite.Set +import Mathlib.Data.Finite.Sigma +import Mathlib.Data.Finite.Sum +import Mathlib.Data.Finite.Vector import Mathlib.Data.Finmap import Mathlib.Data.Finset.Attr import Mathlib.Data.Finset.Basic diff --git a/Mathlib/CategoryTheory/FintypeCat.lean b/Mathlib/CategoryTheory/FintypeCat.lean index 30efd8e330d9f3..519fda3a21f041 100644 --- a/Mathlib/CategoryTheory/FintypeCat.lean +++ b/Mathlib/CategoryTheory/FintypeCat.lean @@ -6,7 +6,7 @@ Authors: Bhavik Mehta, Adam Topaz import Mathlib.CategoryTheory.ConcreteCategory.Basic import Mathlib.CategoryTheory.Endomorphism import Mathlib.CategoryTheory.Skeletal -import Mathlib.Data.Finite.Basic +import Mathlib.Data.Finite.Prod /-! # The category of finite types. diff --git a/Mathlib/CategoryTheory/Galois/Decomposition.lean b/Mathlib/CategoryTheory/Galois/Decomposition.lean index 367dfd4597ae66..7b77438602714d 100644 --- a/Mathlib/CategoryTheory/Galois/Decomposition.lean +++ b/Mathlib/CategoryTheory/Galois/Decomposition.lean @@ -5,6 +5,7 @@ Authors: Christian Merten -/ import Mathlib.CategoryTheory.Galois.GaloisObjects import Mathlib.CategoryTheory.Limits.Shapes.CombinedProducts +import Mathlib.Data.Finite.Sum /-! # Decomposition of objects into connected components and applications diff --git a/Mathlib/CategoryTheory/Limits/FintypeCat.lean b/Mathlib/CategoryTheory/Limits/FintypeCat.lean index db0a572fc3b926..91dbe9688d8751 100644 --- a/Mathlib/CategoryTheory/Limits/FintypeCat.lean +++ b/Mathlib/CategoryTheory/Limits/FintypeCat.lean @@ -7,6 +7,8 @@ import Mathlib.CategoryTheory.FintypeCat import Mathlib.CategoryTheory.Limits.Preserves.Finite import Mathlib.CategoryTheory.Limits.Preserves.Shapes.Products import Mathlib.CategoryTheory.Limits.Shapes.Types +import Mathlib.Data.Finite.Basic +import Mathlib.Data.Finite.Sigma /-! # (Co)limits in the category of finite types diff --git a/Mathlib/Combinatorics/HalesJewett.lean b/Mathlib/Combinatorics/HalesJewett.lean index f02b8490121411..04d6ee1658e639 100644 --- a/Mathlib/Combinatorics/HalesJewett.lean +++ b/Mathlib/Combinatorics/HalesJewett.lean @@ -6,6 +6,7 @@ Authors: David Wärn import Mathlib.Algebra.BigOperators.Group.Finset import Mathlib.Data.Fintype.Option import Mathlib.Data.Fintype.Shrink +import Mathlib.Data.Fintype.Sum /-! # The Hales-Jewett theorem diff --git a/Mathlib/Data/Fin/Tuple/BubbleSortInduction.lean b/Mathlib/Data/Fin/Tuple/BubbleSortInduction.lean index 3e674c79d4206e..c109daad37a102 100644 --- a/Mathlib/Data/Fin/Tuple/BubbleSortInduction.lean +++ b/Mathlib/Data/Fin/Tuple/BubbleSortInduction.lean @@ -6,6 +6,7 @@ Authors: Michael Stoll import Mathlib.Data.Fin.Tuple.Sort import Mathlib.Order.WellFounded import Mathlib.Order.PiLex +import Mathlib.Data.Finite.Basic /-! # "Bubble sort" induction diff --git a/Mathlib/Data/Fin/Tuple/Sort.lean b/Mathlib/Data/Fin/Tuple/Sort.lean index 6dfe8a11de7e85..0823fab46883af 100644 --- a/Mathlib/Data/Fin/Tuple/Sort.lean +++ b/Mathlib/Data/Fin/Tuple/Sort.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Kyle Miller -/ import Mathlib.Data.Finset.Sort +import Mathlib.Data.Fintype.Sum import Mathlib.Data.List.FinRange import Mathlib.Data.Prod.Lex import Mathlib.GroupTheory.Perm.Basic diff --git a/Mathlib/Data/Finite/Basic.lean b/Mathlib/Data/Finite/Basic.lean index fdc0bab1f42de9..59b373c1f27981 100644 --- a/Mathlib/Data/Finite/Basic.lean +++ b/Mathlib/Data/Finite/Basic.lean @@ -3,11 +3,7 @@ Copyright (c) 2022 Kyle Miller. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Kyle Miller -/ -import Mathlib.Data.Fintype.Powerset -import Mathlib.Data.Fintype.Prod -import Mathlib.Data.Fintype.Sigma -import Mathlib.Data.Fintype.Sum -import Mathlib.Data.Fintype.Vector +import Mathlib.Data.Finite.Prod /-! # Finite types @@ -42,12 +38,7 @@ finiteness, finite types open Mathlib -noncomputable section - -open scoped Classical - -variable {α β γ : Type*} - +variable {α β : Type*} namespace Finite -- see Note [lower instance priority] @@ -59,57 +50,8 @@ instance (priority := 100) of_subsingleton {α : Sort*} [Subsingleton α] : Fini instance prop (p : Prop) : Finite p := Finite.of_subsingleton -instance [Finite α] [Finite β] : Finite (α × β) := by - haveI := Fintype.ofFinite α - haveI := Fintype.ofFinite β - infer_instance - -instance {α β : Sort*} [Finite α] [Finite β] : Finite (PProd α β) := - of_equiv _ Equiv.pprodEquivProdPLift.symm - -theorem prod_left (β) [Finite (α × β)] [Nonempty β] : Finite α := - of_surjective (Prod.fst : α × β → α) Prod.fst_surjective - -theorem prod_right (α) [Finite (α × β)] [Nonempty α] : Finite β := - of_surjective (Prod.snd : α × β → β) Prod.snd_surjective - -instance [Finite α] [Finite β] : Finite (α ⊕ β) := by - haveI := Fintype.ofFinite α - haveI := Fintype.ofFinite β - infer_instance - -theorem sum_left (β) [Finite (α ⊕ β)] : Finite α := - of_injective (Sum.inl : α → α ⊕ β) Sum.inl_injective - -theorem sum_right (α) [Finite (α ⊕ β)] : Finite β := - of_injective (Sum.inr : β → α ⊕ β) Sum.inr_injective - -instance {β : α → Type*} [Finite α] [∀ a, Finite (β a)] : Finite (Σa, β a) := by - letI := Fintype.ofFinite α - letI := fun a => Fintype.ofFinite (β a) - infer_instance - -instance {ι : Sort*} {π : ι → Sort*} [Finite ι] [∀ i, Finite (π i)] : Finite (Σ'i, π i) := - of_equiv _ (Equiv.psigmaEquivSigmaPLift π).symm - -instance [Finite α] : Finite (Set α) := by - cases nonempty_fintype α - infer_instance - end Finite -instance Pi.finite {α : Sort*} {β : α → Sort*} [Finite α] [∀ a, Finite (β a)] : - Finite (∀ a, β a) := by - haveI := Fintype.ofFinite (PLift α) - haveI := fun a => Fintype.ofFinite (PLift (β a)) - exact - Finite.of_equiv (∀ a : PLift α, PLift (β (Equiv.plift a))) - (Equiv.piCongr Equiv.plift fun _ => Equiv.plift) - -instance Vector.finite {α : Type*} [Finite α] {n : ℕ} : Finite (Vector α n) := by - haveI := Fintype.ofFinite α - infer_instance - instance Quot.finite {α : Sort*} [Finite α] (r : α → α → Prop) : Finite (Quot r) := Finite.of_surjective _ (surjective_quot_mk r) @@ -132,7 +74,3 @@ instance Equiv.finite_right {α β : Sort*} [Finite β] : Finite (α ≃ β) := instance Equiv.finite_left {α β : Sort*} [Finite α] : Finite (α ≃ β) := Finite.of_equiv _ ⟨Equiv.symm, Equiv.symm, Equiv.symm_symm, Equiv.symm_symm⟩ - -instance [Finite α] {n : ℕ} : Finite (Sym α n) := by - haveI := Fintype.ofFinite α - infer_instance diff --git a/Mathlib/Data/Finite/Powerset.lean b/Mathlib/Data/Finite/Powerset.lean new file mode 100644 index 00000000000000..d505de253c6e8e --- /dev/null +++ b/Mathlib/Data/Finite/Powerset.lean @@ -0,0 +1,20 @@ +/- +Copyright (c) 2022 Kyle Miller. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Kyle Miller +-/ +import Mathlib.Data.Fintype.Powerset + +/-! +# Finiteness of powersets +-/ + +variable {α : Type*} + +namespace Finite + +instance [Finite α] : Finite (Set α) := by + cases nonempty_fintype α + infer_instance + +end Finite diff --git a/Mathlib/Data/Finite/Prod.lean b/Mathlib/Data/Finite/Prod.lean new file mode 100644 index 00000000000000..4ae0c09c2c903b --- /dev/null +++ b/Mathlib/Data/Finite/Prod.lean @@ -0,0 +1,45 @@ +/- +Copyright (c) 2022 Kyle Miller. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Kyle Miller +-/ +import Mathlib.Data.Fintype.Prod +import Mathlib.Data.Fintype.Vector + +/-! +# Finiteness of products +-/ + +open scoped Classical + +variable {α β : Type*} + +namespace Finite + +instance [Finite α] [Finite β] : Finite (α × β) := by + haveI := Fintype.ofFinite α + haveI := Fintype.ofFinite β + infer_instance + +instance {α β : Sort*} [Finite α] [Finite β] : Finite (PProd α β) := + of_equiv _ Equiv.pprodEquivProdPLift.symm + +theorem prod_left (β) [Finite (α × β)] [Nonempty β] : Finite α := + of_surjective (Prod.fst : α × β → α) Prod.fst_surjective + +theorem prod_right (α) [Finite (α × β)] [Nonempty α] : Finite β := + of_surjective (Prod.snd : α × β → β) Prod.snd_surjective + +end Finite + +instance Pi.finite {α : Sort*} {β : α → Sort*} [Finite α] [∀ a, Finite (β a)] : + Finite (∀ a, β a) := by + haveI := Fintype.ofFinite (PLift α) + haveI := fun a => Fintype.ofFinite (PLift (β a)) + exact + Finite.of_equiv (∀ a : PLift α, PLift (β (Equiv.plift a))) + (Equiv.piCongr Equiv.plift fun _ => Equiv.plift) + +instance [Finite α] {n : ℕ} : Finite (Sym α n) := by + haveI := Fintype.ofFinite α + infer_instance diff --git a/Mathlib/Data/Finite/Sigma.lean b/Mathlib/Data/Finite/Sigma.lean new file mode 100644 index 00000000000000..487abd57fc0074 --- /dev/null +++ b/Mathlib/Data/Finite/Sigma.lean @@ -0,0 +1,25 @@ +/- +Copyright (c) 2022 Kyle Miller. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Kyle Miller +-/ +import Mathlib.Data.Fintype.Sigma +import Mathlib.Data.Fintype.Card + +/-! +# Finiteness of sigma types +-/ + +variable {α : Type*} + +namespace Finite + +instance {β : α → Type*} [Finite α] [∀ a, Finite (β a)] : Finite (Σa, β a) := by + letI := Fintype.ofFinite α + letI := fun a => Fintype.ofFinite (β a) + infer_instance + +instance {ι : Sort*} {π : ι → Sort*} [Finite ι] [∀ i, Finite (π i)] : Finite (Σ'i, π i) := + of_equiv _ (Equiv.psigmaEquivSigmaPLift π).symm + +end Finite diff --git a/Mathlib/Data/Finite/Sum.lean b/Mathlib/Data/Finite/Sum.lean new file mode 100644 index 00000000000000..177f8e038134a3 --- /dev/null +++ b/Mathlib/Data/Finite/Sum.lean @@ -0,0 +1,27 @@ +/- +Copyright (c) 2022 Kyle Miller. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Kyle Miller +-/ +import Mathlib.Data.Fintype.Sum + +/-! +# Finiteness of sum types +-/ + +variable {α β : Type*} + +namespace Finite + +instance [Finite α] [Finite β] : Finite (α ⊕ β) := by + haveI := Fintype.ofFinite α + haveI := Fintype.ofFinite β + infer_instance + +theorem sum_left (β) [Finite (α ⊕ β)] : Finite α := + of_injective (Sum.inl : α → α ⊕ β) Sum.inl_injective + +theorem sum_right (α) [Finite (α ⊕ β)] : Finite β := + of_injective (Sum.inr : β → α ⊕ β) Sum.inr_injective + +end Finite diff --git a/Mathlib/Data/Finite/Vector.lean b/Mathlib/Data/Finite/Vector.lean new file mode 100644 index 00000000000000..9beba5adef6831 --- /dev/null +++ b/Mathlib/Data/Finite/Vector.lean @@ -0,0 +1,15 @@ +/- +Copyright (c) 2022 Kyle Miller. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Kyle Miller +-/ +import Mathlib.Data.Fintype.Vector +import Mathlib.Data.Fintype.Card + +/-! +# Finiteness of vector types +-/ + +instance Mathlib.Vector.finite {α : Type*} [Finite α] {n : ℕ} : Finite (Vector α n) := by + haveI := Fintype.ofFinite α + infer_instance diff --git a/Mathlib/Data/Finset/Preimage.lean b/Mathlib/Data/Finset/Preimage.lean index 520e3ea422f204..5a78ba233b2d20 100644 --- a/Mathlib/Data/Finset/Preimage.lean +++ b/Mathlib/Data/Finset/Preimage.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Johannes Hölzl, Mario Carneiro -/ import Mathlib.Data.Set.Finite +import Mathlib.Data.Finset.Sum /-! # Preimage of a `Finset` under an injective map. diff --git a/Mathlib/Data/FunLike/Fintype.lean b/Mathlib/Data/FunLike/Fintype.lean index e8d4b935941a6c..cafeb127772dd1 100644 --- a/Mathlib/Data/FunLike/Fintype.lean +++ b/Mathlib/Data/FunLike/Fintype.lean @@ -3,9 +3,9 @@ Copyright (c) 2022 Anne Baanen. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Anne Baanen -/ -import Mathlib.Data.Finite.Basic import Mathlib.Data.Fintype.Basic import Mathlib.Data.FunLike.Basic +import Mathlib.Data.Finite.Prod /-! # Finiteness of `DFunLike` types diff --git a/Mathlib/Data/Set/Finite.lean b/Mathlib/Data/Set/Finite.lean index 32b8fcd009e0f1..cdbea2da573220 100644 --- a/Mathlib/Data/Set/Finite.lean +++ b/Mathlib/Data/Set/Finite.lean @@ -3,10 +3,15 @@ Copyright (c) 2017 Johannes Hölzl. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Johannes Hölzl, Mario Carneiro, Kyle Miller -/ -import Mathlib.Data.Finite.Basic import Mathlib.Data.Finset.Max import Mathlib.Data.Set.Functor import Mathlib.Data.Set.Lattice +import Mathlib.Data.Finite.Powerset +import Mathlib.Data.Finite.Prod +import Mathlib.Data.Finite.Sigma +import Mathlib.Data.Finite.Vector +import Mathlib.Data.Finite.Basic +import Mathlib.Logic.Embedding.Set /-! # Finite sets @@ -1574,7 +1579,7 @@ end LinearOrder namespace List variable (α) [Finite α] (n : ℕ) -lemma finite_length_eq : {l : List α | l.length = n}.Finite := Vector.finite +lemma finite_length_eq : {l : List α | l.length = n}.Finite := Mathlib.Vector.finite lemma finite_length_lt : {l : List α | l.length < n}.Finite := by convert (Finset.range n).finite_toSet.biUnion fun i _ ↦ finite_length_eq α i; ext; simp diff --git a/Mathlib/GroupTheory/Abelianization.lean b/Mathlib/GroupTheory/Abelianization.lean index 46351f703f1ebd..b4f47685efdc92 100644 --- a/Mathlib/GroupTheory/Abelianization.lean +++ b/Mathlib/GroupTheory/Abelianization.lean @@ -6,6 +6,7 @@ Authors: Kenny Lau, Michael Howes import Mathlib.Data.Finite.Card import Mathlib.GroupTheory.Finiteness import Mathlib.GroupTheory.Commutator.Basic +import Mathlib.Data.Finite.Basic /-! # The abelianization of a group diff --git a/Mathlib/GroupTheory/GroupAction/Quotient.lean b/Mathlib/GroupTheory/GroupAction/Quotient.lean index 8d5f1ebb80f808..3babc32ec40718 100644 --- a/Mathlib/GroupTheory/GroupAction/Quotient.lean +++ b/Mathlib/GroupTheory/GroupAction/Quotient.lean @@ -10,6 +10,7 @@ import Mathlib.GroupTheory.GroupAction.Hom import Mathlib.GroupTheory.Coset.Basic import Mathlib.GroupTheory.Commutator.Basic import Mathlib.Algebra.Group.Subgroup.Actions +import Mathlib.Data.Finite.Basic /-! # Properties of group actions involving quotient groups diff --git a/Mathlib/GroupTheory/Perm/Finite.lean b/Mathlib/GroupTheory/Perm/Finite.lean index 4c4f0cfef47b79..e7ead8ca2a46cd 100644 --- a/Mathlib/GroupTheory/Perm/Finite.lean +++ b/Mathlib/GroupTheory/Perm/Finite.lean @@ -8,6 +8,7 @@ import Mathlib.Data.Int.Order.Units import Mathlib.GroupTheory.OrderOfElement import Mathlib.GroupTheory.Perm.Support import Mathlib.Logic.Equiv.Fintype +import Mathlib.Data.Finite.Sum /-! # Permutations on `Fintype`s diff --git a/Mathlib/GroupTheory/Perm/Sign.lean b/Mathlib/GroupTheory/Perm/Sign.lean index f40786fe4064c9..98b302cba6c58f 100644 --- a/Mathlib/GroupTheory/Perm/Sign.lean +++ b/Mathlib/GroupTheory/Perm/Sign.lean @@ -7,6 +7,7 @@ import Mathlib.Algebra.Group.Subgroup.Basic import Mathlib.Algebra.Group.Submonoid.Membership import Mathlib.Data.Finset.Fin import Mathlib.Data.Finset.Sort +import Mathlib.Data.Fintype.Sum import Mathlib.Data.Int.Order.Units import Mathlib.GroupTheory.Perm.Support import Mathlib.Logic.Equiv.Fin diff --git a/Mathlib/GroupTheory/SpecificGroups/Dihedral.lean b/Mathlib/GroupTheory/SpecificGroups/Dihedral.lean index 843bcfd6e14855..3618172616b02a 100644 --- a/Mathlib/GroupTheory/SpecificGroups/Dihedral.lean +++ b/Mathlib/GroupTheory/SpecificGroups/Dihedral.lean @@ -6,6 +6,7 @@ Authors: Shing Tak Lam import Mathlib.Data.ZMod.Basic import Mathlib.GroupTheory.Exponent import Mathlib.GroupTheory.GroupAction.CardCommute +import Mathlib.Data.Finite.Sum /-! # Dihedral Groups diff --git a/Mathlib/LinearAlgebra/Matrix/ToLin.lean b/Mathlib/LinearAlgebra/Matrix/ToLin.lean index 803a75b7be1493..de60812076e723 100644 --- a/Mathlib/LinearAlgebra/Matrix/ToLin.lean +++ b/Mathlib/LinearAlgebra/Matrix/ToLin.lean @@ -8,6 +8,7 @@ import Mathlib.Data.Matrix.Notation import Mathlib.LinearAlgebra.StdBasis import Mathlib.RingTheory.AlgebraTower import Mathlib.Algebra.Algebra.Subalgebra.Tower +import Mathlib.Data.Finite.Sum /-! # Linear maps and matrices diff --git a/Mathlib/ModelTheory/DirectLimit.lean b/Mathlib/ModelTheory/DirectLimit.lean index 496585e0014ae5..295d49fb6ebf96 100644 --- a/Mathlib/ModelTheory/DirectLimit.lean +++ b/Mathlib/ModelTheory/DirectLimit.lean @@ -7,6 +7,7 @@ import Mathlib.Data.Fintype.Order import Mathlib.Algebra.DirectLimit import Mathlib.ModelTheory.Quotients import Mathlib.ModelTheory.FinitelyGenerated +import Mathlib.Data.Finite.Sum /-! # Direct Limits of First-Order Structures From 43a210eec459e77414f2868eb3bac16deadd6ef3 Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Wed, 16 Oct 2024 04:44:12 +0000 Subject: [PATCH 191/425] Trigger CI for https://github.com/leanprover/lean4/pull/5694 --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 7ca16287fbf192..55dbc2bf8da771 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "e8c146e77ce3c575c3966766f9d4f9ca4366f566", + "rev": "2d87b4e8b42309949f61b9545d1510f7fe7ad9b7", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "lean-pr-testing-5694", From 7a8cf3c4b324fbfaf375dccf41c5be3c3099c3bb Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Wed, 16 Oct 2024 05:50:11 +0000 Subject: [PATCH 192/425] feat(AlgebraicGeometry/RingHomProperties): a property induced from `Locally Q` is equivalent to locally `Q` (#17305) If `P` is a morphism property of schemes associated to the property `Locally Q` for a property of ring homomorphisms `Q`, then for a morphism `f`, `P f` is equivalent to: for every point `x` in the source there exist open affine neighborhoods around `x` and `f.val.base x` respectively such that the induced map of rings satisfies `Q`. This guarantees that we may define properties of scheme morphisms explicitly as described above for properties of ring homomorphisms that are not necessarily local at the target and still use the API for `HasRingHomProperty`. --- .../Morphisms/RingHomProperties.lean | 57 ++++++++++++++++--- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean b/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean index 9a5b418ed0cd6a..93a2ff38a6b0a7 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean @@ -5,6 +5,7 @@ Authors: Andrew Yang -/ import Mathlib.AlgebraicGeometry.Morphisms.Basic import Mathlib.RingTheory.LocalProperties.Basic +import Mathlib.RingTheory.RingHom.Locally /-! @@ -182,6 +183,17 @@ namespace HasRingHomProperty variable (P : MorphismProperty Scheme.{u}) {Q} [HasRingHomProperty P Q] variable {X Y Z : Scheme.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) +lemma copy {P' : MorphismProperty Scheme.{u}} + {Q' : ∀ {R S : Type u} [CommRing R] [CommRing S], (R →+* S) → Prop} + (e : P = P') (e' : ∀ {R S : Type u} [CommRing R] [CommRing S] (f : R →+* S), Q f ↔ Q' f) : + HasRingHomProperty P' Q' := by + subst e + have heq : @Q = @Q' := by + ext R S _ _ f + exact (e' f) + rw [← heq] + infer_instance + lemma eq_affineLocally : P = affineLocally Q := eq_affineLocally' @[local instance] @@ -416,25 +428,52 @@ instance respects_isOpenImmersion : P.Respects @IsOpenImmersion where rw [show f ≫ i = f ≫ e.hom ≫ i.opensRange.ι by simp [e], ← Category.assoc] exact respects_isOpenImmersion_aux _ (by rwa [P.cancel_right_of_respectsIso]) -open RingHom in -/-- `P` can be checked locally around points of the source. -/ -lemma iff_exists_appLE : P f ↔ - ∀ (x : X), ∃ (U : Y.affineOpens) (V : X.affineOpens) (_ : x ∈ V.1) (e : V.1 ≤ f ⁻¹ᵁ U.1), +open RingHom + +omit [HasRingHomProperty P Q] in +/-- If `P` is induced by `Locally Q`, it suffices to check `Q` on affine open sets locally around +points of the source. -/ +lemma iff_exists_appLE_locally (hQi : RespectsIso Q) [HasRingHomProperty P (Locally 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) := by refine ⟨fun hf x ↦ ?_, fun hf ↦ (IsLocalAtSource.iff_exists_resLE (P := P)).mpr <| fun x ↦ ?_⟩ · obtain ⟨U, hU, hfx, _⟩ := Opens.isBasis_iff_nbhd.mp (isBasis_affine_open Y) (Opens.mem_top <| f.val.base x) obtain ⟨V, hV, hx, e⟩ := Opens.isBasis_iff_nbhd.mp (isBasis_affine_open X) (show x ∈ f ⁻¹ᵁ U from hfx) - use ⟨U, hU⟩, ⟨V, hV⟩, hx, e - apply appLE P f hf + simp_rw [HasRingHomProperty.iff_appLE (P := P), locally_iff_isLocalization hQi] at hf + obtain ⟨s, hs, hfs⟩ := hf ⟨U, hU⟩ ⟨V, hV⟩ e + apply iSup_basicOpen_of_span_eq_top at hs + have : x ∈ (⨆ i ∈ s, X.basicOpen i) := hs.symm ▸ hx + have : ∃ r ∈ s, x ∈ X.basicOpen r := by simpa using this + 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 + 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 Q).RespectsIso := toMorphismProperty_respectsIso_iff.mp <| + haveI : (toMorphismProperty (Locally Q)).RespectsIso := toMorphismProperty_respectsIso_iff.mp <| (isLocal_ringHomProperty P).respectsIso - exact (MorphismProperty.arrow_mk_iso_iff (toMorphismProperty Q) (arrowResLEAppIso f U V e)).mpr - hf + exact (MorphismProperty.arrow_mk_iso_iff (toMorphismProperty (Locally Q)) + (arrowResLEAppIso f U V e)).mpr (locally_of hQi _ hf) + +/-- `P` can be checked locally around points of the source. -/ +lemma iff_exists_appLE : 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) := by + haveI inst : HasRingHomProperty P Q := inferInstance + haveI : HasRingHomProperty P (Locally Q) := by + apply @copy (P' := P) (Q := Q) (Q' := Locally Q) + · infer_instance + · rfl + · intro R S _ _ f + exact (locally_iff_of_localizationSpanTarget (isLocal_ringHomProperty P).respectsIso + (isLocal_ringHomProperty P).OfLocalizationSpanTarget _).symm + rw [iff_exists_appLE_locally (P := P) ] + haveI : HasRingHomProperty P Q := inst + apply (isLocal_ringHomProperty P (Q := Q)).respectsIso end HasRingHomProperty From b3db14fd6ff41d064b5c86d29fb7749d24a3347b Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Wed, 16 Oct 2024 05:50:13 +0000 Subject: [PATCH 193/425] feat(CategoryTheory/Sites): infima of pretopologies (#17734) Defines a complete lattice structure on pretopologies with good definitional properties for bottom, top and infima. --- .../CategoryTheory/Sites/Grothendieck.lean | 5 ++ Mathlib/CategoryTheory/Sites/Pretopology.lean | 66 ++++++++++++++++++- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/Mathlib/CategoryTheory/Sites/Grothendieck.lean b/Mathlib/CategoryTheory/Sites/Grothendieck.lean index aaf3d4a203a5ba..c29e44a6f4bf37 100644 --- a/Mathlib/CategoryTheory/Sites/Grothendieck.lean +++ b/Mathlib/CategoryTheory/Sites/Grothendieck.lean @@ -260,6 +260,11 @@ instance : InfSet (GrothendieckTopology C) where apply J.transitive (hS _ ⟨⟨_, _, hJ, rfl⟩, rfl⟩) _ fun Y f hf => h hf _ ⟨⟨_, _, hJ, rfl⟩, rfl⟩ } +lemma mem_sInf (s : Set (GrothendieckTopology C)) {X : C} (S : Sieve X) : + S ∈ sInf s X ↔ ∀ t ∈ s, S ∈ t X := by + show S ∈ sInf (sieves '' s) X ↔ _ + simp + /-- See -/ theorem isGLB_sInf (s : Set (GrothendieckTopology C)) : IsGLB s (sInf s) := by refine @IsGLB.of_image _ _ _ _ sieves ?_ _ _ ?_ diff --git a/Mathlib/CategoryTheory/Sites/Pretopology.lean b/Mathlib/CategoryTheory/Sites/Pretopology.lean index a70e13cc0de8b4..85b5f87c3c0a87 100644 --- a/Mathlib/CategoryTheory/Sites/Pretopology.lean +++ b/Mathlib/CategoryTheory/Sites/Pretopology.lean @@ -87,7 +87,7 @@ instance : PartialOrder (Pretopology C) := le_trans := fun _ _ _ h₁₂ h₂₃ => le_def.mpr (le_trans h₁₂ h₂₃) le_antisymm := fun _ _ h₁₂ h₂₁ => Pretopology.ext (le_antisymm h₁₂ h₂₁) } -instance : OrderTop (Pretopology C) where +instance orderTop : OrderTop (Pretopology C) where top := { coverings := fun _ => Set.univ has_isos := fun _ _ _ _ => Set.mem_univ _ @@ -156,6 +156,10 @@ def gi : GaloisInsertion (toGrothendieck C) (ofGrothendieck C) where choice x _ := toGrothendieck C x choice_eq _ _ := rfl +lemma mem_ofGrothendieck (t : GrothendieckTopology C) {X : C} (S : Presieve X) : + S ∈ ofGrothendieck C t X ↔ Sieve.generate S ∈ t X := + Iff.rfl + /-- The trivial pretopology, in which the coverings are exactly singleton isomorphisms. This topology is also known as the indiscrete, coarse, or chaotic topology. @@ -194,7 +198,7 @@ def trivial : Pretopology C where rw [hTi] apply singleton.mk -instance : OrderBot (Pretopology C) where +instance orderBot : OrderBot (Pretopology C) where bot := trivial C bot_le K X R := by rintro ⟨Y, f, hf, rfl⟩ @@ -204,6 +208,64 @@ instance : OrderBot (Pretopology C) where theorem toGrothendieck_bot : toGrothendieck C ⊥ = ⊥ := (gi C).gc.l_bot +instance : InfSet (Pretopology C) where + sInf T := { + coverings := sInf (coverings '' T) + has_isos := fun X Y f _ ↦ by + simp only [sInf_apply, Set.iInf_eq_iInter, Set.iInter_coe_set, Set.mem_image, + Set.iInter_exists, + Set.biInter_and', Set.iInter_iInter_eq_right, Set.mem_iInter] + intro t _ + exact t.has_isos f + pullbacks := fun X Y f S hS ↦ by + simp only [sInf_apply, Set.iInf_eq_iInter, Set.iInter_coe_set, Set.mem_image, + Set.iInter_exists, Set.biInter_and', Set.iInter_iInter_eq_right, Set.mem_iInter] at hS ⊢ + intro t ht + exact t.pullbacks f S (hS t ht) + transitive := fun X S Ti hS hTi ↦ by + simp only [sInf_apply, Set.iInf_eq_iInter, Set.iInter_coe_set, Set.mem_image, + Set.iInter_exists, Set.biInter_and', Set.iInter_iInter_eq_right, Set.mem_iInter] at hS hTi ⊢ + intro t ht + exact t.transitive S Ti (hS t ht) (fun Y f H ↦ hTi f H t ht) + } + +lemma mem_sInf (T : Set (Pretopology C)) {X : C} (S : Presieve X) : + S ∈ sInf T X ↔ ∀ t ∈ T, S ∈ t X := by + show S ∈ sInf (Pretopology.coverings '' T) X ↔ _ + simp + +lemma sInf_ofGrothendieck (T : Set (GrothendieckTopology C)) : + ofGrothendieck C (sInf T) = sInf (ofGrothendieck C '' T) := by + ext X S + simp [mem_sInf, mem_ofGrothendieck, GrothendieckTopology.mem_sInf] + +lemma isGLB_sInf (T : Set (Pretopology C)) : IsGLB T (sInf T) := + IsGLB.of_image (f := coverings) Iff.rfl (_root_.isGLB_sInf _) + +/-- The complete lattice structure on pretopologies. This is induced by the `InfSet` instance, but +with good definitional equalities for `⊥`, `⊤` and `⊓`. -/ +instance : CompleteLattice (Pretopology C) where + __ := orderBot C + __ := orderTop C + inf t₁ t₂ := { + coverings := fun X ↦ t₁.coverings X ∩ t₂.coverings X + has_isos := fun _ _ f _ ↦ + ⟨t₁.has_isos f, t₂.has_isos f⟩ + pullbacks := fun _ _ f S hS ↦ + ⟨t₁.pullbacks f S hS.left, t₂.pullbacks f S hS.right⟩ + transitive := fun _ S Ti hS hTi ↦ + ⟨t₁.transitive S Ti hS.left (fun _ f H ↦ (hTi f H).left), + t₂.transitive S Ti hS.right (fun _ f H ↦ (hTi f H).right)⟩ + } + inf_le_left _ _ _ _ hS := hS.left + inf_le_right _ _ _ _ hS := hS.right + le_inf _ _ _ hts htr X _ hS := ⟨hts X hS, htr X hS⟩ + __ := completeLatticeOfInf _ (isGLB_sInf C) + +lemma mem_inf (t₁ t₂ : Pretopology C) {X : C} (S : Presieve X) : + S ∈ (t₁ ⊓ t₂) X ↔ S ∈ t₁ X ∧ S ∈ t₂ X := + Iff.rfl + end Pretopology end CategoryTheory From a5bdd27269ae4202c997b47d7879fc90089abbe6 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 05:50:14 +0000 Subject: [PATCH 194/425] chore: deprecate Fin.ofNat'' (#17759) Now that `NeZero` is in Lean, `Fin.ofNat'` already means the right thing. --- Mathlib/Algebra/Group/Fin/Basic.lean | 2 +- Mathlib/Data/Fin/Basic.lean | 15 +++------------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/Mathlib/Algebra/Group/Fin/Basic.lean b/Mathlib/Algebra/Group/Fin/Basic.lean index 9385f63b707219..06f0bb2f7ad67a 100644 --- a/Mathlib/Algebra/Group/Fin/Basic.lean +++ b/Mathlib/Algebra/Group/Fin/Basic.lean @@ -43,7 +43,7 @@ instance addCommMonoid (n : ℕ) [NeZero n] : AddCommMonoid (Fin n) where instance instAddMonoidWithOne (n) [NeZero n] : AddMonoidWithOne (Fin n) where __ := inferInstanceAs (AddCommMonoid (Fin n)) - natCast n := Fin.ofNat'' n + natCast i := Fin.ofNat' n i natCast_zero := rfl natCast_succ _ := Fin.ext (add_mod _ _ _) diff --git a/Mathlib/Data/Fin/Basic.lean b/Mathlib/Data/Fin/Basic.lean index edc71f8ff4d06c..0da69a90e9ab73 100644 --- a/Mathlib/Data/Fin/Basic.lean +++ b/Mathlib/Data/Fin/Basic.lean @@ -242,14 +242,12 @@ instance {n : ℕ} : WellFoundedRelation (Fin n) := measure (val : Fin n → ℕ) /-- Given a positive `n`, `Fin.ofNat' i` is `i % n` as an element of `Fin n`. -/ +@[deprecated Fin.ofNat' (since := "2024-10-15")] def ofNat'' [NeZero n] (i : ℕ) : Fin n := ⟨i % n, mod_lt _ n.pos_of_neZero⟩ -- Porting note: `Fin.ofNat'` conflicts with something in core (there the hypothesis is `n > 0`), -- so for now we make this double-prime `''`. This is also the reason for the dubious translation. -instance {n : ℕ} [NeZero n] : Zero (Fin n) := ⟨ofNat'' 0⟩ -instance {n : ℕ} [NeZero n] : One (Fin n) := ⟨ofNat'' 1⟩ - /-- The `Fin.val_zero` in `Lean` only applies in `Fin (n+1)`. This one instead uses a `NeZero n` typeclass hypothesis. @@ -422,15 +420,8 @@ instance inhabitedFinOneAdd (n : ℕ) : Inhabited (Fin (1 + n)) := theorem default_eq_zero (n : ℕ) [NeZero n] : (default : Fin n) = 0 := rfl -section from_ad_hoc - -@[simp] lemma ofNat'_zero [NeZero n] : (Fin.ofNat' n 0) = 0 := rfl -@[simp] lemma ofNat'_one [NeZero n] : (Fin.ofNat' n 1) = 1 := rfl - -end from_ad_hoc - instance instNatCast [NeZero n] : NatCast (Fin n) where - natCast n := Fin.ofNat'' n + natCast i := Fin.ofNat' n i lemma natCast_def [NeZero n] (a : ℕ) : (a : Fin n) = ⟨a % n, mod_lt _ n.pos_of_neZero⟩ := rfl @@ -445,7 +436,7 @@ theorem val_add_eq_ite {n : ℕ} (a b : Fin n) : section OfNatCoe @[simp] -theorem ofNat''_eq_cast (n : ℕ) [NeZero n] (a : ℕ) : (Fin.ofNat'' a : Fin n) = a := +theorem ofNat'_eq_cast (n : ℕ) [NeZero n] (a : ℕ) : Fin.ofNat' n a = a := rfl @[simp] lemma val_natCast (a n : ℕ) [NeZero n] : (a : Fin n).val = a % n := rfl From 0f1371d67efe19c44b0c3eac124b31b367ecc86c Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Wed, 16 Oct 2024 06:05:26 +0000 Subject: [PATCH 195/425] Update lean-toolchain for testing https://github.com/leanprover/lean4/pull/5732 --- lake-manifest.json | 4 ++-- lakefile.lean | 2 +- lean-toolchain | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index 824bd6242b29c2..f78f6b6678ef38 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,10 +5,10 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "4def8ae307885daef61c66aa5fa95b6377aa5eff", + "rev": "61207caf0c8f87fc4c00901d356d2a37ebef7e5b", "name": "batteries", "manifestFile": "lake-manifest.json", - "inputRev": "nightly-testing", + "inputRev": "lean-pr-testing-5732", "inherited": false, "configFile": "lakefile.lean"}, {"url": "https://github.com/leanprover-community/quote4", diff --git a/lakefile.lean b/lakefile.lean index ac51402c176115..5274787473c484 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -7,7 +7,7 @@ open Lake DSL ## Mathlib dependencies on upstream projects -/ -require "leanprover-community" / "batteries" @ git "nightly-testing" +require "leanprover-community" / "batteries" @ git "lean-pr-testing-5732" require "leanprover-community" / "Qq" @ git "master" require "leanprover-community" / "aesop" @ git "master" require "leanprover-community" / "proofwidgets" @ git "v0.0.43-pre" diff --git a/lean-toolchain b/lean-toolchain index af6a54a1b05087..7797d846438132 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-15 +leanprover/lean4-pr-releases:pr-release-5732 From df5c26a578844ce5683f016b2299821b4dd9f7d1 Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Wed, 16 Oct 2024 06:07:32 +0000 Subject: [PATCH 196/425] Update lean-toolchain for testing https://github.com/leanprover/lean4/pull/5731 --- lake-manifest.json | 4 ++-- lakefile.lean | 2 +- lean-toolchain | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index 824bd6242b29c2..35d3524d139f96 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,10 +5,10 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "4def8ae307885daef61c66aa5fa95b6377aa5eff", + "rev": "f46281aa070a896c28f7f41da460fe93448dd4b6", "name": "batteries", "manifestFile": "lake-manifest.json", - "inputRev": "nightly-testing", + "inputRev": "lean-pr-testing-5731", "inherited": false, "configFile": "lakefile.lean"}, {"url": "https://github.com/leanprover-community/quote4", diff --git a/lakefile.lean b/lakefile.lean index ac51402c176115..688c43af3b207f 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -7,7 +7,7 @@ open Lake DSL ## Mathlib dependencies on upstream projects -/ -require "leanprover-community" / "batteries" @ git "nightly-testing" +require "leanprover-community" / "batteries" @ git "lean-pr-testing-5731" require "leanprover-community" / "Qq" @ git "master" require "leanprover-community" / "aesop" @ git "master" require "leanprover-community" / "proofwidgets" @ git "v0.0.43-pre" diff --git a/lean-toolchain b/lean-toolchain index af6a54a1b05087..0be20ac17cd3ed 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-15 +leanprover/lean4-pr-releases:pr-release-5731 From 9a958e834a5a2be5d704777f1e7dcf7c728f0888 Mon Sep 17 00:00:00 2001 From: Riccardo Brasca Date: Wed, 16 Oct 2024 06:24:48 +0000 Subject: [PATCH 197/425] doc: clarify doc of `Module.finrank` (#17780) --- Mathlib/LinearAlgebra/Dimension/Finrank.lean | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mathlib/LinearAlgebra/Dimension/Finrank.lean b/Mathlib/LinearAlgebra/Dimension/Finrank.lean index 69668ef8b667a3..b702b49f38f5c6 100644 --- a/Mathlib/LinearAlgebra/Dimension/Finrank.lean +++ b/Mathlib/LinearAlgebra/Dimension/Finrank.lean @@ -48,6 +48,9 @@ Defined by convention to be `0` if the space has infinite rank. For a vector space `M` over a field `R`, this is the same as the finite dimension of `M` over `R`. + +Note that it is possible to have `M` with `¬(Module.Finite R M)` but `finrank R M ≠ 0`, for example +`ℤ × ℚ/ℤ` has `finrank` equal to `1`. -/ noncomputable def finrank (R M : Type*) [Semiring R] [AddCommGroup M] [Module R M] : ℕ := Cardinal.toNat (Module.rank R M) From e398204ea3e5001b88c0c7f48e736664a9f0a235 Mon Sep 17 00:00:00 2001 From: Moritz Firsching Date: Wed, 16 Oct 2024 07:57:08 +0000 Subject: [PATCH 198/425] feat(NumberTheory/Fermat): fermat_eq_fermat_sub_one_pow_two_add_one (#17611) - [x] depends on: #17618 Co-authored-by: Moritz Firsching --- Mathlib/NumberTheory/Fermat.lean | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mathlib/NumberTheory/Fermat.lean b/Mathlib/NumberTheory/Fermat.lean index 0fcd105b0a6009..5fe9b6b32bc736 100644 --- a/Mathlib/NumberTheory/Fermat.lean +++ b/Mathlib/NumberTheory/Fermat.lean @@ -58,6 +58,10 @@ theorem fermatNumber_eq_prod_add_two (n : ℕ) : rw [fermatNumber_product, Nat.sub_add_cancel] exact le_of_lt <| two_lt_fermatNumber _ +theorem fermatNumber_succ (n : ℕ) : fermatNumber (n + 1) = (fermatNumber n - 1) ^ 2 + 1 := by + rw [fermatNumber, pow_succ, mul_comm, Nat.pow_mul'] + rfl + /-- **Goldbach's theorem** : no two distinct Fermat numbers share a common factor greater than one. From 765ccc9135f3ebeec047798d6c715dc3224c0c73 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 07:57:09 +0000 Subject: [PATCH 199/425] chore: update overview to use Std.HashMap, not Batteries.HashMap (#17797) --- docs/overview.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/overview.yaml b/docs/overview.yaml index d020bc5328e44b..7113041d2dfc9d 100644 --- a/docs/overview.yaml +++ b/docs/overview.yaml @@ -468,7 +468,7 @@ Data structures: Maps: key-value map: 'AList' red-black map: 'Batteries.RBMap' - hash map: 'Batteries.HashMap' + hash map: 'Std.HashMap' finitely supported function: 'Finsupp' finite map: 'Finmap' From d0bd67ca03873ffdd6ba93ead902fa5087e36740 Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Wed, 16 Oct 2024 08:24:38 +0000 Subject: [PATCH 200/425] chore: bump to nightly-2024-10-16 --- lean-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lean-toolchain b/lean-toolchain index af6a54a1b05087..c7e012c64aaed0 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-15 +leanprover/lean4:nightly-2024-10-16 From f38babeaf882777867f57167bb35d3695d1c513f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Wed, 16 Oct 2024 08:26:02 +0000 Subject: [PATCH 201/425] feat: `comap` of a finite measure along a measurable equiv is finite (#17639) From PFR --- Mathlib/MeasureTheory/Measure/MeasureSpace.lean | 4 ++++ Mathlib/MeasureTheory/Measure/Typeclasses.lean | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/Mathlib/MeasureTheory/Measure/MeasureSpace.lean b/Mathlib/MeasureTheory/Measure/MeasureSpace.lean index 2bbeba47597478..6068dcd58e2748 100644 --- a/Mathlib/MeasureTheory/Measure/MeasureSpace.lean +++ b/Mathlib/MeasureTheory/Measure/MeasureSpace.lean @@ -1029,6 +1029,10 @@ instance [NeZero μ] : NeZero (μ univ) := ⟨measure_univ_ne_zero.2 <| NeZero.n theorem measure_univ_pos : 0 < μ univ ↔ μ ≠ 0 := pos_iff_ne_zero.trans measure_univ_ne_zero +lemma nonempty_of_neZero (μ : Measure α) [NeZero μ] : Nonempty α := + (isEmpty_or_nonempty α).resolve_left fun h ↦ by + simpa [eq_empty_of_isEmpty] using NeZero.ne (μ univ) + /-! ### Pushforward and pullback -/ diff --git a/Mathlib/MeasureTheory/Measure/Typeclasses.lean b/Mathlib/MeasureTheory/Measure/Typeclasses.lean index fb5f43b48b9f27..e84781a13f0595 100644 --- a/Mathlib/MeasureTheory/Measure/Typeclasses.lean +++ b/Mathlib/MeasureTheory/Measure/Typeclasses.lean @@ -122,6 +122,14 @@ theorem Measure.isFiniteMeasure_map {m : MeasurableSpace α} (μ : Measure α) [ · rw [map_of_not_aemeasurable hf] exact MeasureTheory.isFiniteMeasureZero +instance IsFiniteMeasure_comap (f : β → α) [IsFiniteMeasure μ] : IsFiniteMeasure (μ.comap f) where + measure_univ_lt_top := by + by_cases hf : Injective f ∧ ∀ s, MeasurableSet s → NullMeasurableSet (f '' s) μ + · rw [Measure.comap_apply₀ _ _ hf.1 hf.2 MeasurableSet.univ.nullMeasurableSet] + exact measure_lt_top μ _ + · rw [Measure.comap, dif_neg hf] + exact zero_lt_top + @[simp] theorem measureUnivNNReal_eq_zero [IsFiniteMeasure μ] : measureUnivNNReal μ = 0 ↔ μ = 0 := by rw [← MeasureTheory.Measure.measure_univ_eq_zero, ← coe_measureUnivNNReal] @@ -277,6 +285,9 @@ theorem isProbabilityMeasure_map {f : α → β} (hf : AEMeasurable f μ) : IsProbabilityMeasure (map f μ) := ⟨by simp [map_apply_of_aemeasurable, hf]⟩ +instance IsProbabilityMeasure_comap_equiv (f : β ≃ᵐ α) : IsProbabilityMeasure (μ.comap f) := by + rw [← MeasurableEquiv.map_symm]; exact isProbabilityMeasure_map f.symm.measurable.aemeasurable + /-- Note that this is not quite as useful as it looks because the measure takes values in `ℝ≥0∞`. Thus the subtraction appearing is the truncated subtraction of `ℝ≥0∞`, rather than the better-behaved subtraction of `ℝ`. -/ From b913345e5847bd22f23ab83b6256654095f161eb Mon Sep 17 00:00:00 2001 From: Robin Carlier <57142648+robin-carlier@users.noreply.github.com> Date: Wed, 16 Oct 2024 08:40:45 +0000 Subject: [PATCH 202/425] feat(CategoryTheory/Limits): definition of sifted categories (#17779) Introduce the class of sifted categories. A category `IsSifted` if it is nonempty and the diagonal functor is a final functor. - Show that sifted categories are stable under equivalences of categories. - Show that a category is sifted if and only if a small model of it is sifted. - Show that a sifted category is connected. - Show that a category with binary coproducts is sifted. --- Mathlib.lean | 1 + Mathlib/CategoryTheory/Limits/Sifted.lean | 104 ++++++++++++++++++++++ docs/references.bib | 11 +++ 3 files changed, 116 insertions(+) create mode 100644 Mathlib/CategoryTheory/Limits/Sifted.lean diff --git a/Mathlib.lean b/Mathlib.lean index e2a1e20cdd35a5..4145efbc9c714a 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1708,6 +1708,7 @@ import Mathlib.CategoryTheory.Limits.Shapes.WideEqualizers import Mathlib.CategoryTheory.Limits.Shapes.WidePullbacks import Mathlib.CategoryTheory.Limits.Shapes.ZeroMorphisms import Mathlib.CategoryTheory.Limits.Shapes.ZeroObjects +import Mathlib.CategoryTheory.Limits.Sifted import Mathlib.CategoryTheory.Limits.SmallComplete import Mathlib.CategoryTheory.Limits.Types import Mathlib.CategoryTheory.Limits.TypesFiltered diff --git a/Mathlib/CategoryTheory/Limits/Sifted.lean b/Mathlib/CategoryTheory/Limits/Sifted.lean new file mode 100644 index 00000000000000..0949b037550c1d --- /dev/null +++ b/Mathlib/CategoryTheory/Limits/Sifted.lean @@ -0,0 +1,104 @@ +/- +Copyright (c) 2024 Robin Carlier. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Robin Carlier +-/ +import Mathlib.CategoryTheory.Limits.Final +/-! +# Sifted categories + +A category `C` is sifted if `C` is nonempty and the diagonal functor `C ⥤ C × C` is final. +Sifted categories can be characterized as those such that the colimit functor `(C ⥤ Type) ⥤ Type ` +preserves finite products. + +## Main results +- `isSifted_of_hasBinaryCoproducts_and_nonempty`: A nonempty category with binary coproducts is + sifted. + +## References +- [nLab, *Sifted category*](https://ncatlab.org/nlab/show/sifted+category) +- [*Algebraic Theories*, Chapter 2.][Adámek_Rosický_Vitale_2010] +-/ + +universe w v v₁ u u₁ + +namespace CategoryTheory + +open Limits Functor + +section + +variable (C : Type u) [Category.{v} C] + +/-- A category `C` `IsSiftedOrEmpty` if the diagonal functor `C ⥤ C × C` is final. -/ +abbrev IsSiftedOrEmpty : Prop := Final (diag C) + +/-- A category `C` `IsSfited` if +1. the diagonal functor `C ⥤ C × C` is final. +2. there exists some object. -/ +class IsSifted extends IsSiftedOrEmpty C : Prop where + [nonempty : Nonempty C] + +attribute [instance] IsSifted.nonempty + +namespace IsSifted + +variable {C} + +/-- 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 + 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)) + apply_rules [final_iff_comp_equivalence _ this.functor|>.mpr, + final_iff_final_comp e.inverse _ |>.mpr, final_of_natIso sq.symm] + letI : _root_.Nonempty D := ⟨e.inverse.obj (_root_.Nonempty.some IsSifted.nonempty)⟩ + ⟨⟩ + +/-- In particular a category is sifted iff and only if it is so when viewed as a small category -/ +lemma isSifted_iff_asSmallIsSifted : IsSifted C ↔ IsSifted (AsSmall.{w} C) where + mp _ := isSifted_of_equiv AsSmall.equiv.symm + mpr _ := isSifted_of_equiv AsSmall.equiv + +/-- A sifted category is connected. -/ +instance [IsSifted C] : IsConnected C := + isConnected_of_zigzag + (by intro c₁ c₂ + have X : StructuredArrow (c₁, c₂) (diag C) := + letI S : Final (diag C) := by infer_instance + Nonempty.some (S.out (c₁, c₂)).is_nonempty + use [X.right, c₂] + constructor + · constructor + · exact Zag.of_hom X.hom.fst + · simp + exact Zag.of_inv X.hom.snd + · rfl) + +/-- A category with binary coproducts is sifted or empty. -/ +instance [HasBinaryCoproducts C] : IsSiftedOrEmpty C := by + constructor + rintro ⟨c₁, c₂⟩ + haveI : _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⟩ + dsimp only [const_obj_obj, diag_obj, prod_Hom] at f g + use [.mk ((coprod.inl : c₁ ⟶ c₁ ⨿ c₂), (coprod.inr : c₂ ⟶ c₁ ⨿ c₂)), .mk (g.fst, g.snd)] + simp only [colimit.cocone_x, diag_obj, Prod.mk.eta, List.chain_cons, List.Chain.nil, and_true, + ne_eq, reduceCtorEq, not_false_eq_true, List.getLast_cons, List.cons_ne_self, + List.getLast_singleton] + exact ⟨⟨Zag.of_inv <| StructuredArrow.homMk <| coprod.desc f.fst f.snd, + Zag.of_hom <| StructuredArrow.homMk <| coprod.desc g.fst g.snd⟩, rfl⟩ + +/-- A nonempty category with binary coproducts is sifted. -/ +instance isSifted_of_hasBinaryCoproducts_and_nonempty [_root_.Nonempty C] [HasBinaryCoproducts C] : + IsSifted C where + +end IsSifted + +end + +end CategoryTheory diff --git a/docs/references.bib b/docs/references.bib index 67919e2ced15f7..39e500681a6499 100644 --- a/docs/references.bib +++ b/docs/references.bib @@ -34,6 +34,17 @@ @InProceedings{ adhesive2004 url = {https://www.ioc.ee/~pawel/papers/adhesive.pdf} } +@Book{ Adámek_Rosický_Vitale_2010, + place = {Cambridge}, + series = {Cambridge Tracts in Mathematics}, + title = {Algebraic Theories: A Categorical Introduction to General + Algebra}, + publisher = {Cambridge University Press}, + author = {Adámek, J. and Rosický, J. and Vitale, E. M.}, + year = {2010}, + collection = {Cambridge Tracts in Mathematics} +} + @Article{ ahrens2017, author = {Benedikt Ahrens and Peter LeFanu Lumsdaine}, year = {2019}, From 4564def38d31320ae5385d4d4463f4942bcbafc3 Mon Sep 17 00:00:00 2001 From: Quang Dao Date: Wed, 16 Oct 2024 08:50:02 +0000 Subject: [PATCH 203/425] chore(Multiset/Basic): added `gcongr` and `congr` to `Multiset` (#17793) While working on some theorems about `MvPolynomial.degrees`, I noticed that a lot of `Multiset` functions do not have `gcongr` or `congr` attributes. So I added them in this PR. Note: I only looked at the definitions in `Multiset/Basic`. If this PR is approved I will do the same for other functions in `Multiset` folder. Co-authored-by: Quang Dao --- Mathlib/Data/Multiset/Basic.lean | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/Mathlib/Data/Multiset/Basic.lean b/Mathlib/Data/Multiset/Basic.lean index b54ec18a4e5313..7dc4316f0e993a 100644 --- a/Mathlib/Data/Multiset/Basic.lean +++ b/Mathlib/Data/Multiset/Basic.lean @@ -864,6 +864,10 @@ theorem nsmul_singleton (a : α) (n) : n • ({a} : Multiset α) = replicate n a theorem replicate_le_replicate (a : α) {k n : ℕ} : replicate k a ≤ replicate n a ↔ k ≤ n := _root_.trans (by rw [← replicate_le_coe, coe_replicate]) (List.replicate_sublist_replicate a) +@[gcongr] +theorem replicate_mono (a : α) {k n : ℕ} (h : k ≤ n) : replicate k a ≤ replicate n a := + (replicate_le_replicate a).2 h + theorem le_replicate_iff {m : Multiset α} {a : α} {n : ℕ} : m ≤ replicate n a ↔ ∃ k ≤ n, m = replicate k a := ⟨fun h => ⟨card m, (card_mono h).trans_eq (card_replicate _ _), @@ -972,6 +976,7 @@ theorem erase_comm (s : Multiset α) (a b : α) : (s.erase a).erase b = (s.erase instance : RightCommutative erase (α := α) := ⟨erase_comm⟩ +@[gcongr] theorem erase_le_erase {s t : Multiset α} (a : α) (h : s ≤ t) : s.erase a ≤ t.erase a := leInductionOn h fun h => (h.erase _).subperm @@ -1151,11 +1156,11 @@ theorem eq_of_mem_map_const {b₁ b₂ : β} {l : List α} (h : b₁ ∈ map (Fu b₁ = b₂ := eq_of_mem_replicate (n := card (l : Multiset α)) <| by rwa [map_const] at h -@[simp] +@[simp, gcongr] theorem map_le_map {f : α → β} {s t : Multiset α} (h : s ≤ t) : map f s ≤ map f t := leInductionOn h fun h => (h.map f).subperm -@[simp] +@[simp, gcongr] theorem map_lt_map {f : α → β} {s t : Multiset α} (h : s < t) : s.map f < t.map f := by refine (map_le_map h.le).lt_of_not_le fun H => h.ne <| eq_of_le_of_card_le h.le ?_ rw [← s.card_map f, ← t.card_map f] @@ -1165,7 +1170,7 @@ theorem map_mono (f : α → β) : Monotone (map f) := fun _ _ => map_le_map theorem map_strictMono (f : α → β) : StrictMono (map f) := fun _ _ => map_lt_map -@[simp] +@[simp, gcongr] theorem map_subset_map {f : α → β} {s t : Multiset α} (H : s ⊆ t) : map f s ⊆ map f t := fun _b m => let ⟨a, h, e⟩ := mem_map.1 m mem_map.2 ⟨a, H h, e⟩ @@ -1521,6 +1526,7 @@ theorem le_union_right (s t : Multiset α) : t ≤ s ∪ t := theorem eq_union_left : t ≤ s → s ∪ t = s := tsub_add_cancel_of_le +@[gcongr] theorem union_le_union_right (h : s ≤ t) (u) : s ∪ u ≤ t ∪ u := add_le_add_right (tsub_le_tsub_right h _) u @@ -1626,6 +1632,7 @@ theorem inter_comm (s t : Multiset α) : s ∩ t = t ∩ s := inf_comm _ _ theorem eq_union_right (h : s ≤ t) : s ∪ t = t := by rw [union_comm, eq_union_left h] +@[gcongr] theorem union_le_union_left (h : s ≤ t) (u) : u ∪ s ≤ u ∪ t := sup_le_sup_left h _ @@ -1710,6 +1717,7 @@ theorem filter_zero : filter p 0 = 0 := Please re-enable the linter once we moved to `nightly-2024-06-22` or later. -/ set_option linter.deprecated false in +@[congr] theorem filter_congr {p q : α → Prop} [DecidablePred p] [DecidablePred q] {s : Multiset α} : (∀ x ∈ s, p x ↔ q x) → filter p s = filter q s := Quot.inductionOn s fun _l h => congr_arg ofList <| filter_congr' <| by simpa using h @@ -1726,6 +1734,7 @@ theorem filter_le (s : Multiset α) : filter p s ≤ s := theorem filter_subset (s : Multiset α) : filter p s ⊆ s := subset_of_le <| filter_le _ _ +@[gcongr] theorem filter_le_filter {s t} (h : s ≤ t) : filter p s ≤ filter p t := leInductionOn h fun h => (h.filter (p ·)).subperm @@ -1938,6 +1947,7 @@ theorem map_filterMap_of_inv (f : α → Option β) (g : β → α) (H : ∀ x : (s : Multiset α) : map g (filterMap f s) = s := Quot.inductionOn s fun l => congr_arg ofList <| List.map_filterMap_of_inv f g H l +@[gcongr] theorem filterMap_le_filterMap (f : α → Option β) {s t : Multiset α} (h : s ≤ t) : filterMap f s ≤ filterMap f t := leInductionOn h fun h => (h.filterMap _).subperm @@ -2006,6 +2016,7 @@ theorem countP_sub [DecidableEq α] {s t : Multiset α} (h : t ≤ s) : countP p (s - t) = countP p s - countP p t := by simp [countP_eq_card_filter, h, filter_le_filter] +@[gcongr] theorem countP_le_of_le {s t} (h : s ≤ t) : countP p s ≤ countP p t := by simpa [countP_eq_card_filter] using card_le_card (filter_le_filter p h) @@ -2065,6 +2076,7 @@ theorem countP_eq_card {s} : countP p s = card s ↔ ∀ a ∈ s, p a := theorem countP_pos_of_mem {s a} (h : a ∈ s) (pa : p a) : 0 < countP p s := countP_pos.2 ⟨_, h, pa⟩ +@[congr] theorem countP_congr {s s' : Multiset α} (hs : s = s') {p p' : α → Prop} [DecidablePred p] [DecidablePred p'] (hp : ∀ x ∈ s, p x = p' x) : s.countP p = s'.countP p' := by @@ -2108,6 +2120,7 @@ theorem count_cons_of_ne {a b : α} (h : a ≠ b) (s : Multiset α) : count a (b theorem count_le_card (a : α) (s) : count a s ≤ card s := countP_le_card _ _ +@[gcongr] theorem count_le_of_le (a : α) {s t} : s ≤ t → count a s ≤ count a t := countP_le_of_le _ From 2148d6685294e201b8e822a1053f3c6c9fa837f1 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 20:32:52 +1100 Subject: [PATCH 204/425] update batteries --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 35d3524d139f96..3483aa5156c1df 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "f46281aa070a896c28f7f41da460fe93448dd4b6", + "rev": "0e55c5ddf1f0be57ebdffa9f44fc98882b1a9a41", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "lean-pr-testing-5731", From c8c3d8ada8d3784397e8077d73e9904319f24f64 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 20:42:28 +1100 Subject: [PATCH 205/425] fixes for leanprover/lean4#5732 --- Mathlib/Data/List/Monad.lean | 2 +- lake-manifest.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Data/List/Monad.lean b/Mathlib/Data/List/Monad.lean index 04d1477cbd14d0..e4bcb48dbf66ae 100644 --- a/Mathlib/Data/List/Monad.lean +++ b/Mathlib/Data/List/Monad.lean @@ -16,7 +16,7 @@ namespace List variable {α : Type u} instance instMonad : Monad List.{u} where - pure := @List.pure + pure := @List.singleton bind := @List.bind map := @List.map diff --git a/lake-manifest.json b/lake-manifest.json index f78f6b6678ef38..b7eb4db14e6003 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "61207caf0c8f87fc4c00901d356d2a37ebef7e5b", + "rev": "fd223041ee7c5c9ea183c8995ef2822543e3e56e", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "lean-pr-testing-5732", From 66289b2ea0b316dd716e5935f2f130e3ccfaf9ba Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 20:45:41 +1100 Subject: [PATCH 206/425] fix for leanprover/lean4#5732 --- Mathlib/Data/Multiset/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Data/Multiset/Basic.lean b/Mathlib/Data/Multiset/Basic.lean index b54ec18a4e5313..97ed4b8d3f67f8 100644 --- a/Mathlib/Data/Multiset/Basic.lean +++ b/Mathlib/Data/Multiset/Basic.lean @@ -1780,7 +1780,7 @@ theorem filter_cons {a : α} (s : Multiset α) : theorem filter_singleton {a : α} (p : α → Prop) [DecidablePred p] : filter p {a} = if p a then {a} else ∅ := by - simp only [singleton, filter_cons, filter_zero, add_zero, empty_eq_zero] + simp only [Singleton.singleton, filter_cons, filter_zero, add_zero, empty_eq_zero] theorem filter_nsmul (s : Multiset α) (n : ℕ) : filter p (n • s) = n • filter p s := by refine s.induction_on ?_ ?_ From 8e7833a57c7331fcf2a2b9776482ae29dca6d004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Wed, 16 Oct 2024 10:11:37 +0000 Subject: [PATCH 207/425] feat: `MeasurableSpace` instance for the quotient of a module by a submodule (#17812) From PFR --- Mathlib.lean | 1 + .../Constructions/SubmoduleQuotient.lean | 20 +++++++++++++++++++ .../MeasureTheory/MeasurableSpace/Basic.lean | 9 +++++++++ 3 files changed, 30 insertions(+) create mode 100644 Mathlib/MeasureTheory/Constructions/SubmoduleQuotient.lean diff --git a/Mathlib.lean b/Mathlib.lean index 4145efbc9c714a..ad61f598310a68 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3241,6 +3241,7 @@ import Mathlib.MeasureTheory.Constructions.Polish.EmbeddingReal import Mathlib.MeasureTheory.Constructions.Prod.Basic import Mathlib.MeasureTheory.Constructions.Prod.Integral import Mathlib.MeasureTheory.Constructions.Projective +import Mathlib.MeasureTheory.Constructions.SubmoduleQuotient import Mathlib.MeasureTheory.Constructions.UnitInterval import Mathlib.MeasureTheory.Covering.Besicovitch import Mathlib.MeasureTheory.Covering.BesicovitchVectorSpace diff --git a/Mathlib/MeasureTheory/Constructions/SubmoduleQuotient.lean b/Mathlib/MeasureTheory/Constructions/SubmoduleQuotient.lean new file mode 100644 index 00000000000000..e5bcc2ccd92dd4 --- /dev/null +++ b/Mathlib/MeasureTheory/Constructions/SubmoduleQuotient.lean @@ -0,0 +1,20 @@ +/- +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 +-/ +import Mathlib.LinearAlgebra.Quotient +import Mathlib.MeasureTheory.MeasurableSpace.Basic + +/-! +# Measurability on the quotient of a module by a submodule +-/ + +namespace Submodule.Quotient +variable {R M : Type*} [Ring R] [AddCommGroup M] [Module R M] {p : Submodule R M} + +instance [MeasurableSpace M] : MeasurableSpace (M ⧸ p) := Quotient.instMeasurableSpace +instance [MeasurableSpace M] [DiscreteMeasurableSpace M] : DiscreteMeasurableSpace (M ⧸ p) := + Quotient.instDiscreteMeasurableSpace + +end Submodule.Quotient diff --git a/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean b/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean index 573857eeaad279..49c7a06029ead3 100644 --- a/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean +++ b/Mathlib/MeasureTheory/MeasurableSpace/Basic.lean @@ -472,6 +472,15 @@ nonrec theorem QuotientGroup.measurable_from_quotient {G} [Group G] [MeasurableS {S : Subgroup G} {f : G ⧸ S → α} : Measurable f ↔ Measurable (f ∘ ((↑) : G → G ⧸ S)) := measurable_from_quotient +instance Quotient.instDiscreteMeasurableSpace {α} {s : Setoid α} [MeasurableSpace α] + [DiscreteMeasurableSpace α] : DiscreteMeasurableSpace (Quotient s) where + forall_measurableSet _ := measurableSet_quotient.2 .of_discrete + +@[to_additive] +instance QuotientGroup.instDiscreteMeasurableSpace {G} [Group G] [MeasurableSpace G] + [DiscreteMeasurableSpace G] (S : Subgroup G) : DiscreteMeasurableSpace (G ⧸ S) := + Quotient.instDiscreteMeasurableSpace + end Quotient section Subtype From 88e7113ac302a91f873cb154ca186f8a0c7b89ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Wed, 16 Oct 2024 10:27:00 +0000 Subject: [PATCH 208/425] =?UTF-8?q?feat(SetTheory/Ordinal/Arithmetic):=20`?= =?UTF-8?q?a=20=E2=89=A4=20b=20=E2=86=92=20a=20/=20c=20=E2=89=A4=20b=20/?= =?UTF-8?q?=20c`=20(#17741)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Mathlib/SetTheory/Ordinal/Arithmetic.lean | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Mathlib/SetTheory/Ordinal/Arithmetic.lean b/Mathlib/SetTheory/Ordinal/Arithmetic.lean index 65ed7c402f75f1..aa95e0d9ce2168 100644 --- a/Mathlib/SetTheory/Ordinal/Arithmetic.lean +++ b/Mathlib/SetTheory/Ordinal/Arithmetic.lean @@ -865,6 +865,12 @@ theorem zero_div (a : Ordinal) : 0 / a = 0 := theorem mul_div_le (a b : Ordinal) : b * (a / b) ≤ a := if b0 : b = 0 then by simp only [b0, zero_mul, Ordinal.zero_le] else (le_div b0).1 le_rfl +theorem div_le_left {a b : Ordinal} (h : a ≤ b) (c : Ordinal) : a / c ≤ b / c := by + obtain rfl | hc := eq_or_ne c 0 + · rw [div_zero, div_zero] + · rw [le_div hc] + exact (mul_div_le a c).trans h + theorem mul_add_div (a) {b : Ordinal} (b0 : b ≠ 0) (c) : (b * a + c) / b = a + c / b := by apply le_antisymm · apply (div_le b0).2 From 8591fb6789e584a8f8d46509cc803b7475140a93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Wed, 16 Oct 2024 10:27:01 +0000 Subject: [PATCH 209/425] =?UTF-8?q?feat:=20`s=20=E2=8A=86=20f=20''=20t=20?= =?UTF-8?q?=E2=86=92=20f=20=E2=81=BB=C2=B9'=20s=20=E2=8A=86=20t`=20(#17788?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Mathlib/Data/Finset/Preimage.lean | 4 ++++ Mathlib/Data/Set/Image.lean | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/Mathlib/Data/Finset/Preimage.lean b/Mathlib/Data/Finset/Preimage.lean index 5a78ba233b2d20..1331695180e29b 100644 --- a/Mathlib/Data/Finset/Preimage.lean +++ b/Mathlib/Data/Finset/Preimage.lean @@ -95,6 +95,10 @@ theorem image_preimage_of_bij [DecidableEq β] (f : α → β) (s : Finset β) (hf : Set.BijOn f (f ⁻¹' ↑s) ↑s) : image f (preimage s f hf.injOn) = s := Finset.coe_inj.1 <| by simpa using hf.image_eq +lemma preimage_subset_of_subset_image [DecidableEq β] {f : α → β} {s : Finset β} {t : Finset α} + (hs : s ⊆ t.image f) {hf} : s.preimage f hf ⊆ t := by + rw [← coe_subset, coe_preimage]; exact Set.preimage_subset (mod_cast hs) hf + theorem preimage_subset {f : α ↪ β} {s : Finset β} {t : Finset α} (hs : s ⊆ t.map f) : s.preimage f f.injective.injOn ⊆ t := fun _ h => (mem_map' f).1 (hs (mem_preimage.1 h)) diff --git a/Mathlib/Data/Set/Image.lean b/Mathlib/Data/Set/Image.lean index e70bfdc19f8d57..bbd73befb9a8c0 100644 --- a/Mathlib/Data/Set/Image.lean +++ b/Mathlib/Data/Set/Image.lean @@ -168,6 +168,12 @@ theorem preimage_subtype_coe_eq_compl {s u v : Set α} (hsuv : s ⊆ u ∪ v) · intro hx exact Or.elim (hsuv x_in_s) id fun hx' => hx.elim hx' +lemma preimage_subset {s t} (hs : s ⊆ f '' t) (hf : Set.InjOn f (f ⁻¹' s)) : f ⁻¹' s ⊆ t := by + rintro a ha + obtain ⟨b, hb, hba⟩ := hs ha + rwa [hf ha _ hba.symm] + simpa [hba] + end Preimage /-! ### Image of a set under a function -/ From 4fde5a554745253ba37fb31dbd63eda984eadc58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Wed, 16 Oct 2024 10:27:02 +0000 Subject: [PATCH 210/425] feat(SetTheory/Ordinal/Exponential): more lemmas on `opow` (#17804) --- Mathlib/SetTheory/Ordinal/Exponential.lean | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Mathlib/SetTheory/Ordinal/Exponential.lean b/Mathlib/SetTheory/Ordinal/Exponential.lean index 902f6a296c0359..3fad6ff39bde58 100644 --- a/Mathlib/SetTheory/Ordinal/Exponential.lean +++ b/Mathlib/SetTheory/Ordinal/Exponential.lean @@ -157,6 +157,9 @@ theorem opow_le_opow_left {a b : Ordinal} (c : Ordinal) (ab : a ≤ b) : a ^ c (opow_le_of_limit a0 l).2 fun b' h => (IH _ h).trans (opow_le_opow_right ((Ordinal.pos_iff_ne_zero.2 a0).trans_le ab) h.le) +theorem opow_le_opow {a b c d : Ordinal} (hac : a ≤ c) (hbd : b ≤ d) (hc : 0 < c) : a ^ b ≤ c ^ d := + (opow_le_opow_left b hac).trans (opow_le_opow_right hc hbd) + theorem left_le_opow (a : Ordinal) {b : Ordinal} (b1 : 0 < b) : a ≤ a ^ b := by nth_rw 1 [← opow_one a] cases' le_or_gt a 1 with a1 a1 @@ -167,8 +170,12 @@ theorem left_le_opow (a : Ordinal) {b : Ordinal} (b1 : 0 < b) : a ≤ a ^ b := b rw [a1, one_opow, one_opow] rwa [opow_le_opow_iff_right a1, one_le_iff_pos] +theorem left_lt_opow {a b : Ordinal} (ha : 1 < a) (hb : 1 < b) : a < a ^ b := by + conv_lhs => rw [← opow_one a] + rwa [opow_lt_opow_iff_right ha] + theorem right_le_opow {a : Ordinal} (b : Ordinal) (a1 : 1 < a) : b ≤ a ^ b := - (isNormal_opow a1).id_le _ + (isNormal_opow a1).le_apply theorem opow_lt_opow_left_of_succ {a b c : Ordinal} (ab : a < b) : a ^ succ c < b ^ succ c := by rw [opow_succ, opow_succ] From 27f2bb61023552a20bf282e1faa83804c9de8776 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 21:27:18 +1100 Subject: [PATCH 211/425] adaptations for leanprover/lean4#5731 --- Mathlib/Algebra/BigOperators/Group/List.lean | 22 +++++--- Mathlib/Computability/Primrec.lean | 22 ++++---- Mathlib/Computability/TuringMachine.lean | 35 +++++++----- Mathlib/Data/Fin/Tuple/NatAntidiagonal.lean | 18 +++--- Mathlib/Data/FinEnum.lean | 4 +- Mathlib/Data/Fintype/Perm.lean | 12 ++-- Mathlib/Data/List/Basic.lean | 30 ++++++---- Mathlib/Data/List/Defs.lean | 4 +- Mathlib/Data/List/Forall2.lean | 4 +- Mathlib/Data/List/Join.lean | 31 +++++++---- Mathlib/Data/List/Monad.lean | 6 +- Mathlib/Data/List/Nodup.lean | 12 ++-- Mathlib/Data/List/Perm.lean | 58 +++++++++++--------- Mathlib/Data/List/Permutation.lean | 15 ++--- Mathlib/Data/List/Pi.lean | 4 +- Mathlib/Data/List/ProdSigma.lean | 4 +- Mathlib/Data/List/Sections.lean | 6 +- Mathlib/Data/List/Sublists.lean | 39 +++++++------ Mathlib/Data/Multiset/Bind.lean | 6 +- Mathlib/Data/Multiset/Powerset.lean | 4 +- Mathlib/Data/Multiset/Sections.lean | 2 +- Mathlib/ModelTheory/Encoding.lean | 22 ++++---- Mathlib/Tactic/Simps/Basic.lean | 2 +- Mathlib/Testing/SlimCheck/Sampleable.lean | 2 +- lake-manifest.json | 10 ++-- lakefile.lean | 4 +- 26 files changed, 212 insertions(+), 166 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Group/List.lean b/Mathlib/Algebra/BigOperators/Group/List.lean index 69d4afc12ffe69..361d6c1d66dc55 100644 --- a/Mathlib/Algebra/BigOperators/Group/List.lean +++ b/Mathlib/Algebra/BigOperators/Group/List.lean @@ -651,17 +651,23 @@ lemma mem_mem_ranges_iff_lt_sum (l : List ℕ) {n : ℕ} : (∃ s ∈ l.ranges, n ∈ s) ↔ n < l.sum := by simp [mem_mem_ranges_iff_lt_natSum] @[simp] -theorem length_bind (l : List α) (f : α → List β) : - length (List.bind l f) = sum (map (length ∘ f) l) := by - rw [List.bind, length_flatten, map_map, Nat.sum_eq_listSum] +theorem length_flatMap (l : List α) (f : α → List β) : + length (List.flatMap l f) = sum (map (length ∘ f) l) := by + rw [List.flatMap, length_flatten, map_map, Nat.sum_eq_listSum] -lemma countP_bind (p : β → Bool) (l : List α) (f : α → List β) : - countP p (l.bind f) = sum (map (countP p ∘ f) l) := by - rw [List.bind, countP_flatten, map_map] +@[deprecated (since := "2024-10-16")] alias length_bind := length_flatMap + +lemma countP_flatMap (p : β → Bool) (l : List α) (f : α → List β) : + countP p (l.flatMap f) = sum (map (countP p ∘ f) l) := by + rw [List.flatMap, countP_flatten, map_map] simp -lemma count_bind [BEq β] (l : List α) (f : α → List β) (x : β) : - count x (l.bind f) = sum (map (count x ∘ f) l) := countP_bind _ _ _ +@[deprecated (since := "2024-10-16")] alias countP_bind := countP_flatMap + +lemma count_flatMap [BEq β] (l : List α) (f : α → List β) (x : β) : + count x (l.flatMap f) = sum (map (count x ∘ f) l) := countP_flatMap _ _ _ + +@[deprecated (since := "2024-10-16")] alias count_bind := count_flatMap /-- In a flatten, taking the first elements up to an index which is the sum of the lengths of the first `i` sublists, is the same as taking the flatten of the first `i` sublists. -/ diff --git a/Mathlib/Computability/Primrec.lean b/Mathlib/Computability/Primrec.lean index 36e36c0d4f5d16..113af207a4ec4e 100644 --- a/Mathlib/Computability/Primrec.lean +++ b/Mathlib/Computability/Primrec.lean @@ -959,8 +959,10 @@ theorem list_flatten : Primrec (@List.flatten α) := @[deprecated (since := "2024-10-15")] alias list_join := list_flatten -theorem list_bind {f : α → List β} {g : α → β → List σ} (hf : Primrec f) (hg : Primrec₂ g) : - Primrec (fun a => (f a).bind (g a)) := list_flatten.comp (list_map hf hg) +theorem list_flatMap {f : α → List β} {g : α → β → List σ} (hf : Primrec f) (hg : Primrec₂ g) : + Primrec (fun a => (f a).flatMap (g a)) := list_flatten.comp (list_map hf hg) + +@[deprecated (since := "2024-10-16")] alias list_bind := list_flatMap theorem optionToList : Primrec (Option.toList : Option α → List α) := (option_casesOn Primrec.id (const []) @@ -969,8 +971,8 @@ theorem optionToList : Primrec (Option.toList : Option α → List α) := theorem listFilterMap {f : α → List β} {g : α → β → Option σ} (hf : Primrec f) (hg : Primrec₂ g) : Primrec fun a => (f a).filterMap (g a) := - (list_bind hf (comp₂ optionToList hg)).of_eq - fun _ ↦ Eq.symm <| List.filterMap_eq_bind_toList _ _ + (list_flatMap hf (comp₂ optionToList hg)).of_eq + fun _ ↦ Eq.symm <| List.filterMap_eq_flatMap_toList _ _ theorem list_length : Primrec (@List.length α) := (list_foldr (@Primrec.id (List α) _) (const 0) <| to₂ <| (succ.comp <| snd.comp snd).to₂).of_eq @@ -1018,16 +1020,16 @@ theorem nat_omega_rec' (f : β → σ) {m : β → ℕ} {l : β → List β} {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 β - let mapGraph (M : List (β × σ)) (bs : List β) : List σ := bs.bind (Option.toList <| M.lookup ·) - let bindList (b : β) : ℕ → List β := fun n ↦ n.rec [b] fun _ bs ↦ bs.bind l + 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 ↦ (bindList b (m b - i)).filterMap fun b' ↦ (g b' <| mapGraph ih (l b')).map (b', ·) have mapGraph_primrec : Primrec₂ mapGraph := - to₂ <| list_bind snd <| optionToList.comp₂ <| listLookup.comp₂ .right (fst.comp₂ .left) + to₂ <| list_flatMap snd <| optionToList.comp₂ <| listLookup.comp₂ .right (fst.comp₂ .left) have bindList_primrec : Primrec₂ (bindList) := nat_rec' snd (list_cons.comp fst (const [])) - (to₂ <| list_bind (snd.comp snd) (hl.comp₂ .right)) + (to₂ <| list_flatMap (snd.comp snd) (hl.comp₂ .right)) have graph_primrec : Primrec₂ (graph) := to₂ <| nat_rec' snd (const []) <| to₂ <| listFilterMap @@ -1063,7 +1065,7 @@ theorem nat_omega_rec' (f : β → σ) {m : β → ℕ} {l : β → List β} {g have graph_succ : ∀ i, graph b (i + 1) = (bindList b (m b - i)).filterMap fun b' => (g b' <| mapGraph (graph b i) (l b')).map (b', ·) := fun _ => rfl - have bindList_succ : ∀ i, bindList b (i + 1) = (bindList b i).bind l := fun _ => rfl + have bindList_succ : ∀ i, bindList b (i + 1) = (bindList b i).flatMap l := fun _ => rfl induction' i with i ih · symm; simpa [graph] using bindList_eq_nil · simp only [graph_succ, ih (Nat.le_of_lt hi), Nat.succ_sub (Nat.lt_succ.mp hi), @@ -1071,7 +1073,7 @@ theorem nat_omega_rec' (f : β → σ) {m : β → ℕ} {l : β → List β} {g apply List.filterMap_eq_map_iff_forall_eq_some.mpr intro b' ha'; simp; rw [mapGraph_graph] · exact H b' - · exact (List.infix_bind_of_mem ha' l).subset + · exact (List.infix_flatMap_of_mem ha' l).subset simp [graph_eq_map_bindList (m b + 1) (Nat.le_refl _), bindList] theorem nat_omega_rec (f : α → β → σ) {m : α → β → ℕ} diff --git a/Mathlib/Computability/TuringMachine.lean b/Mathlib/Computability/TuringMachine.lean index a9037ff96e553c..c441e597e82a59 100644 --- a/Mathlib/Computability/TuringMachine.lean +++ b/Mathlib/Computability/TuringMachine.lean @@ -419,29 +419,36 @@ theorem ListBlank.append_assoc {Γ} [Inhabited Γ] (l₁ l₂ : List Γ) (l₃ : suffices append (l₁ ++ l₂) (mk l) = append l₁ (append l₂ (mk l)) by exact this simp only [ListBlank.append_mk, List.append_assoc] -/-- The `bind` function on lists is well defined on `ListBlank`s provided that the default element -is sent to a sequence of default elements. -/ -def ListBlank.bind {Γ Γ'} [Inhabited Γ] [Inhabited Γ'] (l : ListBlank Γ) (f : Γ → List Γ') +/-- The `flatMap` function on lists is well defined on `ListBlank`s provided that the default +element is sent to a sequence of default elements. -/ +def ListBlank.flatMap {Γ Γ'} [Inhabited Γ] [Inhabited Γ'] (l : ListBlank Γ) (f : Γ → List Γ') (hf : ∃ n, f default = List.replicate n default) : ListBlank Γ' := by - apply l.liftOn (fun l ↦ ListBlank.mk (List.bind l f)) + apply l.liftOn (fun l ↦ ListBlank.mk (List.flatMap l f)) rintro l _ ⟨i, rfl⟩; cases' hf with n e; refine Quotient.sound' (Or.inl ⟨i * n, ?_⟩) - rw [List.append_bind, mul_comm]; congr + rw [List.flatMap_append, mul_comm]; congr induction' i with i IH · rfl simp only [IH, e, List.replicate_add, Nat.mul_succ, add_comm, List.replicate_succ, List.cons_bind] +@[deprecated (since := "2024-10-16")] alias ListBlank.bind := ListBlank.flatMap + @[simp] -theorem ListBlank.bind_mk {Γ Γ'} [Inhabited Γ] [Inhabited Γ'] (l : List Γ) (f : Γ → List Γ') (hf) : - (ListBlank.mk l).bind f hf = ListBlank.mk (l.bind f) := +theorem ListBlank.flatMap_mk + {Γ Γ'} [Inhabited Γ] [Inhabited Γ'] (l : List Γ) (f : Γ → List Γ') (hf) : + (ListBlank.mk l).flatMap f hf = ListBlank.mk (l.flatMap f) := rfl +@[deprecated (since := "2024-10-16")] alias ListBlank.bind_mk := ListBlank.flatMap_mk + @[simp] -theorem ListBlank.cons_bind {Γ Γ'} [Inhabited Γ] [Inhabited Γ'] (a : Γ) (l : ListBlank Γ) - (f : Γ → List Γ') (hf) : (l.cons a).bind f hf = (l.bind f hf).append (f a) := by +theorem ListBlank.cons_flatMap {Γ Γ'} [Inhabited Γ] [Inhabited Γ'] (a : Γ) (l : ListBlank Γ) + (f : Γ → List Γ') (hf) : (l.cons a).flatMap f hf = (l.flatMap f hf).append (f a) := by refine l.inductionOn fun l ↦ ?_ -- Porting note: Added `suffices` to get `simp` to work. - suffices ((mk l).cons a).bind f hf = ((mk l).bind f hf).append (f a) by exact this - simp only [ListBlank.append_mk, ListBlank.bind_mk, ListBlank.cons_mk, List.cons_bind] + suffices ((mk l).cons a).flatMap f hf = ((mk l).flatMap f hf).append (f a) by exact this + simp only [ListBlank.append_mk, ListBlank.flatMap_mk, ListBlank.cons_mk, List.cons_flatMap] + +@[deprecated (since := "2024-10-16")] alias ListBlank.cons_bind := ListBlank.cons_flatMap /-- The tape of a Turing machine is composed of a head element (which we imagine to be the current position of the head), together with two `ListBlank`s denoting the portions of the tape @@ -1548,8 +1555,8 @@ variable {enc} /-- The low level tape corresponding to the given tape over alphabet `Γ`. -/ def trTape' (L R : ListBlank Γ) : Tape Bool := by refine - Tape.mk' (L.bind (fun x ↦ (enc x).toList.reverse) ⟨n, ?_⟩) - (R.bind (fun x ↦ (enc x).toList) ⟨n, ?_⟩) <;> + Tape.mk' (L.flatMap (fun x ↦ (enc x).toList.reverse) ⟨n, ?_⟩) + (R.flatMap (fun x ↦ (enc x).toList) ⟨n, ?_⟩) <;> simp only [enc0, Vector.replicate, List.reverse_replicate, Bool.default_bool, Vector.toList_mk] /-- The low level tape corresponding to the given tape over alphabet `Γ`. -/ @@ -1575,7 +1582,7 @@ variable {enc} theorem trTape'_move_left (L R : ListBlank Γ) : (Tape.move Dir.left)^[n] (trTape' enc0 L R) = trTape' enc0 L.tail (R.cons L.head) := by obtain ⟨a, L, rfl⟩ := L.exists_cons - simp only [trTape', ListBlank.cons_bind, ListBlank.head_cons, ListBlank.tail_cons] + simp only [trTape', ListBlank.cons_flatMap, ListBlank.head_cons, ListBlank.tail_cons] suffices ∀ {L' R' l₁ l₂} (_ : Vector.toList (enc a) = List.reverseAux l₁ l₂), (Tape.move Dir.left)^[l₁.length] (Tape.mk' (ListBlank.append l₁ L') (ListBlank.append l₂ R')) = diff --git a/Mathlib/Data/Fin/Tuple/NatAntidiagonal.lean b/Mathlib/Data/Fin/Tuple/NatAntidiagonal.lean index 7f311baa1744cd..a3608131c30449 100644 --- a/Mathlib/Data/Fin/Tuple/NatAntidiagonal.lean +++ b/Mathlib/Data/Fin/Tuple/NatAntidiagonal.lean @@ -60,7 +60,7 @@ def antidiagonalTuple : ∀ k, ℕ → List (Fin k → ℕ) | 0, 0 => [![]] | 0, _ + 1 => [] | k + 1, n => - (List.Nat.antidiagonal n).bind fun ni => + (List.Nat.antidiagonal n).flatMap fun ni => (antidiagonalTuple k ni.2).map fun x => Fin.cons ni.1 x @[simp] @@ -79,7 +79,7 @@ theorem mem_antidiagonalTuple {n : ℕ} {k : ℕ} {x : Fin k → ℕ} : · decide · simp [eq_comm] | h x₀ x ih => - simp_rw [Fin.sum_cons, antidiagonalTuple, List.mem_bind, List.mem_map, + simp_rw [Fin.sum_cons, antidiagonalTuple, List.mem_flatMap, List.mem_map, List.Nat.mem_antidiagonal, Fin.cons_eq_cons, exists_eq_right_right, ih, @eq_comm _ _ (Prod.snd _), and_comm (a := Prod.snd _ = _), ← Prod.mk.inj_iff (a₁ := Prod.fst _), exists_eq_right] @@ -90,7 +90,7 @@ theorem nodup_antidiagonalTuple (k n : ℕ) : List.Nodup (antidiagonalTuple k n) · cases n · simp · simp [eq_comm] - simp_rw [antidiagonalTuple, List.nodup_bind] + simp_rw [antidiagonalTuple, List.nodup_flatMap] constructor · intro i _ exact (ih i.snd).map (Fin.cons_right_injective (α := fun _ => ℕ) i.fst) @@ -113,17 +113,17 @@ theorem nodup_antidiagonalTuple (k n : ℕ) : List.Nodup (antidiagonalTuple k n) theorem antidiagonalTuple_zero_right : ∀ k, antidiagonalTuple k 0 = [0] | 0 => (congr_arg fun x => [x]) <| Subsingleton.elim _ _ | k + 1 => by - rw [antidiagonalTuple, antidiagonal_zero, List.bind_singleton, antidiagonalTuple_zero_right k, - List.map_singleton] + rw [antidiagonalTuple, antidiagonal_zero, List.flatMap_singleton, + antidiagonalTuple_zero_right k, List.map_singleton] exact congr_arg (fun x => [x]) Matrix.cons_zero_zero @[simp] theorem antidiagonalTuple_one (n : ℕ) : antidiagonalTuple 1 n = [![n]] := by simp_rw [antidiagonalTuple, antidiagonal, List.range_succ, List.map_append, List.map_singleton, - Nat.sub_self, List.bind_append, List.bind_singleton, List.bind_map] + Nat.sub_self, List.flatMap_append, List.flatMap_singleton, List.flatMap_map] conv_rhs => rw [← List.nil_append [![n]]] congr 1 - simp_rw [List.bind_eq_nil_iff, List.mem_range, List.map_eq_nil_iff] + simp_rw [List.flatMap_eq_nil_iff, List.mem_range, List.map_eq_nil_iff] intro x hx obtain ⟨m, rfl⟩ := Nat.exists_eq_add_of_lt hx rw [add_assoc, add_tsub_cancel_left, antidiagonalTuple_zero_succ] @@ -132,7 +132,7 @@ theorem antidiagonalTuple_two (n : ℕ) : antidiagonalTuple 2 n = (antidiagonal n).map fun i => ![i.1, i.2] := by rw [antidiagonalTuple] simp_rw [antidiagonalTuple_one, List.map_singleton] - rw [List.map_eq_bind] + rw [List.map_eq_flatMap] rfl theorem antidiagonalTuple_pairwise_pi_lex : @@ -140,7 +140,7 @@ theorem antidiagonalTuple_pairwise_pi_lex : | 0, 0 => List.pairwise_singleton _ _ | 0, _ + 1 => List.Pairwise.nil | k + 1, n => by - simp_rw [antidiagonalTuple, List.pairwise_bind, List.pairwise_map, List.mem_map, + simp_rw [antidiagonalTuple, List.pairwise_flatMap, List.pairwise_map, List.mem_map, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂] simp only [mem_antidiagonal, Prod.forall, and_imp, forall_apply_eq_imp_iff₂] simp only [Fin.pi_lex_lt_cons_cons, eq_self_iff_true, true_and, lt_self_iff_false, diff --git a/Mathlib/Data/FinEnum.lean b/Mathlib/Data/FinEnum.lean index f4a3ae5c5e0e22..62061de371ca04 100644 --- a/Mathlib/Data/FinEnum.lean +++ b/Mathlib/Data/FinEnum.lean @@ -115,7 +115,7 @@ theorem Finset.mem_enum [DecidableEq α] (s : Finset α) (xs : List α) : induction xs generalizing s with | nil => simp [enum, eq_empty_iff_forall_not_mem] | cons x xs ih => - simp only [enum, List.bind_eq_bind, List.mem_bind, List.mem_cons, List.mem_singleton, + simp only [enum, List.bind_eq_flatMap, List.mem_flatMap, List.mem_cons, List.mem_singleton, List.not_mem_nil, or_false, ih] refine ⟨by aesop, fun hs => ⟨s.erase x, ?_⟩⟩ simp only [or_iff_not_imp_left] at hs @@ -129,7 +129,7 @@ instance Subtype.finEnum [FinEnum α] (p : α → Prop) [DecidablePred p] : FinE (by rintro ⟨x, h⟩; simpa) instance (β : α → Type v) [FinEnum α] [∀ a, FinEnum (β a)] : FinEnum (Sigma β) := - ofList ((toList α).bind fun a => (toList (β a)).map <| Sigma.mk a) + ofList ((toList α).flatMap fun a => (toList (β a)).map <| Sigma.mk a) (by intro x; cases x; simp) instance PSigma.finEnum [FinEnum α] [∀ a, FinEnum (β a)] : FinEnum (Σ'a, β a) := diff --git a/Mathlib/Data/Fintype/Perm.lean b/Mathlib/Data/Fintype/Perm.lean index 47dbd625b6d70e..a62007cabd6cff 100644 --- a/Mathlib/Data/Fintype/Perm.lean +++ b/Mathlib/Data/Fintype/Perm.lean @@ -30,13 +30,13 @@ variable [DecidableEq α] [DecidableEq β] /-- Given a list, produce a list of all permutations of its elements. -/ def permsOfList : List α → List (Perm α) | [] => [1] - | a :: l => permsOfList l ++ l.bind fun b => (permsOfList l).map fun f => Equiv.swap a b * f + | a :: l => permsOfList l ++ l.flatMap fun b => (permsOfList l).map fun f => Equiv.swap a b * f theorem length_permsOfList : ∀ l : List α, length (permsOfList l) = l.length ! | [] => rfl | a :: l => by rw [length_cons, Nat.factorial_succ] - simp only [permsOfList, length_append, length_permsOfList, length_bind, comp_def, + simp only [permsOfList, length_append, length_permsOfList, length_flatMap, comp_def, length_map, map_const', sum_replicate, smul_eq_mul, succ_mul] ring @@ -64,7 +64,7 @@ theorem mem_permsOfList_of_mem {l : List α} {f : Perm α} (h : ∀ x, f x ≠ x split_ifs at hx with h_1 exacts [hxa (h.symm.trans h_1), hx h] suffices f ∈ permsOfList l ∨ ∃ b ∈ l, ∃ g ∈ permsOfList l, Equiv.swap a b * g = f by - simpa only [permsOfList, exists_prop, List.mem_map, mem_append, List.mem_bind] + 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] @@ -78,7 +78,7 @@ theorem mem_of_mem_permsOfList : | a :: l, f, h, x => (mem_append.1 h).elim (fun h hx => mem_cons_of_mem _ (mem_of_mem_permsOfList h x hx)) fun h hx => - let ⟨y, hy, hy'⟩ := List.mem_bind.1 h + let ⟨y, hy, hy'⟩ := List.mem_flatMap.1 h let ⟨g, hg₁, hg₂⟩ := List.mem_map.1 hy' -- Porting note: Seems like the implicit variable `x` of type `α` is needed. if hxa : x = a then by simp [hxa] @@ -99,7 +99,7 @@ theorem nodup_permsOfList : ∀ {l : List α}, l.Nodup → (permsOfList l).Nodup have hln' : (permsOfList l).Nodup := nodup_permsOfList hl' have hmeml : ∀ {f : Perm α}, f ∈ permsOfList l → f a = a := fun {f} hf => not_not.1 (mt (mem_of_mem_permsOfList hf _) (nodup_cons.1 hl).1) - rw [permsOfList, List.nodup_append, List.nodup_bind, pairwise_iff_getElem] + rw [permsOfList, List.nodup_append, List.nodup_flatMap, pairwise_iff_getElem] refine ⟨?_, ⟨⟨?_,?_ ⟩, ?_⟩⟩ · exact hln' · exact fun _ _ => hln'.map fun _ _ => mul_left_cancel @@ -113,7 +113,7 @@ theorem nodup_permsOfList : ∀ {l : List α}, l.Nodup → (permsOfList l).Nodup have hieqj : i = j := hl'.getElem_inj_iff.1 (hix.symm.trans hiy) exact absurd hieqj (_root_.ne_of_lt hij) · intros f hf₁ hf₂ - let ⟨x, hx, hx'⟩ := List.mem_bind.1 hf₂ + let ⟨x, hx, hx'⟩ := List.mem_flatMap.1 hf₂ let ⟨g, hg⟩ := List.mem_map.1 hx' have hgxa : g⁻¹ x = a := f.injective <| by rw [hmeml hf₁, ← hg.2]; simp have hxa : x ≠ a := fun h => (List.nodup_cons.1 hl).1 (h ▸ hx) diff --git a/Mathlib/Data/List/Basic.lean b/Mathlib/Data/List/Basic.lean index 5e2ac7f43629c9..7241561c4aa231 100644 --- a/Mathlib/Data/List/Basic.lean +++ b/Mathlib/Data/List/Basic.lean @@ -248,9 +248,11 @@ theorem mem_pure (x y : α) : x ∈ (pure y : List α) ↔ x = y := by simp /-! ### bind -/ @[simp] -theorem bind_eq_bind {α β} (f : α → List β) (l : List α) : l >>= f = l.bind f := +theorem bind_eq_flatMap {α β} (f : α → List β) (l : List α) : l >>= f = l.flatMap f := rfl +@[deprecated (since := "2024-10-16")] alias bind_eq_bind := bind_eq_flatMap + /-! ### concat -/ /-! ### reverse -/ @@ -887,22 +889,28 @@ attribute [simp] map_const' @[deprecated (since := "2024-06-21")] alias map_congr := map_congr_left -theorem bind_pure_eq_map (f : α → β) (l : List α) : l.bind (pure ∘ f) = map f l := - .symm <| map_eq_bind .. +theorem flatMap_pure_eq_map (f : α → β) (l : List α) : l.flatMap (pure ∘ f) = map f l := + .symm <| map_eq_flatMap .. + +@[deprecated (since := "2024-10-16")] alias bind_pure_eq_map := flatMap_pure_eq_map set_option linter.deprecated false in -@[deprecated bind_pure_eq_map (since := "2024-03-24")] +@[deprecated flatMap_pure_eq_map (since := "2024-03-24")] theorem bind_ret_eq_map (f : α → β) (l : List α) : l.bind (List.ret ∘ f) = map f l := bind_pure_eq_map f l -theorem bind_congr {l : List α} {f g : α → List β} (h : ∀ x ∈ l, f x = g x) : - List.bind l f = List.bind l g := +theorem flatMap_congr {l : List α} {f g : α → List β} (h : ∀ x ∈ l, f x = g x) : + List.flatMap l f = List.flatMap l g := (congr_arg List.flatten <| map_congr_left h : _) -theorem infix_bind_of_mem {a : α} {as : List α} (h : a ∈ as) (f : α → List α) : - f a <:+: as.bind f := +@[deprecated (since := "2024-10-16")] alias bind_congr := flatMap_congr + +theorem infix_flatMap_of_mem {a : α} {as : List α} (h : a ∈ as) (f : α → List α) : + f a <:+: as.flatMap f := List.infix_of_mem_flatten (List.mem_map_of_mem f h) +@[deprecated (since := "2024-10-16")] alias infix_bind_of_mem := infix_flatMap_of_mem + @[simp] theorem map_eq_map {α β} (f : α → β) (l : List α) : f <$> l = map f l := rfl @@ -1625,11 +1633,13 @@ attribute [simp 1100] filterMap_cons_none -- removing attribute `nolint simpNF` attribute [simp 1100] filterMap_cons_some -theorem filterMap_eq_bind_toList (f : α → Option β) (l : List α) : - l.filterMap f = l.bind fun a ↦ (f a).toList := by +theorem filterMap_eq_flatMap_toList (f : α → Option β) (l : List α) : + l.filterMap f = l.flatMap fun a ↦ (f a).toList := by induction' l with a l ih <;> simp [filterMap_cons] rcases f a <;> simp [ih] +@[deprecated (since := "2024-10-16")] alias filterMap_eq_bind_toList := filterMap_eq_flatMap_toList + theorem filterMap_congr {f g : α → Option β} {l : List α} (h : ∀ x ∈ l, f x = g x) : l.filterMap f = l.filterMap g := by induction' l with a l ih <;> simp [filterMap_cons] diff --git a/Mathlib/Data/List/Defs.lean b/Mathlib/Data/List/Defs.lean index f0aad1fcd0f005..2c5156f69ea723 100644 --- a/Mathlib/Data/List/Defs.lean +++ b/Mathlib/Data/List/Defs.lean @@ -210,7 +210,7 @@ but are equal up to permutation, as shown by `List.permutations_perm_permutation @[simp] def permutations' : List α → List (List α) | [] => [[]] - | t :: ts => (permutations' ts).bind <| permutations'Aux t + | t :: ts => (permutations' ts).flatMap <| permutations'Aux t end Permutations @@ -384,7 +384,7 @@ def map₂Right (f : Option α → β → γ) (as : List α) (bs : List β) : Li /-- Asynchronous version of `List.map`. -/ def mapAsyncChunked {α β} (f : α → β) (xs : List α) (chunk_size := 1024) : List β := - ((xs.toChunks chunk_size).map fun xs => Task.spawn fun _ => List.map f xs).bind Task.get + ((xs.toChunks chunk_size).map fun xs => Task.spawn fun _ => List.map f xs).flatMap Task.get /-! diff --git a/Mathlib/Data/List/Forall2.lean b/Mathlib/Data/List/Forall2.lean index f70e1557c45d3d..710339118e7472 100644 --- a/Mathlib/Data/List/Forall2.lean +++ b/Mathlib/Data/List/Forall2.lean @@ -230,9 +230,11 @@ theorem rel_flatten : (Forall₂ (Forall₂ R) ⇒ Forall₂ R) flatten flatten @[deprecated (since := "2025-10-15")] alias rel_join := rel_flatten -theorem rel_bind : (Forall₂ R ⇒ (R ⇒ Forall₂ P) ⇒ Forall₂ P) List.bind List.bind := +theorem rel_flatMap : (Forall₂ R ⇒ (R ⇒ Forall₂ P) ⇒ Forall₂ P) List.flatMap List.flatMap := fun _ _ h₁ _ _ h₂ => rel_flatten (rel_map (@h₂) h₁) +@[deprecated (since := "2025-10-16")] alias rel_bind := rel_flatMap + theorem rel_foldl : ((P ⇒ R ⇒ P) ⇒ P ⇒ Forall₂ R ⇒ P) foldl foldl | _, _, _, _, _, h, _, _, Forall₂.nil => h | _, _, hfg, _, _, hxy, _, _, Forall₂.cons hab hs => rel_foldl (@hfg) (hfg hxy hab) hs diff --git a/Mathlib/Data/List/Join.lean b/Mathlib/Data/List/Join.lean index 8c6ed6907be8b1..9f102b7523d063 100644 --- a/Mathlib/Data/List/Join.lean +++ b/Mathlib/Data/List/Join.lean @@ -39,18 +39,25 @@ lemma count_flatten' [BEq α] (L : List (List α)) (a : α) : @[deprecated (since := "2024-10-25")] alias count_join' := count_flatten' -/-- See `List.length_bind` for the corresponding statement using `List.sum`. -/ -lemma length_bind' (l : List α) (f : α → List β) : - length (l.bind f) = Nat.sum (map (length ∘ f) l) := by rw [List.bind, length_flatten', map_map] - -/-- See `List.countP_bind` for the corresponding statement using `List.sum`. -/ -lemma countP_bind' (p : β → Bool) (l : List α) (f : α → List β) : - countP p (l.bind f) = Nat.sum (map (countP p ∘ f) l) := by - rw [List.bind, countP_flatten', map_map] - -/-- See `List.count_bind` for the corresponding statement using `List.sum`. -/ -lemma count_bind' [BEq β] (l : List α) (f : α → List β) (x : β) : - count x (l.bind f) = Nat.sum (map (count x ∘ f) l) := countP_bind' _ _ _ +/-- See `List.length_flatMap` for the corresponding statement using `List.sum`. -/ +lemma length_flatMap' (l : List α) (f : α → List β) : + length (l.flatMap f) = Nat.sum (map (length ∘ f) l) := by + rw [List.flatMap, length_flatten', map_map] + +@[deprecated (since := "2024-10-25")] alias length_bind' := length_flatMap' + +/-- See `List.countP_flatMap` for the corresponding statement using `List.sum`. -/ +lemma countP_flatMap' (p : β → Bool) (l : List α) (f : α → List β) : + countP p (l.flatMap f) = Nat.sum (map (countP p ∘ f) l) := by + rw [List.flatMap, countP_flatten', map_map] + +@[deprecated (since := "2024-10-16")] alias countP_bind' := countP_flatMap' + +/-- See `List.count_flatMap` for the corresponding statement using `List.sum`. -/ +lemma count_flatMap' [BEq β] (l : List α) (f : α → List β) (x : β) : + count x (l.flatMap f) = Nat.sum (map (count x ∘ f) l) := countP_flatMap' _ _ _ + +@[deprecated (since := "2024-10-16")] alias count_bind' := count_flatMap' /-- In a join, taking the first elements up to an index which is the sum of the lengths of the first `i` sublists, is the same as taking the join of the first `i` sublists. diff --git a/Mathlib/Data/List/Monad.lean b/Mathlib/Data/List/Monad.lean index 04d1477cbd14d0..fce001d7741345 100644 --- a/Mathlib/Data/List/Monad.lean +++ b/Mathlib/Data/List/Monad.lean @@ -17,7 +17,7 @@ variable {α : Type u} instance instMonad : Monad List.{u} where pure := @List.pure - bind := @List.bind + bind := @List.flatMap map := @List.map @[simp] theorem pure_def (a : α) : pure a = [a] := rfl @@ -25,8 +25,8 @@ instance instMonad : Monad List.{u} where instance instLawfulMonad : LawfulMonad List.{u} := LawfulMonad.mk' (id_map := map_id) (pure_bind := fun _ _ => List.append_nil _) - (bind_assoc := List.bind_assoc) - (bind_pure_comp := fun _ _ => (map_eq_bind _ _).symm) + (bind_assoc := List.flatMap_assoc) + (bind_pure_comp := fun _ _ => (map_eq_flatMap _ _).symm) instance instAlternative : Alternative List.{u} where failure := @List.nil diff --git a/Mathlib/Data/List/Nodup.lean b/Mathlib/Data/List/Nodup.lean index 438d1ecf9ea7d3..a0a51d1e30d5bb 100644 --- a/Mathlib/Data/List/Nodup.lean +++ b/Mathlib/Data/List/Nodup.lean @@ -260,17 +260,19 @@ theorem nodup_flatten {L : List (List α)} : @[deprecated (since := "2025-10-15")] alias nodup_join := nodup_flatten -theorem nodup_bind {l₁ : List α} {f : α → List β} : - Nodup (l₁.bind f) ↔ +theorem nodup_flatMap {l₁ : List α} {f : α → List β} : + Nodup (l₁.flatMap f) ↔ (∀ x ∈ l₁, Nodup (f x)) ∧ Pairwise (fun a b : α => Disjoint (f a) (f b)) l₁ := by - simp only [List.bind, nodup_flatten, pairwise_map, and_comm, and_left_comm, mem_map, + simp only [List.flatMap, nodup_flatten, pairwise_map, and_comm, and_left_comm, mem_map, exists_imp, and_imp] rw [show (∀ (l : List β) (x : α), f x = l → x ∈ l₁ → Nodup l) ↔ ∀ x : α, x ∈ l₁ → Nodup (f x) from forall_swap.trans <| forall_congr' fun _ => forall_eq'] +@[deprecated (since := "2025-10-16")] alias nodup_bind := nodup_flatMap + protected theorem Nodup.product {l₂ : List β} (d₁ : l₁.Nodup) (d₂ : l₂.Nodup) : (l₁ ×ˢ l₂).Nodup := - nodup_bind.2 + nodup_flatMap.2 ⟨fun a _ => d₂.map <| LeftInverse.injective fun b => (rfl : (a, b).2 = b), d₁.imp fun {a₁ a₂} n x h₁ h₂ => by rcases mem_map.1 h₁ with ⟨b₁, _, rfl⟩ @@ -279,7 +281,7 @@ protected theorem Nodup.product {l₂ : List β} (d₁ : l₁.Nodup) (d₂ : l theorem Nodup.sigma {σ : α → Type*} {l₂ : ∀ a , List (σ a)} (d₁ : Nodup l₁) (d₂ : ∀ a , Nodup (l₂ a)) : (l₁.sigma l₂).Nodup := - nodup_bind.2 + nodup_flatMap.2 ⟨fun a _ => (d₂ a).map fun b b' h => by injection h with _ h, d₁.imp fun {a₁ a₂} n x h₁ h₂ => by rcases mem_map.1 h₁ with ⟨b₁, _, rfl⟩ diff --git a/Mathlib/Data/List/Perm.lean b/Mathlib/Data/List/Perm.lean index 2cf64feeb63cdc..341eb70bbbc289 100644 --- a/Mathlib/Data/List/Perm.lean +++ b/Mathlib/Data/List/Perm.lean @@ -275,31 +275,37 @@ theorem Perm.inter_append {l t₁ t₂ : List α} (h : Disjoint t₁ t₂) : end -theorem Perm.bind_left (l : List α) {f g : α → List β} (h : ∀ a ∈ l, f a ~ g a) : - l.bind f ~ l.bind g := +theorem Perm.flatMap_left (l : List α) {f g : α → List β} (h : ∀ a ∈ l, f a ~ g a) : + l.flatMap f ~ l.flatMap g := Perm.flatten_congr <| by rwa [List.forall₂_map_right_iff, List.forall₂_map_left_iff, List.forall₂_same] -theorem bind_append_perm (l : List α) (f g : α → List β) : - l.bind f ++ l.bind g ~ l.bind fun x => f x ++ g x := by +@[deprecated (since := "2024-10-16")] alias Perm.bind_left := Perm.flatMap_left + +theorem flatMap_append_perm (l : List α) (f g : α → List β) : + l.flatMap f ++ l.flatMap g ~ l.flatMap fun x => f x ++ g x := by induction' l with a l IH · simp - simp only [bind_cons, append_assoc] + simp only [flatMap_cons, append_assoc] refine (Perm.trans ?_ (IH.append_left _)).append_left _ rw [← append_assoc, ← append_assoc] exact perm_append_comm.append_right _ -theorem map_append_bind_perm (l : List α) (f : α → β) (g : α → List β) : - l.map f ++ l.bind g ~ l.bind fun x => f x :: g x := by - simpa [← map_eq_bind] using bind_append_perm l (fun x => [f x]) g +@[deprecated (since := "2024-10-16")] alias bind_append_perm := flatMap_append_perm + +theorem map_append_flatMap_perm (l : List α) (f : α → β) (g : α → List β) : + l.map f ++ l.flatMap g ~ l.flatMap fun x => f x :: g x := by + simpa [← map_eq_flatMap] using flatMap_append_perm l (fun x => [f x]) g + +@[deprecated (since := "2024-10-16")] alias map_append_bind_perm := map_append_flatMap_perm theorem Perm.product_right {l₁ l₂ : List α} (t₁ : List β) (p : l₁ ~ l₂) : product l₁ t₁ ~ product l₂ t₁ := - p.bind_right _ + p.flatMap_right _ theorem Perm.product_left (l : List α) {t₁ t₂ : List β} (p : t₁ ~ t₂) : product l t₁ ~ product l t₂ := - (Perm.bind_left _) fun _ _ => p.map _ + (Perm.flatMap_left _) fun _ _ => p.map _ theorem Perm.product {l₁ l₂ : List α} {t₁ t₂ : List β} (p₁ : l₁ ~ l₂) (p₂ : t₁ ~ t₂) : product l₁ t₁ ~ product l₂ t₂ := @@ -429,23 +435,23 @@ private theorem DecEq_eq [DecidableEq α] : rw [Bool.eq_iff_iff, @beq_iff_eq _ (_), decide_eq_true_iff] theorem perm_permutations'Aux_comm (a b : α) (l : List α) : - (permutations'Aux a l).bind (permutations'Aux b) ~ - (permutations'Aux b l).bind (permutations'Aux a) := by + (permutations'Aux a l).flatMap (permutations'Aux b) ~ + (permutations'Aux b l).flatMap (permutations'Aux a) := by induction' l with c l ih · simp [swap] - simp only [permutations'Aux, bind_cons, map_cons, map_map, cons_append] + simp only [permutations'Aux, flatMap_cons, map_cons, map_map, cons_append] apply Perm.swap' have : ∀ a b, - (map (cons c) (permutations'Aux a l)).bind (permutations'Aux b) ~ + (map (cons c) (permutations'Aux a l)).flatMap (permutations'Aux b) ~ map (cons b ∘ cons c) (permutations'Aux a l) ++ - map (cons c) ((permutations'Aux a l).bind (permutations'Aux b)) := by + map (cons c) ((permutations'Aux a l).flatMap (permutations'Aux b)) := by intros a' b' - simp only [bind_map, permutations'Aux] - show List.bind (permutations'Aux _ l) (fun a => ([b' :: c :: a] ++ + simp only [flatMap_map, permutations'Aux] + show List.flatMap (permutations'Aux _ l) (fun a => ([b' :: c :: a] ++ map (cons c) (permutations'Aux _ a))) ~ _ - refine (bind_append_perm _ (fun x => [b' :: c :: x]) _).symm.trans ?_ - rw [← map_eq_bind, ← map_bind] + refine (flatMap_append_perm _ (fun x => [b' :: c :: x]) _).symm.trans ?_ + rw [← map_eq_flatMap, ← map_flatMap] exact Perm.refl _ refine (((this _ _).append_left _).trans ?_).trans ((this _ _).append_left _).symm rw [← append_assoc, ← append_assoc] @@ -454,11 +460,11 @@ theorem perm_permutations'Aux_comm (a b : α) (l : List α) : theorem Perm.permutations' {s t : List α} (p : s ~ t) : permutations' s ~ permutations' t := by induction p with | nil => simp - | cons _ _ IH => exact IH.bind_right _ + | cons _ _ IH => exact IH.flatMap_right _ | swap => dsimp - rw [bind_assoc, bind_assoc] - apply Perm.bind_left + rw [flatMap_assoc, flatMap_assoc] + apply Perm.flatMap_left intro l' _ apply perm_permutations'Aux_comm | trans _ _ IH₁ IH₂ => exact IH₁.trans IH₂ @@ -472,10 +478,10 @@ theorem permutations_perm_permutations' (ts : List α) : ts.permutations ~ ts.pe simp only [permutations_append, foldr_permutationsAux2, permutationsAux_nil, permutationsAux_cons, append_nil] refine - (perm_append_comm.trans ((IH₂.bind_right _).append ((IH _ h).map _))).trans + (perm_append_comm.trans ((IH₂.flatMap_right _).append ((IH _ h).map _))).trans (Perm.trans ?_ perm_append_comm.permutations') - rw [map_eq_bind, singleton_append, permutations'] - refine (bind_append_perm _ _ _).trans ?_ + rw [map_eq_flatMap, singleton_append, permutations'] + refine (flatMap_append_perm _ _ _).trans ?_ refine Perm.of_eq ?_ congr funext _ @@ -591,7 +597,7 @@ theorem nodup_permutations (s : List α) (hs : Nodup s) : Nodup s.permutations : induction' hs with x l h h' IH · simp · rw [permutations'] - rw [nodup_bind] + rw [nodup_flatMap] constructor · intro ys hy rw [mem_permutations'] at hy diff --git a/Mathlib/Data/List/Permutation.lean b/Mathlib/Data/List/Permutation.lean index a08663b6819164..07b7e3a39f965c 100644 --- a/Mathlib/Data/List/Permutation.lean +++ b/Mathlib/Data/List/Permutation.lean @@ -161,10 +161,10 @@ theorem length_permutationsAux2 (t : α) (ts : List α) (ys : List α) (f : List theorem foldr_permutationsAux2 (t : α) (ts : List α) (r L : List (List α)) : foldr (fun y r => (permutationsAux2 t ts r y id).2) r L = - (L.bind fun y => (permutationsAux2 t ts [] y id).2) ++ r := by + (L.flatMap fun y => (permutationsAux2 t ts [] y id).2) ++ r := by induction' L with l L ih · rfl - · simp_rw [foldr_cons, ih, bind_cons, append_assoc, permutationsAux2_append] + · simp_rw [foldr_cons, ih, flatMap_cons, append_assoc, permutationsAux2_append] theorem mem_foldr_permutationsAux2 {t : α} {ts : List α} {r L : List (List α)} {l' : List α} : l' ∈ foldr (fun y r => (permutationsAux2 t ts r y id).2) r L ↔ @@ -176,13 +176,13 @@ theorem mem_foldr_permutationsAux2 {t : α} {ts : List α} {r L : List (List α) ⟨fun ⟨_, aL, l₁, l₂, l0, e, h⟩ => ⟨l₁, l₂, l0, e ▸ aL, h⟩, fun ⟨l₁, l₂, l0, aL, h⟩ => ⟨_, aL, l₁, l₂, l0, rfl, h⟩⟩ rw [foldr_permutationsAux2] - simp only [mem_permutationsAux2', ← this, or_comm, and_left_comm, mem_append, mem_bind, + simp only [mem_permutationsAux2', ← this, or_comm, and_left_comm, mem_append, mem_flatMap, append_assoc, cons_append, exists_prop] theorem length_foldr_permutationsAux2 (t : α) (ts : List α) (r L : List (List α)) : length (foldr (fun y r => (permutationsAux2 t ts r y id).2) r L) = Nat.sum (map length L) + length r := by - simp [foldr_permutationsAux2, Function.comp_def, length_permutationsAux2, length_bind'] + simp [foldr_permutationsAux2, Function.comp_def, length_permutationsAux2, length_flatMap'] theorem length_foldr_permutationsAux2' (t : α) (ts : List α) (r L : List (List α)) (n) (H : ∀ l ∈ L, length l = n) : @@ -215,7 +215,7 @@ theorem map_permutationsAux (f : α → β) : refine permutationsAux.rec (by simp) ?_ introv IH1 IH2; rw [map] at IH2 simp only [foldr_permutationsAux2, map_append, map, map_map_permutationsAux2, permutations, - bind_map, IH1, append_assoc, permutationsAux_cons, bind_cons, ← IH2, map_bind] + flatMap_map, IH1, append_assoc, permutationsAux_cons, flatMap_cons, ← IH2, map_flatMap] theorem map_permutations (f : α → β) (ts : List α) : map (map f) (permutations ts) = permutations (map f ts) := by @@ -223,13 +223,14 @@ theorem map_permutations (f : α → β) (ts : List α) : theorem map_permutations' (f : α → β) (ts : List α) : map (map f) (permutations' ts) = permutations' (map f ts) := by - induction' ts with t ts ih <;> [rfl; simp [← ih, map_bind, ← map_map_permutations'Aux, bind_map]] + induction' ts with t ts ih <;> + [rfl; simp [← ih, map_flatMap, ← map_map_permutations'Aux, flatMap_map]] theorem permutationsAux_append (is is' ts : List α) : permutationsAux (is ++ ts) is' = (permutationsAux is is').map (· ++ ts) ++ permutationsAux ts (is.reverse ++ is') := by induction' is with t is ih generalizing is'; · simp - simp only [foldr_permutationsAux2, ih, map_bind, cons_append, permutationsAux_cons, map_append, + simp only [foldr_permutationsAux2, ih, map_flatMap, cons_append, permutationsAux_cons, map_append, reverse_cons, append_assoc, singleton_append] congr 2 funext _ diff --git a/Mathlib/Data/List/Pi.lean b/Mathlib/Data/List/Pi.lean index 629d8a1e4f8553..c269bd13bc9ee0 100644 --- a/Mathlib/Data/List/Pi.lean +++ b/Mathlib/Data/List/Pi.lean @@ -72,14 +72,14 @@ variable {ι : Type*} [DecidableEq ι] {α : ι → Type*} /-- `pi xs f` creates the list of functions `g` such that, for `x ∈ xs`, `g x ∈ f x` -/ def pi : ∀ l : List ι, (∀ i, List (α i)) → List (∀ i, i ∈ l → α i) | [], _ => [List.Pi.nil α] - | i :: l, fs => (fs i).bind (fun b ↦ (pi l fs).map (List.Pi.cons _ _ b)) + | i :: l, fs => (fs i).flatMap (fun b ↦ (pi l fs).map (List.Pi.cons _ _ b)) @[simp] lemma pi_nil (t : ∀ i, List (α i)) : pi [] t = [Pi.nil α] := rfl @[simp] lemma pi_cons (i : ι) (l : List ι) (t : ∀ j, List (α j)) : - pi (i :: l) t = ((t i).bind fun b ↦ (pi l t).map <| Pi.cons _ _ b) := + pi (i :: l) t = ((t i).flatMap fun b ↦ (pi l t).map <| Pi.cons _ _ b) := rfl lemma _root_.Multiset.pi_coe (l : List ι) (fs : ∀ i, List (α i)) : diff --git a/Mathlib/Data/List/ProdSigma.lean b/Mathlib/Data/List/ProdSigma.lean index 5b55bac8afedbf..ed1fc2757b8599 100644 --- a/Mathlib/Data/List/ProdSigma.lean +++ b/Mathlib/Data/List/ProdSigma.lean @@ -39,7 +39,7 @@ theorem product_nil : ∀ l : List α, l ×ˢ (@nil β) = [] @[simp] theorem mem_product {l₁ : List α} {l₂ : List β} {a : α} {b : β} : (a, b) ∈ l₁ ×ˢ l₂ ↔ a ∈ l₁ ∧ b ∈ l₂ := by - simp_all [SProd.sprod, product, mem_bind, mem_map, Prod.ext_iff, exists_prop, and_left_comm, + simp_all [SProd.sprod, product, mem_flatMap, mem_map, Prod.ext_iff, exists_prop, and_left_comm, exists_and_left, exists_eq_left, exists_eq_right] theorem length_product (l₁ : List α) (l₂ : List β) : @@ -71,7 +71,7 @@ theorem sigma_nil : ∀ l : List α, (l.sigma fun a => @nil (σ a)) = [] @[simp] theorem mem_sigma {l₁ : List α} {l₂ : ∀ a, List (σ a)} {a : α} {b : σ a} : Sigma.mk a b ∈ l₁.sigma l₂ ↔ a ∈ l₁ ∧ b ∈ l₂ a := by - simp [List.sigma, mem_bind, mem_map, exists_prop, exists_and_left, and_left_comm, + simp [List.sigma, mem_flatMap, mem_map, exists_prop, exists_and_left, and_left_comm, exists_eq_left, heq_iff_eq, exists_eq_right] /-- See `List.length_sigma` for the corresponding statement using `List.sum`. -/ diff --git a/Mathlib/Data/List/Sections.lean b/Mathlib/Data/List/Sections.lean index c604e4d75e47c0..03bf99def29d61 100644 --- a/Mathlib/Data/List/Sections.lean +++ b/Mathlib/Data/List/Sections.lean @@ -23,12 +23,12 @@ theorem mem_sections {L : List (List α)} {f} : f ∈ sections L ↔ Forall₂ ( · induction L generalizing f · cases mem_singleton.1 h exact Forall₂.nil - simp only [sections, bind_eq_bind, mem_bind, mem_map] at h + simp only [sections, bind_eq_flatMap, mem_flatMap, mem_map] at h rcases h with ⟨_, _, _, _, rfl⟩ simp only [*, forall₂_cons, true_and] · induction' h with a l f L al fL fs · simp only [sections, mem_singleton] - simp only [sections, bind_eq_bind, mem_bind, mem_map] + simp only [sections, bind_eq_flatMap, mem_flatMap, mem_map] exact ⟨f, fs, a, al, rfl⟩ theorem mem_sections_length {L : List (List α)} {f} (h : f ∈ sections L) : length f = length L := @@ -38,6 +38,6 @@ theorem rel_sections {r : α → β → Prop} : (Forall₂ (Forall₂ r) ⇒ Forall₂ (Forall₂ r)) sections sections | _, _, Forall₂.nil => Forall₂.cons Forall₂.nil Forall₂.nil | _, _, Forall₂.cons h₀ h₁ => - rel_bind (rel_sections h₁) fun _ _ hl => rel_map (fun _ _ ha => Forall₂.cons ha hl) h₀ + rel_flatMap (rel_sections h₁) fun _ _ hl => rel_map (fun _ _ ha => Forall₂.cons ha hl) h₀ end List diff --git a/Mathlib/Data/List/Sublists.lean b/Mathlib/Data/List/Sublists.lean index a01b524b626c68..a0cdcf86d53f50 100644 --- a/Mathlib/Data/List/Sublists.lean +++ b/Mathlib/Data/List/Sublists.lean @@ -112,19 +112,21 @@ theorem sublistsAux_eq_array_foldl : (by simp) simpa using this -theorem sublistsAux_eq_bind : - sublistsAux = fun (a : α) (r : List (List α)) => r.bind fun l => [l, a :: l] := +theorem sublistsAux_eq_flatMap : + sublistsAux = fun (a : α) (r : List (List α)) => r.flatMap fun l => [l, a :: l] := funext fun a => funext fun r => List.reverseRecOn r (by simp [sublistsAux]) (fun r l ih => by - rw [bind_append, ← ih, bind_singleton, sublistsAux, foldl_append] + rw [flatMap_append, ← ih, flatMap_singleton, sublistsAux, foldl_append] simp [sublistsAux]) +@[deprecated (since := "2024-10-16")] alias sublistsAux_eq_bind := sublistsAux_eq_flatMap + @[csimp] theorem sublists_eq_sublistsFast : @sublists = @sublistsFast := by ext α l : 2 trans l.foldr sublistsAux [[]] - · rw [sublistsAux_eq_bind, sublists] + · rw [sublistsAux_eq_flatMap, sublists] · simp only [sublistsFast, sublistsAux_eq_array_foldl, Array.foldr_eq_foldr_toList] rw [← foldr_hom Array.toList] · intros _ _; congr @@ -136,24 +138,25 @@ theorem sublists_append (l₁ l₂ : List α) : | nil => simp | cons a l₁ ih => rw [foldr_cons, ih] - simp [List.bind, flatten_flatten, Function.comp_def] + simp [List.flatMap, flatten_flatten, Function.comp_def] theorem sublists_cons (a : α) (l : List α) : sublists (a :: l) = sublists l >>= (fun x => [x, a :: x]) := show sublists ([a] ++ l) = _ by rw [sublists_append] - simp only [sublists_singleton, map_cons, bind_eq_bind, nil_append, cons_append, map_nil] + simp only [sublists_singleton, map_cons, bind_eq_flatMap, nil_append, cons_append, map_nil] @[simp] theorem sublists_concat (l : List α) (a : α) : sublists (l ++ [a]) = sublists l ++ map (fun x => x ++ [a]) (sublists l) := by - rw [sublists_append, sublists_singleton, bind_eq_bind, bind_cons, bind_cons, bind_nil, + rw [sublists_append, sublists_singleton, bind_eq_flatMap, flatMap_cons, flatMap_cons, flatMap_nil, map_id'' append_nil, append_nil] theorem sublists_reverse (l : List α) : sublists (reverse l) = map reverse (sublists' l) := by induction' l with hd tl ih <;> [rfl; simp only [reverse_cons, sublists_append, sublists'_cons, map_append, ih, sublists_singleton, - map_eq_map, bind_eq_bind, map_map, bind_cons, append_nil, bind_nil, Function.comp_def]] + map_eq_map, bind_eq_flatMap, map_map, flatMap_cons, append_nil, flatMap_nil, + Function.comp_def]] theorem sublists_eq_sublists' (l : List α) : sublists l = map reverse (sublists' (reverse l)) := by rw [← sublists_reverse, reverse_reverse] @@ -343,8 +346,8 @@ theorem sublists_map (f : α → β) : ∀ (l : List α), sublists (map f l) = map (map f) (sublists l) | [] => by simp | a::l => by - rw [map_cons, sublists_cons, bind_eq_bind, sublists_map f l, sublists_cons, - bind_eq_bind, map_eq_bind, map_eq_bind] + rw [map_cons, sublists_cons, bind_eq_flatMap, sublists_map f l, sublists_cons, + bind_eq_flatMap, map_eq_flatMap, map_eq_flatMap] induction sublists l <;> simp [*] theorem sublists'_map (f : α → β) : ∀ (l : List α), @@ -400,19 +403,19 @@ theorem revzip_sublists' (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip · exact (IH _ _ h).cons _ theorem range_bind_sublistsLen_perm (l : List α) : - ((List.range (l.length + 1)).bind fun n => sublistsLen n l) ~ sublists' l := by + ((List.range (l.length + 1)).flatMap fun n => sublistsLen n l) ~ sublists' l := by induction' l with h tl l_ih · simp [range_succ] - · simp_rw [range_succ_eq_map, length, bind_cons, bind_map, sublistsLen_succ_cons, sublists'_cons, - List.sublistsLen_zero, List.singleton_append] - refine ((bind_append_perm (range (tl.length + 1)) _ _).symm.cons _).trans ?_ - simp_rw [← List.map_bind, ← cons_append] + · simp_rw [range_succ_eq_map, length, flatMap_cons, flatMap_map, sublistsLen_succ_cons, + sublists'_cons, List.sublistsLen_zero, List.singleton_append] + refine ((flatMap_append_perm (range (tl.length + 1)) _ _).symm.cons _).trans ?_ + simp_rw [← List.map_flatMap, ← cons_append] rw [← List.singleton_append, ← List.sublistsLen_zero tl] refine Perm.append ?_ (l_ih.map _) - rw [List.range_succ, bind_append, bind_singleton, + rw [List.range_succ, flatMap_append, flatMap_singleton, sublistsLen_of_length_lt (Nat.lt_succ_self _), append_nil, - ← List.bind_map Nat.succ fun n => sublistsLen n tl, - ← bind_cons 0 _ fun n => sublistsLen n tl, ← range_succ_eq_map] + ← List.flatMap_map Nat.succ fun n => sublistsLen n tl, + ← flatMap_cons 0 _ fun n => sublistsLen n tl, ← range_succ_eq_map] exact l_ih end List diff --git a/Mathlib/Data/Multiset/Bind.lean b/Mathlib/Data/Multiset/Bind.lean index 2f8c64e94ac94c..5c17aae5730e13 100644 --- a/Mathlib/Data/Multiset/Bind.lean +++ b/Mathlib/Data/Multiset/Bind.lean @@ -99,8 +99,8 @@ def bind (s : Multiset α) (f : α → Multiset β) : Multiset β := (s.map f).join @[simp] -theorem coe_bind (l : List α) (f : α → List β) : (@bind α β l fun a => f a) = l.bind f := by - rw [List.bind, ← coe_join, List.map_map] +theorem coe_bind (l : List α) (f : α → List β) : (@bind α β l fun a => f a) = l.flatMap f := by + rw [List.flatMap, ← coe_join, List.map_map] rfl @[simp] @@ -207,7 +207,7 @@ variable {f s t} choose f' h' using this have : f = fun a ↦ ofList (f' a) := funext h' have hd : Symmetric fun a b ↦ List.Disjoint (f' a) (f' b) := fun a b h ↦ h.symm - exact Quot.induction_on s <| by simp [this, List.nodup_bind, pairwise_coe_iff_pairwise hd] + exact Quot.induction_on s <| by simp [this, List.nodup_flatMap, pairwise_coe_iff_pairwise hd] @[simp] lemma dedup_bind_dedup [DecidableEq α] [DecidableEq β] (s : Multiset α) (f : α → Multiset β) : diff --git a/Mathlib/Data/Multiset/Powerset.lean b/Mathlib/Data/Multiset/Powerset.lean index 924f768a2ffbb5..e8f1d0420d6fb4 100644 --- a/Mathlib/Data/Multiset/Powerset.lean +++ b/Mathlib/Data/Multiset/Powerset.lean @@ -269,8 +269,8 @@ theorem pairwise_disjoint_powersetCard (s : Multiset α) : theorem bind_powerset_len {α : Type*} (S : Multiset α) : (bind (Multiset.range (card S + 1)) fun k => S.powersetCard k) = S.powerset := by induction S using Quotient.inductionOn - simp_rw [quot_mk_to_coe, powerset_coe', powersetCard_coe, ← coe_range, coe_bind, ← List.map_bind, - coe_card] + simp_rw [quot_mk_to_coe, powerset_coe', powersetCard_coe, ← coe_range, coe_bind, + ← List.map_flatMap, coe_card] exact coe_eq_coe.mpr ((List.range_bind_sublistsLen_perm _).map _) @[simp] diff --git a/Mathlib/Data/Multiset/Sections.lean b/Mathlib/Data/Multiset/Sections.lean index 4cc916de7c550d..e6474a3568c73a 100644 --- a/Mathlib/Data/Multiset/Sections.lean +++ b/Mathlib/Data/Multiset/Sections.lean @@ -42,7 +42,7 @@ theorem coe_sections : | a :: l => by simp only [List.map_cons, List.sections] rw [← cons_coe, sections_cons, bind_map_comm, coe_sections l] - simp [List.sections, Function.comp_def, List.bind] + simp [List.sections, Function.comp_def, List.flatMap] @[simp] theorem sections_add (s t : Multiset (Multiset α)) : diff --git a/Mathlib/ModelTheory/Encoding.lean b/Mathlib/ModelTheory/Encoding.lean index b8219e55752e1e..cff44b0f3e2771 100644 --- a/Mathlib/ModelTheory/Encoding.lean +++ b/Mathlib/ModelTheory/Encoding.lean @@ -53,7 +53,7 @@ namespace Term def listEncode : L.Term α → List (α ⊕ (Σi, L.Functions i)) | var i => [Sum.inl i] | func f ts => - Sum.inr (⟨_, f⟩ : Σi, L.Functions i)::(List.finRange _).bind fun i => (ts i).listEncode + Sum.inr (⟨_, f⟩ : Σi, L.Functions i)::(List.finRange _).flatMap fun i => (ts i).listEncode /-- Decodes a list of variables and function symbols as a list of terms. -/ def listDecode : List (α ⊕ (Σi, L.Functions i)) → List (L.Term α) @@ -65,21 +65,21 @@ def listDecode : List (α ⊕ (Σi, L.Functions i)) → List (L.Term α) else [] theorem listDecode_encode_list (l : List (L.Term α)) : - listDecode (l.bind listEncode) = l := by + listDecode (l.flatMap listEncode) = l := by suffices h : ∀ (t : L.Term α) (l : List (α ⊕ (Σi, L.Functions i))), listDecode (t.listEncode ++ l) = t::listDecode l by induction' l with t l lih · rfl - · rw [bind_cons, h t (l.bind listEncode), lih] + · rw [flatMap_cons, h t (l.flatMap listEncode), lih] intro t induction' t with a n f ts ih <;> intro l · rw [listEncode, singleton_append, listDecode] · rw [listEncode, cons_append, listDecode] - have h : listDecode (((finRange n).bind fun i : Fin n => (ts i).listEncode) ++ l) = + have h : listDecode (((finRange n).flatMap fun i : Fin n => (ts i).listEncode) ++ l) = (finRange n).map ts ++ listDecode l := by induction' finRange n with i l' l'ih · rfl - · rw [bind_cons, List.append_assoc, ih, map_cons, l'ih, cons_append] + · rw [flatMap_cons, List.append_assoc, ih, map_cons, l'ih, cons_append] simp only [h, length_append, length_map, length_finRange, le_add_iff_nonneg_right, _root_.zero_le, ↓reduceDIte, getElem_fin, cons.injEq, func.injEq, heq_eq_eq, true_and] refine ⟨funext (fun i => ?_), ?_⟩ @@ -95,7 +95,7 @@ protected def encoding : Encoding (L.Term α) where decode l := (listDecode l).head?.join decode_encode t := by have h := listDecode_encode_list [t] - rw [bind_singleton] at h + rw [flatMap_singleton] at h simp only [Option.join, h, head?_cons, Option.pure_def, Option.bind_eq_bind, Option.some_bind, id_eq] @@ -140,7 +140,7 @@ theorem card_sigma : #(Σn, L.Term (α ⊕ (Fin n))) = max ℵ₀ #(α ⊕ (Σi, instance [Encodable α] [Encodable (Σi, L.Functions i)] : Encodable (L.Term α) := Encodable.ofLeftInjection listEncode (fun l => (listDecode l).head?.join) fun t => by simp only - rw [← bind_singleton listEncode, listDecode_encode_list] + rw [← flatMap_singleton listEncode, listDecode_encode_list] simp only [Option.join, head?_cons, Option.pure_def, Option.bind_eq_bind, Option.some_bind, id_eq] @@ -218,14 +218,14 @@ def listDecode : @[simp] theorem listDecode_encode_list (l : List (Σn, L.BoundedFormula α n)) : - listDecode (l.bind (fun φ => φ.2.listEncode)) = l := by + listDecode (l.flatMap (fun φ => φ.2.listEncode)) = l := by suffices h : ∀ (φ : Σn, L.BoundedFormula α n) (l' : List ((Σk, L.Term (α ⊕ Fin k)) ⊕ ((Σn, L.Relations n) ⊕ ℕ))), (listDecode (listEncode φ.2 ++ l')) = φ::(listDecode l') by induction' l with φ l ih - · rw [List.bind_nil] + · rw [List.flatMap_nil] simp [listDecode] - · rw [bind_cons, h φ _, ih] + · rw [flatMap_cons, h φ _, ih] rintro ⟨n, φ⟩ induction φ with | falsum => intro l; rw [listEncode, singleton_append, listDecode] @@ -285,7 +285,7 @@ protected def encoding : Encoding (Σn, L.BoundedFormula α n) where decode l := (listDecode l)[0]? decode_encode φ := by have h := listDecode_encode_list [φ] - rw [bind_singleton] at h + rw [flatMap_singleton] at h simp only rw [h] rfl diff --git a/Mathlib/Tactic/Simps/Basic.lean b/Mathlib/Tactic/Simps/Basic.lean index 1caba0e4825aba..9214c8da797c7c 100644 --- a/Mathlib/Tactic/Simps/Basic.lean +++ b/Mathlib/Tactic/Simps/Basic.lean @@ -1153,7 +1153,7 @@ partial def addProjections (nm : Name) (type lhs rhs : Expr) \n `initialize_simps_projections? {str}`.\n\ Note: these projection names might be customly defined for `simps`, \ and could differ from the projection names of the structure." - let nms ← projInfo.concatMapM fun ⟨newRhs, proj, projExpr, projNrs, isDefault, isPrefix⟩ ↦ do + let nms ← projInfo.flatMapM fun ⟨newRhs, proj, projExpr, projNrs, isDefault, isPrefix⟩ ↦ do let newType ← inferType newRhs let newTodo := todo.filterMap fun (x, stx) ↦ (dropPrefixIfNotNumber? x (proj.lastComponentAsString ++ "_")).map diff --git a/Mathlib/Testing/SlimCheck/Sampleable.lean b/Mathlib/Testing/SlimCheck/Sampleable.lean index 9636bc1f1368ac..1433c1962e259e 100644 --- a/Mathlib/Testing/SlimCheck/Sampleable.lean +++ b/Mathlib/Testing/SlimCheck/Sampleable.lean @@ -163,7 +163,7 @@ instance Int.shrinkable : Shrinkable Int where instance Rat.shrinkable : Shrinkable Rat where shrink r := - (Shrinkable.shrink r.num).bind fun d => Nat.shrink r.den |>.map fun n => Rat.divInt d n + (Shrinkable.shrink r.num).flatMap fun d => Nat.shrink r.den |>.map fun n => Rat.divInt d n instance Bool.shrinkable : Shrinkable Bool := {} instance Char.shrinkable : Shrinkable Char := {} diff --git a/lake-manifest.json b/lake-manifest.json index 3483aa5156c1df..86db2abbc420e8 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "0e55c5ddf1f0be57ebdffa9f44fc98882b1a9a41", + "rev": "b4cb0a5212271f661c27f52ef0923be1ec3ddd0b", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "lean-pr-testing-5731", @@ -25,10 +25,10 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "b20a88676fd00affb90cbc9f1ff004ae588103b3", + "rev": "5736e15a5dbd3eac3e98b539df00dfd147585482", "name": "aesop", "manifestFile": "lake-manifest.json", - "inputRev": "master", + "inputRev": "lean-pr-testing-5731", "inherited": false, "configFile": "lakefile.toml"}, {"url": "https://github.com/leanprover-community/ProofWidgets4", @@ -55,10 +55,10 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "9b4088ccf0f44ddd7b1132bb1348aef8cf481e12", + "rev": "c2913a0d46da4699971b7a6d45190e562584e0ba", "name": "importGraph", "manifestFile": "lake-manifest.json", - "inputRev": "main", + "inputRev": "lean-pr-testing-5731", "inherited": false, "configFile": "lakefile.toml"}, {"url": "https://github.com/leanprover-community/LeanSearchClient", diff --git a/lakefile.lean b/lakefile.lean index 688c43af3b207f..36ddb8a2d3f76e 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -9,9 +9,9 @@ open Lake DSL require "leanprover-community" / "batteries" @ git "lean-pr-testing-5731" require "leanprover-community" / "Qq" @ git "master" -require "leanprover-community" / "aesop" @ git "master" +require "leanprover-community" / "aesop" @ git "lean-pr-testing-5731" require "leanprover-community" / "proofwidgets" @ git "v0.0.43-pre" -require "leanprover-community" / "importGraph" @ git "main" +require "leanprover-community" / "importGraph" @ git "lean-pr-testing-5731" require "leanprover-community" / "LeanSearchClient" @ git "main" from git "https://github.com/leanprover-community/LeanSearchClient" @ "main" From a04e77de8d85064d17515a54d5dc2b5e77a3dd0e Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Wed, 16 Oct 2024 10:53:42 +0000 Subject: [PATCH 212/425] Trigger CI for https://github.com/leanprover/lean4/pull/5732 --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index b7eb4db14e6003..37281019e476e1 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "fd223041ee7c5c9ea183c8995ef2822543e3e56e", + "rev": "8dbc730e0a6a73324ce0b93405447eda5bf57aa0", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "lean-pr-testing-5732", From 522cf155307e5a95b7242044222708aee40363a8 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 21:56:22 +1100 Subject: [PATCH 213/425] . --- Mathlib/Data/Multiset/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Data/Multiset/Basic.lean b/Mathlib/Data/Multiset/Basic.lean index 97ed4b8d3f67f8..b54ec18a4e5313 100644 --- a/Mathlib/Data/Multiset/Basic.lean +++ b/Mathlib/Data/Multiset/Basic.lean @@ -1780,7 +1780,7 @@ theorem filter_cons {a : α} (s : Multiset α) : theorem filter_singleton {a : α} (p : α → Prop) [DecidablePred p] : filter p {a} = if p a then {a} else ∅ := by - simp only [Singleton.singleton, filter_cons, filter_zero, add_zero, empty_eq_zero] + simp only [singleton, filter_cons, filter_zero, add_zero, empty_eq_zero] theorem filter_nsmul (s : Multiset α) (n : ℕ) : filter p (n • s) = n • filter p s := by refine s.induction_on ?_ ?_ From c413259dcbda2b17ccee6b75c3f74f9d60ca462b Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 22:00:29 +1100 Subject: [PATCH 214/425] bump aesop --- lake-manifest.json | 4 ++-- lakefile.lean | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index abd0e77c070fae..23d24ea19734bc 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -25,10 +25,10 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "b20a88676fd00affb90cbc9f1ff004ae588103b3", + "rev": "6503af80a441d6d5351e60e6256b45d135d46d50", "name": "aesop", "manifestFile": "lake-manifest.json", - "inputRev": "master", + "inputRev": "nightly-testing", "inherited": false, "configFile": "lakefile.toml"}, {"url": "https://github.com/leanprover-community/ProofWidgets4", diff --git a/lakefile.lean b/lakefile.lean index e587975da38fdc..745cde3759780f 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -9,7 +9,7 @@ open Lake DSL require "leanprover-community" / "batteries" @ git "nightly-testing" require "leanprover-community" / "Qq" @ git "master" -require "leanprover-community" / "aesop" @ git "master" +require "leanprover-community" / "aesop" @ git "nightly-testing" require "leanprover-community" / "proofwidgets" @ git "v0.0.43-pre" require "leanprover-community" / "importGraph" @ git "main" require "leanprover-community" / "LeanSearchClient" @ git "main" From ea31955799668d5e616f65768165103e4cf26f03 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 22:01:58 +1100 Subject: [PATCH 215/425] rm open private --- Mathlib/Tactic/Core.lean | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mathlib/Tactic/Core.lean b/Mathlib/Tactic/Core.lean index 1aeb2717c5047e..fc6cf43ed4dc64 100644 --- a/Mathlib/Tactic/Core.lean +++ b/Mathlib/Tactic/Core.lean @@ -19,7 +19,7 @@ open Lean.Elab.Tactic namespace Lean -open Elab +open Elab Meta /-- Return the modifiers of declaration `nm` with (optional) docstring `newDoc`. @@ -69,7 +69,6 @@ def toPreDefinition (nm newNm : Name) (newType newValue : Expr) (newDoc : Option def setProtected {m : Type → Type} [MonadEnv m] (nm : Name) : m Unit := modifyEnv (addProtected · nm) -open private getIntrosSize from Lean.Meta.Tactic.Intro in /-- Introduce variables, giving them names from a specified list. -/ def MVarId.introsWithBinderIdents (g : MVarId) (ids : List (TSyntax ``binderIdent)) : From 1816277a0ff8cdf4a9023e14fc018311de03c778 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 22:03:29 +1100 Subject: [PATCH 216/425] update batteries --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 23d24ea19734bc..9658c384500867 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "0a6bfc711cbc3b4a98d89a65bc904c361a792386", + "rev": "108e204d0822981f8d2c7c0e65f5201071126681", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "nightly-testing", From 36c03bdc010a49587fe6b786f92f6eb1e9a75040 Mon Sep 17 00:00:00 2001 From: Andrew Yang Date: Wed, 16 Oct 2024 11:05:15 +0000 Subject: [PATCH 217/425] refactor(AlgebraicGeometry): Make `Scheme.Hom` a structure. (#15093) We make `LocallyRingedSpace.Hom` (resp. `Scheme.Hom`) into a structure instead of a subtype (resp. type-synonym of the former) to make clearer the abstraction boundaries between them and presheafed spaces, which allow us to remove some `erw`s. Plus, this enables us to write `f.base` and `f.c` instead of `f.val.base` and `f.val.c`. Co-authored-by: Andrew Yang <36414270+erdOne@users.noreply.github.com> --- Mathlib/AlgebraicGeometry/AffineScheme.lean | 54 ++--- Mathlib/AlgebraicGeometry/Cover/Open.lean | 48 ++--- Mathlib/AlgebraicGeometry/FunctionField.lean | 4 +- .../GammaSpecAdjunction.lean | 60 +++--- Mathlib/AlgebraicGeometry/Gluing.lean | 42 ++-- Mathlib/AlgebraicGeometry/Limits.lean | 35 ++-- .../AlgebraicGeometry/Morphisms/Affine.lean | 4 +- .../AlgebraicGeometry/Morphisms/Basic.lean | 2 +- .../Morphisms/ClosedImmersion.lean | 16 +- .../Morphisms/Constructors.lean | 20 +- .../AlgebraicGeometry/Morphisms/IsIso.lean | 4 +- .../Morphisms/OpenImmersion.lean | 4 +- .../Morphisms/Preimmersion.lean | 6 +- .../Morphisms/QuasiCompact.lean | 18 +- .../Morphisms/QuasiSeparated.lean | 2 +- .../Morphisms/RingHomProperties.lean | 2 +- .../Morphisms/UnderlyingMap.lean | 6 +- .../Morphisms/UniversallyClosed.lean | 4 +- Mathlib/AlgebraicGeometry/Noetherian.lean | 2 +- Mathlib/AlgebraicGeometry/OpenImmersion.lean | 139 ++++++------- .../ProjectiveSpectrum/Scheme.lean | 34 +-- Mathlib/AlgebraicGeometry/Properties.lean | 14 +- Mathlib/AlgebraicGeometry/Pullbacks.lean | 20 +- Mathlib/AlgebraicGeometry/ResidueField.lean | 22 +- Mathlib/AlgebraicGeometry/Restrict.lean | 36 ++-- Mathlib/AlgebraicGeometry/Scheme.lean | 195 ++++++++++-------- Mathlib/AlgebraicGeometry/Spec.lean | 10 +- .../RingedSpace/LocallyRingedSpace.lean | 152 ++++++++------ .../LocallyRingedSpace/HasColimits.lean | 109 +++++----- .../LocallyRingedSpace/ResidueField.lean | 32 +-- .../Geometry/RingedSpace/OpenImmersion.lean | 68 +++--- .../Geometry/RingedSpace/PresheafedSpace.lean | 3 + .../RingedSpace/PresheafedSpace/Gluing.lean | 2 +- 33 files changed, 608 insertions(+), 561 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AffineScheme.lean b/Mathlib/AlgebraicGeometry/AffineScheme.lean index 35d58412138ae3..731a32691323c1 100644 --- a/Mathlib/AlgebraicGeometry/AffineScheme.lean +++ b/Mathlib/AlgebraicGeometry/AffineScheme.lean @@ -281,12 +281,12 @@ def isoSpec : (X.presheaf.mapIso (eqToIso U.openEmbedding_obj_top).op).op open LocalRing in -lemma isoSpec_hom_val_base_apply (x : U) : - hU.isoSpec.hom.1.base x = (Spec.map (X.presheaf.germ _ x x.2)).val.base (closedPoint _) := by - dsimp [IsAffineOpen.isoSpec_hom, Scheme.isoSpec_hom, Scheme.toSpecΓ_val_base] - rw [← Scheme.comp_val_base_apply, ← Spec.map_comp, +lemma isoSpec_hom_base_apply (x : U) : + hU.isoSpec.hom.base x = (Spec.map (X.presheaf.germ _ x x.2)).base (closedPoint _) := by + dsimp [IsAffineOpen.isoSpec_hom, Scheme.isoSpec_hom, Scheme.toSpecΓ_base] + rw [← Scheme.comp_base_apply, ← Spec.map_comp, (Iso.eq_comp_inv _).mpr (Scheme.Opens.germ_stalkIso_hom U (V := ⊤) x trivial), - X.presheaf.germ_res_assoc, Spec.map_comp, Scheme.comp_val_base_apply] + X.presheaf.germ_res_assoc, Spec.map_comp, Scheme.comp_base_apply] congr 1 have := isLocalRingHom_of_isIso (U.stalkIso x).inv exact LocalRing.comap_closedPoint (U.stalkIso x).inv @@ -322,7 +322,7 @@ lemma isoSpec_inv_ι : hU.isoSpec.inv ≫ U.ι = hU.fromSpec := rfl @[simp] theorem range_fromSpec : - Set.range hU.fromSpec.1.base = (U : Set X) := by + Set.range hU.fromSpec.base = (U : Set X) := by delta IsAffineOpen.fromSpec; dsimp [IsAffineOpen.isoSpec_inv] rw [Set.range_comp, Set.range_iff_surjective.mpr, Set.image_univ] · exact Subtype.range_coe @@ -374,7 +374,7 @@ lemma fromSpec_app_of_le (V : X.Opens) (h : U ≤ V) : include hU in protected theorem isCompact : IsCompact (U : Set X) := by - convert @IsCompact.image _ _ _ _ Set.univ hU.fromSpec.1.base PrimeSpectrum.compactSpace.1 + convert @IsCompact.image _ _ _ _ Set.univ hU.fromSpec.base PrimeSpectrum.compactSpace.1 (by fun_prop) convert hU.range_fromSpec.symm exact Set.image_univ @@ -398,7 +398,7 @@ theorem _root_.AlgebraicGeometry.Scheme.Hom.isAffineOpen_iff_of_isOpenImmersion refine ⟨fun hU => @isAffine_of_isIso _ _ (IsOpenImmersion.isoOfRangeEq (X.ofRestrict U.openEmbedding ≫ f) (Y.ofRestrict _) ?_).hom ?_ hU, fun hU => hU.image_of_isOpenImmersion f⟩ - · rw [Scheme.comp_val_base, coe_comp, Set.range_comp] + · rw [Scheme.comp_base, coe_comp, Set.range_comp] dsimp [Opens.coe_inclusion', Scheme.restrict] erw [Subtype.range_coe, Subtype.range_coe] -- now `erw` after #13170 rfl @@ -467,7 +467,7 @@ theorem fromSpec_image_basicOpen : hU.fromSpec ''ᵁ (PrimeSpectrum.basicOpen f) = X.basicOpen f := by rw [← hU.fromSpec_preimage_basicOpen] ext1 - change hU.fromSpec.val.base '' (hU.fromSpec.val.base ⁻¹' (X.basicOpen f : Set X)) = _ + change hU.fromSpec.base '' (hU.fromSpec.base ⁻¹' (X.basicOpen f : Set X)) = _ rw [Set.image_preimage_eq_inter_range, Set.inter_eq_left, hU.range_fromSpec] exact Scheme.basicOpen_le _ _ @@ -519,7 +519,7 @@ this is the canonical map `Γ(𝒪ₓ, D(f)) ⟶ Γ(Spec 𝒪ₓ(U), D(f))` This is an isomorphism, as witnessed by an `IsIso` instance. -/ def basicOpenSectionsToAffine : Γ(X, X.basicOpen f) ⟶ Γ(Spec Γ(X, U), PrimeSpectrum.basicOpen f) := - hU.fromSpec.1.c.app (op <| X.basicOpen f) ≫ + hU.fromSpec.c.app (op <| X.basicOpen f) ≫ (Spec Γ(X, U)).presheaf.map (eqToHom <| (hU.fromSpec_preimage_basicOpen f).symm).op instance basicOpenSectionsToAffine_isIso : @@ -607,28 +607,28 @@ theorem _root_.AlgebraicGeometry.exists_basicOpen_le_affine_inter /-- The prime ideal of `𝒪ₓ(U)` corresponding to a point `x : U`. -/ noncomputable def primeIdealOf (x : U) : PrimeSpectrum Γ(X, U) := - hU.isoSpec.hom.1.base x + hU.isoSpec.hom.base x theorem fromSpec_primeIdealOf (x : U) : - hU.fromSpec.val.base (hU.primeIdealOf x) = x.1 := by + hU.fromSpec.base (hU.primeIdealOf x) = x.1 := by dsimp only [IsAffineOpen.fromSpec, Subtype.coe_mk, IsAffineOpen.primeIdealOf] - rw [← Scheme.comp_val_base_apply, Iso.hom_inv_id_assoc] + rw [← Scheme.comp_base_apply, Iso.hom_inv_id_assoc] rfl open LocalRing in theorem primeIdealOf_eq_map_closedPoint (x : U) : - hU.primeIdealOf x = (Spec.map (X.presheaf.germ _ x x.2)).val.base (closedPoint _) := - hU.isoSpec_hom_val_base_apply _ + hU.primeIdealOf x = (Spec.map (X.presheaf.germ _ x x.2)).base (closedPoint _) := + hU.isoSpec_hom_base_apply _ -theorem isLocalization_stalk' (y : PrimeSpectrum Γ(X, U)) (hy : hU.fromSpec.1.base y ∈ U) : +theorem isLocalization_stalk' (y : PrimeSpectrum Γ(X, U)) (hy : hU.fromSpec.base y ∈ U) : @IsLocalization.AtPrime (R := Γ(X, U)) - (S := X.presheaf.stalk <| hU.fromSpec.1.base y) _ _ + (S := X.presheaf.stalk <| hU.fromSpec.base y) _ _ ((TopCat.Presheaf.algebra_section_stalk X.presheaf _)) y.asIdeal _ := by apply (@IsLocalization.isLocalization_iff_of_ringEquiv (R := Γ(X, U)) - (S := X.presheaf.stalk (hU.fromSpec.1.base y)) _ y.asIdeal.primeCompl _ - (TopCat.Presheaf.algebra_section_stalk X.presheaf ⟨hU.fromSpec.1.base y, hy⟩) _ _ + (S := X.presheaf.stalk (hU.fromSpec.base y)) _ y.asIdeal.primeCompl _ + (TopCat.Presheaf.algebra_section_stalk X.presheaf ⟨hU.fromSpec.base y, hy⟩) _ _ (asIso <| hU.fromSpec.stalkMap y).commRingCatIsoToRingEquiv).mpr -- Porting note: need to know what the ring is and after convert, instead of equality -- we get an `iff`. @@ -646,7 +646,7 @@ theorem isLocalization_stalk (x : U) : IsLocalization.AtPrime (X.presheaf.stalk x) (hU.primeIdealOf x).asIdeal := by rcases x with ⟨x, hx⟩ set y := hU.primeIdealOf ⟨x, hx⟩ with hy - have : hU.fromSpec.val.base y = x := hy ▸ hU.fromSpec_primeIdealOf ⟨x, hx⟩ + have : hU.fromSpec.base y = x := hy ▸ hU.fromSpec_primeIdealOf ⟨x, hx⟩ clear_value y subst this exact hU.isLocalization_stalk' y hx @@ -666,11 +666,11 @@ theorem basicOpen_union_eq_self_iff (s : Set Γ(X, U)) : ⨆ f : s, X.basicOpen (f : Γ(X, U)) = U ↔ Ideal.span s = ⊤ := by trans ⋃ i : s, (PrimeSpectrum.basicOpen i.1).1 = Set.univ · trans - hU.fromSpec.1.base ⁻¹' (⨆ f : s, X.basicOpen (f : Γ(X, U))).1 = - hU.fromSpec.1.base ⁻¹' U.1 + hU.fromSpec.base ⁻¹' (⨆ f : s, X.basicOpen (f : Γ(X, U))).1 = + hU.fromSpec.base ⁻¹' U.1 · refine ⟨fun h => by rw [h], ?_⟩ intro h - apply_fun Set.image hU.fromSpec.1.base at h + apply_fun Set.image hU.fromSpec.base at h rw [Set.image_preimage_eq_inter_range, Set.image_preimage_eq_inter_range, hU.range_fromSpec] at h simp only [Set.inter_self, Opens.carrier_eq_coe, Set.inter_eq_right] at h @@ -765,7 +765,7 @@ section ZeroLocus /-- On a locally ringed space `X`, the preimage of the zero locus of the prime spectrum of `Γ(X, ⊤)` under `toΓSpecFun` agrees with the associated zero locus on `X`. -/ lemma Scheme.toΓSpec_preimage_zeroLocus_eq {X : Scheme.{u}} (s : Set Γ(X, ⊤)) : - X.toSpecΓ.val.base ⁻¹' PrimeSpectrum.zeroLocus s = X.zeroLocus s := + X.toSpecΓ.base ⁻¹' PrimeSpectrum.zeroLocus s = X.zeroLocus s := LocallyRingedSpace.toΓSpec_preimage_zeroLocus_eq s open ConcreteCategory @@ -774,9 +774,9 @@ open ConcreteCategory is the zero locus in terms of the prime spectrum of `Γ(X, ⊤)`. -/ lemma Scheme.toΓSpec_image_zeroLocus_eq_of_isAffine {X : Scheme.{u}} [IsAffine X] (s : Set Γ(X, ⊤)) : - X.isoSpec.hom.val.base '' X.zeroLocus s = PrimeSpectrum.zeroLocus s := by + X.isoSpec.hom.base '' X.zeroLocus s = PrimeSpectrum.zeroLocus s := by erw [← X.toΓSpec_preimage_zeroLocus_eq, Set.image_preimage_eq] - exact (bijective_of_isIso X.isoSpec.hom.val.base).surjective + exact (bijective_of_isIso X.isoSpec.hom.base).surjective /-- If `X` is an affine scheme, every closed set of `X` is the zero locus of a set of global sections. -/ @@ -788,7 +788,7 @@ lemma Scheme.eq_zeroLocus_of_isClosed_of_isAffine (X : Scheme.{u}) [IsAffine X] obtain ⟨I, (hI : Z = _)⟩ := (PrimeSpectrum.isClosed_iff_zeroLocus_ideal _).mp hZ use I simp only [← Scheme.toΓSpec_preimage_zeroLocus_eq, ← hI, Z] - erw [Set.preimage_image_eq _ (bijective_of_isIso X.isoSpec.hom.val.base).injective] + erw [Set.preimage_image_eq _ (bijective_of_isIso X.isoSpec.hom.base).injective] · rintro ⟨I, rfl⟩ exact zeroLocus_isClosed X I.carrier diff --git a/Mathlib/AlgebraicGeometry/Cover/Open.lean b/Mathlib/AlgebraicGeometry/Cover/Open.lean index d24109a03e4e46..836bfdf366a33f 100644 --- a/Mathlib/AlgebraicGeometry/Cover/Open.lean +++ b/Mathlib/AlgebraicGeometry/Cover/Open.lean @@ -49,7 +49,7 @@ structure OpenCover (X : Scheme.{u}) where /-- given a point of `x : X`, `f x` is the index of the subscheme which contains `x` -/ f : X → J /-- the subschemes covers `X` -/ - covers : ∀ x, x ∈ Set.range (map (f x)).1.base + covers : ∀ x, x ∈ Set.range (map (f x)).base /-- the embedding of subschemes are open immersions -/ IsOpen : ∀ x, IsOpenImmersion (map x) := by infer_instance @@ -65,7 +65,7 @@ def affineCover (X : Scheme.{u}) : OpenCover X where J := X obj x := Spec (X.local_affine x).choose_spec.choose map x := - ((X.local_affine x).choose_spec.choose_spec.some.inv ≫ X.toLocallyRingedSpace.ofRestrict _ : _) + ⟨(X.local_affine x).choose_spec.choose_spec.some.inv ≫ X.toLocallyRingedSpace.ofRestrict _⟩ f x := x covers := by intro x @@ -81,7 +81,7 @@ instance : Inhabited X.OpenCover := ⟨X.affineCover⟩ theorem OpenCover.iUnion_range {X : Scheme.{u}} (𝒰 : X.OpenCover) : - ⋃ i, Set.range (𝒰.map i).1.base = Set.univ := by + ⋃ i, Set.range (𝒰.map i).base = Set.univ := by rw [Set.eq_univ_iff_forall] intro x rw [Set.mem_iUnion] @@ -101,9 +101,9 @@ def OpenCover.bind (f : ∀ x : 𝒰.J, OpenCover (𝒰.obj x)) : OpenCover X wh f x := ⟨_, (f _).f (𝒰.covers x).choose⟩ covers x := by let y := (𝒰.covers x).choose - have hy : (𝒰.map (𝒰.f x)).val.base y = x := (𝒰.covers x).choose_spec + have hy : (𝒰.map (𝒰.f x)).base y = x := (𝒰.covers x).choose_spec rcases (f (𝒰.f x)).covers y with ⟨z, hz⟩ - change x ∈ Set.range ((f (𝒰.f x)).map ((f (𝒰.f x)).f y) ≫ 𝒰.map (𝒰.f x)).1.base + change x ∈ Set.range ((f (𝒰.f x)).map ((f (𝒰.f x)).f y) ≫ 𝒰.map (𝒰.f x)).base use z erw [comp_apply] rw [hz, hy] @@ -133,7 +133,7 @@ def OpenCover.copy {X : Scheme.{u}} (𝒰 : OpenCover X) (J : Type*) (obj : J { J, obj, map f := fun x => e₁.symm (𝒰.f x) covers := fun x => by - rw [e₂, Scheme.comp_val_base, TopCat.coe_comp, Set.range_comp, Set.range_iff_surjective.mpr, + rw [e₂, Scheme.comp_base, TopCat.coe_comp, Set.range_comp, Set.range_iff_surjective.mpr, Set.image_univ, e₁.rightInverse_symm] · exact 𝒰.covers x · rw [← TopCat.epi_iff_surjective]; infer_instance @@ -169,15 +169,15 @@ def OpenCover.pullbackCover {X W : Scheme.{u}} (𝒰 : X.OpenCover) (f : W ⟶ X J := 𝒰.J obj x := pullback f (𝒰.map x) map _ := pullback.fst _ _ - f x := 𝒰.f (f.1.base x) + f x := 𝒰.f (f.base x) covers x := by rw [← - show _ = (pullback.fst _ _ : pullback f (𝒰.map (𝒰.f (f.1.base x))) ⟶ _).1.base from - PreservesPullback.iso_hom_fst Scheme.forgetToTop f (𝒰.map (𝒰.f (f.1.base x)))] + show _ = (pullback.fst _ _ : pullback f (𝒰.map (𝒰.f (f.base x))) ⟶ _).base from + PreservesPullback.iso_hom_fst Scheme.forgetToTop f (𝒰.map (𝒰.f (f.base x)))] -- Porting note: `rw` to `erw` on this single lemma rw [TopCat.coe_comp, Set.range_comp, Set.range_iff_surjective.mpr, Set.image_univ, TopCat.pullback_fst_range] - · obtain ⟨y, h⟩ := 𝒰.covers (f.1.base x) + · obtain ⟨y, h⟩ := 𝒰.covers (f.base x) exact ⟨y, h.symm⟩ · rw [← TopCat.epi_iff_surjective]; infer_instance @@ -199,15 +199,15 @@ def OpenCover.pullbackCover' {X W : Scheme.{u}} (𝒰 : X.OpenCover) (f : W ⟶ J := 𝒰.J obj x := pullback (𝒰.map x) f map _ := pullback.snd _ _ - f x := 𝒰.f (f.1.base x) + f x := 𝒰.f (f.base x) covers x := by rw [← - show _ = (pullback.snd (𝒰.map (𝒰.f (f.1.base x))) f).1.base from - PreservesPullback.iso_hom_snd Scheme.forgetToTop (𝒰.map (𝒰.f (f.1.base x))) f] + show _ = (pullback.snd (𝒰.map (𝒰.f (f.base x))) f).base from + PreservesPullback.iso_hom_snd Scheme.forgetToTop (𝒰.map (𝒰.f (f.base x))) f] -- Porting note: `rw` to `erw` on this single lemma rw [TopCat.coe_comp, Set.range_comp, Set.range_iff_surjective.mpr, Set.image_univ, TopCat.pullback_snd_range] - · obtain ⟨y, h⟩ := 𝒰.covers (f.1.base x) + · obtain ⟨y, h⟩ := 𝒰.covers (f.base x) exact ⟨y, h⟩ · rw [← TopCat.epi_iff_surjective]; infer_instance @@ -217,10 +217,10 @@ def OpenCover.pullbackCover' {X W : Scheme.{u}} (𝒰 : X.OpenCover) (f : W ⟶ def OpenCover.finiteSubcover {X : Scheme.{u}} (𝒰 : OpenCover X) [H : CompactSpace X] : OpenCover X := by have := - @CompactSpace.elim_nhds_subcover _ _ H (fun x : X => Set.range (𝒰.map (𝒰.f x)).1.base) + @CompactSpace.elim_nhds_subcover _ _ H (fun x : X => Set.range (𝒰.map (𝒰.f x)).base) fun x => (IsOpenImmersion.isOpen_range (𝒰.map (𝒰.f x))).mem_nhds (𝒰.covers x) let t := this.choose - have h : ∀ x : X, ∃ y : t, x ∈ Set.range (𝒰.map (𝒰.f y)).1.base := by + have h : ∀ x : X, ∃ y : t, x ∈ Set.range (𝒰.map (𝒰.f y)).base := by intro x have h' : x ∈ (⊤ : Set X) := trivial rw [← Classical.choose_spec this, Set.mem_iUnion] at h' @@ -249,7 +249,7 @@ theorem OpenCover.compactSpace {X : Scheme.{u}} (𝒰 : X.OpenCover) [Finite (asIso (IsOpenImmersion.isoOfRangeEq (𝒰.map i) (X.ofRestrict (Opens.openEmbedding ⟨_, (𝒰.IsOpen i).base_open.isOpen_range⟩)) - Subtype.range_coe.symm).hom.1.base)) + Subtype.range_coe.symm).hom.base)) /-- Given open covers `{ Uᵢ }` and `{ Uⱼ }`, we may form the open cover `{ Uᵢ ∩ Uⱼ }`. -/ def OpenCover.inter {X : Scheme.{u}} (𝒰₁ : Scheme.OpenCover.{v₁} X) @@ -277,7 +277,7 @@ structure AffineOpenCover (X : Scheme.{u}) where /-- given a point of `x : X`, `f x` is the index of the subscheme which contains `x` -/ f : X → J /-- the subschemes covers `X` -/ - covers : ∀ x, x ∈ Set.range (map (f x)).1.base + covers : ∀ x, x ∈ Set.range (map (f x)).base /-- the embedding of subschemes are open immersions -/ IsOpen : ∀ x, IsOpenImmersion (map x) := by infer_instance @@ -462,7 +462,7 @@ def affineBasisCoverOfAffine (R : CommRingCat.{u}) : OpenCover (Spec R) where · exact trivial · -- Porting note: need more hand holding here because Lean knows that -- `CommRing.ofHom ...` is iso, but without `ofHom` Lean does not know what to do - change Epi (Spec.map (CommRingCat.ofHom (algebraMap _ _))).1.base + change Epi (Spec.map (CommRingCat.ofHom (algebraMap _ _))).base infer_instance IsOpen x := AlgebraicGeometry.Scheme.basic_open_isOpenImmersion x @@ -481,8 +481,8 @@ theorem affineBasisCover_obj (X : Scheme.{u}) (i : X.affineBasisCover.J) : theorem affineBasisCover_map_range (X : Scheme.{u}) (x : X) (r : (X.local_affine x).choose_spec.choose) : - Set.range (X.affineBasisCover.map ⟨x, r⟩).1.base = - (X.affineCover.map x).1.base '' (PrimeSpectrum.basicOpen r).1 := by + Set.range (X.affineBasisCover.map ⟨x, r⟩).base = + (X.affineCover.map x).base '' (PrimeSpectrum.basicOpen r).1 := by erw [coe_comp, Set.range_comp] -- Porting note: `congr` fails to see the goal is comparing image of the same function refine congr_arg (_ '' ·) ?_ @@ -491,16 +491,16 @@ theorem affineBasisCover_map_range (X : Scheme.{u}) (x : X) theorem affineBasisCover_is_basis (X : Scheme.{u}) : TopologicalSpace.IsTopologicalBasis {x : Set X | - ∃ a : X.affineBasisCover.J, x = Set.range (X.affineBasisCover.map a).1.base} := by + ∃ a : X.affineBasisCover.J, x = Set.range (X.affineBasisCover.map a).base} := by apply TopologicalSpace.isTopologicalBasis_of_isOpen_of_nhds · rintro _ ⟨a, rfl⟩ exact IsOpenImmersion.isOpen_range (X.affineBasisCover.map a) · rintro a U haU hU rcases X.affineCover.covers a with ⟨x, e⟩ - let U' := (X.affineCover.map (X.affineCover.f a)).1.base ⁻¹' U + let U' := (X.affineCover.map (X.affineCover.f a)).base ⁻¹' U have hxU' : x ∈ U' := by rw [← e] at haU; exact haU rcases PrimeSpectrum.isBasis_basic_opens.exists_subset_of_mem_open hxU' - ((X.affineCover.map (X.affineCover.f a)).1.base.continuous_toFun.isOpen_preimage _ + ((X.affineCover.map (X.affineCover.f a)).base.continuous_toFun.isOpen_preimage _ hU) with ⟨_, ⟨_, ⟨s, rfl⟩, rfl⟩, hxV, hVU⟩ refine ⟨_, ⟨⟨_, s⟩, rfl⟩, ?_, ?_⟩ <;> rw [affineBasisCover_map_range] diff --git a/Mathlib/AlgebraicGeometry/FunctionField.lean b/Mathlib/AlgebraicGeometry/FunctionField.lean index c58bde48fa4dbe..1b998330cf3664 100644 --- a/Mathlib/AlgebraicGeometry/FunctionField.lean +++ b/Mathlib/AlgebraicGeometry/FunctionField.lean @@ -75,9 +75,9 @@ theorem Scheme.germToFunctionField_injective [IsIntegral X] (U : X.Opens) [Nonem theorem genericPoint_eq_of_isOpenImmersion {X Y : Scheme} (f : X ⟶ Y) [H : IsOpenImmersion f] [hX : IrreducibleSpace X] [IrreducibleSpace Y] : - f.1.base (genericPoint X) = genericPoint Y := by + f.base (genericPoint X) = genericPoint Y := by apply ((genericPoint_spec Y).eq _).symm - convert (genericPoint_spec X).image (show Continuous f.1.base by fun_prop) + convert (genericPoint_spec X).image (show Continuous f.base by fun_prop) symm rw [eq_top_iff, Set.top_eq_univ, Set.top_eq_univ] convert subset_closure_inter_of_isPreirreducible_of_isOpen _ H.base_open.isOpen_range _ diff --git a/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean b/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean index 7bd7ef196c89a8..bd775fd8d0f992 100644 --- a/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean +++ b/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean @@ -193,9 +193,9 @@ theorem toStalk_stalkMap_toΓSpec (x : X) : exact (X.toΓSpecBase _* X.presheaf).germ_res le_top.hom _ _ /-- The canonical morphism from `X` to the spectrum of its global sections. -/ -@[simps! val_base] +@[simps! base] def toΓSpec : X ⟶ Spec.locallyRingedSpaceObj (Γ.obj (op X)) where - val := X.toΓSpecSheafedSpace + __ := X.toΓSpecSheafedSpace prop := by intro x let p : PrimeSpectrum (Γ.obj (op X)) := X.toΓSpecFun x @@ -220,11 +220,11 @@ def toΓSpec : X ⟶ Spec.locallyRingedSpaceObj (Γ.obj (op X)) where of `Γ(X, ⊤)` under `toΓSpec` agrees with the associated zero locus on `X`. -/ lemma toΓSpec_preimage_zeroLocus_eq {X : LocallyRingedSpace.{u}} (s : Set (X.presheaf.obj (op ⊤))) : - X.toΓSpec.val.base ⁻¹' PrimeSpectrum.zeroLocus s = X.toRingedSpace.zeroLocus s := by + X.toΓSpec.base ⁻¹' PrimeSpectrum.zeroLocus s = X.toRingedSpace.zeroLocus s := by simp only [RingedSpace.zeroLocus] have (i : LocallyRingedSpace.Γ.obj (op X)) (_ : i ∈ s) : ((X.toRingedSpace.basicOpen i).carrier)ᶜ = - X.toΓSpec.val.base ⁻¹' (PrimeSpectrum.basicOpen i).carrierᶜ := by + X.toΓSpec.base ⁻¹' (PrimeSpectrum.basicOpen i).carrierᶜ := by symm erw [Set.preimage_compl, X.toΓSpec_preimage_basicOpen_eq i] erw [Set.iInter₂_congr this] @@ -235,24 +235,24 @@ lemma toΓSpec_preimage_zeroLocus_eq {X : LocallyRingedSpace.{u}} theorem comp_ring_hom_ext {X : LocallyRingedSpace.{u}} {R : CommRingCat.{u}} {f : R ⟶ Γ.obj (op X)} {β : X ⟶ Spec.locallyRingedSpaceObj R} - (w : X.toΓSpec.1.base ≫ (Spec.locallyRingedSpaceMap f).1.base = β.1.base) + (w : X.toΓSpec.base ≫ (Spec.locallyRingedSpaceMap f).base = β.base) (h : ∀ r : R, - f ≫ X.presheaf.map (homOfLE le_top : (Opens.map β.1.base).obj (basicOpen r) ⟶ _).op = - toOpen R (basicOpen r) ≫ β.1.c.app (op (basicOpen r))) : + f ≫ X.presheaf.map (homOfLE le_top : (Opens.map β.base).obj (basicOpen r) ⟶ _).op = + toOpen R (basicOpen r) ≫ β.c.app (op (basicOpen r))) : X.toΓSpec ≫ Spec.locallyRingedSpaceMap f = β := by ext1 -- Porting note: was `apply Spec.basicOpen_hom_ext` refine Spec.basicOpen_hom_ext w ?_ intro r U - rw [LocallyRingedSpace.comp_val_c_app] + rw [LocallyRingedSpace.comp_c_app] erw [toOpen_comp_comap_assoc] rw [Category.assoc] erw [toΓSpecSheafedSpace_app_spec, ← X.presheaf.map_comp] exact h r /-- `toSpecΓ _` is an isomorphism so these are mutually two-sided inverses. -/ -theorem Γ_Spec_left_triangle : toSpecΓ (Γ.obj (op X)) ≫ X.toΓSpec.1.c.app (op ⊤) = 𝟙 _ := by +theorem Γ_Spec_left_triangle : toSpecΓ (Γ.obj (op X)) ≫ X.toΓSpec.c.app (op ⊤) = 𝟙 _ := by unfold toSpecΓ rw [← toOpen_res _ (basicOpen (1 : Γ.obj (op X))) ⊤ (eqToHom basicOpen_one.symm), Category.assoc, NatTrans.naturality, ← Category.assoc] @@ -269,7 +269,7 @@ def identityToΓSpec : 𝟭 LocallyRingedSpace.{u} ⟶ Γ.rightOp ⋙ Spec.toLoc apply LocallyRingedSpace.comp_ring_hom_ext · ext1 x dsimp - show PrimeSpectrum.comap (f.val.c.app (op ⊤)) (X.toΓSpecFun x) = Y.toΓSpecFun (f.val.base x) + show PrimeSpectrum.comap (f.c.app (op ⊤)) (X.toΓSpecFun x) = Y.toΓSpecFun (f.base x) dsimp [toΓSpecFun] -- TODO: this instance was found automatically before #6045 have := @AlgebraicGeometry.LocallyRingedSpace.isLocalRingHomStalkMap X Y @@ -278,14 +278,14 @@ def identityToΓSpec : 𝟭 LocallyRingedSpace.{u} ⟶ Γ.rightOp ⋙ Spec.toLoc congr 2 exact (PresheafedSpace.stalkMap_germ f.1 ⊤ x trivial).symm · intro r - rw [LocallyRingedSpace.comp_val_c_app, ← Category.assoc] - erw [Y.toΓSpecSheafedSpace_app_spec, f.1.c.naturality] + rw [LocallyRingedSpace.comp_c_app, ← Category.assoc] + erw [Y.toΓSpecSheafedSpace_app_spec, f.c.naturality] rfl namespace ΓSpec theorem left_triangle (X : LocallyRingedSpace) : - SpecΓIdentity.inv.app (Γ.obj (op X)) ≫ (identityToΓSpec.app X).val.c.app (op ⊤) = 𝟙 _ := + SpecΓIdentity.inv.app (Γ.obj (op X)) ≫ (identityToΓSpec.app X).c.app (op ⊤) = 𝟙 _ := X.Γ_Spec_left_triangle /-- `SpecΓIdentity` is iso so these are mutually two-sided inverses. -/ @@ -352,7 +352,7 @@ lemma toOpen_comp_locallyRingedSpaceAdjunction_homEquiv_app {X : LocallyRingedSpace} {R : Type u} [CommRing R] (f : Γ.rightOp.obj X ⟶ op (CommRingCat.of R)) (U) : StructureSheaf.toOpen R U.unop ≫ - (locallyRingedSpaceAdjunction.homEquiv X (op <| CommRingCat.of R) f).1.c.app U = + (locallyRingedSpaceAdjunction.homEquiv X (op <| CommRingCat.of R) f).c.app U = f.unop ≫ X.presheaf.map (homOfLE le_top).op := by rw [← StructureSheaf.toOpen_res _ _ _ (homOfLE le_top), Category.assoc, NatTrans.naturality _ (homOfLE (le_top (a := U.unop))).op, @@ -364,27 +364,25 @@ lemma toOpen_comp_locallyRingedSpaceAdjunction_homEquiv_app rfl /-- The adjunction `Γ ⊣ Spec` from `CommRingᵒᵖ` to `Scheme`. -/ -def adjunction : Scheme.Γ.rightOp ⊣ Scheme.Spec.{u} := - Adjunction.mk' { - homEquiv := fun X Y ↦ locallyRingedSpaceAdjunction.{u}.homEquiv X.toLocallyRingedSpace Y - unit := - { app := fun X ↦ locallyRingedSpaceAdjunction.{u}.unit.app X.toLocallyRingedSpace - naturality := fun _ _ f ↦ locallyRingedSpaceAdjunction.{u}.unit.naturality f } - counit := (NatIso.op Scheme.SpecΓIdentity.{u}).inv - homEquiv_unit := rfl - homEquiv_counit := rfl } +def adjunction : Scheme.Γ.rightOp ⊣ Scheme.Spec.{u} where + unit := + { app := fun X ↦ ⟨locallyRingedSpaceAdjunction.{u}.unit.app X.toLocallyRingedSpace⟩ + naturality := fun _ _ f ↦ + Scheme.Hom.ext' (locallyRingedSpaceAdjunction.{u}.unit.naturality f.toLRSHom) } + counit := (NatIso.op Scheme.SpecΓIdentity.{u}).inv + left_triangle_components Y := + locallyRingedSpaceAdjunction.left_triangle_components Y.toLocallyRingedSpace + right_triangle_components R := + Scheme.Hom.ext' <| locallyRingedSpaceAdjunction.right_triangle_components R theorem adjunction_homEquiv_apply {X : Scheme} {R : CommRingCatᵒᵖ} (f : (op <| Scheme.Γ.obj <| op X) ⟶ R) : - ΓSpec.adjunction.homEquiv X R f = locallyRingedSpaceAdjunction.homEquiv X.1 R f := rfl - -theorem adjunction_homEquiv (X : Scheme) (R : CommRingCatᵒᵖ) : - ΓSpec.adjunction.homEquiv X R = locallyRingedSpaceAdjunction.homEquiv X.1 R := rfl + ΓSpec.adjunction.homEquiv X R f = ⟨locallyRingedSpaceAdjunction.homEquiv X.1 R f⟩ := rfl theorem adjunction_homEquiv_symm_apply {X : Scheme} {R : CommRingCatᵒᵖ} (f : X ⟶ Scheme.Spec.obj R) : (ΓSpec.adjunction.homEquiv X R).symm f = - (locallyRingedSpaceAdjunction.homEquiv X.1 R).symm f := rfl + (locallyRingedSpaceAdjunction.homEquiv X.1 R).symm f.toLRSHom := rfl theorem adjunction_counit_app' {R : CommRingCatᵒᵖ} : ΓSpec.adjunction.counit.app R = locallyRingedSpaceAdjunction.counit.app R := rfl @@ -413,9 +411,9 @@ instance isIso_adjunction_counit : IsIso ΓSpec.adjunction.counit := by end ΓSpec -theorem Scheme.toSpecΓ_val_base (X : Scheme.{u}) (x) : - (Scheme.toSpecΓ X).1.base x = - (Spec.map (X.presheaf.germ ⊤ x trivial)).1.base (LocalRing.closedPoint _) := rfl +theorem Scheme.toSpecΓ_base (X : Scheme.{u}) (x) : + (Scheme.toSpecΓ X).base x = + (Spec.map (X.presheaf.germ ⊤ x trivial)).base (LocalRing.closedPoint _) := rfl @[reassoc (attr := simp)] theorem Scheme.toSpecΓ_naturality {X Y : Scheme.{u}} (f : X ⟶ Y) : diff --git a/Mathlib/AlgebraicGeometry/Gluing.lean b/Mathlib/AlgebraicGeometry/Gluing.lean index 2907eed57c7e5b..9eeee3d9e71e3a 100644 --- a/Mathlib/AlgebraicGeometry/Gluing.lean +++ b/Mathlib/AlgebraicGeometry/Gluing.lean @@ -123,9 +123,8 @@ def gluedScheme : Scheme := by D.toLocallyRingedSpaceGlueData.toGlueData.glued intro x obtain ⟨i, y, rfl⟩ := D.toLocallyRingedSpaceGlueData.ι_jointly_surjective x - refine ⟨?_, ?_ ≫ D.toLocallyRingedSpaceGlueData.toGlueData.ι i, ?_⟩ - swap - · exact (D.U i).affineCover.map y + refine ⟨_, ((D.U i).affineCover.map y).toLRSHom ≫ + D.toLocallyRingedSpaceGlueData.toGlueData.ι i, ?_⟩ constructor · erw [TopCat.coe_comp, Set.range_comp] -- now `erw` after #13170 refine Set.mem_image_of_mem _ ?_ @@ -157,14 +156,15 @@ abbrev isoLocallyRingedSpace : 𝖣.gluedIso forgetToLocallyRingedSpace theorem ι_isoLocallyRingedSpace_inv (i : D.J) : - D.toLocallyRingedSpaceGlueData.toGlueData.ι i ≫ D.isoLocallyRingedSpace.inv = 𝖣.ι i := + D.toLocallyRingedSpaceGlueData.toGlueData.ι i ≫ + D.isoLocallyRingedSpace.inv = (𝖣.ι i).toLRSHom := 𝖣.ι_gluedIso_inv forgetToLocallyRingedSpace i instance ι_isOpenImmersion (i : D.J) : IsOpenImmersion (𝖣.ι i) := by - rw [← D.ι_isoLocallyRingedSpace_inv]; infer_instance + rw [IsOpenImmersion, ← D.ι_isoLocallyRingedSpace_inv]; infer_instance theorem ι_jointly_surjective (x : 𝖣.glued.carrier) : - ∃ (i : D.J) (y : (D.U i).carrier), (D.ι i).1.base y = x := + ∃ (i : D.J) (y : (D.U i).carrier), (D.ι i).base y = x := 𝖣.ι_jointly_surjective (forgetToTop ⋙ forget TopCat) x -- Porting note: promote to higher priority to short circuit simplifier @@ -206,24 +206,24 @@ def isoCarrier : @[simp] theorem ι_isoCarrier_inv (i : D.J) : - (D_).ι i ≫ D.isoCarrier.inv = (D.ι i).1.base := by + (D_).ι i ≫ D.isoCarrier.inv = (D.ι i).base := by delta isoCarrier rw [Iso.trans_inv, GlueData.ι_gluedIso_inv_assoc, Functor.mapIso_inv, Iso.trans_inv, Functor.mapIso_inv, Iso.trans_inv, SheafedSpace.forgetToPresheafedSpace_map, forget_map, - forget_map, ← comp_base, ← Category.assoc, + forget_map, ← PresheafedSpace.comp_base, ← Category.assoc, D.toLocallyRingedSpaceGlueData.toSheafedSpaceGlueData.ι_isoPresheafedSpace_inv i] erw [← Category.assoc, D.toLocallyRingedSpaceGlueData.ι_isoSheafedSpace_inv i] - change (_ ≫ D.isoLocallyRingedSpace.inv).1.base = _ + change (_ ≫ D.isoLocallyRingedSpace.inv).base = _ rw [D.ι_isoLocallyRingedSpace_inv i] /-- An equivalence relation on `Σ i, D.U i` that holds iff `𝖣 .ι i x = 𝖣 .ι j y`. See `AlgebraicGeometry.Scheme.GlueData.ι_eq_iff`. -/ def Rel (a b : Σ i, ((D.U i).carrier : Type _)) : Prop := a = b ∨ - ∃ x : (D.V (a.1, b.1)).carrier, (D.f _ _).1.base x = a.2 ∧ (D.t _ _ ≫ D.f _ _).1.base x = b.2 + ∃ x : (D.V (a.1, b.1)).carrier, (D.f _ _).base x = a.2 ∧ (D.t _ _ ≫ D.f _ _).base x = b.2 theorem ι_eq_iff (i j : D.J) (x : (D.U i).carrier) (y : (D.U j).carrier) : - (𝖣.ι i).1.base x = (𝖣.ι j).1.base y ↔ D.Rel ⟨i, x⟩ ⟨j, y⟩ := by + (𝖣.ι i).base x = (𝖣.ι j).base y ↔ D.Rel ⟨i, x⟩ ⟨j, y⟩ := by refine Iff.trans ?_ (TopCat.GlueData.ι_eq_iff_rel D.toLocallyRingedSpaceGlueData.toSheafedSpaceGlueData.toPresheafedSpaceGlueData.toTopGlueData @@ -233,7 +233,7 @@ theorem ι_eq_iff (i j : D.J) (x : (D.U i).carrier) (y : (D.U j).carrier) : rfl -- `rfl` was not needed before #13170 · infer_instance -theorem isOpen_iff (U : Set D.glued.carrier) : IsOpen U ↔ ∀ i, IsOpen ((D.ι i).1.base ⁻¹' U) := by +theorem isOpen_iff (U : Set D.glued.carrier) : IsOpen U ↔ ∀ i, IsOpen ((D.ι i).base ⁻¹' U) := by rw [← (TopCat.homeoOfIso D.isoCarrier.symm).isOpen_preimage, TopCat.GlueData.isOpen_iff] apply forall_congr' intro i @@ -336,13 +336,13 @@ def fromGlued : 𝒰.gluedCover.glued ⟶ X := by theorem ι_fromGlued (x : 𝒰.J) : 𝒰.gluedCover.ι x ≫ 𝒰.fromGlued = 𝒰.map x := Multicoequalizer.π_desc _ _ _ _ _ -theorem fromGlued_injective : Function.Injective 𝒰.fromGlued.1.base := by +theorem fromGlued_injective : Function.Injective 𝒰.fromGlued.base := by intro x y h obtain ⟨i, x, rfl⟩ := 𝒰.gluedCover.ι_jointly_surjective x obtain ⟨j, y, rfl⟩ := 𝒰.gluedCover.ι_jointly_surjective y rw [← comp_apply, ← comp_apply] at h - simp_rw [← SheafedSpace.comp_base, ← LocallyRingedSpace.comp_val] at h - erw [ι_fromGlued, ι_fromGlued] at h + simp_rw [← Scheme.comp_base] at h + rw [ι_fromGlued, ι_fromGlued] at h let e := (TopCat.pullbackConeIsLimit _ _).conePointUniqueUpToIso (isLimitOfHasPullbackOfPreservesLimit Scheme.forgetToTop (𝒰.map i) (𝒰.map j)) @@ -363,12 +363,12 @@ instance fromGlued_stalk_iso (x : 𝒰.gluedCover.glued.carrier) : rw [this] infer_instance -theorem fromGlued_open_map : IsOpenMap 𝒰.fromGlued.1.base := by +theorem fromGlued_open_map : IsOpenMap 𝒰.fromGlued.base := by intro U hU rw [isOpen_iff_forall_mem_open] intro x hx rw [𝒰.gluedCover.isOpen_iff] at hU - use 𝒰.fromGlued.val.base '' U ∩ Set.range (𝒰.map (𝒰.f x)).1.base + use 𝒰.fromGlued.base '' U ∩ Set.range (𝒰.map (𝒰.f x)).base use Set.inter_subset_left constructor · rw [← Set.image_preimage_eq_inter_range] @@ -379,15 +379,15 @@ theorem fromGlued_open_map : IsOpenMap 𝒰.fromGlued.1.base := by exact Set.preimage_image_eq _ 𝒰.fromGlued_injective · exact ⟨hx, 𝒰.covers x⟩ -theorem fromGlued_openEmbedding : OpenEmbedding 𝒰.fromGlued.1.base := +theorem fromGlued_openEmbedding : OpenEmbedding 𝒰.fromGlued.base := openEmbedding_of_continuous_injective_open (by fun_prop) 𝒰.fromGlued_injective 𝒰.fromGlued_open_map -instance : Epi 𝒰.fromGlued.val.base := by +instance : Epi 𝒰.fromGlued.base := by rw [TopCat.epi_iff_surjective] intro x obtain ⟨y, h⟩ := 𝒰.covers x - use (𝒰.gluedCover.ι (𝒰.f x)).1.base y + use (𝒰.gluedCover.ι (𝒰.f x)).base y rw [← comp_apply] rw [← 𝒰.ι_fromGlued (𝒰.f x)] at h exact h @@ -399,7 +399,7 @@ instance : IsIso 𝒰.fromGlued := let F := Scheme.forgetToLocallyRingedSpace ⋙ LocallyRingedSpace.forgetToSheafedSpace ⋙ SheafedSpace.forgetToPresheafedSpace have : IsIso (F.map (fromGlued 𝒰)) := by - change @IsIso (PresheafedSpace _) _ _ _ 𝒰.fromGlued.val + change IsIso 𝒰.fromGlued.toPshHom apply PresheafedSpace.IsOpenImmersion.to_iso isIso_of_reflects_iso _ F diff --git a/Mathlib/AlgebraicGeometry/Limits.lean b/Mathlib/AlgebraicGeometry/Limits.lean index 5124bdbd6e750f..d5614273639d98 100644 --- a/Mathlib/AlgebraicGeometry/Limits.lean +++ b/Mathlib/AlgebraicGeometry/Limits.lean @@ -58,8 +58,7 @@ def Scheme.emptyTo (X : Scheme.{u}) : ∅ ⟶ X := @[ext] theorem Scheme.empty_ext {X : Scheme.{u}} (f g : ∅ ⟶ X) : f = g := -- Porting note (#11041): `ext` regression - LocallyRingedSpace.Hom.ext <| PresheafedSpace.ext _ _ (by ext a; exact PEmpty.elim a) <| - NatTrans.ext <| funext fun a => by aesop_cat + Scheme.Hom.ext' (Subsingleton.elim (α := ∅ ⟶ _) _ _) theorem Scheme.eq_emptyTo {X : Scheme.{u}} (f : ∅ ⟶ X) : f = Scheme.emptyTo X := Scheme.empty_ext f (Scheme.emptyTo X) @@ -89,8 +88,8 @@ 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.1.base.1.isEmpty - have : Epi f.1.base := by + haveI : IsEmpty X := f.base.1.isEmpty + have : Epi f.base := by rw [TopCat.epi_iff_surjective]; rintro (x : Y) exact isEmptyElim x apply IsOpenImmersion.to_iso @@ -110,7 +109,7 @@ instance : HasInitial Scheme.{u} := hasInitial_of_unique ∅ instance initial_isEmpty : IsEmpty (⊥_ Scheme) := - ⟨fun x => ((initial.to Scheme.empty : _).1.base x).elim⟩ + ⟨fun x => ((initial.to Scheme.empty : _).base x).elim⟩ theorem isAffineOpen_bot (X : Scheme) : IsAffineOpen (⊥ : X.Opens) := @isAffine_of_isEmpty _ (inferInstanceAs (IsEmpty (∅ : Set X))) @@ -242,7 +241,7 @@ instance (i) : IsOpenImmersion (Sigma.ι f i) := by infer_instance lemma sigmaι_eq_iff (i j : ι) (x y) : - (Sigma.ι f i).1.base x = (Sigma.ι f j).1.base y ↔ + (Sigma.ι f i).base x = (Sigma.ι f j).base y ↔ (Sigma.mk i x : Σ i, f i) = Sigma.mk j y := by constructor · intro H @@ -269,10 +268,10 @@ lemma disjoint_opensRange_sigmaι (i j : ι) (h : i ≠ j) : obtain ⟨rfl⟩ := (sigmaι_eq_iff _ _ _ _ _).mp hy cases h rfl -lemma exists_sigmaι_eq (x : (∐ f : _)) : ∃ i y, (Sigma.ι f i).1.base y = x := by - obtain ⟨i, y, e⟩ := (disjointGlueData f).ι_jointly_surjective ((sigmaIsoGlued f).hom.1.base x) +lemma exists_sigmaι_eq (x : (∐ f : _)) : ∃ i y, (Sigma.ι f i).base y = x := by + obtain ⟨i, y, e⟩ := (disjointGlueData f).ι_jointly_surjective ((sigmaIsoGlued f).hom.base x) refine ⟨i, y, (sigmaIsoGlued f).hom.openEmbedding.inj ?_⟩ - rwa [← Scheme.comp_val_base_apply, ι_sigmaIsoGlued_hom] + rwa [← Scheme.comp_base_apply, ι_sigmaIsoGlued_hom] lemma iSup_opensRange_sigmaι : ⨆ i, (Sigma.ι f i).opensRange = ⊤ := eq_top_iff.mpr fun x ↦ by simpa using exists_sigmaι_eq f x @@ -295,7 +294,7 @@ def sigmaMk : (Σ i, f i) ≃ₜ (∐ f : _) := @[simp] lemma sigmaMk_mk (i) (x : f i) : - sigmaMk f (.mk i x) = (Sigma.ι f i).1.base x := by + sigmaMk f (.mk i x) = (Sigma.ι f i).base x := by show ((TopCat.sigmaCofan (fun x ↦ (f x).toTopCat)).inj i ≫ (colimit.isoColimitCocone ⟨_, TopCat.sigmaCofanIsColimit _⟩).inv ≫ _) x = Scheme.forgetToTop.map (Sigma.ι f i) x @@ -324,8 +323,8 @@ instance : IsOpenImmersion (coprod.inr : Y ⟶ X ⨿ Y) := by rw [← ι_right_coprodIsoSigma_inv]; infer_instance lemma isCompl_range_inl_inr : - IsCompl (Set.range (coprod.inl : X ⟶ X ⨿ Y).1.base) - (Set.range (coprod.inr : Y ⟶ X ⨿ Y).1.base) := + IsCompl (Set.range (coprod.inl : X ⟶ X ⨿ Y).base) + (Set.range (coprod.inr : Y ⟶ X ⨿ Y).base) := ((TopCat.binaryCofan_isColimit_iff _).mp ⟨mapIsColimitOfPreservesOfIsColimit Scheme.forgetToTop _ _ (coprodIsCoprod X Y)⟩).2.2 @@ -343,7 +342,7 @@ def coprodMk : X ⊕ Y ≃ₜ (X ⨿ Y : Scheme.{u}) := @[simp] lemma coprodMk_inl (x : X) : - coprodMk X Y (.inl x) = (coprod.inl : X ⟶ X ⨿ Y).1.base x := by + coprodMk X Y (.inl x) = (coprod.inl : X ⟶ X ⨿ Y).base x := by show ((TopCat.binaryCofan X Y).inl ≫ (colimit.isoColimitCocone ⟨_, TopCat.binaryCofanIsColimit _ _⟩).inv ≫ _) x = Scheme.forgetToTop.map coprod.inl x @@ -353,7 +352,7 @@ lemma coprodMk_inl (x : X) : @[simp] lemma coprodMk_inr (x : Y) : - coprodMk X Y (.inr x) = (coprod.inr : Y ⟶ X ⨿ Y).1.base x := by + coprodMk X Y (.inr x) = (coprod.inr : Y ⟶ X ⨿ Y).base x := by show ((TopCat.binaryCofan X Y).inr ≫ (colimit.isoColimitCocone ⟨_, TopCat.binaryCofanIsColimit _ _⟩).inv ≫ _) x = Scheme.forgetToTop.map coprod.inr x @@ -397,10 +396,10 @@ lemma coprodSpec_inr : coprod.inr ≫ coprodSpec R S = coprod.inr_desc _ _ lemma coprodSpec_coprodMk (x) : - (coprodSpec R S).1.base (coprodMk _ _ x) = (PrimeSpectrum.primeSpectrumProd R S).symm x := by + (coprodSpec R S).base (coprodMk _ _ x) = (PrimeSpectrum.primeSpectrumProd R S).symm x := by apply PrimeSpectrum.ext obtain (x | x) := x <;> - simp only [coprodMk_inl, coprodMk_inr, ← Scheme.comp_val_base_apply, + simp only [coprodMk_inl, coprodMk_inr, ← Scheme.comp_base_apply, coprodSpec, coprod.inl_desc, coprod.inr_desc] · show Ideal.comap _ _ = x.asIdeal.prod ⊤ ext; simp [Ideal.prod, CommRingCat.ofHom] @@ -408,7 +407,7 @@ lemma coprodSpec_coprodMk (x) : ext; simp [Ideal.prod, CommRingCat.ofHom] lemma coprodSpec_apply (x) : - (coprodSpec R S).1.base x = (PrimeSpectrum.primeSpectrumProd R S).symm + (coprodSpec R S).base x = (PrimeSpectrum.primeSpectrumProd R S).symm ((coprodMk (Spec (.of R)) (Spec (.of S))).symm x) := by rw [← coprodSpec_coprodMk, Homeomorph.apply_symm_apply] @@ -467,7 +466,7 @@ noncomputable instance : PreservesColimitsOfShape (Discrete PEmpty.{1}) Scheme.Spec := by have : IsEmpty (Scheme.Spec.obj (⊥_ CommRingCatᵒᵖ)) := @Function.isEmpty _ _ spec_punit_isEmpty (Scheme.Spec.mapIso - (initialIsoIsInitial (initialOpOfTerminal CommRingCat.punitIsTerminal))).hom.1.base + (initialIsoIsInitial (initialOpOfTerminal CommRingCat.punitIsTerminal))).hom.base have := preservesInitialOfIso Scheme.Spec (asIso (initial.to _)) exact preservesColimitsOfShapePemptyOfPreservesInitial _ diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean b/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean index c990b0ee818d76..ecd431a4735b48 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean @@ -66,7 +66,7 @@ instance (priority := 900) [IsAffineHom f] : QuasiCompact f := instance [IsAffineHom f] [IsAffineHom g] : IsAffineHom (f ≫ g) := by constructor intros U hU - rw [Scheme.comp_val_base, Opens.map_comp_obj] + rw [Scheme.comp_base, Opens.map_comp_obj] apply IsAffineHom.isAffine_preimage apply IsAffineHom.isAffine_preimage exact hU @@ -158,7 +158,7 @@ instance : HasAffineProperty @IsAffineHom fun X _ _ _ ↦ IsAffine X where rw [Scheme.preimage_basicOpen] exact (isAffineOpen_top X).basicOpen _ · intro X Y _ f S hS hS' - apply_fun Ideal.map (f.1.c.app (op ⊤)) at hS + apply_fun Ideal.map (f.app ⊤) at hS rw [Ideal.map_span, Ideal.map_top] at hS apply isAffine_of_isAffineOpen_basicOpen _ hS have : ∀ i : S, IsAffineOpen (f⁻¹ᵁ Y.basicOpen i.1) := hS' diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean b/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean index a9f5d34528df43..50efd7b087298e 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Basic.lean @@ -437,7 +437,7 @@ instance (P : AffineTargetMorphismProperty) [P.toProperty.RespectsIso] : rintro ⟨U, hU : IsAffineOpen U⟩; dsimp haveI : IsAffine _ := hU.preimage_of_isIso e.hom rw [morphismRestrict_comp, P.cancel_right_of_respectsIso] - exact H ⟨(Opens.map e.hom.val.base).obj U, hU.preimage_of_isIso e.hom⟩ + exact H ⟨(Opens.map e.hom.base).obj U, hU.preimage_of_isIso e.hom⟩ /-- `HasAffineProperty P Q` is a type class asserting that `P` is local at the target, and over affine diff --git a/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean b/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean index e0f201805fa3b8..592f5829e66faa 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean @@ -38,13 +38,13 @@ namespace AlgebraicGeometry topological map is a closed embedding and the induced stalk maps are surjective. -/ @[mk_iff] class IsClosedImmersion {X Y : Scheme} (f : X ⟶ Y) : Prop where - base_closed : ClosedEmbedding f.1.base + base_closed : ClosedEmbedding f.base surj_on_stalks : ∀ x, Function.Surjective (f.stalkMap x) namespace IsClosedImmersion lemma closedEmbedding {X Y : Scheme} (f : X ⟶ Y) - [IsClosedImmersion f] : ClosedEmbedding f.1.base := + [IsClosedImmersion f] : ClosedEmbedding f.base := IsClosedImmersion.base_closed lemma eq_inf : @IsClosedImmersion = (topologically ClosedEmbedding) ⊓ @@ -54,12 +54,12 @@ lemma eq_inf : @IsClosedImmersion = (topologically ClosedEmbedding) ⊓ rfl lemma iff_isPreimmersion {X Y : Scheme} {f : X ⟶ Y} : - IsClosedImmersion f ↔ IsPreimmersion f ∧ IsClosed (Set.range f.1.base) := by + IsClosedImmersion f ↔ IsPreimmersion f ∧ IsClosed (Set.range f.base) := by rw [and_comm, isClosedImmersion_iff, isPreimmersion_iff, ← and_assoc, closedEmbedding_iff, @and_comm (Embedding _)] lemma of_isPreimmersion {X Y : Scheme} (f : X ⟶ Y) [IsPreimmersion f] - (hf : IsClosed (Set.range f.1.base)) : IsClosedImmersion f := + (hf : IsClosed (Set.range f.base)) : IsClosedImmersion f := iff_isPreimmersion.mpr ⟨‹_›, hf⟩ instance (priority := 900) {X Y : Scheme} (f : X ⟶ Y) [IsClosedImmersion f] : IsPreimmersion f := @@ -67,7 +67,7 @@ instance (priority := 900) {X Y : Scheme} (f : X ⟶ Y) [IsClosedImmersion f] : /-- Isomorphisms are closed immersions. -/ instance {X Y : Scheme} (f : X ⟶ Y) [IsIso f] : IsClosedImmersion f where - base_closed := Homeomorph.closedEmbedding <| TopCat.homeoOfIso (asIso f.1.base) + base_closed := Homeomorph.closedEmbedding <| TopCat.homeoOfIso (asIso f.base) surj_on_stalks := fun _ ↦ (ConcreteCategory.bijective_of_isIso _).2 instance : MorphismProperty.IsMultiplicative @IsClosedImmersion where @@ -75,7 +75,7 @@ instance : MorphismProperty.IsMultiplicative @IsClosedImmersion where comp_mem {X Y Z} f g hf hg := by refine ⟨hg.base_closed.comp hf.base_closed, fun x ↦ ?_⟩ rw [Scheme.stalkMap_comp] - exact (hf.surj_on_stalks x).comp (hg.surj_on_stalks (f.1.1 x)) + exact (hf.surj_on_stalks x).comp (hg.surj_on_stalks (f.base x)) /-- Composition of closed immersions is a closed immersion. -/ instance comp {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) [IsClosedImmersion f] @@ -120,7 +120,7 @@ theorem of_comp {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) [IsClosedImmersion [IsClosedImmersion (f ≫ g)] : IsClosedImmersion f where base_closed := by have h := closedEmbedding (f ≫ g) - rw [Scheme.comp_val_base] at h + rw [Scheme.comp_base] at h apply closedEmbedding_of_continuous_injective_closed (Scheme.Hom.continuous f) · exact Function.Injective.of_comp h.inj · intro Z hZ @@ -129,7 +129,7 @@ theorem of_comp {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) [IsClosedImmersion exact ClosedEmbedding.isClosedMap h _ hZ surj_on_stalks x := by have h := (f ≫ g).stalkMap_surjective x - simp_rw [Scheme.comp_val, Scheme.stalkMap_comp] at h + simp_rw [Scheme.stalkMap_comp] at h exact Function.Surjective.of_comp h instance {X Y : Scheme} (f : X ⟶ Y) [IsClosedImmersion f] : QuasiCompact f where diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Constructors.lean b/Mathlib/AlgebraicGeometry/Morphisms/Constructors.lean index d817f2b6c1a4ce..6cfb3141006be3 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Constructors.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Constructors.lean @@ -165,7 +165,7 @@ theorem universally_isLocalAtTarget (P : MorphismProperty Scheme) apply hP₂ _ (fun i ↦ i₂ ⁻¹ᵁ U i) · rw [← top_le_iff] at hU ⊢ rintro x - - simpa using @hU (i₂.1.base x) trivial + simpa using @hU (i₂.base x) trivial · rintro i refine H _ ((X'.restrictIsoOfEq ?_).hom ≫ i₁ ∣_ _) (i₂ ∣_ _) _ ?_ · exact congr($(h.1.1) ⁻¹ᵁ U i) @@ -184,7 +184,7 @@ section Topologically /-- `topologically P` holds for a morphism if the underlying topological map satisfies `P`. -/ def topologically (P : ∀ {α β : Type u} [TopologicalSpace α] [TopologicalSpace β] (_ : α → β), Prop) : - MorphismProperty Scheme.{u} := fun _ _ f => P f.1.base + MorphismProperty Scheme.{u} := fun _ _ f => P f.base variable (P : ∀ {α β : Type u} [TopologicalSpace α] [TopologicalSpace β] (_ : α → β), Prop) @@ -205,7 +205,7 @@ lemma topologically_iso_le MorphismProperty.isomorphisms Scheme ≤ (topologically P) := by intro X Y e (he : IsIso e) have : IsIso e := he - exact hP (TopCat.homeoOfIso (asIso e.val.base)) + exact hP (TopCat.homeoOfIso (asIso e.base)) /-- If a property of maps of topological spaces is satisfied by homeomorphisms and is stable under composition, the induced property on schemes respects isomorphisms. -/ @@ -230,11 +230,11 @@ lemma topologically_isLocalAtTarget IsLocalAtTarget (topologically P) := by apply IsLocalAtTarget.mk' · intro X Y f U hf - simp_rw [topologically, morphismRestrict_val_base] - exact hP₂ f.val.base U.carrier hf + simp_rw [topologically, morphismRestrict_base] + exact hP₂ f.base U.carrier hf · intro X Y f ι U hU hf - apply hP₃ f.val.base U hU f.val.base.continuous fun i ↦ ?_ - rw [← morphismRestrict_val_base] + apply hP₃ f.base U hU f.base.continuous fun i ↦ ?_ + rw [← morphismRestrict_base] exact hf i end Topologically @@ -255,8 +255,8 @@ lemma stalkwise_respectsIso (hP : RingHom.RespectsIso P) : simp only [stalkwise, Scheme.comp_coeBase, TopCat.coe_comp, Function.comp_apply] intro x rw [Scheme.stalkMap_comp] - exact (RingHom.RespectsIso.cancel_right_isIso hP _ _).mpr <| hf (e.val.base x) - postcomp {X Y Z} e (he : IsIso e) f hf := by + exact (RingHom.RespectsIso.cancel_right_isIso hP _ _).mpr <| hf (e.base x) + postcomp {X Y Z} e (he : IsIso _) f hf := by simp only [stalkwise, Scheme.comp_coeBase, TopCat.coe_comp, Function.comp_apply] intro x rw [Scheme.stalkMap_comp] @@ -273,7 +273,7 @@ lemma stalkwiseIsLocalAtTarget_of_respectsIso (hP : RingHom.RespectsIso P) : apply ((RingHom.toMorphismProperty P).arrow_mk_iso_iff <| morphismRestrictStalkMap f U x).mpr <| hf _ · intro X Y f ι U hU hf x - have hy : f.val.base x ∈ iSup U := by rw [hU]; trivial + have hy : f.base x ∈ iSup U := by rw [hU]; trivial obtain ⟨i, hi⟩ := Opens.mem_iSup.mp hy exact ((RingHom.toMorphismProperty P).arrow_mk_iso_iff <| morphismRestrictStalkMap f (U i) ⟨x, hi⟩).mp <| hf i ⟨x, hi⟩ diff --git a/Mathlib/AlgebraicGeometry/Morphisms/IsIso.lean b/Mathlib/AlgebraicGeometry/Morphisms/IsIso.lean index ad9b6dcc7c5f60..384f3493f9a1eb 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/IsIso.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/IsIso.lean @@ -30,8 +30,8 @@ lemma isomorphisms_eq_stalkwise : congr 1 ext X Y f exact ⟨fun H ↦ inferInstanceAs (IsIso (TopCat.isoOfHomeo - (H.1.1.toHomeomeomorph_of_surjective H.2)).hom), fun (_ : IsIso f.1.base) ↦ - let e := (TopCat.homeoOfIso <| asIso f.1.base); ⟨e.openEmbedding, e.surjective⟩⟩ + (H.1.1.toHomeomeomorph_of_surjective H.2)).hom), fun (_ : IsIso f.base) ↦ + let e := (TopCat.homeoOfIso <| asIso f.base); ⟨e.openEmbedding, e.surjective⟩⟩ instance : IsLocalAtTarget (isomorphisms Scheme) := isomorphisms_eq_isOpenImmersion_inf_surjective ▸ inferInstance diff --git a/Mathlib/AlgebraicGeometry/Morphisms/OpenImmersion.lean b/Mathlib/AlgebraicGeometry/Morphisms/OpenImmersion.lean index 3fc310d18e2077..43a94b8d2d1a0e 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/OpenImmersion.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/OpenImmersion.lean @@ -29,7 +29,7 @@ namespace AlgebraicGeometry variable {X Y Z : Scheme.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) theorem isOpenImmersion_iff_stalk {f : X ⟶ Y} : IsOpenImmersion f ↔ - OpenEmbedding f.1.base ∧ ∀ x, IsIso (f.stalkMap x) := by + OpenEmbedding f.base ∧ ∀ x, IsIso (f.stalkMap x) := by constructor · intro h; exact ⟨h.1, inferInstance⟩ · rintro ⟨h₁, h₂⟩; exact IsOpenImmersion.of_stalk_iso f h₁ @@ -43,7 +43,7 @@ theorem isOpenImmersion_eq_inf : instance isOpenImmersion_isStableUnderComposition : MorphismProperty.IsStableUnderComposition @IsOpenImmersion where - comp_mem f g _ _ := LocallyRingedSpace.IsOpenImmersion.comp f g + comp_mem f g _ _ := LocallyRingedSpace.IsOpenImmersion.comp f.toLRSHom g.toLRSHom instance isOpenImmersion_respectsIso : MorphismProperty.RespectsIso @IsOpenImmersion := by apply MorphismProperty.respectsIso_of_isStableUnderComposition diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean b/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean index b9472fc3ea5504..a5fd6903836cb9 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean @@ -33,10 +33,10 @@ namespace AlgebraicGeometry topological spaces is an embedding and the induced morphisms of stalks are all surjective. -/ @[mk_iff] class IsPreimmersion {X Y : Scheme} (f : X ⟶ Y) : Prop where - base_embedding : Embedding f.1.base + base_embedding : Embedding f.base surj_on_stalks : ∀ x, Function.Surjective (f.stalkMap x) -lemma Scheme.Hom.embedding {X Y : Scheme} (f : Hom X Y) [IsPreimmersion f] : Embedding f.1.base := +lemma Scheme.Hom.embedding {X Y : Scheme} (f : Hom X Y) [IsPreimmersion f] : Embedding f.base := IsPreimmersion.base_embedding lemma Scheme.Hom.stalkMap_surjective {X Y : Scheme} (f : Hom X Y) [IsPreimmersion f] (x) : @@ -68,7 +68,7 @@ instance : MorphismProperty.IsMultiplicative @IsPreimmersion where comp_mem {X Y Z} f g hf hg := by refine ⟨hg.base_embedding.comp hf.base_embedding, fun x ↦ ?_⟩ rw [Scheme.stalkMap_comp] - exact (hf.surj_on_stalks x).comp (hg.surj_on_stalks (f.1.1 x)) + exact (hf.surj_on_stalks x).comp (hg.surj_on_stalks (f.base x)) instance comp {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) [IsPreimmersion f] [IsPreimmersion g] : IsPreimmersion (f ≫ g) := diff --git a/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean b/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean index cf3a6124cc51f5..2e50b205e0b3e6 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean @@ -38,26 +38,26 @@ of quasi-compact open sets are quasi-compact. @[mk_iff] class QuasiCompact (f : X ⟶ Y) : Prop where /-- Preimage of compact open set under a quasi-compact morphism between schemes is compact. -/ - isCompact_preimage : ∀ U : Set Y, IsOpen U → IsCompact U → IsCompact (f.1.base ⁻¹' U) + isCompact_preimage : ∀ U : Set Y, IsOpen U → IsCompact U → IsCompact (f.base ⁻¹' U) -theorem quasiCompact_iff_spectral : QuasiCompact f ↔ IsSpectralMap f.1.base := +theorem quasiCompact_iff_spectral : QuasiCompact f ↔ IsSpectralMap f.base := ⟨fun ⟨h⟩ => ⟨by fun_prop, h⟩, fun h => ⟨h.2⟩⟩ instance (priority := 900) quasiCompact_of_isIso {X Y : Scheme} (f : X ⟶ Y) [IsIso f] : QuasiCompact f := by constructor intro U _ hU' - convert hU'.image (inv f.1.base).continuous_toFun using 1 + convert hU'.image (inv f.base).continuous_toFun using 1 rw [Set.image_eq_preimage_of_inverse] · delta Function.LeftInverse - exact IsIso.inv_hom_id_apply f.1.base - · exact IsIso.hom_inv_id_apply f.1.base + exact IsIso.inv_hom_id_apply f.base + · exact IsIso.hom_inv_id_apply f.base instance quasiCompact_comp {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) [QuasiCompact f] [QuasiCompact g] : QuasiCompact (f ≫ g) := by constructor intro U hU hU' - rw [Scheme.comp_val_base, TopCat.coe_comp, Set.preimage_comp] + rw [Scheme.comp_base, TopCat.coe_comp, Set.preimage_comp] apply QuasiCompact.isCompact_preimage · exact Continuous.isOpen_preimage (by fun_prop) _ hU apply QuasiCompact.isCompact_preimage <;> assumption @@ -126,9 +126,9 @@ instance : HasAffineProperty @QuasiCompact (fun X _ _ _ ↦ CompactSpace X) wher isLocal_affineProperty := by constructor · apply AffineTargetMorphismProperty.respectsIso_mk <;> rintro X Y Z e _ _ H - exacts [@Homeomorph.compactSpace _ _ _ _ H (TopCat.homeoOfIso (asIso e.inv.1.base)), H] + exacts [@Homeomorph.compactSpace _ _ _ _ H (TopCat.homeoOfIso (asIso e.inv.base)), H] · introv _ H - change CompactSpace ((Opens.map f.val.base).obj (Y.basicOpen r)) + change CompactSpace ((Opens.map f.base).obj (Y.basicOpen r)) rw [Scheme.preimage_basicOpen f r] erw [← isCompact_iff_compactSpace] rw [← isCompact_univ_iff] at H @@ -137,7 +137,7 @@ instance : HasAffineProperty @QuasiCompact (fun X _ _ _ ↦ CompactSpace X) wher · rintro X Y H f S hS hS' rw [← IsAffineOpen.basicOpen_union_eq_self_iff] at hS · rw [← isCompact_univ_iff] - change IsCompact ((Opens.map f.val.base).obj ⊤).1 + change IsCompact ((Opens.map f.base).obj ⊤).1 rw [← hS] dsimp [Opens.map] simp only [Opens.iSup_mk, Opens.coe_mk, Set.preimage_iUnion] diff --git a/Mathlib/AlgebraicGeometry/Morphisms/QuasiSeparated.lean b/Mathlib/AlgebraicGeometry/Morphisms/QuasiSeparated.lean index e9ffc71cd889f8..be7e03dfc20b17 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/QuasiSeparated.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/QuasiSeparated.lean @@ -351,7 +351,7 @@ theorem is_localization_basicOpen_of_qcqs {X : Scheme} {U : X.Opens} (hU : IsCom This is known as the **Qcqs lemma** in [R. Vakil, *The rising sea*][RisingSea]. -/ theorem isIso_ΓSpec_adjunction_unit_app_basicOpen {X : Scheme} [CompactSpace X] [QuasiSeparatedSpace X] (f : X.presheaf.obj (op ⊤)) : - IsIso ((ΓSpec.adjunction.unit.app X).val.c.app (op (PrimeSpectrum.basicOpen f))) := by + IsIso ((ΓSpec.adjunction.unit.app X).c.app (op (PrimeSpectrum.basicOpen f))) := by refine @IsIso.of_isIso_comp_right _ _ _ _ _ _ (X.presheaf.map (eqToHom (Scheme.toSpecΓ_preimage_basicOpen _ _).symm).op) _ ?_ rw [ConcreteCategory.isIso_iff_bijective, CommRingCat.forget_map] diff --git a/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean b/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean index 93a2ff38a6b0a7..8e9613ac56f3a2 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean @@ -438,7 +438,7 @@ lemma iff_exists_appLE_locally (hQi : RespectsIso Q) [HasRingHomProperty P (Loca Q (f.appLE U V e) := by refine ⟨fun hf x ↦ ?_, fun hf ↦ (IsLocalAtSource.iff_exists_resLE (P := P)).mpr <| fun x ↦ ?_⟩ · obtain ⟨U, hU, hfx, _⟩ := Opens.isBasis_iff_nbhd.mp (isBasis_affine_open Y) - (Opens.mem_top <| f.val.base x) + (Opens.mem_top <| f.base x) obtain ⟨V, hV, hx, e⟩ := Opens.isBasis_iff_nbhd.mp (isBasis_affine_open X) (show x ∈ f ⁻¹ᵁ U from hfx) simp_rw [HasRingHomProperty.iff_appLE (P := P), locally_iff_isLocalization hQi] at hf diff --git a/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean b/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean index b2c7a9ad876814..ff349f67ab6a8c 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean @@ -51,12 +51,12 @@ variable {X Y Z : Scheme.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) /-- A morphism of schemes is surjective if the underlying map is. -/ @[mk_iff] class Surjective : Prop where - surj : Function.Surjective f.1.base + surj : Function.Surjective f.base lemma surjective_eq_topologically : @Surjective = topologically Function.Surjective := by ext; exact surjective_iff _ -lemma Scheme.Hom.surjective (f : X.Hom Y) [Surjective f] : Function.Surjective f.1.base := +lemma Scheme.Hom.surjective (f : X.Hom Y) [Surjective f] : Function.Surjective f.base := Surjective.surj instance (priority := 100) [IsIso f] : Surjective f := ⟨f.homeomorph.surjective⟩ @@ -64,7 +64,7 @@ instance (priority := 100) [IsIso f] : Surjective f := ⟨f.homeomorph.surjectiv instance [Surjective f] [Surjective g] : Surjective (f ≫ g) := ⟨g.surjective.comp f.surjective⟩ lemma Surjective.of_comp [Surjective (f ≫ g)] : Surjective g where - surj := Function.Surjective.of_comp (g := f.1.base) (f ≫ g).surjective + surj := Function.Surjective.of_comp (g := f.base) (f ≫ g).surjective lemma Surjective.comp_iff [Surjective f] : Surjective (f ≫ g) ↔ Surjective g := ⟨fun _ ↦ of_comp f g, fun _ ↦ inferInstance⟩ diff --git a/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean b/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean index 3e0a0c0b91874c..6a5489d9924768 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean @@ -48,7 +48,7 @@ theorem universallyClosed_stableUnderBaseChange : StableUnderBaseChange @Univers instance isClosedMap_isStableUnderComposition : IsStableUnderComposition (topologically @IsClosedMap) where - comp_mem f g hf hg := IsClosedMap.comp (f := f.1.base) (g := g.1.base) hg hf + comp_mem f g hf hg := IsClosedMap.comp (f := f.base) (g := g.base) hg hf instance universallyClosed_isStableUnderComposition : IsStableUnderComposition @UniversallyClosed := by @@ -71,7 +71,7 @@ instance universallyClosed_isLocalAtTarget : IsLocalAtTarget @UniversallyClosed rw [universallyClosed_eq] apply universally_isLocalAtTarget intro X Y f ι U hU H - simp_rw [topologically, morphismRestrict_val_base] at H + simp_rw [topologically, morphismRestrict_base] at H exact (isClosedMap_iff_isClosedMap_of_iSup_eq_top hU).mpr H end AlgebraicGeometry diff --git a/Mathlib/AlgebraicGeometry/Noetherian.lean b/Mathlib/AlgebraicGeometry/Noetherian.lean index 5b47926dddcf1f..45c741d3583198 100644 --- a/Mathlib/AlgebraicGeometry/Noetherian.lean +++ b/Mathlib/AlgebraicGeometry/Noetherian.lean @@ -274,7 +274,7 @@ instance (priority := 100) IsNoetherian.noetherianSpace [IsNoetherian X] : apply TopologicalSpace.noetherian_univ_iff.mp let 𝒰 := X.affineCover.finiteSubcover rw [← 𝒰.iUnion_range] - suffices ∀ i : 𝒰.J, NoetherianSpace (Set.range <| (𝒰.map i).val.base) by + suffices ∀ i : 𝒰.J, NoetherianSpace (Set.range <| (𝒰.map i).base) by apply NoetherianSpace.iUnion intro i have : IsAffine (𝒰.obj i) := by diff --git a/Mathlib/AlgebraicGeometry/OpenImmersion.lean b/Mathlib/AlgebraicGeometry/OpenImmersion.lean index 860d3cba578d79..75394dff9384f0 100644 --- a/Mathlib/AlgebraicGeometry/OpenImmersion.lean +++ b/Mathlib/AlgebraicGeometry/OpenImmersion.lean @@ -31,11 +31,11 @@ variable {C : Type u} [Category.{v} C] of LocallyRingedSpaces -/ abbrev IsOpenImmersion {X Y : Scheme.{u}} (f : X ⟶ Y) : Prop := - LocallyRingedSpace.IsOpenImmersion f + LocallyRingedSpace.IsOpenImmersion f.toLRSHom instance IsOpenImmersion.comp {X Y Z : Scheme.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) [IsOpenImmersion f] [IsOpenImmersion g] : IsOpenImmersion (f ≫ g) := -LocallyRingedSpace.IsOpenImmersion.comp f g +LocallyRingedSpace.IsOpenImmersion.comp f.toLRSHom g.toLRSHom namespace LocallyRingedSpace.IsOpenImmersion @@ -45,7 +45,7 @@ protected def scheme (X : LocallyRingedSpace.{u}) (h : ∀ x : X, ∃ (R : CommRingCat) (f : Spec.toLocallyRingedSpace.obj (op R) ⟶ X), - (x ∈ Set.range f.1.base : _) ∧ LocallyRingedSpace.IsOpenImmersion f) : + (x ∈ Set.range f.base : _) ∧ LocallyRingedSpace.IsOpenImmersion f) : Scheme where toLocallyRingedSpace := X local_affine := by @@ -61,7 +61,7 @@ protected def scheme (X : LocallyRingedSpace.{u}) end LocallyRingedSpace.IsOpenImmersion theorem IsOpenImmersion.isOpen_range {X Y : Scheme.{u}} (f : X ⟶ Y) [H : IsOpenImmersion f] : - IsOpen (Set.range f.1.base) := + IsOpen (Set.range f.base) := H.base_open.isOpen_range @[deprecated (since := "2024-03-17")] @@ -71,7 +71,7 @@ namespace Scheme.Hom variable {X Y : Scheme.{u}} (f : Scheme.Hom X Y) [H : IsOpenImmersion f] -theorem openEmbedding : OpenEmbedding f.1.base := +theorem openEmbedding : OpenEmbedding f.base := H.base_open /-- The image of an open immersion as an open set. -/ @@ -81,14 +81,14 @@ def opensRange : Y.Opens := /-- The functor `opens X ⥤ opens Y` associated with an open immersion `f : X ⟶ Y`. -/ abbrev opensFunctor : X.Opens ⥤ Y.Opens := - LocallyRingedSpace.IsOpenImmersion.opensFunctor f + LocallyRingedSpace.IsOpenImmersion.opensFunctor f.toLRSHom /-- `f ''ᵁ U` is notation for the image (as an open set) of `U` under an open immersion `f`. -/ scoped[AlgebraicGeometry] notation3:90 f:91 " ''ᵁ " U:90 => (Scheme.Hom.opensFunctor f).obj U lemma image_le_image_of_le {U V : X.Opens} (e : U ≤ V) : f ''ᵁ U ≤ f ''ᵁ V := by rintro a ⟨u, hu, rfl⟩ - exact Set.mem_image_of_mem (⇑f.val.base) (e hu) + exact Set.mem_image_of_mem (⇑f.base) (e hu) @[simp] lemma opensFunctor_map_homOfLE {U V : X.Opens} (e : U ≤ V) : @@ -131,7 +131,7 @@ lemma image_iSup₂ {ι : Sort*} {κ : ι → Sort*} (s : (i : ι) → κ i → /-- 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 U).symm + (asIso <| LocallyRingedSpace.IsOpenImmersion.invApp f.toLRSHom U).symm @[reassoc (attr := simp)] theorem appIso_inv_naturality {U V : X.Opens} (i : op U ⟶ op V) : @@ -142,7 +142,7 @@ theorem appIso_inv_naturality {U V : X.Opens} (i : op U ⟶ op V) : theorem appIso_hom (U) : (f.appIso U).hom = f.app (f ''ᵁ U) ≫ X.presheaf.map (eqToHom (preimage_image_eq f U).symm).op := - (PresheafedSpace.IsOpenImmersion.inv_invApp f.1 U).trans (by rw [eqToHom_op]) + (PresheafedSpace.IsOpenImmersion.inv_invApp f.toPshHom U).trans (by rw [eqToHom_op]) theorem appIso_hom' (U) : (f.appIso U).hom = f.appLE (f ''ᵁ U) U (preimage_image_eq f U).ge := @@ -151,7 +151,7 @@ theorem appIso_hom' (U) : @[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.1.base U.1)).op := + Y.presheaf.map (homOfLE (Set.image_preimage_subset f.base U.1)).op := PresheafedSpace.IsOpenImmersion.app_invApp _ _ /-- A variant of `app_invApp` that gives an `eqToHom` instead of `homOfLE`. -/ @@ -227,19 +227,18 @@ lemma _root_.AlgebraicGeometry.IsOpenImmersion.of_isLocalization {R S} [CommRing theorem exists_affine_mem_range_and_range_subset {X : Scheme.{u}} {x : X} {U : X.Opens} (hxU : x ∈ U) : ∃ (R : CommRingCat) (f : Spec R ⟶ X), - IsOpenImmersion f ∧ x ∈ Set.range f.1.base ∧ Set.range f.1.base ⊆ U := by + IsOpenImmersion f ∧ x ∈ Set.range f.base ∧ Set.range f.base ⊆ U := by obtain ⟨⟨V, hxV⟩, R, ⟨e⟩⟩ := X.2 x - have : e.hom.1.base ⟨x, hxV⟩ ∈ (Opens.map (e.inv.1.base ≫ V.inclusion')).obj U := - show ((e.hom ≫ e.inv).1.base ⟨x, hxV⟩).1 ∈ U from e.hom_inv_id ▸ hxU + have : e.hom.base ⟨x, hxV⟩ ∈ (Opens.map (e.inv.base ≫ V.inclusion')).obj U := + show ((e.hom ≫ e.inv).base ⟨x, hxV⟩).1 ∈ U from e.hom_inv_id ▸ hxU obtain ⟨_, ⟨_, ⟨r : R, rfl⟩, rfl⟩, hr, hr'⟩ := PrimeSpectrum.isBasis_basic_opens.exists_subset_of_mem_open this (Opens.is_open' _) let f : Spec (CommRingCat.of (Localization.Away r)) ⟶ X := - Spec.map (CommRingCat.ofHom (algebraMap R (Localization.Away r))) ≫ (e.inv ≫ X.ofRestrict _ : _) + Spec.map (CommRingCat.ofHom (algebraMap R (Localization.Away r))) ≫ ⟨e.inv ≫ X.ofRestrict _⟩ refine ⟨.of (Localization.Away r), f, inferInstance, ?_⟩ - rw [Scheme.comp_val_base, LocallyRingedSpace.comp_val, SheafedSpace.comp_base, TopCat.coe_comp, - Set.range_comp] + rw [Scheme.comp_base, TopCat.coe_comp, Set.range_comp] erw [PrimeSpectrum.localization_away_comap_range (Localization.Away r) r] - exact ⟨⟨_, hr, congr(($(e.hom_inv_id).1.base ⟨x, hxV⟩).1)⟩, Set.image_subset_iff.mpr hr'⟩ + exact ⟨⟨_, hr, congr(($(e.hom_inv_id).base ⟨x, hxV⟩).1)⟩, Set.image_subset_iff.mpr hr'⟩ end Scheme @@ -269,10 +268,10 @@ theorem toScheme_toLocallyRingedSpace : upgrade it into a morphism of Schemes. -/ def toSchemeHom : toScheme Y f ⟶ Y := - toLocallyRingedSpaceHom _ f + ⟨toLocallyRingedSpaceHom _ f⟩ @[simp] -theorem toSchemeHom_val : (toSchemeHom Y f).val = f := +theorem toSchemeHom_toPshHom : (toSchemeHom Y f).toPshHom = f := rfl instance toSchemeHom_isOpenImmersion : AlgebraicGeometry.IsOpenImmersion (toSchemeHom Y f) := @@ -283,9 +282,9 @@ theorem scheme_eq_of_locallyRingedSpace_eq {X Y : Scheme.{u}} cases X; cases Y; congr theorem scheme_toScheme {X Y : Scheme.{u}} (f : X ⟶ Y) [AlgebraicGeometry.IsOpenImmersion f] : - toScheme Y f.1 = X := by + toScheme Y f.toPshHom = X := by apply scheme_eq_of_locallyRingedSpace_eq - exact locallyRingedSpace_toLocallyRingedSpace f + exact locallyRingedSpace_toLocallyRingedSpace f.toLRSHom end ToScheme @@ -305,14 +304,14 @@ lemma Scheme.restrict_toPresheafedSpace : (X.restrict h).toPresheafedSpace = X.toPresheafedSpace.restrict h := rfl /-- The canonical map from the restriction to the subspace. -/ -@[simps! val_base, simps! (config := .lemmasOnly) val_c_app] +@[simps! toLRSHom_base, simps! (config := .lemmasOnly) toLRSHom_c_app] def Scheme.ofRestrict : X.restrict h ⟶ X := - X.toLocallyRingedSpace.ofRestrict h + ⟨X.toLocallyRingedSpace.ofRestrict h⟩ @[simp] lemma Scheme.ofRestrict_app (V) : (X.ofRestrict h).app V = X.presheaf.map (h.isOpenMap.adjunction.counit.app V).op := - Scheme.ofRestrict_val_c_app X h (op V) + Scheme.ofRestrict_toLRSHom_c_app X h (op V) instance IsOpenImmersion.ofRestrict : IsOpenImmersion (X.ofRestrict h) := show PresheafedSpace.IsOpenImmersion (X.toPresheafedSpace.ofRestrict h) by infer_instance @@ -344,45 +343,44 @@ variable {X Y Z : Scheme.{u}} (f : X ⟶ Z) (g : Y ⟶ Z) variable [H : IsOpenImmersion f] instance (priority := 100) of_isIso [IsIso g] : IsOpenImmersion g := - @LocallyRingedSpace.IsOpenImmersion.of_isIso _ _ _ - (show IsIso ((inducedFunctor _).map g) by infer_instance) + LocallyRingedSpace.IsOpenImmersion.of_isIso _ -theorem to_iso {X Y : Scheme.{u}} (f : X ⟶ Y) [h : IsOpenImmersion f] [Epi f.1.base] : IsIso f := +theorem to_iso {X Y : Scheme.{u}} (f : X ⟶ Y) [h : IsOpenImmersion f] [Epi f.base] : IsIso f := @isIso_of_reflects_iso _ _ _ _ _ _ f (Scheme.forgetToLocallyRingedSpace ⋙ LocallyRingedSpace.forgetToSheafedSpace ⋙ SheafedSpace.forgetToPresheafedSpace) - (@PresheafedSpace.IsOpenImmersion.to_iso _ _ _ _ f.1 h _) _ + (@PresheafedSpace.IsOpenImmersion.to_iso _ _ _ _ f.toPshHom h _) _ -theorem of_stalk_iso {X Y : Scheme.{u}} (f : X ⟶ Y) (hf : OpenEmbedding f.1.base) +theorem of_stalk_iso {X Y : Scheme.{u}} (f : X ⟶ Y) (hf : OpenEmbedding f.base) [∀ x, IsIso (f.stalkMap x)] : IsOpenImmersion f := - haveI (x : X) : IsIso (f.val.stalkMap x) := inferInstanceAs <| IsIso (f.stalkMap x) - SheafedSpace.IsOpenImmersion.of_stalk_iso f.1 hf + haveI (x : X) : IsIso (f.toShHom.stalkMap x) := inferInstanceAs <| IsIso (f.stalkMap x) + SheafedSpace.IsOpenImmersion.of_stalk_iso f.toShHom hf instance stalk_iso {X Y : Scheme.{u}} (f : X ⟶ Y) [IsOpenImmersion f] (x : X) : IsIso (f.stalkMap x) := - inferInstanceAs <| IsIso (f.val.stalkMap x) + inferInstanceAs <| IsIso (f.toLRSHom.stalkMap x) lemma of_comp {X Y Z : Scheme.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) [IsOpenImmersion g] [IsOpenImmersion (f ≫ g)] : IsOpenImmersion f := haveI (x : X) : IsIso (f.stalkMap x) := - haveI : IsIso (g.stalkMap (f.val.base x) ≫ f.stalkMap x) := by + haveI : IsIso (g.stalkMap (f.base x) ≫ f.stalkMap x) := by rw [← Scheme.stalkMap_comp] infer_instance - IsIso.of_isIso_comp_left (f := g.stalkMap (f.val.base x)) _ + IsIso.of_isIso_comp_left (f := g.stalkMap (f.base x)) _ IsOpenImmersion.of_stalk_iso _ <| OpenEmbedding.of_comp _ (Scheme.Hom.openEmbedding g) (Scheme.Hom.openEmbedding (f ≫ g)) theorem iff_stalk_iso {X Y : Scheme.{u}} (f : X ⟶ Y) : - IsOpenImmersion f ↔ OpenEmbedding f.1.base ∧ ∀ x, IsIso (f.stalkMap x) := - ⟨fun H => ⟨H.1, fun x ↦ inferInstanceAs <| IsIso (f.val.stalkMap x)⟩, + IsOpenImmersion f ↔ OpenEmbedding f.base ∧ ∀ x, IsIso (f.stalkMap x) := + ⟨fun H => ⟨H.1, fun x ↦ inferInstanceAs <| IsIso (f.toPshHom.stalkMap x)⟩, fun ⟨h₁, h₂⟩ => @IsOpenImmersion.of_stalk_iso _ _ f h₁ h₂⟩ theorem _root_.AlgebraicGeometry.isIso_iff_isOpenImmersion {X Y : Scheme.{u}} (f : X ⟶ Y) : - IsIso f ↔ IsOpenImmersion f ∧ Epi f.1.base := + IsIso f ↔ IsOpenImmersion f ∧ Epi f.base := ⟨fun _ => ⟨inferInstance, inferInstance⟩, fun ⟨h₁, h₂⟩ => @IsOpenImmersion.to_iso _ _ f h₁ h₂⟩ theorem _root_.AlgebraicGeometry.isIso_iff_stalk_iso {X Y : Scheme.{u}} (f : X ⟶ Y) : - IsIso f ↔ IsIso f.1.base ∧ ∀ x, IsIso (f.stalkMap x) := by + IsIso f ↔ IsIso f.base ∧ ∀ x, IsIso (f.stalkMap x) := by rw [isIso_iff_isOpenImmersion, IsOpenImmersion.iff_stalk_iso, and_comm, ← and_assoc] refine and_congr ⟨?_, ?_⟩ Iff.rfl · rintro ⟨h₁, h₂⟩ @@ -393,16 +391,18 @@ theorem _root_.AlgebraicGeometry.isIso_iff_stalk_iso {X Y : Scheme.{u}} (f : X (Equiv.ofBijective _ ⟨h₂.inj, (TopCat.epi_iff_surjective _).mp h₁⟩) h₂.continuous h₂.isOpenMap)).hom infer_instance - · intro H; exact ⟨inferInstance, (TopCat.homeoOfIso (asIso f.1.base)).openEmbedding⟩ + · intro H; exact ⟨inferInstance, (TopCat.homeoOfIso (asIso f.base)).openEmbedding⟩ /-- An open immersion induces an isomorphism from the domain onto the image -/ -def isoRestrict : X ≅ (Z.restrict H.base_open : _) where - __ := (LocallyRingedSpace.IsOpenImmersion.isoRestrict f) +def isoRestrict : X ≅ (Z.restrict H.base_open : _) := + Scheme.fullyFaithfulForgetToLocallyRingedSpace.preimageIso + (LocallyRingedSpace.IsOpenImmersion.isoRestrict f.toLRSHom) local notation "forget" => Scheme.forgetToLocallyRingedSpace instance mono : Mono f := - (inducedFunctor _).mono_of_mono_map (show @Mono LocallyRingedSpace _ _ _ f by infer_instance) + Scheme.forgetToLocallyRingedSpace.mono_of_mono_map + (show Mono f.toLRSHom by infer_instance) instance forget_map_isOpenImmersion : LocallyRingedSpace.IsOpenImmersion ((forget).map f) := ⟨H.base_open, H.c_iso⟩ @@ -430,12 +430,12 @@ instance hasLimit_cospan_forget_of_right' : instance forgetCreatesPullbackOfLeft : CreatesLimit (cospan f g) forget := createsLimitOfFullyFaithfulOfIso - (PresheafedSpace.IsOpenImmersion.toScheme Y (@pullback.snd LocallyRingedSpace _ _ _ _ f g _).1) + (PresheafedSpace.IsOpenImmersion.toScheme Y (pullback.snd f.toLRSHom g.toLRSHom).toShHom) (eqToIso (by simp) ≪≫ HasLimit.isoOfNatIso (diagramIsoCospan _).symm) instance forgetCreatesPullbackOfRight : CreatesLimit (cospan g f) forget := createsLimitOfFullyFaithfulOfIso - (PresheafedSpace.IsOpenImmersion.toScheme Y (@pullback.fst LocallyRingedSpace _ _ _ _ g f _).1) + (PresheafedSpace.IsOpenImmersion.toScheme Y (pullback.fst g.toLRSHom f.toLRSHom).1) (eqToIso (by simp) ≪≫ HasLimit.isoOfNatIso (diagramIsoCospan _).symm) instance forgetPreservesOfLeft : PreservesLimit (cospan f g) forget := @@ -453,8 +453,8 @@ instance hasPullback_of_right : HasPullback g f := instance pullback_snd_of_left : IsOpenImmersion (pullback.snd f g) := by have := PreservesPullback.iso_hom_snd forget f g dsimp only [Scheme.forgetToLocallyRingedSpace, inducedFunctor_map] at this - rw [← this] change LocallyRingedSpace.IsOpenImmersion _ + rw [← this] infer_instance instance pullback_fst_of_right : IsOpenImmersion (pullback.fst g f) := by @@ -484,10 +484,10 @@ instance forgetToTopPreservesOfRight : PreservesLimit (cospan g f) Scheme.forget preservesPullbackSymmetry _ _ _ theorem range_pullback_snd_of_left : - Set.range (pullback.snd f g).1.base = (g ⁻¹ᵁ f.opensRange).1 := by - rw [← show _ = (pullback.snd f g).1.base from + Set.range (pullback.snd f g).base = (g ⁻¹ᵁ f.opensRange).1 := by + rw [← show _ = (pullback.snd f g).base from PreservesPullback.iso_hom_snd Scheme.forgetToTop f g, TopCat.coe_comp, Set.range_comp, - Set.range_iff_surjective.mpr, ← @Set.preimage_univ _ _ (pullback.fst f.1.base g.1.base)] + Set.range_iff_surjective.mpr, ← @Set.preimage_univ _ _ (pullback.fst f.base g.base)] -- Porting note (#10691): was `rw` · erw [TopCat.pullback_snd_image_fst_preimage] rw [Set.image_univ] @@ -500,11 +500,11 @@ theorem opensRange_pullback_snd_of_left : Opens.ext (range_pullback_snd_of_left f g) theorem range_pullback_fst_of_right : - Set.range (pullback.fst g f).1.base = - ((Opens.map g.1.base).obj ⟨Set.range f.1.base, H.base_open.isOpen_range⟩).1 := by - rw [← show _ = (pullback.fst g f).1.base from + Set.range (pullback.fst g f).base = + ((Opens.map g.base).obj ⟨Set.range f.base, H.base_open.isOpen_range⟩).1 := by + rw [← show _ = (pullback.fst g f).base from PreservesPullback.iso_hom_fst Scheme.forgetToTop g f, TopCat.coe_comp, Set.range_comp, - Set.range_iff_surjective.mpr, ← @Set.preimage_univ _ _ (pullback.snd g.1.base f.1.base)] + Set.range_iff_surjective.mpr, ← @Set.preimage_univ _ _ (pullback.snd g.base f.base)] -- Porting note (#10691): was `rw` · erw [TopCat.pullback_fst_image_snd_preimage] rw [Set.image_univ] @@ -517,16 +517,16 @@ theorem opensRange_pullback_fst_of_right : Opens.ext (range_pullback_fst_of_right f g) theorem range_pullback_to_base_of_left : - Set.range (pullback.fst f g ≫ f).1.base = - Set.range f.1.base ∩ Set.range g.1.base := by - rw [pullback.condition, Scheme.comp_val_base, TopCat.coe_comp, Set.range_comp, + Set.range (pullback.fst f g ≫ f).base = + Set.range f.base ∩ Set.range g.base := by + rw [pullback.condition, Scheme.comp_base, TopCat.coe_comp, Set.range_comp, range_pullback_snd_of_left, Opens.carrier_eq_coe, Opens.map_obj, Opens.coe_mk, Set.image_preimage_eq_inter_range, Opens.carrier_eq_coe, Scheme.Hom.opensRange_coe] theorem range_pullback_to_base_of_right : - Set.range (pullback.fst g f ≫ g).1.base = - Set.range g.1.base ∩ Set.range f.1.base := by - rw [Scheme.comp_val_base, TopCat.coe_comp, Set.range_comp, range_pullback_fst_of_right, + Set.range (pullback.fst g f ≫ g).base = + Set.range g.base ∩ Set.range f.base := by + rw [Scheme.comp_base, TopCat.coe_comp, Set.range_comp, range_pullback_fst_of_right, Opens.map_obj, Opens.carrier_eq_coe, Opens.coe_mk, Set.image_preimage_eq_inter_range, Set.inter_comm] @@ -535,19 +535,20 @@ For an open immersion `f : X ⟶ Z`, given any morphism of schemes `g : Y ⟶ Z` image is contained in the image of `f`, we can lift this morphism to a unique `Y ⟶ X` that commutes with these maps. -/ -def lift (H' : Set.range g.1.base ⊆ Set.range f.1.base) : Y ⟶ X := - LocallyRingedSpace.IsOpenImmersion.lift f g H' +def lift (H' : Set.range g.base ⊆ Set.range f.base) : Y ⟶ X := + ⟨LocallyRingedSpace.IsOpenImmersion.lift f.toLRSHom g.toLRSHom H'⟩ @[simp, reassoc] -theorem lift_fac (H' : Set.range g.1.base ⊆ Set.range f.1.base) : lift f g H' ≫ f = g := - LocallyRingedSpace.IsOpenImmersion.lift_fac f g H' +theorem lift_fac (H' : Set.range g.base ⊆ Set.range f.base) : lift f g H' ≫ f = g := + Scheme.Hom.ext' <| LocallyRingedSpace.IsOpenImmersion.lift_fac f.toLRSHom g.toLRSHom H' -theorem lift_uniq (H' : Set.range g.1.base ⊆ Set.range f.1.base) (l : Y ⟶ X) (hl : l ≫ f = g) : +theorem lift_uniq (H' : Set.range g.base ⊆ Set.range f.base) (l : Y ⟶ X) (hl : l ≫ f = g) : l = lift f g H' := - LocallyRingedSpace.IsOpenImmersion.lift_uniq f g H' l hl + Scheme.Hom.ext' <| LocallyRingedSpace.IsOpenImmersion.lift_uniq + f.toLRSHom g.toLRSHom H' l.toLRSHom congr(($hl).toLRSHom) /-- Two open immersions with equal range are isomorphic. -/ -def isoOfRangeEq [IsOpenImmersion g] (e : Set.range f.1.base = Set.range g.1.base) : X ≅ Y where +def isoOfRangeEq [IsOpenImmersion g] (e : Set.range f.base = Set.range g.base) : X ≅ Y where hom := lift g f (le_of_eq e) inv := lift f g (le_of_eq e.symm) hom_inv_id := by rw [← cancel_mono f]; simp @@ -555,13 +556,13 @@ def isoOfRangeEq [IsOpenImmersion g] (e : Set.range f.1.base = Set.range g.1.bas @[simp, reassoc] lemma isoOfRangeEq_hom_fac {X Y Z : Scheme.{u}} (f : X ⟶ Z) (g : Y ⟶ Z) - [IsOpenImmersion f] [IsOpenImmersion g] (e : Set.range f.1.base = Set.range g.1.base) : + [IsOpenImmersion f] [IsOpenImmersion g] (e : Set.range f.base = Set.range g.base) : (isoOfRangeEq f g e).hom ≫ g = f := lift_fac _ _ (le_of_eq e) @[simp, reassoc] lemma isoOfRangeEq_inv_fac {X Y Z : Scheme.{u}} (f : X ⟶ Z) (g : Y ⟶ Z) - [IsOpenImmersion f] [IsOpenImmersion g] (e : Set.range f.1.base = Set.range g.1.base) : + [IsOpenImmersion f] [IsOpenImmersion g] (e : Set.range f.base = Set.range g.base) : (isoOfRangeEq f g e).inv ≫ f = g := lift_fac _ _ (le_of_eq e.symm) @@ -569,7 +570,7 @@ theorem app_eq_invApp_app_of_comp_eq_aux {X Y U : Scheme.{u}} (f : Y ⟶ U) (g : (H : fg = f ≫ g) [h : IsOpenImmersion g] (V : U.Opens) : f ⁻¹ᵁ V = fg ⁻¹ᵁ (g ''ᵁ V) := by subst H - rw [Scheme.comp_val_base, Opens.map_comp_obj] + rw [Scheme.comp_base, Opens.map_comp_obj] congr 1 ext1 exact (Set.preimage_image_eq _ h.base_open.inj).symm @@ -625,7 +626,7 @@ def ΓIsoTop {X Y : Scheme.{u}} (f : X ⟶ Y) [IsOpenImmersion f] : (f.appIso ⊤).symm ≪≫ Y.presheaf.mapIso (eqToIso f.image_top_eq_opensRange.symm).op instance {Z : Scheme.{u}} (f : X ⟶ Z) (g : Y ⟶ Z) [IsOpenImmersion f] - (H' : Set.range g.val.base ⊆ Set.range f.val.base) [IsOpenImmersion g] : + (H' : Set.range g.base ⊆ Set.range f.base) [IsOpenImmersion g] : IsOpenImmersion (IsOpenImmersion.lift f g H') := haveI : IsOpenImmersion (IsOpenImmersion.lift f g H' ≫ f) := by simpa IsOpenImmersion.of_comp _ f diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean index 35a672056282e3..106326628a9e44 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean @@ -635,7 +635,7 @@ def toSpec (f) : (Proj| pbo f) ⟶ Spec (A⁰_ f) := open HomogeneousLocalization LocalRing lemma toSpec_base_apply_eq_comap {f} (x : Proj| pbo f) : - (toSpec 𝒜 f).1.base x = PrimeSpectrum.comap (mapId 𝒜 (Submonoid.powers_le.mpr x.2)) + (toSpec 𝒜 f).base x = PrimeSpectrum.comap (mapId 𝒜 (Submonoid.powers_le.mpr x.2)) (closedPoint (AtPrime 𝒜 x.1.asHomogeneousIdeal.toIdeal)) := by show PrimeSpectrum.comap (awayToΓ 𝒜 f ≫ (Proj| pbo f).presheaf.Γgerm x) (LocalRing.closedPoint ((Proj| pbo f).presheaf.stalk x)) = _ @@ -645,7 +645,7 @@ lemma toSpec_base_apply_eq_comap {f} (x : Proj| pbo f) : ((Proj| pbo f).presheaf.stalk x) _ _ _ (isLocalRingHom_of_isIso _))) lemma toSpec_base_apply_eq {f} (x : Proj| pbo f) : - (toSpec 𝒜 f).1.base x = ProjIsoSpecTopComponent.toSpec 𝒜 f x := + (toSpec 𝒜 f).base x = ProjIsoSpecTopComponent.toSpec 𝒜 f x := toSpec_base_apply_eq_comap 𝒜 x |>.trans <| PrimeSpectrum.ext <| Ideal.ext fun z => show ¬ IsUnit _ ↔ z ∈ ProjIsoSpecTopComponent.ToSpec.carrier _ by obtain ⟨z, rfl⟩ := z.mk_surjective @@ -656,19 +656,19 @@ lemma toSpec_base_apply_eq {f} (x : Proj| pbo f) : exact not_not lemma toSpec_base_isIso {f} {m} (f_deg : f ∈ 𝒜 m) (hm : 0 < m) : - IsIso (toSpec 𝒜 f).1.base := by + IsIso (toSpec 𝒜 f).base := by convert (projIsoSpecTopComponent f_deg hm).isIso_hom exact DFunLike.ext _ _ <| toSpec_base_apply_eq 𝒜 lemma mk_mem_toSpec_base_apply {f} (x : Proj| pbo f) (z : NumDenSameDeg 𝒜 (.powers f)) : - HomogeneousLocalization.mk z ∈ ((toSpec 𝒜 f).1.base x).asIdeal ↔ + HomogeneousLocalization.mk z ∈ ((toSpec 𝒜 f).base x).asIdeal ↔ z.num.1 ∈ x.1.asHomogeneousIdeal := (toSpec_base_apply_eq 𝒜 x).symm ▸ ProjIsoSpecTopComponent.ToSpec.mk_mem_carrier _ _ lemma toSpec_preimage_basicOpen {f} (t : NumDenSameDeg 𝒜 (.powers f)) : - (Opens.map (toSpec 𝒜 f).1.base).obj (sbo (.mk t)) = + (Opens.map (toSpec 𝒜 f).base).obj (sbo (.mk t)) = Opens.comap ⟨_, continuous_subtype_val⟩ (pbo t.num.1) := Opens.ext <| Opens.map_coe _ _ ▸ by convert (ProjIsoSpecTopComponent.ToSpec.preimage_basicOpen f t) @@ -676,7 +676,7 @@ lemma toSpec_preimage_basicOpen {f} @[reassoc] lemma toOpen_toSpec_val_c_app (f) (U) : - StructureSheaf.toOpen (A⁰_ f) U.unop ≫ (toSpec 𝒜 f).val.c.app U = + StructureSheaf.toOpen (A⁰_ f) U.unop ≫ (toSpec 𝒜 f).c.app U = awayToΓ 𝒜 f ≫ (Proj| pbo f).presheaf.map (homOfLE le_top).op := Eq.trans (by congr) <| ΓSpec.toOpen_comp_locallyRingedSpaceAdjunction_homEquiv_app _ U @@ -697,7 +697,7 @@ of `A⁰_f` at `φ(x)` where `φ : Proj|D(f) ⟶ Spec A⁰_f` is the morphism of constructed as above. -/ lemma isLocalization_atPrime (f) (x : pbo f) {m} (f_deg : f ∈ 𝒜 m) (hm : 0 < m) : - @IsLocalization (Away 𝒜 f) _ ((toSpec 𝒜 f).1.base x).asIdeal.primeCompl + @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) := @@ -755,46 +755,46 @@ stalk of `Spec A⁰_ f` at `y` is isomorphic to `A⁰ₓ` where `y` is the point to `x`. -/ def specStalkEquiv (f) (x : pbo f) {m} (f_deg : f ∈ 𝒜 m) (hm : 0 < m) : - (Spec.structureSheaf (A⁰_ f)).presheaf.stalk ((toSpec 𝒜 f).1.base x) ≅ + (Spec.structureSheaf (A⁰_ f)).presheaf.stalk ((toSpec 𝒜 f).base x) ≅ CommRingCat.of (AtPrime 𝒜 x.1.asHomogeneousIdeal.toIdeal) := letI : Algebra (Away 𝒜 f) (AtPrime 𝒜 x.1.asHomogeneousIdeal.toIdeal) := (mapId 𝒜 (Submonoid.powers_le.mpr x.2)).toAlgebra haveI := isLocalization_atPrime 𝒜 f x f_deg hm (IsLocalization.algEquiv (R := A⁰_ f) - (M := ((toSpec 𝒜 f).1.base x).asIdeal.primeCompl) - (S := (Spec.structureSheaf (A⁰_ f)).presheaf.stalk ((toSpec 𝒜 f).1.base x)) + (M := ((toSpec 𝒜 f).base x).asIdeal.primeCompl) + (S := (Spec.structureSheaf (A⁰_ f)).presheaf.stalk ((toSpec 𝒜 f).base x)) (Q := AtPrime 𝒜 x.1.asHomogeneousIdeal.toIdeal)).toRingEquiv.toCommRingCatIso lemma toStalk_specStalkEquiv (f) (x : pbo f) {m} (f_deg : f ∈ 𝒜 m) (hm : 0 < m) : - StructureSheaf.toStalk (A⁰_ f) ((toSpec 𝒜 f).1.base x) ≫ (specStalkEquiv 𝒜 f x f_deg hm).hom = + StructureSheaf.toStalk (A⁰_ f) ((toSpec 𝒜 f).base x) ≫ (specStalkEquiv 𝒜 f x f_deg hm).hom = (mapId _ <| Submonoid.powers_le.mpr x.2 : (A⁰_ f) →+* AtPrime 𝒜 x.1.1.toIdeal) := letI : Algebra (Away 𝒜 f) (AtPrime 𝒜 x.1.asHomogeneousIdeal.toIdeal) := (mapId 𝒜 (Submonoid.powers_le.mpr x.2)).toAlgebra letI := isLocalization_atPrime 𝒜 f x f_deg hm (IsLocalization.algEquiv (R := A⁰_ f) - (M := ((toSpec 𝒜 f).1.base x).asIdeal.primeCompl) - (S := (Spec.structureSheaf (A⁰_ f)).presheaf.stalk ((toSpec 𝒜 f).1.base x)) + (M := ((toSpec 𝒜 f).base x).asIdeal.primeCompl) + (S := (Spec.structureSheaf (A⁰_ f)).presheaf.stalk ((toSpec 𝒜 f).base x)) (Q := AtPrime 𝒜 x.1.asHomogeneousIdeal.toIdeal)).toAlgHom.comp_algebraMap 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 ≫ ((Proj.toLocallyRingedSpace 𝒜).restrictStalkIso (Opens.openEmbedding _) x).inv := - IsLocalization.ringHom_ext (R := A⁰_ f) ((toSpec 𝒜 f).1.base x).asIdeal.primeCompl - (S := (Spec.structureSheaf (A⁰_ f)).presheaf.stalk ((toSpec 𝒜 f).1.base x)) <| + IsLocalization.ringHom_ext (R := A⁰_ f) ((toSpec 𝒜 f).base x).asIdeal.primeCompl + (S := (Spec.structureSheaf (A⁰_ f)).presheaf.stalk ((toSpec 𝒜 f).base x)) <| (toStalk_stalkMap_toSpec _ _ _).trans <| by rw [awayToΓ_ΓToStalk, ← toStalk_specStalkEquiv, Category.assoc]; rfl lemma isIso_toSpec (f) {m} (f_deg : f ∈ 𝒜 m) (hm : 0 < m) : IsIso (toSpec 𝒜 f) := by - haveI : IsIso (toSpec 𝒜 f).1.base := toSpec_base_isIso 𝒜 f_deg hm + haveI : IsIso (toSpec 𝒜 f).base := toSpec_base_isIso 𝒜 f_deg hm haveI (x) : IsIso ((toSpec 𝒜 f).stalkMap x) := by rw [stalkMap_toSpec 𝒜 f x f_deg hm]; infer_instance haveI : LocallyRingedSpace.IsOpenImmersion (toSpec 𝒜 f) := LocallyRingedSpace.IsOpenImmersion.of_stalk_iso (toSpec 𝒜 f) - (TopCat.homeoOfIso (asIso <| (toSpec 𝒜 f).1.base)).openEmbedding + (TopCat.homeoOfIso (asIso <| (toSpec 𝒜 f).base)).openEmbedding exact LocallyRingedSpace.IsOpenImmersion.to_iso _ end ProjectiveSpectrum.Proj diff --git a/Mathlib/AlgebraicGeometry/Properties.lean b/Mathlib/AlgebraicGeometry/Properties.lean index 626ba8ab0aecfc..a5bbb08d90c154 100644 --- a/Mathlib/AlgebraicGeometry/Properties.lean +++ b/Mathlib/AlgebraicGeometry/Properties.lean @@ -29,16 +29,14 @@ namespace AlgebraicGeometry variable (X : Scheme) -instance : T0Space X := by - refine T0Space.of_open_cover fun x => ?_ - obtain ⟨U, R, ⟨e⟩⟩ := X.local_affine x - let e' : U.1 ≃ₜ PrimeSpectrum R := - homeoOfIso ((LocallyRingedSpace.forgetToSheafedSpace ⋙ SheafedSpace.forget _).mapIso e) - exact ⟨U.1.1, U.2, U.1.2, e'.embedding.t0Space⟩ +instance : T0Space X := + T0Space.of_open_cover fun x => ⟨_, X.affineCover.covers x, + (X.affineCover.map x).opensRange.2, Embedding.t0Space (Y := PrimeSpectrum _) + (isAffineOpen_opensRange (X.affineCover.map x)).isoSpec.schemeIsoToHomeo.embedding⟩ instance : QuasiSober X := by apply (config := { allowSynthFailures := true }) - quasiSober_of_open_cover (Set.range fun x => Set.range <| (X.affineCover.map x).1.base) + quasiSober_of_open_cover (Set.range fun x => Set.range <| (X.affineCover.map x).base) · rintro ⟨_, i, rfl⟩; exact (X.affineCover.IsOpen i).base_open.isOpen_range · rintro ⟨_, i, rfl⟩ exact @OpenEmbedding.quasiSober _ _ _ _ _ (Homeomorph.ofEmbedding _ @@ -128,7 +126,7 @@ theorem reduce_to_affine_global (P : ∀ {X : Scheme} (_ : X.Opens), Prop) theorem reduce_to_affine_nbhd (P : ∀ (X : Scheme) (_ : X), Prop) (h₁ : ∀ R x, P (Spec R) x) - (h₂ : ∀ {X Y} (f : X ⟶ Y) [IsOpenImmersion f] (x : X), P X x → P Y (f.1.base x)) : + (h₂ : ∀ {X Y} (f : X ⟶ Y) [IsOpenImmersion f] (x : X), P X x → P Y (f.base x)) : ∀ (X : Scheme) (x : X), P X x := by intro X x obtain ⟨y, e⟩ := X.affineCover.covers x diff --git a/Mathlib/AlgebraicGeometry/Pullbacks.lean b/Mathlib/AlgebraicGeometry/Pullbacks.lean index a20cda1ec55677..ca37134839d141 100644 --- a/Mathlib/AlgebraicGeometry/Pullbacks.lean +++ b/Mathlib/AlgebraicGeometry/Pullbacks.lean @@ -503,12 +503,12 @@ def openCoverOfLeftRight (𝒰X : X.OpenCover) (𝒰Y : Y.OpenCover) (f : X ⟶ def openCoverOfBase' (𝒰 : OpenCover Z) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover (pullback f g) := by apply (openCoverOfLeft (𝒰.pullbackCover f) f g).bind intro i - have := PullbackCone.flipIsLimit <| - pasteVertIsPullback rfl (pullbackIsPullback g (𝒰.map i)) - (pullbackIsPullback (pullback.snd g (𝒰.map i)) (pullback.snd f (𝒰.map i))) + haveI := ((IsPullback.of_hasPullback (pullback.snd g (𝒰.map i)) + (pullback.snd f (𝒰.map i))).paste_horiz (IsPullback.of_hasPullback _ _)).flip refine @openCoverOfIsIso _ _ - (f := (pullbackSymmetry _ _).hom ≫ (limit.isoLimitCone ⟨_, this⟩).inv ≫ + (f := (pullbackSymmetry (pullback.snd f (𝒰.map i)) (pullback.snd g (𝒰.map i))).hom ≫ + (limit.isoLimitCone ⟨_, this.isLimit⟩).inv ≫ pullback.map _ _ _ _ (𝟙 _) (𝟙 _) (𝟙 _) ?_ ?_) inferInstance · simp [← pullback.condition] · simp only [Category.comp_id, Category.id_comp] @@ -528,12 +528,12 @@ def openCoverOfBase (𝒰 : OpenCover Z) (f : X ⟶ Z) (g : Y ⟶ Z) : OpenCover ((Equiv.prodPUnit 𝒰.J).symm.trans (Equiv.sigmaEquivProd 𝒰.J PUnit).symm) fun _ => Iso.refl _ intro i rw [Iso.refl_hom, Category.id_comp, openCoverOfBase'_map] - apply pullback.hom_ext <;> dsimp <;> - · simp only [limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app, Category.assoc, - limit.lift_π_assoc, cospan_left, Category.comp_id, limit.isoLimitCone_inv_π, - limit.isoLimitCone_inv_π_assoc, PullbackCone.flip_pt, PullbackCone.π_app_left, - PullbackCone.π_app_right, PullbackCone.flip_fst, PullbackCone.flip_snd, - pullbackSymmetry_hom_comp_snd_assoc, pullbackSymmetry_hom_comp_fst_assoc] + ext : 1 <;> + · simp only [limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app, Equiv.trans_apply, + Equiv.prodPUnit_symm_apply, Category.assoc, limit.lift_π_assoc, cospan_left, Category.comp_id, + limit.isoLimitCone_inv_π_assoc, PullbackCone.π_app_left, IsPullback.cone_fst, + pullbackSymmetry_hom_comp_snd_assoc, limit.isoLimitCone_inv_π, + PullbackCone.π_app_right, IsPullback.cone_snd, pullbackSymmetry_hom_comp_fst_assoc] rfl end Pullback diff --git a/Mathlib/AlgebraicGeometry/ResidueField.lean b/Mathlib/AlgebraicGeometry/ResidueField.lean index 1649e31a1b5e39..dc139a1ac5f989 100644 --- a/Mathlib/AlgebraicGeometry/ResidueField.lean +++ b/Mathlib/AlgebraicGeometry/ResidueField.lean @@ -84,19 +84,19 @@ variable {X Y : Scheme.{u}} (f : X ⟶ Y) -- We need this strange instance for `residueFieldMap`, the type of `F` must be fixed -- like this. The instance `IsLocalRingHom (f.stalkMap x)` already exists, but does not work for -- `residueFieldMap`. -instance (x): IsLocalRingHom (F := Y.presheaf.stalk (f.val.base x) →+* X.presheaf.stalk x) +instance (x): IsLocalRingHom (F := Y.presheaf.stalk (f.base x) →+* X.presheaf.stalk x) (f.stalkMap x) := - f.2 x + f.1.2 x /-- If `X ⟶ Y` is a morphism of locally ringed spaces and `x` a point of `X`, we obtain a morphism of residue fields in the other direction. -/ def Hom.residueFieldMap (f : X.Hom Y) (x : X) : - Y.residueField (f.val.base x) ⟶ X.residueField x := + Y.residueField (f.base x) ⟶ X.residueField x := LocalRing.ResidueField.map (f.stalkMap x) @[reassoc] lemma residue_residueFieldMap (x : X) : - Y.residue (f.val.base x) ≫ f.residueFieldMap x = f.stalkMap x ≫ X.residue x := by + Y.residue (f.base x) ≫ f.residueFieldMap x = f.stalkMap x ≫ X.residue x := by simp [Hom.residueFieldMap] rfl @@ -107,19 +107,19 @@ lemma residueFieldMap_id (x : X) : @[simp] lemma residueFieldMap_comp {Z : Scheme.{u}} (g : Y ⟶ Z) (x : X) : - (f ≫ g).residueFieldMap x = g.residueFieldMap (f.val.base x) ≫ f.residueFieldMap x := + (f ≫ g).residueFieldMap x = g.residueFieldMap (f.base x) ≫ f.residueFieldMap x := LocallyRingedSpace.residueFieldMap_comp _ _ _ @[reassoc] -lemma evaluation_naturality {V : Opens Y} (x : X) (hx : f.val.base x ∈ V) : - Y.evaluation V (f.val.base x) hx ≫ f.residueFieldMap x = +lemma evaluation_naturality {V : Opens Y} (x : X) (hx : f.base x ∈ V) : + Y.evaluation V (f.base x) hx ≫ f.residueFieldMap x = f.app V ≫ X.evaluation (f ⁻¹ᵁ V) x hx := - LocallyRingedSpace.evaluation_naturality f ⟨x, hx⟩ + LocallyRingedSpace.evaluation_naturality f.1 ⟨x, hx⟩ -lemma evaluation_naturality_apply {V : Opens Y} (x : X) (hx : f.val.base x ∈ V) (s) : - f.residueFieldMap x (Y.evaluation V (f.val.base x) hx s) = +lemma evaluation_naturality_apply {V : Opens Y} (x : X) (hx : f.base x ∈ V) (s) : + f.residueFieldMap x (Y.evaluation V (f.base x) hx s) = X.evaluation (f ⁻¹ᵁ V) x hx (f.app V s) := - LocallyRingedSpace.evaluation_naturality_apply f ⟨x, hx⟩ s + LocallyRingedSpace.evaluation_naturality_apply f.1 ⟨x, hx⟩ s instance [IsOpenImmersion f] (x) : IsIso (f.residueFieldMap x) := (LocalRing.ResidueField.mapEquiv diff --git a/Mathlib/AlgebraicGeometry/Restrict.lean b/Mathlib/AlgebraicGeometry/Restrict.lean index dd7a7046d4bdf6..db1fe2f6dad5c9 100644 --- a/Mathlib/AlgebraicGeometry/Restrict.lean +++ b/Mathlib/AlgebraicGeometry/Restrict.lean @@ -46,7 +46,7 @@ def toScheme {X : Scheme.{u}} (U : X.Opens) : Scheme.{u} := instance : CoeOut X.Opens Scheme := ⟨toScheme⟩ /-- The restriction of a scheme to an open subset. -/ -@[simps! val_base_apply] +@[simps! base_apply] def ι : ↑U ⟶ X := X.ofRestrict _ instance : IsOpenImmersion U.ι := inferInstanceAs (IsOpenImmersion (X.ofRestrict _)) @@ -81,7 +81,7 @@ lemma opensRange_ι : U.ι.opensRange = U := Opens.ext Subtype.range_val @[simp] -lemma range_ι : Set.range U.ι.val.base = U := +lemma range_ι : Set.range U.ι.base = U := Subtype.range_val lemma ι_image_top : U.ι ''ᵁ ⊤ = U := @@ -225,17 +225,17 @@ instance {U V : X.Opens} (i : U ⟶ V) : IsOpenImmersion (X.restrictFunctor.map -- Porting note: the `by ...` used to be automatically done by unification magic @[reassoc] theorem Scheme.restrictFunctor_map_ofRestrict {U V : X.Opens} (i : U ⟶ V) : - (X.restrictFunctor.map i).1 ≫ V.ι = U.ι := + (X.restrictFunctor.map i).left ≫ V.ι = U.ι := IsOpenImmersion.lift_fac _ _ (by simpa using i.le) theorem Scheme.restrictFunctor_map_base {U V : X.Opens} (i : U ⟶ V) : - (X.restrictFunctor.map i).1.val.base = (Opens.toTopCat _).map i := by + (X.restrictFunctor.map i).left.base = (Opens.toTopCat _).map i := by ext a; refine Subtype.ext ?_ -- Porting note: `ext` did not pick up `Subtype.ext` - exact (congr_arg (fun f : X.restrict U.openEmbedding ⟶ X => f.val.base a) + exact (congr_arg (fun f : X.restrict U.openEmbedding ⟶ X => f.base a) (X.restrictFunctor_map_ofRestrict i)) theorem Scheme.restrictFunctor_map_app_aux {U V : X.Opens} (i : U ⟶ V) (W : Opens V) : - U.ι ''ᵁ ((X.restrictFunctor.map i).1 ⁻¹ᵁ W) ≤ V.ι ''ᵁ W := by + U.ι ''ᵁ ((X.restrictFunctor.map i).left ⁻¹ᵁ W) ≤ V.ι ''ᵁ W := by simp only [← SetLike.coe_subset_coe, IsOpenMap.functor_obj_coe, Set.image_subset_iff, Scheme.restrictFunctor_map_base, Opens.map_coe, Opens.inclusion'_apply] rintro _ h @@ -304,7 +304,7 @@ noncomputable abbrev Scheme.restrictMapIso {X Y : Scheme.{u}} (f : X ⟶ Y) [IsI apply IsOpenImmersion.isoOfRangeEq (f := (f ⁻¹ᵁ U).ι ≫ f) U.ι _ dsimp rw [Set.range_comp, Opens.range_ι, Opens.range_ι] - refine @Set.image_preimage_eq _ _ f.val.base U.1 f.homeomorph.surjective + refine @Set.image_preimage_eq _ _ f.base U.1 f.homeomorph.surjective section MorphismRestrict @@ -374,12 +374,12 @@ instance {X Y : Scheme.{u}} (f : X ⟶ Y) [IsIso f] (U : Y.Opens) : IsIso (f ∣ delta morphismRestrict; infer_instance theorem morphismRestrict_base_coe {X Y : Scheme.{u}} (f : X ⟶ Y) (U : Y.Opens) (x) : - @Coe.coe U Y (⟨fun x => x.1⟩) ((f ∣_ U).val.base x) = f.val.base x.1 := - congr_arg (fun f => PresheafedSpace.Hom.base (LocallyRingedSpace.Hom.val f) x) + @Coe.coe U Y (⟨fun x => x.1⟩) ((f ∣_ U).base x) = f.base x.1 := + congr_arg (fun f => (Scheme.Hom.toLRSHom f).base x) (morphismRestrict_ι f U) -theorem morphismRestrict_val_base {X Y : Scheme.{u}} (f : X ⟶ Y) (U : Y.Opens) : - ⇑(f ∣_ U).val.base = U.1.restrictPreimage f.val.base := +theorem morphismRestrict_base {X Y : Scheme.{u}} (f : X ⟶ Y) (U : Y.Opens) : + ⇑(f ∣_ U).base = U.1.restrictPreimage f.base := funext fun x => Subtype.ext (morphismRestrict_base_coe f U x) theorem image_morphismRestrict_preimage {X Y : Scheme.{u}} (f : X ⟶ Y) (U : Y.Opens) (V : Opens U) : @@ -387,7 +387,7 @@ theorem image_morphismRestrict_preimage {X Y : Scheme.{u}} (f : X ⟶ Y) (U : Y. ext1 ext x constructor - · rintro ⟨⟨x, hx⟩, hx' : (f ∣_ U).val.base _ ∈ V, rfl⟩ + · rintro ⟨⟨x, hx⟩, hx' : (f ∣_ U).base _ ∈ V, rfl⟩ refine ⟨⟨_, hx⟩, ?_, rfl⟩ -- Porting note: this rewrite was not necessary rw [SetLike.mem_coe] @@ -396,7 +396,7 @@ theorem image_morphismRestrict_preimage {X Y : Scheme.{u}} (f : X ⟶ Y) (U : Y. refine Subtype.ext ?_ exact (morphismRestrict_base_coe f U ⟨x, hx⟩).symm · rintro ⟨⟨x, hx⟩, hx' : _ ∈ V.1, rfl : x = _⟩ - refine ⟨⟨_, hx⟩, (?_ : (f ∣_ U).val.base ⟨x, hx⟩ ∈ V.1), rfl⟩ + refine ⟨⟨_, hx⟩, (?_ : (f ∣_ U).base ⟨x, hx⟩ ∈ V.1), rfl⟩ convert hx' -- Porting note: `ext1` is compiling refine Subtype.ext ?_ @@ -470,7 +470,7 @@ def morphismRestrictRestrict {X Y : Scheme.{u}} (f : X ⟶ Y) (U : Y.Opens) (V : (Scheme.restrictRestrict _ _ _) ?_ · ext x simp only [IsOpenMap.functor_obj_coe, Opens.coe_inclusion', - Opens.map_coe, Set.mem_image, Set.mem_preimage, SetLike.mem_coe, morphismRestrict_val_base] + Opens.map_coe, Set.mem_image, Set.mem_preimage, SetLike.mem_coe, morphismRestrict_base] constructor · rintro ⟨⟨a, h₁⟩, h₂, rfl⟩ exact ⟨_, h₂, rfl⟩ @@ -505,7 +505,7 @@ def morphismRestrictRestrictBasicOpen {X Y : Scheme.{u}} (f : X ⟶ Y) (U : Y.Op -/ def morphismRestrictStalkMap {X Y : Scheme.{u}} (f : X ⟶ Y) (U : Y.Opens) (x) : Arrow.mk ((f ∣_ U).stalkMap x) ≅ Arrow.mk (f.stalkMap x.1) := Arrow.isoMk' _ _ - (U.stalkIso ((f ∣_ U).1.base x) ≪≫ + (U.stalkIso ((f ∣_ U).base x) ≪≫ (TopCat.Presheaf.stalkCongr _ <| Inseparable.of_eq <| morphismRestrict_base_coe f U x)) ((f ⁻¹ᵁ U).stalkIso x) <| by apply TopCat.Presheaf.stalk_hom_ext @@ -532,7 +532,7 @@ lemma resLE_eq_morphismRestrict : f.resLE U (f ⁻¹ᵁ U) le_rfl = f ∣_ U := simp [Scheme.Hom.resLE] lemma resLE_id (i : V ⟶ V') : resLE (𝟙 X) V' V i.le = (X.restrictFunctor.map i).left := by - simp only [resLE, id_val_base, morphismRestrict_id, Category.comp_id] + simp only [resLE, morphismRestrict_id] rfl @[reassoc (attr := simp)] @@ -542,7 +542,7 @@ lemma resLE_comp_ι : f.resLE U V e ≫ U.ι = V.ι ≫ f := by @[reassoc] lemma resLE_comp_resLE {Z : Scheme.{u}} (g : Y ⟶ Z) {W : Z.Opens} (e') : f.resLE U V e ≫ g.resLE W U e' = (f ≫ g).resLE W V - (e.trans ((Opens.map f.val.base).map (homOfLE e')).le) := by + (e.trans ((Opens.map f.base).map (homOfLE e')).le) := by simp [← cancel_mono W.ι] @[reassoc (attr := simp)] @@ -553,7 +553,7 @@ lemma map_resLE (i : V' ⟶ V) : @[reassoc (attr := simp)] lemma resLE_map (i : U ⟶ U') : f.resLE U V e ≫ (Y.restrictFunctor.map i).left = - f.resLE U' V (e.trans ((Opens.map f.1.base).map i).le) := by + f.resLE U' V (e.trans ((Opens.map f.base).map i).le) := by simp_rw [← resLE_id, resLE_comp_resLE, Category.comp_id] lemma resLE_congr (e₁ : U = U') (e₂ : V = V') (P : MorphismProperty Scheme.{u}) : diff --git a/Mathlib/AlgebraicGeometry/Scheme.lean b/Mathlib/AlgebraicGeometry/Scheme.lean index 7714e1f80579cf..3a705c863a6a41 100644 --- a/Mathlib/AlgebraicGeometry/Scheme.lean +++ b/Mathlib/AlgebraicGeometry/Scheme.lean @@ -57,20 +57,31 @@ instance : CoeSort Scheme Type* where abbrev Opens (X : Scheme) : Type* := TopologicalSpace.Opens X /-- A morphism between schemes is a morphism between the underlying locally ringed spaces. -/ --- @[nolint has_nonempty_instance] -- Porting note(#5171): linter not ported yet -def Hom (X Y : Scheme) : Type* := - X.toLocallyRingedSpace ⟶ Y.toLocallyRingedSpace +structure Hom (X Y : Scheme) extends X.toLocallyRingedSpace.Hom Y.toLocallyRingedSpace where + +/-- Cast a morphism of schemes into morphisms of local ringed spaces. -/ +abbrev Hom.toLRSHom {X Y : Scheme.{u}} (f : X.Hom Y) : + X.toLocallyRingedSpace ⟶ Y.toLocallyRingedSpace := + f.toHom_1 + +/-- See Note [custom simps projection] -/ +def Hom.Simps.toLRSHom {X Y : Scheme.{u}} (f : X.Hom Y) : + X.toLocallyRingedSpace ⟶ Y.toLocallyRingedSpace := + f.toLRSHom + +initialize_simps_projections Hom (toHom_1 → toLRSHom) /-- Schemes are a full subcategory of locally ringed spaces. -/ -instance : Category Scheme := - { InducedCategory.category Scheme.toLocallyRingedSpace with Hom := Hom } +instance : Category Scheme where + id X := Hom.mk (𝟙 X.toLocallyRingedSpace) + comp f g := Hom.mk (f.toLRSHom ≫ g.toLRSHom) -/-- `f ⁻¹ᵁ U` is notation for `(Opens.map f.1.base).obj U`, +/-- `f ⁻¹ᵁ U` is notation for `(Opens.map f.base).obj U`, the preimage of an open set `U` under `f`. -/ scoped[AlgebraicGeometry] notation3:90 f:91 " ⁻¹ᵁ " U:90 => @Prefunctor.obj (Scheme.Opens _) _ (Scheme.Opens _) _ - (Opens.map (f : LocallyRingedSpace.Hom _ _).val.base).toPrefunctor U + (Opens.map (f : Scheme.Hom _ _).base).toPrefunctor U /-- `Γ(X, U)` is notation for `X.presheaf.obj (op U)`. -/ scoped[AlgebraicGeometry] notation3 "Γ(" X ", " U ")" => @@ -82,7 +93,7 @@ instance {X : Scheme.{u}} : Subsingleton Γ(X, ⊥) := CommRingCat.subsingleton_of_isTerminal X.sheaf.isTerminalOfEmpty @[continuity, fun_prop] -lemma Hom.continuous {X Y : Scheme} (f : X ⟶ Y) : Continuous f.1.base := f.1.base.2 +lemma Hom.continuous {X Y : Scheme} (f : X ⟶ Y) : Continuous f.base := f.base.2 /-- The structure sheaf of a scheme. -/ protected abbrev sheaf (X : Scheme) := @@ -95,12 +106,12 @@ variable {X Y : Scheme.{u}} (f : Hom X Y) {U U' : Y.Opens} {V V' : X.Opens} /-- Given a morphism of schemes `f : X ⟶ Y`, and open `U ⊆ Y`, this is the induced map `Γ(Y, U) ⟶ Γ(X, f ⁻¹ᵁ U)`. -/ abbrev app (U : Y.Opens) : Γ(Y, U) ⟶ Γ(X, f ⁻¹ᵁ U) := - f.1.c.app (op U) + f.c.app (op U) @[reassoc] lemma naturality (i : op U' ⟶ op U) : - Y.presheaf.map i ≫ f.app U = f.app U' ≫ X.presheaf.map ((Opens.map f.1.base).map i.unop).op := - f.1.c.naturality i + Y.presheaf.map i ≫ f.app U = f.app U' ≫ X.presheaf.map ((Opens.map f.base).map i.unop).op := + f.c.naturality i /-- Given a morphism of schemes `f : X ⟶ Y`, and open sets `U ⊆ Y`, `V ⊆ f ⁻¹' U`, this is the induced map `Γ(Y, U) ⟶ Γ(X, V)`. -/ @@ -121,7 +132,7 @@ lemma appLE_map' (e : V ≤ f ⁻¹ᵁ U) (i : V = V') : @[reassoc (attr := simp)] lemma map_appLE (e : V ≤ f ⁻¹ᵁ U) (i : op U' ⟶ op U) : Y.presheaf.map i ≫ f.appLE U V e = - f.appLE U' V (e.trans ((Opens.map f.1.base).map i.unop).le) := by + f.appLE U' V (e.trans ((Opens.map f.base).map i.unop).le) := by rw [Hom.appLE, f.naturality_assoc, ← Functor.map_comp] rfl @@ -143,22 +154,23 @@ lemma appLE_congr (e : V ≤ f ⁻¹ᵁ U) (e₁ : U = U') (e₂ : V = V') P (f.appLE U V e) ↔ P (f.appLE U' V' (e₁ ▸ e₂ ▸ e)) := by subst e₁; subst e₂; rfl -/-- An isomorphism of schemes induces a homeomorphism of the underlying topological spaces. -/ -noncomputable def homeomorph [IsIso f] : X ≃ₜ Y := - TopCat.homeoOfIso (asIso <| f.val.base) - -/-- A morphism of schemes `f : X ⟶ Y` induces a local ring homomorphis from `Y.presheaf.stalk (f x)` -to `X.presheaf.stalk x` for any `x : X`. -/ -def stalkMap (x : X) : Y.presheaf.stalk (f.val.base x) ⟶ X.presheaf.stalk x := - f.val.stalkMap x +/-- A morphism of schemes `f : X ⟶ Y` induces a local ring homomorphism from +`Y.presheaf.stalk (f x)` to `X.presheaf.stalk x` for any `x : X`. -/ +def stalkMap (x : X) : Y.presheaf.stalk (f.base x) ⟶ X.presheaf.stalk x := + f.toLRSHom.stalkMap x @[ext (iff := false)] -protected lemma ext {f g : X ⟶ Y} (h_base : f.1.base = g.1.base) +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 := - LocallyRingedSpace.Hom.ext <| SheafedSpace.ext _ _ h_base + (eqToHom congr((Opens.map $h_base.symm).obj U)).op = g.app U) : f = g := by + cases f; cases g; congr 1 + exact LocallyRingedSpace.Hom.ext' <| SheafedSpace.ext _ _ h_base (TopCat.Presheaf.ext fun U ↦ by simpa using h_app U) +/-- An alternative ext lemma for scheme morphisms. -/ +protected lemma ext' {f g : X ⟶ Y} (h : f.toLRSHom = g.toLRSHom) : f = g := by + cases f; cases g; congr 1 + lemma preimage_iSup {ι} (U : ι → Opens Y) : f ⁻¹ᵁ iSup U = ⨆ i, f ⁻¹ᵁ U i := Opens.ext (by simp) @@ -177,27 +189,38 @@ lemma preimage_comp {X Y Z : Scheme.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) (U) : /-- The forgetful functor from `Scheme` to `LocallyRingedSpace`. -/ @[simps!] -def forgetToLocallyRingedSpace : Scheme ⥤ LocallyRingedSpace := - inducedFunctor _ --- deriving Full, Faithful -- Porting note: no delta derive handler, see https://github.com/leanprover-community/mathlib4/issues/5020 +def forgetToLocallyRingedSpace : Scheme ⥤ LocallyRingedSpace where + obj := toLocallyRingedSpace + map := Hom.toLRSHom /-- The forget functor `Scheme ⥤ LocallyRingedSpace` is fully faithful. -/ -@[simps!] +@[simps preimage_toLRSHom] def fullyFaithfulForgetToLocallyRingedSpace : - forgetToLocallyRingedSpace.FullyFaithful := - fullyFaithfulInducedFunctor _ + forgetToLocallyRingedSpace.FullyFaithful where + preimage := Hom.mk instance : forgetToLocallyRingedSpace.Full := - InducedCategory.full _ + fullyFaithfulForgetToLocallyRingedSpace.full instance : forgetToLocallyRingedSpace.Faithful := - InducedCategory.faithful _ + fullyFaithfulForgetToLocallyRingedSpace.faithful /-- The forgetful functor from `Scheme` to `TopCat`. -/ @[simps!] def forgetToTop : Scheme ⥤ TopCat := Scheme.forgetToLocallyRingedSpace ⋙ LocallyRingedSpace.forgetToTop +/-- An isomorphism of schemes induces a homeomorphism of the underlying topological spaces. -/ +noncomputable def homeoOfIso {X Y : Scheme.{u}} (e : X ≅ Y) : X ≃ₜ Y := + TopCat.homeoOfIso (forgetToTop.mapIso e) + +alias _root_.CategoryTheory.Iso.schemeIsoToHomeo := homeoOfIso + +/-- An isomorphism of schemes induces a homeomorphism of the underlying topological spaces. -/ +noncomputable def Hom.homeomorph {X Y : Scheme.{u}} (f : X.Hom Y) [IsIso (C := Scheme) f] : + X ≃ₜ Y := + (asIso f).schemeIsoToHomeo + -- Porting note: Lean seems not able to find this coercion any more instance hasCoeToTopCat : CoeOut Scheme TopCat where coe X := X.carrier @@ -208,7 +231,7 @@ unif_hint forgetToTop_obj_eq_coe (X : Scheme) where ⊢ forgetToTop.obj X ≟ (X : TopCat) @[simp] -theorem id_val_base (X : Scheme) : (𝟙 X : _).1.base = 𝟙 _ := +theorem id.base (X : Scheme) : (𝟙 X : _).base = 𝟙 _ := rfl @[simp] @@ -216,22 +239,23 @@ theorem id_app {X : Scheme} (U : X.Opens) : (𝟙 X : _).app U = 𝟙 _ := rfl @[reassoc] -theorem comp_val {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) : (f ≫ g).val = f.val ≫ g.val := +theorem comp_toLRSHom {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) : + (f ≫ g).toLRSHom = f.toLRSHom ≫ g.toLRSHom := rfl @[simp, reassoc] -- reassoc lemma does not need `simp` theorem comp_coeBase {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) : - (f ≫ g).val.base = f.val.base ≫ g.val.base := + (f ≫ g).base = f.base ≫ g.base := rfl -- Porting note: removed elementwise attribute, as generated lemmas were trivial. @[reassoc] -theorem comp_val_base {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) : - (f ≫ g).val.base = f.val.base ≫ g.val.base := +theorem comp_base {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) : + (f ≫ g).base = f.base ≫ g.base := rfl -theorem comp_val_base_apply {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) (x : X) : - (f ≫ g).val.base x = g.val.base (f.val.base x) := by +theorem comp_base_apply {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) (x : X) : + (f ≫ g).base x = g.base (f.base x) := by simp @[simp, reassoc] -- reassoc lemma does not need `simp` @@ -244,7 +268,7 @@ theorem comp_app {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) (U) : theorem appLE_comp_appLE {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) (U V W e₁ e₂) : g.appLE U V e₁ ≫ f.appLE V W e₂ = - (f ≫ g).appLE U W (e₂.trans ((Opens.map f.1.base).map (homOfLE e₁)).le) := by + (f ≫ g).appLE U W (e₂.trans ((Opens.map f.base).map (homOfLE e₁)).le) := by dsimp [Hom.appLE] rw [Category.assoc, f.naturality_assoc, ← Functor.map_comp] rfl @@ -262,8 +286,8 @@ theorem app_eq {X Y : Scheme} (f : X ⟶ Y) {U V : Y.Opens} (e : U = V) : f.app U = Y.presheaf.map (eqToHom e.symm).op ≫ f.app V ≫ - X.presheaf.map (eqToHom (congr_arg (Opens.map f.val.base).obj e)).op := by - rw [← IsIso.inv_comp_eq, ← Functor.map_inv, f.val.c.naturality] + X.presheaf.map (eqToHom (congr_arg (Opens.map f.base).obj e)).op := by + rw [← IsIso.inv_comp_eq, ← Functor.map_inv, f.naturality] cases e rfl @@ -276,21 +300,20 @@ lemma presheaf_map_eqToHom_op (X : Scheme) (U V : X.Opens) (i : U = V) : X.presheaf.map (eqToHom i).op = eqToHom (i ▸ rfl) := by rw [eqToHom_op, eqToHom_map] -instance is_locallyRingedSpace_iso {X Y : Scheme} (f : X ⟶ Y) [IsIso f] : - @IsIso LocallyRingedSpace _ _ _ f := +instance is_locallyRingedSpace_iso {X Y : Scheme} (f : X ⟶ Y) [IsIso f] : IsIso f.toLRSHom := forgetToLocallyRingedSpace.map_isIso f -instance val_base_isIso {X Y : Scheme.{u}} (f : X ⟶ Y) [IsIso f] : IsIso f.1.base := +instance base_isIso {X Y : Scheme.{u}} (f : X ⟶ Y) [IsIso f] : IsIso f.base := Scheme.forgetToTop.map_isIso f -- Porting note: need an extra instance here. -instance {X Y : Scheme} (f : X ⟶ Y) [IsIso f] (U) : IsIso (f.val.c.app U) := - haveI := PresheafedSpace.c_isIso_of_iso f.val - NatIso.isIso_app_of_isIso _ _ +instance {X Y : Scheme} (f : X ⟶ Y) [IsIso f] (U) : IsIso (f.c.app U) := + haveI := PresheafedSpace.c_isIso_of_iso f.toPshHom + NatIso.isIso_app_of_isIso f.c _ instance {X Y : Scheme} (f : X ⟶ Y) [IsIso f] (U) : IsIso (f.app U) := - haveI := PresheafedSpace.c_isIso_of_iso f.val - NatIso.isIso_app_of_isIso _ _ + haveI := PresheafedSpace.c_isIso_of_iso f.toPshHom + NatIso.isIso_app_of_isIso f.c _ @[simp] theorem inv_app {X Y : Scheme} (f : X ⟶ Y) [IsIso f] (U : X.Opens) : @@ -318,16 +341,16 @@ theorem Spec_toLocallyRingedSpace (R : CommRingCat) : /-- The induced map of a ring homomorphism on the ring spectra, as a morphism of schemes. -/ def Spec.map {R S : CommRingCat} (f : R ⟶ S) : Spec S ⟶ Spec R := - (Spec.locallyRingedSpaceMap f : Spec.locallyRingedSpaceObj S ⟶ Spec.locallyRingedSpaceObj R) + ⟨Spec.locallyRingedSpaceMap f⟩ @[simp] theorem Spec.map_id (R : CommRingCat) : Spec.map (𝟙 R) = 𝟙 (Spec R) := - Spec.locallyRingedSpaceMap_id R + Scheme.Hom.ext' <| Spec.locallyRingedSpaceMap_id R @[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 := - Spec.locallyRingedSpaceMap_comp f g + Scheme.Hom.ext' <| Spec.locallyRingedSpaceMap_comp f g /-- The spectrum, as a contravariant functor from commutative rings to schemes. -/ @[simps] @@ -358,7 +381,7 @@ variable {R S : CommRingCat.{u}} (f : R ⟶ S) lemma Spec_carrier (R : CommRingCat.{u}) : (Spec R).carrier = PrimeSpectrum R := rfl lemma Spec_sheaf (R : CommRingCat.{u}) : (Spec R).sheaf = Spec.structureSheaf R := rfl lemma Spec_presheaf (R : CommRingCat.{u}) : (Spec R).presheaf = (Spec.structureSheaf R).1 := rfl -lemma Spec.map_base : (Spec.map f).1.base = PrimeSpectrum.comap f := rfl +lemma Spec.map_base : (Spec.map f).base = PrimeSpectrum.comap f := rfl lemma Spec.map_app (U) : (Spec.map f).app U = StructureSheaf.comap f U (Spec.map f ⁻¹ᵁ U) le_rfl := rfl @@ -388,9 +411,9 @@ instance : Inhabited Scheme := /-- The global sections, notated Gamma. -/ def Γ : Schemeᵒᵖ ⥤ CommRingCat := - (inducedFunctor Scheme.toLocallyRingedSpace).op ⋙ LocallyRingedSpace.Γ + Scheme.forgetToLocallyRingedSpace.op ⋙ LocallyRingedSpace.Γ -theorem Γ_def : Γ = (inducedFunctor Scheme.toLocallyRingedSpace).op ⋙ LocallyRingedSpace.Γ := +theorem Γ_def : Γ = Scheme.forgetToLocallyRingedSpace.op ⋙ LocallyRingedSpace.Γ := rfl @[simp] @@ -491,7 +514,7 @@ lemma basicOpen_restrict (i : V ⟶ U) (f : Γ(X, U)) : @[simp] theorem preimage_basicOpen {X Y : Scheme.{u}} (f : X ⟶ Y) {U : Y.Opens} (r : Γ(Y, U)) : f ⁻¹ᵁ (Y.basicOpen r) = X.basicOpen (f.app U r) := - LocallyRingedSpace.preimage_basicOpen f r + LocallyRingedSpace.preimage_basicOpen f.toLRSHom r lemma basicOpen_appLE {X Y : Scheme.{u}} (f : X ⟶ Y) (U : X.Opens) (V : Y.Opens) (e : U ≤ f ⁻¹ᵁ V) (s : Γ(Y, V)) : X.basicOpen (f.appLE V U e s) = U ⊓ f ⁻¹ᵁ (Y.basicOpen s) := by @@ -582,25 +605,25 @@ theorem Scheme.Spec_map_presheaf_map_eqToHom {X : Scheme} {U V : X.Opens} (h : U simp [eqToHom_map] @[reassoc (attr := simp)] -lemma Scheme.iso_hom_val_base_inv_val_base {X Y : Scheme.{u}} (e : X ≅ Y) : - e.hom.val.base ≫ e.inv.val.base = 𝟙 _ := - LocallyRingedSpace.iso_hom_val_base_inv_val_base (Scheme.forgetToLocallyRingedSpace.mapIso e) +lemma Scheme.iso_hom_base_inv_base {X Y : Scheme.{u}} (e : X ≅ Y) : + e.hom.base ≫ e.inv.base = 𝟙 _ := + LocallyRingedSpace.iso_hom_base_inv_base (Scheme.forgetToLocallyRingedSpace.mapIso e) @[simp] -lemma Scheme.iso_hom_val_base_inv_val_base_apply {X Y : Scheme.{u}} (e : X ≅ Y) (x : X) : - (e.inv.val.base (e.hom.val.base x)) = x := by - show (e.hom.val.base ≫ e.inv.val.base) x = 𝟙 X.toPresheafedSpace x +lemma Scheme.iso_hom_base_inv_base_apply {X Y : Scheme.{u}} (e : X ≅ Y) (x : X) : + (e.inv.base (e.hom.base x)) = x := by + show (e.hom.base ≫ e.inv.base) x = 𝟙 X.toPresheafedSpace x simp @[reassoc (attr := simp)] -lemma Scheme.iso_inv_val_base_hom_val_base {X Y : Scheme.{u}} (e : X ≅ Y) : - e.inv.val.base ≫ e.hom.val.base = 𝟙 _ := - LocallyRingedSpace.iso_inv_val_base_hom_val_base (Scheme.forgetToLocallyRingedSpace.mapIso e) +lemma Scheme.iso_inv_base_hom_base {X Y : Scheme.{u}} (e : X ≅ Y) : + e.inv.base ≫ e.hom.base = 𝟙 _ := + LocallyRingedSpace.iso_inv_base_hom_base (Scheme.forgetToLocallyRingedSpace.mapIso e) @[simp] -lemma Scheme.iso_inv_val_base_hom_val_base_apply {X Y : Scheme.{u}} (e : X ≅ Y) (y : Y) : - (e.hom.val.base (e.inv.val.base y)) = y := by - show (e.inv.val.base ≫ e.hom.val.base) y = 𝟙 Y.toPresheafedSpace y +lemma Scheme.iso_inv_base_hom_base_apply {X Y : Scheme.{u}} (e : X ≅ Y) (y : Y) : + (e.hom.base (e.inv.base y)) = y := by + show (e.inv.base ≫ e.hom.base) y = 𝟙 Y.toPresheafedSpace y simp section Stalks @@ -615,17 +638,17 @@ lemma stalkMap_id (X : Scheme.{u}) (x : X) : PresheafedSpace.stalkMap.id _ x lemma stalkMap_comp {X Y Z : Scheme.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) (x : X) : - (f ≫ g : X ⟶ Z).stalkMap x = g.stalkMap (f.val.base x) ≫ f.stalkMap x := - PresheafedSpace.stalkMap.comp f.val g.val x + (f ≫ g : X ⟶ Z).stalkMap x = g.stalkMap (f.base x) ≫ f.stalkMap x := + PresheafedSpace.stalkMap.comp f.toPshHom g.toPshHom x @[reassoc] lemma stalkSpecializes_stalkMap (x x' : X) - (h : x ⤳ x') : Y.presheaf.stalkSpecializes (f.val.base.map_specializes h) ≫ f.stalkMap x = + (h : x ⤳ x') : Y.presheaf.stalkSpecializes (f.base.map_specializes h) ≫ f.stalkMap x = f.stalkMap x' ≫ X.presheaf.stalkSpecializes h := - PresheafedSpace.stalkMap.stalkSpecializes_stalkMap f.val h + PresheafedSpace.stalkMap.stalkSpecializes_stalkMap f.toPshHom h lemma stalkSpecializes_stalkMap_apply (x x' : X) (h : x ⤳ x') (y) : - f.stalkMap x (Y.presheaf.stalkSpecializes (f.val.base.map_specializes h) y) = + f.stalkMap x (Y.presheaf.stalkSpecializes (f.base.map_specializes h) y) = (X.presheaf.stalkSpecializes h (f.stalkMap x' y)) := DFunLike.congr_fun (stalkSpecializes_stalkMap f x x' h) y @@ -633,54 +656,54 @@ lemma stalkSpecializes_stalkMap_apply (x x' : X) (h : x ⤳ x') (y) : lemma stalkMap_congr (f g : X ⟶ Y) (hfg : f = g) (x x' : X) (hxx' : x = x') : f.stalkMap x ≫ (X.presheaf.stalkCongr (.of_eq hxx')).hom = (Y.presheaf.stalkCongr (.of_eq <| hfg ▸ hxx' ▸ rfl)).hom ≫ g.stalkMap x' := - LocallyRingedSpace.stalkMap_congr f g hfg x x' hxx' + LocallyRingedSpace.stalkMap_congr f.toLRSHom g.toLRSHom congr(($hfg).toLRSHom) x x' hxx' @[reassoc] lemma stalkMap_congr_hom (f g : X ⟶ Y) (hfg : f = g) (x : X) : f.stalkMap x = (Y.presheaf.stalkCongr (.of_eq <| hfg ▸ rfl)).hom ≫ g.stalkMap x := - LocallyRingedSpace.stalkMap_congr_hom f g hfg x + LocallyRingedSpace.stalkMap_congr_hom f.toLRSHom g.toLRSHom congr(($hfg).toLRSHom) x @[reassoc] lemma stalkMap_congr_point (x x' : X) (hxx' : x = x') : f.stalkMap x ≫ (X.presheaf.stalkCongr (.of_eq hxx')).hom = (Y.presheaf.stalkCongr (.of_eq <| hxx' ▸ rfl)).hom ≫ f.stalkMap x' := - LocallyRingedSpace.stalkMap_congr_point f x x' hxx' + LocallyRingedSpace.stalkMap_congr_point f.toLRSHom x x' hxx' @[reassoc (attr := simp)] lemma stalkMap_hom_inv (e : X ≅ Y) (y : Y) : - e.hom.stalkMap (e.inv.val.base y) ≫ e.inv.stalkMap y = + e.hom.stalkMap (e.inv.base y) ≫ e.inv.stalkMap y = (Y.presheaf.stalkCongr (.of_eq (by simp))).hom := LocallyRingedSpace.stalkMap_hom_inv (forgetToLocallyRingedSpace.mapIso e) y @[simp] lemma stalkMap_hom_inv_apply (e : X ≅ Y) (y : Y) (z) : - e.inv.stalkMap y (e.hom.stalkMap (e.inv.val.base y) z) = + e.inv.stalkMap y (e.hom.stalkMap (e.inv.base y) z) = (Y.presheaf.stalkCongr (.of_eq (by simp))).hom z := DFunLike.congr_fun (stalkMap_hom_inv e y) z @[reassoc (attr := simp)] lemma stalkMap_inv_hom (e : X ≅ Y) (x : X) : - e.inv.stalkMap (e.hom.val.base x) ≫ e.hom.stalkMap x = + e.inv.stalkMap (e.hom.base x) ≫ e.hom.stalkMap x = (X.presheaf.stalkCongr (.of_eq (by simp))).hom := LocallyRingedSpace.stalkMap_inv_hom (forgetToLocallyRingedSpace.mapIso e) x @[simp] lemma stalkMap_inv_hom_apply (e : X ≅ Y) (x : X) (y) : - e.hom.stalkMap x (e.inv.stalkMap (e.hom.val.base x) y) = + e.hom.stalkMap x (e.inv.stalkMap (e.hom.base x) y) = (X.presheaf.stalkCongr (.of_eq (by simp))).hom y := DFunLike.congr_fun (stalkMap_inv_hom e x) y @[reassoc (attr := simp)] -lemma stalkMap_germ (U : Y.Opens) (x : X) (hx : f.val.base x ∈ U) : - Y.presheaf.germ U (f.val.base x) hx ≫ f.stalkMap x = +lemma stalkMap_germ (U : Y.Opens) (x : X) (hx : f.base x ∈ U) : + Y.presheaf.germ U (f.base x) hx ≫ f.stalkMap x = f.app U ≫ X.presheaf.germ (f ⁻¹ᵁ U) x hx := - PresheafedSpace.stalkMap_germ f.val U x hx + PresheafedSpace.stalkMap_germ f.toPshHom U x hx @[simp] -lemma stalkMap_germ_apply (U : Y.Opens) (x : X) (hx : f.val.base x ∈ U) (y) : - f.stalkMap x (Y.presheaf.germ _ (f.val.base x) hx y) = +lemma stalkMap_germ_apply (U : Y.Opens) (x : X) (hx : f.base x ∈ U) (y) : + f.stalkMap x (Y.presheaf.germ _ (f.base x) hx y) = X.presheaf.germ (f ⁻¹ᵁ U) x hx (f.app U y) := - PresheafedSpace.stalkMap_germ_apply f.val U x hx y + PresheafedSpace.stalkMap_germ_apply f.toPshHom U x hx y end Scheme diff --git a/Mathlib/AlgebraicGeometry/Spec.lean b/Mathlib/AlgebraicGeometry/Spec.lean index 80690a03c20225..349fe5db9ccec0 100644 --- a/Mathlib/AlgebraicGeometry/Spec.lean +++ b/Mathlib/AlgebraicGeometry/Spec.lean @@ -226,7 +226,7 @@ theorem localRingHom_comp_stalkIso {R S : CommRingCat.{u}} (f : R ⟶ S) (p : Pr /-- The induced map of a ring homomorphism on the prime spectra, as a morphism of locally ringed spaces. -/ -@[simps] +@[simps toShHom] def Spec.locallyRingedSpaceMap {R S : CommRingCat.{u}} (f : R ⟶ S) : Spec.locallyRingedSpaceObj S ⟶ Spec.locallyRingedSpaceObj R := LocallyRingedSpace.Hom.mk (Spec.sheafedSpaceMap f) fun p => @@ -251,14 +251,14 @@ def Spec.locallyRingedSpaceMap {R S : CommRingCat.{u}} (f : R ⟶ S) : @[simp] theorem Spec.locallyRingedSpaceMap_id (R : CommRingCat.{u}) : Spec.locallyRingedSpaceMap (𝟙 R) = 𝟙 (Spec.locallyRingedSpaceObj R) := - LocallyRingedSpace.Hom.ext <| by - rw [Spec.locallyRingedSpaceMap_val, Spec.sheafedSpaceMap_id]; rfl + LocallyRingedSpace.Hom.ext' <| by + rw [Spec.locallyRingedSpaceMap_toShHom, Spec.sheafedSpaceMap_id]; rfl theorem Spec.locallyRingedSpaceMap_comp {R S T : CommRingCat.{u}} (f : R ⟶ S) (g : S ⟶ T) : Spec.locallyRingedSpaceMap (f ≫ g) = Spec.locallyRingedSpaceMap g ≫ Spec.locallyRingedSpaceMap f := - LocallyRingedSpace.Hom.ext <| by - rw [Spec.locallyRingedSpaceMap_val, Spec.sheafedSpaceMap_comp]; rfl + LocallyRingedSpace.Hom.ext' <| by + rw [Spec.locallyRingedSpaceMap_toShHom, Spec.sheafedSpaceMap_comp]; rfl /-- Spec, as a contravariant functor from commutative rings to locally ringed spaces. -/ diff --git a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean index 0f98d08e805815..72d5eb095aa969 100644 --- a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean +++ b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean @@ -70,44 +70,59 @@ def 𝒪 : Sheaf CommRingCat X.toTopCat := /-- A morphism of locally ringed spaces is a morphism of ringed spaces such that the morphisms induced on stalks are local ring homomorphisms. -/ @[ext] -structure Hom (X Y : LocallyRingedSpace.{u}) : Type _ where - /-- the underlying morphism between ringed spaces -/ - val : X.toSheafedSpace ⟶ Y.toSheafedSpace +structure Hom (X Y : LocallyRingedSpace.{u}) + extends X.toPresheafedSpace.Hom Y.toPresheafedSpace : Type _ where /-- the underlying morphism induces a local ring homomorphism on stalks -/ - prop : ∀ x, IsLocalRingHom (val.stalkMap x) + prop : ∀ x, IsLocalRingHom (toHom.stalkMap x) + +/-- A morphism of locally ringed spaces as a morphism of sheafed spaces. -/ +abbrev Hom.toShHom {X Y : LocallyRingedSpace.{u}} (f : X.Hom Y) : + X.toSheafedSpace ⟶ Y.toSheafedSpace := f.1 + +@[simp, nolint simpVarHead] +lemma Hom.toShHom_mk {X Y : LocallyRingedSpace.{u}} + (f : X.toPresheafedSpace.Hom Y.toPresheafedSpace) (hf) : + Hom.toShHom ⟨f, hf⟩ = f := rfl instance : Quiver LocallyRingedSpace := ⟨Hom⟩ -@[ext] lemma Hom.ext' (X Y : LocallyRingedSpace.{u}) {f g : X ⟶ Y} (h : f.val = g.val) : f = g := - Hom.ext h +@[ext] lemma Hom.ext' {X Y : LocallyRingedSpace.{u}} {f g : X ⟶ Y} (h : f.toShHom = g.toShHom) : + f = g := by cases f; cases g; congr + +/-- See Note [custom simps projection] -/ +def Hom.Simps.toShHom {X Y : LocallyRingedSpace.{u}} (f : X.Hom Y) : + X.toSheafedSpace ⟶ Y.toSheafedSpace := + f.toShHom + +initialize_simps_projections Hom (toHom → toShHom) /-- 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) : Y.presheaf.stalk (f.1.1 x) ⟶ X.presheaf.stalk x := - f.val.stalkMap x + f.toShHom.stalkMap x instance isLocalRingHomStalkMap {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) (x : X) : IsLocalRingHom (f.stalkMap x) := f.2 x instance isLocalRingHomValStalkMap {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) (x : X) : - IsLocalRingHom (f.val.stalkMap x) := + IsLocalRingHom (f.toShHom.stalkMap x) := f.2 x /-- The identity morphism on a locally ringed space. -/ -@[simps] +@[simps! toShHom] def id (X : LocallyRingedSpace.{u}) : Hom X X := - ⟨𝟙 _, fun x => by erw [PresheafedSpace.stalkMap.id]; apply isLocalRingHom_id⟩ + ⟨𝟙 X.toSheafedSpace, fun x => by erw [PresheafedSpace.stalkMap.id]; apply isLocalRingHom_id⟩ instance (X : LocallyRingedSpace.{u}) : Inhabited (Hom X X) := ⟨id X⟩ /-- Composition of morphisms of locally ringed spaces. -/ def comp {X Y Z : LocallyRingedSpace.{u}} (f : Hom X Y) (g : Hom Y Z) : Hom X Z := - ⟨f.val ≫ g.val, fun x => by + ⟨f.toShHom ≫ g.toShHom, fun x => by erw [PresheafedSpace.stalkMap.comp] exact @RingHom.isLocalRingHom_comp _ _ _ _ _ _ _ _ (f.2 _) (g.2 _)⟩ @@ -116,9 +131,9 @@ instance : Category LocallyRingedSpace.{u} where Hom := Hom id := id comp {_ _ _} f g := comp f g - comp_id {X Y} f := Hom.ext <| by simp [comp] - id_comp {X Y} f := Hom.ext <| by simp [comp] - assoc {_ _ _ _} f g h := Hom.ext <| by simp [comp] + comp_id {X Y} f := Hom.ext' <| by simp [comp] + id_comp {X Y} f := Hom.ext' <| by simp [comp] + assoc {_ _ _ _} f g h := Hom.ext' <| by simp [comp] /-- The forgetful functor from `LocallyRingedSpace` to `SheafedSpace CommRing`. -/ @[simps] @@ -126,8 +141,9 @@ def forgetToSheafedSpace : LocallyRingedSpace.{u} ⥤ SheafedSpace CommRingCat.{ obj X := X.toSheafedSpace map {_ _} f := f.1 +/-- The canonical map `X ⟶ Spec Γ(X, ⊤)`. This is the unit of the `Γ-Spec` adjunction. -/ instance : forgetToSheafedSpace.Faithful where - map_injective {_ _} _ _ h := Hom.ext h + map_injective {_ _} _ _ h := Hom.ext' h /-- The forgetful functor from `LocallyRingedSpace` to `Top`. -/ @[simps!] @@ -135,22 +151,25 @@ def forgetToTop : LocallyRingedSpace.{u} ⥤ TopCat.{u} := forgetToSheafedSpace ⋙ SheafedSpace.forget _ @[simp] -theorem comp_val {X Y Z : LocallyRingedSpace.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) : - (f ≫ g).val = f.val ≫ g.val := +theorem comp_toShHom {X Y Z : LocallyRingedSpace.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) : + (f ≫ g).toShHom = f.toShHom ≫ g.toShHom := rfl -@[simp] theorem id_val' (X : LocallyRingedSpace.{u}) : Hom.val (𝟙 X) = 𝟙 X.toSheafedSpace := +/-- A variant of `id_toShHom'` that works with `𝟙 X` instead of `id X`. -/ +@[simp] theorem id_toShHom' (X : LocallyRingedSpace.{u}) : + Hom.toShHom (𝟙 X) = 𝟙 X.toSheafedSpace := rfl --- Porting note: complains that `(f ≫ g).val.c` can be further simplified --- so changed to its simp normal form `(f.val ≫ g.val).c` -@[simp] -theorem comp_val_c {X Y Z : LocallyRingedSpace.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) : - (f.1 ≫ g.1).c = g.val.c ≫ (Presheaf.pushforward _ g.val.base).map f.val.c := +theorem comp_base {X Y Z : LocallyRingedSpace.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) : + (f ≫ g).base = f.base ≫ g.base := + rfl + +theorem comp_c {X Y Z : LocallyRingedSpace.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) : + (f ≫ g).c = g.c ≫ (Presheaf.pushforward _ g.base).map f.c := rfl -theorem comp_val_c_app {X Y Z : LocallyRingedSpace.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) (U : (Opens Z)ᵒᵖ) : - (f ≫ g).val.c.app U = g.val.c.app U ≫ f.val.c.app (op <| (Opens.map g.val.base).obj U.unop) := +theorem comp_c_app {X Y Z : LocallyRingedSpace.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) (U : (Opens Z)ᵒᵖ) : + (f ≫ g).c.app U = g.c.app U ≫ f.c.app (op <| (Opens.map g.base).obj U.unop) := rfl /-- Given two locally ringed spaces `X` and `Y`, an isomorphism between `X` and `Y` as _sheafed_ @@ -158,7 +177,7 @@ spaces can be lifted to a morphism `X ⟶ Y` as locally ringed spaces. See also `isoOfSheafedSpaceIso`. -/ -@[simps] +@[simps! toShHom] def homOfSheafedSpaceHomOfIsIso {X Y : LocallyRingedSpace.{u}} (f : X.toSheafedSpace ⟶ Y.toSheafedSpace) [IsIso f] : X ⟶ Y := Hom.mk f fun x => @@ -179,15 +198,16 @@ def isoOfSheafedSpaceIso {X Y : LocallyRingedSpace.{u}} (f : X.toSheafedSpace X ≅ Y where hom := homOfSheafedSpaceHomOfIsIso f.hom inv := homOfSheafedSpaceHomOfIsIso f.inv - hom_inv_id := Hom.ext f.hom_inv_id - inv_hom_id := Hom.ext f.inv_hom_id + hom_inv_id := Hom.ext' f.hom_inv_id + inv_hom_id := Hom.ext' f.inv_hom_id instance : forgetToSheafedSpace.ReflectsIsomorphisms where reflects {_ _} f i := { out := ⟨homOfSheafedSpaceHomOfIsIso (CategoryTheory.inv (forgetToSheafedSpace.map f)), - Hom.ext (IsIso.hom_inv_id (I := i)), Hom.ext (IsIso.inv_hom_id (I := i))⟩ } + Hom.ext' (IsIso.hom_inv_id (I := i)), Hom.ext' (IsIso.inv_hom_id (I := i))⟩ } -instance is_sheafedSpace_iso {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) [IsIso f] : IsIso f.1 := +instance is_sheafedSpace_iso {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) [IsIso f] : + IsIso f.toShHom := LocallyRingedSpace.forgetToSheafedSpace.map_isIso f /-- The restriction of a locally ringed space along an open embedding. @@ -229,10 +249,10 @@ theorem Γ_obj_op (X : LocallyRingedSpace.{u}) : Γ.obj (op X) = X.presheaf.obj rfl @[simp] -theorem Γ_map {X Y : LocallyRingedSpace.{u}ᵒᵖ} (f : X ⟶ Y) : Γ.map f = f.unop.1.c.app (op ⊤) := +theorem Γ_map {X Y : LocallyRingedSpace.{u}ᵒᵖ} (f : X ⟶ Y) : Γ.map f = f.unop.c.app (op ⊤) := rfl -theorem Γ_map_op {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) : Γ.map f.op = f.1.c.app (op ⊤) := +theorem Γ_map_op {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) : Γ.map f.op = f.c.app (op ⊤) := rfl /-- The empty locally ringed space. -/ @@ -289,27 +309,27 @@ instance component_nontrivial (X : LocallyRingedSpace.{u}) (U : Opens X.carrier) (X.presheaf.germ _ _ hU.some.2).domain_nontrivial @[simp] -lemma iso_hom_val_base_inv_val_base {X Y : LocallyRingedSpace.{u}} (e : X ≅ Y) : - e.hom.val.base ≫ e.inv.val.base = 𝟙 _ := by - rw [← SheafedSpace.comp_base, ← LocallyRingedSpace.comp_val] +lemma iso_hom_base_inv_base {X Y : LocallyRingedSpace.{u}} (e : X ≅ Y) : + e.hom.base ≫ e.inv.base = 𝟙 _ := by + rw [← SheafedSpace.comp_base, ← LocallyRingedSpace.comp_toShHom] simp @[simp] -lemma iso_hom_val_base_inv_val_base_apply {X Y : LocallyRingedSpace.{u}} (e : X ≅ Y) (x : X) : - (e.inv.val.base (e.hom.val.base x)) = x := by - show (e.hom.val.base ≫ e.inv.val.base) x = 𝟙 X.toPresheafedSpace x +lemma iso_hom_base_inv_base_apply {X Y : LocallyRingedSpace.{u}} (e : X ≅ Y) (x : X) : + (e.inv.base (e.hom.base x)) = x := by + show (e.hom.base ≫ e.inv.base) x = 𝟙 X.toPresheafedSpace x simp @[simp] -lemma iso_inv_val_base_hom_val_base {X Y : LocallyRingedSpace.{u}} (e : X ≅ Y) : - e.inv.val.base ≫ e.hom.val.base = 𝟙 _ := by - rw [← SheafedSpace.comp_base, ← LocallyRingedSpace.comp_val] +lemma iso_inv_base_hom_base {X Y : LocallyRingedSpace.{u}} (e : X ≅ Y) : + e.inv.base ≫ e.hom.base = 𝟙 _ := by + rw [← SheafedSpace.comp_base, ← LocallyRingedSpace.comp_toShHom] simp @[simp] -lemma iso_inv_val_base_hom_val_base_apply {X Y : LocallyRingedSpace.{u}} (e : X ≅ Y) (y : Y) : - (e.hom.val.base (e.inv.val.base y)) = y := by - show (e.inv.val.base ≫ e.hom.val.base) y = 𝟙 Y.toPresheafedSpace y +lemma iso_inv_base_hom_base_apply {X Y : LocallyRingedSpace.{u}} (e : X ≅ Y) (y : Y) : + (e.hom.base (e.inv.base y)) = y := by + show (e.inv.base ≫ e.hom.base) y = 𝟙 Y.toPresheafedSpace y simp section Stalks @@ -322,17 +342,17 @@ lemma stalkMap_id (X : LocallyRingedSpace.{u}) (x : X) : PresheafedSpace.stalkMap.id _ x lemma stalkMap_comp (x : X) : - (f ≫ g : X ⟶ Z).stalkMap x = g.stalkMap (f.val.base x) ≫ f.stalkMap x := - PresheafedSpace.stalkMap.comp f.val g.val x + (f ≫ g : X ⟶ Z).stalkMap x = g.stalkMap (f.base x) ≫ f.stalkMap x := + PresheafedSpace.stalkMap.comp f.toShHom g.toShHom x @[reassoc] lemma stalkSpecializes_stalkMap (x x' : X) (h : x ⤳ x') : - Y.presheaf.stalkSpecializes (f.val.base.map_specializes h) ≫ f.stalkMap x = + Y.presheaf.stalkSpecializes (f.base.map_specializes h) ≫ f.stalkMap x = f.stalkMap x' ≫ X.presheaf.stalkSpecializes h := - PresheafedSpace.stalkMap.stalkSpecializes_stalkMap f.val h + PresheafedSpace.stalkMap.stalkSpecializes_stalkMap f.toShHom h lemma stalkSpecializes_stalkMap_apply (x x' : X) (h : x ⤳ x') (y) : - f.stalkMap x (Y.presheaf.stalkSpecializes (f.val.base.map_specializes h) y) = + f.stalkMap x (Y.presheaf.stalkSpecializes (f.base.map_specializes h) y) = (X.presheaf.stalkSpecializes h (f.stalkMap x' y)) := DFunLike.congr_fun (stalkSpecializes_stalkMap f x x' h) y @@ -360,57 +380,57 @@ lemma stalkMap_congr_point {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) (x x' : @[reassoc (attr := simp)] lemma stalkMap_hom_inv (e : X ≅ Y) (y : Y) : - e.hom.stalkMap (e.inv.val.base y) ≫ e.inv.stalkMap y = + e.hom.stalkMap (e.inv.base y) ≫ e.inv.stalkMap y = Y.presheaf.stalkSpecializes (specializes_of_eq <| by simp) := by rw [← stalkMap_comp, LocallyRingedSpace.stalkMap_congr_hom (e.inv ≫ e.hom) (𝟙 _) (by simp)] simp @[simp] lemma stalkMap_hom_inv_apply (e : X ≅ Y) (y : Y) (z) : - e.inv.stalkMap y (e.hom.stalkMap (e.inv.val.base 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 (stalkMap_hom_inv e y) z @[reassoc (attr := simp)] lemma stalkMap_inv_hom (e : X ≅ Y) (x : X) : - e.inv.stalkMap (e.hom.val.base x) ≫ e.hom.stalkMap x = + e.inv.stalkMap (e.hom.base x) ≫ e.hom.stalkMap x = X.presheaf.stalkSpecializes (specializes_of_eq <| by simp) := by rw [← stalkMap_comp, LocallyRingedSpace.stalkMap_congr_hom (e.hom ≫ e.inv) (𝟙 _) (by simp)] simp @[simp] lemma stalkMap_inv_hom_apply (e : X ≅ Y) (x : X) (y) : - e.hom.stalkMap x (e.inv.stalkMap (e.hom.val.base x) y) = + e.hom.stalkMap x (e.inv.stalkMap (e.hom.base x) y) = X.presheaf.stalkSpecializes (specializes_of_eq <| by simp) y := DFunLike.congr_fun (stalkMap_inv_hom e x) y @[reassoc (attr := simp)] -lemma stalkMap_germ (U : Opens Y) (x : X) (hx : f.val.base x ∈ U) : - Y.presheaf.germ U (f.val.base x) hx ≫ f.stalkMap x = - f.val.c.app (op U) ≫ X.presheaf.germ ((Opens.map f.1.base).obj U) x hx := - PresheafedSpace.stalkMap_germ f.val U x hx +lemma stalkMap_germ (U : Opens Y) (x : X) (hx : f.base x ∈ U) : + Y.presheaf.germ U (f.base x) hx ≫ f.stalkMap x = + f.c.app (op U) ≫ X.presheaf.germ ((Opens.map f.base).obj U) x hx := + PresheafedSpace.stalkMap_germ f.toShHom U x hx -lemma stalkMap_germ_apply (U : Opens Y) (x : X) (hx : f.val.base x ∈ U) (y) : - f.stalkMap x (Y.presheaf.germ U (f.val.base x) hx y) = - X.presheaf.germ ((Opens.map f.1.base).obj U) x hx (f.val.c.app (op U) y) := - PresheafedSpace.stalkMap_germ_apply f.val U x hx y +lemma stalkMap_germ_apply (U : Opens Y) (x : X) (hx : f.base x ∈ U) (y) : + f.stalkMap x (Y.presheaf.germ U (f.base x) hx y) = + X.presheaf.germ ((Opens.map f.base).obj U) x hx (f.c.app (op U) y) := + PresheafedSpace.stalkMap_germ_apply f.toShHom U x hx y theorem preimage_basicOpen {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) {U : Opens Y} (s : Y.presheaf.obj (op U)) : - (Opens.map f.1.base).obj (Y.toRingedSpace.basicOpen s) = - @RingedSpace.basicOpen X.toRingedSpace ((Opens.map f.1.base).obj U) (f.1.c.app _ s) := by + (Opens.map f.base).obj (Y.toRingedSpace.basicOpen s) = + @RingedSpace.basicOpen X.toRingedSpace ((Opens.map f.base).obj U) (f.c.app _ s) := by ext x constructor · rintro ⟨hxU, hx⟩ rw [SetLike.mem_coe, X.toRingedSpace.mem_basicOpen _ _ hxU] delta toRingedSpace rw [← stalkMap_germ_apply] - exact (f.val.stalkMap _).isUnit_map hx + exact (f.stalkMap _).isUnit_map hx · rintro ⟨hxU, hx⟩ simp only [Opens.map_coe, Set.mem_preimage, SetLike.mem_coe, toRingedSpace] at hx ⊢ - rw [RingedSpace.mem_basicOpen _ s (f.1.base x) hxU] + rw [RingedSpace.mem_basicOpen _ s (f.base x) hxU] rw [← stalkMap_germ_apply] at hx - exact (isUnit_map_iff (f.val.stalkMap _) _).mp hx + exact (isUnit_map_iff (f.toShHom.stalkMap _) _).mp hx variable {U : TopCat} (X : LocallyRingedSpace.{u}) {f : U ⟶ X.toTopCat} (h : OpenEmbedding f) (V : Opens U) (x : U) (hx : x ∈ V) diff --git a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean index fac6ae0294b93b..a45f070a1bf4f5 100644 --- a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean +++ b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean @@ -106,12 +106,12 @@ noncomputable def coproductCofanIsColimit : IsColimit (coproductCofan F) where (((forgetToSheafedSpace.mapCocone s).ι.app i).stalkMap y) := (s.ι.app i).2 y infer_instance⟩ - fac _ _ := LocallyRingedSpace.Hom.ext + fac _ _ := LocallyRingedSpace.Hom.ext' (colimit.ι_desc (C := SheafedSpace.{u+1, u, u} CommRingCatMax.{u, u}) _ _) uniq s f h := - LocallyRingedSpace.Hom.ext - (IsColimit.uniq _ (forgetToSheafedSpace.mapCocone s) f.1 fun j => - congr_arg LocallyRingedSpace.Hom.val (h j)) + LocallyRingedSpace.Hom.ext' + (IsColimit.uniq _ (forgetToSheafedSpace.mapCocone s) f.toShHom fun j => + congr_arg LocallyRingedSpace.Hom.toShHom (h j)) instance : HasCoproducts.{u} LocallyRingedSpace.{u} := fun _ => ⟨fun F => ⟨⟨⟨_, coproductCofanIsColimit F⟩⟩⟩⟩ @@ -132,14 +132,15 @@ variable {X Y : LocallyRingedSpace.{v}} (f g : X ⟶ Y) namespace HasCoequalizer instance coequalizer_π_app_isLocalRingHom - (U : TopologicalSpace.Opens (coequalizer f.val g.val).carrier) : - IsLocalRingHom ((coequalizer.π f.val g.val : _).c.app (op U)) := by - have := ι_comp_coequalizerComparison f.1 g.1 SheafedSpace.forgetToPresheafedSpace + (U : TopologicalSpace.Opens (coequalizer f.toShHom g.toShHom).carrier) : + IsLocalRingHom ((coequalizer.π f.toShHom g.toShHom : _).c.app (op U)) := by + have := ι_comp_coequalizerComparison f.toShHom g.toShHom SheafedSpace.forgetToPresheafedSpace rw [← PreservesCoequalizer.iso_hom] at this erw [SheafedSpace.congr_app this.symm (op U)] rw [PresheafedSpace.comp_c_app, ← PresheafedSpace.colimitPresheafObjIsoComponentwiseLimit_hom_π] -- Porting note (#10754): this instance has to be manually added - haveI : IsIso (PreservesCoequalizer.iso SheafedSpace.forgetToPresheafedSpace f.val g.val).hom.c := + haveI : IsIso (PreservesCoequalizer.iso + SheafedSpace.forgetToPresheafedSpace f.toShHom g.toShHom).hom.c := PresheafedSpace.c_isIso_of_iso _ infer_instance @@ -162,46 +163,46 @@ are local ring homs. -/ -variable (U : Opens (coequalizer f.1 g.1).carrier) -variable (s : (coequalizer f.1 g.1).presheaf.obj (op U)) +variable (U : Opens (coequalizer f.toShHom g.toShHom).carrier) +variable (s : (coequalizer f.toShHom g.toShHom).presheaf.obj (op U)) /-- (Implementation). The basic open set of the section `π꙳ s`. -/ noncomputable def imageBasicOpen : Opens Y := Y.toRingedSpace.basicOpen - (show Y.presheaf.obj (op (unop _)) from ((coequalizer.π f.1 g.1).c.app (op U)) s) + (show Y.presheaf.obj (op (unop _)) from ((coequalizer.π f.toShHom g.toShHom).c.app (op U)) s) theorem imageBasicOpen_image_preimage : - (coequalizer.π f.1 g.1).base ⁻¹' ((coequalizer.π f.1 g.1).base '' (imageBasicOpen f g U s).1) = - (imageBasicOpen f g U s).1 := by - fapply Types.coequalizer_preimage_image_eq_of_preimage_eq - -- Porting note: Type of `f.1.base` and `g.1.base` needs to be explicit - (f.1.base : X.carrier.1 ⟶ Y.carrier.1) (g.1.base : X.carrier.1 ⟶ Y.carrier.1) + (coequalizer.π f.toShHom g.toShHom).base ⁻¹' ((coequalizer.π f.toShHom g.toShHom).base '' + (imageBasicOpen f g U s).1) = (imageBasicOpen f g U s).1 := by + fapply Types.coequalizer_preimage_image_eq_of_preimage_eq f.base + -- Porting note: Type of `f.base` and `g.base` needs to be explicit + (g.base : X.carrier.1 ⟶ Y.carrier.1) · ext simp_rw [types_comp_apply, ← TopCat.comp_app, ← PresheafedSpace.comp_base] congr 2 - exact coequalizer.condition f.1 g.1 + exact coequalizer.condition f.toShHom g.toShHom · apply isColimitCoforkMapOfIsColimit (forget TopCat) apply isColimitCoforkMapOfIsColimit (SheafedSpace.forget _) - exact coequalizerIsCoequalizer f.1 g.1 + exact coequalizerIsCoequalizer f.toShHom g.toShHom · suffices - (TopologicalSpace.Opens.map f.1.base).obj (imageBasicOpen f g U s) = - (TopologicalSpace.Opens.map g.1.base).obj (imageBasicOpen f g U s) + (TopologicalSpace.Opens.map f.base).obj (imageBasicOpen f g U s) = + (TopologicalSpace.Opens.map g.base).obj (imageBasicOpen f g U s) by injection this delta imageBasicOpen rw [preimage_basicOpen f, preimage_basicOpen g] dsimp only [Functor.op, unop_op] -- Porting note (#11224): change `rw` to `erw` erw [← comp_apply, ← SheafedSpace.comp_c_app', ← comp_apply, ← SheafedSpace.comp_c_app', - SheafedSpace.congr_app (coequalizer.condition f.1 g.1), comp_apply, + SheafedSpace.congr_app (coequalizer.condition f.toShHom g.toShHom), comp_apply, X.toRingedSpace.basicOpen_res] apply inf_eq_right.mpr refine (RingedSpace.basicOpen_le _ _).trans ?_ - rw [coequalizer.condition f.1 g.1] + rw [coequalizer.condition f.toShHom g.toShHom] theorem imageBasicOpen_image_open : - IsOpen ((coequalizer.π f.1 g.1).base '' (imageBasicOpen f g U s).1) := by - rw [← (TopCat.homeoOfIso (PreservesCoequalizer.iso (SheafedSpace.forget _) f.1 - g.1)).isOpen_preimage, TopCat.coequalizer_isOpen_iff, ← Set.preimage_comp] + IsOpen ((coequalizer.π f.toShHom g.toShHom).base '' (imageBasicOpen f g U s).1) := by + rw [← (TopCat.homeoOfIso (PreservesCoequalizer.iso (SheafedSpace.forget _) f.toShHom + g.toShHom)).isOpen_preimage, TopCat.coequalizer_isOpen_iff, ← Set.preimage_comp] erw [← TopCat.coe_comp] rw [PreservesCoequalizer.iso_hom, ι_comp_coequalizerComparison] dsimp only [SheafedSpace.forget] @@ -210,52 +211,54 @@ theorem imageBasicOpen_image_open : exact (imageBasicOpen f g U s).2 instance coequalizer_π_stalk_isLocalRingHom (x : Y) : - IsLocalRingHom ((coequalizer.π f.val g.val : _).stalkMap x) := by + IsLocalRingHom ((coequalizer.π f.toShHom g.toShHom : _).stalkMap x) := by constructor rintro a ha rcases TopCat.Presheaf.germ_exist _ _ a with ⟨U, hU, s, rfl⟩ - rw [PresheafedSpace.stalkMap_germ_apply (coequalizer.π f.1 g.1 : _) U _ hU] at ha + rw [PresheafedSpace.stalkMap_germ_apply + (coequalizer.π (C := SheafedSpace _) f.toShHom g.toShHom) U _ hU] at ha let V := imageBasicOpen f g U s - have hV : (coequalizer.π f.1 g.1).base ⁻¹' ((coequalizer.π f.1 g.1).base '' V.1) = V.1 := + have hV : (coequalizer.π f.toShHom g.toShHom).base ⁻¹' + ((coequalizer.π f.toShHom g.toShHom).base '' V.1) = V.1 := imageBasicOpen_image_preimage f g U s - have hV' : - V = ⟨(coequalizer.π f.1 g.1).base ⁻¹' ((coequalizer.π f.1 g.1).base '' V.1), hV.symm ▸ V.2⟩ := + have hV' : V = ⟨(coequalizer.π f.toShHom g.toShHom).base ⁻¹' + ((coequalizer.π f.toShHom g.toShHom).base '' V.1), hV.symm ▸ V.2⟩ := SetLike.ext' hV.symm - have V_open : IsOpen ((coequalizer.π f.val g.val).base '' V.1) := + have V_open : IsOpen ((coequalizer.π f.toShHom g.toShHom).base '' V.1) := imageBasicOpen_image_open f g U s - have VleU : (⟨(coequalizer.π f.val g.val).base '' V.1, V_open⟩ : TopologicalSpace.Opens _) ≤ U := + have VleU : (⟨(coequalizer.π f.toShHom g.toShHom).base '' V.1, V_open⟩ : _) ≤ U := Set.image_subset_iff.mpr (Y.toRingedSpace.basicOpen_le _) have hxV : x ∈ V := ⟨hU, ha⟩ rw [← - (coequalizer f.val g.val).presheaf.germ_res_apply (homOfLE VleU) _ - (@Set.mem_image_of_mem _ _ (coequalizer.π f.val g.val).base x V.1 hxV) s] + (coequalizer f.toShHom g.toShHom).presheaf.germ_res_apply (homOfLE VleU) _ + (@Set.mem_image_of_mem _ _ (coequalizer.π f.toShHom g.toShHom).base x V.1 hxV) s] apply RingHom.isUnit_map - rw [← isUnit_map_iff ((coequalizer.π f.val g.val : _).c.app _), ← comp_apply, + rw [← isUnit_map_iff ((coequalizer.π f.toShHom g.toShHom : _).c.app _), ← comp_apply, NatTrans.naturality, comp_apply, ← isUnit_map_iff (Y.presheaf.map (eqToHom hV').op)] -- Porting note (#11224): change `rw` to `erw` erw [← comp_apply, ← comp_apply, ← Y.presheaf.map_comp] convert @RingedSpace.isUnit_res_basicOpen Y.toRingedSpace (unop _) - (((coequalizer.π f.val g.val).c.app (op U)) s) + (((coequalizer.π f.toShHom g.toShHom).c.app (op U)) s) end HasCoequalizer /-- The coequalizer of two locally ringed space in the category of sheafed spaces is a locally ringed space. -/ noncomputable def coequalizer : LocallyRingedSpace where - toSheafedSpace := Limits.coequalizer f.1 g.1 + toSheafedSpace := Limits.coequalizer f.toShHom g.toShHom localRing x := by obtain ⟨y, rfl⟩ := - (TopCat.epi_iff_surjective (coequalizer.π f.val g.val).base).mp inferInstance x + (TopCat.epi_iff_surjective (coequalizer.π f.toShHom g.toShHom).base).mp inferInstance x -- TODO: this instance was found automatically before #6045 - have _ : IsLocalRingHom ((coequalizer.π f.val g.val).stalkMap y) := inferInstance - exact ((coequalizer.π f.val g.val : _).stalkMap y).domain_localRing + have _ : IsLocalRingHom ((coequalizer.π f.toShHom g.toShHom).stalkMap y) := inferInstance + exact ((coequalizer.π f.toShHom g.toShHom : _).stalkMap y).domain_localRing /-- The explicit coequalizer cofork of locally ringed spaces. -/ noncomputable def coequalizerCofork : Cofork f g := - @Cofork.ofπ _ _ _ _ f g (coequalizer f g) ⟨coequalizer.π f.1 g.1, + @Cofork.ofπ _ _ _ _ f g (coequalizer f g) ⟨coequalizer.π f.toShHom g.toShHom, -- Porting note: this used to be automatic HasCoequalizer.coequalizer_π_stalk_isLocalRingHom _ _⟩ - (LocallyRingedSpace.Hom.ext (coequalizer.condition f.1 g.1)) + (LocallyRingedSpace.Hom.ext' (coequalizer.condition f.toShHom g.toShHom)) theorem isLocalRingHom_stalkMap_congr {X Y : RingedSpace} (f g : X ⟶ Y) (H : f = g) (x) (h : IsLocalRingHom (f.stalkMap x)) : @@ -266,11 +269,11 @@ theorem isLocalRingHom_stalkMap_congr {X Y : RingedSpace} (f g : X ⟶ Y) (H : f noncomputable def coequalizerCoforkIsColimit : IsColimit (coequalizerCofork f g) := by apply Cofork.IsColimit.mk' intro s - have e : f.val ≫ s.π.val = g.val ≫ s.π.val := by injection s.condition - refine ⟨⟨coequalizer.desc s.π.1 e, ?_⟩, ?_⟩ + have e : f.toShHom ≫ s.π.toShHom = g.toShHom ≫ s.π.toShHom := by injection s.condition + refine ⟨⟨coequalizer.desc s.π.toShHom e, ?_⟩, ?_⟩ · intro x - rcases (TopCat.epi_iff_surjective (coequalizer.π f.val g.val).base).mp inferInstance x with - ⟨y, rfl⟩ + rcases (TopCat.epi_iff_surjective + (coequalizer.π f.toShHom g.toShHom).base).mp inferInstance x with ⟨y, rfl⟩ -- Porting note: was `apply isLocalRingHom_of_comp _ (PresheafedSpace.stalkMap ...)`, this -- used to allow you to provide the proof that `... ≫ ...` is a local ring homomorphism later, -- but this is no longer possible @@ -281,18 +284,18 @@ noncomputable def coequalizerCoforkIsColimit : IsColimit (coequalizerCofork f g) -- note to reviewers: this `change` is now more brittle because it now has to fully resolve -- the type to be able to search for `MonoidHomClass`, even though of course all homs in -- `CommRingCat` are clearly such - change IsLocalRingHom (h ≫ (coequalizerCofork f g).π.val.stalkMap y) + change IsLocalRingHom (h ≫ (coequalizerCofork f g).π.toShHom.stalkMap y) erw [← PresheafedSpace.stalkMap.comp] - apply isLocalRingHom_stalkMap_congr _ _ (coequalizer.π_desc s.π.1 e).symm y + apply isLocalRingHom_stalkMap_congr _ _ (coequalizer.π_desc s.π.toShHom e).symm y infer_instance constructor - · exact LocallyRingedSpace.Hom.ext (coequalizer.π_desc _ _) + · exact LocallyRingedSpace.Hom.ext' (coequalizer.π_desc _ _) intro m h - replace h : (coequalizerCofork f g).π.1 ≫ m.1 = s.π.1 := by rw [← h]; rfl - apply LocallyRingedSpace.Hom.ext - apply (colimit.isColimit (parallelPair f.1 g.1)).uniq (Cofork.ofπ s.π.1 e) m.1 + replace h : (coequalizerCofork f g).π.toShHom ≫ m.1 = s.π.toShHom := by rw [← h]; rfl + apply LocallyRingedSpace.Hom.ext' + apply (colimit.isColimit (parallelPair f.toShHom g.toShHom)).uniq (Cofork.ofπ s.π.toShHom e) m.1 rintro ⟨⟩ - · rw [← (colimit.cocone (parallelPair f.val g.val)).w WalkingParallelPairHom.left, + · rw [← (colimit.cocone (parallelPair f.toShHom g.toShHom)).w WalkingParallelPairHom.left, Category.assoc] change _ ≫ _ ≫ _ = _ ≫ _ congr diff --git a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean index 44d7e9d141d920..b09ad64961538a 100644 --- a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean +++ b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean @@ -83,13 +83,13 @@ variable {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) (x : X) -- We need this strange instance for `residueFieldMap`, the type of `F` must be fixed -- like this. The instance `IsLocalRingHom (f.stalkMap x)` already exists, but does not work for -- `residueFieldMap`. -instance : IsLocalRingHom (F := Y.presheaf.stalk (f.val.base x) →+* X.presheaf.stalk x) +instance : IsLocalRingHom (F := Y.presheaf.stalk (f.base x) →+* X.presheaf.stalk x) (f.stalkMap x) := f.2 x /-- If `X ⟶ Y` is a morphism of locally ringed spaces and `x` a point of `X`, we obtain a morphism of residue fields in the other direction. -/ -def residueFieldMap (x : X) : Y.residueField (f.val.base x) ⟶ X.residueField x := +def residueFieldMap (x : X) : Y.residueField (f.base x) ⟶ X.residueField x := LocalRing.ResidueField.map (f.stalkMap x) lemma residue_comp_residueFieldMap_eq_stalkMap_comp_residue (x : X) : @@ -100,23 +100,23 @@ lemma residue_comp_residueFieldMap_eq_stalkMap_comp_residue (x : X) : @[simp] lemma residueFieldMap_id (x : X) : residueFieldMap (𝟙 X) x = 𝟙 (X.residueField x) := by - simp only [id_val', SheafedSpace.id_base, TopCat.coe_id, id_eq, residueFieldMap, stalkMap_id] + simp only [id_toShHom', SheafedSpace.id_base, TopCat.coe_id, id_eq, residueFieldMap, stalkMap_id] apply LocalRing.ResidueField.map_id @[simp] lemma residueFieldMap_comp {Z : LocallyRingedSpace.{u}} (g : Y ⟶ Z) (x : X) : - residueFieldMap (f ≫ g) x = residueFieldMap g (f.val.base x) ≫ residueFieldMap f x := by - simp only [comp_val, SheafedSpace.comp_base, Function.comp_apply, residueFieldMap] + residueFieldMap (f ≫ g) x = residueFieldMap g (f.base x) ≫ residueFieldMap f x := by + simp only [comp_toShHom, SheafedSpace.comp_base, Function.comp_apply, residueFieldMap] simp_rw [stalkMap_comp] - haveI : IsLocalRingHom (g.stalkMap (f.val.base x)) := inferInstance + haveI : IsLocalRingHom (g.stalkMap (f.base x)) := inferInstance -- TODO: This instance is found before #6045. haveI : IsLocalRingHom (f.stalkMap x) := inferInstance apply LocalRing.ResidueField.map_comp @[reassoc] -lemma evaluation_naturality {V : Opens Y} (x : (Opens.map f.1.base).obj V) : - Y.evaluation ⟨f.val.base x, x.property⟩ ≫ residueFieldMap f x.val = - f.val.c.app (op V) ≫ X.evaluation x := by +lemma evaluation_naturality {V : Opens Y} (x : (Opens.map f.base).obj V) : + Y.evaluation ⟨f.base x, x.property⟩ ≫ residueFieldMap f x.val = + f.c.app (op V) ≫ X.evaluation x := by dsimp only [LocallyRingedSpace.evaluation, LocallyRingedSpace.residueFieldMap] rw [Category.assoc] @@ -125,21 +125,21 @@ lemma evaluation_naturality {V : Opens Y} (x : (Opens.map f.1.base).obj V) : erw [LocalRing.ResidueField.map_residue, PresheafedSpace.stalkMap_germ_apply] rfl -lemma evaluation_naturality_apply {V : Opens Y} (x : (Opens.map f.1.base).obj V) +lemma evaluation_naturality_apply {V : Opens Y} (x : (Opens.map f.base).obj V) (a : Y.presheaf.obj (op V)) : - residueFieldMap f x.val (Y.evaluation ⟨f.val.base x, x.property⟩ a) = - X.evaluation x (f.val.c.app (op V) a) := by + residueFieldMap f x.val (Y.evaluation ⟨f.base x, x.property⟩ a) = + X.evaluation x (f.c.app (op V) a) := by simpa using congrFun (congrArg DFunLike.coe <| evaluation_naturality f x) a @[reassoc] lemma Γevaluation_naturality (x : X) : - Y.Γevaluation (f.val.base x) ≫ residueFieldMap f x = - f.val.c.app (op ⊤) ≫ X.Γevaluation x := + Y.Γevaluation (f.base x) ≫ residueFieldMap f x = + f.c.app (op ⊤) ≫ X.Γevaluation x := evaluation_naturality f ⟨x, by simp only [Opens.map_top]; trivial⟩ lemma Γevaluation_naturality_apply (x : X) (a : Y.presheaf.obj (op ⊤)) : - residueFieldMap f x (Y.Γevaluation (f.val.base x) a) = - X.Γevaluation x (f.val.c.app (op ⊤) a) := + residueFieldMap f x (Y.Γevaluation (f.base x) a) = + X.Γevaluation x (f.c.app (op ⊤) a) := evaluation_naturality_apply f ⟨x, by simp only [Opens.map_top]; trivial⟩ a end LocallyRingedSpace diff --git a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean index a5571115fc47de..0f4f4ce207163c 100644 --- a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean +++ b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean @@ -577,7 +577,7 @@ def toLocallyRingedSpaceHom : toLocallyRingedSpace Y f ⟶ Y := ⟨f, fun _ => inferInstance⟩ @[simp] -theorem toLocallyRingedSpaceHom_val : (toLocallyRingedSpaceHom Y f).val = f := +theorem toLocallyRingedSpaceHom_val : (toLocallyRingedSpaceHom Y f).toShHom = f := rfl instance toLocallyRingedSpace_isOpenImmersion : @@ -933,15 +933,15 @@ variable [H : LocallyRingedSpace.IsOpenImmersion f] instance (priority := 100) of_isIso [IsIso g] : LocallyRingedSpace.IsOpenImmersion g := @PresheafedSpace.IsOpenImmersion.ofIsIso _ _ _ _ g.1 ⟨⟨(inv g).1, by - erw [← LocallyRingedSpace.comp_val]; rw [IsIso.hom_inv_id] - erw [← LocallyRingedSpace.comp_val]; rw [IsIso.inv_hom_id]; constructor <;> rfl⟩⟩ + erw [← LocallyRingedSpace.comp_toShHom]; rw [IsIso.hom_inv_id] + erw [← LocallyRingedSpace.comp_toShHom]; rw [IsIso.inv_hom_id]; constructor <;> rfl⟩⟩ instance comp (g : Z ⟶ Y) [LocallyRingedSpace.IsOpenImmersion g] : LocallyRingedSpace.IsOpenImmersion (f ≫ g) := PresheafedSpace.IsOpenImmersion.comp f.1 g.1 instance mono : Mono f := - LocallyRingedSpace.forgetToSheafedSpace.mono_of_mono_map (show Mono f.1 by infer_instance) + LocallyRingedSpace.forgetToSheafedSpace.mono_of_mono_map (show Mono f.toShHom by infer_instance) instance : SheafedSpace.IsOpenImmersion (LocallyRingedSpace.forgetToSheafedSpace.map f) := H @@ -951,7 +951,7 @@ set_option synthInstance.maxHeartbeats 30000 in /-- An explicit pullback cone over `cospan f g` if `f` is an open immersion. -/ def pullbackConeOfLeft : PullbackCone f g := by refine PullbackCone.mk ?_ - (Y.ofRestrict (TopCat.snd_openEmbedding_of_left_openEmbedding H.base_open g.1.base)) ?_ + (Y.ofRestrict (TopCat.snd_openEmbedding_of_left_openEmbedding H.base_open g.base)) ?_ · use PresheafedSpace.IsOpenImmersion.pullbackConeOfLeftFst f.1 g.1 intro x have := PresheafedSpace.stalkMap.congr_hom _ _ @@ -960,7 +960,7 @@ def pullbackConeOfLeft : PullbackCone f g := by rw [← IsIso.eq_inv_comp] at this rw [this] infer_instance - · exact LocallyRingedSpace.Hom.ext + · exact LocallyRingedSpace.Hom.ext' (PresheafedSpace.IsOpenImmersion.pullback_cone_of_left_condition _ _) instance : LocallyRingedSpace.IsOpenImmersion (pullbackConeOfLeft f g).snd := @@ -971,16 +971,17 @@ set_option synthInstance.maxHeartbeats 80000 in def pullbackConeOfLeftIsLimit : IsLimit (pullbackConeOfLeft f g) := PullbackCone.isLimitAux' _ fun s => by refine ⟨LocallyRingedSpace.Hom.mk (PresheafedSpace.IsOpenImmersion.pullbackConeOfLeftLift - f.1 g.1 (PullbackCone.mk _ _ (congr_arg LocallyRingedSpace.Hom.val s.condition))) ?_, - LocallyRingedSpace.Hom.ext + f.1 g.1 (PullbackCone.mk _ _ (congr_arg LocallyRingedSpace.Hom.toShHom s.condition))) ?_, + LocallyRingedSpace.Hom.ext' (PresheafedSpace.IsOpenImmersion.pullbackConeOfLeftLift_fst f.1 g.1 _), - LocallyRingedSpace.Hom.ext + LocallyRingedSpace.Hom.ext' (PresheafedSpace.IsOpenImmersion.pullbackConeOfLeftLift_snd f.1 g.1 _), ?_⟩ · intro x have := PresheafedSpace.stalkMap.congr_hom _ _ (PresheafedSpace.IsOpenImmersion.pullbackConeOfLeftLift_snd f.1 g.1 - (PullbackCone.mk s.fst.1 s.snd.1 (congr_arg LocallyRingedSpace.Hom.val s.condition))) + (PullbackCone.mk s.fst.1 s.snd.1 + (congr_arg LocallyRingedSpace.Hom.toShHom s.condition))) x change _ = _ ≫ s.snd.1.stalkMap x at this rw [PresheafedSpace.stalkMap.comp, ← IsIso.eq_inv_comp] at this @@ -989,9 +990,10 @@ def pullbackConeOfLeftIsLimit : IsLimit (pullbackConeOfLeft f g) := apply CommRingCat.isLocalRingHom_comp · intro m _ h₂ rw [← cancel_mono (pullbackConeOfLeft f g).snd] - exact h₂.trans <| LocallyRingedSpace.Hom.ext + exact h₂.trans <| LocallyRingedSpace.Hom.ext' (PresheafedSpace.IsOpenImmersion.pullbackConeOfLeftLift_snd f.1 g.1 <| - PullbackCone.mk s.fst.1 s.snd.1 <| congr_arg LocallyRingedSpace.Hom.val s.condition).symm + PullbackCone.mk s.fst.1 s.snd.1 <| congr_arg + LocallyRingedSpace.Hom.toShHom s.condition).symm instance hasPullback_of_left : HasPullback f g := ⟨⟨⟨_, pullbackConeOfLeftIsLimit f g⟩⟩⟩ @@ -1082,7 +1084,7 @@ instance forgetToPresheafedSpaceReflectsPullbackOfRight : (LocallyRingedSpace.forgetToSheafedSpace ⋙ SheafedSpace.forgetToPresheafedSpace) := reflectsLimitOfReflectsIsomorphisms _ _ -theorem pullback_snd_isIso_of_range_subset (H' : Set.range g.1.base ⊆ Set.range f.1.base) : +theorem pullback_snd_isIso_of_range_subset (H' : Set.range g.base ⊆ Set.range f.base) : IsIso (pullback.snd f g) := by apply (config := {allowSynthFailures := true}) Functor.ReflectsIsomorphisms.reflects (F := LocallyRingedSpace.forgetToSheafedSpace) @@ -1099,35 +1101,35 @@ For an open immersion `f : X ⟶ Z`, given any morphism of schemes `g : Y ⟶ Z` image is contained in the image of `f`, we can lift this morphism to a unique `Y ⟶ X` that commutes with these maps. -/ -def lift (H' : Set.range g.1.base ⊆ Set.range f.1.base) : Y ⟶ X := +def lift (H' : Set.range g.base ⊆ Set.range f.base) : Y ⟶ X := -- Porting note (#10754): added instance manually have := pullback_snd_isIso_of_range_subset f g H' inv (pullback.snd f g) ≫ pullback.fst _ _ @[simp, reassoc] -theorem lift_fac (H' : Set.range g.1.base ⊆ Set.range f.1.base) : lift f g H' ≫ f = g := by +theorem lift_fac (H' : Set.range g.base ⊆ Set.range f.base) : lift f g H' ≫ f = g := by erw [Category.assoc]; rw [IsIso.inv_comp_eq]; exact pullback.condition -theorem lift_uniq (H' : Set.range g.1.base ⊆ Set.range f.1.base) (l : Y ⟶ X) (hl : l ≫ f = g) : +theorem lift_uniq (H' : Set.range g.base ⊆ Set.range f.base) (l : Y ⟶ X) (hl : l ≫ f = g) : l = lift f g H' := by rw [← cancel_mono f, hl, lift_fac] -theorem lift_range (H' : Set.range g.1.base ⊆ Set.range f.1.base) : - Set.range (lift f g H').1.base = f.1.base ⁻¹' Set.range g.1.base := by +theorem lift_range (H' : Set.range g.base ⊆ Set.range f.base) : + Set.range (lift f g H').base = f.base ⁻¹' Set.range g.base := by -- Porting note (#10754): added instance manually have := pullback_snd_isIso_of_range_subset f g H' dsimp only [lift] - have : _ = (pullback.fst f g).val.base := + have : _ = (pullback.fst f g).base := PreservesPullback.iso_hom_fst (LocallyRingedSpace.forgetToSheafedSpace ⋙ SheafedSpace.forget _) f g - rw [LocallyRingedSpace.comp_val, SheafedSpace.comp_base, ← this, ← Category.assoc, coe_comp, - Set.range_comp, Set.range_iff_surjective.mpr, Set.image_univ] + rw [LocallyRingedSpace.comp_base, ← this, ← Category.assoc, coe_comp] + rw [Set.range_comp, Set.range_iff_surjective.mpr, Set.image_univ] -- Porting note (#11224): change `rw` to `erw` on this lemma · erw [TopCat.pullback_fst_range] ext constructor · rintro ⟨y, eq⟩; exact ⟨y, eq.symm⟩ · rintro ⟨y, eq⟩; exact ⟨y, eq.symm⟩ - · rw [← TopCat.epi_iff_surjective, show (inv (pullback.snd f g)).val.base = _ from + · rw [← TopCat.epi_iff_surjective, show (inv (pullback.snd f g)).base = _ from (LocallyRingedSpace.forgetToSheafedSpace ⋙ SheafedSpace.forget _).map_inv _] infer_instance @@ -1153,7 +1155,7 @@ whose forgetful functor reflects isomorphisms, preserves limits and filtered col Then a morphism `X ⟶ Y` that is a topological open embedding is an open immersion iff every stalk map is an iso. -/ -theorem of_stalk_iso {X Y : LocallyRingedSpace} (f : X ⟶ Y) (hf : OpenEmbedding f.1.base) +theorem of_stalk_iso {X Y : LocallyRingedSpace} (f : X ⟶ Y) (hf : OpenEmbedding f.base) [stalk_iso : ∀ x : X.1, IsIso (f.stalkMap x)] : LocallyRingedSpace.IsOpenImmersion f := SheafedSpace.IsOpenImmersion.of_stalk_iso _ hf (H := stalk_iso) @@ -1190,13 +1192,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.1.c.app (op (opensFunctor f |>.obj U)) ≫ + f.c.app (op (opensFunctor f |>.obj U)) ≫ X.presheaf.map (eqToHom (by simp [Opens.map, Set.preimage_image_eq _ H.base_open.inj])) := PresheafedSpace.IsOpenImmersion.inv_invApp f.1 U @[reassoc (attr := simp)] theorem invApp_app (U : Opens X) : - H.invApp _ U ≫ f.1.c.app (op (opensFunctor f |>.obj U)) = + 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.inj])) := PresheafedSpace.IsOpenImmersion.invApp_app f.1 U @@ -1204,20 +1206,20 @@ attribute [elementwise] invApp_app @[reassoc (attr := simp)] theorem app_invApp (U : Opens Y) : - f.1.c.app (op U) ≫ H.invApp _ ((Opens.map f.1.base).obj U) = + f.c.app (op U) ≫ H.invApp _ ((Opens.map f.base).obj U) = Y.presheaf.map - ((homOfLE (Set.image_preimage_subset f.1.base U.1)).op : - op U ⟶ op (opensFunctor f |>.obj ((Opens.map f.1.base).obj U))) := + ((homOfLE (Set.image_preimage_subset f.base U.1)).op : + op U ⟶ op (opensFunctor f |>.obj ((Opens.map f.base).obj U))) := PresheafedSpace.IsOpenImmersion.app_invApp f.1 U /-- A variant of `app_inv_app` that gives an `eqToHom` instead of `homOfLe`. -/ @[reassoc] -theorem app_inv_app' (U : Opens Y) (hU : (U : Set Y) ⊆ Set.range f.1.base) : - f.1.c.app (op U) ≫ H.invApp _ ((Opens.map f.1.base).obj U) = +theorem app_inv_app' (U : Opens Y) (hU : (U : Set Y) ⊆ Set.range f.base) : + f.c.app (op U) ≫ H.invApp _ ((Opens.map f.base).obj U) = Y.presheaf.map (eqToHom <| - le_antisymm (Set.image_preimage_subset f.1.base U.1) <| - (Set.image_preimage_eq_inter_range (f := f.1.base) (t := U.1)).symm ▸ + le_antisymm (Set.image_preimage_subset f.base U.1) <| + (Set.image_preimage_eq_inter_range (f := f.base) (t := U.1)).symm ▸ Set.subset_inter_iff.mpr ⟨fun _ h => h, hU⟩).op := PresheafedSpace.IsOpenImmersion.app_invApp f.1 U @@ -1234,7 +1236,7 @@ theorem ofRestrict_invApp (X : LocallyRingedSpace) {Y : TopCat} instance stalk_iso (x : X) : IsIso (f.stalkMap x) := PresheafedSpace.IsOpenImmersion.stalk_iso f.1 x -theorem to_iso [h' : Epi f.1.base] : IsIso f := by +theorem to_iso [h' : Epi f.base] : IsIso f := by suffices IsIso (LocallyRingedSpace.forgetToSheafedSpace.map f) from isIso_of_reflects_iso _ LocallyRingedSpace.forgetToSheafedSpace exact SheafedSpace.IsOpenImmersion.to_iso f.1 diff --git a/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean b/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean index 43d40b52b040ca..f4762b2bced5c9 100644 --- a/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean +++ b/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean @@ -157,6 +157,9 @@ instance categoryOfPresheafedSpaces : Category (PresheafedSpace C) where variable {C} +/-- Cast `Hom X Y` as an arrow `X ⟶ Y` of presheaves. -/ +abbrev Hom.toPshHom {X Y : PresheafedSpace C} (f : Hom X Y) : X ⟶ Y := f + -- Porting note (#5229): adding an `ext` lemma. @[ext (iff := false)] theorem ext {X Y : PresheafedSpace C} (α β : X ⟶ Y) (w : α.base = β.base) diff --git a/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean b/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean index 19b9450951092e..bcfd0917ee8440 100644 --- a/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean +++ b/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean @@ -660,7 +660,7 @@ instance ι_isOpenImmersion (i : D.J) : IsOpenImmersion (𝖣.ι i) := by instance (i j k : D.J) : PreservesLimit (cospan (𝖣.f i j) (𝖣.f i k)) forgetToSheafedSpace := inferInstance -theorem ι_jointly_surjective (x : 𝖣.glued) : ∃ (i : D.J) (y : D.U i), (𝖣.ι i).1.base y = x := +theorem ι_jointly_surjective (x : 𝖣.glued) : ∃ (i : D.J) (y : D.U i), (𝖣.ι i).base y = x := 𝖣.ι_jointly_surjective ((LocallyRingedSpace.forgetToSheafedSpace.{u} ⋙ SheafedSpace.forget CommRingCatMax.{u, u}) ⋙ forget TopCat.{u}) x From 6eec427982c8cb527cd6e3c99d067d9e2218e719 Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Wed, 16 Oct 2024 11:05:16 +0000 Subject: [PATCH 218/425] feat(RingTheory/StandardSmooth): meta properties of standard smooth ring homomorphisms (#16868) In particular we show that being standard smooth is stable under composition and base change. This contribution was created as part of the AIM workshop "Formalizing algebraic geometry" in June 2024. --- Mathlib.lean | 1 + Mathlib/RingTheory/LocalProperties/Basic.lean | 38 ++++ .../RingTheory/Localization/BaseChange.lean | 9 + .../RingTheory/RingHom/StandardSmooth.lean | 168 ++++++++++++++++++ Mathlib/RingTheory/Smooth/StandardSmooth.lean | 26 +-- 5 files changed, 217 insertions(+), 25 deletions(-) create mode 100644 Mathlib/RingTheory/RingHom/StandardSmooth.lean diff --git a/Mathlib.lean b/Mathlib.lean index ad61f598310a68..5c43f1b7e519b0 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4110,6 +4110,7 @@ import Mathlib.RingTheory.RingHom.FinitePresentation import Mathlib.RingTheory.RingHom.FiniteType import Mathlib.RingTheory.RingHom.Integral import Mathlib.RingTheory.RingHom.Locally +import Mathlib.RingTheory.RingHom.StandardSmooth import Mathlib.RingTheory.RingHom.Surjective import Mathlib.RingTheory.RingHomProperties import Mathlib.RingTheory.RingInvo diff --git a/Mathlib/RingTheory/LocalProperties/Basic.lean b/Mathlib/RingTheory/LocalProperties/Basic.lean index 9c1bfac28d009f..7982b328a9a8c9 100644 --- a/Mathlib/RingTheory/LocalProperties/Basic.lean +++ b/Mathlib/RingTheory/LocalProperties/Basic.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Andrew Yang -/ import Mathlib.RingTheory.Localization.AtPrime +import Mathlib.RingTheory.Localization.BaseChange import Mathlib.RingTheory.Localization.Submodule import Mathlib.RingTheory.RingHomProperties @@ -261,6 +262,43 @@ lemma RingHom.OfLocalizationSpanTarget.ofIsLocalization AlgEquiv.toRingEquiv_toRingHom, Localization.coe_algEquiv_symm, IsLocalization.map_comp, RingHom.comp_id] +section + +variable (hP : RingHom.StableUnderBaseChange @P) +variable {R S Rᵣ Sᵣ : Type u} [CommRing R] [CommRing S] [CommRing Rᵣ] [CommRing Sᵣ] [Algebra R Rᵣ] + [Algebra S Sᵣ] + +include hP + +/-- Let `S` be an `R`-algebra and `Sᵣ` and `Rᵣ` be the respective localizations at a submonoid +`M` of `R`. If `P` is stable under base change and `P` holds for `algebraMap R S`, then +`P` holds for `algebraMap Rᵣ Sᵣ`. -/ +lemma RingHom.StableUnderBaseChange.of_isLocalization [Algebra R S] [Algebra R Sᵣ] [Algebra Rᵣ Sᵣ] + [IsScalarTower R S Sᵣ] [IsScalarTower R Rᵣ Sᵣ] + (M : Submonoid R) [IsLocalization M Rᵣ] [IsLocalization (Algebra.algebraMapSubmonoid S M) Sᵣ] + (h : P (algebraMap R S)) : P (algebraMap Rᵣ Sᵣ) := + letI : Algebra.IsPushout R S Rᵣ Sᵣ := Algebra.isPushout_of_isLocalization M Rᵣ S Sᵣ + hP R S Rᵣ Sᵣ h + +/-- If `P` is stable under base change and holds for `f`, then `P` holds for `f` localized +at any submonoid `M` of `R`. -/ +lemma RingHom.StableUnderBaseChange.isLocalization_map (M : Submonoid R) [IsLocalization M Rᵣ] + (f : R →+* S) [IsLocalization (M.map f) Sᵣ] (hf : P f) : + 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' + (IsLocalization.map_comp M.le_comap_map) + haveI : IsLocalization (Algebra.algebraMapSubmonoid S M) Sᵣ := + inferInstanceAs <| IsLocalization (M.map f) Sᵣ + apply hP.of_isLocalization M hf + +lemma RingHom.StableUnderBaseChange.localizationPreserves : LocalizationPreserves P := by + introv R hf + exact hP.isLocalization_map _ _ hf + +end + end RingHom end Properties diff --git a/Mathlib/RingTheory/Localization/BaseChange.lean b/Mathlib/RingTheory/Localization/BaseChange.lean index fcb23d52941ff1..999592d5ff5876 100644 --- a/Mathlib/RingTheory/Localization/BaseChange.lean +++ b/Mathlib/RingTheory/Localization/BaseChange.lean @@ -47,3 +47,12 @@ theorem isLocalizedModule_iff_isBaseChange : IsLocalizedModule S f ↔ IsBaseCha rw [LinearMap.coe_comp, LinearEquiv.coe_coe, Function.comp_apply, LinearEquiv.restrictScalars_apply, LinearEquiv.trans_apply, IsBaseChange.equiv_symm_apply, IsBaseChange.equiv_tmul, one_smul] + +variable (T B : Type*) [CommSemiring T] [CommSemiring B] + [Algebra R T] [Algebra T B] [Algebra R B] [Algebra A B] [IsScalarTower R T B] + [IsScalarTower R A B] + +lemma Algebra.isPushout_of_isLocalization [IsLocalization (Algebra.algebraMapSubmonoid T S) B] : + Algebra.IsPushout R T A B := by + rw [Algebra.IsPushout.comm, Algebra.isPushout_iff] + apply IsLocalizedModule.isBaseChange S diff --git a/Mathlib/RingTheory/RingHom/StandardSmooth.lean b/Mathlib/RingTheory/RingHom/StandardSmooth.lean new file mode 100644 index 00000000000000..8b47fbfe7bf3a1 --- /dev/null +++ b/Mathlib/RingTheory/RingHom/StandardSmooth.lean @@ -0,0 +1,168 @@ +/- +Copyright (c) 2024 Christian Merten. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christian Merten +-/ +import Mathlib.RingTheory.LocalProperties.Basic +import Mathlib.RingTheory.Smooth.StandardSmooth +import Mathlib.Tactic.Algebraize + +/-! +# Standard smooth ring homomorphisms + +In this file we define standard smooth ring homomorphisms and show their +meta properties. + +## Notes + +This contribution was created as part of the AIM workshop "Formalizing algebraic geometry" +in June 2024. + +-/ + +universe t t' w w' u v + +variable (n m : ℕ) + +open TensorProduct + +namespace RingHom + +variable {R : Type u} {S : Type v} [CommRing R] [CommRing S] + +/-- A ring homomorphism `R →+* S` is standard smooth if `S` is standard smooth as `R`-algebra. -/ +def IsStandardSmooth (f : R →+* S) : Prop := + @Algebra.IsStandardSmooth.{t, w} _ _ _ _ f.toAlgebra + +/-- A ring homomorphism `R →+* S` is standard smooth of relative dimension `n` if +`S` is standard smooth of relative dimension `n` as `R`-algebra. -/ +def IsStandardSmoothOfRelativeDimension (f : R →+* S) : Prop := + @Algebra.IsStandardSmoothOfRelativeDimension.{t, w} n _ _ _ _ f.toAlgebra + +lemma IsStandardSmoothOfRelativeDimension.isStandardSmooth (f : R →+* S) + (hf : IsStandardSmoothOfRelativeDimension.{t, w} n f) : + IsStandardSmooth.{t, w} f := by + algebraize [f] + letI : Algebra.IsStandardSmoothOfRelativeDimension.{t, w} n R S := hf + exact Algebra.IsStandardSmoothOfRelativeDimension.isStandardSmooth n + +variable {n m} + +variable (R) in +lemma IsStandardSmoothOfRelativeDimension.id : + IsStandardSmoothOfRelativeDimension.{t, w} 0 (RingHom.id R) := + Algebra.IsStandardSmoothOfRelativeDimension.id R + +lemma IsStandardSmoothOfRelativeDimension.equiv (e : R ≃+* S) : + IsStandardSmoothOfRelativeDimension.{t, w} 0 (e : R →+* S) := by + algebraize [e.toRingHom] + exact Algebra.IsStandardSmoothOfRelativeDimension.of_algebraMap_bijective e.bijective + +variable {T : Type*} [CommRing T] + +lemma IsStandardSmooth.comp {g : S →+* T} {f : R →+* S} + (hg : IsStandardSmooth.{t', w'} g) (hf : IsStandardSmooth.{t, w} f) : + IsStandardSmooth.{max t t', max w w'} (g.comp f) := by + rw [IsStandardSmooth] + algebraize [f, g, (g.comp f)] + letI : Algebra.IsStandardSmooth R S := hf + letI : Algebra.IsStandardSmooth S T := hg + exact Algebra.IsStandardSmooth.trans.{t, t', w, w'} R S T + +lemma IsStandardSmoothOfRelativeDimension.comp {g : S →+* T} {f : R →+* S} + (hg : IsStandardSmoothOfRelativeDimension.{t', w'} n g) + (hf : IsStandardSmoothOfRelativeDimension.{t, w} m f) : + IsStandardSmoothOfRelativeDimension.{max t t', max w w'} (n + m) (g.comp f) := by + rw [IsStandardSmoothOfRelativeDimension] + algebraize [f, g, (g.comp f)] + letI : Algebra.IsStandardSmoothOfRelativeDimension m R S := hf + letI : Algebra.IsStandardSmoothOfRelativeDimension n S T := hg + exact Algebra.IsStandardSmoothOfRelativeDimension.trans m n R S T + +lemma isStandardSmooth_stableUnderComposition : + StableUnderComposition @IsStandardSmooth.{t, w} := + fun _ _ _ _ _ _ _ _ hf hg ↦ hg.comp hf + +lemma isStandardSmooth_respectsIso : RespectsIso @IsStandardSmooth.{t, w} := by + apply isStandardSmooth_stableUnderComposition.respectsIso + introv + exact (IsStandardSmoothOfRelativeDimension.equiv e).isStandardSmooth + +lemma isStandardSmoothOfRelativeDimension_respectsIso : + RespectsIso (@IsStandardSmoothOfRelativeDimension.{t, w} n) where + left {R S T _ _ _} f e hf := by + rw [← zero_add n] + exact (IsStandardSmoothOfRelativeDimension.equiv e).comp hf + right {R S T _ _ _} f e hf := by + rw [← add_zero n] + exact hf.comp (IsStandardSmoothOfRelativeDimension.equiv e) + +lemma isStandardSmooth_stableUnderBaseChange : StableUnderBaseChange @IsStandardSmooth.{t, w} := by + apply StableUnderBaseChange.mk + · exact isStandardSmooth_respectsIso + · introv h + replace h : Algebra.IsStandardSmooth R T := by + rw [RingHom.IsStandardSmooth] at h; convert h; ext; simp_rw [Algebra.smul_def]; rfl + suffices Algebra.IsStandardSmooth S (S ⊗[R] T) by + rw [RingHom.IsStandardSmooth]; convert this; ext; simp_rw [Algebra.smul_def]; rfl + infer_instance + +variable (n) + +lemma isStandardSmoothOfRelativeDimension_stableUnderBaseChange : + StableUnderBaseChange (@IsStandardSmoothOfRelativeDimension.{t, w} n) := by + apply StableUnderBaseChange.mk + · exact isStandardSmoothOfRelativeDimension_respectsIso + · introv h + replace h : Algebra.IsStandardSmoothOfRelativeDimension n R T := by + rw [RingHom.IsStandardSmoothOfRelativeDimension] at h + convert h; ext; simp_rw [Algebra.smul_def]; rfl + suffices Algebra.IsStandardSmoothOfRelativeDimension n S (S ⊗[R] T) by + rw [RingHom.IsStandardSmoothOfRelativeDimension] + convert this; ext; simp_rw [Algebra.smul_def]; rfl + infer_instance + +lemma IsStandardSmoothOfRelativeDimension.algebraMap_isLocalizationAway {Rᵣ : Type*} [CommRing Rᵣ] + [Algebra R Rᵣ] (r : R) [IsLocalization.Away r Rᵣ] : + IsStandardSmoothOfRelativeDimension.{0, 0} 0 (algebraMap R Rᵣ) := by + have : (algebraMap R Rᵣ).toAlgebra = ‹Algebra R Rᵣ› := by + ext + rw [Algebra.smul_def] + rfl + rw [IsStandardSmoothOfRelativeDimension, this] + exact Algebra.IsStandardSmoothOfRelativeDimension.localization_away r + +lemma isStandardSmooth_localizationPreserves : LocalizationPreserves IsStandardSmooth.{t, w} := + isStandardSmooth_stableUnderBaseChange.localizationPreserves + +lemma isStandardSmoothOfRelativeDimension_localizationPreserves : + LocalizationPreserves (IsStandardSmoothOfRelativeDimension.{t, w} n) := + (isStandardSmoothOfRelativeDimension_stableUnderBaseChange n).localizationPreserves + +lemma isStandardSmooth_holdsForLocalizationAway : + HoldsForLocalizationAway IsStandardSmooth.{0, 0} := by + introv R h + exact (IsStandardSmoothOfRelativeDimension.algebraMap_isLocalizationAway r).isStandardSmooth + +lemma isStandardSmoothOfRelativeDimension_holdsForLocalizationAway : + HoldsForLocalizationAway (IsStandardSmoothOfRelativeDimension.{0, 0} 0) := by + introv R h + exact IsStandardSmoothOfRelativeDimension.algebraMap_isLocalizationAway r + +lemma isStandardSmooth_stableUnderCompositionWithLocalizationAway : + StableUnderCompositionWithLocalizationAway IsStandardSmooth.{0, 0} := + isStandardSmooth_stableUnderComposition.stableUnderCompositionWithLocalizationAway + isStandardSmooth_holdsForLocalizationAway + +lemma isStandardSmoothOfRelativeDimension_stableUnderCompositionWithLocalizationAway : + StableUnderCompositionWithLocalizationAway (IsStandardSmoothOfRelativeDimension.{0, 0} n) where + left _ S T _ _ _ _ s _ _ hf := + have : (algebraMap S T).IsStandardSmoothOfRelativeDimension 0 := + IsStandardSmoothOfRelativeDimension.algebraMap_isLocalizationAway s + zero_add n ▸ IsStandardSmoothOfRelativeDimension.comp this hf + right R S _ _ _ _ _ r _ _ hf := + have : (algebraMap R S).IsStandardSmoothOfRelativeDimension 0 := + IsStandardSmoothOfRelativeDimension.algebraMap_isLocalizationAway r + add_zero n ▸ IsStandardSmoothOfRelativeDimension.comp hf this + +end RingHom diff --git a/Mathlib/RingTheory/Smooth/StandardSmooth.lean b/Mathlib/RingTheory/Smooth/StandardSmooth.lean index 988a61b9c879e4..8d4159379686e4 100644 --- a/Mathlib/RingTheory/Smooth/StandardSmooth.lean +++ b/Mathlib/RingTheory/Smooth/StandardSmooth.lean @@ -89,8 +89,7 @@ variable (n m : ℕ) namespace Algebra -variable (R : Type u) [CommRing R] -variable (S : Type v) [CommRing S] [Algebra R S] +variable (R : Type u) (S : Type v) [CommRing R] [CommRing S] [Algebra R S] /-- A `PreSubmersivePresentation` of an `R`-algebra `S` is a `Presentation` @@ -556,26 +555,3 @@ instance IsStandardSmoothOfRelativeDimension.baseChange end BaseChange end Algebra - -namespace RingHom - -variable {R : Type u} [CommRing R] -variable {S : Type v} [CommRing S] - -/-- A ring homomorphism `R →+* S` is standard smooth if `S` is standard smooth as `R`-algebra. -/ -def IsStandardSmooth (f : R →+* S) : Prop := - @Algebra.IsStandardSmooth.{t, w} _ _ _ _ f.toAlgebra - -/-- A ring homomorphism `R →+* S` is standard smooth of relative dimension `n` if -`S` is standard smooth of relative dimension `n` as `R`-algebra. -/ -def IsStandardSmoothOfRelativeDimension (f : R →+* S) : Prop := - @Algebra.IsStandardSmoothOfRelativeDimension.{t, w} n _ _ _ _ f.toAlgebra - -lemma IsStandardSmoothOfRelativeDimension.isStandardSmooth (f : R →+* S) - (hf : IsStandardSmoothOfRelativeDimension.{t, w} n f) : - IsStandardSmooth.{t, w} f := - letI : Algebra R S := f.toAlgebra - letI : Algebra.IsStandardSmoothOfRelativeDimension.{t, w} n R S := hf - Algebra.IsStandardSmoothOfRelativeDimension.isStandardSmooth n - -end RingHom From fd745ec84d75a14cf4e28e4ee85ef766290c778e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Wed, 16 Oct 2024 11:05:17 +0000 Subject: [PATCH 219/425] feat(SetTheory/Cardinal/Aleph): define initial ordinals (#16964) --- Mathlib/SetTheory/Cardinal/Aleph.lean | 57 ++++++++++++++++++++++- Mathlib/SetTheory/Ordinal/Arithmetic.lean | 8 ---- Mathlib/SetTheory/Ordinal/Basic.lean | 8 ++++ 3 files changed, 64 insertions(+), 9 deletions(-) diff --git a/Mathlib/SetTheory/Cardinal/Aleph.lean b/Mathlib/SetTheory/Cardinal/Aleph.lean index c1fc5cb463cb7e..7a654d0363135c 100644 --- a/Mathlib/SetTheory/Cardinal/Aleph.lean +++ b/Mathlib/SetTheory/Cardinal/Aleph.lean @@ -41,10 +41,65 @@ open Function Set Cardinal Equiv Order Ordinal universe u v w -namespace Cardinal +/-! ### Omega ordinals -/ + +namespace Ordinal + +/-- An ordinal is initial when it is the first ordinal with a given cardinality. + +This is written as `o.card.ord = o`, i.e. `o` is the smallest ordinal with cardinality `o.card`. -/ +def IsInitial (o : Ordinal) : Prop := + o.card.ord = o + +theorem IsInitial.ord_card {o : Ordinal} (h : IsInitial o) : o.card.ord = o := h + +theorem IsInitial.card_le_card {a b : Ordinal} (ha : IsInitial a) : a.card ≤ b.card ↔ a ≤ b := by + refine ⟨fun h ↦ ?_, Ordinal.card_le_card⟩ + rw [← ord_le_ord, ha.ord_card] at h + exact h.trans (ord_card_le b) + +theorem IsInitial.card_lt_card {a b : Ordinal} (hb : IsInitial b) : a.card < b.card ↔ a < b := + lt_iff_lt_of_le_iff_le hb.card_le_card + +theorem isInitial_ord (c : Cardinal) : IsInitial c.ord := by + rw [IsInitial, card_ord] + +theorem isInitial_natCast (n : ℕ) : IsInitial n := by + rw [IsInitial, card_nat, ord_nat] + +theorem isInitial_zero : IsInitial 0 := by + exact_mod_cast isInitial_natCast 0 + +theorem isInitial_one : IsInitial 1 := by + exact_mod_cast isInitial_natCast 1 + +theorem isInitial_omega0 : IsInitial ω := by + rw [IsInitial, card_omega0, ord_aleph0] + +theorem not_bddAbove_isInitial : ¬ BddAbove {x | IsInitial x} := by + rintro ⟨a, ha⟩ + have := ha (isInitial_ord (succ a.card)) + rw [ord_le] at this + exact (lt_succ _).not_le this + +/-- Initial ordinals are order-isomorphic to the cardinals. -/ +@[simps!] +def isInitialIso : {x // IsInitial x} ≃o Cardinal where + toFun x := x.1.card + invFun x := ⟨x.ord, isInitial_ord _⟩ + left_inv x := Subtype.ext x.2.ord_card + right_inv x := card_ord x + map_rel_iff' {a _} := a.2.card_le_card + +-- TODO: define `omega` as the enumerator function of `IsInitial`, and redefine +-- `aleph x = (omega x).card`. + +end Ordinal /-! ### Aleph cardinals -/ +namespace Cardinal + /-- The `aleph'` function gives the cardinals listed by their ordinal index. `aleph' n = n`, `aleph' ω = ℵ₀`, `aleph' (ω + 1) = succ ℵ₀`, etc. diff --git a/Mathlib/SetTheory/Ordinal/Arithmetic.lean b/Mathlib/SetTheory/Ordinal/Arithmetic.lean index aa95e0d9ce2168..d8239b6b16acc5 100644 --- a/Mathlib/SetTheory/Ordinal/Arithmetic.lean +++ b/Mathlib/SetTheory/Ordinal/Arithmetic.lean @@ -2219,14 +2219,6 @@ namespace Cardinal open Ordinal -@[simp] -theorem ord_aleph0 : ord.{u} ℵ₀ = ω := - le_antisymm (ord_le.2 <| le_rfl) <| - le_of_forall_lt fun o h => by - rcases Ordinal.lt_lift_iff.1 h with ⟨o, rfl, h'⟩ - rw [lt_ord, ← lift_card, lift_lt_aleph0, ← typein_enum (· < ·) h'] - exact lt_aleph0_iff_fintype.2 ⟨Set.fintypeLTNat _⟩ - @[simp] theorem add_one_of_aleph0_le {c} (h : ℵ₀ ≤ c) : c + 1 = c := by rw [add_comm, ← card_ord c, ← card_one, ← card_add, one_add_of_omega0_le] diff --git a/Mathlib/SetTheory/Ordinal/Basic.lean b/Mathlib/SetTheory/Ordinal/Basic.lean index f6526c9ba0f286..b0d0c08af9e087 100644 --- a/Mathlib/SetTheory/Ordinal/Basic.lean +++ b/Mathlib/SetTheory/Ordinal/Basic.lean @@ -1214,6 +1214,14 @@ theorem ord_one : ord 1 = 1 := by simpa using ord_nat 1 theorem ord_ofNat (n : ℕ) [n.AtLeastTwo] : ord (no_index (OfNat.ofNat n)) = OfNat.ofNat n := ord_nat n +@[simp] +theorem ord_aleph0 : ord.{u} ℵ₀ = ω := + le_antisymm (ord_le.2 le_rfl) <| + le_of_forall_lt fun o h => by + rcases Ordinal.lt_lift_iff.1 h with ⟨o, rfl, h'⟩ + rw [lt_ord, ← lift_card, lift_lt_aleph0, ← typein_enum (· < ·) h'] + exact lt_aleph0_iff_fintype.2 ⟨Set.fintypeLTNat _⟩ + @[simp] theorem lift_ord (c) : Ordinal.lift.{u,v} (ord c) = ord (lift.{u,v} c) := by refine le_antisymm (le_of_forall_lt fun a ha => ?_) ?_ From e0e004a2406351f254842985eb68b467c53c2cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Wed, 16 Oct 2024 11:05:19 +0000 Subject: [PATCH 220/425] chore(SetTheory/Ordinal/Arithmetic): fix `Ordinal.enum` type signature (#17601) For some reason, Lean was inferring [some nonsense](https://leanprover-community.github.io/mathlib4_docs/Mathlib/SetTheory/Ordinal/Basic.html#Ordinal.enum). Unfortunately, the explicit typing is required for `simp`; see [Zulip](https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/simp.20and.20subrel). --- Mathlib/SetTheory/Ordinal/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/SetTheory/Ordinal/Basic.lean b/Mathlib/SetTheory/Ordinal/Basic.lean index b0d0c08af9e087..2de607c6ac4062 100644 --- a/Mathlib/SetTheory/Ordinal/Basic.lean +++ b/Mathlib/SetTheory/Ordinal/Basic.lean @@ -449,7 +449,7 @@ the elements of `α`. -/ -- The explicit typing is required in order for `simp` to work properly. @[simps! symm_apply_coe] def enum (r : α → α → Prop) [IsWellOrder α r] : - @RelIso (Subtype fun o => o < type r) α (Subrel (· < · ) _) r := + @RelIso { o // o < type r } α (Subrel (· < ·) { o | o < type r }) r := (typein.principalSeg r).subrelIso @[simp] From fde83d96472bb47daa76ef4a93bd6b5bae1a1fc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Wed, 16 Oct 2024 11:05:20 +0000 Subject: [PATCH 221/425] feat(SetTheory/Ordinal/Principal): simpler characterization of `Principal` for monotone operations (#17742) plus some drive-by spacing fixes. Subsequent PRs will use this to golf results on additive and multiplicative principal ordinals. --- Mathlib/SetTheory/Ordinal/Principal.lean | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Mathlib/SetTheory/Ordinal/Principal.lean b/Mathlib/SetTheory/Ordinal/Principal.lean index 58596bf0f6d53d..d58c0eff2dd351 100644 --- a/Mathlib/SetTheory/Ordinal/Principal.lean +++ b/Mathlib/SetTheory/Ordinal/Principal.lean @@ -11,6 +11,7 @@ import Mathlib.SetTheory.Ordinal.FixedPoint We define principal or indecomposable ordinals, and we prove the standard properties about them. ## Main definitions and results + * `Principal`: A principal or indecomposable ordinal under some binary operation. We include 0 and any other typically excluded edge cases for simplicity. * `unbounded_principal`: Principal ordinals are unbounded. @@ -20,6 +21,7 @@ We define principal or indecomposable ordinals, and we prove the standard proper multiplicative principal ordinals. ## TODO + * Prove that exponential principal ordinals are 0, 1, 2, ω, or epsilon numbers, i.e. fixed points of `fun x ↦ ω ^ x`. -/ @@ -56,6 +58,15 @@ theorem principal_iff_principal_swap {o : Ordinal} : theorem not_principal_iff {o : Ordinal} : ¬ Principal op o ↔ ∃ a < o, ∃ b < o, o ≤ op a b := by simp [Principal] +theorem principal_iff_of_monotone {o : Ordinal} + (h₁ : ∀ a, Monotone (op a)) (h₂ : ∀ a, Monotone (Function.swap op a)): + Principal op o ↔ ∀ a < o, op a a < o := by + use fun h a ha => h ha ha + intro H a b ha hb + obtain hab | hba := le_or_lt a b + · exact (h₂ b hab).trans_lt <| H b hb + · exact (h₁ a hba.le).trans_lt <| H a ha + theorem principal_zero : Principal op 0 := fun a _ h => (Ordinal.not_lt_zero a h).elim @@ -115,7 +126,6 @@ theorem unbounded_principal (op : Ordinal → Ordinal → Ordinal) : /-! #### Additive principal ordinals -/ - theorem principal_add_one : Principal (· + ·) 1 := principal_one_iff.2 <| zero_add 0 @@ -265,7 +275,6 @@ theorem mul_principal_add_is_principal_add (a : Ordinal.{u}) {b : Ordinal.{u}} ( /-! #### Multiplicative principal ordinals -/ - theorem principal_mul_one : Principal (· * ·) 1 := by rw [principal_one_iff] exact zero_mul _ @@ -423,7 +432,6 @@ theorem mul_eq_opow_log_succ {a b : Ordinal.{u}} (ha : a ≠ 0) (hb : Principal /-! #### Exponential principal ordinals -/ - theorem principal_opow_omega0 : Principal (· ^ ·) ω := fun a b ha hb => match a, b, lt_omega0.1 ha, lt_omega0.1 hb with | _, _, ⟨m, rfl⟩, ⟨n, rfl⟩ => by From 298e0e0dda8ccdfe6eeca0b8acf8615d45c4c296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Wed, 16 Oct 2024 11:05:21 +0000 Subject: [PATCH 222/425] =?UTF-8?q?feat:=20`card=20(=CE=B9=20=E2=86=92?= =?UTF-8?q?=E2=82=80=20=CE=B1)=20=3D=20card=20=CE=B1=20^=20card=20=CE=B9`?= =?UTF-8?q?=20(#17807)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From PFR --- Mathlib/Data/Finsupp/Fintype.lean | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Mathlib/Data/Finsupp/Fintype.lean b/Mathlib/Data/Finsupp/Fintype.lean index 0f5b2e08e49867..b347815decf835 100644 --- a/Mathlib/Data/Finsupp/Fintype.lean +++ b/Mathlib/Data/Finsupp/Fintype.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Anne Baanen, Alex J. Best -/ import Mathlib.Data.Finsupp.Defs -import Mathlib.Data.Fintype.Basic +import Mathlib.Data.Fintype.BigOperators /-! @@ -14,17 +14,19 @@ Some lemmas on the combination of `Finsupp`, `Fintype` and `Infinite`. -/ +variable {ι α : Type*} [DecidableEq ι] [Fintype ι] [Zero α] [Fintype α] -noncomputable instance Finsupp.fintype {ι π : Sort _} [DecidableEq ι] [Zero π] [Fintype ι] - [Fintype π] : Fintype (ι →₀ π) := +noncomputable instance Finsupp.fintype : Fintype (ι →₀ α) := Fintype.ofEquiv _ Finsupp.equivFunOnFinite.symm -instance Finsupp.infinite_of_left {ι π : Sort _} [Nontrivial π] [Zero π] [Infinite ι] : - Infinite (ι →₀ π) := - let ⟨_, hm⟩ := exists_ne (0 : π) +instance Finsupp.infinite_of_left [Nontrivial α] [Infinite ι] : Infinite (ι →₀ α) := + let ⟨_, hm⟩ := exists_ne (0 : α) Infinite.of_injective _ <| Finsupp.single_left_injective hm -instance Finsupp.infinite_of_right {ι π : Sort _} [Infinite π] [Zero π] [Nonempty ι] : - Infinite (ι →₀ π) := +instance Finsupp.infinite_of_right [Infinite α] [Nonempty ι] : Infinite (ι →₀ α) := Infinite.of_injective (fun i => Finsupp.single (Classical.arbitrary ι) i) (Finsupp.single_injective (Classical.arbitrary ι)) + +variable (ι α) in +@[simp] lemma Fintype.card_finsupp : card (ι →₀ α) = card α ^ card ι := by + simp [card_congr Finsupp.equivFunOnFinite] From c15f22017089abf7801d49d1d4cf0df79d096aa0 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 22:07:34 +1100 Subject: [PATCH 223/425] . --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index 9658c384500867..257131cde67cba 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "108e204d0822981f8d2c7c0e65f5201071126681", + "rev": "acc9722fa789363b2c7cd0c0e3ee69a9048b459a", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "nightly-testing", From 06dcc3e054eb5821fc61a639cf9a091e04bf716a Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 22:17:56 +1100 Subject: [PATCH 224/425] remove missing import --- Mathlib/Algebra/Group/Pi/Basic.lean | 1 - Mathlib/Data/List/TFAE.lean | 1 - Mathlib/Order/Basic.lean | 1 - Mathlib/Tactic/Tauto.lean | 1 - scripts/noshake.json | 3 --- 5 files changed, 7 deletions(-) diff --git a/Mathlib/Algebra/Group/Pi/Basic.lean b/Mathlib/Algebra/Group/Pi/Basic.lean index 7a88ae8220a12e..b455b861786e4c 100644 --- a/Mathlib/Algebra/Group/Pi/Basic.lean +++ b/Mathlib/Algebra/Group/Pi/Basic.lean @@ -8,7 +8,6 @@ import Mathlib.Data.Prod.Basic import Mathlib.Data.Sum.Basic import Mathlib.Logic.Unique import Mathlib.Tactic.Spread -import Batteries.Tactic.Classical /-! # Instances and theorems on pi types diff --git a/Mathlib/Data/List/TFAE.lean b/Mathlib/Data/List/TFAE.lean index 3dd02febe8c138..24e43d9612f033 100644 --- a/Mathlib/Data/List/TFAE.lean +++ b/Mathlib/Data/List/TFAE.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Johan Commelin, Simon Hudon -/ import Batteries.Data.List.Lemmas -import Batteries.Tactic.Classical import Mathlib.Tactic.TypeStar /-! diff --git a/Mathlib/Order/Basic.lean b/Mathlib/Order/Basic.lean index f7a234670ae36b..b090a893ae8119 100644 --- a/Mathlib/Order/Basic.lean +++ b/Mathlib/Order/Basic.lean @@ -11,7 +11,6 @@ import Mathlib.Tactic.Spread import Mathlib.Tactic.Convert import Mathlib.Tactic.SimpRw import Batteries.Data.Sum.Lemmas -import Batteries.Tactic.Classical /-! # Basic definitions about `≤` and `<` diff --git a/Mathlib/Tactic/Tauto.lean b/Mathlib/Tactic/Tauto.lean index 14285f3eb54287..f68a5143bdf0d4 100644 --- a/Mathlib/Tactic/Tauto.lean +++ b/Mathlib/Tactic/Tauto.lean @@ -8,7 +8,6 @@ import Mathlib.Tactic.Core import Mathlib.Lean.Elab.Tactic.Basic import Mathlib.Logic.Basic import Qq -import Batteries.Tactic.Classical /-! The `tauto` tactic. diff --git a/scripts/noshake.json b/scripts/noshake.json index 75da1806f1ee3e..ed46703c4eb516 100644 --- a/scripts/noshake.json +++ b/scripts/noshake.json @@ -325,7 +325,6 @@ "Mathlib.Order.RelClasses": ["Batteries.WF"], "Mathlib.Order.Filter.ListTraverse": ["Mathlib.Control.Traversable.Instances"], - "Mathlib.Order.Basic": ["Batteries.Tactic.Classical"], "Mathlib.NumberTheory.Harmonic.Defs": ["Mathlib.Algebra.Order.BigOperators.Ring.Finset", "Mathlib.Algebra.Order.Field.Basic"], @@ -361,7 +360,6 @@ ["Batteries.Tactic.Init", "Mathlib.Logic.Function.Defs"], "Mathlib.Data.Nat.Find": ["Batteries.WF"], "Mathlib.Data.Multiset.Bind": ["Mathlib.Algebra.GroupWithZero.Action.Defs"], - "Mathlib.Data.List.TFAE": ["Batteries.Tactic.Classical"], "Mathlib.Data.List.Range": ["Batteries.Data.Nat.Lemmas"], "Mathlib.Data.List.ProdSigma": ["Batteries.Data.Nat.Lemmas", "Mathlib.Data.List.Basic"], @@ -422,7 +420,6 @@ "Mathlib.Algebra.Homology.ModuleCat": ["Mathlib.Algebra.Homology.Homotopy"], "Mathlib.Algebra.Group.Units.Basic": ["Mathlib.Tactic.Subsingleton"], "Mathlib.Algebra.Group.Units": ["Mathlib.Tactic.Subsingleton"], - "Mathlib.Algebra.Group.Pi.Basic": ["Batteries.Tactic.Classical"], "Mathlib.Algebra.Group.Defs": ["Mathlib.Data.Int.Notation"], "Mathlib.Algebra.GeomSum": ["Mathlib.Algebra.Order.BigOperators.Ring.Finset"], "Mathlib.Algebra.Category.Ring.Basic": From e4a2f090270c44f739b37cfa06b2c2099333b3d5 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 22:22:38 +1100 Subject: [PATCH 225/425] . --- Mathlib/Data/List/DropRight.lean | 2 +- Mathlib/Logic/Relation.lean | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/Mathlib/Data/List/DropRight.lean b/Mathlib/Data/List/DropRight.lean index 10638f80de52e0..f55afc95cdd9f4 100644 --- a/Mathlib/Data/List/DropRight.lean +++ b/Mathlib/Data/List/DropRight.lean @@ -212,7 +212,7 @@ theorem rtakeWhile_idempotent (p : α → Bool) (l : List α) : rtakeWhile_eq_self_iff.mpr fun _ => mem_rtakeWhile_imp lemma rdrop_add (i j : ℕ) : (l.rdrop i).rdrop j = l.rdrop (i + j) := by - simp_rw [rdrop_eq_reverse_drop_reverse, reverse_reverse, drop_drop, Nat.add_comm] + simp_rw [rdrop_eq_reverse_drop_reverse, reverse_reverse, drop_drop] @[simp] lemma rdrop_append_length {l₁ l₂ : List α} : diff --git a/Mathlib/Logic/Relation.lean b/Mathlib/Logic/Relation.lean index 93afac58af7093..0e8c56a80eb73a 100644 --- a/Mathlib/Logic/Relation.lean +++ b/Mathlib/Logic/Relation.lean @@ -689,15 +689,6 @@ theorem Quot.eqvGen_sound (H : EqvGen r a b) : Quot.mk r a = Quot.mk r b := (fun _ _ _ _ _ IH₁ IH₂ ↦ Eq.trans IH₁ IH₂) H -instance Quotient.decidableEq {α : Sort*} {s : Setoid α} [d : ∀ a b : α, Decidable (a ≈ b)] : - DecidableEq (Quotient s) := - fun q₁ q₂ : Quotient s ↦ - Quotient.recOnSubsingleton₂ q₁ q₂ - (fun a₁ a₂ ↦ - match (d a₁ a₂) with - | (isTrue h₁) => isTrue (Quotient.sound h₁) - | (isFalse h₂) => isFalse (fun h ↦ absurd (Quotient.exact h) h₂)) - theorem Equivalence.eqvGen_iff (h : Equivalence r) : EqvGen r a b ↔ r a b := Iff.intro (by From cdfd2b4becf2ae3d5deafeae8befa870daa1334e Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Wed, 16 Oct 2024 22:25:34 +1100 Subject: [PATCH 226/425] . --- Mathlib/Data/List/Range.lean | 2 +- scripts/noshake.json | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Mathlib/Data/List/Range.lean b/Mathlib/Data/List/Range.lean index bd491ba6ccd4ab..f1e03a895c1e49 100644 --- a/Mathlib/Data/List/Range.lean +++ b/Mathlib/Data/List/Range.lean @@ -144,7 +144,7 @@ theorem ranges_length (l : List ℕ) : /-- See `List.ranges_flatten` for the version about `List.sum`. -/ lemma ranges_flatten' : ∀ l : List ℕ, l.ranges.flatten = range (Nat.sum l) | [] => rfl - | a :: l => by simp only [sum_cons, flatten, ← map_flatten, ranges_flatten', range_add] + | a :: l => by simp only [Nat.sum_cons, flatten, ← map_flatten, ranges_flatten', range_add] @[deprecated (since := "2024-10-15")] alias ranges_join' := ranges_flatten' diff --git a/scripts/noshake.json b/scripts/noshake.json index ed46703c4eb516..96b77d34aeb98d 100644 --- a/scripts/noshake.json +++ b/scripts/noshake.json @@ -73,7 +73,6 @@ "Mathlib.Tactic.CategoryTheory.Elementwise", "Mathlib.Tactic.CategoryTheory.Slice", "Mathlib.Tactic.Choose", - "Mathlib.Tactic.Classical", "Mathlib.Tactic.Clean", "Mathlib.Tactic.ClearExcept", "Mathlib.Tactic.ClearExclamation", From ebec1b61db40c3352391654316f3644e268fee46 Mon Sep 17 00:00:00 2001 From: mathlib4-update-dependencies-bot <150093616+mathlib-bors@users.noreply.github.com> Date: Wed, 16 Oct 2024 11:28:18 +0000 Subject: [PATCH 227/425] chore: update Mathlib dependencies 2024-10-16 (#17816) 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 eedfc9ff53b9ba..6e5aa7951c279e 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "b731e84cb99d738b8d9710a0ba02bf8ec8d7fd26", + "rev": "422d1a5f608fccafeddab9748e8038ef346b59bf", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", @@ -65,7 +65,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "4b61d4abc1659f15ffda5ec24fdebc229d51d066", + "rev": "7bedaed1ef024add1e171cc17706b012a9a37802", "name": "LeanSearchClient", "manifestFile": "lake-manifest.json", "inputRev": "main", From 1aaa5b99d39e4bc03db73fd848a03062b974846f Mon Sep 17 00:00:00 2001 From: Daniel Weber Date: Wed, 16 Oct 2024 12:04:57 +0000 Subject: [PATCH 228/425] feat(Data/Fin/Basic): `intCast_val_sub_eq_ite` (#17190) Co-authored-by: Daniel Weber <55664973+Command-Master@users.noreply.github.com> --- Mathlib/Data/Fin/Basic.lean | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mathlib/Data/Fin/Basic.lean b/Mathlib/Data/Fin/Basic.lean index 0da69a90e9ab73..7b7b730d2913b7 100644 --- a/Mathlib/Data/Fin/Basic.lean +++ b/Mathlib/Data/Fin/Basic.lean @@ -433,6 +433,10 @@ theorem val_add_eq_ite {n : ℕ} (a b : Fin n) : Nat.mod_eq_of_lt (show ↑b < n from b.2)] --- Porting note: syntactically the same as the above +lemma intCast_val_sub_eq_sub_add_ite {n : ℕ} (a b : Fin n) : + ((a - b).val : ℤ) = a.val - b.val + if b ≤ a then 0 else n := by + split <;> fin_omega + section OfNatCoe @[simp] From a7cd6bdbf63a4ad953c080bcbe3104d8acf670fc Mon Sep 17 00:00:00 2001 From: Bryan Gin-ge Chen Date: Wed, 16 Oct 2024 12:56:20 +0000 Subject: [PATCH 229/425] feat: action for labeling and closing stale PRs (#17041) Per discussion in the maintainer channel. Uses a PR branch https://github.com/actions/stale/pull/1145 of [actions/stale](https://github.com/actions/stale/) since it has a feature that will allow us to only consider PRs not sitting on the [#queue](https://bit.ly/3Ymuh0U). There's still placeholder text for the comments, but this is intended to be merged with the `debug-only` flag until we have the kinks sorted out, so we could fill in that text in a later PR. --- .github/workflows/stale.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/stale.yml diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 00000000000000..ea5585c38e83ef --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,25 @@ +name: 'Close stale issues and PRs' +on: + schedule: + - cron: '30 1 * * *' # every day at 01:30 UTC + workflow_dispatch: + +jobs: + stale: + runs-on: ubuntu-latest + steps: + # until https://github.com/actions/stale/pull/1145 is merged + - uses: asterisk/github-actions-stale@main-only-matching-filter + with: + debug-only: 'true' # TODO: remove in follow-up PR after testing is done! + stale-pr-label: 'stale' + stale-pr-message: 'Message to comment on stale PRs.' + close-pr-label: 'closed-due-to-inactivity' + close-pr-message: 'Comment on the staled PRs while closed' + days-before-stale: 60 + days-before-close: 120 + # search string from the Zulip #queue link at https://bit.ly/4eo6brN + # "is:open is:pr -is:draft base:master sort:updated-asc status:success -label:blocked-by-other-PR -label:merge-conflict -label:awaiting-CI -label:WIP -label:awaiting-author -label:delegated -label:auto-merge-after-CI -label:ready-to-merge -label:please-adopt -label:help-wanted -label:awaiting-zulip" + # We want PRs _not_ on the queue, so we keep "is:pr -is:draft base:master" (is:open is added by the action by default) as a prefix for all queries and then negate the rest of the params in separate queries to simulate boolean OR (see https://github.com/actions/stale/pull/1145) + # except for label:auto-merge-after-CI and label:ready-to-merge which presumably will be noticed before they go stale + only-matching-filter: '[ "is:pr -is:draft base:master -status:success", "is:pr -is:draft base:master label:blocked-by-other-PR", "is:pr -is:draft base:master label:merge-conflict", "is:pr -is:draft base:master label:awaiting-CI", "is:pr -is:draft base:master label:WIP", "is:pr -is:draft base:master label:awaiting-author", "is:pr -is:draft base:master label:delegated", "is:pr -is:draft base:master label:please-adopt", "is:pr -is:draft base:master label:help-wanted", "is:pr -is:draft base:master label:awaiting-zulip" ]' From d03e389cacbdd56f187bf32e31d3cfd401fb94c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Wed, 16 Oct 2024 12:56:21 +0000 Subject: [PATCH 230/425] feat(SetTheory/Ordinal/Enum): more lemmas on `enumOrd` (#17668) --- .../ConditionallyCompleteLattice/Basic.lean | 12 +++++++++++ Mathlib/SetTheory/Ordinal/Enum.lean | 20 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean b/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean index f14480f908ed03..e0b7205db68948 100644 --- a/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean +++ b/Mathlib/Order/ConditionallyCompleteLattice/Basic.lean @@ -1106,6 +1106,18 @@ theorem cbiInf_eq_of_not_forall {p : ι → Prop} {f : Subtype p → α} (hp : ⨅ (i) (h : p i), f ⟨i, h⟩ = iInf f ⊓ sInf ∅ := cbiSup_eq_of_not_forall (α := αᵒᵈ) hp +theorem csInf_eq_bot_of_bot_mem [OrderBot α] {s : Set α} (hs : ⊥ ∈ s) : sInf s = ⊥ := + eq_bot_iff.2 <| csInf_le (OrderBot.bddBelow s) hs + +theorem ciInf_eq_bot_of_bot_mem [OrderBot α] {f : ι → α} (hs : ⊥ ∈ range f) : iInf f = ⊥ := + csInf_eq_bot_of_bot_mem hs + +theorem csSup_eq_top_of_top_mem [OrderTop α] {s : Set α} (hs : ⊤ ∈ s) : sSup s = ⊤ := + csInf_eq_bot_of_bot_mem (α := αᵒᵈ) hs + +theorem ciInf_eq_top_of_top_mem [OrderTop α] {f : ι → α} (hs : ⊤ ∈ range f) : iSup f = ⊤ := + csSup_eq_top_of_top_mem hs + open Function variable [WellFoundedLT α] diff --git a/Mathlib/SetTheory/Ordinal/Enum.lean b/Mathlib/SetTheory/Ordinal/Enum.lean index c5a4c3b7442d66..4e5d4d38a7cf6b 100644 --- a/Mathlib/SetTheory/Ordinal/Enum.lean +++ b/Mathlib/SetTheory/Ordinal/Enum.lean @@ -61,6 +61,26 @@ theorem enumOrd_mem (hs : ¬ BddAbove s) (o : Ordinal) : enumOrd s o ∈ s := theorem enumOrd_strictMono (hs : ¬ BddAbove s) : StrictMono (enumOrd s) := fun a b ↦ (enumOrd_mem_aux hs b).2 a +theorem enumOrd_injective (hs : ¬ BddAbove s) : Function.Injective (enumOrd s) := + (enumOrd_strictMono hs).injective + +theorem enumOrd_inj (hs : ¬ BddAbove s) {a b : Ordinal} : enumOrd s a = enumOrd s b ↔ a = b := + (enumOrd_injective hs).eq_iff + +theorem enumOrd_le_enumOrd (hs : ¬ BddAbove s) {a b : Ordinal} : + enumOrd s a ≤ enumOrd s b ↔ a ≤ b := + (enumOrd_strictMono hs).le_iff_le + +theorem enumOrd_lt_enumOrd (hs : ¬ BddAbove s) {a b : Ordinal} : + enumOrd s a < enumOrd s b ↔ a < b := + (enumOrd_strictMono hs).lt_iff_lt + +theorem id_le_enumOrd (hs : ¬ BddAbove s) : id ≤ enumOrd s := + (enumOrd_strictMono hs).id_le + +theorem le_enumOrd_self (hs : ¬ BddAbove s) {a} : a ≤ enumOrd s a := + (enumOrd_strictMono hs).le_apply + theorem enumOrd_succ_le (hs : ¬ BddAbove s) (ha : a ∈ s) (hb : enumOrd s b < a) : enumOrd s (succ b) ≤ a := by apply enumOrd_le_of_forall_lt ha From 15a391f3007c5c377ba21af3e0a1d53502310685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Wed, 16 Oct 2024 12:56:22 +0000 Subject: [PATCH 231/425] feat(SetTheory/Ordinal/Exponential): `lt_omega0_opow` (#17740) --- Mathlib/SetTheory/Ordinal/Exponential.lean | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Mathlib/SetTheory/Ordinal/Exponential.lean b/Mathlib/SetTheory/Ordinal/Exponential.lean index 3fad6ff39bde58..57fe4e7e7b0e4b 100644 --- a/Mathlib/SetTheory/Ordinal/Exponential.lean +++ b/Mathlib/SetTheory/Ordinal/Exponential.lean @@ -486,6 +486,26 @@ theorem add_log_le_log_mul {x y : Ordinal} (b : Ordinal) (hx : x ≠ 0) (hy : y exact mul_le_mul' (opow_log_le_self b hx) (opow_log_le_self b hy) · simpa only [log_of_left_le_one hb, zero_add] using le_rfl +theorem omega0_opow_mul_nat_lt {a b : Ordinal} (h : a < b) (n : ℕ) : ω ^ a * n < ω ^ b := by + apply lt_of_lt_of_le _ (opow_le_opow_right omega0_pos (succ_le_of_lt h)) + rw [opow_succ] + exact mul_lt_mul_of_pos_left (nat_lt_omega0 n) (opow_pos a omega0_pos) + +theorem lt_omega0_opow {a b : Ordinal} (hb : b ≠ 0) : + a < ω ^ b ↔ ∃ c < b, ∃ n : ℕ, a < ω ^ c * n := by + refine ⟨fun ha ↦ ⟨_, lt_log_of_lt_opow hb ha, ?_⟩, + fun ⟨c, hc, n, hn⟩ ↦ hn.trans (omega0_opow_mul_nat_lt hc n)⟩ + obtain ⟨n, hn⟩ := lt_omega0.1 (div_opow_log_lt a one_lt_omega0) + use n.succ + rw [natCast_succ, ← hn] + exact lt_mul_succ_div a (opow_ne_zero _ omega0_ne_zero) + +theorem lt_omega0_opow_succ {a b : Ordinal} : a < ω ^ succ b ↔ ∃ n : ℕ, a < ω ^ b * n := by + refine ⟨fun ha ↦ ?_, fun ⟨n, hn⟩ ↦ hn.trans (omega0_opow_mul_nat_lt (lt_succ b) n)⟩ + obtain ⟨c, hc, n, hn⟩ := (lt_omega0_opow (succ_ne_zero b)).1 ha + refine ⟨n, hn.trans_le (mul_le_mul_right' ?_ _)⟩ + rwa [opow_le_opow_iff_right one_lt_omega0, ← lt_succ_iff] + /-! ### Interaction with `Nat.cast` -/ @[simp, norm_cast] From 8d09169a88254125170bdc9b4ffd787fbe0b3e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Wed, 16 Oct 2024 13:45:57 +0000 Subject: [PATCH 232/425] chore(BorelSpace): make `MeasurableSpace` arguments implicit (#17819) ... rather than instance arguments. This is motivated by non-canonical sigma-algebras showing up in the theory of Gibbs measures. From GibbsMeasure --- .../Constructions/BorelSpace/Order.lean | 18 ++--- .../Constructions/BorelSpace/Real.lean | 15 ++-- .../MeasureTheory/Measure/MeasureSpace.lean | 78 +++++++++---------- 3 files changed, 55 insertions(+), 56 deletions(-) diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean index 1014d372633329..8a3ca4d20c7d54 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Order.lean @@ -94,8 +94,8 @@ end OrderTopology section Orders -variable [TopologicalSpace α] [MeasurableSpace α] [OpensMeasurableSpace α] -variable [MeasurableSpace δ] +variable [TopologicalSpace α] {mα : MeasurableSpace α} [OpensMeasurableSpace α] +variable {mδ : MeasurableSpace δ} section Preorder @@ -473,7 +473,7 @@ end LinearOrder section Lattice -variable [TopologicalSpace γ] [MeasurableSpace γ] [BorelSpace γ] +variable [TopologicalSpace γ] {mγ : MeasurableSpace γ} [BorelSpace γ] instance (priority := 100) ContinuousSup.measurableSup [Sup γ] [ContinuousSup γ] : MeasurableSup γ where @@ -499,9 +499,9 @@ end Orders section BorelSpace -variable [TopologicalSpace α] [MeasurableSpace α] [BorelSpace α] -variable [TopologicalSpace β] [MeasurableSpace β] [BorelSpace β] -variable [MeasurableSpace δ] +variable [TopologicalSpace α] {mα : MeasurableSpace α} [BorelSpace α] +variable [TopologicalSpace β] {mβ : MeasurableSpace β} [BorelSpace β] +variable {mδ : MeasurableSpace δ} section LinearOrder @@ -721,7 +721,7 @@ end LinearOrder section ConditionallyCompleteLattice @[measurability] -theorem Measurable.iSup_Prop {α} [MeasurableSpace α] [ConditionallyCompleteLattice α] +theorem Measurable.iSup_Prop {α} {mα : MeasurableSpace α} [ConditionallyCompleteLattice α] (p : Prop) {f : δ → α} (hf : Measurable f) : Measurable fun b => ⨆ _ : p, f b := by classical simp_rw [ciSup_eq_ite] @@ -730,7 +730,7 @@ theorem Measurable.iSup_Prop {α} [MeasurableSpace α] [ConditionallyCompleteLat · exact measurable_const @[measurability] -theorem Measurable.iInf_Prop {α} [MeasurableSpace α] [ConditionallyCompleteLattice α] +theorem Measurable.iInf_Prop {α} {mα : MeasurableSpace α} [ConditionallyCompleteLattice α] (p : Prop) {f : δ → α} (hf : Measurable f) : Measurable fun b => ⨅ _ : p, f b := by classical simp_rw [ciInf_eq_ite] @@ -923,7 +923,7 @@ section ENNReal /-- One can cut out `ℝ≥0∞` into the sets `{0}`, `Ico (t^n) (t^(n+1))` for `n : ℤ` and `{∞}`. This gives a way to compute the measure of a set in terms of sets on which a given function `f` does not fluctuate by more than `t`. -/ -theorem measure_eq_measure_preimage_add_measure_tsum_Ico_zpow {α : Type*} [MeasurableSpace α] +theorem measure_eq_measure_preimage_add_measure_tsum_Ico_zpow {α : Type*} {mα : MeasurableSpace α} (μ : Measure α) {f : α → ℝ≥0∞} (hf : Measurable f) {s : Set α} (hs : MeasurableSet s) {t : ℝ≥0} (ht : 1 < t) : μ s = diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean index c5fadec87d50e1..2f7ad05237166e 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean @@ -130,7 +130,7 @@ theorem measure_ext_Ioo_rat {μ ν : Measure ℝ} [IsLocallyFiniteMeasure μ] end Real -variable [MeasurableSpace α] +variable {mα : MeasurableSpace α} @[measurability, fun_prop] theorem measurable_real_toNNReal : Measurable Real.toNNReal := @@ -217,7 +217,7 @@ def ennrealEquivSum : ℝ≥0∞ ≃ᵐ ℝ≥0 ⊕ Unit := open Function (uncurry) -theorem measurable_of_measurable_nnreal_prod [MeasurableSpace β] [MeasurableSpace γ] +theorem measurable_of_measurable_nnreal_prod {_ : MeasurableSpace β} {_ : MeasurableSpace γ} {f : ℝ≥0∞ × β → γ} (H₁ : Measurable fun p : ℝ≥0 × β => f (p.1, p.2)) (H₂ : Measurable fun x => f (∞, x)) : Measurable f := let e : ℝ≥0∞ × β ≃ᵐ (ℝ≥0 × β) ⊕ (Unit × β) := @@ -225,7 +225,7 @@ theorem measurable_of_measurable_nnreal_prod [MeasurableSpace β] [MeasurableSpa (MeasurableEquiv.sumProdDistrib _ _ _) e.symm.measurable_comp_iff.1 <| measurable_sum H₁ (H₂.comp measurable_id.snd) -theorem measurable_of_measurable_nnreal_nnreal [MeasurableSpace β] {f : ℝ≥0∞ × ℝ≥0∞ → β} +theorem measurable_of_measurable_nnreal_nnreal {_ : MeasurableSpace β} {f : ℝ≥0∞ × ℝ≥0∞ → β} (h₁ : Measurable fun p : ℝ≥0 × ℝ≥0 => f (p.1, p.2)) (h₂ : Measurable fun r : ℝ≥0 => f (∞, r)) (h₃ : Measurable fun r : ℝ≥0 => f (r, ∞)) : Measurable f := measurable_of_measurable_nnreal_prod @@ -382,8 +382,8 @@ theorem AEMeasurable.ennreal_tsum {ι} [Countable ι] {f : ι → α → ℝ≥0 exact fun s => Finset.aemeasurable_sum s fun i _ => h i @[measurability, fun_prop] -theorem AEMeasurable.nnreal_tsum {α : Type*} [MeasurableSpace α] {ι : Type*} [Countable ι] - {f : ι → α → NNReal} {μ : MeasureTheory.Measure α} (h : ∀ i : ι, AEMeasurable (f i) μ) : +theorem AEMeasurable.nnreal_tsum {α : Type*} {_ : MeasurableSpace α} {ι : Type*} [Countable ι] + {f : ι → α → NNReal} {μ : Measure α} (h : ∀ i : ι, AEMeasurable (f i) μ) : AEMeasurable (fun x : α => ∑' i : ι, f i x) μ := by simp_rw [NNReal.tsum_eq_toNNReal_tsum] exact (AEMeasurable.ennreal_tsum fun i => (h i).coe_nnreal_ennreal).ennreal_toNNReal @@ -470,9 +470,8 @@ end NNReal spanning measurable sets with finite measure on which `f` is bounded. See also `StronglyMeasurable.exists_spanning_measurableSet_norm_le` for functions into normed groups. -/ --- We redeclare `α` to temporarily avoid the `[MeasurableSpace α]` instance. -theorem exists_spanning_measurableSet_le {α : Type*} {m : MeasurableSpace α} {f : α → ℝ≥0} - (hf : Measurable f) (μ : Measure α) [SigmaFinite μ] : +theorem exists_spanning_measurableSet_le {f : α → ℝ≥0} (hf : Measurable f) (μ : Measure α) + [SigmaFinite μ] : ∃ s : ℕ → Set α, (∀ n, MeasurableSet (s n) ∧ μ (s n) < ∞ ∧ ∀ x ∈ s n, f x ≤ n) ∧ ⋃ i, s i = Set.univ := by diff --git a/Mathlib/MeasureTheory/Measure/MeasureSpace.lean b/Mathlib/MeasureTheory/Measure/MeasureSpace.lean index 6068dcd58e2748..7a7ab5f8c32c69 100644 --- a/Mathlib/MeasureTheory/Measure/MeasureSpace.lean +++ b/Mathlib/MeasureTheory/Measure/MeasureSpace.lean @@ -171,7 +171,7 @@ theorem measure_biUnion_finset {s : Finset ι} {f : ι → Set α} (hd : Pairwis /-- The measure of an a.e. disjoint union (even uncountable) of null-measurable sets is at least the sum of the measures of the sets. -/ -theorem tsum_meas_le_meas_iUnion_of_disjoint₀ {ι : Type*} [MeasurableSpace α] (μ : Measure α) +theorem tsum_meas_le_meas_iUnion_of_disjoint₀ {ι : Type*} {_ : MeasurableSpace α} (μ : Measure α) {As : ι → Set α} (As_mble : ∀ i : ι, NullMeasurableSet (As i) μ) (As_disj : Pairwise (AEDisjoint μ on As)) : (∑' i, μ (As i)) ≤ μ (⋃ i, As i) := by rw [ENNReal.tsum_eq_iSup_sum, iSup_le_iff] @@ -182,7 +182,7 @@ theorem tsum_meas_le_meas_iUnion_of_disjoint₀ {ι : Type*} [MeasurableSpace α /-- The measure of a disjoint union (even uncountable) of measurable sets is at least the sum of the measures of the sets. -/ -theorem tsum_meas_le_meas_iUnion_of_disjoint {ι : Type*} [MeasurableSpace α] (μ : Measure α) +theorem tsum_meas_le_meas_iUnion_of_disjoint {ι : Type*} {_ : MeasurableSpace α} (μ : Measure α) {As : ι → Set α} (As_mble : ∀ i : ι, MeasurableSet (As i)) (As_disj : Pairwise (Disjoint on As)) : (∑' i, μ (As i)) ≤ μ (⋃ i, As i) := tsum_meas_le_meas_iUnion_of_disjoint₀ μ (fun i ↦ (As_mble i).nullMeasurableSet) @@ -518,7 +518,7 @@ theorem measure_iInter_eq_iInf [Countable ι] {s : ι → Set α} (h : ∀ i, Nu /-- Continuity from above: the measure of the intersection of a sequence of measurable sets is the infimum of the measures of the partial intersections. -/ -theorem measure_iInter_eq_iInf' {α ι : Type*} [MeasurableSpace α] {μ : Measure α} +theorem measure_iInter_eq_iInf' {α ι : Type*} {_ : MeasurableSpace α} {μ : Measure α} [Countable ι] [Preorder ι] [IsDirected ι (· ≤ ·)] {f : ι → Set α} (h : ∀ i, NullMeasurableSet (f i) μ) (hfin : ∃ i, μ (f i) ≠ ∞) : μ (⋂ i, f i) = ⨅ i, μ (⋂ j ≤ i, f j) := by @@ -560,7 +560,7 @@ theorem tendsto_measure_iUnion_atBot [Preorder ι] [IsCountablyGenerated (atBot sets is the limit of the measures of the partial unions. -/ theorem tendsto_measure_iUnion_accumulate {α ι : Type*} [Preorder ι] [IsCountablyGenerated (atTop : Filter ι)] - [MeasurableSpace α] {μ : Measure α} {f : ι → Set α} : + {_ : MeasurableSpace α} {μ : Measure α} {f : ι → Set α} : Tendsto (fun i ↦ μ (Accumulate f i)) atTop (𝓝 (μ (⋃ i, f i))) := by refine .of_neBot_imp fun h ↦ ?_ have := (atTop_neBot_iff.1 h).2 @@ -582,7 +582,7 @@ theorem tendsto_measure_iInter [Countable ι] [Preorder ι] {s : ι → Set α} /-- Continuity from above: the measure of the intersection of a sequence of measurable sets such that one has finite measure is the limit of the measures of the partial intersections. -/ -theorem tendsto_measure_iInter' {α ι : Type*} [MeasurableSpace α] {μ : Measure α} [Countable ι] +theorem tendsto_measure_iInter' {α ι : Type*} {_ : MeasurableSpace α} {μ : Measure α} [Countable ι] [Preorder ι] [IsDirected ι (· ≤ ·)] {f : ι → Set α} (hm : ∀ i, NullMeasurableSet (f i) μ) (hf : ∃ i, μ (f i) ≠ ∞) : Tendsto (fun i ↦ μ (⋂ j ∈ {j | j ≤ i}, f j)) atTop (𝓝 (μ (⋂ i, f i))) := by @@ -715,7 +715,7 @@ theorem measure_toMeasurable_inter {s t : Set α} (hs : MeasurableSet s) (ht : /-! ### The `ℝ≥0∞`-module of measures -/ -instance instZero [MeasurableSpace α] : Zero (Measure α) := +instance instZero {_ : MeasurableSpace α} : Zero (Measure α) := ⟨{ toOuterMeasure := 0 m_iUnion := fun _f _hf _hd => tsum_zero.symm trim_le := OuterMeasure.trim_zero.le }⟩ @@ -745,10 +745,10 @@ instance instSubsingleton [IsEmpty α] {m : MeasurableSpace α} : Subsingleton ( theorem eq_zero_of_isEmpty [IsEmpty α] {_m : MeasurableSpace α} (μ : Measure α) : μ = 0 := Subsingleton.elim μ 0 -instance instInhabited [MeasurableSpace α] : Inhabited (Measure α) := +instance instInhabited {_ : MeasurableSpace α} : Inhabited (Measure α) := ⟨0⟩ -instance instAdd [MeasurableSpace α] : Add (Measure α) := +instance instAdd {_ : MeasurableSpace α} : Add (Measure α) := ⟨fun μ₁ μ₂ => { toOuterMeasure := μ₁.toOuterMeasure + μ₂.toOuterMeasure m_iUnion := fun s hs hd => @@ -774,7 +774,7 @@ section SMul variable [SMul R ℝ≥0∞] [IsScalarTower R ℝ≥0∞ ℝ≥0∞] variable [SMul R' ℝ≥0∞] [IsScalarTower R' ℝ≥0∞ ℝ≥0∞] -instance instSMul [MeasurableSpace α] : SMul R (Measure α) := +instance instSMul {_ : MeasurableSpace α} : SMul R (Measure α) := ⟨fun c μ => { toOuterMeasure := c • μ.toOuterMeasure m_iUnion := fun s hs hd => by @@ -796,15 +796,15 @@ theorem smul_apply {_m : MeasurableSpace α} (c : R) (μ : Measure α) (s : Set (c • μ) s = c • μ s := rfl -instance instSMulCommClass [SMulCommClass R R' ℝ≥0∞] [MeasurableSpace α] : +instance instSMulCommClass [SMulCommClass R R' ℝ≥0∞] {_ : MeasurableSpace α} : SMulCommClass R R' (Measure α) := ⟨fun _ _ _ => ext fun _ _ => smul_comm _ _ _⟩ -instance instIsScalarTower [SMul R R'] [IsScalarTower R R' ℝ≥0∞] [MeasurableSpace α] : +instance instIsScalarTower [SMul R R'] [IsScalarTower R R' ℝ≥0∞] {_ : MeasurableSpace α} : IsScalarTower R R' (Measure α) := ⟨fun _ _ _ => ext fun _ _ => smul_assoc _ _ _⟩ -instance instIsCentralScalar [SMul Rᵐᵒᵖ ℝ≥0∞] [IsCentralScalar R ℝ≥0∞] [MeasurableSpace α] : +instance instIsCentralScalar [SMul Rᵐᵒᵖ ℝ≥0∞] [IsCentralScalar R ℝ≥0∞] {_ : MeasurableSpace α} : IsCentralScalar R (Measure α) := ⟨fun _ _ => ext fun _ _ => op_smul_eq_smul _ _⟩ @@ -815,10 +815,10 @@ instance instNoZeroSMulDivisors [Zero R] [SMulWithZero R ℝ≥0∞] [IsScalarTo eq_zero_or_eq_zero_of_smul_eq_zero h := by simpa [Ne, ext_iff', forall_or_left] using h instance instMulAction [Monoid R] [MulAction R ℝ≥0∞] [IsScalarTower R ℝ≥0∞ ℝ≥0∞] - [MeasurableSpace α] : MulAction R (Measure α) := + {_ : MeasurableSpace α} : MulAction R (Measure α) := Injective.mulAction _ toOuterMeasure_injective smul_toOuterMeasure -instance instAddCommMonoid [MeasurableSpace α] : AddCommMonoid (Measure α) := +instance instAddCommMonoid {_ : MeasurableSpace α} : AddCommMonoid (Measure α) := toOuterMeasure_injective.addCommMonoid toOuterMeasure zero_toOuterMeasure add_toOuterMeasure fun _ _ => smul_toOuterMeasure _ _ @@ -836,12 +836,12 @@ theorem finset_sum_apply {m : MeasurableSpace α} (I : Finset ι) (μ : ι → M (∑ i ∈ I, μ i) s = ∑ i ∈ I, μ i s := by rw [coe_finset_sum, Finset.sum_apply] instance instDistribMulAction [Monoid R] [DistribMulAction R ℝ≥0∞] [IsScalarTower R ℝ≥0∞ ℝ≥0∞] - [MeasurableSpace α] : DistribMulAction R (Measure α) := + {_ : MeasurableSpace α} : DistribMulAction R (Measure α) := Injective.distribMulAction ⟨⟨toOuterMeasure, zero_toOuterMeasure⟩, add_toOuterMeasure⟩ toOuterMeasure_injective smul_toOuterMeasure -instance instModule [Semiring R] [Module R ℝ≥0∞] [IsScalarTower R ℝ≥0∞ ℝ≥0∞] [MeasurableSpace α] : - Module R (Measure α) := +instance instModule [Semiring R] [Module R ℝ≥0∞] [IsScalarTower R ℝ≥0∞ ℝ≥0∞] + {_ : MeasurableSpace α} : Module R (Measure α) := Injective.module R ⟨⟨toOuterMeasure, zero_toOuterMeasure⟩, add_toOuterMeasure⟩ toOuterMeasure_injective smul_toOuterMeasure @@ -902,7 +902,7 @@ theorem measure_toMeasurable_add_inter_right {s t : Set α} (hs : MeasurableSet /-- Measures are partially ordered. -/ -instance instPartialOrder [MeasurableSpace α] : PartialOrder (Measure α) where +instance instPartialOrder {_ : MeasurableSpace α} : PartialOrder (Measure α) where le m₁ m₂ := ∀ s, m₁ s ≤ m₂ s le_refl _ _ := le_rfl le_trans _ _ _ h₁ h₂ s := le_trans (h₁ s) (h₂ s) @@ -924,7 +924,7 @@ theorem lt_iff : μ < ν ↔ μ ≤ ν ∧ ∃ s, MeasurableSet s ∧ μ s < ν theorem lt_iff' : μ < ν ↔ μ ≤ ν ∧ ∃ s, μ s < ν s := lt_iff_le_not_le.trans <| and_congr Iff.rfl <| by simp only [le_iff', not_forall, not_le] -instance covariantAddLE [MeasurableSpace α] : +instance covariantAddLE {_ : MeasurableSpace α} : CovariantClass (Measure α) (Measure α) (· + ·) (· ≤ ·) := ⟨fun _ν _μ₁ _μ₂ hμ s => add_le_add_left (hμ s) _⟩ @@ -950,7 +950,7 @@ theorem sInf_caratheodory (s : Set α) (hs : MeasurableSet s) : rw [← measure_inter_add_diff u hs] exact add_le_add (hm <| inter_subset_inter_left _ htu) (hm <| diff_subset_diff_left htu) -instance [MeasurableSpace α] : InfSet (Measure α) := +instance {_ : MeasurableSpace α} : InfSet (Measure α) := ⟨fun m => (sInf (toOuterMeasure '' m)).toMeasure <| sInf_caratheodory⟩ theorem sInf_apply (hs : MeasurableSet s) : sInf m s = sInf (toOuterMeasure '' m) s := @@ -965,13 +965,13 @@ private theorem measure_le_sInf (h : ∀ μ' ∈ m, μ ≤ μ') : μ ≤ sInf m le_sInf <| forall_mem_image.2 fun _ hμ ↦ toOuterMeasure_le.2 <| h _ hμ le_iff.2 fun s hs => by rw [sInf_apply hs]; exact this s -instance instCompleteSemilatticeInf [MeasurableSpace α] : CompleteSemilatticeInf (Measure α) := +instance instCompleteSemilatticeInf {_ : MeasurableSpace α} : CompleteSemilatticeInf (Measure α) := { (by infer_instance : PartialOrder (Measure α)), (by infer_instance : InfSet (Measure α)) with sInf_le := fun _s _a => measure_sInf_le le_sInf := fun _s _a => measure_le_sInf } -instance instCompleteLattice [MeasurableSpace α] : CompleteLattice (Measure α) := +instance instCompleteLattice {_ : MeasurableSpace α} : CompleteLattice (Measure α) := { completeLatticeOfCompleteSemilatticeInf (Measure α) with top := { toOuterMeasure := ⊤, @@ -997,7 +997,7 @@ theorem _root_.MeasureTheory.OuterMeasure.toMeasure_top : toOuterMeasure_toMeasure (μ := ⊤) @[simp] -theorem toOuterMeasure_top [MeasurableSpace α] : +theorem toOuterMeasure_top {_ : MeasurableSpace α} : (⊤ : Measure α).toOuterMeasure = (⊤ : OuterMeasure α) := rfl @@ -1235,7 +1235,7 @@ def comapₗ [MeasurableSpace α] (f : α → β) : Measure β →ₗ[ℝ≥0∞ exact hf.2 s hs else 0 -theorem comapₗ_apply {β} [MeasurableSpace α] {mβ : MeasurableSpace β} (f : α → β) +theorem comapₗ_apply {β} {_ : MeasurableSpace α} {mβ : 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] @@ -1253,35 +1253,35 @@ def comap [MeasurableSpace α] (f : α → β) (μ : Measure β) : Measure α := exact (measure_inter_add_diff₀ _ (hf.2 s hs)).symm else 0 -theorem comap_apply₀ [MeasurableSpace α] (f : α → β) (μ : Measure β) (hfi : Injective f) +theorem comap_apply₀ {_ : MeasurableSpace α} (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 [toMeasure_apply₀ _ _ hs, OuterMeasure.comap_apply, coe_toOuterMeasure] -theorem le_comap_apply {β} [MeasurableSpace α] {mβ : MeasurableSpace β} (f : α → β) (μ : Measure β) - (hfi : Injective f) (hf : ∀ s, MeasurableSet s → NullMeasurableSet (f '' s) μ) (s : Set α) : - μ (f '' s) ≤ comap f μ s := by +theorem le_comap_apply {β} {_ : MeasurableSpace α} {mβ : MeasurableSpace β} (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)] exact le_toMeasure_apply _ _ _ -theorem comap_apply {β} [MeasurableSpace α] {_mβ : MeasurableSpace β} (f : α → β) +theorem comap_apply {β} {_ : MeasurableSpace α} {_mβ : MeasurableSpace β} (f : α → β) (hfi : Injective f) (hf : ∀ s, MeasurableSet s → MeasurableSet (f '' s)) (μ : Measure β) (hs : MeasurableSet s) : comap f μ s = μ (f '' s) := comap_apply₀ f μ hfi (fun s hs => (hf s hs).nullMeasurableSet) hs.nullMeasurableSet -theorem comapₗ_eq_comap {β} [MeasurableSpace α] {_mβ : MeasurableSpace β} (f : α → β) +theorem comapₗ_eq_comap {β} {_ : MeasurableSpace α} {_mβ : MeasurableSpace β} (f : α → β) (hfi : Injective f) (hf : ∀ s, MeasurableSet s → MeasurableSet (f '' s)) (μ : Measure β) (hs : MeasurableSet s) : comapₗ f μ s = comap f μ s := (comapₗ_apply f hfi hf μ hs).trans (comap_apply f hfi hf μ hs).symm -theorem measure_image_eq_zero_of_comap_eq_zero {β} [MeasurableSpace α] {_mβ : MeasurableSpace β} +theorem measure_image_eq_zero_of_comap_eq_zero {β} {_ : MeasurableSpace α} {_mβ : MeasurableSpace β} (f : α → β) (μ : Measure β) (hfi : Injective f) (hf : ∀ s, MeasurableSet s → NullMeasurableSet (f '' s) μ) {s : Set α} (hs : comap f μ s = 0) : μ (f '' s) = 0 := le_antisymm ((le_comap_apply f μ hfi hf s).trans hs.le) (zero_le _) -theorem ae_eq_image_of_ae_eq_comap {β} [MeasurableSpace α] {mβ : MeasurableSpace β} (f : α → β) +theorem ae_eq_image_of_ae_eq_comap {β} {_ : MeasurableSpace α} {mβ : MeasurableSpace β} (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 rw [EventuallyEq, ae_iff] at hst ⊢ @@ -1298,7 +1298,7 @@ theorem ae_eq_image_of_ae_eq_comap {β} [MeasurableSpace α] {mβ : MeasurableSp rw [h_eq_α] at hst exact measure_image_eq_zero_of_comap_eq_zero f μ hfi hf hst -theorem NullMeasurableSet.image {β} [MeasurableSpace α] {mβ : MeasurableSpace β} (f : α → β) +theorem NullMeasurableSet.image {β} {_ : MeasurableSpace α} {mβ : MeasurableSpace β} (f : α → β) (μ : Measure β) (hfi : Injective f) (hf : ∀ s, MeasurableSet s → NullMeasurableSet (f '' s) μ) {s : Set α} (hs : NullMeasurableSet s (μ.comap f)) : NullMeasurableSet (f '' s) μ := by refine ⟨toMeasurable μ (f '' toMeasurable (μ.comap f) s), measurableSet_toMeasurable _ _, ?_⟩ @@ -1309,8 +1309,8 @@ theorem NullMeasurableSet.image {β} [MeasurableSpace α] {mβ : MeasurableSpace NullMeasurableSet.toMeasurable_ae_eq hs exact ae_eq_image_of_ae_eq_comap f μ hfi hf h.symm -theorem comap_preimage {β} [MeasurableSpace α] {mβ : MeasurableSpace β} (f : α → β) (μ : Measure β) - {s : Set β} (hf : Injective f) (hf' : Measurable f) +theorem comap_preimage {β} {_ : MeasurableSpace α} {mβ : MeasurableSpace β} (f : α → β) + (μ : Measure β) {s : Set β} (hf : Injective f) (hf' : Measurable f) (h : ∀ t, MeasurableSet t → NullMeasurableSet (f '' t) μ) (hs : MeasurableSet s) : μ.comap f (f ⁻¹' s) = μ (s ∩ range f) := by rw [comap_apply₀ _ _ hf h (hf' hs).nullMeasurableSet, image_preimage_eq_inter_range] @@ -1483,7 +1483,7 @@ protected theorem refl {_m0 : MeasurableSpace α} (μ : Measure α) : μ ≪ μ protected theorem rfl : μ ≪ μ := fun _s hs => hs -instance instIsRefl [MeasurableSpace α] : IsRefl (Measure α) (· ≪ ·) := +instance instIsRefl {_ : MeasurableSpace α} : IsRefl (Measure α) (· ≪ ·) := ⟨fun _ => AbsolutelyContinuous.rfl⟩ @[simp] @@ -1706,7 +1706,7 @@ theorem exists_preimage_eq_of_preimage_ae {f : α → α} (h : QuasiMeasurePrese open Pointwise @[to_additive] -theorem smul_ae_eq_of_ae_eq {G α : Type*} [Group G] [MulAction G α] [MeasurableSpace α] +theorem smul_ae_eq_of_ae_eq {G α : Type*} [Group G] [MulAction G α] {_ : MeasurableSpace α} {s t : Set α} {μ : Measure α} (g : G) (h_qmp : QuasiMeasurePreserving (g⁻¹ • · : α → α) μ μ) (h_ae_eq : s =ᵐ[μ] t) : (g • s : Set α) =ᵐ[μ] (g • t : Set α) := by @@ -1720,7 +1720,7 @@ open Pointwise @[to_additive] theorem pairwise_aedisjoint_of_aedisjoint_forall_ne_one {G α : Type*} [Group G] [MulAction G α] - [MeasurableSpace α] {μ : Measure α} {s : Set α} + {_ : MeasurableSpace α} {μ : Measure α} {s : Set α} (h_ae_disjoint : ∀ g ≠ (1 : G), AEDisjoint μ (g • s) s) (h_qmp : ∀ g : G, QuasiMeasurePreserving (g • ·) μ μ) : Pairwise (AEDisjoint μ on fun g : G => g • s) := by @@ -1934,7 +1934,7 @@ namespace MeasurableEquiv open Equiv MeasureTheory.Measure -variable [MeasurableSpace α] [MeasurableSpace β] {μ : Measure α} {ν : Measure β} +variable {_ : MeasurableSpace α} [MeasurableSpace β] {μ : Measure α} {ν : Measure β} /-- If we map a measure along a measurable equivalence, we can compute the measure on all sets (not just the measurable ones). -/ From d3d1be67abff029258750868b89b1cfa8b22b3a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Wed, 16 Oct 2024 14:07:05 +0000 Subject: [PATCH 233/425] feat: post-composing independent random variables (#17811) From PFR --- Mathlib/Probability/Independence/Basic.lean | 5 +++++ Mathlib/Probability/Independence/Kernel.lean | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/Mathlib/Probability/Independence/Basic.lean b/Mathlib/Probability/Independence/Basic.lean index cf6f2aebad8a93..cfa5d0c19e7b76 100644 --- a/Mathlib/Probability/Independence/Basic.lean +++ b/Mathlib/Probability/Independence/Basic.lean @@ -563,6 +563,11 @@ theorem iIndepFun_iff_measure_inter_preimage_eq_mul {ι : Type*} {β : ι → Ty alias ⟨iIndepFun.measure_inter_preimage_eq_mul, _⟩ := iIndepFun_iff_measure_inter_preimage_eq_mul +nonrec lemma iIndepFun.comp {β γ : ι → Type*} {mβ : ∀ i, MeasurableSpace (β i)} + {mγ : ∀ i, MeasurableSpace (γ i)} {f : ∀ i, Ω → β i} + (h : iIndepFun mβ f μ) (g : ∀ i, β i → γ i) (hg : ∀ i, Measurable (g i)) : + iIndepFun mγ (fun i ↦ g i ∘ f i) μ := h.comp _ hg + theorem indepFun_iff_indepSet_preimage {mβ : MeasurableSpace β} {mβ' : MeasurableSpace β'} [IsZeroOrProbabilityMeasure μ] (hf : Measurable f) (hg : Measurable g) : IndepFun f g μ ↔ diff --git a/Mathlib/Probability/Independence/Kernel.lean b/Mathlib/Probability/Independence/Kernel.lean index 6986bae0a89f3e..cf48a19edc3394 100644 --- a/Mathlib/Probability/Independence/Kernel.lean +++ b/Mathlib/Probability/Independence/Kernel.lean @@ -907,6 +907,17 @@ theorem iIndepFun_iff_measure_inter_preimage_eq_mul {ι : Type*} {β : ι → Ty alias ⟨iIndepFun.measure_inter_preimage_eq_mul, _⟩ := iIndepFun_iff_measure_inter_preimage_eq_mul +lemma iIndepFun.comp {β γ : ι → Type*} {mβ : ∀ i, MeasurableSpace (β i)} + {mγ : ∀ i, MeasurableSpace (γ i)} {f : ∀ i, Ω → β i} + (h : iIndepFun mβ f κ μ) (g : ∀ i, β i → γ i) (hg : ∀ i, Measurable (g i)) : + iIndepFun mγ (fun i ↦ g i ∘ f i) κ μ := by + rw [iIndepFun_iff_measure_inter_preimage_eq_mul] at h ⊢ + refine fun t s hs ↦ ?_ + have := h t (sets := fun i ↦ g i ⁻¹' (s i)) (fun i a ↦ hg i (hs i a)) + filter_upwards [this] with a ha + simp_rw [Set.preimage_comp] + exact ha + theorem indepFun_iff_indepSet_preimage {mβ : MeasurableSpace β} {mβ' : MeasurableSpace β'} [IsZeroOrMarkovKernel κ] (hf : Measurable f) (hg : Measurable g) : IndepFun f g κ μ ↔ From a818532749203501896bb16bfdb4187e965cd8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Wed, 16 Oct 2024 14:07:07 +0000 Subject: [PATCH 234/425] =?UTF-8?q?feat(Kernel):=20`=CE=BA.comap=20g=20=3D?= =?UTF-8?q?=20=CE=BA=20=E2=88=98=20g`=20(#17823)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From GibbsMeasure --- Mathlib/Probability/Kernel/Composition.lean | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mathlib/Probability/Kernel/Composition.lean b/Mathlib/Probability/Kernel/Composition.lean index aa3839f4407e93..7fbfe68d509e19 100644 --- a/Mathlib/Probability/Kernel/Composition.lean +++ b/Mathlib/Probability/Kernel/Composition.lean @@ -663,6 +663,9 @@ def comap (κ : Kernel α β) (g : γ → α) (hg : Measurable g) : Kernel γ β toFun a := κ (g a) measurable' := κ.measurable.comp hg +@[simp, norm_cast] +lemma coe_comap (κ : Kernel α β) (g : γ → α) (hg : Measurable g) : κ.comap g hg = κ ∘ g := rfl + theorem comap_apply (κ : Kernel α β) (hg : Measurable g) (c : γ) : comap κ g hg c = κ (g c) := rfl From 617ce534454a10c7a537bf470ff7a2f77163e113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Wed, 16 Oct 2024 14:29:59 +0000 Subject: [PATCH 235/425] chore(MeasureTheory): let `gcongr` know about `spanningSets` (#17824) From GibbsMeasure --- Mathlib/MeasureTheory/Measure/Typeclasses.lean | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Mathlib/MeasureTheory/Measure/Typeclasses.lean b/Mathlib/MeasureTheory/Measure/Typeclasses.lean index e84781a13f0595..5dc07c2bfba726 100644 --- a/Mathlib/MeasureTheory/Measure/Typeclasses.lean +++ b/Mathlib/MeasureTheory/Measure/Typeclasses.lean @@ -668,6 +668,10 @@ def spanningSets (μ : Measure α) [SigmaFinite μ] (i : ℕ) : Set α := theorem monotone_spanningSets (μ : Measure α) [SigmaFinite μ] : Monotone (spanningSets μ) := monotone_accumulate +@[gcongr] +lemma spanningSets_mono [SigmaFinite μ] {m n : ℕ} (hmn : m ≤ n) : + spanningSets μ m ⊆ spanningSets μ n := monotone_spanningSets _ hmn + theorem measurable_spanningSets (μ : Measure α) [SigmaFinite μ] (i : ℕ) : MeasurableSet (spanningSets μ i) := MeasurableSet.iUnion fun j => MeasurableSet.iUnion fun _ => μ.toFiniteSpanningSetsIn.set_mem j @@ -676,6 +680,7 @@ theorem measure_spanningSets_lt_top (μ : Measure α) [SigmaFinite μ] (i : ℕ) μ (spanningSets μ i) < ∞ := measure_biUnion_lt_top (finite_le_nat i) fun j _ => μ.toFiniteSpanningSetsIn.finite j +@[simp] theorem iUnion_spanningSets (μ : Measure α) [SigmaFinite μ] : ⋃ i : ℕ, spanningSets μ i = univ := by simp_rw [spanningSets, iUnion_accumulate, μ.toFiniteSpanningSetsIn.spanning] From edc37a1b204745492894deeb385aaf66c0540beb Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Wed, 16 Oct 2024 14:44:33 +0000 Subject: [PATCH 236/425] chore: remove porting notes about deprecation / "not used" (#17821) These deprecated/commented-out declarations are not going to return, and if we do want to deprecate something we have a much nicer infrastructure using the `@[deprecated]` attribute. It's also been a long time since the port, so we can now just delete the remaining porting notes. Closes: #11229 --- Mathlib/Algebra/Category/Semigrp/Basic.lean | 1 - Mathlib/Algebra/GCDMonoid/Multiset.lean | 3 --- Mathlib/Analysis/InnerProductSpace/Projection.lean | 1 - Mathlib/Computability/PartrecCode.lean | 1 - Mathlib/Computability/Primrec.lean | 8 -------- Mathlib/Data/NNRat/Defs.lean | 4 ---- Mathlib/Data/Vector/Basic.lean | 6 ------ Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean | 1 - Mathlib/SetTheory/Game/Short.lean | 3 --- 9 files changed, 28 deletions(-) diff --git a/Mathlib/Algebra/Category/Semigrp/Basic.lean b/Mathlib/Algebra/Category/Semigrp/Basic.lean index a9305e7dd672d8..d30f2b19f232e6 100644 --- a/Mathlib/Algebra/Category/Semigrp/Basic.lean +++ b/Mathlib/Algebra/Category/Semigrp/Basic.lean @@ -44,7 +44,6 @@ namespace MagmaCat @[to_additive] instance bundledHom : BundledHom @MulHom := ⟨@MulHom.toFun, @MulHom.id, @MulHom.comp, - -- Porting note: was `@MulHom.coe_inj` which is deprecated by intros; apply @DFunLike.coe_injective, by aesop_cat, by aesop_cat⟩ -- Porting note: deriving failed for `ConcreteCategory`, diff --git a/Mathlib/Algebra/GCDMonoid/Multiset.lean b/Mathlib/Algebra/GCDMonoid/Multiset.lean index ea5a208bda10a5..4bbe0597cd14b4 100644 --- a/Mathlib/Algebra/GCDMonoid/Multiset.lean +++ b/Mathlib/Algebra/GCDMonoid/Multiset.lean @@ -199,9 +199,6 @@ theorem extract_gcd' (s t : Multiset α) (hs : ∃ x, x ∈ s ∧ x ≠ (0 : α) contrapose! hs exact s.gcd_eq_zero_iff.1 hs -/- Porting note: Deprecated lemmas like `map_repeat` and `eq_repeat` weren't "officially" -converted to `Multiset.replicate` format yet, so I made some ad hoc ones in `Data.Multiset.Basic` -using the originals. -/ /- Porting note: The old proof used a strange form `have := _, refine ⟨s.pmap @f (fun _ ↦ id), this, extract_gcd' s _ h this⟩,` so I rearranged the proof slightly. -/ diff --git a/Mathlib/Analysis/InnerProductSpace/Projection.lean b/Mathlib/Analysis/InnerProductSpace/Projection.lean index 28ef290eefc609..6edcc178e0c8e1 100644 --- a/Mathlib/Analysis/InnerProductSpace/Projection.lean +++ b/Mathlib/Analysis/InnerProductSpace/Projection.lean @@ -621,7 +621,6 @@ section reflection variable [HasOrthogonalProjection K] --- Porting note: `bit0` is deprecated. /-- Auxiliary definition for `reflection`: the reflection as a linear equivalence. -/ def reflectionLinearEquiv : E ≃ₗ[𝕜] E := LinearEquiv.ofInvolutive diff --git a/Mathlib/Computability/PartrecCode.lean b/Mathlib/Computability/PartrecCode.lean index 77e572cb6f2a63..723eb31bfc2bee 100644 --- a/Mathlib/Computability/PartrecCode.lean +++ b/Mathlib/Computability/PartrecCode.lean @@ -109,7 +109,6 @@ protected def id : Code := def curry (c : Code) (n : ℕ) : Code := comp c (pair (Code.const n) Code.id) --- Porting note: `bit0` and `bit1` are deprecated. /-- An encoding of a `Nat.Partrec.Code` as a ℕ. -/ def encodeCode : Code → ℕ | zero => 0 diff --git a/Mathlib/Computability/Primrec.lean b/Mathlib/Computability/Primrec.lean index 17cbe2ce38bec5..3defa207c49ee2 100644 --- a/Mathlib/Computability/Primrec.lean +++ b/Mathlib/Computability/Primrec.lean @@ -706,20 +706,12 @@ theorem nat_bodd : Primrec Nat.bodd := theorem nat_div2 : Primrec Nat.div2 := (nat_div.comp .id (const 2)).of_eq fun n => n.div2_val.symm --- Porting note: this is no longer used --- theorem nat_boddDiv2 : Primrec Nat.boddDiv2 := pair nat_bodd nat_div2 - --- Porting note: bit0 is deprecated theorem nat_double : Primrec (fun n : ℕ => 2 * n) := nat_mul.comp (const _) Primrec.id --- Porting note: bit1 is deprecated theorem nat_double_succ : Primrec (fun n : ℕ => 2 * n + 1) := nat_double |> Primrec.succ.comp --- Porting note: this is no longer used --- theorem nat_div_mod : Primrec₂ fun n k : ℕ => (n / k, n % k) := pair nat_div nat_mod - end Primrec section diff --git a/Mathlib/Data/NNRat/Defs.lean b/Mathlib/Data/NNRat/Defs.lean index 2c17c0c61fcc18..00cb00c61e5065 100644 --- a/Mathlib/Data/NNRat/Defs.lean +++ b/Mathlib/Data/NNRat/Defs.lean @@ -127,8 +127,6 @@ theorem coe_mul (p q : ℚ≥0) : ((p * q : ℚ≥0) : ℚ) = p * q := @[simp] lemma num_pow (q : ℚ≥0) (n : ℕ) : (q ^ n).num = q.num ^ n := by simp [num, Int.natAbs_pow] @[simp] lemma den_pow (q : ℚ≥0) (n : ℕ) : (q ^ n).den = q.den ^ n := rfl --- Porting note: `bit0` `bit1` are deprecated, so remove these theorems. - @[simp, norm_cast] theorem coe_sub (h : q ≤ p) : ((p - q : ℚ≥0) : ℚ) = p - q := max_eq_left <| le_sub_comm.2 <| by rwa [sub_zero] @@ -287,8 +285,6 @@ 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 --- Porting note: `bit0` `bit1` are deprecated, so remove these theorems. - 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, max_eq_left, mul_nonneg] diff --git a/Mathlib/Data/Vector/Basic.lean b/Mathlib/Data/Vector/Basic.lean index 14362f975a7191..67059f9ba1cbd2 100644 --- a/Mathlib/Data/Vector/Basic.lean +++ b/Mathlib/Data/Vector/Basic.lean @@ -73,12 +73,6 @@ theorem mk_toList : ∀ (v : Vector α n) (h), (⟨toList v, h⟩ : Vector α n) @[simp] theorem length_val (v : Vector α n) : v.val.length = n := v.2 --- Porting note: not used in mathlib and coercions done differently in Lean 4 --- @[simp] --- theorem length_coe (v : Vector α n) : --- ((coe : { l : List α // l.length = n } → List α) v).length = n := --- v.2 - @[simp] theorem toList_map {β : Type*} (v : Vector α n) (f : α → β) : (v.map f).toList = v.toList.map f := by cases v; rfl diff --git a/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean b/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean index 6669bfc8d8d210..61c97a1f0113b2 100644 --- a/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean +++ b/Mathlib/GroupTheory/FreeGroup/NielsenSchreier.lean @@ -121,7 +121,6 @@ instance actionGroupoidIsFree {G A : Type u} [Group G] [IsFreeGroup G] [MulActio rcases IsFreeGroup.unique_lift f' with ⟨F', hF', uF'⟩ refine ⟨uncurry F' ?_, ?_, ?_⟩ · suffices SemidirectProduct.rightHom.comp F' = MonoidHom.id _ by - -- Porting note: `MonoidHom.ext_iff` has been deprecated. exact DFunLike.ext_iff.mp this apply IsFreeGroup.ext_hom (fun x ↦ ?_) rw [MonoidHom.comp_apply, hF'] diff --git a/Mathlib/SetTheory/Game/Short.lean b/Mathlib/SetTheory/Game/Short.lean index 03c8ecbda2c5ba..37fa7839716d3f 100644 --- a/Mathlib/SetTheory/Game/Short.lean +++ b/Mathlib/SetTheory/Game/Short.lean @@ -219,11 +219,8 @@ instance shortNat : ∀ n : ℕ, Short n instance shortOfNat (n : ℕ) [Nat.AtLeastTwo n] : Short (no_index (OfNat.ofNat n)) := shortNat n --- Porting note: `bit0` and `bit1` are deprecated so these instances can probably be removed. -set_option linter.deprecated false in instance shortBit0 (x : PGame.{u}) [Short x] : Short (x + x) := by infer_instance -set_option linter.deprecated false in instance shortBit1 (x : PGame.{u}) [Short x] : Short ((x + x) + 1) := shortAdd _ _ /-- Auxiliary construction of decidability instances. From 2ec6c3d15fc6dec388a4b7817b2a7cee9757ab79 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Wed, 16 Oct 2024 14:44:35 +0000 Subject: [PATCH 237/425] chore: remove some `attribute [irreducible]` that don't seem to help much (#17829) This attribute doesn't seem to impact performance, so remove it and the associated porting note. --- Mathlib/AlgebraicTopology/DoldKan/GammaCompN.lean | 9 --------- Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean | 9 --------- 2 files changed, 18 deletions(-) diff --git a/Mathlib/AlgebraicTopology/DoldKan/GammaCompN.lean b/Mathlib/AlgebraicTopology/DoldKan/GammaCompN.lean index 8b92fd134e5711..b6025650b82bb0 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/GammaCompN.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/GammaCompN.lean @@ -101,9 +101,6 @@ theorem N₁Γ₀_inv_app_f_f (K : ChainComplex C ℕ) (n : ℕ) : rw [N₁Γ₀_inv_app] apply id_comp --- Porting note (#10694): added to speed up elaboration -attribute [irreducible] N₁Γ₀ - /-- Compatibility isomorphism between `toKaroubi _ ⋙ Γ₂ ⋙ N₂` and `Γ₀ ⋙ N₁` which are functors `ChainComplex C ℕ ⥤ Karoubi (ChainComplex C ℕ)`. -/ def N₂Γ₂ToKaroubiIso : toKaroubi (ChainComplex C ℕ) ⋙ Γ₂ ⋙ N₂ ≅ Γ₀ ⋙ N₁ := @@ -142,9 +139,6 @@ lemma N₂Γ₂ToKaroubiIso_inv_app (X : ChainComplex C ℕ) : rw [Splitting.ι_desc] erw [comp_id, id_comp] --- Porting note (#10694): added to speed up elaboration -attribute [irreducible] N₂Γ₂ToKaroubiIso - /-- The counit isomorphism of the Dold-Kan equivalence for additive categories. -/ def N₂Γ₂ : Γ₂ ⋙ N₂ ≅ 𝟭 (Karoubi (ChainComplex C ℕ)) := ((whiskeringLeft _ _ _).obj (toKaroubi (ChainComplex C ℕ))).preimageIso @@ -173,9 +167,6 @@ lemma whiskerLeft_toKaroubi_N₂Γ₂_hom : dsimp only [whiskeringLeft, N₂Γ₂, Functor.preimageIso] at h ⊢ exact h --- Porting note (#10694): added to speed up elaboration -attribute [irreducible] N₂Γ₂ - theorem N₂Γ₂_compatible_with_N₁Γ₀ (K : ChainComplex C ℕ) : N₂Γ₂.hom.app ((toKaroubi _).obj K) = N₂Γ₂ToKaroubiIso.hom.app K ≫ N₁Γ₀.hom.app K := congr_app whiskerLeft_toKaroubi_N₂Γ₂_hom K diff --git a/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean b/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean index 1e25732cfa5339..a62ceb55bcb32f 100644 --- a/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean +++ b/Mathlib/AlgebraicTopology/DoldKan/NCompGamma.lean @@ -157,9 +157,6 @@ def natTrans : (N₁ : SimplicialObject C ⥤ _) ⋙ Γ₂ ⟶ toKaroubi _ where HomologicalComplex.comp_f, AlternatingFaceMapComplex.map_f, PInfty_f_naturality_assoc, NatTrans.naturality, Splitting.IndexSet.id_fst, unop_op, len_mk] --- Porting note (#10694): added to speed up elaboration -attribute [irreducible] natTrans - end Γ₂N₁ -- Porting note: removed @[simps] attribute because it was creating timeouts @@ -177,9 +174,6 @@ lemma Γ₂N₂ToKaroubiIso_inv_app (X : SimplicialObject C) : Γ₂N₂ToKaroubiIso.inv.app X = Γ₂.map (toKaroubiCompN₂IsoN₁.inv.app X) := by simp [Γ₂N₂ToKaroubiIso] --- Porting note (#10694): added to speed up elaboration -attribute [irreducible] Γ₂N₂ToKaroubiIso - namespace Γ₂N₂ /-- The natural transformation `N₂ ⋙ Γ₂ ⟶ 𝟭 (SimplicialObject C)`. -/ @@ -194,9 +188,6 @@ theorem natTrans_app_f_app (P : Karoubi (SimplicialObject C)) : dsimp only [natTrans] simp only [whiskeringLeft_obj_preimage_app, Functor.id_map, assoc] --- Porting note (#10694): added to speed up elaboration -attribute [irreducible] natTrans - end Γ₂N₂ theorem compatibility_Γ₂N₁_Γ₂N₂_natTrans (X : SimplicialObject C) : From a54be302d6fd476755ef0d77c2e4b3a7768e9c9c Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Wed, 16 Oct 2024 14:44:36 +0000 Subject: [PATCH 238/425] chore: clean up "slow" or "speedup" porting notes (#17832) Fix and remove the porting notes that don't apply anymore (for example, if `count_heartbeats` says it's an order of magnitude or more under the heartbeat limit). --- Mathlib/Algebra/DirectSum/Ring.lean | 11 +--- Mathlib/Algebra/GCDMonoid/Basic.lean | 3 - Mathlib/Algebra/Lie/Weights/Cartan.lean | 2 - Mathlib/Combinatorics/Hindman.lean | 3 +- Mathlib/Data/Quot.lean | 10 ---- Mathlib/FieldTheory/Minpoly/Field.lean | 2 - Mathlib/GroupTheory/GroupAction/ConjAct.lean | 58 +++++--------------- Mathlib/LinearAlgebra/QuotientPi.lean | 1 - Mathlib/Topology/Homotopy/HomotopyGroup.lean | 3 +- Mathlib/Topology/Metrizable/Uniformity.lean | 1 - 10 files changed, 19 insertions(+), 75 deletions(-) diff --git a/Mathlib/Algebra/DirectSum/Ring.lean b/Mathlib/Algebra/DirectSum/Ring.lean index 39d62eca17f6e7..b68930289ac050 100644 --- a/Mathlib/Algebra/DirectSum/Ring.lean +++ b/Mathlib/Algebra/DirectSum/Ring.lean @@ -222,7 +222,6 @@ private nonrec theorem one_mul (x : ⨁ i, A i) : 1 * x = x := by rw [mulHom_of_of] exact of_eq_of_gradedMonoid_eq (one_mul <| GradedMonoid.mk i xi) --- Porting note (#11083): `suffices` is very slow here. private nonrec theorem mul_one (x : ⨁ i, A i) : x * 1 = x := by suffices (mulHom A).flip One.one = AddMonoidHom.id (⨁ i, A i) from DFunLike.congr_fun this x apply addHom_ext; intro i xi @@ -230,17 +229,13 @@ private nonrec theorem mul_one (x : ⨁ i, A i) : x * 1 = x := by rw [flip_apply, mulHom_of_of] exact of_eq_of_gradedMonoid_eq (mul_one <| GradedMonoid.mk i xi) -/- Porting note: Some auxiliary statements were needed in the proof of the `suffices`, -otherwise would timeout -/ private theorem mul_assoc (a b c : ⨁ i, A i) : a * b * c = a * (b * c) := by -- (`fun a b c => a * b * c` as a bundled hom) = (`fun a b c => a * (b * c)` as a bundled hom) suffices (mulHom A).compHom.comp (mulHom A) = (AddMonoidHom.compHom flipHom <| (mulHom A).flip.compHom.comp (mulHom A)).flip by - have sol := DFunLike.congr_fun (DFunLike.congr_fun (DFunLike.congr_fun this a) b) c - have aux : ∀ a b, (mulHom A) a b = a * b := fun _ _ ↦ rfl - simp only [coe_comp, Function.comp_apply, AddMonoidHom.compHom_apply_apply, aux, flip_apply, - AddMonoidHom.flipHom_apply] at sol - exact sol + simpa only [coe_comp, Function.comp_apply, AddMonoidHom.compHom_apply_apply, flip_apply, + AddMonoidHom.flipHom_apply] + using DFunLike.congr_fun (DFunLike.congr_fun (DFunLike.congr_fun this a) b) c ext ai ax bi bx ci cx dsimp only [coe_comp, Function.comp_apply, AddMonoidHom.compHom_apply_apply, flip_apply, AddMonoidHom.flipHom_apply] diff --git a/Mathlib/Algebra/GCDMonoid/Basic.lean b/Mathlib/Algebra/GCDMonoid/Basic.lean index e0744b9bcc73a4..1eb20199e470b4 100644 --- a/Mathlib/Algebra/GCDMonoid/Basic.lean +++ b/Mathlib/Algebra/GCDMonoid/Basic.lean @@ -89,7 +89,6 @@ variable [CancelCommMonoidWithZero α] [NormalizationMonoid α] theorem normUnit_one : normUnit (1 : α) = 1 := normUnit_coe_units 1 --- Porting note (#11083): quite slow. Improve performance? /-- Chooses an element of each associate class, by multiplying by `normUnit` -/ def normalize : α →*₀ α where toFun x := x * normUnit x @@ -1112,7 +1111,6 @@ noncomputable def gcdMonoidOfLCM [DecidableEq α] (lcm : α → α → α) rw [mul_comm, mul_dvd_mul_iff_right h_1.2] apply ac } --- Porting note (#11083): very slow; improve performance? /-- Define `NormalizedGCDMonoid` on a structure just from the `lcm` and its properties. -/ noncomputable def normalizedGCDMonoidOfLCM [NormalizationMonoid α] [DecidableEq α] (lcm : α → α → α) (dvd_lcm_left : ∀ a b, a ∣ lcm a b) (dvd_lcm_right : ∀ a b, b ∣ lcm a b) @@ -1252,7 +1250,6 @@ namespace CommGroupWithZero variable (G₀ : Type*) [CommGroupWithZero G₀] [DecidableEq G₀] --- Porting note (#11083): very slow; improve performance? -- see Note [lower instance priority] instance (priority := 100) : NormalizedGCDMonoid G₀ where normUnit x := if h : x = 0 then 1 else (Units.mk0 x h)⁻¹ diff --git a/Mathlib/Algebra/Lie/Weights/Cartan.lean b/Mathlib/Algebra/Lie/Weights/Cartan.lean index 0ef812f460f9e3..e494e0e19ba5d7 100644 --- a/Mathlib/Algebra/Lie/Weights/Cartan.lean +++ b/Mathlib/Algebra/Lie/Weights/Cartan.lean @@ -105,8 +105,6 @@ def rootSpaceWeightSpaceProductAux {χ₁ χ₂ χ₃ : H → R} (hχ : χ₁ + simp only [SetLike.val_smul, smul_lie, LinearMap.coe_mk, AddHom.coe_mk, LinearMap.smul_apply, SetLike.mk_smul_mk] --- Porting note (#11083): this def is _really_ slow --- See https://github.com/leanprover-community/mathlib4/issues/5028 /-- Given a nilpotent Lie subalgebra `H ⊆ L` together with `χ₁ χ₂ : H → R`, there is a natural `R`-bilinear product of root vectors and weight vectors, compatible with the actions of `H`. -/ def rootSpaceWeightSpaceProduct (χ₁ χ₂ χ₃ : H → R) (hχ : χ₁ + χ₂ = χ₃) : diff --git a/Mathlib/Combinatorics/Hindman.lean b/Mathlib/Combinatorics/Hindman.lean index 18555bba2e0801..25e45662baf0d7 100644 --- a/Mathlib/Combinatorics/Hindman.lean +++ b/Mathlib/Combinatorics/Hindman.lean @@ -66,8 +66,7 @@ def Ultrafilter.semigroup {M} [Semigroup M] : Semigroup (Ultrafilter M) := { Ultrafilter.mul with mul_assoc := fun U V W => Ultrafilter.coe_inj.mp <| - -- porting note (#11083): `simp` was slow to typecheck, replaced by `simp_rw` - Filter.ext' fun p => by simp_rw [Ultrafilter.eventually_mul, mul_assoc] } + Filter.ext' fun p => by simp [Ultrafilter.eventually_mul, mul_assoc] } attribute [local instance] Ultrafilter.semigroup Ultrafilter.addSemigroup diff --git a/Mathlib/Data/Quot.lean b/Mathlib/Data/Quot.lean index a6769d8795ab8e..8f524efb7730bb 100644 --- a/Mathlib/Data/Quot.lean +++ b/Mathlib/Data/Quot.lean @@ -109,7 +109,6 @@ theorem liftOn_mk (a : α) (f : α → γ) (h : ∀ a₁ a₂, r a₁ a₂ → f ⟨fun hf => hf.comp Quot.exists_rep, fun hf y => let ⟨x, hx⟩ := hf y; ⟨Quot.mk _ x, hx⟩⟩ /-- Descends a function `f : α → β → γ` to quotients of `α` and `β`. -/ --- porting note (#11083): removed `@[reducible]` because it caused extremely slow `simp` protected def lift₂ (f : α → β → γ) (hr : ∀ a b₁ b₂, s b₁ b₂ → f a b₁ = f a b₂) (hs : ∀ a₁ a₂ b, r a₁ a₂ → f a₁ b = f a₂ b) (q₁ : Quot r) (q₂ : Quot s) : γ := Quot.lift (fun a ↦ Quot.lift (f a) (hr a)) @@ -122,7 +121,6 @@ theorem lift₂_mk (f : α → β → γ) (hr : ∀ a b₁ b₂, s b₁ b₂ → rfl /-- Descends a function `f : α → β → γ` to quotients of `α` and `β` and applies it. -/ --- porting note (#11083): removed `@[reducible]` because it caused extremely slow `simp` protected def liftOn₂ (p : Quot r) (q : Quot s) (f : α → β → γ) (hr : ∀ a b₁ b₂, s b₁ b₂ → f a b₁ = f a b₂) (hs : ∀ a₁ a₂ b, r a₁ a₂ → f a₁ b = f a₂ b) : γ := Quot.lift₂ f hr hs p q @@ -149,7 +147,6 @@ theorem map₂_mk (f : α → β → γ) (hr : ∀ a b₁ b₂, s b₁ b₂ → rfl /-- A binary version of `Quot.recOnSubsingleton`. -/ --- porting note (#11083): removed `@[reducible]` because it caused extremely slow `simp` @[elab_as_elim] protected def recOnSubsingleton₂ {φ : Quot r → Quot s → Sort*} [h : ∀ a b, Subsingleton (φ ⟦a⟧ ⟦b⟧)] (q₁ : Quot r) @@ -449,7 +446,6 @@ protected theorem lift_mk (f : α → β) (c) (a : α) : lift f c (mk a) = f a : rfl /-- Lift a constant function on `q : Trunc α`. -/ --- porting note (#11083): removed `@[reducible]` because it caused extremely slow `simp` protected def liftOn (q : Trunc α) (f : α → β) (c : ∀ a b : α, f a = f b) : β := lift f c q @@ -498,7 +494,6 @@ instance : LawfulMonad Trunc where variable {C : Trunc α → Sort*} /-- Recursion/induction principle for `Trunc`. -/ --- porting note (#11083): removed `@[reducible]` because it caused extremely slow `simp` @[elab_as_elim] protected def rec (f : ∀ a, C (mk a)) (h : ∀ a b : α, (Eq.ndrec (f a) (Trunc.eq (mk a) (mk b)) : C (mk b)) = f b) @@ -506,14 +501,12 @@ protected def rec (f : ∀ a, C (mk a)) Quot.rec f (fun a b _ ↦ h a b) q /-- A version of `Trunc.rec` taking `q : Trunc α` as the first argument. -/ --- porting note (#11083): removed `@[reducible]` because it caused extremely slow `simp` @[elab_as_elim] protected def recOn (q : Trunc α) (f : ∀ a, C (mk a)) (h : ∀ a b : α, (Eq.ndrec (f a) (Trunc.eq (mk a) (mk b)) : C (mk b)) = f b) : C q := Trunc.rec f h q /-- A version of `Trunc.recOn` assuming the codomain is a `Subsingleton`. -/ --- porting note (#11083)s: removed `@[reducible]` because it caused extremely slow `simp` @[elab_as_elim] protected def recOnSubsingleton [∀ a, Subsingleton (C (mk a))] (q : Trunc α) (f : ∀ a, C (mk a)) : C q := @@ -557,7 +550,6 @@ theorem surjective_Quotient_mk'' : Function.Surjective (Quotient.mk'' : α → Q /-- A version of `Quotient.liftOn` taking `{s : Setoid α}` as an implicit argument instead of an instance argument. -/ --- porting note (#11083): removed `@[reducible]` because it caused extremely slow `simp` protected def liftOn' (q : Quotient s₁) (f : α → φ) (h : ∀ a b, s₁ a b → f a = f b) : φ := Quotient.liftOn q f h @@ -573,7 +565,6 @@ protected theorem liftOn'_mk'' (f : α → φ) (h) (x : α) : /-- A version of `Quotient.liftOn₂` taking `{s₁ : Setoid α} {s₂ : Setoid β}` as implicit arguments instead of instance arguments. -/ --- porting note (#11083): removed `@[reducible]` because it caused extremely slow `simp` protected def liftOn₂' (q₁ : Quotient s₁) (q₂ : Quotient s₂) (f : α → β → γ) (h : ∀ a₁ a₂ b₁ b₂, s₁ a₁ b₁ → s₂ a₂ b₂ → f a₁ a₂ = f b₁ b₂) : γ := Quotient.liftOn₂ q₁ q₂ f h @@ -632,7 +623,6 @@ protected def recOnSubsingleton' {φ : Quotient s₁ → Sort*} [∀ a, Subsingl /-- A version of `Quotient.recOnSubsingleton₂` taking `{s₁ : Setoid α} {s₂ : Setoid α}` as implicit arguments instead of instance arguments. -/ --- porting note (#11083): removed `@[reducible]` because it caused extremely slow `simp` @[elab_as_elim] protected def recOnSubsingleton₂' {φ : Quotient s₁ → Quotient s₂ → Sort*} [∀ a b, Subsingleton (φ ⟦a⟧ ⟦b⟧)] diff --git a/Mathlib/FieldTheory/Minpoly/Field.lean b/Mathlib/FieldTheory/Minpoly/Field.lean index b129b8a0ecbc57..ad3c581e77e1ed 100644 --- a/Mathlib/FieldTheory/Minpoly/Field.lean +++ b/Mathlib/FieldTheory/Minpoly/Field.lean @@ -179,8 +179,6 @@ noncomputable def Fintype.subtypeProd {E : Type*} {X : Set E} (hX : X.Finite) {L variable (F E K : Type*) [Field F] [Ring E] [CommRing K] [IsDomain K] [Algebra F E] [Algebra F K] [FiniteDimensional F E] --- Porting note (#11083): removed `noncomputable!` since it seems not to be slow in lean 4, --- though it isn't very computable in practice (since neither `finrank` nor `finBasis` are). /-- Function from Hom_K(E,L) to pi type Π (x : basis), roots of min poly of x -/ def rootsOfMinPolyPiType (φ : E →ₐ[F] K) (x : range (Module.finBasis F E : _ → E)) : diff --git a/Mathlib/GroupTheory/GroupAction/ConjAct.lean b/Mathlib/GroupTheory/GroupAction/ConjAct.lean index c1d499828409fb..1f5c561c568efb 100644 --- a/Mathlib/GroupTheory/GroupAction/ConjAct.lean +++ b/Mathlib/GroupTheory/GroupAction/ConjAct.lean @@ -146,18 +146,11 @@ instance unitsScalar : SMul (ConjAct Mˣ) M where smul g h := ofConjAct g * h * theorem units_smul_def (g : ConjAct Mˣ) (h : M) : g • h = ofConjAct g * h * ↑(ofConjAct g)⁻¹ := rfl --- porting note (#11083): very slow without `simp only` and need to separate `units_smul_def` --- so that things trigger appropriately instance unitsMulDistribMulAction : MulDistribMulAction (ConjAct Mˣ) M where - one_smul := by simp only [units_smul_def, ofConjAct_one, Units.val_one, one_mul, inv_one, - mul_one, forall_const] - mul_smul := by - simp only [units_smul_def] - simp only [map_mul, Units.val_mul, mul_assoc, mul_inv_rev, forall_const, «forall»] - smul_mul := by - simp only [units_smul_def] - simp only [mul_assoc, Units.inv_mul_cancel_left, forall_const, «forall»] - smul_one := by simp [units_smul_def, mul_one, Units.mul_inv, «forall», forall_const] + one_smul := by simp [units_smul_def] + mul_smul := by simp [units_smul_def, mul_assoc] + smul_mul := by simp [units_smul_def, mul_assoc] + smul_one := by simp [units_smul_def] instance unitsSMulCommClass [SMul α M] [SMulCommClass α M M] [IsScalarTower α M M] : @@ -175,15 +168,10 @@ section Semiring variable [Semiring R] --- porting note (#11083): very slow without `simp only` and need to separate `units_smul_def` --- so that things trigger appropriately instance unitsMulSemiringAction : MulSemiringAction (ConjAct Rˣ) R := { ConjAct.unitsMulDistribMulAction with - smul_zero := by - simp only [units_smul_def, mul_zero, zero_mul, «forall», forall_const] - smul_add := by - simp only [units_smul_def] - simp only [mul_add, add_mul, forall_const, «forall»] } + smul_zero := by simp [units_smul_def] + smul_add := by simp [units_smul_def, mul_add, add_mul] } end Semiring @@ -201,15 +189,9 @@ theorem ofConjAct_zero : ofConjAct (0 : ConjAct G₀) = 0 := theorem toConjAct_zero : toConjAct (0 : G₀) = 0 := rfl --- porting note (#11083): very slow without `simp only` and need to separate `smul_def` --- so that things trigger appropriately instance mulAction₀ : MulAction (ConjAct G₀) G₀ where - one_smul := by - simp only [smul_def] - simp only [map_one, one_mul, inv_one, mul_one, forall_const] - mul_smul := by - simp only [smul_def] - simp only [map_mul, mul_assoc, mul_inv_rev, forall_const, «forall»] + one_smul := by simp [smul_def] + mul_smul := by simp [smul_def, mul_assoc] instance smulCommClass₀ [SMul α G₀] [SMulCommClass α G₀ G₀] [IsScalarTower α G₀ G₀] : SMulCommClass α (ConjAct G₀) G₀ where @@ -226,16 +208,10 @@ section DivisionRing variable [DivisionRing K] --- porting note (#11083): very slow without `simp only` and need to separate `smul_def` --- so that things trigger appropriately instance distribMulAction₀ : DistribMulAction (ConjAct K) K := { ConjAct.mulAction₀ with - smul_zero := by - simp only [smul_def] - simp only [mul_zero, zero_mul, «forall», forall_const] - smul_add := by - simp only [smul_def] - simp only [mul_add, add_mul, forall_const, «forall»] } + smul_zero := by simp [smul_def] + smul_add := by simp [smul_def, mul_add, add_mul] } end DivisionRing @@ -243,17 +219,11 @@ variable [Group G] -- todo: this file is not in good order; I will refactor this after the PR --- porting note (#11083): very slow without `simp only` and need to separate `smul_def` --- so that things trigger appropriately instance : MulDistribMulAction (ConjAct G) G where - smul_mul := by - simp only [smul_def] - simp only [mul_assoc, inv_mul_cancel_left, forall_const, «forall»] - smul_one := by simp only [smul_def, mul_one, mul_inv_cancel, «forall», forall_const] - one_smul := by simp only [smul_def, ofConjAct_one, one_mul, inv_one, mul_one, forall_const] - mul_smul := by - simp only [smul_def] - simp only [map_mul, mul_assoc, mul_inv_rev, forall_const, «forall»] + smul_mul := by simp [smul_def] + smul_one := by simp [smul_def] + one_smul := by simp [smul_def] + mul_smul := by simp [smul_def, mul_assoc] instance smulCommClass [SMul α G] [SMulCommClass α G G] [IsScalarTower α G G] : SMulCommClass α (ConjAct G) G where diff --git a/Mathlib/LinearAlgebra/QuotientPi.lean b/Mathlib/LinearAlgebra/QuotientPi.lean index e4771d9be3c91b..103b03974aa55c 100644 --- a/Mathlib/LinearAlgebra/QuotientPi.lean +++ b/Mathlib/LinearAlgebra/QuotientPi.lean @@ -69,7 +69,6 @@ theorem quotientPiLift_mk (p : ∀ i, Submodule R (Ms i)) (f : ∀ i, Ms i → quotientPiLift p f hf (Quotient.mk x) = fun i => f i (x i) := rfl --- Porting note (#11083): split up the definition to avoid timeouts. Still slow. namespace quotientPi_aux variable (p : ∀ i, Submodule R (Ms i)) diff --git a/Mathlib/Topology/Homotopy/HomotopyGroup.lean b/Mathlib/Topology/Homotopy/HomotopyGroup.lean index daaa41db02500f..fac80ea72c6068 100644 --- a/Mathlib/Topology/Homotopy/HomotopyGroup.lean +++ b/Mathlib/Topology/Homotopy/HomotopyGroup.lean @@ -248,7 +248,7 @@ def homotopyTo (i : N) {p q : Ω^ N X x} (H : p.1.HomotopyRel q.1 (Cube.boundary ((⟨_, ContinuousMap.continuous_curry⟩ : C(_, _)).comp <| (cCompInsert i).comp H.toContinuousMap.curry).uncurry --- porting note (#11083): `@[simps]` no longer too slow in Lean 4 but does not generate this lemma. +-- porting note: `@[simps]` generates this lemma but it's named `homotopyTo_apply_apply` instead theorem homotopyTo_apply (i : N) {p q : Ω^ N X x} (H : p.1.HomotopyRel q.1 <| Cube.boundary N) (t : I × I) (tₙ : I^{ j // j ≠ i }) : homotopyTo i H t tₙ = H (t.fst, Cube.insertAt i (t.snd, tₙ)) := @@ -276,7 +276,6 @@ theorem homotopicTo (i : N) {p q : Ω^ N X x} : (ContinuousMap.comp ⟨_, ContinuousMap.continuous_uncurry⟩ (ContinuousMap.comp ⟨Subtype.val, by continuity⟩ H.toContinuousMap).curry).uncurry.comp <| (ContinuousMap.id I).prodMap (Cube.splitAt i).toContinuousMap --- porting note (#11083): @[simps!] no longer too slow in Lean 4. theorem homotopicFrom (i : N) {p q : Ω^ N X x} : (toLoop i p).Homotopic (toLoop i q) → Homotopic p q := by diff --git a/Mathlib/Topology/Metrizable/Uniformity.lean b/Mathlib/Topology/Metrizable/Uniformity.lean index 3aaa2860dcb661..c4bd746dd6f0d7 100644 --- a/Mathlib/Topology/Metrizable/Uniformity.lean +++ b/Mathlib/Topology/Metrizable/Uniformity.lean @@ -173,7 +173,6 @@ theorem le_two_mul_dist_ofPreNNDist (d : X → X → ℝ≥0) (dist_self : ∀ x end PseudoMetricSpace --- Porting note (#11083): this is slower than in Lean3 for some reason... /-- If `X` is a uniform space with countably generated uniformity filter, there exists a `PseudoMetricSpace` structure compatible with the `UniformSpace` structure. Use `UniformSpace.pseudoMetricSpace` or `UniformSpace.metricSpace` instead. -/ From 0b07d2aeefb43ce191fcf685dbdc36baf22e714a Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Wed, 16 Oct 2024 15:23:29 +0000 Subject: [PATCH 239/425] chore: classify porting notes about `ext` (#17809) I checked all porting notes mentioning `ext` and either fixed them (see #17810), or classified them as * #5229 if it's a new `@[ext]` lemma * #11041 if it's a regression in `ext` * #11182 if `@[ext]` had to be removed This PR should contain only modifications to comments. --- .../Category/ModuleCat/Adjunctions.lean | 2 +- .../Algebra/Homology/HomologicalComplex.lean | 2 +- Mathlib/Algebra/Lie/DirectSum.lean | 24 +++++++++---------- Mathlib/Algebra/MonoidAlgebra/Basic.lean | 10 ++++---- Mathlib/Algebra/MonoidAlgebra/Defs.lean | 12 +++++----- Mathlib/Algebra/MonoidAlgebra/Division.lean | 14 +++++------ .../Algebra/MonoidAlgebra/ToDirectSum.lean | 2 +- Mathlib/Algebra/MvPolynomial/Basic.lean | 4 ++-- Mathlib/Algebra/Polynomial/Laurent.lean | 2 +- Mathlib/AlgebraicGeometry/Restrict.lean | 4 ++-- Mathlib/AlgebraicGeometry/Spec.lean | 2 +- .../AlgebraicTopology/SimplexCategory.lean | 2 +- .../SplitSimplicialObject.lean | 2 +- .../Abelian/Pseudoelements.lean | 2 +- .../NaturalTransformation/Oplax.lean | 2 +- Mathlib/CategoryTheory/Closed/Functor.lean | 4 ++-- Mathlib/CategoryTheory/Comma/Basic.lean | 2 +- Mathlib/CategoryTheory/Elements.lean | 2 +- Mathlib/CategoryTheory/Endomorphism.lean | 2 +- Mathlib/CategoryTheory/Functor/Category.lean | 2 +- .../CategoryTheory/Idempotents/Karoubi.lean | 2 +- Mathlib/CategoryTheory/Iso.lean | 8 +++---- Mathlib/CategoryTheory/Limits/Cones.lean | 4 ++-- .../Limits/Shapes/Biproducts.lean | 4 ++-- .../Limits/Shapes/Multiequalizer.lean | 2 +- Mathlib/CategoryTheory/Monoidal/Bimod.lean | 2 +- .../Monoidal/Braided/Basic.lean | 4 ++-- Mathlib/CategoryTheory/Monoidal/Center.lean | 6 ++--- .../Monoidal/Internal/Module.lean | 10 ++++---- Mathlib/CategoryTheory/Monoidal/Mon_.lean | 2 +- .../Monoidal/NaturalTransformation.lean | 2 +- Mathlib/CategoryTheory/Pi/Basic.lean | 2 +- Mathlib/CategoryTheory/Sites/Pretopology.lean | 2 +- Mathlib/CategoryTheory/Sites/Sheaf.lean | 2 +- Mathlib/Data/PFunctor/Univariate/M.lean | 2 +- .../Geometry/RingedSpace/OpenImmersion.lean | 8 +++---- .../PresheafedSpace/HasColimits.lean | 2 +- .../Category/OmegaCompletePartialOrder.lean | 6 ++--- .../RepresentationTheory/Action/Basic.lean | 2 +- .../DedekindDomain/FiniteAdeleRing.lean | 4 ++-- Mathlib/Topology/Category/CompHaus/Basic.lean | 6 ++--- .../Topology/Category/Profinite/AsLimit.lean | 3 ++- .../Category/TopCat/Limits/Products.lean | 2 +- .../Topology/Sheaves/PresheafOfFunctions.lean | 2 +- 44 files changed, 94 insertions(+), 93 deletions(-) diff --git a/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean b/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean index c45921b738acdc..2abebe30399c0a 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean @@ -369,7 +369,7 @@ def embeddingLiftIso (F : C ⥤ D) : embedding R C ⋙ lift R F ≅ F := /-- Two `R`-linear functors out of the `R`-linear completion are isomorphic iff their compositions with the embedding functor are isomorphic. -/ --- Porting note: used to be @[ext] +-- Porting note (#11182): used to be @[ext] def ext {F G : Free R C ⥤ D} [F.Additive] [F.Linear R] [G.Additive] [G.Linear R] (α : embedding R C ⋙ F ≅ embedding R C ⋙ G) : F ≅ G := NatIso.ofComponents (fun X => α.app X) diff --git a/Mathlib/Algebra/Homology/HomologicalComplex.lean b/Mathlib/Algebra/Homology/HomologicalComplex.lean index 0b0c05b2019edb..6ea13712672bd3 100644 --- a/Mathlib/Algebra/Homology/HomologicalComplex.lean +++ b/Mathlib/Algebra/Homology/HomologicalComplex.lean @@ -244,7 +244,7 @@ instance : Category (HomologicalComplex V c) where end --- Porting note: added because `Hom.ext` is not triggered automatically +-- Porting note (#5229): added because `Hom.ext` is not triggered automatically @[ext] lemma hom_ext {C D : HomologicalComplex V c} (f g : C ⟶ D) (h : ∀ i, f.f i = g.f i) : f = g := by diff --git a/Mathlib/Algebra/Lie/DirectSum.lean b/Mathlib/Algebra/Lie/DirectSum.lean index d6222f0c9db3e3..830fec1d310b73 100644 --- a/Mathlib/Algebra/Lie/DirectSum.lean +++ b/Mathlib/Algebra/Lie/DirectSum.lean @@ -43,13 +43,13 @@ variable [∀ i, LieRingModule L (M i)] [∀ i, LieModule R L (M i)] instance : LieRingModule L (⨁ i, M i) where bracket x m := m.mapRange (fun _ m' => ⁅x, m'⁆) fun _ => lie_zero x add_lie x y m := by - refine DFinsupp.ext fun _ => ?_ -- Porting note: Originally `ext` + refine DFinsupp.ext fun _ => ?_ -- Porting note (#11041): Originally `ext` simp only [mapRange_apply, add_apply, add_lie] lie_add x m n := by - refine DFinsupp.ext fun _ => ?_ -- Porting note: Originally `ext` + refine DFinsupp.ext fun _ => ?_ -- Porting note (#11041): Originally `ext` simp only [mapRange_apply, add_apply, lie_add] leibniz_lie x y m := by - refine DFinsupp.ext fun _ => ?_ -- Porting note: Originally `ext` + refine DFinsupp.ext fun _ => ?_ -- Porting note (#11041): Originally `ext` simp only [mapRange_apply, lie_lie, add_apply, sub_add_cancel] @[simp] @@ -58,10 +58,10 @@ theorem lie_module_bracket_apply (x : L) (m : ⨁ i, M i) (i : ι) : ⁅x, m⁆ instance : LieModule R L (⨁ i, M i) where smul_lie t x m := by - refine DFinsupp.ext fun _ => ?_ -- Porting note: Originally `ext i` + refine DFinsupp.ext fun _ => ?_ -- Porting note (#11041): Originally `ext i` simp only [smul_lie, lie_module_bracket_apply, smul_apply] lie_smul t x m := by - refine DFinsupp.ext fun _ => ?_ -- Porting note: Originally `ext i` + refine DFinsupp.ext fun _ => ?_ -- Porting note (#11041): Originally `ext i` simp only [lie_smul, lie_module_bracket_apply, smul_apply] variable (R ι L M) @@ -70,7 +70,7 @@ variable (R ι L M) def lieModuleOf [DecidableEq ι] (j : ι) : M j →ₗ⁅R,L⁆ ⨁ i, M i := { lof R ι M j with map_lie' := fun {x m} => by - refine DFinsupp.ext fun i => ?_ -- Porting note: Originally `ext i` + refine DFinsupp.ext fun i => ?_ -- Porting note (#11041): Originally `ext i` by_cases h : j = i · rw [← h]; simp · -- This used to be the end of the proof before leanprover/lean4#2644 @@ -98,16 +98,16 @@ instance lieRing : LieRing (⨁ i, L i) := { (inferInstance : AddCommGroup _) with bracket := zipWith (fun _ => fun x y => ⁅x, y⁆) fun _ => lie_zero 0 add_lie := fun x y z => by - refine DFinsupp.ext fun _ => ?_ -- Porting note: Originally `ext` + refine DFinsupp.ext fun _ => ?_ -- Porting note (#11041): Originally `ext` simp only [zipWith_apply, add_apply, add_lie] lie_add := fun x y z => by - refine DFinsupp.ext fun _ => ?_ -- Porting note: Originally `ext` + refine DFinsupp.ext fun _ => ?_ -- Porting note (#11041): Originally `ext` simp only [zipWith_apply, add_apply, lie_add] lie_self := fun x => by - refine DFinsupp.ext fun _ => ?_ -- Porting note: Originally `ext` + refine DFinsupp.ext fun _ => ?_ -- Porting note (#11041): Originally `ext` simp only [zipWith_apply, add_apply, lie_self, zero_apply] leibniz_lie := fun x y z => by - refine DFinsupp.ext fun _ => ?_ -- Porting note: Originally `ext` + refine DFinsupp.ext fun _ => ?_ -- Porting note (#11041): Originally `ext` simp only [sub_apply, zipWith_apply, add_apply, zero_apply] apply leibniz_lie } @@ -137,7 +137,7 @@ theorem lie_of [DecidableEq ι] {i j : ι} (x : L i) (y : L j) : instance lieAlgebra : LieAlgebra R (⨁ i, L i) := { (inferInstance : Module R _) with lie_smul := fun c x y => by - refine DFinsupp.ext fun _ => ?_ -- Porting note: Originally `ext` + refine DFinsupp.ext fun _ => ?_ -- Porting note (#11041): Originally `ext` simp only [zipWith_apply, smul_apply, bracket_apply, lie_smul] } variable (R ι) @@ -148,7 +148,7 @@ def lieAlgebraOf [DecidableEq ι] (j : ι) : L j →ₗ⁅R⁆ ⨁ i, L i := { lof R ι L j with toFun := of L j map_lie' := fun {x y} => by - refine DFinsupp.ext fun i => ?_ -- Porting note: Originally `ext i` + refine DFinsupp.ext fun i => ?_ -- Porting note (#11041): Originally `ext i` by_cases h : j = i · rw [← h] -- This used to be the end of the proof before leanprover/lean4#2644 diff --git a/Mathlib/Algebra/MonoidAlgebra/Basic.lean b/Mathlib/Algebra/MonoidAlgebra/Basic.lean index c859345b543ca3..9eb40ad475be09 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Basic.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Basic.lean @@ -90,7 +90,7 @@ def liftMagma [Module k A] [IsScalarTower k A A] [SMulCommClass k A A] : sum_single_index, Function.comp_apply, one_smul, zero_smul, MulHom.coe_comp, NonUnitalAlgHom.coe_to_mulHom] right_inv F := by - -- Porting note: `ext` → `refine nonUnitalAlgHom_ext' k (MulHom.ext fun m => ?_)` + -- Porting note (#11041): `ext` → `refine nonUnitalAlgHom_ext' k (MulHom.ext fun m => ?_)` refine nonUnitalAlgHom_ext' k (MulHom.ext fun m => ?_) simp only [NonUnitalAlgHom.coe_mk, ofMagma_apply, NonUnitalAlgHom.toMulHom_eq_coe, sum_single_index, Function.comp_apply, one_smul, zero_smul, MulHom.coe_comp, @@ -109,7 +109,7 @@ In particular this provides the instance `Algebra k (MonoidAlgebra k G)`. instance algebra {A : Type*} [CommSemiring k] [Semiring A] [Algebra k A] [Monoid G] : Algebra k (MonoidAlgebra A G) := { singleOneRingHom.comp (algebraMap k A) with - -- Porting note: `ext` → `refine Finsupp.ext fun _ => ?_` + -- Porting note (#11041): `ext` → `refine Finsupp.ext fun _ => ?_` smul_def' := fun r a => by refine Finsupp.ext fun _ => ?_ -- Porting note: Newly required. @@ -125,7 +125,7 @@ def singleOneAlgHom {A : Type*} [CommSemiring k] [Semiring A] [Algebra k A] [Mon A →ₐ[k] MonoidAlgebra A G := { singleOneRingHom with commutes' := fun r => by - -- Porting note: `ext` → `refine Finsupp.ext fun _ => ?_` + -- Porting note (#11041): `ext` → `refine Finsupp.ext fun _ => ?_` refine Finsupp.ext fun _ => ?_ simp rfl } @@ -390,7 +390,7 @@ In particular this provides the instance `Algebra k k[G]`. instance algebra [CommSemiring R] [Semiring k] [Algebra R k] [AddMonoid G] : Algebra R k[G] := { singleZeroRingHom.comp (algebraMap R k) with - -- Porting note: `ext` → `refine Finsupp.ext fun _ => ?_` + -- Porting note (#11041): `ext` → `refine Finsupp.ext fun _ => ?_` smul_def' := fun r a => by refine Finsupp.ext fun _ => ?_ -- Porting note: Newly required. @@ -405,7 +405,7 @@ instance algebra [CommSemiring R] [Semiring k] [Algebra R k] [AddMonoid G] : def singleZeroAlgHom [CommSemiring R] [Semiring k] [Algebra R k] [AddMonoid G] : k →ₐ[R] k[G] := { singleZeroRingHom with commutes' := fun r => by - -- Porting note: `ext` → `refine Finsupp.ext fun _ => ?_` + -- Porting note (#11041): `ext` → `refine Finsupp.ext fun _ => ?_` refine Finsupp.ext fun _ => ?_ simp rfl } diff --git a/Mathlib/Algebra/MonoidAlgebra/Defs.lean b/Mathlib/Algebra/MonoidAlgebra/Defs.lean index a2574ffe76219d..d7cde54dca7006 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Defs.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Defs.lean @@ -563,7 +563,7 @@ theorem liftNC_smul [MulOneClass G] {R : Type*} [Semiring R] (f : k →+* R) (g suffices (liftNC (↑f) g).comp (smulAddHom k (MonoidAlgebra k G) c) = (AddMonoidHom.mulLeft (f c)).comp (liftNC (↑f) g) from DFunLike.congr_fun this φ - -- Porting note: `ext` couldn't a find appropriate theorem. + -- Porting note (#11041): `ext` couldn't a find appropriate theorem. refine addHom_ext' fun a => AddMonoidHom.ext fun b => ?_ -- Porting note: `reducible` cannot be `local` so the proof gets more complex. unfold MonoidAlgebra @@ -584,7 +584,7 @@ variable (k) [Semiring k] [DistribSMul R k] [Mul G] instance isScalarTower_self [IsScalarTower R k k] : IsScalarTower R (MonoidAlgebra k G) (MonoidAlgebra k G) := ⟨fun t a b => by - -- Porting note: `ext` → `refine Finsupp.ext fun _ => ?_` + -- Porting note (#11041): `ext` → `refine Finsupp.ext fun _ => ?_` refine Finsupp.ext fun m => ?_ -- Porting note: `refine` & `rw` are required because `simp` behaves differently. classical @@ -600,7 +600,7 @@ also commute with the algebra multiplication. -/ instance smulCommClass_self [SMulCommClass R k k] : SMulCommClass R (MonoidAlgebra k G) (MonoidAlgebra k G) := ⟨fun t a b => by - -- Porting note: `ext` → `refine Finsupp.ext fun _ => ?_` + -- Porting note (#11041): `ext` → `refine Finsupp.ext fun _ => ?_` refine Finsupp.ext fun m => ?_ -- Porting note: `refine` & `rw` are required because `simp` behaves differently. classical @@ -742,7 +742,7 @@ protected noncomputable def opRingEquiv [Monoid G] : rw [← AddEquiv.coe_toAddMonoidHom] refine Iff.mpr (AddMonoidHom.map_mul_iff (R := (MonoidAlgebra k G)ᵐᵒᵖ) (S := MonoidAlgebra kᵐᵒᵖ Gᵐᵒᵖ) _) ?_ - -- Porting note: Was `ext`. + -- Porting note (#11041): Was `ext`. refine AddMonoidHom.mul_op_ext _ _ <| addHom_ext' fun i₁ => AddMonoidHom.ext fun r₁ => AddMonoidHom.mul_op_ext _ _ <| addHom_ext' fun i₂ => AddMonoidHom.ext fun r₂ => ?_ -- Porting note: `reducible` cannot be `local` so proof gets long. @@ -924,7 +924,7 @@ instance nonUnitalNonAssocSemiring : NonUnitalNonAssocSemiring k[G] := simp only [mul_def] exact Eq.trans (congr_arg (sum f) (funext₂ fun a₁ b₁ => sum_zero_index)) sum_zero nsmul := fun n f => n • f - -- Porting note: `ext` → `refine Finsupp.ext fun _ => ?_` + -- Porting note (#11041): `ext` → `refine Finsupp.ext fun _ => ?_` nsmul_zero := by intros refine Finsupp.ext fun _ => ?_ @@ -1399,7 +1399,7 @@ protected noncomputable def opRingEquiv [AddCommMonoid G] : rw [Equiv.toFun_as_coe, AddEquiv.toEquiv_eq_coe]; erw [AddEquiv.coe_toEquiv] rw [← AddEquiv.coe_toAddMonoidHom] refine Iff.mpr (AddMonoidHom.map_mul_iff (R := k[G]ᵐᵒᵖ) (S := kᵐᵒᵖ[G]) _) ?_ - -- Porting note: Was `ext`. + -- Porting note (#11041): Was `ext`. refine AddMonoidHom.mul_op_ext _ _ <| addHom_ext' fun i₁ => AddMonoidHom.ext fun r₁ => AddMonoidHom.mul_op_ext _ _ <| addHom_ext' fun i₂ => AddMonoidHom.ext fun r₂ => ?_ -- Porting note: `reducible` cannot be `local` so proof gets long. diff --git a/Mathlib/Algebra/MonoidAlgebra/Division.lean b/Mathlib/Algebra/MonoidAlgebra/Division.lean index 3eb1337dc20172..42c2c79cdba87f 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Division.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Division.lean @@ -69,14 +69,14 @@ theorem zero_divOf (g : G) : (0 : k[G]) /ᵒᶠ g = 0 := @[simp] theorem divOf_zero (x : k[G]) : x /ᵒᶠ 0 = x := by - refine Finsupp.ext fun _ => ?_ -- Porting note: `ext` doesn't work + refine Finsupp.ext fun _ => ?_ -- Porting note (#11041): `ext` doesn't work simp only [AddMonoidAlgebra.divOf_apply, zero_add] theorem add_divOf (x y : k[G]) (g : G) : (x + y) /ᵒᶠ g = x /ᵒᶠ g + y /ᵒᶠ g := map_add (Finsupp.comapDomain.addMonoidHom _) _ _ theorem divOf_add (x : k[G]) (a b : G) : x /ᵒᶠ (a + b) = x /ᵒᶠ a /ᵒᶠ b := by - refine Finsupp.ext fun _ => ?_ -- Porting note: `ext` doesn't work + refine Finsupp.ext fun _ => ?_ -- Porting note (#11041): `ext` doesn't work simp only [AddMonoidAlgebra.divOf_apply, add_assoc] /-- A bundled version of `AddMonoidAlgebra.divOf`. -/ @@ -93,13 +93,13 @@ 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 - refine Finsupp.ext fun _ => ?_ -- Porting note: `ext` doesn't work + refine Finsupp.ext fun _ => ?_ -- Porting note (#11041): `ext` doesn't work rw [AddMonoidAlgebra.divOf_apply, of'_apply, single_mul_apply_aux, one_mul] intro c exact add_right_inj _ theorem mul_of'_divOf (x : k[G]) (a : G) : x * of' k G a /ᵒᶠ a = x := by - refine Finsupp.ext fun _ => ?_ -- Porting note: `ext` doesn't work + refine Finsupp.ext fun _ => ?_ -- Porting note (#11041): `ext` doesn't work rw [AddMonoidAlgebra.divOf_apply, of'_apply, mul_single_apply_aux, mul_one] intro c rw [add_comm] @@ -134,14 +134,14 @@ theorem modOf_apply_self_add (x : k[G]) (g : G) (d : G) : (x %ᵒᶠ g) (g + d) modOf_apply_of_exists_add _ _ _ ⟨_, rfl⟩ theorem of'_mul_modOf (g : G) (x : k[G]) : of' k G g * x %ᵒᶠ g = 0 := by - refine Finsupp.ext fun g' => ?_ -- Porting note: `ext g'` doesn't work + refine Finsupp.ext fun g' => ?_ -- Porting note (#11041): `ext g'` doesn't work rw [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, single_mul_apply_of_not_exists_add _ _ h] theorem mul_of'_modOf (x : k[G]) (g : G) : x * of' k G g %ᵒᶠ g = 0 := by - refine Finsupp.ext fun g' => ?_ -- Porting note: `ext g'` doesn't work + refine Finsupp.ext fun g' => ?_ -- Porting note (#11041): `ext g'` doesn't work rw [Finsupp.zero_apply] obtain ⟨d, rfl⟩ | h := em (∃ d, g' = g + d) · rw [modOf_apply_self_add] @@ -153,7 +153,7 @@ theorem of'_modOf (g : G) : of' k G g %ᵒᶠ g = 0 := by theorem divOf_add_modOf (x : k[G]) (g : G) : of' k G g * (x /ᵒᶠ g) + x %ᵒᶠ g = x := by - refine Finsupp.ext fun g' => ?_ -- Porting note: `ext` doesn't work + refine Finsupp.ext fun g' => ?_ -- Porting note (#11041): `ext` doesn't work rw [Finsupp.add_apply] -- Porting note: changed from `simp_rw` which can't see through the type obtain ⟨d, rfl⟩ | h := em (∃ d, g' = g + d) swap diff --git a/Mathlib/Algebra/MonoidAlgebra/ToDirectSum.lean b/Mathlib/Algebra/MonoidAlgebra/ToDirectSum.lean index aa57dcae344e6d..9f6803f7cbf494 100644 --- a/Mathlib/Algebra/MonoidAlgebra/ToDirectSum.lean +++ b/Mathlib/Algebra/MonoidAlgebra/ToDirectSum.lean @@ -129,7 +129,7 @@ theorem toDirectSum_mul [DecidableEq ι] [AddMonoid ι] [Semiring M] (f g : AddM let _ : NonUnitalNonAssocSemiring (ι →₀ M) := AddMonoidAlgebra.nonUnitalNonAssocSemiring revert f g rw [AddMonoidHom.map_mul_iff] - -- Porting note: does not find `addHom_ext'`, was `ext (xi xv yi yv) : 4` + -- Porting note (#11041): does not find `addHom_ext'`, was `ext (xi xv yi yv) : 4` refine Finsupp.addHom_ext' fun xi => AddMonoidHom.ext fun xv => ?_ refine Finsupp.addHom_ext' fun yi => AddMonoidHom.ext fun yv => ?_ dsimp only [AddMonoidHom.comp_apply, AddMonoidHom.compl₂_apply, AddMonoidHom.compr₂_apply, diff --git a/Mathlib/Algebra/MvPolynomial/Basic.lean b/Mathlib/Algebra/MvPolynomial/Basic.lean index 1c4137397a564a..c5e9e3036cee45 100644 --- a/Mathlib/Algebra/MvPolynomial/Basic.lean +++ b/Mathlib/Algebra/MvPolynomial/Basic.lean @@ -404,12 +404,12 @@ theorem induction_on {M : MvPolynomial σ R → Prop} (p : MvPolynomial σ R) (h theorem ringHom_ext {A : Type*} [Semiring A] {f g : MvPolynomial σ R →+* A} (hC : ∀ r, f (C r) = g (C r)) (hX : ∀ i, f (X i) = g (X i)) : f = g := by refine AddMonoidAlgebra.ringHom_ext' ?_ ?_ - -- Porting note: this has high priority, but Lean still chooses `RingHom.ext`, why? + -- Porting note (#11041): this has high priority, but Lean still chooses `RingHom.ext`, why? -- probably because of the type synonym · ext x exact hC _ · apply Finsupp.mulHom_ext'; intros x - -- Porting note: `Finsupp.mulHom_ext'` needs to have increased priority + -- Porting note (#11041): `Finsupp.mulHom_ext'` needs to have increased priority apply MonoidHom.ext_mnat exact hX _ diff --git a/Mathlib/Algebra/Polynomial/Laurent.lean b/Mathlib/Algebra/Polynomial/Laurent.lean index cd5d3cd5dc75a0..c139a6417371f7 100644 --- a/Mathlib/Algebra/Polynomial/Laurent.lean +++ b/Mathlib/Algebra/Polynomial/Laurent.lean @@ -87,7 +87,7 @@ scoped[LaurentPolynomial] notation:9000 R "[T;T⁻¹]" => LaurentPolynomial R open LaurentPolynomial --- Porting note: `ext` no longer applies `Finsupp.ext` automatically +-- Porting note (#5229): `ext` no longer applies `Finsupp.ext` automatically @[ext] theorem LaurentPolynomial.ext [Semiring R] {p q : R[T;T⁻¹]} (h : ∀ a, p a = q a) : p = q := Finsupp.ext h diff --git a/Mathlib/AlgebraicGeometry/Restrict.lean b/Mathlib/AlgebraicGeometry/Restrict.lean index db1fe2f6dad5c9..3eadf0265e3fc8 100644 --- a/Mathlib/AlgebraicGeometry/Restrict.lean +++ b/Mathlib/AlgebraicGeometry/Restrict.lean @@ -392,13 +392,13 @@ theorem image_morphismRestrict_preimage {X Y : Scheme.{u}} (f : X ⟶ Y) (U : Y. -- Porting note: this rewrite was not necessary rw [SetLike.mem_coe] convert hx' - -- Porting note: `ext1` is not compiling + -- Porting note (#11041): `ext1` is not compiling refine Subtype.ext ?_ exact (morphismRestrict_base_coe f U ⟨x, hx⟩).symm · rintro ⟨⟨x, hx⟩, hx' : _ ∈ V.1, rfl : x = _⟩ refine ⟨⟨_, hx⟩, (?_ : (f ∣_ U).base ⟨x, hx⟩ ∈ V.1), rfl⟩ convert hx' - -- Porting note: `ext1` is compiling + -- Porting note (#11041): `ext1` is compiling refine Subtype.ext ?_ exact morphismRestrict_base_coe f U ⟨x, hx⟩ diff --git a/Mathlib/AlgebraicGeometry/Spec.lean b/Mathlib/AlgebraicGeometry/Spec.lean index 349fe5db9ccec0..25719eb7d693ff 100644 --- a/Mathlib/AlgebraicGeometry/Spec.lean +++ b/Mathlib/AlgebraicGeometry/Spec.lean @@ -287,7 +287,7 @@ instance isIso_toSpecΓ (R : CommRingCat.{u}) : IsIso (toSpecΓ R) := by @[reassoc] theorem Spec_Γ_naturality {R S : CommRingCat.{u}} (f : R ⟶ S) : f ≫ toSpecΓ S = toSpecΓ R ≫ Γ.map (Spec.toLocallyRingedSpace.map f.op).op := by - -- Porting note: `ext` failed to pick up one of the three lemmas + -- Porting note (#11041): `ext` failed to pick up one of the three lemmas refine RingHom.ext fun x => Subtype.ext <| funext fun x' => ?_; symm apply Localization.localRingHom_to_map diff --git a/Mathlib/AlgebraicTopology/SimplexCategory.lean b/Mathlib/AlgebraicTopology/SimplexCategory.lean index 036111e7e6ab63..ac2101ce20054f 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory.lean @@ -142,7 +142,7 @@ lemma id_toOrderHom (a : SimplexCategory) : lemma comp_toOrderHom {a b c : SimplexCategory} (f : a ⟶ b) (g : b ⟶ c) : (f ≫ g).toOrderHom = g.toOrderHom.comp f.toOrderHom := rfl --- Porting note: added because `Hom.ext'` is not triggered automatically +-- Porting note (#5229): added because `Hom.ext'` is not triggered automatically @[ext] theorem Hom.ext {a b : SimplexCategory} (f g : a ⟶ b) : f.toOrderHom = g.toOrderHom → f = g := diff --git a/Mathlib/AlgebraicTopology/SplitSimplicialObject.lean b/Mathlib/AlgebraicTopology/SplitSimplicialObject.lean index 246867b17fe5c1..48c6023dd10539 100644 --- a/Mathlib/AlgebraicTopology/SplitSimplicialObject.lean +++ b/Mathlib/AlgebraicTopology/SplitSimplicialObject.lean @@ -351,7 +351,7 @@ variable {C} namespace Split --- Porting note: added as `Hom.ext` is not triggered automatically +-- Porting note (#5229): added as `Hom.ext` is not triggered automatically @[ext] theorem hom_ext {S₁ S₂ : Split C} (Φ₁ Φ₂ : S₁ ⟶ S₂) (h : ∀ n : ℕ, Φ₁.f n = Φ₂.f n) : Φ₁ = Φ₂ := Hom.ext _ _ h diff --git a/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean b/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean index b472107dc47f5a..7c2ed530109620 100644 --- a/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean +++ b/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean @@ -258,7 +258,7 @@ theorem zero_morphism_ext {P Q : C} (f : P ⟶ Q) : (∀ a, f a = 0) → f = 0 : theorem zero_morphism_ext' {P Q : C} (f : P ⟶ Q) : (∀ a, f a = 0) → 0 = f := Eq.symm ∘ zero_morphism_ext f --- Porting note: these are no longer valid as `ext` lemmas. +-- Porting note (#11182): these are no longer valid as `ext` lemmas. -- scoped[Pseudoelement] -- attribute [ext] -- CategoryTheory.Abelian.Pseudoelement.zero_morphism_ext diff --git a/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Oplax.lean b/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Oplax.lean index 28abd4f9c4360a..2d6217112669a1 100644 --- a/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Oplax.lean +++ b/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Oplax.lean @@ -245,7 +245,7 @@ instance category (F G : OplaxFunctor B C) : Category (F ⟶ G) where id := Modification.id comp := Modification.vcomp --- Porting note: duplicating the `ext` lemma. +-- Porting note (#5229): duplicating the `ext` lemma. @[ext] lemma ext {F G : OplaxFunctor B C} {α β : F ⟶ G} {m n : α ⟶ β} (w : ∀ b, m.app b = n.app b) : m = n := by diff --git a/Mathlib/CategoryTheory/Closed/Functor.lean b/Mathlib/CategoryTheory/Closed/Functor.lean index c0348d31a52bfa..a725454594c48d 100644 --- a/Mathlib/CategoryTheory/Closed/Functor.lean +++ b/Mathlib/CategoryTheory/Closed/Functor.lean @@ -79,14 +79,14 @@ theorem expComparison_ev (A B : C) : Limits.prod.map (𝟙 (F.obj A)) ((expComparison F A).app B) ≫ (exp.ev (F.obj A)).app (F.obj B) = inv (prodComparison F _ _) ≫ F.map ((exp.ev _).app _) := by convert mateEquiv_counit _ _ (prodComparisonNatIso F A).inv B using 2 - apply IsIso.inv_eq_of_hom_inv_id -- Porting note: was `ext` + apply IsIso.inv_eq_of_hom_inv_id -- Porting note (#11041): was `ext` simp only [Limits.prodComparisonNatIso_inv, asIso_inv, NatIso.isIso_inv_app, IsIso.hom_inv_id] theorem coev_expComparison (A B : C) : F.map ((exp.coev A).app B) ≫ (expComparison F A).app (A ⨯ B) = (exp.coev _).app (F.obj B) ≫ (exp (F.obj A)).map (inv (prodComparison F A B)) := by convert unit_mateEquiv _ _ (prodComparisonNatIso F A).inv B using 3 - apply IsIso.inv_eq_of_hom_inv_id -- Porting note: was `ext` + apply IsIso.inv_eq_of_hom_inv_id -- Porting note (#11041): was `ext` dsimp simp diff --git a/Mathlib/CategoryTheory/Comma/Basic.lean b/Mathlib/CategoryTheory/Comma/Basic.lean index 8cff758d674631..74eebe08f5cf9f 100644 --- a/Mathlib/CategoryTheory/Comma/Basic.lean +++ b/Mathlib/CategoryTheory/Comma/Basic.lean @@ -106,7 +106,7 @@ section variable {X Y Z : Comma L R} {f : X ⟶ Y} {g : Y ⟶ Z} --- Porting note: this lemma was added because `CommaMorphism.ext` +-- Porting note (#5229): this lemma was added because `CommaMorphism.ext` -- was not triggered automatically @[ext] lemma hom_ext (f g : X ⟶ Y) (h₁ : f.left = g.left) (h₂ : f.right = g.right) : f = g := diff --git a/Mathlib/CategoryTheory/Elements.lean b/Mathlib/CategoryTheory/Elements.lean index 3ff60562fdb116..588561a7941f82 100644 --- a/Mathlib/CategoryTheory/Elements.lean +++ b/Mathlib/CategoryTheory/Elements.lean @@ -47,7 +47,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⟩ --- Porting note: added because Sigma.ext would be triggered automatically +-- Porting note (#5229): added because Sigma.ext would be triggered automatically 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 diff --git a/Mathlib/CategoryTheory/Endomorphism.lean b/Mathlib/CategoryTheory/Endomorphism.lean index 1e553ff57a4dc5..4845f0a202a033 100644 --- a/Mathlib/CategoryTheory/Endomorphism.lean +++ b/Mathlib/CategoryTheory/Endomorphism.lean @@ -114,7 +114,7 @@ def Aut (X : C) := X ≅ X namespace Aut --- Porting note: added because `Iso.ext` is not triggered automatically +-- Porting note (#5229): added because `Iso.ext` is not triggered automatically @[ext] lemma ext {X : C} {φ₁ φ₂ : Aut X} (h : φ₁.hom = φ₂.hom) : φ₁ = φ₂ := Iso.ext h diff --git a/Mathlib/CategoryTheory/Functor/Category.lean b/Mathlib/CategoryTheory/Functor/Category.lean index e1f0445ab692b0..e1bd5dc1cfab1b 100644 --- a/Mathlib/CategoryTheory/Functor/Category.lean +++ b/Mathlib/CategoryTheory/Functor/Category.lean @@ -48,7 +48,7 @@ instance Functor.category : Category.{max u₁ v₂} (C ⥤ D) where namespace NatTrans --- Porting note: the behaviour of `ext` has changed here. +-- Porting note (#5229): the behaviour of `ext` has changed here. -- We need to provide a copy of the `NatTrans.ext` lemma, -- written in terms of `F ⟶ G` rather than `NatTrans F G`, -- or `ext` will not retrieve it from the cache. diff --git a/Mathlib/CategoryTheory/Idempotents/Karoubi.lean b/Mathlib/CategoryTheory/Idempotents/Karoubi.lean index a0cd003efe4197..abcded134084eb 100644 --- a/Mathlib/CategoryTheory/Idempotents/Karoubi.lean +++ b/Mathlib/CategoryTheory/Idempotents/Karoubi.lean @@ -101,7 +101,7 @@ theorem hom_ext_iff {P Q : Karoubi C} {f g : P ⟶ Q} : f = g ↔ f.f = g.f := b rw [h] · apply Hom.ext --- Porting note: added because `Hom.ext` is not triggered automatically +-- Porting note (#5229): added because `Hom.ext` is not triggered automatically @[ext] theorem hom_ext {P Q : Karoubi C} (f g : P ⟶ Q) (h : f.f = g.f) : f = g := by simpa [hom_ext_iff] using h diff --git a/Mathlib/CategoryTheory/Iso.lean b/Mathlib/CategoryTheory/Iso.lean index af07a00e52f8da..7ce50b850ef49b 100644 --- a/Mathlib/CategoryTheory/Iso.lean +++ b/Mathlib/CategoryTheory/Iso.lean @@ -305,7 +305,7 @@ instance (priority := 100) mono_of_iso (f : X ⟶ Y) [IsIso f] : Mono f where rw [← Category.comp_id g, ← Category.comp_id h, ← IsIso.hom_inv_id f, ← Category.assoc, w, ← Category.assoc] --- Porting note: `@[ext]` used to accept lemmas like this. Now we add an aesop rule +-- Porting note (#11182): `@[ext]` used to accept lemmas like this. Now we add an aesop rule @[aesop apply safe (rule_sets := [CategoryTheory])] theorem inv_eq_of_hom_inv_id {f : X ⟶ Y} [IsIso f] {g : Y ⟶ X} (hom_inv_id : f ≫ g = 𝟙 X) : inv f = g := by @@ -317,7 +317,7 @@ theorem inv_eq_of_inv_hom_id {f : X ⟶ Y} [IsIso f] {g : Y ⟶ X} (inv_hom_id : apply (cancel_mono f).mp simp [inv_hom_id] --- Porting note: `@[ext]` used to accept lemmas like this. +-- Porting note (#11182): `@[ext]` used to accept lemmas like this. @[aesop apply safe (rule_sets := [CategoryTheory])] theorem eq_inv_of_hom_inv_id {f : X ⟶ Y} [IsIso f] {g : Y ⟶ X} (hom_inv_id : f ≫ g = 𝟙 X) : g = inv f := @@ -446,12 +446,12 @@ theorem isIso_of_comp_hom_eq_id (g : X ⟶ Y) [IsIso g] {f : Y ⟶ X} (h : f ≫ namespace Iso --- Porting note: `@[ext]` used to accept lemmas like this. +-- Porting note (#11182): `@[ext]` used to accept lemmas like this. @[aesop apply safe (rule_sets := [CategoryTheory])] theorem inv_ext {f : X ≅ Y} {g : Y ⟶ X} (hom_inv_id : f.hom ≫ g = 𝟙 X) : f.inv = g := ((hom_comp_eq_id f).1 hom_inv_id).symm --- Porting note: `@[ext]` used to accept lemmas like this. +-- Porting note (#11182): `@[ext]` used to accept lemmas like this. @[aesop apply safe (rule_sets := [CategoryTheory])] theorem inv_ext' {f : X ≅ Y} {g : Y ⟶ X} (hom_inv_id : f.hom ≫ g = 𝟙 X) : g = f.inv := (hom_comp_eq_id f).1 hom_inv_id diff --git a/Mathlib/CategoryTheory/Limits/Cones.lean b/Mathlib/CategoryTheory/Limits/Cones.lean index 29912d06cb23ce..098f9f7adcb6a2 100644 --- a/Mathlib/CategoryTheory/Limits/Cones.lean +++ b/Mathlib/CategoryTheory/Limits/Cones.lean @@ -283,7 +283,7 @@ namespace Cones /-- To give an isomorphism between cones, it suffices to give an isomorphism between their vertices which commutes with the cone maps. -/ --- Porting note: `@[ext]` used to accept lemmas like this. Now we add an aesop rule +-- Porting note (#11182): `@[ext]` used to accept lemmas like this. Now we add an aesop rule @[aesop apply safe (rule_sets := [CategoryTheory]), simps] def ext {c c' : Cone F} (φ : c.pt ≅ c'.pt) (w : ∀ j, c.π.app j = φ.hom ≫ c'.π.app j := by aesop_cat) : c ≅ c' where @@ -484,7 +484,7 @@ namespace Cocones /-- To give an isomorphism between cocones, it suffices to give an isomorphism between their vertices which commutes with the cocone maps. -/ --- Porting note: `@[ext]` used to accept lemmas like this. Now we add an aesop rule +-- Porting note (#11182): `@[ext]` used to accept lemmas like this. Now we add an aesop rule @[aesop apply safe (rule_sets := [CategoryTheory]), simps] def ext {c c' : Cocone F} (φ : c.pt ≅ c'.pt) (w : ∀ j, c.ι.app j ≫ φ.hom = c'.ι.app j := by aesop_cat) : c ≅ c' where diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean b/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean index 78e960db24953c..2d164996009819 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean @@ -122,7 +122,7 @@ namespace Bicones /-- To give an isomorphism between cocones, it suffices to give an isomorphism between their vertices which commutes with the cocone maps. -/ --- Porting note: `@[ext]` used to accept lemmas like this. Now we add an aesop rule +-- Porting note (#11182): `@[ext]` used to accept lemmas like this. Now we add an aesop rule @[aesop apply safe (rule_sets := [CategoryTheory]), simps] def ext {c c' : Bicone F} (φ : c.pt ≅ c'.pt) (wι : ∀ j, c.ι j ≫ φ.hom = c'.ι j := by aesop_cat) @@ -1119,7 +1119,7 @@ namespace BinaryBicones /-- To give an isomorphism between cocones, it suffices to give an isomorphism between their vertices which commutes with the cocone maps. -/ --- Porting note: `@[ext]` used to accept lemmas like this. Now we add an aesop rule +-- Porting note (#11182): `@[ext]` used to accept lemmas like this. Now we add an aesop rule @[aesop apply safe (rule_sets := [CategoryTheory]), simps] def ext {P Q : C} {c c' : BinaryBicone P Q} (φ : c.pt ≅ c'.pt) (winl : c.inl ≫ φ.hom = c'.inl := by aesop_cat) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean b/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean index 54c25d54c53c4d..d880d204adea3a 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean @@ -662,7 +662,7 @@ noncomputable def multicoforkEquivSigmaCofork : counitIso := NatIso.ofComponents fun K => Cofork.ext (Iso.refl _) (by - -- Porting note: in mathlib3 this was just `ext` and I don't know why it's not here + -- Porting note (#11041): in mathlib3 this was just `ext` and I don't know why it's not here apply Limits.colimit.hom_ext rintro ⟨j⟩ dsimp diff --git a/Mathlib/CategoryTheory/Monoidal/Bimod.lean b/Mathlib/CategoryTheory/Monoidal/Bimod.lean index b4118c7d293bfa..b6d566f92f32a4 100644 --- a/Mathlib/CategoryTheory/Monoidal/Bimod.lean +++ b/Mathlib/CategoryTheory/Monoidal/Bimod.lean @@ -120,7 +120,7 @@ instance : Category (Bimod A B) where id := id' comp f g := comp f g --- Porting note: added because `Hom.ext` is not triggered automatically +-- Porting note (#5229): added because `Hom.ext` is not triggered automatically @[ext] lemma hom_ext {M N : Bimod A B} (f g : M ⟶ N) (h : f.hom = g.hom) : f = g := Hom.ext h diff --git a/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean b/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean index ecac5bcd3be125..c0dfcace9f9a67 100644 --- a/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean +++ b/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean @@ -399,7 +399,7 @@ def comp (F : LaxBraidedFunctor C D) (G : LaxBraidedFunctor D E) : LaxBraidedFun instance categoryLaxBraidedFunctor : Category (LaxBraidedFunctor C D) := InducedCategory.category LaxBraidedFunctor.toLaxMonoidalFunctor --- Porting note: added, as `MonoidalNatTrans.ext` does not apply to morphisms. +-- Porting note (#5229): added, as `MonoidalNatTrans.ext` does not apply to morphisms. @[ext] lemma ext' {F G : LaxBraidedFunctor C D} {α β : F ⟶ G} (w : ∀ X : C, α.app X = β.app X) : α = β := MonoidalNatTrans.ext (funext w) @@ -463,7 +463,7 @@ def comp (F : BraidedFunctor C D) (G : BraidedFunctor D E) : BraidedFunctor C E instance categoryBraidedFunctor : Category (BraidedFunctor C D) := InducedCategory.category BraidedFunctor.toMonoidalFunctor --- Porting note: added, as `MonoidalNatTrans.ext` does not apply to morphisms. +-- Porting note (#5229): added, as `MonoidalNatTrans.ext` does not apply to morphisms. @[ext] lemma ext' {F G : BraidedFunctor C D} {α β : F ⟶ G} (w : ∀ X : C, α.app X = β.app X) : α = β := MonoidalNatTrans.ext (funext w) diff --git a/Mathlib/CategoryTheory/Monoidal/Center.lean b/Mathlib/CategoryTheory/Monoidal/Center.lean index 5eab3c67802bae..3e6f4d3046f5ae 100644 --- a/Mathlib/CategoryTheory/Monoidal/Center.lean +++ b/Mathlib/CategoryTheory/Monoidal/Center.lean @@ -278,7 +278,7 @@ theorem associator_hom_f (X Y Z : Center C) : Hom.f (α_ X Y Z).hom = (α_ X.1 Y @[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: Originally `ext` + apply Iso.inv_ext' -- Porting note (#11041): Originally `ext` rw [← associator_hom_f, ← comp_f, Iso.hom_inv_id]; rfl @[simp] @@ -287,7 +287,7 @@ theorem leftUnitor_hom_f (X : Center C) : Hom.f (λ_ X).hom = (λ_ X.1).hom := @[simp] theorem leftUnitor_inv_f (X : Center C) : Hom.f (λ_ X).inv = (λ_ X.1).inv := by - apply Iso.inv_ext' -- Porting note: Originally `ext` + apply Iso.inv_ext' -- Porting note (#11041): Originally `ext` rw [← leftUnitor_hom_f, ← comp_f, Iso.hom_inv_id]; rfl @[simp] @@ -296,7 +296,7 @@ theorem rightUnitor_hom_f (X : Center C) : Hom.f (ρ_ X).hom = (ρ_ X.1).hom := @[simp] theorem rightUnitor_inv_f (X : Center C) : Hom.f (ρ_ X).inv = (ρ_ X.1).inv := by - apply Iso.inv_ext' -- Porting note: Originally `ext` + apply Iso.inv_ext' -- Porting note (#11041): Originally `ext` rw [← rightUnitor_hom_f, ← comp_f, Iso.hom_inv_id]; rfl end diff --git a/Mathlib/CategoryTheory/Monoidal/Internal/Module.lean b/Mathlib/CategoryTheory/Monoidal/Internal/Module.lean index 4bdf23e5898f46..b579897c35ad0d 100644 --- a/Mathlib/CategoryTheory/Monoidal/Internal/Module.lean +++ b/Mathlib/CategoryTheory/Monoidal/Internal/Module.lean @@ -103,7 +103,7 @@ def inverseObj (A : AlgebraCat.{u} R) : Mon_ (ModuleCat.{u} R) where one := Algebra.linearMap R A mul := LinearMap.mul' R A one_mul := by - -- Porting note: `ext` did not pick up `TensorProduct.ext` + -- Porting note (#11041): `ext` did not pick up `TensorProduct.ext` refine TensorProduct.ext <| LinearMap.ext_ring <| LinearMap.ext fun x => ?_ -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644 erw [compr₂_apply, compr₂_apply, CategoryTheory.comp_apply] @@ -116,7 +116,7 @@ def inverseObj (A : AlgebraCat.{u} R) : Mon_ (ModuleCat.{u} R) where erw [LinearMap.mul'_apply, MonoidalCategory.leftUnitor_hom_apply, ← Algebra.smul_def] erw [id_apply] mul_one := by - -- Porting note: `ext` did not pick up `TensorProduct.ext` + -- Porting note (#11041): `ext` did not pick up `TensorProduct.ext` refine TensorProduct.ext <| LinearMap.ext fun x => LinearMap.ext_ring ?_ -- Porting note: this `dsimp` does nothing -- dsimp only [AlgebraCat.id_apply, TensorProduct.mk_apply, Algebra.linearMap_apply, @@ -131,7 +131,7 @@ def inverseObj (A : AlgebraCat.{u} R) : Mon_ (ModuleCat.{u} R) where erw [id_apply] mul_assoc := by set_option tactic.skipAssignedInstances false in - -- Porting note: `ext` did not pick up `TensorProduct.ext` + -- Porting note (#11041): `ext` did not pick up `TensorProduct.ext` refine TensorProduct.ext <| TensorProduct.ext <| LinearMap.ext fun x => LinearMap.ext fun y => LinearMap.ext fun z => ?_ dsimp only [AlgebraCat.id_apply, TensorProduct.mk_apply, LinearMap.compr₂_apply, @@ -176,7 +176,7 @@ def monModuleEquivalenceAlgebra : Mon_ (ModuleCat.{u} R) ≌ AlgebraCat R where map_add' := fun _ _ => rfl map_smul' := fun _ _ => rfl } mul_hom := by - -- Porting note: `ext` did not pick up `TensorProduct.ext` + -- Porting note (#11041): `ext` did not pick up `TensorProduct.ext` refine TensorProduct.ext ?_ dsimp at * rfl } @@ -186,7 +186,7 @@ def monModuleEquivalenceAlgebra : Mon_ (ModuleCat.{u} R) ≌ AlgebraCat R where map_add' := fun _ _ => rfl map_smul' := fun _ _ => rfl } mul_hom := by - -- Porting note: `ext` did not pick up `TensorProduct.ext` + -- Porting note (#11041): `ext` did not pick up `TensorProduct.ext` refine TensorProduct.ext ?_ dsimp at * rfl } }) diff --git a/Mathlib/CategoryTheory/Monoidal/Mon_.lean b/Mathlib/CategoryTheory/Monoidal/Mon_.lean index be13f54b4dd13c..82f033d04a0451 100644 --- a/Mathlib/CategoryTheory/Monoidal/Mon_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Mon_.lean @@ -104,7 +104,7 @@ instance : Category (Mon_ C) where id := id comp f g := comp f g --- Porting note: added, as `Hom.ext` does not apply to a morphism. +-- Porting note (#5229): added, as `Hom.ext` does not apply to a morphism. @[ext] lemma ext {X Y : Mon_ C} {f g : X ⟶ Y} (w : f.hom = g.hom) : f = g := Hom.ext w diff --git a/Mathlib/CategoryTheory/Monoidal/NaturalTransformation.lean b/Mathlib/CategoryTheory/Monoidal/NaturalTransformation.lean index 37d92020f5dfd4..4d73ab1b96ac53 100644 --- a/Mathlib/CategoryTheory/Monoidal/NaturalTransformation.lean +++ b/Mathlib/CategoryTheory/Monoidal/NaturalTransformation.lean @@ -81,7 +81,7 @@ theorem comp_toNatTrans_lax {F G H : LaxMonoidalFunctor C D} {α : F ⟶ G} {β instance categoryMonoidalFunctor : Category (MonoidalFunctor C D) := InducedCategory.category MonoidalFunctor.toLaxMonoidalFunctor --- Porting note: added, as `MonoidalNatTrans.ext` does not apply to morphisms. +-- Porting note (#5229): added, as `MonoidalNatTrans.ext` does not apply to morphisms. @[ext] lemma ext' {F G : LaxMonoidalFunctor C D} {α β : F ⟶ G} (w : ∀ X : C, α.app X = β.app X) : α = β := MonoidalNatTrans.ext (funext w) diff --git a/Mathlib/CategoryTheory/Pi/Basic.lean b/Mathlib/CategoryTheory/Pi/Basic.lean index 6827f96279d677..beeb60fcf3da4f 100644 --- a/Mathlib/CategoryTheory/Pi/Basic.lean +++ b/Mathlib/CategoryTheory/Pi/Basic.lean @@ -49,7 +49,7 @@ theorem comp_apply {X Y Z : ∀ i, C i} (f : X ⟶ Y) (g : Y ⟶ Z) (i) : (f ≫ g : ∀ i, X i ⟶ Z i) i = f i ≫ g i := rfl --- Porting note: need to add an additional `ext` lemma. +-- Porting note (#5229): need to add an additional `ext` lemma. @[ext] lemma ext {X Y : ∀ i, C i} {f g : X ⟶ Y} (w : ∀ i, f i = g i) : f = g := funext (w ·) diff --git a/Mathlib/CategoryTheory/Sites/Pretopology.lean b/Mathlib/CategoryTheory/Sites/Pretopology.lean index 85b5f87c3c0a87..972ef7c94b08d5 100644 --- a/Mathlib/CategoryTheory/Sites/Pretopology.lean +++ b/Mathlib/CategoryTheory/Sites/Pretopology.lean @@ -183,7 +183,7 @@ def trivial : Pretopology C where rcases hS g (singleton_self g) with ⟨Y, f, i, hTi⟩ refine ⟨_, f ≫ g, ?_, ?_⟩ · infer_instance - -- Porting note: the next four lines were just "ext (W k)" + -- Porting note (#11041): the next four lines were just "ext (W k)" apply funext rintro W apply Set.ext diff --git a/Mathlib/CategoryTheory/Sites/Sheaf.lean b/Mathlib/CategoryTheory/Sites/Sheaf.lean index 07e5279a343961..99d958c7ef6869 100644 --- a/Mathlib/CategoryTheory/Sites/Sheaf.lean +++ b/Mathlib/CategoryTheory/Sites/Sheaf.lean @@ -332,7 +332,7 @@ instance instCategorySheaf : Category (Sheaf J A) where instance (X : Sheaf J A) : Inhabited (Hom X X) := ⟨𝟙 X⟩ --- Porting note: added because `Sheaf.Hom.ext` was not triggered automatically +-- Porting note (#5229): added because `Sheaf.Hom.ext` was not triggered automatically @[ext] lemma hom_ext {X Y : Sheaf J A} (x y : X ⟶ Y) (h : x.val = y.val) : x = y := Sheaf.Hom.ext h diff --git a/Mathlib/Data/PFunctor/Univariate/M.lean b/Mathlib/Data/PFunctor/Univariate/M.lean index 73fe251a4dda5e..58879cd06c1362 100644 --- a/Mathlib/Data/PFunctor/Univariate/M.lean +++ b/Mathlib/Data/PFunctor/Univariate/M.lean @@ -92,7 +92,7 @@ theorem truncate_eq_of_agree {n : ℕ} (x : CofixA F n) (y : CofixA F (succ n)) · -- cases' h with _ _ _ _ _ h₀ h₁ cases h simp only [truncate, Function.comp_def, eq_self_iff_true, heq_iff_eq] - -- Porting note: used to be `ext y` + -- Porting note (#11041): used to be `ext y` rename_i n_ih a f y h₁ suffices (fun x => truncate (y x)) = f by simp [this] diff --git a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean index 0f4f4ce207163c..a29fd4205a61ae 100644 --- a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean +++ b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean @@ -123,7 +123,7 @@ noncomputable def isoRestrict : X ≅ Y.restrict H.base_open := @[reassoc (attr := simp)] theorem isoRestrict_hom_ofRestrict : (isoRestrict f).hom ≫ Y.ofRestrict _ = f := by - -- Porting note: `ext` did not pick up `NatTrans.ext` + -- Porting note (#11041): `ext` did not pick up `NatTrans.ext` refine PresheafedSpace.Hom.ext _ _ rfl <| NatTrans.ext <| funext fun x => ?_ simp only [isoRestrict_hom_c_app, NatTrans.comp_app, eqToHom_refl, ofRestrict_c_app, Category.assoc, whiskerRight_id'] @@ -330,7 +330,7 @@ def pullbackConeOfLeftFst : rfl } theorem pullback_cone_of_left_condition : pullbackConeOfLeftFst f g ≫ f = Y.ofRestrict _ ≫ g := by - -- Porting note: `ext` did not pick up `NatTrans.ext` + -- Porting note (#11041): `ext` did not pick up `NatTrans.ext` refine PresheafedSpace.Hom.ext _ _ ?_ <| NatTrans.ext <| funext fun U => ?_ · simpa using pullback.condition · induction U using Opposite.rec' @@ -388,7 +388,7 @@ def pullbackConeOfLeftLift : s.pt ⟶ (pullbackConeOfLeft f g).pt where -- this lemma is not a `simp` lemma, because it is an implementation detail theorem pullbackConeOfLeftLift_fst : pullbackConeOfLeftLift f g s ≫ (pullbackConeOfLeft f g).fst = s.fst := by - -- Porting note: `ext` did not pick up `NatTrans.ext` + -- Porting note (#11041): `ext` did not pick up `NatTrans.ext` refine PresheafedSpace.Hom.ext _ _ ?_ <| NatTrans.ext <| funext fun x => ?_ · change pullback.lift _ _ _ ≫ pullback.fst _ _ = _ simp @@ -407,7 +407,7 @@ theorem pullbackConeOfLeftLift_fst : -- this lemma is not a `simp` lemma, because it is an implementation detail theorem pullbackConeOfLeftLift_snd : pullbackConeOfLeftLift f g s ≫ (pullbackConeOfLeft f g).snd = s.snd := by - -- Porting note: `ext` did not pick up `NatTrans.ext` + -- Porting note (#11041): `ext` did not pick up `NatTrans.ext` refine PresheafedSpace.Hom.ext _ _ ?_ <| NatTrans.ext <| funext fun x => ?_ · change pullback.lift _ _ _ ≫ pullback.snd _ _ = _ simp diff --git a/Mathlib/Geometry/RingedSpace/PresheafedSpace/HasColimits.lean b/Mathlib/Geometry/RingedSpace/PresheafedSpace/HasColimits.lean index ce942b2c84104a..9b2339708fe4b8 100644 --- a/Mathlib/Geometry/RingedSpace/PresheafedSpace/HasColimits.lean +++ b/Mathlib/Geometry/RingedSpace/PresheafedSpace/HasColimits.lean @@ -224,7 +224,7 @@ theorem desc_fac (F : J ⥤ PresheafedSpace.{_, _, v} C) (s : Cocone F) (j : J) (colimitCocone F).ι.app j ≫ desc F s = s.ι.app j := by ext U · simp [desc] - · -- Porting note: the original proof is just `ext; dsimp [desc, descCApp]; simpa`, + · -- Porting note (#11041): the original proof is just `ext; dsimp [desc, descCApp]; simpa`, -- but this has to be expanded a bit rw [NatTrans.comp_app, PresheafedSpace.comp_c_app, whiskerRight_app] dsimp [desc, descCApp] diff --git a/Mathlib/Order/Category/OmegaCompletePartialOrder.lean b/Mathlib/Order/Category/OmegaCompletePartialOrder.lean index 7a02ed603f9c1d..7f8ab62dfc2491 100644 --- a/Mathlib/Order/Category/OmegaCompletePartialOrder.lean +++ b/Mathlib/Order/Category/OmegaCompletePartialOrder.lean @@ -81,7 +81,7 @@ def isProduct (J : Type v) (f : J → ωCPO) : IsLimit (product f) where ⟨⟨fun t j => (s.π.app ⟨j⟩).toFun t, fun _ _ h j => (s.π.app ⟨j⟩).monotone h⟩, fun x => funext fun j => (s.π.app ⟨j⟩).continuous x⟩ uniq s m w := by - ext t; funext j -- Porting note: Originally `ext t j` + ext t; funext j -- Porting note (#11041): Originally `ext t j` change m.toFun t j = (s.π.app ⟨j⟩).toFun t rw [← w ⟨j⟩] rfl @@ -98,7 +98,7 @@ instance omegaCompletePartialOrderEqualizer {α β : Type*} [OmegaCompletePartia OmegaCompletePartialOrder.subtype _ fun c hc => by rw [f.continuous, g.continuous] congr 1 - apply OrderHom.ext; funext x -- Porting note: Originally `ext` + apply OrderHom.ext; funext x -- Porting note (#11041): Originally `ext` apply hc _ ⟨_, rfl⟩ namespace HasEqualizers @@ -122,7 +122,7 @@ def isEqualizer {X Y : ωCPO.{v}} (f g : X ⟶ Y) : IsLimit (equalizer f g) := monotone' := fun _ _ h => s.ι.monotone h map_ωSup' := fun x => Subtype.ext (s.ι.continuous x) }, by ext; rfl, fun hm => by - apply ContinuousHom.ext _ _ fun x => Subtype.ext ?_ -- Porting note: Originally `ext` + apply ContinuousHom.ext _ _ fun x => Subtype.ext ?_ -- Porting note (#11041): Originally `ext` apply ContinuousHom.congr_fun hm⟩ end HasEqualizers diff --git a/Mathlib/RepresentationTheory/Action/Basic.lean b/Mathlib/RepresentationTheory/Action/Basic.lean index 9097a7d47988b2..4c1ae310a58124 100644 --- a/Mathlib/RepresentationTheory/Action/Basic.lean +++ b/Mathlib/RepresentationTheory/Action/Basic.lean @@ -111,7 +111,7 @@ instance : Category (Action V G) where id M := Hom.id M comp f g := Hom.comp f g --- Porting note: added because `Hom.ext` is not triggered automatically +-- Porting note (#5229): added because `Hom.ext` is not triggered automatically @[ext] lemma hom_ext {M N : Action V G} (φ₁ φ₂ : M ⟶ N) (h : φ₁.hom = φ₂.hom) : φ₁ = φ₂ := Hom.ext h diff --git a/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean b/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean index 5ad19cc5ca6aef..6481e7153138ac 100644 --- a/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean +++ b/Mathlib/RingTheory/DedekindDomain/FiniteAdeleRing.lean @@ -106,7 +106,7 @@ def Coe.addMonoidHom : AddMonoidHom (R_hat R K) (K_hat R K) where toFun := (↑) map_zero' := rfl map_add' x y := by - -- Porting note: was `ext v` + -- Porting note (#11041): was `ext v` refine funext fun v => ?_ simp only [coe_apply, Pi.add_apply, Subring.coe_add] -- Porting note: added @@ -119,7 +119,7 @@ def Coe.ringHom : RingHom (R_hat R K) (K_hat R K) := toFun := (↑) map_one' := rfl map_mul' := fun x y => by - -- Porting note: was `ext p` + -- Porting note (#11041): was `ext p` refine funext fun p => ?_ simp only [Pi.mul_apply, Subring.coe_mul] -- Porting note: added diff --git a/Mathlib/Topology/Category/CompHaus/Basic.lean b/Mathlib/Topology/Category/CompHaus/Basic.lean index 0306bef4b8f7de..00e0ff959c9f68 100644 --- a/Mathlib/Topology/Category/CompHaus/Basic.lean +++ b/Mathlib/Topology/Category/CompHaus/Basic.lean @@ -93,7 +93,7 @@ noncomputable def stoneCechEquivalence (X : TopCat.{u}) (Y : CompHaus.{u}) : continuous_toFun := continuous_stoneCechExtend f.2 } left_inv := by rintro ⟨f : StoneCech X ⟶ Y, hf : Continuous f⟩ - -- Porting note: `ext` fails. + -- Porting note (#11041): `ext` fails. apply ContinuousMap.ext intro (x : StoneCech X) refine congr_fun ?_ x @@ -103,7 +103,7 @@ noncomputable def stoneCechEquivalence (X : TopCat.{u}) (Y : CompHaus.{u}) : apply continuous_stoneCechUnit right_inv := by rintro ⟨f : (X : Type _) ⟶ Y, hf : Continuous f⟩ - -- Porting note: `ext` fails. + -- Porting note (#11041): `ext` fails. apply ContinuousMap.ext intro exact congr_fun (stoneCechExtend_extends hf) _ @@ -203,7 +203,7 @@ theorem epi_iff_surjective {X Y : CompHaus.{u}} (f : X ⟶ Y) : Epi f ↔ Functi have H : h = g := by rw [← cancel_epi f] ext x - -- Porting note: `ext` doesn't apply these two lemmas. + -- Porting note (#11041): `ext` doesn't apply these two lemmas. apply ULift.ext apply Subtype.ext dsimp diff --git a/Mathlib/Topology/Category/Profinite/AsLimit.lean b/Mathlib/Topology/Category/Profinite/AsLimit.lean index 812192fbc07578..9a23eb81a082af 100644 --- a/Mathlib/Topology/Category/Profinite/AsLimit.lean +++ b/Mathlib/Topology/Category/Profinite/AsLimit.lean @@ -66,7 +66,8 @@ instance isIso_asLimitCone_lift : IsIso ((limitConeIsLimit.{u, u} X.diagram).lif · obtain ⟨b, hb⟩ := DiscreteQuotient.exists_of_compat (fun S => a.val S) fun _ _ h => a.prop (homOfLE h) use b - -- ext S : 3 -- Porting note: `ext` does not work, replaced with following three lines. + -- ext S : 3 -- Porting note (#11041): `ext` does not work, replaced with following + -- three lines. apply Subtype.ext apply funext rintro S diff --git a/Mathlib/Topology/Category/TopCat/Limits/Products.lean b/Mathlib/Topology/Category/TopCat/Limits/Products.lean index 4a6576bc290e8e..cd45197d42a40a 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Products.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Products.lean @@ -161,7 +161,7 @@ def prodBinaryFanIsLimit (X Y : TopCat.{u}) : IsLimit (prodBinaryFan X Y) where rintro S (_ | _) <;> {dsimp; ext; rfl} uniq := by intro S m h - -- Porting note: used to be `ext x` + -- Porting note (#11041): used to be `ext x` refine ContinuousMap.ext (fun (x : ↥(S.pt)) => Prod.ext ?_ ?_) · specialize h ⟨WalkingPair.left⟩ apply_fun fun e => e x at h diff --git a/Mathlib/Topology/Sheaves/PresheafOfFunctions.lean b/Mathlib/Topology/Sheaves/PresheafOfFunctions.lean index ce0908cb259703..4ce4eaa2a3fd1a 100644 --- a/Mathlib/Topology/Sheaves/PresheafOfFunctions.lean +++ b/Mathlib/Topology/Sheaves/PresheafOfFunctions.lean @@ -121,7 +121,7 @@ this is a ring homomorphism (with respect to the pointwise ring operations on fu def map (X : TopCat.{u}ᵒᵖ) {R S : TopCommRingCat.{u}} (φ : R ⟶ S) : continuousFunctions X R ⟶ continuousFunctions X S where toFun g := g ≫ (forget₂ TopCommRingCat TopCat).map φ - -- Porting note: `ext` tactic does not work, since Lean can't see through `R ⟶ S` is just + -- Porting note (#11041): `ext` tactic does not work, since Lean can't see through `R ⟶ S` is just -- continuous ring homomorphism map_one' := ContinuousMap.ext fun _ => φ.1.map_one map_zero' := ContinuousMap.ext fun _ => φ.1.map_zero From bfe51d4ef05f50660a2ffb13e0a4286ac7f3a5bb Mon Sep 17 00:00:00 2001 From: damiano Date: Wed, 16 Oct 2024 15:23:31 +0000 Subject: [PATCH 240/425] chore: yet more unused variables (#17826) --- Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean | 4 ++-- .../FundamentalGroupoid/FundamentalGroup.lean | 4 ++-- Mathlib/CategoryTheory/Limits/Shapes/Pullback/Assoc.lean | 2 +- Mathlib/CategoryTheory/Sites/Canonical.lean | 4 +--- Mathlib/Computability/Reduce.lean | 7 ++----- Mathlib/Control/Fold.lean | 1 - Mathlib/Control/Functor/Multivariate.lean | 2 +- Mathlib/Data/BitVec.lean | 2 +- Mathlib/Data/DFinsupp/Multiset.lean | 4 ++-- Mathlib/Data/TypeVec.lean | 4 ++-- Mathlib/Geometry/Manifold/SmoothManifoldWithCorners.lean | 4 ++-- Mathlib/MeasureTheory/Measure/Hausdorff.lean | 4 ++-- Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean | 6 +++--- Mathlib/MeasureTheory/Order/UpperLower.lean | 2 +- Mathlib/ModelTheory/Complexity.lean | 7 ++----- Mathlib/ModelTheory/ElementarySubstructures.lean | 3 +-- Mathlib/ModelTheory/Encoding.lean | 5 ++--- Mathlib/ModelTheory/Syntax.lean | 3 +-- Mathlib/RingTheory/GradedAlgebra/HomogeneousIdeal.lean | 2 +- Mathlib/RingTheory/Localization/Finiteness.lean | 2 +- Mathlib/RingTheory/TensorProduct/MvPolynomial.lean | 5 ++--- Mathlib/Topology/MetricSpace/Holder.lean | 2 +- Mathlib/Topology/MetricSpace/MetricSeparated.lean | 2 +- Mathlib/Topology/Order/DenselyOrdered.lean | 2 +- Mathlib/Topology/Order/IntermediateValue.lean | 6 ++---- Mathlib/Topology/Order/IsLUB.lean | 5 ++--- Mathlib/Topology/Order/Monotone.lean | 7 +++---- Mathlib/Topology/UniformSpace/Equicontinuity.lean | 4 ++-- .../Topology/UniformSpace/UniformConvergenceTopology.lean | 4 ++-- 29 files changed, 46 insertions(+), 63 deletions(-) diff --git a/Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean b/Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean index 2af55680d6b61a..441b8fdab6dd2d 100644 --- a/Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean +++ b/Mathlib/AlgebraicTopology/FundamentalGroupoid/Basic.lean @@ -20,9 +20,9 @@ group of `x`. open CategoryTheory -universe u v +universe u -variable {X : Type u} {Y : Type v} [TopologicalSpace X] [TopologicalSpace Y] +variable {X : Type u} [TopologicalSpace X] variable {x₀ x₁ : X} noncomputable section diff --git a/Mathlib/AlgebraicTopology/FundamentalGroupoid/FundamentalGroup.lean b/Mathlib/AlgebraicTopology/FundamentalGroupoid/FundamentalGroup.lean index b1c4b82e4469b7..e5d2e226cd5190 100644 --- a/Mathlib/AlgebraicTopology/FundamentalGroupoid/FundamentalGroup.lean +++ b/Mathlib/AlgebraicTopology/FundamentalGroupoid/FundamentalGroup.lean @@ -17,9 +17,9 @@ of `x` i.e. the group with elements being loops based at `x` (quotiented by homo -/ -universe u v +universe u -variable {X : Type u} {Y : Type v} [TopologicalSpace X] [TopologicalSpace Y] +variable {X : Type u} [TopologicalSpace X] variable {x₀ x₁ : X} noncomputable section diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Assoc.lean b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Assoc.lean index 541f09bc26155e..795528a7feb859 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Assoc.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Pullback/Assoc.lean @@ -21,7 +21,7 @@ universe w v₁ v₂ v u u₂ namespace CategoryTheory.Limits -variable {C : Type u} [Category.{v} C] {W X Y Z : C} +variable {C : Type u} [Category.{v} C] section PullbackAssoc diff --git a/Mathlib/CategoryTheory/Sites/Canonical.lean b/Mathlib/CategoryTheory/Sites/Canonical.lean index ec5fdd447f5e9e..a31fc323954e77 100644 --- a/Mathlib/CategoryTheory/Sites/Canonical.lean +++ b/Mathlib/CategoryTheory/Sites/Canonical.lean @@ -43,9 +43,7 @@ variable {C : Type u} [Category.{v} C] namespace Sheaf -variable {P : Cᵒᵖ ⥤ Type v} -variable {X Y : C} {S : Sieve X} {R : Presieve X} -variable (J J₂ : GrothendieckTopology C) +variable {P : Cᵒᵖ ⥤ Type v} {X : C} (J : GrothendieckTopology C) /-- To show `P` is a sheaf for the binding of `U` with `B`, it suffices to show that `P` is a sheaf for diff --git a/Mathlib/Computability/Reduce.lean b/Mathlib/Computability/Reduce.lean index f3131659de7716..4b09ff9c741192 100644 --- a/Mathlib/Computability/Reduce.lean +++ b/Mathlib/Computability/Reduce.lean @@ -106,8 +106,7 @@ theorem transitive_oneOneReducible {α} [Primcodable α] : Transitive (@OneOneRe namespace ComputablePred -variable {α : Type*} {β : Type*} {σ : Type*} -variable [Primcodable α] [Primcodable β] [Primcodable σ] +variable {α : Type*} {β : Type*} [Primcodable α] [Primcodable β] open Computable @@ -266,9 +265,7 @@ theorem disjoin_le {α β γ} [Primcodable α] [Primcodable β] [Primcodable γ] OneOneReducible.disjoin_right.to_many_one.trans h⟩, fun ⟨h₁, h₂⟩ => disjoin_manyOneReducible h₁ h₂⟩ -variable {α : Type u} [Primcodable α] [Inhabited α] -variable {β : Type v} [Primcodable β] [Inhabited β] -variable {γ : Type w} [Primcodable γ] [Inhabited γ] +variable {α : Type u} [Primcodable α] [Inhabited α] {β : Type v} [Primcodable β] [Inhabited β] /-- Computable and injective mapping of predicates to sets of natural numbers. -/ diff --git a/Mathlib/Control/Fold.lean b/Mathlib/Control/Fold.lean index 71a4d437faaa34..711e71a9106354 100644 --- a/Mathlib/Control/Fold.lean +++ b/Mathlib/Control/Fold.lean @@ -239,7 +239,6 @@ theorem foldl.unop_ofFreeMonoid (f : β → α → β) (xs : FreeMonoid α) (a : unop (Foldl.ofFreeMonoid f xs) a = List.foldl f a (FreeMonoid.toList xs) := rfl -variable (m : Type u → Type u) [Monad m] [LawfulMonad m] variable {t : Type u → Type u} [Traversable t] [LawfulTraversable t] open LawfulTraversable diff --git a/Mathlib/Control/Functor/Multivariate.lean b/Mathlib/Control/Functor/Multivariate.lean index 5234cb42fc0e86..042f138715b1f2 100644 --- a/Mathlib/Control/Functor/Multivariate.lean +++ b/Mathlib/Control/Functor/Multivariate.lean @@ -36,7 +36,7 @@ variable {n : ℕ} namespace MvFunctor -variable {α β γ : TypeVec.{u} n} {F : TypeVec.{u} n → Type v} [MvFunctor F] +variable {α β : TypeVec.{u} n} {F : TypeVec.{u} n → Type v} [MvFunctor F] /-- predicate lifting over multivariate functors -/ def LiftP {α : TypeVec n} (P : ∀ i, α i → Prop) (x : F α) : Prop := diff --git a/Mathlib/Data/BitVec.lean b/Mathlib/Data/BitVec.lean index e3928ba4fb51cf..3fb3407a84cb6b 100644 --- a/Mathlib/Data/BitVec.lean +++ b/Mathlib/Data/BitVec.lean @@ -18,7 +18,7 @@ can either be PR'd to Lean, or kept downstream if it also relies on Mathlib. namespace BitVec -variable {w v : Nat} +variable {w : Nat} /-! ## Injectivity diff --git a/Mathlib/Data/DFinsupp/Multiset.lean b/Mathlib/Data/DFinsupp/Multiset.lean index 949128cc0bccbc..fe589464c5396d 100644 --- a/Mathlib/Data/DFinsupp/Multiset.lean +++ b/Mathlib/Data/DFinsupp/Multiset.lean @@ -14,7 +14,7 @@ with `Multiset.toDFinsupp` the reverse equivalence. open Function -variable {α : Type*} {β : α → Type*} +variable {α : Type*} namespace DFinsupp @@ -22,7 +22,7 @@ namespace DFinsupp instance addZeroClass' {β} [AddZeroClass β] : AddZeroClass (Π₀ _ : α, β) := @DFinsupp.addZeroClass α (fun _ ↦ β) _ -variable [DecidableEq α] {s t : Multiset α} +variable [DecidableEq α] /-- A DFinsupp version of `Finsupp.toMultiset`. -/ def toMultiset : (Π₀ _ : α, ℕ) →+ Multiset α := diff --git a/Mathlib/Data/TypeVec.lean b/Mathlib/Data/TypeVec.lean index ed974cab4a625e..df15092ea20be7 100644 --- a/Mathlib/Data/TypeVec.lean +++ b/Mathlib/Data/TypeVec.lean @@ -419,8 +419,8 @@ theorem const_iff_true {α : TypeVec n} {i x p} : ofRepeat (TypeVec.const p α i section -variable {α β γ : TypeVec.{u} n} -variable (p : α ⟹ «repeat» n Prop) (r : α ⊗ α ⟹ «repeat» n Prop) +variable {α β : TypeVec.{u} n} +variable (p : α ⟹ «repeat» n Prop) /-- left projection of a `prod` vector -/ def prod.fst : ∀ {n} {α β : TypeVec.{u} n}, α ⊗ β ⟹ α diff --git a/Mathlib/Geometry/Manifold/SmoothManifoldWithCorners.lean b/Mathlib/Geometry/Manifold/SmoothManifoldWithCorners.lean index 55142a16d8ebd1..d6cebfb34829fb 100644 --- a/Mathlib/Geometry/Manifold/SmoothManifoldWithCorners.lean +++ b/Mathlib/Geometry/Manifold/SmoothManifoldWithCorners.lean @@ -417,9 +417,9 @@ abbrev ModelWithCorners.tangent {𝕜 : Type u} [NontriviallyNormedField 𝕜] { variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] {F : Type*} - [NormedAddCommGroup F] [NormedSpace 𝕜 F] {F' : Type*} [NormedAddCommGroup F'] [NormedSpace 𝕜 F'] + [NormedAddCommGroup F] [NormedSpace 𝕜 F] {H : Type*} [TopologicalSpace H] {H' : Type*} [TopologicalSpace H'] {G : Type*} - [TopologicalSpace G] {G' : Type*} [TopologicalSpace G'] {I : ModelWithCorners 𝕜 E H} + [TopologicalSpace G] {I : ModelWithCorners 𝕜 E H} {J : ModelWithCorners 𝕜 F G} @[simp, mfld_simps] diff --git a/Mathlib/MeasureTheory/Measure/Hausdorff.lean b/Mathlib/MeasureTheory/Measure/Hausdorff.lean index fc55f1955171d1..d4023bb58018d7 100644 --- a/Mathlib/MeasureTheory/Measure/Hausdorff.lean +++ b/Mathlib/MeasureTheory/Measure/Hausdorff.lean @@ -669,7 +669,7 @@ variable [MeasurableSpace X] [BorelSpace X] [MeasurableSpace Y] [BorelSpace Y] namespace HolderOnWith -variable {C r : ℝ≥0} {f : X → Y} {s t : Set X} +variable {C r : ℝ≥0} {f : X → Y} {s : Set X} /-- If `f : X → Y` is Hölder continuous on `s` with a positive exponent `r`, then `μH[d] (f '' s) ≤ C ^ d * μH[r * d] s`. -/ @@ -715,7 +715,7 @@ end HolderOnWith namespace LipschitzOnWith -variable {K : ℝ≥0} {f : X → Y} {s t : Set X} +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`. -/ theorem hausdorffMeasure_image_le (h : LipschitzOnWith K f s) {d : ℝ} (hd : 0 ≤ d) : diff --git a/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean b/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean index 1a99901e0a12a5..fa9209bc596e0a 100644 --- a/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean +++ b/Mathlib/MeasureTheory/Measure/LevyProkhorovMetric.lean @@ -43,7 +43,7 @@ section Levy_Prokhorov /-! ### Lévy-Prokhorov metric -/ -variable {ι : Type*} {Ω : Type*} [MeasurableSpace Ω] [PseudoEMetricSpace Ω] +variable {Ω : Type*} [MeasurableSpace Ω] [PseudoEMetricSpace Ω] /-- The Lévy-Prokhorov edistance between measures: `d(μ,ν) = inf {r ≥ 0 | ∀ B, μ B ≤ ν Bᵣ + r ∧ ν B ≤ μ Bᵣ + r}`. -/ @@ -333,7 +333,7 @@ section Levy_Prokhorov_is_finer open BoundedContinuousFunction -variable {ι : Type*} {Ω : Type*} [MeasurableSpace Ω] +variable {Ω : Type*} [MeasurableSpace Ω] variable [PseudoMetricSpace Ω] [OpensMeasurableSpace Ω] @@ -497,7 +497,7 @@ section Levy_Prokhorov_metrizes_convergence_in_distribution open BoundedContinuousFunction TopologicalSpace -variable {ι : Type*} {Ω : Type*} [PseudoMetricSpace Ω] +variable {Ω : Type*} [PseudoMetricSpace Ω] variable [MeasurableSpace Ω] [OpensMeasurableSpace Ω] lemma ProbabilityMeasure.toMeasure_add_pos_gt_mem_nhds (P : ProbabilityMeasure Ω) diff --git a/Mathlib/MeasureTheory/Order/UpperLower.lean b/Mathlib/MeasureTheory/Order/UpperLower.lean index 6e04d112e9d588..3813db3c363dd6 100644 --- a/Mathlib/MeasureTheory/Order/UpperLower.lean +++ b/Mathlib/MeasureTheory/Order/UpperLower.lean @@ -48,7 +48,7 @@ Generalize so that it also applies to `ℝ × ℝ`, for example. open Filter MeasureTheory Metric Set open scoped Topology -variable {ι : Type*} [Fintype ι] {s : Set (ι → ℝ)} {x y : ι → ℝ} {δ : ℝ} +variable {ι : Type*} [Fintype ι] {s : Set (ι → ℝ)} {x : ι → ℝ} /-- If we can fit a small ball inside a set `s` intersected with any neighborhood of `x`, then the density of `s` near `x` is not `0`. diff --git a/Mathlib/ModelTheory/Complexity.lean b/Mathlib/ModelTheory/Complexity.lean index e4d9bfc7ef31fe..a44a3ddcd67f95 100644 --- a/Mathlib/ModelTheory/Complexity.lean +++ b/Mathlib/ModelTheory/Complexity.lean @@ -34,11 +34,8 @@ namespace FirstOrder namespace Language -variable {L : Language.{u, v}} {L' : Language} -variable {M : Type w} {N P : Type*} [L.Structure M] [L.Structure N] [L.Structure P] -variable {α : Type u'} {β : Type v'} {γ : Type*} -variable {n l : ℕ} {φ ψ : L.BoundedFormula α l} {θ : L.BoundedFormula α l.succ} -variable {v : α → M} {xs : Fin l → M} +variable {L : Language.{u, v}} {M : Type w} [L.Structure M] {α : Type u'} {β : Type v'} +variable {n l : ℕ} {φ : L.BoundedFormula α l} open FirstOrder Structure Fin diff --git a/Mathlib/ModelTheory/ElementarySubstructures.lean b/Mathlib/ModelTheory/ElementarySubstructures.lean index e0a575f7c8a3d6..c2321b14f9d6a9 100644 --- a/Mathlib/ModelTheory/ElementarySubstructures.lean +++ b/Mathlib/ModelTheory/ElementarySubstructures.lean @@ -29,8 +29,7 @@ namespace Language open Structure -variable {L : Language} {M : Type*} {N : Type*} {P : Type*} {Q : Type*} -variable [L.Structure M] [L.Structure N] [L.Structure P] [L.Structure Q] +variable {L : Language} {M : Type*} [L.Structure M] /-- A substructure is elementary when every formula applied to a tuple in the substructure agrees with its value in the overall structure. -/ diff --git a/Mathlib/ModelTheory/Encoding.lean b/Mathlib/ModelTheory/Encoding.lean index b8219e55752e1e..8e4da06e5a48ad 100644 --- a/Mathlib/ModelTheory/Encoding.lean +++ b/Mathlib/ModelTheory/Encoding.lean @@ -33,15 +33,14 @@ import Mathlib.SetTheory.Cardinal.Arithmetic -/ -universe u v w u' v' +universe u v w u' namespace FirstOrder namespace Language variable {L : Language.{u, v}} -variable {M : Type w} {N P : Type*} [L.Structure M] [L.Structure N] [L.Structure P] -variable {α : Type u'} {β : Type v'} +variable {α : Type u'} open FirstOrder Cardinal diff --git a/Mathlib/ModelTheory/Syntax.lean b/Mathlib/ModelTheory/Syntax.lean index 1c3ec68f882e69..24c9794e5cfbdb 100644 --- a/Mathlib/ModelTheory/Syntax.lean +++ b/Mathlib/ModelTheory/Syntax.lean @@ -61,8 +61,7 @@ namespace FirstOrder namespace Language variable (L : Language.{u, v}) {L' : Language} -variable {M : Type w} {N P : Type*} [L.Structure M] [L.Structure N] [L.Structure P] -variable {α : Type u'} {β : Type v'} {γ : Type*} +variable {M : Type w} {α : Type u'} {β : Type v'} {γ : Type*} open FirstOrder diff --git a/Mathlib/RingTheory/GradedAlgebra/HomogeneousIdeal.lean b/Mathlib/RingTheory/GradedAlgebra/HomogeneousIdeal.lean index f434e98f774a38..bd67fd0c747837 100644 --- a/Mathlib/RingTheory/GradedAlgebra/HomogeneousIdeal.lean +++ b/Mathlib/RingTheory/GradedAlgebra/HomogeneousIdeal.lean @@ -44,7 +44,7 @@ open SetLike DirectSum Set open Pointwise DirectSum -variable {ι σ R A : Type*} +variable {ι σ A : Type*} section HomogeneousDef diff --git a/Mathlib/RingTheory/Localization/Finiteness.lean b/Mathlib/RingTheory/Localization/Finiteness.lean index ab340bfec93301..4998718519d381 100644 --- a/Mathlib/RingTheory/Localization/Finiteness.lean +++ b/Mathlib/RingTheory/Localization/Finiteness.lean @@ -59,7 +59,7 @@ lemma of_isLocalizedModule [Module.Finite R M] : Module.Finite Rₚ Mₚ := by end -variable {R : Type u} [CommRing R] (S : Submonoid R) {M : Type w} [AddCommMonoid M] [Module R M] +variable {R : Type u} [CommRing R] {M : Type w} [AddCommMonoid M] [Module R M] /-- If there exists a finite set `{ r }` of `R` such that `Mᵣ` is `Rᵣ`-finite for each `r`, diff --git a/Mathlib/RingTheory/TensorProduct/MvPolynomial.lean b/Mathlib/RingTheory/TensorProduct/MvPolynomial.lean index 5b8ae61882f731..529b84b2a297c7 100644 --- a/Mathlib/RingTheory/TensorProduct/MvPolynomial.lean +++ b/Mathlib/RingTheory/TensorProduct/MvPolynomial.lean @@ -37,7 +37,7 @@ Let `Semiring R`, `Algebra R S` and `Module R N`. -/ -universe u v w +universe u v noncomputable section @@ -47,8 +47,7 @@ open DirectSum TensorProduct open Set LinearMap Submodule -variable {R : Type u} {M : Type v} {N : Type w} - [CommSemiring R] [AddCommMonoid M] [Module R M] +variable {R : Type u} {N : Type v} [CommSemiring R] variable {σ : Type*} diff --git a/Mathlib/Topology/MetricSpace/Holder.lean b/Mathlib/Topology/MetricSpace/Holder.lean index da0e2b14c4f818..70758a458af3f7 100644 --- a/Mathlib/Topology/MetricSpace/Holder.lean +++ b/Mathlib/Topology/MetricSpace/Holder.lean @@ -239,7 +239,7 @@ end PseudoMetric section Metric -variable [PseudoMetricSpace X] [MetricSpace Y] {C r : ℝ≥0} {f : X → Y} +variable [PseudoMetricSpace X] [MetricSpace Y] {r : ℝ≥0} {f : X → Y} @[simp] lemma holderWith_zero_iff : HolderWith 0 r f ↔ ∀ x₁ x₂, f x₁ = f x₂ := by diff --git a/Mathlib/Topology/MetricSpace/MetricSeparated.lean b/Mathlib/Topology/MetricSpace/MetricSeparated.lean index 2529db5502ed7f..520ee661e12190 100644 --- a/Mathlib/Topology/MetricSpace/MetricSeparated.lean +++ b/Mathlib/Topology/MetricSpace/MetricSeparated.lean @@ -27,7 +27,7 @@ def IsMetricSeparated {X : Type*} [EMetricSpace X] (s t : Set X) := namespace IsMetricSeparated -variable {X : Type*} [EMetricSpace X] {s t : Set X} {x y : X} +variable {X : Type*} [EMetricSpace X] {s t : Set X} @[symm] theorem symm (h : IsMetricSeparated s t) : IsMetricSeparated t s := diff --git a/Mathlib/Topology/Order/DenselyOrdered.lean b/Mathlib/Topology/Order/DenselyOrdered.lean index 80ad140e2daf80..e427346122b7ae 100644 --- a/Mathlib/Topology/Order/DenselyOrdered.lean +++ b/Mathlib/Topology/Order/DenselyOrdered.lean @@ -13,7 +13,7 @@ open Set Filter TopologicalSpace Topology Function open OrderDual (toDual ofDual) -variable {α β γ : Type*} +variable {α β : Type*} section DenselyOrdered diff --git a/Mathlib/Topology/Order/IntermediateValue.lean b/Mathlib/Topology/Order/IntermediateValue.lean index 9b86197c50a9eb..12e59d849ba918 100644 --- a/Mathlib/Topology/Order/IntermediateValue.lean +++ b/Mathlib/Topology/Order/IntermediateValue.lean @@ -45,7 +45,7 @@ intermediate value theorem, connected space, connected set open Filter OrderDual TopologicalSpace Function Set open scoped Topology Filter Interval -universe u v w +universe u v /-! ### Intermediate value theorem on a (pre)connected space @@ -216,9 +216,7 @@ theorem IsPreconnected.eq_univ_of_unbounded {s : Set α} (hs : IsPreconnected s) end -variable {α : Type u} {β : Type v} {γ : Type w} [ConditionallyCompleteLinearOrder α] - [TopologicalSpace α] [OrderTopology α] [ConditionallyCompleteLinearOrder β] [TopologicalSpace β] - [OrderTopology β] [Nonempty γ] +variable {α : Type u} [ConditionallyCompleteLinearOrder α] [TopologicalSpace α] [OrderTopology α] /-- A bounded connected subset of a conditionally complete linear order includes the open interval `(Inf s, Sup s)`. -/ diff --git a/Mathlib/Topology/Order/IsLUB.lean b/Mathlib/Topology/Order/IsLUB.lean index 2d6f0f82dc7200..39f599a2851f8a 100644 --- a/Mathlib/Topology/Order/IsLUB.lean +++ b/Mathlib/Topology/Order/IsLUB.lean @@ -14,12 +14,11 @@ open Set Filter TopologicalSpace Topology Function open OrderDual (toDual ofDual) -variable {α β γ : Type*} +variable {α γ : Type*} section OrderTopology -variable [TopologicalSpace α] [TopologicalSpace β] [LinearOrder α] [LinearOrder β] [OrderTopology α] - [OrderTopology β] +variable [TopologicalSpace α] [LinearOrder α] [OrderTopology α] theorem IsLUB.frequently_mem {a : α} {s : Set α} (ha : IsLUB s a) (hs : s.Nonempty) : ∃ᶠ x in 𝓝[≤] a, x ∈ s := by diff --git a/Mathlib/Topology/Order/Monotone.lean b/Mathlib/Topology/Order/Monotone.lean index c807d80f962d5d..c6aefd9a4b657a 100644 --- a/Mathlib/Topology/Order/Monotone.lean +++ b/Mathlib/Topology/Order/Monotone.lean @@ -19,12 +19,12 @@ open Set Filter TopologicalSpace Topology Function open OrderDual (toDual ofDual) -variable {α β γ : Type*} +variable {α β : Type*} section ConditionallyCompleteLinearOrder variable [ConditionallyCompleteLinearOrder α] [TopologicalSpace α] [OrderTopology α] - [ConditionallyCompleteLinearOrder β] [TopologicalSpace β] [OrderClosedTopology β] [Nonempty γ] + [ConditionallyCompleteLinearOrder β] [TopologicalSpace β] [OrderClosedTopology β] /-- A monotone function continuous at the supremum of a nonempty set sends this supremum to the supremum of the image of this set. -/ @@ -150,7 +150,7 @@ end ConditionallyCompleteLinearOrder section CompleteLinearOrder variable [CompleteLinearOrder α] [TopologicalSpace α] [OrderTopology α] [CompleteLinearOrder β] - [TopologicalSpace β] [OrderClosedTopology β] [Nonempty γ] + [TopologicalSpace β] [OrderClosedTopology β] theorem sSup_mem_closure {s : Set α} (hs : s.Nonempty) : sSup s ∈ closure s := (isLUB_sSup s).mem_closure hs @@ -255,7 +255,6 @@ end CompleteLinearOrder section ConditionallyCompleteLinearOrder variable [ConditionallyCompleteLinearOrder α] [TopologicalSpace α] [OrderTopology α] - [ConditionallyCompleteLinearOrder β] [TopologicalSpace β] [OrderClosedTopology β] [Nonempty γ] theorem csSup_mem_closure {s : Set α} (hs : s.Nonempty) (B : BddAbove s) : sSup s ∈ closure s := (isLUB_csSup hs B).mem_closure hs diff --git a/Mathlib/Topology/UniformSpace/Equicontinuity.lean b/Mathlib/Topology/UniformSpace/Equicontinuity.lean index 807c30865e06db..c3444a738efe49 100644 --- a/Mathlib/Topology/UniformSpace/Equicontinuity.lean +++ b/Mathlib/Topology/UniformSpace/Equicontinuity.lean @@ -82,8 +82,8 @@ section open UniformSpace Filter Set Uniformity Topology UniformConvergence Function -variable {ι κ X X' Y Z α α' β β' γ 𝓕 : Type*} [tX : TopologicalSpace X] [tY : TopologicalSpace Y] - [tZ : TopologicalSpace Z] [uα : UniformSpace α] [uβ : UniformSpace β] [uγ : UniformSpace γ] +variable {ι κ X X' Y α α' β β' γ : Type*} [tX : TopologicalSpace X] [tY : TopologicalSpace Y] + [uα : UniformSpace α] [uβ : UniformSpace β] [uγ : UniformSpace γ] /-- A family `F : ι → X → α` of functions from a topological space to a uniform space is *equicontinuous at `x₀ : X`* if, for all entourages `U ∈ 𝓤 α`, there is a neighborhood `V` of `x₀` diff --git a/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean b/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean index 00cd2deafccea0..9a7542b8c7d0c1 100644 --- a/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean +++ b/Mathlib/Topology/UniformSpace/UniformConvergenceTopology.lean @@ -197,7 +197,7 @@ open UniformConvergence namespace UniformFun variable (α β : Type*) {γ ι : Type*} -variable {s s' : Set α} {x : α} {p : Filter ι} {g : ι → α} +variable {p : Filter ι} /-- Basis sets for the uniformity of uniform convergence: `gen α β V` is the set of pairs `(f, g)` of functions `α →ᵤ β` such that `∀ x, (f x, g x) ∈ V`. -/ @@ -555,7 +555,7 @@ end UniformFun namespace UniformOnFun variable {α β : Type*} {γ ι : Type*} -variable {s s' : Set α} {x : α} {p : Filter ι} {g : ι → α} +variable {s : Set α} {p : Filter ι} local notation "𝒰(" α ", " β ", " u ")" => @UniformFun.uniformSpace α β u From 8d6f380fde8631e39a62b5a009b2ffec2eb3c17f Mon Sep 17 00:00:00 2001 From: Yongle Hu Date: Wed, 16 Oct 2024 15:54:25 +0000 Subject: [PATCH 241/425] feat(RingTheory/Flat/Basic): drop `[Small.{v} R]` assumption in `Module.Flat.iff_*` lemmas (#17484) Drop `[Small.{v} R]` assumption from `Module.Flat.iff_*` lemmas [Module.Flat.iff_rTensor_preserves_injective_linearMap](https://leanprover-community.github.io/mathlib4_docs/Mathlib/RingTheory/Flat/Basic.html#Module.Flat.iff_rTensor_preserves_injective_linearMap), [Module.Flat.iff_lTensor_exact](https://leanprover-community.github.io/mathlib4_docs/Mathlib/RingTheory/Flat/Basic.html#Module.Flat.iff_lTensor_exact), and so on. Co-authored-by: Hu Yongle <2065545849@qq.com> --- Mathlib/RingTheory/Flat/Basic.lean | 175 +++++++++++++++++++---------- 1 file changed, 115 insertions(+), 60 deletions(-) diff --git a/Mathlib/RingTheory/Flat/Basic.lean b/Mathlib/RingTheory/Flat/Basic.lean index 813b32f84d0ac2..9c3da85861bf39 100644 --- a/Mathlib/RingTheory/Flat/Basic.lean +++ b/Mathlib/RingTheory/Flat/Basic.lean @@ -1,7 +1,7 @@ /- Copyright (c) 2020 Johan Commelin. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Johan Commelin, Jujian Zhang +Authors: Johan Commelin, Jujian Zhang, Yongle Hu -/ import Mathlib.Algebra.DirectSum.Finsupp import Mathlib.Algebra.DirectSum.Module @@ -39,14 +39,13 @@ See . * `Module.Flat.preserves_injective_linearMap`: If `M` is a flat module then tensoring with `M` preserves injectivity of linear maps. This lemma is fully universally polymorphic in all arguments, i.e. `R`, `M` and linear maps `N → N'` can all have different universe levels. -* `Module.Flat.iff_rTensor_preserves_injective_linearMap`: a module is flat iff tensoring preserves - injectivity in the ring's universe (or higher). - -## Implementation notes -In `Module.Flat.iff_rTensor_preserves_injective_linearMap`, we require that the universe level of -the ring is lower than or equal to that of the module. This requirement is to make sure ideals of -the ring can be lifted to the universe of the module. It is unclear if this lemma also holds -when the module lives in a lower universe. +* `Module.Flat.iff_rTensor_preserves_injective_linearMap`: a module is flat iff tensoring modules + in the higher universe preserves injectivity . +* `Module.Flat.lTensor_exact`: If `M` is a flat module then tensoring with `M` is an exact + functor. This lemma is fully universally polymorphic in all arguments, i.e. + `R`, `M` and linear maps `N → N' → N''` can all have different universe levels. +* `Module.Flat.iff_lTensor_exact`: a module is flat iff tensoring modules + in the higher universe is an exact functor. ## TODO @@ -55,7 +54,7 @@ when the module lives in a lower universe. -/ -universe u v w +universe v' u v w namespace Module @@ -144,6 +143,24 @@ lemma of_linearEquiv [f : Flat R M] (e : N ≃ₗ[R] M) : Flat R N := by have h : e.symm.toLinearMap.comp e.toLinearMap = LinearMap.id := by simp exact of_retract _ _ _ e.toLinearMap e.symm.toLinearMap h +/-- If an `R`-module `M` is linearly equivalent to another `R`-module `N`, then `M` is flat + if and only if `N` is flat. -/ +lemma equiv_iff (e : M ≃ₗ[R] N) : Flat R M ↔ Flat R N := + ⟨fun _ => of_linearEquiv R M N e.symm, fun _ => of_linearEquiv R N M e⟩ + +instance ulift [Module.Flat R M] : Module.Flat R (ULift.{v'} M) := + of_linearEquiv R M (ULift.{v'} M) ULift.moduleEquiv + +instance (priority := 100) of_ulift [Module.Flat R (ULift.{v'} M)] : Module.Flat R M := + of_linearEquiv R (ULift.{v'} M) M ULift.moduleEquiv.symm + +instance shrink [Small.{v'} M] [Module.Flat R M] : Module.Flat R (Shrink.{v'} M) := + of_linearEquiv R M (Shrink.{v'} M) (Shrink.linearEquiv M R) + +instance (priority := 100) of_shrink [Small.{v'} M] [Module.Flat R (Shrink.{v'} M)] : + Module.Flat R M := + of_linearEquiv R (Shrink.{v'} M) M (Shrink.linearEquiv M R).symm + /-- A direct sum of flat `R`-modules is flat. -/ instance directSum (ι : Type v) (M : ι → Type w) [(i : ι) → AddCommGroup (M i)] [(i : ι) → Module R (M i)] [F : (i : ι) → (Flat R (M i))] : Flat R (⨁ i, M i) := by @@ -250,28 +267,55 @@ theorem lTensor_preserves_injective_linearMap {N' : Type*} [AddCommGroup N'] [Mo (L.lTensor_inj_iff_rTensor_inj M).2 (rTensor_preserves_injective_linearMap L hL) variable (R M) in -/-- -M is flat if and only if `f ⊗ 𝟙 M` is injective whenever `f` is an injective linear map. --/ -lemma iff_rTensor_preserves_injective_linearMap [Small.{v} R] : - Flat R M ↔ - ∀ ⦃N N' : Type v⦄ [AddCommGroup N] [AddCommGroup N'] [Module R N] [Module R N'] - (L : N →ₗ[R] N'), Function.Injective L → Function.Injective (L.rTensor M) := by - rw [iff_characterModule_injective, - injective_characterModule_iff_rTensor_preserves_injective_linearMap] +/-- `M` is flat if and only if `f ⊗ 𝟙 M` is injective whenever `f` is an injective linear map. + See `Module.Flat.iff_rTensor_preserves_injective_linearMap` to specialize the universe of + `N, N', N''` to `Type (max u v)`. -/ +lemma iff_rTensor_preserves_injective_linearMap' [Small.{v'} R] [Small.{v'} M] : Flat R M ↔ + ∀ ⦃N N' : Type v'⦄ [AddCommGroup N] [AddCommGroup N'] [Module R N] [Module R N'] + (f : N →ₗ[R] N') (_ : Function.Injective f), Function.Injective (f.rTensor M) := + (Module.Flat.equiv_iff R M (Shrink.{v'} M) (Shrink.linearEquiv M R).symm).trans <| + iff_characterModule_injective.trans <| + (injective_characterModule_iff_rTensor_preserves_injective_linearMap R (Shrink.{v'} M)).trans + <| forall₅_congr <| fun N N' _ _ _ => forall₃_congr <| fun _ f _ => + let frmu := f.rTensor (Shrink.{v'} M) + let frm := f.rTensor M + let emn := TensorProduct.congr (LinearEquiv.refl R N) (Shrink.linearEquiv M R) + let emn' := TensorProduct.congr (LinearEquiv.refl R N') (Shrink.linearEquiv M R) + have h : emn'.toLinearMap.comp frmu = frm.comp emn.toLinearMap := TensorProduct.ext rfl + (EquivLike.comp_injective frmu emn').symm.trans <| + (congrArg Function.Injective (congrArg DFunLike.coe h)).to_iff.trans <| + EquivLike.injective_comp emn frm variable (R M) in -/-- -M is flat if and only if `𝟙 M ⊗ f` is injective whenever `f` is an injective linear map. --/ -lemma iff_lTensor_preserves_injective_linearMap [Small.{v} R] : - Flat R M ↔ - ∀ ⦃N N' : Type v⦄ [AddCommGroup N] [AddCommGroup N'] [Module R N] [Module R N'] +/-- `M` is flat if and only if `f ⊗ 𝟙 M` is injective whenever `f` is an injective linear map. + See `Module.Flat.iff_rTensor_preserves_injective_linearMap'` to generalize the universe of + `N, N', N''` to any universe that is higher than `R` and `M`. -/ +lemma iff_rTensor_preserves_injective_linearMap : Flat R M ↔ + ∀ ⦃N N' : Type (max u v)⦄ [AddCommGroup N] [AddCommGroup N'] [Module R N] [Module R N'] + (f : N →ₗ[R] N') (_ : Function.Injective f), Function.Injective (f.rTensor M) := + iff_rTensor_preserves_injective_linearMap'.{max u v} R M + +variable (R M) in +/-- `M` is flat if and only if `𝟙 M ⊗ f` is injective whenever `f` is an injective linear map. + See `Module.Flat.iff_lTensor_preserves_injective_linearMap` to specialize the universe of + `N, N', N''` to `Type (max u v)`. -/ +lemma iff_lTensor_preserves_injective_linearMap' [Small.{v'} R] [Small.{v'} M] : Flat R M ↔ + ∀ ⦃N N' : Type v'⦄ [AddCommGroup N] [AddCommGroup N'] [Module R N] [Module R N'] (L : N →ₗ[R] N'), Function.Injective L → Function.Injective (L.lTensor M) := by - simp_rw [iff_rTensor_preserves_injective_linearMap, LinearMap.lTensor_inj_iff_rTensor_inj] + simp_rw [iff_rTensor_preserves_injective_linearMap', LinearMap.lTensor_inj_iff_rTensor_inj] + +variable (R M) in +/-- `M` is flat if and only if `𝟙 M ⊗ f` is injective whenever `f` is an injective linear map. + See `Module.Flat.iff_lTensor_preserves_injective_linearMap'` to generalize the universe of + `N, N', N''` to any universe that is higher than `R` and `M`. -/ +lemma iff_lTensor_preserves_injective_linearMap : Flat R M ↔ + ∀ ⦃N N' : Type (max u v)⦄ [AddCommGroup N] [AddCommGroup N'] [Module R N] [Module R N'] + (f : N →ₗ[R] N') (_ : Function.Injective f), Function.Injective (f.lTensor M) := + iff_lTensor_preserves_injective_linearMap'.{max u v} R M variable (M) in -lemma lTensor_exact [Small.{v} R] [flat : Flat R M] ⦃N N' N'' : Type v⦄ +/-- If `M` is flat then `M ⊗ -` is an exact functor. -/ +lemma lTensor_exact [Flat R M] ⦃N N' N'' : Type*⦄ [AddCommGroup N] [AddCommGroup N'] [AddCommGroup N''] [Module R N] [Module R N'] [Module R N''] ⦃f : N →ₗ[R] N'⦄ ⦃g : N' →ₗ[R] N''⦄ (exact : Function.Exact f g) : Function.Exact (f.lTensor M) (g.lTensor M) := by @@ -280,18 +324,15 @@ lemma lTensor_exact [Small.{v} R] [flat : Flat R M] ⦃N N' N'' : Type v⦄ Submodule.subtype _ ∘ₗ (LinearMap.quotKerEquivRange g).toLinearMap ∘ₗ Submodule.quotEquivOfEq (LinearMap.range f) (LinearMap.ker g) (LinearMap.exact_iff.mp exact).symm - suffices exact1 : Function.Exact (f.lTensor M) (π.lTensor M) by - rw [show g = ι.comp π by aesop, lTensor_comp] - exact exact1.comp_injective - (inj := iff_lTensor_preserves_injective_linearMap R M |>.mp flat _ <| by - simpa [ι] using Subtype.val_injective) - (h0 := map_zero _) - + rw [show g = ι.comp π from rfl, lTensor_comp] + exact exact1.comp_injective _ (lTensor_preserves_injective_linearMap ι <| by + simpa [ι] using Subtype.val_injective) (map_zero _) exact _root_.lTensor_exact _ (fun x => by simp [π]) Quotient.surjective_Quotient_mk'' variable (M) in -lemma rTensor_exact [Small.{v} R] [flat : Flat R M] ⦃N N' N'' : Type v⦄ +/-- If `M` is flat then `- ⊗ M` is an exact functor. -/ +lemma rTensor_exact [Flat R M] ⦃N N' N'' : Type*⦄ [AddCommGroup N] [AddCommGroup N'] [AddCommGroup N''] [Module R N] [Module R N'] [Module R N''] ⦃f : N →ₗ[R] N'⦄ ⦃g : N' →ₗ[R] N''⦄ (exact : Function.Exact f g) : Function.Exact (f.rTensor M) (g.rTensor M) := by @@ -300,41 +341,55 @@ lemma rTensor_exact [Small.{v} R] [flat : Flat R M] ⦃N N' N'' : Type v⦄ Submodule.subtype _ ∘ₗ (LinearMap.quotKerEquivRange g).toLinearMap ∘ₗ Submodule.quotEquivOfEq (LinearMap.range f) (LinearMap.ker g) (LinearMap.exact_iff.mp exact).symm - suffices exact1 : Function.Exact (f.rTensor M) (π.rTensor M) by - rw [show g = ι.comp π by aesop, rTensor_comp] - exact exact1.comp_injective - (inj := iff_rTensor_preserves_injective_linearMap R M |>.mp flat _ <| by - simpa [ι] using Subtype.val_injective) - (h0 := map_zero _) - - exact _root_.rTensor_exact _ (fun x => by simp [π]) Quotient.surjective_Quotient_mk'' - -/-- -M is flat if and only if `M ⊗ -` is a left exact functor. --/ -lemma iff_lTensor_exact [Small.{v} R] : - Flat R M ↔ - ∀ ⦃N N' N'' : Type v⦄ [AddCommGroup N] [AddCommGroup N'] [AddCommGroup N''] + rw [show g = ι.comp π from rfl, rTensor_comp] + exact exact1.comp_injective _ (rTensor_preserves_injective_linearMap ι <| by + simpa [ι] using Subtype.val_injective) (map_zero _) + exact _root_.rTensor_exact M (fun x => by simp [π]) Quotient.surjective_Quotient_mk'' + +/-- `M` is flat if and only if `M ⊗ -` is an exact functor. See + `Module.Flat.iff_lTensor_exact` to specialize the universe of `N, N', N''` to `Type (max u v)`. -/ +theorem iff_lTensor_exact' [Small.{v'} R] [Small.{v'} M] : Flat R M ↔ + ∀ ⦃N N' N'' : Type v'⦄ [AddCommGroup N] [AddCommGroup N'] [AddCommGroup N''] [Module R N] [Module R N'] [Module R N''] ⦃f : N →ₗ[R] N'⦄ ⦃g : N' →ₗ[R] N''⦄, Function.Exact f g → Function.Exact (f.lTensor M) (g.lTensor M) := by - refine ⟨fun _ => lTensor_exact M, fun H => iff_lTensor_preserves_injective_linearMap R M |>.mpr + refine ⟨fun _ => lTensor_exact M, fun H => iff_lTensor_preserves_injective_linearMap' R M |>.mpr fun N' N'' _ _ _ _ L hL => LinearMap.ker_eq_bot |>.mp <| eq_bot_iff |>.mpr fun x (hx : _ = 0) => ?_⟩ - simpa [Eq.comm] using @H PUnit N' N'' _ _ _ _ _ _ 0 L (fun x => by aesop) x |>.mp hx + simpa [Eq.comm] using @H PUnit N' N'' _ _ _ _ _ _ 0 L (fun x => by + simp_rw [Set.mem_range, LinearMap.zero_apply, exists_const] + exact (L.map_eq_zero_iff hL).trans eq_comm) x |>.mp hx + +/-- `M` is flat if and only if `M ⊗ -` is an exact functor. + See `Module.Flat.iff_lTensor_exact'` to generalize the universe of + `N, N', N''` to any universe that is higher than `R` and `M`. -/ +theorem iff_lTensor_exact : Flat R M ↔ + ∀ ⦃N N' N'' : Type (max u v)⦄ [AddCommGroup N] [AddCommGroup N'] [AddCommGroup N''] + [Module R N] [Module R N'] [Module R N''] ⦃f : N →ₗ[R] N'⦄ ⦃g : N' →ₗ[R] N''⦄, + Function.Exact f g → Function.Exact (f.lTensor M) (g.lTensor M) := + iff_lTensor_exact'.{max u v} -/-- -M is flat if and only if `- ⊗ M` is a left exact functor. --/ -lemma iff_rTensor_exact [Small.{v} R] : - Flat R M ↔ - ∀ ⦃N N' N'' : Type v⦄ [AddCommGroup N] [AddCommGroup N'] [AddCommGroup N''] +/-- `M` is flat if and only if `- ⊗ M` is an exact functor. See + `Module.Flat.iff_rTensor_exact` to specialize the universe of `N, N', N''` to `Type (max u v)`. -/ +theorem iff_rTensor_exact' [Small.{v'} R] [Small.{v'} M] : Flat R M ↔ + ∀ ⦃N N' N'' : Type v'⦄ [AddCommGroup N] [AddCommGroup N'] [AddCommGroup N''] [Module R N] [Module R N'] [Module R N''] ⦃f : N →ₗ[R] N'⦄ ⦃g : N' →ₗ[R] N''⦄, Function.Exact f g → Function.Exact (f.rTensor M) (g.rTensor M) := by - refine ⟨fun _ => rTensor_exact M, fun H => iff_rTensor_preserves_injective_linearMap R M |>.mpr + refine ⟨fun _ => rTensor_exact M, fun H => iff_rTensor_preserves_injective_linearMap' R M |>.mpr fun N' N'' _ _ _ _ L hL => LinearMap.ker_eq_bot |>.mp <| eq_bot_iff |>.mpr fun x (hx : _ = 0) => ?_⟩ - simpa [Eq.comm] using @H PUnit N' N'' _ _ _ _ _ _ 0 L (fun x => by aesop) x |>.mp hx + simpa [Eq.comm] using @H PUnit N' N'' _ _ _ _ _ _ 0 L (fun x => by + simp_rw [Set.mem_range, LinearMap.zero_apply, exists_const] + exact (L.map_eq_zero_iff hL).trans eq_comm) x |>.mp hx + +/-- `M` is flat if and only if `- ⊗ M` is an exact functor. + See `Module.Flat.iff_rTensor_exact'` to generalize the universe of + `N, N', N''` to any universe that is higher than `R` and `M`. -/ +theorem iff_rTensor_exact : Flat R M ↔ + ∀ ⦃N N' N'' : Type (max u v)⦄ [AddCommGroup N] [AddCommGroup N'] [AddCommGroup N''] + [Module R N] [Module R N'] [Module R N''] ⦃f : N →ₗ[R] N'⦄ ⦃g : N' →ₗ[R] N''⦄, + Function.Exact f g → Function.Exact (f.rTensor M) (g.rTensor M) := + iff_rTensor_exact'.{max u v} end Flat From ec9e50a65ce6c7740e7676060d103be493f2169b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Wed, 16 Oct 2024 16:23:46 +0000 Subject: [PATCH 242/425] =?UTF-8?q?chore:=20`measurable=5FspanningSets`=20?= =?UTF-8?q?=E2=86=92=20`measurableSet=5FspanningSets`=20(#17834)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was misnamed. From GibbsMeasure --- .../Constructions/BorelSpace/Real.lean | 2 +- .../Decomposition/Exhaustion.lean | 2 +- .../MeasureTheory/Decomposition/Lebesgue.lean | 4 +-- .../Function/AEEqOfIntegral.lean | 4 +-- .../ConditionalExpectation/CondexpL1.lean | 2 +- Mathlib/MeasureTheory/Function/Jacobian.lean | 4 +-- .../Function/StronglyMeasurable/Basic.lean | 2 +- Mathlib/MeasureTheory/Integral/Lebesgue.lean | 6 ++-- Mathlib/MeasureTheory/Measure/Regular.lean | 2 +- Mathlib/MeasureTheory/Measure/Trim.lean | 2 +- .../MeasureTheory/Measure/Typeclasses.lean | 30 ++++++++++--------- 11 files changed, 31 insertions(+), 29 deletions(-) diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean index 2f7ad05237166e..9dfc57bb162910 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean @@ -484,7 +484,7 @@ theorem exists_spanning_measurableSet_le {f : α → ℝ≥0} (hf : Measurable f let sets n := sigma_finite_sets n ∩ norm_sets n have h_meas : ∀ n, MeasurableSet (sets n) := by refine fun n => MeasurableSet.inter ?_ ?_ - · exact measurable_spanningSets μ n + · exact measurableSet_spanningSets μ n · exact hf measurableSet_Iic have h_finite : ∀ n, μ (sets n) < ∞ := by refine fun n => (measure_mono Set.inter_subset_left).trans_lt ?_ diff --git a/Mathlib/MeasureTheory/Decomposition/Exhaustion.lean b/Mathlib/MeasureTheory/Decomposition/Exhaustion.lean index a6f283377c6c5c..0cf002bd37fb1e 100644 --- a/Mathlib/MeasureTheory/Decomposition/Exhaustion.lean +++ b/Mathlib/MeasureTheory/Decomposition/Exhaustion.lean @@ -284,7 +284,7 @@ lemma measure_compl_sigmaFiniteSetWRT (hμν : μ ≪ ν) [SigmaFinite μ] [SFin by_contra h0 refine ENNReal.top_ne_zero ?_ rw [← h h0, ← Measure.iSup_restrict_spanningSets] - simp_rw [Measure.restrict_apply' (measurable_spanningSets μ _), ENNReal.iSup_eq_zero] + simp_rw [Measure.restrict_apply' (measurableSet_spanningSets μ _), ENNReal.iSup_eq_zero] intro i by_contra h_ne_zero have h_zero_top := measure_eq_top_of_subset_compl_sigmaFiniteSetWRT diff --git a/Mathlib/MeasureTheory/Decomposition/Lebesgue.lean b/Mathlib/MeasureTheory/Decomposition/Lebesgue.lean index b82573cc25bc5e..291ea3c448fc53 100644 --- a/Mathlib/MeasureTheory/Decomposition/Lebesgue.lean +++ b/Mathlib/MeasureTheory/Decomposition/Lebesgue.lean @@ -369,7 +369,7 @@ theorem rnDeriv_lt_top (μ ν : Measure α) [SigmaFinite μ] : ∀ᵐ x ∂ν, suffices ∀ n, ∀ᵐ x ∂ν, x ∈ spanningSets μ n → μ.rnDeriv ν x < ∞ by filter_upwards [ae_all_iff.2 this] with _ hx using hx _ (mem_spanningSetsIndex _ _) intro n - rw [← ae_restrict_iff' (measurable_spanningSets _ _)] + rw [← ae_restrict_iff' (measurableSet_spanningSets _ _)] apply ae_lt_top (measurable_rnDeriv _ _) refine (lintegral_rnDeriv_lt_top_of_measure_ne_top _ ?_).ne exact (measure_spanningSets_lt_top _ _).ne @@ -938,7 +938,7 @@ nonrec instance (priority := 100) haveLebesgueDecomposition_of_sigmaFinite · exact .sfinite_of_isFiniteMeasure fun μ _ ↦ this μ ‹_› -- Take a disjoint cover that consists of sets of finite measure `ν`. set s : ℕ → Set α := disjointed (spanningSets ν) - have hsm : ∀ n, MeasurableSet (s n) := .disjointed <| measurable_spanningSets _ + have hsm : ∀ n, MeasurableSet (s n) := .disjointed <| measurableSet_spanningSets _ have hs : ∀ n, Fact (ν (s n) < ⊤) := fun n ↦ ⟨lt_of_le_of_lt (measure_mono <| disjointed_le ..) (measure_spanningSets_lt_top ν n)⟩ -- Note that the restrictions of `μ` and `ν` to `s n` are finite measures. diff --git a/Mathlib/MeasureTheory/Function/AEEqOfIntegral.lean b/Mathlib/MeasureTheory/Function/AEEqOfIntegral.lean index d9303573bf9fd6..311f212e8f62fa 100644 --- a/Mathlib/MeasureTheory/Function/AEEqOfIntegral.lean +++ b/Mathlib/MeasureTheory/Function/AEEqOfIntegral.lean @@ -423,10 +423,10 @@ theorem ae_eq_zero_of_forall_setIntegral_eq_of_sigmaFinite [SigmaFinite μ] {f : (hf_zero : ∀ s : Set α, MeasurableSet s → μ s < ∞ → ∫ x in s, f x ∂μ = 0) : f =ᵐ[μ] 0 := by let S := spanningSets μ rw [← @Measure.restrict_univ _ _ μ, ← iUnion_spanningSets μ, EventuallyEq, ae_iff, - Measure.restrict_apply' (MeasurableSet.iUnion (measurable_spanningSets μ))] + Measure.restrict_apply' (MeasurableSet.iUnion (measurableSet_spanningSets μ))] rw [Set.inter_iUnion, measure_iUnion_null_iff] intro n - have h_meas_n : MeasurableSet (S n) := measurable_spanningSets μ n + have h_meas_n : MeasurableSet (S n) := measurableSet_spanningSets μ n have hμn : μ (S n) < ∞ := measure_spanningSets_lt_top μ n rw [← Measure.restrict_apply' h_meas_n] exact ae_eq_zero_restrict_of_forall_setIntegral_eq_zero hf_int_finite hf_zero h_meas_n hμn.ne diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL1.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL1.lean index a0b70b96c18845..633ff287c5581b 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL1.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL1.lean @@ -395,7 +395,7 @@ to the integral of `f` on that set. See also `setIntegral_condexp`, the similar theorem setIntegral_condexpL1CLM (f : α →₁[μ] F') (hs : MeasurableSet[m] s) : ∫ x in s, condexpL1CLM F' hm μ f x ∂μ = ∫ x in s, f x ∂μ := by let S := spanningSets (μ.trim hm) - have hS_meas : ∀ i, MeasurableSet[m] (S i) := measurable_spanningSets (μ.trim hm) + have hS_meas : ∀ i, MeasurableSet[m] (S i) := measurableSet_spanningSets (μ.trim hm) have hS_meas0 : ∀ i, MeasurableSet (S i) := fun i => hm _ (hS_meas i) have hs_eq : s = ⋃ i, S i ∩ s := by simp_rw [Set.inter_comm] diff --git a/Mathlib/MeasureTheory/Function/Jacobian.lean b/Mathlib/MeasureTheory/Function/Jacobian.lean index ce6116b747cb50..77a1878659c770 100644 --- a/Mathlib/MeasureTheory/Function/Jacobian.lean +++ b/Mathlib/MeasureTheory/Function/Jacobian.lean @@ -883,7 +883,7 @@ theorem addHaar_image_le_lintegral_abs_det_fderiv (hs : MeasurableSet s) have u_meas : ∀ n, MeasurableSet (u n) := by intro n apply MeasurableSet.disjointed fun i => ?_ - exact measurable_spanningSets μ i + exact measurableSet_spanningSets μ i have A : s = ⋃ n, s ∩ u n := by rw [← inter_iUnion, iUnion_disjointed, iUnion_spanningSets, inter_univ] calc @@ -1035,7 +1035,7 @@ theorem lintegral_abs_det_fderiv_le_addHaar_image (hs : MeasurableSet s) have u_meas : ∀ n, MeasurableSet (u n) := by intro n apply MeasurableSet.disjointed fun i => ?_ - exact measurable_spanningSets μ i + exact measurableSet_spanningSets μ i have A : s = ⋃ n, s ∩ u n := by rw [← inter_iUnion, iUnion_disjointed, iUnion_spanningSets, inter_univ] calc diff --git a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean index b9644215bcca28..7d3943e021a7c0 100644 --- a/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean +++ b/Mathlib/MeasureTheory/Function/StronglyMeasurable/Basic.lean @@ -269,7 +269,7 @@ theorem finStronglyMeasurable_of_set_sigmaFinite [TopologicalSpace β] [Zero β] FinStronglyMeasurable f μ := by haveI : SigmaFinite (μ.restrict t) := htμ let S := spanningSets (μ.restrict t) - have hS_meas : ∀ n, MeasurableSet (S n) := measurable_spanningSets (μ.restrict t) + have hS_meas : ∀ n, MeasurableSet (S n) := measurableSet_spanningSets (μ.restrict t) let f_approx := hf_meas.approx let fs n := SimpleFunc.restrict (f_approx n) (S n ∩ t) have h_fs_t_compl : ∀ n, ∀ x, x ∉ t → fs n x = 0 := by diff --git a/Mathlib/MeasureTheory/Integral/Lebesgue.lean b/Mathlib/MeasureTheory/Integral/Lebesgue.lean index ea728df43b1407..5be3b2d1f299b2 100644 --- a/Mathlib/MeasureTheory/Integral/Lebesgue.lean +++ b/Mathlib/MeasureTheory/Integral/Lebesgue.lean @@ -1898,11 +1898,11 @@ theorem exists_pos_lintegral_lt_of_sigmaFinite (μ : Measure α) [SigmaFinite μ obtain ⟨δ, δpos, δsum⟩ : ∃ δ : ℕ → ℝ≥0, (∀ i, 0 < δ i) ∧ (∑' i, μ (s i) * δ i) < ε := ENNReal.exists_pos_tsum_mul_lt_of_countable ε0 _ fun n => (this n).ne set N : α → ℕ := spanningSetsIndex μ - have hN_meas : Measurable N := measurable_spanningSetsIndex μ + 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] - simpa [N, hNs, lintegral_countable', measurable_spanningSetsIndex, mul_comm] using δsum + simpa [N, hNs, lintegral_countable', measurableSet_spanningSetsIndex, mul_comm] using δsum theorem lintegral_trim {μ : Measure α} (hm : m ≤ m0) {f : α → ℝ≥0∞} (hf : Measurable[m] f) : ∫⁻ a, f a ∂μ.trim hm = ∫⁻ a, f a ∂μ := by @@ -1939,7 +1939,7 @@ theorem univ_le_of_forall_fin_meas_le {μ : Measure α} (hm : m ≤ m0) [SigmaFi f univ ≤ C := by let S := @spanningSets _ m (μ.trim hm) _ have hS_mono : Monotone S := @monotone_spanningSets _ m (μ.trim hm) _ - have hS_meas : ∀ n, MeasurableSet[m] (S n) := @measurable_spanningSets _ m (μ.trim hm) _ + have hS_meas : ∀ n, MeasurableSet[m] (S n) := @measurableSet_spanningSets _ m (μ.trim hm) _ rw [← @iUnion_spanningSets _ m (μ.trim hm)] refine (h_F_lim S hS_meas hS_mono).trans ?_ refine iSup_le fun n => hf (S n) (hS_meas n) ?_ diff --git a/Mathlib/MeasureTheory/Measure/Regular.lean b/Mathlib/MeasureTheory/Measure/Regular.lean index 362b5a971e2a40..f283ccf0b3e834 100644 --- a/Mathlib/MeasureTheory/Measure/Regular.lean +++ b/Mathlib/MeasureTheory/Measure/Regular.lean @@ -511,7 +511,7 @@ lemma of_sigmaFinite [SigmaFinite μ] : rw [← (monotone_const.inter (monotone_spanningSets μ)).measure_iUnion, hBU] rw [this] at hr rcases lt_iSup_iff.1 hr with ⟨n, hn⟩ - refine ⟨s ∩ B n, inter_subset_left, ⟨hs.inter (measurable_spanningSets μ n), ?_⟩, hn⟩ + refine ⟨s ∩ B n, inter_subset_left, ⟨hs.inter (measurableSet_spanningSets μ n), ?_⟩, hn⟩ exact ((measure_mono inter_subset_right).trans_lt (measure_spanningSets_lt_top μ n)).ne variable [TopologicalSpace α] diff --git a/Mathlib/MeasureTheory/Measure/Trim.lean b/Mathlib/MeasureTheory/Measure/Trim.lean index af9a03aa6916a6..3afc9ad874998d 100644 --- a/Mathlib/MeasureTheory/Measure/Trim.lean +++ b/Mathlib/MeasureTheory/Measure/Trim.lean @@ -104,7 +104,7 @@ theorem sigmaFiniteTrim_mono {m m₂ m0 : MeasurableSpace α} {μ : Measure α} 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₂ (measurable_spanningSets _ _)] + 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 _ _ diff --git a/Mathlib/MeasureTheory/Measure/Typeclasses.lean b/Mathlib/MeasureTheory/Measure/Typeclasses.lean index 5dc07c2bfba726..888fe3d0777ee7 100644 --- a/Mathlib/MeasureTheory/Measure/Typeclasses.lean +++ b/Mathlib/MeasureTheory/Measure/Typeclasses.lean @@ -672,10 +672,12 @@ theorem monotone_spanningSets (μ : Measure α) [SigmaFinite μ] : Monotone (spa lemma spanningSets_mono [SigmaFinite μ] {m n : ℕ} (hmn : m ≤ n) : spanningSets μ m ⊆ spanningSets μ n := monotone_spanningSets _ hmn -theorem measurable_spanningSets (μ : Measure α) [SigmaFinite μ] (i : ℕ) : +theorem measurableSet_spanningSets (μ : Measure α) [SigmaFinite μ] (i : ℕ) : MeasurableSet (spanningSets μ i) := MeasurableSet.iUnion fun j => MeasurableSet.iUnion fun _ => μ.toFiniteSpanningSetsIn.set_mem j +@[deprecated (since := "2024-10-16")] alias measurable_spanningSets := measurableSet_spanningSets + theorem measure_spanningSets_lt_top (μ : Measure α) [SigmaFinite μ] (i : ℕ) : μ (spanningSets μ i) < ∞ := measure_biUnion_lt_top (finite_le_nat i) fun j _ => μ.toFiniteSpanningSetsIn.finite j @@ -694,9 +696,9 @@ noncomputable def spanningSetsIndex (μ : Measure α) [SigmaFinite μ] (x : α) Nat.find <| iUnion_eq_univ_iff.1 (iUnion_spanningSets μ) x open scoped Classical in -theorem measurable_spanningSetsIndex (μ : Measure α) [SigmaFinite μ] : +theorem measurableSet_spanningSetsIndex (μ : Measure α) [SigmaFinite μ] : Measurable (spanningSetsIndex μ) := - measurable_find _ <| measurable_spanningSets μ + measurable_find _ <| measurableSet_spanningSets μ open scoped Classical in theorem preimage_spanningSetsIndex_singleton (μ : Measure α) [SigmaFinite μ] (n : ℕ) : @@ -726,7 +728,7 @@ theorem eventually_mem_spanningSets (μ : Measure α) [SigmaFinite μ] (x : α) theorem sum_restrict_disjointed_spanningSets (μ ν : Measure α) [SigmaFinite ν] : sum (fun n ↦ μ.restrict (disjointed (spanningSets ν) n)) = μ := by rw [← restrict_iUnion (disjoint_disjointed _) - (MeasurableSet.disjointed (measurable_spanningSets _)), + (MeasurableSet.disjointed (measurableSet_spanningSets _)), iUnion_disjointed, iUnion_spanningSets, restrict_univ] instance (priority := 100) [SigmaFinite μ] : SFinite μ := by @@ -988,9 +990,9 @@ theorem iSup_restrict_spanningSets [SigmaFinite μ] (s : Set α) : ⨆ i, μ.restrict (spanningSets μ i) s = μ s := by rw [← measure_toMeasurable s, ← iSup_restrict_spanningSets_of_measurableSet (measurableSet_toMeasurable _ _)] - simp_rw [restrict_apply' (measurable_spanningSets μ _), Set.inter_comm s, - ← restrict_apply (measurable_spanningSets μ _), ← restrict_toMeasurable_of_sFinite s, - restrict_apply (measurable_spanningSets μ _), Set.inter_comm _ (toMeasurable μ s)] + simp_rw [restrict_apply' (measurableSet_spanningSets μ _), Set.inter_comm s, + ← restrict_apply (measurableSet_spanningSets μ _), ← restrict_toMeasurable_of_sFinite s, + restrict_apply (measurableSet_spanningSets μ _), Set.inter_comm _ (toMeasurable μ s)] /-- In a σ-finite space, any measurable set of measure `> r` contains a measurable subset of finite measure `> r`. -/ @@ -1001,7 +1003,7 @@ theorem exists_subset_measure_lt_top [SigmaFinite μ] {r : ℝ≥0∞} (hs : Mea rcases h's with ⟨n, hn⟩ simp only [restrict_apply hs] at hn refine - ⟨s ∩ spanningSets μ n, hs.inter (measurable_spanningSets _ _), inter_subset_left, hn, ?_⟩ + ⟨s ∩ spanningSets μ n, hs.inter (measurableSet_spanningSets _ _), inter_subset_left, hn, ?_⟩ exact (measure_mono inter_subset_right).trans_lt (measure_spanningSets_lt_top _ _) namespace FiniteSpanningSetsIn @@ -1081,7 +1083,7 @@ theorem sigmaFinite_bot_iff (μ : @Measure α ⊥) : SigmaFinite μ ↔ IsFinite haveI : SigmaFinite μ := h let s := spanningSets μ have hs_univ : ⋃ i, s i = Set.univ := iUnion_spanningSets μ - have hs_meas : ∀ i, MeasurableSet[⊥] (s i) := measurable_spanningSets μ + have hs_meas : ∀ i, MeasurableSet[⊥] (s i) := measurableSet_spanningSets μ simp_rw [MeasurableSpace.measurableSet_bot_iff] at hs_meas by_cases h_univ_empty : (Set.univ : Set α) = ∅ · rw [h_univ_empty, measure_empty] @@ -1097,14 +1099,14 @@ theorem sigmaFinite_bot_iff (μ : @Measure α ⊥) : SigmaFinite μ ↔ IsFinite instance Restrict.sigmaFinite (μ : Measure α) [SigmaFinite μ] (s : Set α) : SigmaFinite (μ.restrict s) := by refine ⟨⟨⟨spanningSets μ, fun _ => trivial, fun i => ?_, iUnion_spanningSets μ⟩⟩⟩ - rw [Measure.restrict_apply (measurable_spanningSets μ i)] + rw [Measure.restrict_apply (measurableSet_spanningSets μ i)] exact (measure_mono inter_subset_left).trans_lt (measure_spanningSets_lt_top μ i) instance sum.sigmaFinite {ι} [Finite ι] (μ : ι → Measure α) [∀ i, SigmaFinite (μ i)] : SigmaFinite (sum μ) := by cases nonempty_fintype ι have : ∀ n, MeasurableSet (⋂ i : ι, spanningSets (μ i) n) := fun n => - MeasurableSet.iInter fun i => measurable_spanningSets (μ i) n + MeasurableSet.iInter fun i => measurableSet_spanningSets (μ i) n refine ⟨⟨⟨fun n => ⋂ i, spanningSets (μ i) n, fun _ => trivial, fun n => ?_, ?_⟩⟩⟩ · rw [sum_apply _ (this n), tsum_fintype, ENNReal.sum_lt_top] rintro i - @@ -1141,7 +1143,7 @@ instance [SigmaFinite (μ.restrict t)] : SigmaFinite (μ.restrict (s ∩ t)) := theorem SigmaFinite.of_map (μ : Measure α) {f : α → β} (hf : AEMeasurable f μ) (h : SigmaFinite (μ.map f)) : SigmaFinite μ := ⟨⟨⟨fun n => f ⁻¹' spanningSets (μ.map f) n, fun _ => trivial, fun n => by - simp only [← map_apply_of_aemeasurable hf, measurable_spanningSets, + simp only [← map_apply_of_aemeasurable hf, measurableSet_spanningSets, measure_spanningSets_lt_top], by rw [← preimage_iUnion, iUnion_spanningSets, preimage_univ]⟩⟩⟩ @@ -1167,10 +1169,10 @@ theorem ae_of_forall_measure_lt_top_ae_restrict' {μ : Measure α} (ν : Measure have : ∀ n, ∀ᵐ x ∂μ, x ∈ spanningSets (μ + ν) n → P x := by intro n have := h - (spanningSets (μ + ν) n) (measurable_spanningSets _ _) + (spanningSets (μ + ν) n) (measurableSet_spanningSets _ _) ((self_le_add_right _ _).trans_lt (measure_spanningSets_lt_top (μ + ν) _)) ((self_le_add_left _ _).trans_lt (measure_spanningSets_lt_top (μ + ν) _)) - exact (ae_restrict_iff' (measurable_spanningSets _ _)).mp this + exact (ae_restrict_iff' (measurableSet_spanningSets _ _)).mp this filter_upwards [ae_all_iff.2 this] with _ hx using hx _ (mem_spanningSetsIndex _ _) /-- To prove something for almost all `x` w.r.t. a σ-finite measure, it is sufficient to show that From 2de78712a1ca26b255be2351ff54b919d3cba7ba Mon Sep 17 00:00:00 2001 From: damiano Date: Wed, 16 Oct 2024 17:21:07 +0000 Subject: [PATCH 243/425] chore: remove more unused variables (#17749) --- Mathlib/Algebra/Group/Action/Pi.lean | 2 +- Mathlib/Algebra/Group/Units/Defs.lean | 6 +++--- Mathlib/Algebra/GroupPower/IterateHom.lean | 2 +- Mathlib/Algebra/Order/Group/Prod.lean | 2 -- Mathlib/Algebra/Order/Monovary.lean | 12 ++++++------ .../Algebra/Order/Ring/Unbundled/Nonneg.lean | 7 ------- Mathlib/Algebra/Order/Ring/Unbundled/Rat.lean | 2 +- Mathlib/Algebra/Ring/Hom/Basic.lean | 4 ++-- Mathlib/Algebra/Ring/Parity.lean | 4 ++-- .../BoxIntegral/Partition/Additive.lean | 2 +- Mathlib/Analysis/Calculus/Deriv/Basic.lean | 3 +-- Mathlib/Analysis/Calculus/Deriv/Comp.lean | 12 ++++++------ Mathlib/Analysis/Calculus/Deriv/Inv.lean | 17 +++++------------ Mathlib/Analysis/Calculus/Deriv/Polynomial.lean | 16 ++++------------ Mathlib/Analysis/Calculus/Deriv/Pow.lean | 16 ++-------------- Mathlib/Analysis/Calculus/FDeriv/Bilinear.lean | 10 +--------- Mathlib/Analysis/Calculus/FDeriv/Linear.lean | 16 ++++------------ Mathlib/Analysis/Convex/EGauge.lean | 14 ++++++-------- Mathlib/Analysis/Normed/Operator/Banach.lean | 2 +- .../Analysis/NormedSpace/OperatorNorm/Mul.lean | 2 +- .../PiTensorProduct/ProjectiveSeminorm.lean | 1 - .../Functor/KanExtension/Basic.lean | 3 +-- .../CategoryTheory/Limits/Shapes/Images.lean | 4 ++-- Mathlib/CategoryTheory/Limits/Types.lean | 2 +- Mathlib/Condensed/Light/CartesianClosed.lean | 2 -- Mathlib/Data/Fintype/Option.lean | 2 +- Mathlib/Data/NNRat/Defs.lean | 4 ++-- Mathlib/Data/Set/Basic.lean | 4 ++-- Mathlib/Data/Set/Image.lean | 2 +- Mathlib/Data/Set/Prod.lean | 2 +- Mathlib/Dynamics/Ergodic/Conservative.lean | 2 +- Mathlib/Dynamics/Ergodic/Ergodic.lean | 2 +- Mathlib/Geometry/Manifold/ContMDiff/Defs.lean | 15 --------------- .../Geometry/Manifold/ContMDiff/Product.lean | 8 +------- Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean | 4 ---- Mathlib/LinearAlgebra/DFinsupp.lean | 17 ++++++----------- Mathlib/MeasureTheory/Decomposition/Jordan.lean | 4 ++-- Mathlib/MeasureTheory/Function/Egorov.lean | 4 ++-- .../Integral/LebesgueNormedSpace.lean | 2 +- Mathlib/MeasureTheory/Measure/Complex.lean | 2 +- .../MeasureTheory/Measure/VectorMeasure.lean | 2 +- Mathlib/Order/UpperLower/Basic.lean | 6 +++--- .../Disintegration/MeasurableStieltjes.lean | 2 +- .../ProbabilityMassFunction/Basic.lean | 9 ++++----- .../ContinuousMap/StoneWeierstrass.lean | 2 +- Mathlib/Topology/MetricSpace/Pseudo/Basic.lean | 9 ++++----- 46 files changed, 88 insertions(+), 179 deletions(-) diff --git a/Mathlib/Algebra/Group/Action/Pi.lean b/Mathlib/Algebra/Group/Action/Pi.lean index d8c0c7b05deb33..f1ed601c36220e 100644 --- a/Mathlib/Algebra/Group/Action/Pi.lean +++ b/Mathlib/Algebra/Group/Action/Pi.lean @@ -21,7 +21,7 @@ This file defines instances for `MulAction` and related structures on `Pi` types assert_not_exists MonoidWithZero -variable {ι M N : Type*} {α β γ : ι → Type*} (x y : ∀ i, α i) (i : ι) +variable {ι M N : Type*} {α β γ : ι → Type*} (i : ι) namespace Pi diff --git a/Mathlib/Algebra/Group/Units/Defs.lean b/Mathlib/Algebra/Group/Units/Defs.lean index 3e67d4529c21e5..f6034394775327 100644 --- a/Mathlib/Algebra/Group/Units/Defs.lean +++ b/Mathlib/Algebra/Group/Units/Defs.lean @@ -170,7 +170,7 @@ the `AddMonoid`."] instance [Repr α] : Repr αˣ := ⟨reprPrec ∘ val⟩ -variable (a b c : αˣ) {u : αˣ} +variable (a b : αˣ) {u : αˣ} @[to_additive (attr := simp, norm_cast)] theorem val_mul : (↑(a * b) : α) = a * b := @@ -477,7 +477,7 @@ theorem mul_iff [CommMonoid M] {x y : M} : IsUnit (x * y) ↔ IsUnit x ∧ IsUni section Monoid -variable [Monoid M] {a b c : M} +variable [Monoid M] {a : M} /-- The element of the group of units, corresponding to an element of a monoid which is a unit. When `α` is a `DivisionMonoid`, use `IsUnit.unit'` instead. -/ @@ -577,7 +577,7 @@ protected lemma mul_div_mul_right (h : IsUnit c) (a b : α) : a * c / (b * c) = end DivisionMonoid section DivisionCommMonoid -variable [DivisionCommMonoid α] {a b c d : α} +variable [DivisionCommMonoid α] {a c : α} @[to_additive] protected lemma div_mul_cancel_left (h : IsUnit a) (b : α) : a / (a * b) = b⁻¹ := by diff --git a/Mathlib/Algebra/GroupPower/IterateHom.lean b/Mathlib/Algebra/GroupPower/IterateHom.lean index d28361dadaa6ef..50ac0d58a372ae 100644 --- a/Mathlib/Algebra/GroupPower/IterateHom.lean +++ b/Mathlib/Algebra/GroupPower/IterateHom.lean @@ -31,7 +31,7 @@ assert_not_exists DenselyOrdered open Function -variable {M : Type*} {N : Type*} {G : Type*} {H : Type*} +variable {M : Type*} {G : Type*} {H : Type*} /-- An auxiliary lemma that can be used to prove `⇑(f ^ n) = ⇑f^[n]`. -/ theorem hom_coe_pow {F : Type*} [Monoid F] (c : F → M → M) (h1 : c 1 = id) diff --git a/Mathlib/Algebra/Order/Group/Prod.lean b/Mathlib/Algebra/Order/Group/Prod.lean index 3d325521fa7123..9faaea7bf12053 100644 --- a/Mathlib/Algebra/Order/Group/Prod.lean +++ b/Mathlib/Algebra/Order/Group/Prod.lean @@ -11,8 +11,6 @@ import Mathlib.Algebra.Order.Monoid.Prod -/ -variable {α : Type*} - namespace Prod variable {G H : Type*} diff --git a/Mathlib/Algebra/Order/Monovary.lean b/Mathlib/Algebra/Order/Monovary.lean index e085b565b3140c..60f025df1e8106 100644 --- a/Mathlib/Algebra/Order/Monovary.lean +++ b/Mathlib/Algebra/Order/Monovary.lean @@ -26,7 +26,7 @@ variable {ι α β : Type*} /-! ### Algebraic operations on monovarying functions -/ section OrderedCommGroup -variable [OrderedCommGroup α] [OrderedCommGroup β] {s : Set ι} {f f₁ f₂ : ι → α} {g g₁ g₂ : ι → β} +variable [OrderedCommGroup α] [OrderedCommGroup β] {s : Set ι} {f f₁ f₂ : ι → α} {g : ι → β} @[to_additive (attr := simp)] lemma monovaryOn_inv_left : MonovaryOn f⁻¹ g s ↔ AntivaryOn f g s := by @@ -118,7 +118,7 @@ lemma Antivary.div_left (h₁ : Antivary f₁ g) (h₂ : Monovary f₂ g) : Anti end OrderedCommGroup section LinearOrderedCommGroup -variable [OrderedCommGroup α] [LinearOrderedCommGroup β] {s : Set ι} {f f₁ f₂ : ι → α} +variable [OrderedCommGroup α] [LinearOrderedCommGroup β] {s : Set ι} {f : ι → α} {g g₁ g₂ : ι → β} @[to_additive] lemma MonovaryOn.mul_right (h₁ : MonovaryOn f g₁ s) (h₂ : MonovaryOn f g₂ s) : @@ -168,7 +168,7 @@ variable [OrderedCommGroup α] [LinearOrderedCommGroup β] {s : Set ι} {f f₁ end LinearOrderedCommGroup section OrderedSemiring -variable [OrderedSemiring α] [OrderedSemiring β] {s : Set ι} {f f₁ f₂ : ι → α} {g g₁ g₂ : ι → β} +variable [OrderedSemiring α] [OrderedSemiring β] {s : Set ι} {f f₁ f₂ : ι → α} {g : ι → β} lemma MonovaryOn.mul_left₀ (hf₁ : ∀ i ∈ s, 0 ≤ f₁ i) (hf₂ : ∀ i ∈ s, 0 ≤ f₂ i) (h₁ : MonovaryOn f₁ g s) (h₂ : MonovaryOn f₂ g s) : MonovaryOn (f₁ * f₂) g s := @@ -201,7 +201,7 @@ lemma Antivary.pow_left₀ (hf : 0 ≤ f) (hfg : Antivary f g) (n : ℕ) : Antiv end OrderedSemiring section LinearOrderedSemiring -variable [LinearOrderedSemiring α] [LinearOrderedSemiring β] {s : Set ι} {f f₁ f₂ : ι → α} +variable [LinearOrderedSemiring α] [LinearOrderedSemiring β] {s : Set ι} {f : ι → α} {g g₁ g₂ : ι → β} lemma MonovaryOn.mul_right₀ (hg₁ : ∀ i ∈ s, 0 ≤ g₁ i) (hg₂ : ∀ i ∈ s, 0 ≤ g₂ i) @@ -325,7 +325,7 @@ end LinearOrderedSemifield section LinearOrderedAddCommGroup variable [LinearOrderedRing α] [LinearOrderedAddCommGroup β] [Module α β] - [OrderedSMul α β] {f : ι → α} {g : ι → β} {s : Set ι} {a a₁ a₂ : α} {b b₁ b₂ : β} + [OrderedSMul α β] {f : ι → α} {g : ι → β} {s : Set ι} lemma monovaryOn_iff_forall_smul_nonneg : MonovaryOn f g s ↔ ∀ ⦃i⦄, i ∈ s → ∀ ⦃j⦄, j ∈ s → 0 ≤ (f j - f i) • (g j - g i) := by @@ -380,7 +380,7 @@ alias ⟨AntivaryOn.smul_add_smul_le_smul_add_smul, _⟩ := antivaryOn_iff_smul_ end LinearOrderedAddCommGroup section LinearOrderedRing -variable [LinearOrderedRing α] {f g : ι → α} {s : Set ι} {a b c d : α} +variable [LinearOrderedRing α] {f g : ι → α} {s : Set ι} lemma monovaryOn_iff_forall_mul_nonneg : MonovaryOn f g s ↔ ∀ ⦃i⦄, i ∈ s → ∀ ⦃j⦄, j ∈ s → 0 ≤ (f j - f i) * (g j - g i) := by diff --git a/Mathlib/Algebra/Order/Ring/Unbundled/Nonneg.lean b/Mathlib/Algebra/Order/Ring/Unbundled/Nonneg.lean index af0b158eae60c9..672f46dd53d38b 100644 --- a/Mathlib/Algebra/Order/Ring/Unbundled/Nonneg.lean +++ b/Mathlib/Algebra/Order/Ring/Unbundled/Nonneg.lean @@ -273,13 +273,6 @@ def coeRingHom : { x : α // 0 ≤ x } →+* α := end Semiring -section Nontrivial - -variable [Semiring α] [PartialOrder α] [ZeroLEOneClass α] [NeZero 1] - [CovariantClass α α (· + ·) (· ≤ ·)] [PosMulMono α] - -end Nontrivial - section CommSemiring variable [CommSemiring α] [PartialOrder α] [ZeroLEOneClass α] diff --git a/Mathlib/Algebra/Order/Ring/Unbundled/Rat.lean b/Mathlib/Algebra/Order/Ring/Unbundled/Rat.lean index b2ad2a602b3764..857fea4b6cfde6 100644 --- a/Mathlib/Algebra/Order/Ring/Unbundled/Rat.lean +++ b/Mathlib/Algebra/Order/Ring/Unbundled/Rat.lean @@ -29,7 +29,7 @@ assert_not_exists GaloisConnection namespace Rat -variable {a b c p q : ℚ} +variable {a b p q : ℚ} @[simp] lemma divInt_nonneg_iff_of_pos_right {a b : ℤ} (hb : 0 < b) : 0 ≤ a /. b ↔ 0 ≤ a := by cases' hab : a /. b with n d hd hnd diff --git a/Mathlib/Algebra/Ring/Hom/Basic.lean b/Mathlib/Algebra/Ring/Hom/Basic.lean index 8fd264112dd854..354e0701e8d83a 100644 --- a/Mathlib/Algebra/Ring/Hom/Basic.lean +++ b/Mathlib/Algebra/Ring/Hom/Basic.lean @@ -21,13 +21,13 @@ They could be moved to more natural homes. open Function -variable {F α β γ : Type*} +variable {α β : Type*} namespace RingHom section -variable {_ : NonAssocSemiring α} {_ : NonAssocSemiring β} (f : α →+* β) {x y : α} +variable {_ : NonAssocSemiring α} {_ : NonAssocSemiring β} (f : α →+* β) /-- `f : α →+* β` has a trivial codomain iff its range is `{0}`. -/ theorem codomain_trivial_iff_range_eq_singleton_zero : (0 : β) = 1 ↔ Set.range f = {0} := diff --git a/Mathlib/Algebra/Ring/Parity.lean b/Mathlib/Algebra/Ring/Parity.lean index 9205b9aeff65a5..6adab468d1261b 100644 --- a/Mathlib/Algebra/Ring/Parity.lean +++ b/Mathlib/Algebra/Ring/Parity.lean @@ -31,7 +31,7 @@ assert_not_exists OrderedRing open MulOpposite -variable {F α β R : Type*} +variable {F α β : Type*} section Monoid variable [Monoid α] [HasDistribNeg α] {n : ℕ} {a : α} @@ -156,7 +156,7 @@ lemma Odd.pow_add_pow_eq_zero [IsCancelAdd α] (hn : Odd n) (hab : a + b = 0) : end Semiring section Monoid -variable [Monoid α] [HasDistribNeg α] {a : α} {n : ℕ} +variable [Monoid α] [HasDistribNeg α] {n : ℕ} lemma Odd.neg_pow : Odd n → ∀ a : α, (-a) ^ n = -a ^ n := by rintro ⟨c, rfl⟩ a; simp_rw [pow_add, pow_mul, neg_sq, pow_one, mul_neg] diff --git a/Mathlib/Analysis/BoxIntegral/Partition/Additive.lean b/Mathlib/Analysis/BoxIntegral/Partition/Additive.lean index a82e54fd54bb57..648e9dfc503a97 100644 --- a/Mathlib/Analysis/BoxIntegral/Partition/Additive.lean +++ b/Mathlib/Analysis/BoxIntegral/Partition/Additive.lean @@ -57,7 +57,7 @@ namespace BoxAdditiveMap open Box Prepartition Finset -variable {N : Type*} [AddCommMonoid M] [AddCommMonoid N] {I₀ : WithTop (Box ι)} {I J : Box ι} +variable {N : Type*} [AddCommMonoid M] [AddCommMonoid N] {I₀ : WithTop (Box ι)} {I : Box ι} {i : ι} instance : FunLike (ι →ᵇᵃ[I₀] M) (Box ι) M where diff --git a/Mathlib/Analysis/Calculus/Deriv/Basic.lean b/Mathlib/Analysis/Calculus/Deriv/Basic.lean index 5ed888191d0e0b..91f89a76a17777 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Basic.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Basic.lean @@ -97,7 +97,6 @@ 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] /-- `f` has the derivative `f'` at the point `x` as `x` goes along the filter `L`. @@ -142,7 +141,7 @@ If the derivative exists (i.e., `∃ f', HasDerivAt f f' x`), then def deriv (f : 𝕜 → F) (x : 𝕜) := fderiv 𝕜 f x 1 -variable {f f₀ f₁ g : 𝕜 → F} +variable {f f₀ f₁ : 𝕜 → F} variable {f' f₀' f₁' g' : F} variable {x : 𝕜} variable {s t : Set 𝕜} diff --git a/Mathlib/Analysis/Calculus/Deriv/Comp.lean b/Mathlib/Analysis/Calculus/Deriv/Comp.lean index bb0e4bdc37b52b..b57c7cc2a7dcfe 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Comp.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Comp.lean @@ -43,11 +43,11 @@ 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] -variable {f f₀ f₁ g : 𝕜 → F} -variable {f' f₀' f₁' g' : F} +variable {f : 𝕜 → F} +variable {f' : F} variable {x : 𝕜} -variable {s t : Set 𝕜} -variable {L L₁ L₂ : Filter 𝕜} +variable {s : Set 𝕜} +variable {L : Filter 𝕜} section Composition @@ -65,8 +65,8 @@ usual multiplication in `comp` lemmas. /- For composition lemmas, we put x explicit to help the elaborator, as otherwise Lean tends to get confused since there are too many possibilities for composition -/ variable {𝕜' : Type*} [NontriviallyNormedField 𝕜'] [NormedAlgebra 𝕜 𝕜'] [NormedSpace 𝕜' F] - [IsScalarTower 𝕜 𝕜' F] {s' t' : Set 𝕜'} {h : 𝕜 → 𝕜'} {h₁ : 𝕜 → 𝕜} {h₂ : 𝕜' → 𝕜'} {h' h₂' : 𝕜'} - {h₁' : 𝕜} {g₁ : 𝕜' → F} {g₁' : F} {L' : Filter 𝕜'} {y : 𝕜'} (x) + [IsScalarTower 𝕜 𝕜' F] {s' t' : Set 𝕜'} {h : 𝕜 → 𝕜'} {h₂ : 𝕜' → 𝕜'} {h' h₂' : 𝕜'} + {g₁ : 𝕜' → F} {g₁' : F} {L' : Filter 𝕜'} {y : 𝕜'} (x) theorem HasDerivAtFilter.scomp (hg : HasDerivAtFilter g₁ g₁' (h x) L') (hh : HasDerivAtFilter h h' x L) (hL : Tendsto h L L') : diff --git a/Mathlib/Analysis/Calculus/Deriv/Inv.lean b/Mathlib/Analysis/Calculus/Deriv/Inv.lean index 8687b3af9373d6..045ec40200bc67 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Inv.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Inv.lean @@ -21,21 +21,14 @@ derivative -/ -universe u v w +universe u -open scoped Classical Topology ENNReal +open scoped Topology open Filter Asymptotics Set -open ContinuousLinearMap (smulRight smulRight_one_eq_iff) +open ContinuousLinearMap (smulRight) -variable {𝕜 : Type u} [NontriviallyNormedField 𝕜] -variable {F : Type v} [NormedAddCommGroup F] [NormedSpace 𝕜 F] -variable {E : Type w} [NormedAddCommGroup E] [NormedSpace 𝕜 E] -variable {f f₀ f₁ g : 𝕜 → F} -variable {f' f₀' f₁' g' : F} -variable {x : 𝕜} -variable {s t : Set 𝕜} -variable {L : Filter 𝕜} +variable {𝕜 : Type u} [NontriviallyNormedField 𝕜] {x : 𝕜} {s : Set 𝕜} section Inverse @@ -101,7 +94,7 @@ 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 : 𝕜 → 𝕜} {h : E → 𝕜} {c' : 𝕜} {z : E} {S : Set E} +variable {c : 𝕜 → 𝕜} {c' : 𝕜} theorem HasDerivWithinAt.inv (hc : HasDerivWithinAt c c' s x) (hx : c x ≠ 0) : HasDerivWithinAt (fun y => (c y)⁻¹) (-c' / c x ^ 2) s x := by diff --git a/Mathlib/Analysis/Calculus/Deriv/Polynomial.lean b/Mathlib/Analysis/Calculus/Deriv/Polynomial.lean index 3174575fb194dc..1e4623488005db 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Polynomial.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Polynomial.lean @@ -28,21 +28,13 @@ derivative, polynomial -/ -universe u v w +universe u -open scoped Topology Filter ENNReal Polynomial -open Set +open scoped Polynomial -open ContinuousLinearMap (smulRight smulRight_one_eq_iff) +open ContinuousLinearMap (smulRight) -variable {𝕜 : Type u} [NontriviallyNormedField 𝕜] -variable {F : Type v} [NormedAddCommGroup F] [NormedSpace 𝕜 F] -variable {E : Type w} [NormedAddCommGroup E] [NormedSpace 𝕜 E] -variable {f f₀ f₁ g : 𝕜 → F} -variable {f' f₀' f₁' g' : F} -variable {x : 𝕜} -variable {s t : Set 𝕜} -variable {L L₁ L₂ : Filter 𝕜} +variable {𝕜 : Type u} [NontriviallyNormedField 𝕜] {x : 𝕜} {s : Set 𝕜} namespace Polynomial diff --git a/Mathlib/Analysis/Calculus/Deriv/Pow.lean b/Mathlib/Analysis/Calculus/Deriv/Pow.lean index 91052a01837fbf..07f1c232737a5d 100644 --- a/Mathlib/Analysis/Calculus/Deriv/Pow.lean +++ b/Mathlib/Analysis/Calculus/Deriv/Pow.lean @@ -19,21 +19,9 @@ For a more detailed overview of one-dimensional derivatives in mathlib, see the derivative, power -/ -universe u v w +universe u -open scoped Classical -open Topology Filter ENNReal - -open Filter Asymptotics Set - -variable {𝕜 : Type u} [NontriviallyNormedField 𝕜] -variable {F : Type v} [NormedAddCommGroup F] [NormedSpace 𝕜 F] -variable {E : Type w} [NormedAddCommGroup E] [NormedSpace 𝕜 E] -variable {f f₀ f₁ g : 𝕜 → F} -variable {f' f₀' f₁' g' : F} -variable {x : 𝕜} -variable {s t : Set 𝕜} -variable {L L₁ L₂ : Filter 𝕜} +variable {𝕜 : Type u} [NontriviallyNormedField 𝕜] {x : 𝕜} {s : Set 𝕜} /-! ### Derivative of `x ↦ x^n` for `n : ℕ` -/ diff --git a/Mathlib/Analysis/Calculus/FDeriv/Bilinear.lean b/Mathlib/Analysis/Calculus/FDeriv/Bilinear.lean index b5afecc0aa5366..b16d9f55939ba7 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Bilinear.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Bilinear.lean @@ -16,9 +16,7 @@ bounded bilinear maps. -/ -open Filter Asymptotics ContinuousLinearMap Set Metric -open scoped Classical -open Topology NNReal Asymptotics ENNReal +open Asymptotics Topology noncomputable section @@ -29,12 +27,6 @@ variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] variable {G : Type*} [NormedAddCommGroup G] [NormedSpace 𝕜 G] variable {G' : Type*} [NormedAddCommGroup G'] [NormedSpace 𝕜 G'] -variable {f f₀ f₁ g : E → F} -variable {f' f₀' f₁' g' : E →L[𝕜] F} -variable (e : E →L[𝕜] F) -variable {x : E} -variable {s t : Set E} -variable {L L₁ L₂ : Filter E} section BilinearMap diff --git a/Mathlib/Analysis/Calculus/FDeriv/Linear.lean b/Mathlib/Analysis/Calculus/FDeriv/Linear.lean index eba65ff4732613..a705e49b74306f 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Linear.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Linear.lean @@ -17,26 +17,18 @@ bounded linear maps. -/ -open Filter Asymptotics ContinuousLinearMap Set Metric - -open scoped Classical -open Topology NNReal Filter Asymptotics ENNReal - -noncomputable section +open Asymptotics section variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] variable {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] variable {F : Type*} [NormedAddCommGroup F] [NormedSpace 𝕜 F] -variable {G : Type*} [NormedAddCommGroup G] [NormedSpace 𝕜 G] -variable {G' : Type*} [NormedAddCommGroup G'] [NormedSpace 𝕜 G'] -variable {f f₀ f₁ g : E → F} -variable {f' f₀' f₁' g' : E →L[𝕜] F} +variable {f : E → F} variable (e : E →L[𝕜] F) variable {x : E} -variable {s t : Set E} -variable {L L₁ L₂ : Filter E} +variable {s : Set E} +variable {L : Filter E} section ContinuousLinearMap diff --git a/Mathlib/Analysis/Convex/EGauge.lean b/Mathlib/Analysis/Convex/EGauge.lean index 0fc1a2b1524c19..dacb554ee75057 100644 --- a/Mathlib/Analysis/Convex/EGauge.lean +++ b/Mathlib/Analysis/Convex/EGauge.lean @@ -65,8 +65,7 @@ end SMul section SMulZero -variable (𝕜 : Type*) [NNNorm 𝕜] [Nonempty 𝕜] {E : Type*} [Zero E] [SMulZeroClass 𝕜 E] - {c : 𝕜} {s t : Set E} {x : E} {r : ℝ≥0∞} +variable (𝕜 : Type*) [NNNorm 𝕜] [Nonempty 𝕜] {E : Type*} [Zero E] [SMulZeroClass 𝕜 E] {x : E} @[simp] lemma egauge_zero_left_eq_top : egauge 𝕜 0 x = ∞ ↔ x ≠ 0 := by simp [egauge_eq_top] @@ -77,8 +76,8 @@ end SMulZero section Module -variable {𝕜 : Type*} [NormedDivisionRing 𝕜] {α E : Type*} [AddCommGroup E] [Module 𝕜 E] - {c : 𝕜} {s t : Set E} {x y : E} {r : ℝ≥0∞} +variable {𝕜 : Type*} [NormedDivisionRing 𝕜] {E : Type*} [AddCommGroup E] [Module 𝕜 E] + {c : 𝕜} {s : Set E} {x : E} /-- If `c • x ∈ s` and `c ≠ 0`, then `egauge 𝕜 s x` is at most `((‖c‖₊⁻¹ : ℝ≥0) : ℝ≥0∞). @@ -159,8 +158,7 @@ end Module section SeminormedAddCommGroup -variable (𝕜 : Type*) [NormedField 𝕜] {α E : Type*} - [SeminormedAddCommGroup E] [NormedSpace 𝕜 E] {c : 𝕜} {s t : Set E} {x y : E} +variable (𝕜 : Type*) [NormedField 𝕜] {E : Type*} [SeminormedAddCommGroup E] [NormedSpace 𝕜 E] lemma div_le_egauge_closedBall (r : ℝ≥0) (x : E) : ‖x‖₊ / r ≤ egauge 𝕜 (closedBall 0 r) x := by rw [le_egauge_iff] @@ -183,8 +181,8 @@ end SeminormedAddCommGroup section SeminormedAddCommGroup -variable {𝕜 : Type*} [NormedField 𝕜] {α E : Type*} - [NormedAddCommGroup E] [NormedSpace 𝕜 E] {c : 𝕜} {s t : Set E} {x y : E} {r : ℝ≥0} +variable {𝕜 : Type*} [NormedField 𝕜] {E : Type*} + [NormedAddCommGroup E] [NormedSpace 𝕜 E] {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 diff --git a/Mathlib/Analysis/Normed/Operator/Banach.lean b/Mathlib/Analysis/Normed/Operator/Banach.lean index 8561d451ba771d..33ad7e49abced3 100644 --- a/Mathlib/Analysis/Normed/Operator/Banach.lean +++ b/Mathlib/Analysis/Normed/Operator/Banach.lean @@ -531,7 +531,7 @@ section BijectivityCriteria namespace ContinuousLinearMap -variable {σ : 𝕜 →+* 𝕜'} {σ' : 𝕜' →+* 𝕜} [RingHomInvPair σ σ'] {f : E →SL[σ] F} +variable {σ : 𝕜 →+* 𝕜'} {σ' : 𝕜' →+* 𝕜} [RingHomInvPair σ σ'] variable {F : Type u_4} [NormedAddCommGroup F] [NormedSpace 𝕜' F] variable [CompleteSpace E] diff --git a/Mathlib/Analysis/NormedSpace/OperatorNorm/Mul.lean b/Mathlib/Analysis/NormedSpace/OperatorNorm/Mul.lean index a42244f918fa79..25796540eece96 100644 --- a/Mathlib/Analysis/NormedSpace/OperatorNorm/Mul.lean +++ b/Mathlib/Analysis/NormedSpace/OperatorNorm/Mul.lean @@ -239,7 +239,7 @@ section Normed namespace ContinuousLinearMap -variable [NormedAddCommGroup E] [NormedSpace 𝕜 E] (c : 𝕜) +variable [NormedAddCommGroup E] [NormedSpace 𝕜 E] variable (𝕜) (𝕜' : Type*) section diff --git a/Mathlib/Analysis/NormedSpace/PiTensorProduct/ProjectiveSeminorm.lean b/Mathlib/Analysis/NormedSpace/PiTensorProduct/ProjectiveSeminorm.lean index ec8cbeca4457f6..edb1a33efca0f9 100644 --- a/Mathlib/Analysis/NormedSpace/PiTensorProduct/ProjectiveSeminorm.lean +++ b/Mathlib/Analysis/NormedSpace/PiTensorProduct/ProjectiveSeminorm.lean @@ -40,7 +40,6 @@ universe uι u𝕜 uE uF variable {ι : Type uι} [Fintype ι] variable {𝕜 : Type u𝕜} [NontriviallyNormedField 𝕜] variable {E : ι → Type uE} [∀ i, SeminormedAddCommGroup (E i)] -variable {F : Type uF} [SeminormedAddCommGroup F] [NormedSpace 𝕜 F] open scoped TensorProduct diff --git a/Mathlib/CategoryTheory/Functor/KanExtension/Basic.lean b/Mathlib/CategoryTheory/Functor/KanExtension/Basic.lean index 32996f6d67fcb8..6b966a9ee45edb 100644 --- a/Mathlib/CategoryTheory/Functor/KanExtension/Basic.lean +++ b/Mathlib/CategoryTheory/Functor/KanExtension/Basic.lean @@ -36,8 +36,7 @@ open Category Limits namespace Functor -variable {C C' H H' D D' : Type*} [Category C] [Category C'] [Category H] [Category H'] - [Category D] [Category D'] +variable {C C' H D D' : Type*} [Category C] [Category C'] [Category H] [Category D] [Category D'] /-- Given two functors `L : C ⥤ D` and `F : C ⥤ H`, this is the category of functors `F' : H ⥤ D` equipped with a natural transformation `L ⋙ F' ⟶ F`. -/ diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Images.lean b/Mathlib/CategoryTheory/Limits/Shapes/Images.lean index 10e2d68009de0e..fec3f30cad1ff3 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Images.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Images.lean @@ -756,7 +756,7 @@ end HasImageMap section -variable (C) [Category.{v} C] [HasImages C] +variable (C) [HasImages C] /-- If a category `has_image_maps`, then all commutative squares induce morphisms on images. -/ class HasImageMaps : Prop where @@ -830,7 +830,7 @@ end StrongEpiMonoFactorisation section HasStrongEpiImages -variable (C) [Category.{v} C] [HasImages C] +variable (C) [HasImages C] /-- A category has strong epi images if it has all images and `factorThruImage f` is a strong epimorphism for all `f`. -/ diff --git a/Mathlib/CategoryTheory/Limits/Types.lean b/Mathlib/CategoryTheory/Limits/Types.lean index b67691c5eca118..e278c775476354 100644 --- a/Mathlib/CategoryTheory/Limits/Types.lean +++ b/Mathlib/CategoryTheory/Limits/Types.lean @@ -634,7 +634,7 @@ instance : HasImageMaps (Type u) where simp only [Functor.id_obj, Functor.id_map, types_comp_apply] at p rw [p, Classical.choose_spec x.2]⟩⟩) rfl -variable {F : ℕᵒᵖ ⥤ Type u} {c : Cone F} (hc : IsLimit c) +variable {F : ℕᵒᵖ ⥤ Type u} {c : Cone F} (hF : ∀ n, Function.Surjective (F.map (homOfLE (Nat.le_succ n)).op)) private noncomputable def limitOfSurjectionsSurjective.preimage diff --git a/Mathlib/Condensed/Light/CartesianClosed.lean b/Mathlib/Condensed/Light/CartesianClosed.lean index 99af9b717d59ad..4d443905053a2c 100644 --- a/Mathlib/Condensed/Light/CartesianClosed.lean +++ b/Mathlib/Condensed/Light/CartesianClosed.lean @@ -17,6 +17,4 @@ noncomputable section open CategoryTheory -variable {C : Type u} [SmallCategory C] - instance : CartesianClosed (LightCondSet.{u}) := inferInstanceAs (CartesianClosed (Sheaf _ _)) diff --git a/Mathlib/Data/Fintype/Option.lean b/Mathlib/Data/Fintype/Option.lean index 1a4f57cb48b3e6..5bb9fafa8f9165 100644 --- a/Mathlib/Data/Fintype/Option.lean +++ b/Mathlib/Data/Fintype/Option.lean @@ -19,7 +19,7 @@ open Nat universe u v -variable {α β γ : Type*} +variable {α β : Type*} open Finset Function diff --git a/Mathlib/Data/NNRat/Defs.lean b/Mathlib/Data/NNRat/Defs.lean index 00cb00c61e5065..5bda9ba5b38260 100644 --- a/Mathlib/Data/NNRat/Defs.lean +++ b/Mathlib/Data/NNRat/Defs.lean @@ -61,7 +61,7 @@ deriving instance Inhabited for NNRat namespace NNRat -variable {α : Type*} {p q : ℚ≥0} +variable {p q : ℚ≥0} @[simp] lemma val_eq_cast (q : ℚ≥0) : q.1 = q := rfl @@ -345,7 +345,7 @@ See also `Rat.divInt` and `mkRat`. -/ def divNat (n d : ℕ) : ℚ≥0 := ⟨.divInt n d, Rat.divInt_nonneg (Int.ofNat_zero_le n) (Int.ofNat_zero_le d)⟩ -variable {n₁ n₂ d₁ d₂ d : ℕ} +variable {n₁ n₂ d₁ d₂ : ℕ} @[simp, norm_cast] lemma coe_divNat (n d : ℕ) : (divNat n d : ℚ) = .divInt n d := rfl diff --git a/Mathlib/Data/Set/Basic.lean b/Mathlib/Data/Set/Basic.lean index 691836860b5383..2cc7a256bcfdfb 100644 --- a/Mathlib/Data/Set/Basic.lean +++ b/Mathlib/Data/Set/Basic.lean @@ -65,7 +65,7 @@ set, sets, subset, subsets, union, intersection, insert, singleton, complement, open Function -universe u v w x +universe u v namespace Set @@ -182,7 +182,7 @@ theorem Eq.subset {α} {s t : Set α} : s = t → s ⊆ t := namespace Set -variable {α : Type u} {β : Type v} {γ : Type w} {ι : Sort x} {a b : α} {s s₁ s₂ t t₁ t₂ u : Set α} +variable {α : Type u} {β : Type v} {a b : α} {s s₁ s₂ t t₁ t₂ u : Set α} instance : Inhabited (Set α) := ⟨∅⟩ diff --git a/Mathlib/Data/Set/Image.lean b/Mathlib/Data/Set/Image.lean index bbd73befb9a8c0..b0d95b24f93818 100644 --- a/Mathlib/Data/Set/Image.lean +++ b/Mathlib/Data/Set/Image.lean @@ -37,7 +37,7 @@ open Function Set namespace Set -variable {α β γ : Type*} {ι ι' : Sort*} +variable {α β γ : Type*} {ι : Sort*} /-! ### Inverse image -/ diff --git a/Mathlib/Data/Set/Prod.lean b/Mathlib/Data/Set/Prod.lean index 7b460fdb9cb955..5464761ef44751 100644 --- a/Mathlib/Data/Set/Prod.lean +++ b/Mathlib/Data/Set/Prod.lean @@ -532,7 +532,7 @@ namespace Set section OffDiag -variable {α : Type*} {s t : Set α} {x : α × α} {a : α} +variable {α : Type*} {s t : Set α} {a : α} theorem offDiag_mono : Monotone (offDiag : Set α → Set (α × α)) := fun _ _ h _ => And.imp (@h _) <| And.imp_left <| @h _ diff --git a/Mathlib/Dynamics/Ergodic/Conservative.lean b/Mathlib/Dynamics/Ergodic/Conservative.lean index f89c15dd99f1b3..2b9a33bb435bab 100644 --- a/Mathlib/Dynamics/Ergodic/Conservative.lean +++ b/Mathlib/Dynamics/Ergodic/Conservative.lean @@ -40,7 +40,7 @@ noncomputable section open Set Filter MeasureTheory Finset Function TopologicalSpace Topology -variable {ι : Type*} {α : Type*} [MeasurableSpace α] {f : α → α} {s : Set α} {μ : Measure α} +variable {α : Type*} [MeasurableSpace α] {f : α → α} {s : Set α} {μ : Measure α} namespace MeasureTheory diff --git a/Mathlib/Dynamics/Ergodic/Ergodic.lean b/Mathlib/Dynamics/Ergodic/Ergodic.lean index eb2fbac4d06d46..6b1648fa292e16 100644 --- a/Mathlib/Dynamics/Ergodic/Ergodic.lean +++ b/Mathlib/Dynamics/Ergodic/Ergodic.lean @@ -80,7 +80,7 @@ end PreErgodic namespace MeasureTheory.MeasurePreserving -variable {β : Type*} {m' : MeasurableSpace β} {μ' : Measure β} {s' : Set β} {g : α → β} +variable {β : Type*} {m' : MeasurableSpace β} {μ' : Measure β} {g : α → β} theorem preErgodic_of_preErgodic_conjugate (hg : MeasurePreserving g μ μ') (hf : PreErgodic f μ) {f' : β → β} (h_comm : Semiconj g f f') : PreErgodic f' μ' where diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean b/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean index cde9ee6782c472..e52bf1aa65520d 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Defs.lean @@ -64,21 +64,6 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E'' : Type*} [NormedAddCommGroup E''] [NormedSpace 𝕜 E''] {H'' : Type*} [TopologicalSpace H''] {I'' : ModelWithCorners 𝕜 E'' H''} {M'' : Type*} [TopologicalSpace M''] [ChartedSpace H'' M''] - -- declare a smooth manifold `N` over the pair `(F, G)`. - {F : Type*} - [NormedAddCommGroup F] [NormedSpace 𝕜 F] {G : Type*} [TopologicalSpace G] - {J : ModelWithCorners 𝕜 F G} {N : Type*} [TopologicalSpace N] [ChartedSpace G N] - [SmoothManifoldWithCorners J N] - -- declare a smooth manifold `N'` over the pair `(F', G')`. - {F' : Type*} - [NormedAddCommGroup F'] [NormedSpace 𝕜 F'] {G' : Type*} [TopologicalSpace G'] - {J' : ModelWithCorners 𝕜 F' G'} {N' : Type*} [TopologicalSpace N'] [ChartedSpace G' N'] - [SmoothManifoldWithCorners J' N'] - -- F₁, F₂, F₃, F₄ are normed spaces - {F₁ : Type*} - [NormedAddCommGroup F₁] [NormedSpace 𝕜 F₁] {F₂ : Type*} [NormedAddCommGroup F₂] - [NormedSpace 𝕜 F₂] {F₃ : Type*} [NormedAddCommGroup F₃] [NormedSpace 𝕜 F₃] {F₄ : Type*} - [NormedAddCommGroup F₄] [NormedSpace 𝕜 F₄] -- declare functions, sets, points and smoothness indices {e : PartialHomeomorph M H} {e' : PartialHomeomorph M' H'} {f f₁ : M → M'} {s s₁ t : Set M} {x : M} {m n : ℕ∞} diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Product.lean b/Mathlib/Geometry/Manifold/ContMDiff/Product.lean index 5208fce1bdcc33..5c76e05789139e 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Product.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Product.lean @@ -36,14 +36,8 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {F' : Type*} [NormedAddCommGroup F'] [NormedSpace 𝕜 F'] {G' : Type*} [TopologicalSpace G'] {J' : ModelWithCorners 𝕜 F' G'} {N' : Type*} [TopologicalSpace N'] [ChartedSpace G' N'] - -- F₁, F₂, F₃, F₄ are normed spaces - {F₁ : Type*} - [NormedAddCommGroup F₁] [NormedSpace 𝕜 F₁] {F₂ : Type*} [NormedAddCommGroup F₂] - [NormedSpace 𝕜 F₂] {F₃ : Type*} [NormedAddCommGroup F₃] [NormedSpace 𝕜 F₃] {F₄ : Type*} - [NormedAddCommGroup F₄] [NormedSpace 𝕜 F₄] -- declare functions, sets, points and smoothness indices - {e : PartialHomeomorph M H} - {e' : PartialHomeomorph M' H'} {f f₁ : M → M'} {s s₁ t : Set M} {x : M} {m n : ℕ∞} + {f : M → M'} {s : Set M} {x : M} {n : ℕ∞} variable {I I'} section ProdMk diff --git a/Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean b/Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean index b1da80bc215d6d..633857d4ac0f76 100644 --- a/Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean +++ b/Mathlib/Geometry/Manifold/MFDeriv/Tangent.lean @@ -20,10 +20,6 @@ open Bundle 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'] - (I' : ModelWithCorners 𝕜 E' H') {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M'] - {E'' : Type*} [NormedAddCommGroup E''] [NormedSpace 𝕜 E''] {H'' : Type*} [TopologicalSpace H''] - (I'' : ModelWithCorners 𝕜 E'' H'') {M'' : Type*} [TopologicalSpace M''] [ChartedSpace H'' M''] [SmoothManifoldWithCorners I M] /-- The derivative of the chart at a base point is the chart of the tangent bundle, composed with diff --git a/Mathlib/LinearAlgebra/DFinsupp.lean b/Mathlib/LinearAlgebra/DFinsupp.lean index 2313a713d4ae5c..292f5f03db793b 100644 --- a/Mathlib/LinearAlgebra/DFinsupp.lean +++ b/Mathlib/LinearAlgebra/DFinsupp.lean @@ -531,18 +531,13 @@ namespace LinearMap section AddCommMonoid -variable {R : Type*} {R₁ : Type*} {R₂ : Type*} {R₃ : Type*} {R₄ : Type*} -variable {S : Type*} -variable {K : Type*} {K₂ : Type*} -variable {M : Type*} {M' : Type*} {M₁ : Type*} {M₂ : Type*} {M₃ : Type*} {M₄ : Type*} -variable {N : Type*} {N₂ : Type*} +variable {R : Type*} {R₂ : Type*} +variable {M : Type*} {M₂ : Type*} variable {ι : Type*} -variable {V : Type*} {V₂ : Type*} -variable [Semiring R] [Semiring R₂] [Semiring R₃] -variable [AddCommMonoid M] [AddCommMonoid M₂] [AddCommMonoid M₃] -variable {σ₁₂ : R →+* R₂} {σ₂₃ : R₂ →+* R₃} {σ₁₃ : R →+* R₃} -variable [RingHomCompTriple σ₁₂ σ₂₃ σ₁₃] -variable [Module R M] [Module R₂ M₂] [Module R₃ M₃] +variable [Semiring R] [Semiring R₂] +variable [AddCommMonoid M] [AddCommMonoid M₂] +variable {σ₁₂ : R →+* R₂} +variable [Module R M] [Module R₂ M₂] open Submodule diff --git a/Mathlib/MeasureTheory/Decomposition/Jordan.lean b/Mathlib/MeasureTheory/Decomposition/Jordan.lean index 6ff1e74d9497e9..12402fc826ccef 100644 --- a/Mathlib/MeasureTheory/Decomposition/Jordan.lean +++ b/Mathlib/MeasureTheory/Decomposition/Jordan.lean @@ -44,7 +44,7 @@ noncomputable section open scoped Classical MeasureTheory ENNReal NNReal -variable {α β : Type*} [MeasurableSpace α] +variable {α : Type*} [MeasurableSpace α] namespace MeasureTheory @@ -187,7 +187,7 @@ namespace SignedMeasure open scoped Classical open JordanDecomposition Measure Set VectorMeasure -variable {s : SignedMeasure α} {μ ν : Measure α} [IsFiniteMeasure μ] [IsFiniteMeasure ν] +variable {s : SignedMeasure α} /-- Given a signed measure `s`, `s.toJordanDecomposition` is the Jordan decomposition `j`, such that `s = j.toSignedMeasure`. This property is known as the Jordan decomposition diff --git a/Mathlib/MeasureTheory/Function/Egorov.lean b/Mathlib/MeasureTheory/Function/Egorov.lean index 932a6fefb1d331..93797f4c9e62b0 100644 --- a/Mathlib/MeasureTheory/Function/Egorov.lean +++ b/Mathlib/MeasureTheory/Function/Egorov.lean @@ -42,7 +42,7 @@ This definition is useful for Egorov's theorem. -/ def notConvergentSeq [Preorder ι] (f : ι → α → β) (g : α → β) (n : ℕ) (j : ι) : Set α := ⋃ (k) (_ : j ≤ k), { x | 1 / (n + 1 : ℝ) < dist (f k x) (g x) } -variable {n : ℕ} {i j : ι} {s : Set α} {ε : ℝ} {f : ι → α → β} {g : α → β} +variable {n : ℕ} {j : ι} {s : Set α} {ε : ℝ} {f : ι → α → β} {g : α → β} theorem mem_notConvergentSeq_iff [Preorder ι] {x : α} : x ∈ notConvergentSeq f g n j ↔ ∃ k ≥ j, 1 / (n + 1 : ℝ) < dist (f k x) (g x) := by @@ -171,7 +171,7 @@ theorem tendstoUniformlyOn_diff_iUnionNotConvergentSeq (hε : 0 < ε) end Egorov -variable [SemilatticeSup ι] [Nonempty ι] [Countable ι] {γ : Type*} [TopologicalSpace γ] +variable [SemilatticeSup ι] [Nonempty ι] [Countable ι] {f : ι → α → β} {g : α → β} {s : Set α} /-- **Egorov's theorem**: If `f : ι → α → β` is a sequence of strongly measurable functions that diff --git a/Mathlib/MeasureTheory/Integral/LebesgueNormedSpace.lean b/Mathlib/MeasureTheory/Integral/LebesgueNormedSpace.lean index 874a14fc17cc0f..02feec70974ce8 100644 --- a/Mathlib/MeasureTheory/Integral/LebesgueNormedSpace.lean +++ b/Mathlib/MeasureTheory/Integral/LebesgueNormedSpace.lean @@ -13,7 +13,7 @@ open MeasureTheory Filter ENNReal Set open NNReal ENNReal -variable {α β γ δ : Type*} {m : MeasurableSpace α} {μ : MeasureTheory.Measure α} +variable {α : Type*} {m : MeasurableSpace α} {μ : MeasureTheory.Measure α} theorem aemeasurable_withDensity_iff {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [SecondCountableTopology E] [MeasurableSpace E] [BorelSpace E] {f : α → ℝ≥0} diff --git a/Mathlib/MeasureTheory/Measure/Complex.lean b/Mathlib/MeasureTheory/Measure/Complex.lean index 35a76272bc537d..611174a941c5fe 100644 --- a/Mathlib/MeasureTheory/Measure/Complex.lean +++ b/Mathlib/MeasureTheory/Measure/Complex.lean @@ -34,7 +34,7 @@ noncomputable section open scoped MeasureTheory ENNReal NNReal -variable {α β : Type*} {m : MeasurableSpace α} +variable {α : Type*} {m : MeasurableSpace α} namespace MeasureTheory diff --git a/Mathlib/MeasureTheory/Measure/VectorMeasure.lean b/Mathlib/MeasureTheory/Measure/VectorMeasure.lean index 7a254f9b3708c4..d6bc3aa0248e0f 100644 --- a/Mathlib/MeasureTheory/Measure/VectorMeasure.lean +++ b/Mathlib/MeasureTheory/Measure/VectorMeasure.lean @@ -698,7 +698,7 @@ instance instPartialOrder : PartialOrder (VectorMeasure α M) where le_trans _ _ _ h₁ h₂ i hi := le_trans (h₁ i hi) (h₂ i hi) le_antisymm _ _ h₁ h₂ := ext fun i hi => le_antisymm (h₁ i hi) (h₂ i hi) -variable {u v w : VectorMeasure α M} +variable {v w : VectorMeasure α M} theorem le_iff : v ≤ w ↔ ∀ i, MeasurableSet i → v i ≤ w i := Iff.rfl diff --git a/Mathlib/Order/UpperLower/Basic.lean b/Mathlib/Order/UpperLower/Basic.lean index 1c2dbcf53ed269..09c1126722f1f6 100644 --- a/Mathlib/Order/UpperLower/Basic.lean +++ b/Mathlib/Order/UpperLower/Basic.lean @@ -51,7 +51,7 @@ variable {α β γ : Type*} {ι : Sort*} {κ : ι → Sort*} section LE -variable [LE α] [LE β] {s t : Set α} {a : α} +variable [LE α] {s t : Set α} {a : α} /-- An upper set in an order `α` is a set such that any element greater than one of its members is also a member. Also called up-set, upward-closed set. -/ @@ -984,7 +984,7 @@ end UpperSet namespace LowerSet -variable {f : α ≃o β} {s t : LowerSet α} {a : α} {b : β} +variable {f : α ≃o β} {s t : LowerSet α} {a : α} /-- An order isomorphism of Preorders induces an order isomorphism of their lower sets. -/ def map (f : α ≃o β) : LowerSet α ≃o LowerSet β where @@ -1602,7 +1602,7 @@ variable [Preorder α] [Preorder β] section -variable {s : Set α} {t : Set β} {x : α × β} +variable {s : Set α} {t : Set β} theorem IsUpperSet.prod (hs : IsUpperSet s) (ht : IsUpperSet t) : IsUpperSet (s ×ˢ t) := fun _ _ h ha => ⟨hs h.1 ha.1, ht h.2 ha.2⟩ diff --git a/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean b/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean index fce06642b56a2f..9ecc3f1b58b8d5 100644 --- a/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean +++ b/Mathlib/Probability/Kernel/Disintegration/MeasurableStieltjes.lean @@ -48,7 +48,7 @@ open scoped NNReal ENNReal MeasureTheory Topology namespace ProbabilityTheory -variable {α β ι : Type*} +variable {α : Type*} section IsMeasurableRatCDF diff --git a/Mathlib/Probability/ProbabilityMassFunction/Basic.lean b/Mathlib/Probability/ProbabilityMassFunction/Basic.lean index 877ecc41e7f9db..a28a889e12f1a1 100644 --- a/Mathlib/Probability/ProbabilityMassFunction/Basic.lean +++ b/Mathlib/Probability/ProbabilityMassFunction/Basic.lean @@ -32,7 +32,7 @@ probability mass function, discrete probability measure noncomputable section -variable {α β γ : Type*} +variable {α : Type*} open scoped Classical open NNReal ENNReal MeasureTheory @@ -132,7 +132,7 @@ open MeasureTheory MeasureTheory.OuterMeasure def toOuterMeasure (p : PMF α) : OuterMeasure α := OuterMeasure.sum fun x : α => p x • dirac x -variable (p : PMF α) (s t : Set α) +variable (p : PMF α) (s : Set α) theorem toOuterMeasure_apply : p.toOuterMeasure s = ∑' x, s.indicator p x := tsum_congr fun x => smul_dirac_apply (p x) x s @@ -210,7 +210,7 @@ open MeasureTheory def toMeasure [MeasurableSpace α] (p : PMF α) : Measure α := p.toOuterMeasure.toMeasure ((toOuterMeasure_caratheodory p).symm ▸ le_top) -variable [MeasurableSpace α] (p : PMF α) (s t : Set α) +variable [MeasurableSpace α] (p : PMF α) (s : Set α) theorem toOuterMeasure_apply_le_toMeasure_apply : p.toOuterMeasure s ≤ p.toMeasure s := le_toMeasure_apply p.toOuterMeasure _ s @@ -333,8 +333,7 @@ instance toMeasure.isProbabilityMeasure [MeasurableSpace α] (p : PMF α) : simpa only [MeasurableSet.univ, toMeasure_apply_eq_toOuterMeasure_apply, Set.indicator_univ, toOuterMeasure_apply, ENNReal.coe_eq_one] using tsum_coe p⟩ -variable [Countable α] [MeasurableSpace α] [MeasurableSingletonClass α] (p : PMF α) (μ : Measure α) - [IsProbabilityMeasure μ] +variable [Countable α] [MeasurableSpace α] [MeasurableSingletonClass α] (p : PMF α) @[simp] theorem toMeasure_toPMF : p.toMeasure.toPMF = p := diff --git a/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean b/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean index 0bb2fd98c0bd21..8097bb16a5cf8b 100644 --- a/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean +++ b/Mathlib/Topology/ContinuousMap/StoneWeierstrass.lean @@ -453,7 +453,7 @@ end PolynomialFunctions section ContinuousMapZero -variable {X : Type*} [TopologicalSpace X] {𝕜 : Type*} [RCLike 𝕜] +variable {𝕜 : Type*} [RCLike 𝕜] open NonUnitalStarAlgebra Submodule namespace ContinuousMap diff --git a/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean b/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean index 550dee230352d3..94125fb3b8a4c9 100644 --- a/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean +++ b/Mathlib/Topology/MetricSpace/Pseudo/Basic.lean @@ -18,9 +18,9 @@ Further results about pseudo-metric spaces. open Set Filter TopologicalSpace Bornology open scoped ENNReal NNReal Uniformity Topology -universe u v w +universe u v -variable {α : Type u} {β : Type v} {X ι : Type*} +variable {α : Type u} {β : Type v} {ι : Type*} variable [PseudoMetricSpace α] @@ -59,7 +59,6 @@ theorem dist_le_range_sum_of_dist_le {f : ℕ → α} (n : ℕ) {d : ℕ → ℝ namespace Metric -- instantiate pseudometric space as a topology -variable {x y z : α} {δ ε ε₁ ε₂ : ℝ} {s : Set α} nonrec theorem isUniformInducing_iff [PseudoMetricSpace β] {f : α → β} : IsUniformInducing f ↔ UniformContinuous f ∧ @@ -163,6 +162,8 @@ protected theorem cauchy_iff {f : Filter α} : Cauchy f ↔ NeBot f ∧ ∀ ε > 0, ∃ t ∈ f, ∀ x ∈ t, ∀ y ∈ t, dist x y < ε := uniformity_basis_dist.cauchy_iff +variable {s : Set α} + /-- Given a point `x` in a discrete subset `s` of a pseudometric space, there is an open ball centered at `x` and intersecting `s` only at `x`. -/ theorem exists_ball_inter_eq_singleton_of_mem_discrete [DiscreteTopology s] {x : α} (hx : x ∈ s) : @@ -206,8 +207,6 @@ end Real namespace Metric -variable {x y z : α} {ε ε₁ ε₂ : ℝ} {s : Set α} - -- Porting note: `TopologicalSpace.IsSeparable.separableSpace` moved to `EMetricSpace` /-- The preimage of a separable set by an inducing map is separable. -/ From ede775853cc9f271a9fcf1475dec887f82544e30 Mon Sep 17 00:00:00 2001 From: Andrew Yang Date: Wed, 16 Oct 2024 18:15:31 +0000 Subject: [PATCH 244/425] =?UTF-8?q?feat(AlgebraicGeometry):=20Classificati?= =?UTF-8?q?on=20of=20`Spec=20R=20=E2=9F=B6=20X`=20with=20`R`=20local.=20(#?= =?UTF-8?q?15240)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Andrew Yang <36414270+erdOne@users.noreply.github.com> --- .../PrimeSpectrum/Basic.lean | 4 + Mathlib/AlgebraicGeometry/Scheme.lean | 11 + Mathlib/AlgebraicGeometry/Stalk.lean | 270 +++++++++++++++++- 3 files changed, 276 insertions(+), 9 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/PrimeSpectrum/Basic.lean b/Mathlib/AlgebraicGeometry/PrimeSpectrum/Basic.lean index f3fa7a4fbdf4ab..26c8303a688160 100644 --- a/Mathlib/AlgebraicGeometry/PrimeSpectrum/Basic.lean +++ b/Mathlib/AlgebraicGeometry/PrimeSpectrum/Basic.lean @@ -647,6 +647,10 @@ theorem closedPoint_mem_iff (U : TopologicalSpace.Opens <| PrimeSpectrum R) : · rintro rfl trivial +lemma closed_point_mem_iff {U : TopologicalSpace.Opens (PrimeSpectrum R)} : + closedPoint R ∈ U ↔ U = ⊤ := + ⟨(eq_top_iff.mpr fun x _ ↦ (specializes_closedPoint x).mem_open U.2 ·), (· ▸ trivial)⟩ + @[simp] theorem PrimeSpectrum.comap_residue (T : Type u) [CommRing T] [LocalRing T] (x : PrimeSpectrum (ResidueField T)) : PrimeSpectrum.comap (residue T) x = closedPoint T := by diff --git a/Mathlib/AlgebraicGeometry/Scheme.lean b/Mathlib/AlgebraicGeometry/Scheme.lean index 3a705c863a6a41..546fea88d15d5b 100644 --- a/Mathlib/AlgebraicGeometry/Scheme.lean +++ b/Mathlib/AlgebraicGeometry/Scheme.lean @@ -709,4 +709,15 @@ end Scheme end Stalks +section LocalRing + +open LocalRing + +@[simp] +lemma Spec_closedPoint {R S : CommRingCat} [LocalRing R] [LocalRing S] + {f : R ⟶ S} [IsLocalRingHom f] : (Spec.map f).base (closedPoint S) = closedPoint R := + LocalRing.comap_closedPoint f + +end LocalRing + end AlgebraicGeometry diff --git a/Mathlib/AlgebraicGeometry/Stalk.lean b/Mathlib/AlgebraicGeometry/Stalk.lean index 8865ed5e23d8f8..c5d01c49065527 100644 --- a/Mathlib/AlgebraicGeometry/Stalk.lean +++ b/Mathlib/AlgebraicGeometry/Stalk.lean @@ -8,14 +8,25 @@ import Mathlib.AlgebraicGeometry.AffineScheme /-! # Stalks of a Scheme -Given a scheme `X` and a point `x : X`, `AlgebraicGeometry.Scheme.fromSpecStalk X x` is the -canonical scheme morphism from `Spec(O_x)` to `X`. This is helpful for constructing the canonical -map from the spectrum of the residue field of a point to the original scheme. +## Main definitions and results + +- `AlgebraicGeometry.Scheme.fromSpecStalk`: The canonical morphism `Spec 𝒪_{X, x} ⟶ X`. +- `AlgebraicGeometry.Scheme.range_fromSpecStalk`: The range of the map `Spec 𝒪_{X, x} ⟶ X` is + exactly the `y`s that specialize to `x`. +- `AlgebraicGeometry.SpecToEquivOfLocalRing`: + 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. -/ namespace AlgebraicGeometry -open CategoryTheory Opposite TopologicalSpace +open CategoryTheory Opposite TopologicalSpace LocalRing + +universe u + +variable {X Y : Scheme.{u}} (f : X ⟶ Y) {U V : X.Opens} (hU : IsAffineOpen U) (hV : IsAffineOpen V) + +section fromSpecStalk /-- A morphism from `Spec(O_x)` to `X`, which is defined with the help of an affine open @@ -30,8 +41,7 @@ noncomputable def IsAffineOpen.fromSpecStalk The morphism from `Spec(O_x)` to `X` given by `IsAffineOpen.fromSpec` does not depend on the affine open neighborhood of `x` we choose. -/ -theorem IsAffineOpen.fromSpecStalk_eq {X : Scheme} (x : X) {U V : X.Opens} - (hU : IsAffineOpen U) (hV : IsAffineOpen V) (hxU : x ∈ U) (hxV : x ∈ V) : +theorem IsAffineOpen.fromSpecStalk_eq (x : X) (hxU : x ∈ U) (hxV : x ∈ V) : hU.fromSpecStalk hxU = hV.fromSpecStalk hxV := by obtain ⟨U', h₁, h₂, h₃ : U' ≤ U ⊓ V⟩ := Opens.isBasis_iff_nbhd.mp (isBasis_affine_open X) (show x ∈ U ⊓ V from ⟨hxU, hxV⟩) @@ -51,12 +61,254 @@ theorem IsAffineOpen.fromSpecStalk_eq {X : Scheme} (x : X) {U V : X.Opens} If `x` is a point of `X`, this is the canonical morphism from `Spec(O_x)` to `X`. -/ noncomputable def Scheme.fromSpecStalk (X : Scheme) (x : X) : - Scheme.Spec.obj (op (X.presheaf.stalk x)) ⟶ X := + Spec (X.presheaf.stalk x) ⟶ X := (isAffineOpen_opensRange (X.affineOpenCover.map x)).fromSpecStalk (X.affineOpenCover.covers x) @[simp] -theorem IsAffineOpen.fromSpecStalk_eq_fromSpecStalk - {X : Scheme} {U : X.Opens} (hU : IsAffineOpen U) {x : X} (hxU : x ∈ U) : +theorem IsAffineOpen.fromSpecStalk_eq_fromSpecStalk {x : X} (hxU : x ∈ U) : hU.fromSpecStalk hxU = X.fromSpecStalk x := fromSpecStalk_eq .. +lemma IsAffineOpen.fromSpecStalk_closedPoint {U : Opens X} (hU : IsAffineOpen U) + {x : X} (hxU : x ∈ U) : + (hU.fromSpecStalk hxU).base (closedPoint (X.presheaf.stalk x)) = x := by + rw [IsAffineOpen.fromSpecStalk, Scheme.comp_base_apply] + rw [← hU.primeIdealOf_eq_map_closedPoint ⟨x, hxU⟩, hU.fromSpec_primeIdealOf ⟨x, hxU⟩] + +namespace Scheme + +@[simp] +lemma fromSpecStalk_closedPoint {x : X} : + (X.fromSpecStalk x).base (closedPoint (X.presheaf.stalk x)) = x := + IsAffineOpen.fromSpecStalk_closedPoint _ _ + +lemma fromSpecStalk_app {x : X} (hxU : x ∈ U) : + (X.fromSpecStalk x).app U = + X.presheaf.germ U x hxU ≫ + (ΓSpecIso (X.presheaf.stalk x)).inv ≫ + (Spec (X.presheaf.stalk x)).presheaf.map (homOfLE le_top).op := by + obtain ⟨_, ⟨V : X.Opens, hV, rfl⟩, hxV, hVU⟩ := (isBasis_affine_open X).exists_subset_of_mem_open + hxU U.2 + rw [← hV.fromSpecStalk_eq_fromSpecStalk hxV, IsAffineOpen.fromSpecStalk, Scheme.comp_app, + hV.fromSpec_app_of_le _ hVU, ← X.presheaf.germ_res (homOfLE hVU) x hxV] + simp [Category.assoc, ← ΓSpecIso_inv_naturality_assoc] + +@[reassoc] +lemma Spec_map_stalkSpecializes_fromSpecStalk {x y : X} (h : x ⤳ y) : + Spec.map (X.presheaf.stalkSpecializes h) ≫ X.fromSpecStalk y = X.fromSpecStalk x := by + obtain ⟨_, ⟨U, hU, rfl⟩, hyU, -⟩ := + (isBasis_affine_open X).exists_subset_of_mem_open (Set.mem_univ y) isOpen_univ + have hxU : x ∈ U := h.mem_open U.2 hyU + rw [← hU.fromSpecStalk_eq_fromSpecStalk hyU, ← hU.fromSpecStalk_eq_fromSpecStalk hxU, + IsAffineOpen.fromSpecStalk, IsAffineOpen.fromSpecStalk, ← Category.assoc, ← Spec.map_comp, + TopCat.Presheaf.germ_stalkSpecializes] + +@[reassoc (attr := simp)] +lemma Spec_map_stalkMap_fromSpecStalk {x} : + Spec.map (f.stalkMap x) ≫ Y.fromSpecStalk _ = X.fromSpecStalk x ≫ f := by + obtain ⟨_, ⟨U, hU, rfl⟩, hxU, -⟩ := (isBasis_affine_open Y).exists_subset_of_mem_open + (Set.mem_univ (f.base x)) isOpen_univ + obtain ⟨_, ⟨V, hV, rfl⟩, hxV, hVU⟩ := (isBasis_affine_open X).exists_subset_of_mem_open + hxU (f ⁻¹ᵁ U).2 + rw [← hU.fromSpecStalk_eq_fromSpecStalk hxU, ← hV.fromSpecStalk_eq_fromSpecStalk hxV, + IsAffineOpen.fromSpecStalk, ← Spec.map_comp_assoc, Scheme.stalkMap_germ f _ x hxU, + IsAffineOpen.fromSpecStalk, Spec.map_comp_assoc, ← X.presheaf.germ_res (homOfLE hVU) x hxV, + Spec.map_comp_assoc, Category.assoc, ← Spec.map_comp_assoc (f.app _), + Hom.app_eq_appLE, Hom.appLE_map, IsAffineOpen.Spec_map_appLE_fromSpec] + +lemma Spec_fromSpecStalk (R : CommRingCat) (x) : + (Spec R).fromSpecStalk x = + Spec.map ((ΓSpecIso R).inv ≫ (Spec R).presheaf.germ ⊤ x trivial) := by + rw [← (isAffineOpen_top (Spec R)).fromSpecStalk_eq_fromSpecStalk (x := x) trivial, + IsAffineOpen.fromSpecStalk, IsAffineOpen.fromSpec_top, isoSpec_Spec_inv, + ← Spec.map_comp] + +-- This is not a simp lemma to respect the abstraction boundaries +/-- A variant of `Spec_fromSpecStalk` that breaks abstraction boundaries. -/ +lemma Spec_fromSpecStalk' (R : CommRingCat) (x) : + (Spec R).fromSpecStalk x = Spec.map (StructureSheaf.toStalk R _) := + Spec_fromSpecStalk _ _ + +@[stacks 01J7] +lemma range_fromSpecStalk {x : X} : + Set.range (X.fromSpecStalk x).base = { y | y ⤳ x } := by + ext y + constructor + · rintro ⟨y, rfl⟩ + exact ((LocalRing.specializes_closedPoint y).map (X.fromSpecStalk x).base.2).trans + (specializes_of_eq fromSpecStalk_closedPoint) + · rintro (hy : y ⤳ x) + have := fromSpecStalk_closedPoint (x := y) + rw [← Spec_map_stalkSpecializes_fromSpecStalk hy] at this + exact ⟨_, this⟩ + +end Scheme + +end fromSpecStalk + +variable (R : CommRingCat.{u}) [LocalRing R] + +section stalkClosedPointIso + +/-- For a local ring `(R, 𝔪)`, +this is the isomorphism between the stalk of `Spec R` at `𝔪` and `R`. -/ +noncomputable +def stalkClosedPointIso : + (Spec R).presheaf.stalk (closedPoint R) ≅ R := + StructureSheaf.stalkIso _ _ ≪≫ (IsLocalization.atUnits R + (closedPoint R).asIdeal.primeCompl fun _ ↦ not_not.mp).toRingEquiv.toCommRingCatIso.symm + +lemma stalkClosedPointIso_inv : + (stalkClosedPointIso R).inv = StructureSheaf.toStalk R _ := by + ext x + exact StructureSheaf.localizationToStalk_of _ _ _ + +lemma ΓSpecIso_hom_stalkClosedPointIso_inv : + (Scheme.ΓSpecIso R).hom ≫ (stalkClosedPointIso R).inv = + (Spec R).presheaf.germ ⊤ (closedPoint _) trivial := by + rw [stalkClosedPointIso_inv, ← Iso.eq_inv_comp] + rfl + +@[reassoc (attr := simp)] +lemma germ_stalkClosedPointIso_hom : + (Spec R).presheaf.germ ⊤ (closedPoint _) trivial ≫ (stalkClosedPointIso R).hom = + (Scheme.ΓSpecIso R).hom := by + rw [← ΓSpecIso_hom_stalkClosedPointIso_inv, Category.assoc, Iso.inv_hom_id, Category.comp_id] + +lemma Spec_stalkClosedPointIso : + Spec.map (stalkClosedPointIso R).inv = (Spec R).fromSpecStalk (closedPoint R) := by + rw [stalkClosedPointIso_inv, Scheme.Spec_fromSpecStalk'] + +end stalkClosedPointIso + +section stalkClosedPointTo + +variable {R} (f : Spec R ⟶ X) + + +namespace Scheme + +/-- +Given a local ring `(R, 𝔪)` and a morphism `f : Spec R ⟶ X`, +they induce a (local) ring homomorphism `φ : 𝒪_{X, f 𝔪} ⟶ R`. + +This is inverse to `φ ↦ Spec.map φ ≫ X.fromSpecStalk (f 𝔪)`. See `SpecToEquivOfLocalRing`. +-/ +noncomputable +def stalkClosedPointTo : + X.presheaf.stalk (f.base (closedPoint R)) ⟶ R := + f.stalkMap (closedPoint R) ≫ (stalkClosedPointIso R).hom + +instance isLocalRingHom_stalkClosedPointTo : + IsLocalRingHom (stalkClosedPointTo f) := by + apply (config := { allowSynthFailures := true }) RingHom.isLocalRingHom_comp + · apply isLocalRingHom_of_iso + · apply f.prop + +lemma preimage_eq_top_of_closedPoint_mem + {U : Opens X} (hU : f.base (closedPoint R) ∈ U) : f ⁻¹ᵁ U = ⊤ := + LocalRing.closed_point_mem_iff.mp hU + +lemma stalkClosedPointTo_comp (g : X ⟶ Y) : + stalkClosedPointTo (f ≫ g) = g.stalkMap _ ≫ stalkClosedPointTo f := by + rw [stalkClosedPointTo, Scheme.stalkMap_comp] + exact Category.assoc _ _ _ + +lemma germ_stalkClosedPointTo_Spec {R S : CommRingCat} [LocalRing S] (φ : R ⟶ S): + (Spec R).presheaf.germ ⊤ _ trivial ≫ stalkClosedPointTo (Spec.map φ) = + (ΓSpecIso R).hom ≫ φ := by + rw [stalkClosedPointTo, Scheme.stalkMap_germ_assoc, ← Iso.inv_comp_eq, + ← ΓSpecIso_inv_naturality_assoc] + simp_rw [Opens.map_top] + rw [germ_stalkClosedPointIso_hom, Iso.inv_hom_id, Category.comp_id] + +@[reassoc] +lemma germ_stalkClosedPointTo (U : Opens X) (hU : f.base (closedPoint R) ∈ U) : + X.presheaf.germ U _ hU ≫ stalkClosedPointTo f = f.app U ≫ + ((Spec R).presheaf.mapIso (eqToIso (preimage_eq_top_of_closedPoint_mem f hU).symm).op ≪≫ + ΓSpecIso R).hom := by + rw [stalkClosedPointTo, Scheme.stalkMap_germ_assoc, Iso.trans_hom] + congr 1 + rw [← Iso.eq_comp_inv, Category.assoc, ΓSpecIso_hom_stalkClosedPointIso_inv] + simp only [TopCat.Presheaf.pushforward_obj_obj, Functor.mapIso_hom, Iso.op_hom, eqToIso.hom, + TopCat.Presheaf.germ_res] + +@[reassoc] +lemma germ_stalkClosedPointTo_Spec_fromSpecStalk + {x : X} (f : X.presheaf.stalk x ⟶ R) [IsLocalRingHom f] (U : Opens X) (hU) : + X.presheaf.germ U _ hU ≫ stalkClosedPointTo (Spec.map f ≫ X.fromSpecStalk x) = + X.presheaf.germ U x (by simpa using hU) ≫ f := by + have : (Spec.map f ≫ X.fromSpecStalk x).base (closedPoint R) = x := by + rw [comp_base_apply, Spec_closedPoint, fromSpecStalk_closedPoint] + have : x ∈ U := this ▸ hU + simp only [TopCat.Presheaf.stalkCongr_hom, TopCat.Presheaf.germ_stalkSpecializes_assoc, + germ_stalkClosedPointTo, comp_app, + fromSpecStalk_app (X := X) (x := x) this, Category.assoc, Iso.trans_hom, + Functor.mapIso_hom, Hom.naturality_assoc, ← Functor.map_comp_assoc, + (Spec.map f).app_eq_appLE, Hom.appLE_map_assoc, Hom.map_appLE_assoc] + simp_rw [← Opens.map_top (Spec.map f).base] + rw [← (Spec.map f).app_eq_appLE, ΓSpecIso_naturality, Iso.inv_hom_id_assoc] + +lemma stalkClosedPointTo_fromSpecStalk (x : X) : + stalkClosedPointTo (X.fromSpecStalk x) = + (X.presheaf.stalkCongr (by rw [fromSpecStalk_closedPoint]; rfl)).hom := by + refine TopCat.Presheaf.stalk_hom_ext _ fun U hxU ↦ ?_ + simp only [TopCat.Presheaf.stalkCongr_hom, TopCat.Presheaf.germ_stalkSpecializes, id_eq] + 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 + +@[reassoc] +lemma Spec_stalkClosedPointTo_fromSpecStalk : + Spec.map (stalkClosedPointTo f) ≫ X.fromSpecStalk _ = f := by + obtain ⟨_, ⟨U, hU, rfl⟩, hxU, -⟩ := (isBasis_affine_open X).exists_subset_of_mem_open + (Set.mem_univ (f.base (closedPoint R))) isOpen_univ + have := IsAffineOpen.Spec_map_appLE_fromSpec f hU (isAffineOpen_top _) + (preimage_eq_top_of_closedPoint_mem f hxU).ge + rw [IsAffineOpen.fromSpec_top, Iso.eq_inv_comp, isoSpec_Spec_hom] at this + rw [← hU.fromSpecStalk_eq_fromSpecStalk hxU, IsAffineOpen.fromSpecStalk, ← Spec.map_comp_assoc, + germ_stalkClosedPointTo] + simpa only [Iso.trans_hom, Functor.mapIso_hom, Iso.op_hom, Category.assoc, + Hom.app_eq_appLE, Hom.appLE_map_assoc, Spec.map_comp_assoc] + +end Scheme + +end stalkClosedPointTo + +variable {R} + +omit [LocalRing R] in +/-- useful lemma for applications of `SpecToEquivOfLocalRing` -/ +lemma SpecToEquivOfLocalRing_eq_iff + {f₁ f₂ : Σ x, { f : X.presheaf.stalk x ⟶ R // IsLocalRingHom f }} : + f₁ = f₂ ↔ ∃ h₁ : f₁.1 = f₂.1, f₁.2.1 = + (X.presheaf.stalkCongr (by rw [h₁]; rfl)).hom ≫ f₂.2.1 := by + constructor + · rintro rfl; simp + · obtain ⟨x₁, ⟨f₁, h₁⟩⟩ := f₁ + obtain ⟨x₂, ⟨f₂, h₂⟩⟩ := f₂ + rintro ⟨rfl : x₁ = x₂, e : f₁ = _⟩ + simp [e] + +variable (X R) + +/-- +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. +-/ +@[simps] +noncomputable +def SpecToEquivOfLocalRing : + (Spec R ⟶ X) ≃ Σ x, { f : X.presheaf.stalk x ⟶ R // IsLocalRingHom f } where + toFun f := ⟨f.base (closedPoint R), Scheme.stalkClosedPointTo f, inferInstance⟩ + invFun xf := Spec.map xf.2.1 ≫ X.fromSpecStalk xf.1 + left_inv := Scheme.Spec_stalkClosedPointTo_fromSpecStalk + right_inv xf := by + obtain ⟨x, ⟨f, hf⟩⟩ := xf + symm + refine SpecToEquivOfLocalRing_eq_iff.mpr ⟨?_, ?_⟩ + · simp only [Scheme.comp_coeBase, TopCat.coe_comp, Function.comp_apply, Spec_closedPoint, + Scheme.fromSpecStalk_closedPoint] + · refine TopCat.Presheaf.stalk_hom_ext _ fun U hxU ↦ ?_ + simp only [Scheme.germ_stalkClosedPointTo_Spec_fromSpecStalk, + TopCat.Presheaf.stalkCongr_hom, TopCat.Presheaf.germ_stalkSpecializes_assoc] + end AlgebraicGeometry From f4d8a98ef4127d1b1ba22a15494e35d14a03fa0d Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Wed, 16 Oct 2024 21:14:24 +0000 Subject: [PATCH 245/425] chore: copy `Finsupp.smul_single'` to (`Add`)`MonoidAlgebra` to avoid defeq abuse (#17825) This seems to stem from Lean 3 where it was okay to `simp` with `Finsupp` lemmas in its type synonyms `MonoidAlgebra` and `AddMonoidAlgebra`. The discrimination tree in Lean 4 correctly catches the mismatch. So we copy the lemma to the type synonyms and remove some porting notes. --- Mathlib/Algebra/MonoidAlgebra/Defs.lean | 19 ++++++++++----- Mathlib/Algebra/MonoidAlgebra/Grading.lean | 2 +- .../GroupCohomology/Resolution.lean | 23 ++++--------------- 3 files changed, 18 insertions(+), 26 deletions(-) diff --git a/Mathlib/Algebra/MonoidAlgebra/Defs.lean b/Mathlib/Algebra/MonoidAlgebra/Defs.lean index d7cde54dca7006..5f5174af5e9458 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Defs.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Defs.lean @@ -477,9 +477,13 @@ def of [MulOneClass G] : G →* MonoidAlgebra k G := end +/-- Copy of `Finsupp.smul_single'` that avoids the `MonoidAlgebra = Finsupp` defeq abuse. -/ +@[simp] +theorem smul_single' (c : k) (a : G) (b : k) : c • single a b = single a (c * b) := + Finsupp.smul_single' c a b + theorem smul_of [MulOneClass G] (g : G) (r : k) : r • of k G g = single g r := by - -- porting note (#10745): was `simp`. - rw [of_apply, smul_single', mul_one] + simp theorem of_injective [MulOneClass G] [Nontrivial k] : Function.Injective (of k G) := fun a b h => by @@ -671,8 +675,7 @@ theorem induction_on [Semiring k] [Monoid G] {p : MonoidAlgebra k G → Prop} (f refine Finsupp.induction_linear f ?_ (fun f g hf hg => hadd f g hf hg) fun g r => ?_ · simpa using hsmul 0 (of k G 1) (hM 1) · convert hsmul r (of k G g) (hM g) - -- Porting note: Was `simp only`. - rw [of_apply, smul_single', mul_one] + simp section @@ -1223,6 +1226,11 @@ def singleHom [AddZeroClass G] : k × Multiplicative G →* k[G] where map_one' := rfl map_mul' _a _b := single_mul_single.symm +/-- Copy of `Finsupp.smul_single'` that avoids the `AddMonoidAlgebra = Finsupp` defeq abuse. -/ +@[simp] +theorem smul_single' (c : k) (a : G) (b : k) : c • single a b = single a (c * b) := + Finsupp.smul_single' c a b + theorem mul_single_apply_aux [Add G] (f : k[G]) (r : k) (x y z : G) (H : ∀ a, a + x = z ↔ a = y) : (f * single x r) z = f y * r := @MonoidAlgebra.mul_single_apply_aux k (Multiplicative G) _ _ _ _ _ _ _ H @@ -1267,8 +1275,7 @@ theorem induction_on [AddMonoid G] {p : k[G] → Prop} (f : k[G]) refine Finsupp.induction_linear f ?_ (fun f g hf hg => hadd f g hf hg) fun g r => ?_ · simpa using hsmul 0 (of k G (Multiplicative.ofAdd 0)) (hM 0) · convert hsmul r (of k G (Multiplicative.ofAdd g)) (hM g) - -- Porting note: Was `simp only`. - rw [of_apply, toAdd_ofAdd, smul_single', mul_one] + simp /-- If `f : G → H` is an additive homomorphism between two additive monoids, then `Finsupp.mapDomain f` is a ring homomorphism between their add monoid algebras. -/ diff --git a/Mathlib/Algebra/MonoidAlgebra/Grading.lean b/Mathlib/Algebra/MonoidAlgebra/Grading.lean index e6e0a806f2d7f5..86426ba1b83763 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Grading.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Grading.lean @@ -132,7 +132,7 @@ theorem decomposeAux_single (m : M) (r : R) : refine (DirectSum.of_smul R _ _ _).symm.trans ?_ apply DirectSum.of_eq_of_gradedMonoid_eq refine Sigma.subtype_ext rfl ?_ - refine (Finsupp.smul_single' _ _ _).trans ?_ + refine (smul_single' _ _ _).trans ?_ rw [mul_one] rfl diff --git a/Mathlib/RepresentationTheory/GroupCohomology/Resolution.lean b/Mathlib/RepresentationTheory/GroupCohomology/Resolution.lean index acca90f2bc60f9..c99ba8f5afb4ec 100644 --- a/Mathlib/RepresentationTheory/GroupCohomology/Resolution.lean +++ b/Mathlib/RepresentationTheory/GroupCohomology/Resolution.lean @@ -214,35 +214,20 @@ theorem diagonalSucc_inv_single_left (g : G) (f : Gⁿ →₀ k) (r : k) : (diagonalSucc k G n).inv.hom (Finsupp.single g r ⊗ₜ f) = Finsupp.lift (Gⁿ⁺¹ →₀ k) k Gⁿ (fun f => single (g • partialProd f) r) f := by refine f.induction ?_ ?_ -/- Porting note (#11039): broken proof was · simp only [TensorProduct.tmul_zero, map_zero] - · intro a b x ha hb hx + · intro a b x _ _ hx simp only [lift_apply, smul_single', mul_one, TensorProduct.tmul_add, map_add, diagonalSucc_inv_single_single, hx, Finsupp.sum_single_index, mul_comm b, - zero_mul, single_zero] -/ - · rw [TensorProduct.tmul_zero, map_zero] - rw [map_zero] - · intro _ _ _ _ _ hx - rw [TensorProduct.tmul_add, map_add, map_add, hx] - simp_rw [lift_apply, smul_single, smul_eq_mul] - rw [diagonalSucc_inv_single_single, sum_single_index, mul_comm] - rw [zero_mul, single_zero] + zero_mul, single_zero] theorem diagonalSucc_inv_single_right (g : G →₀ k) (f : Gⁿ) (r : k) : (diagonalSucc k G n).inv.hom (g ⊗ₜ Finsupp.single f r) = Finsupp.lift _ k G (fun a => single (a • partialProd f) r) g := by refine g.induction ?_ ?_ -/- Porting note (#11039): broken proof was · simp only [TensorProduct.zero_tmul, map_zero] - · intro a b x ha hb hx + · intro a b x _ _ hx simp only [lift_apply, smul_single', map_add, hx, diagonalSucc_inv_single_single, - TensorProduct.add_tmul, Finsupp.sum_single_index, zero_mul, single_zero] -/ - · rw [TensorProduct.zero_tmul, map_zero, map_zero] - · intro _ _ _ _ _ hx - rw [TensorProduct.add_tmul, map_add, map_add, hx] - simp_rw [lift_apply, smul_single'] - rw [diagonalSucc_inv_single_single, sum_single_index] - rw [zero_mul, single_zero] + TensorProduct.add_tmul, Finsupp.sum_single_index, zero_mul, single_zero] end Rep From 3cf3909884d6457a49762a1d5bd514cfdebf9814 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 08:35:40 +1100 Subject: [PATCH 246/425] . From 054aa6cbdca97165c441575e81897f4c1012b7c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Wed, 16 Oct 2024 22:13:35 +0000 Subject: [PATCH 247/425] feat: `affineSpan k (insert 0 s) = span k s` (#17661) From LeanCamCombi --- .../AffineSpace/AffineSubspace.lean | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace.lean index 70ea2fa9472291..4ad30ae06cd1db 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineSubspace.lean @@ -49,6 +49,7 @@ noncomputable section open Affine open Set +open scoped Pointwise section @@ -510,6 +511,12 @@ theorem direction_affineSpan (s : Set P) : (affineSpan k s).direction = vectorSp theorem mem_affineSpan {p : P} {s : Set P} (hp : p ∈ s) : p ∈ affineSpan k s := mem_spanPoints k p s hp +@[simp] +lemma vectorSpan_add_self (s : Set V) : (vectorSpan k s : Set V) + s = affineSpan k s := by + ext + simp [mem_add, spanPoints] + aesop + end affineSpan namespace AffineSubspace @@ -1284,6 +1291,17 @@ lemma affineSpan_subset_span {s : Set V} : (affineSpan k s : Set V) ⊆ Submodule.span k s := affineSpan_le_toAffineSubspace_span +-- TODO: We want this to be simp, but `affineSpan` gets simped away to `spanPoints`! +-- Let's delete `spanPoints` +lemma affineSpan_insert_zero (s : Set V) : + (affineSpan k (insert 0 s) : Set V) = Submodule.span k s := by + rw [← Submodule.span_insert_zero] + refine affineSpan_subset_span.antisymm ?_ + rw [← vectorSpan_add_self, vectorSpan_def] + refine Subset.trans ?_ <| subset_add_left _ <| mem_insert .. + gcongr + exact subset_sub_left <| mem_insert .. + end AffineSpace' namespace AffineSubspace From 49b85364879f203cf9892c9273e8fa4d74766d53 Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Thu, 17 Oct 2024 01:03:09 +0000 Subject: [PATCH 248/425] Update lean-toolchain for testing https://github.com/leanprover/lean4/pull/5740 --- lake-manifest.json | 4 ++-- lakefile.lean | 2 +- lean-toolchain | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index 824bd6242b29c2..0a986d29971a31 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,10 +5,10 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "4def8ae307885daef61c66aa5fa95b6377aa5eff", + "rev": "ad054014e6a2c71c45bcc9c98bb7a459525bd34d", "name": "batteries", "manifestFile": "lake-manifest.json", - "inputRev": "nightly-testing", + "inputRev": "lean-pr-testing-5740", "inherited": false, "configFile": "lakefile.lean"}, {"url": "https://github.com/leanprover-community/quote4", diff --git a/lakefile.lean b/lakefile.lean index ac51402c176115..415424172db2f1 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -7,7 +7,7 @@ open Lake DSL ## Mathlib dependencies on upstream projects -/ -require "leanprover-community" / "batteries" @ git "nightly-testing" +require "leanprover-community" / "batteries" @ git "lean-pr-testing-5740" require "leanprover-community" / "Qq" @ git "master" require "leanprover-community" / "aesop" @ git "master" require "leanprover-community" / "proofwidgets" @ git "v0.0.43-pre" diff --git a/lean-toolchain b/lean-toolchain index af6a54a1b05087..398ab58674f955 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-15 +leanprover/lean4-pr-releases:pr-release-5740 From 283c172a53b8cd7cc3e0c52277b6a863be2d94c5 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 12:39:15 +1100 Subject: [PATCH 249/425] bump proofwidgets --- lakefile.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lakefile.lean b/lakefile.lean index 745cde3759780f..bb806c24f85559 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -10,7 +10,7 @@ open Lake DSL require "leanprover-community" / "batteries" @ git "nightly-testing" require "leanprover-community" / "Qq" @ git "master" require "leanprover-community" / "aesop" @ git "nightly-testing" -require "leanprover-community" / "proofwidgets" @ git "v0.0.43-pre" +require "leanprover-community" / "proofwidgets" @ git "v0.0.44-pre" require "leanprover-community" / "importGraph" @ git "main" require "leanprover-community" / "LeanSearchClient" @ git "main" from git "https://github.com/leanprover-community/LeanSearchClient" @ "main" From 4061861a77da352e35856873ae5a5be4e99b1fa4 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 02:22:29 +0000 Subject: [PATCH 250/425] chore: bump proofwidgets (#17848) --- lake-manifest.json | 4 ++-- lakefile.lean | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index 6e5aa7951c279e..d4790a02b8a62f 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -35,10 +35,10 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "cd20dae87c48495f0220663014dff11671597fcf", + "rev": "baa65c6339a56bd22b7292aa4511c54b3cc7a6af", "name": "proofwidgets", "manifestFile": "lake-manifest.json", - "inputRev": "v0.0.43-pre", + "inputRev": "v0.0.43", "inherited": false, "configFile": "lakefile.lean"}, {"url": "https://github.com/leanprover/lean4-cli", diff --git a/lakefile.lean b/lakefile.lean index e0fe819c339706..50c310fac84a60 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -10,7 +10,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 "v0.0.43-pre" +require "leanprover-community" / "proofwidgets" @ git "v0.0.43" require "leanprover-community" / "importGraph" @ git "main" require "leanprover-community" / "LeanSearchClient" @ git "main" from git "https://github.com/leanprover-community/LeanSearchClient" @ "main" From f2b345dd40c61d2c27f972b334cc81d7f71fb71a Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 13:26:41 +1100 Subject: [PATCH 251/425] fixes for leanprover/lean0 --- Mathlib/Data/List/MinMax.lean | 2 +- lake-manifest.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Data/List/MinMax.lean b/Mathlib/Data/List/MinMax.lean index 6ba04976bda0c9..fd3d418b64b5ed 100644 --- a/Mathlib/Data/List/MinMax.lean +++ b/Mathlib/Data/List/MinMax.lean @@ -443,7 +443,7 @@ lemma getD_max?_eq_unbot'_maximum (l : List α) (d : α) : cases hz : l.max? with | none => simp [List.max?_eq_none_iff.mp hz] at hy | some z => - have : Antisymm (α := α) (· ≤ ·) := ⟨_root_.le_antisymm⟩ + have : Std.Antisymm (α := α) (· ≤ ·) := ⟨_root_.le_antisymm⟩ rw [List.max?_eq_some_iff] at hz · rw [Option.getD_some] exact _root_.le_antisymm (hy.right _ hz.left) (hz.right _ hy.left) diff --git a/lake-manifest.json b/lake-manifest.json index 0a986d29971a31..4b80e6666c9f47 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "ad054014e6a2c71c45bcc9c98bb7a459525bd34d", + "rev": "0c9c4dc912dcfabebbc0d4127de3da778a4c64dc", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "lean-pr-testing-5740", From 65e1494f16af0b4c31d71f17e1a784e0659c570a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Thu, 17 Oct 2024 02:29:59 +0000 Subject: [PATCH 252/425] chore: make the measurability assumption be the first argument in `lintegral_indicator` (#17830) ... rather than `f`. Change `integral_indicator` and similar lemmas to match. From GibbsMeasure --- .../Constructions/Prod/Basic.lean | 6 +++--- .../MeasureTheory/Decomposition/Lebesgue.lean | 4 ++-- .../ConditionalExpectation/CondexpL2.lean | 2 +- .../Function/LpSeminorm/Basic.lean | 4 ++-- Mathlib/MeasureTheory/Function/LpSpace.lean | 2 +- .../MeasureTheory/Group/FundamentalDomain.lean | 2 +- Mathlib/MeasureTheory/Group/Prod.lean | 10 +++++----- .../MeasureTheory/Integral/IntegrableOn.lean | 2 +- .../Integral/IntegralEqImproper.lean | 2 +- Mathlib/MeasureTheory/Integral/Layercake.lean | 4 ++-- Mathlib/MeasureTheory/Integral/Lebesgue.lean | 18 +++++++++--------- .../MeasureTheory/Integral/SetIntegral.lean | 2 +- Mathlib/MeasureTheory/Measure/GiryMonad.lean | 2 +- .../Measure/HasOuterApproxClosed.lean | 4 ++-- Mathlib/MeasureTheory/Measure/WithDensity.lean | 2 +- Mathlib/Probability/Distributions/Uniform.lean | 2 +- Mathlib/Probability/Integration.lean | 4 ++-- Mathlib/Probability/Kernel/Composition.lean | 2 +- .../Kernel/Disintegration/Basic.lean | 2 +- .../Kernel/Disintegration/Integral.lean | 4 ++-- .../Kernel/Disintegration/Unique.lean | 2 +- .../Probability/Kernel/MeasureCompProd.lean | 2 +- 22 files changed, 42 insertions(+), 42 deletions(-) diff --git a/Mathlib/MeasureTheory/Constructions/Prod/Basic.lean b/Mathlib/MeasureTheory/Constructions/Prod/Basic.lean index a3700ee3a34cfb..a41e36a07b43e2 100644 --- a/Mathlib/MeasureTheory/Constructions/Prod/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/Prod/Basic.lean @@ -260,7 +260,7 @@ theorem Measurable.lintegral_prod_right' [SFinite ν] : ?_ ?_ ?_ · intro c s hs simp only [← indicator_comp_right] - suffices Measurable fun x => c * ν (Prod.mk x ⁻¹' s) by simpa [lintegral_indicator _ (m hs)] + suffices Measurable fun x => c * ν (Prod.mk x ⁻¹' s) by simpa [lintegral_indicator (m hs)] exact (measurable_measure_prod_mk_left hs).const_mul _ · rintro f g - hf - h2f h2g simp only [Pi.add_apply] @@ -333,7 +333,7 @@ theorem prod_prod (s : Set α) (t : Set β) : μ.prod ν (s ×ˢ t) = μ s * ν _ = μ S * ν T := by rw [prod_apply hSTm] simp_rw [mk_preimage_prod_right_eq_if, measure_if, - lintegral_indicator _ (measurableSet_toMeasurable _ _), lintegral_const, + lintegral_indicator (measurableSet_toMeasurable _ _), lintegral_const, restrict_apply_univ, mul_comm] _ = μ s * ν t := by rw [measure_toMeasurable, measure_toMeasurable] · -- Formalization is based on https://mathoverflow.net/a/254134/136589 @@ -899,7 +899,7 @@ theorem lintegral_prod_of_measurable : rw [← indicator_comp_right, const_def, const_comp, ← const_def] conv_rhs => enter [2, x] - rw [lintegral_indicator _ (m (x := x) hs), lintegral_const, + rw [lintegral_indicator (m (x := x) hs), lintegral_const, Measure.restrict_apply MeasurableSet.univ, univ_inter] simp [hs, lintegral_const_mul, measurable_measure_prod_mk_left (ν := ν) hs, prod_apply] · rintro f g - hf _ h2f h2g diff --git a/Mathlib/MeasureTheory/Decomposition/Lebesgue.lean b/Mathlib/MeasureTheory/Decomposition/Lebesgue.lean index 291ea3c448fc53..de3c05de65b395 100644 --- a/Mathlib/MeasureTheory/Decomposition/Lebesgue.lean +++ b/Mathlib/MeasureTheory/Decomposition/Lebesgue.lean @@ -900,7 +900,7 @@ theorem haveLebesgueDecomposition_of_finiteMeasure [IsFiniteMeasure μ] [IsFinit (∫⁻ a in A ∩ E, ε + ξ a ∂ν) + ∫⁻ a in A \ E, ξ a ∂ν := by simp only [lintegral_add_left measurable_const, lintegral_add_left hξm, setLIntegral_const, add_assoc, lintegral_inter_add_diff _ _ hE₁, Pi.add_apply, - lintegral_indicator _ hE₁, restrict_apply hE₁] + lintegral_indicator hE₁, restrict_apply hE₁] rw [inter_comm, add_comm] rw [this, ← measure_inter_add_diff A hE₁] exact add_le_add (hε₂ A hA) (hξle (A \ E) (hA.diff hE₁)) @@ -908,7 +908,7 @@ theorem haveLebesgueDecomposition_of_finiteMeasure [IsFiniteMeasure μ] [IsFinit le_sSup ⟨ξ + E.indicator fun _ ↦ (ε : ℝ≥0∞), hξε, rfl⟩ -- but this contradicts the maximality of `∫⁻ x, ξ x ∂ν` refine not_lt.2 this ?_ - rw [hξ₁, lintegral_add_left hξm, lintegral_indicator _ hE₁, setLIntegral_const] + rw [hξ₁, lintegral_add_left hξm, lintegral_indicator hE₁, setLIntegral_const] refine ENNReal.lt_add_right ?_ (ENNReal.mul_pos_iff.2 ⟨ENNReal.coe_pos.2 hε₁, hE₂⟩).ne' have := measure_ne_top (ν.withDensity ξ) univ rwa [withDensity_apply _ MeasurableSet.univ, Measure.restrict_univ] at this diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean index 31ce53180ae05c..54f8441a10130d 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL2.lean @@ -203,7 +203,7 @@ theorem lintegral_nnnorm_condexpL2_indicator_le_real (hs : MeasurableSet s) (hμ classical simp_rw [Set.indicator_apply] split_ifs <;> simp - rw [h_eq, lintegral_indicator _ hs, lintegral_const, Measure.restrict_restrict hs] + rw [h_eq, lintegral_indicator hs, lintegral_const, Measure.restrict_restrict hs] simp only [one_mul, Set.univ_inter, MeasurableSet.univ, Measure.restrict_apply] end Real diff --git a/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean b/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean index 883a202727ea9e..5bda6afb8f9e16 100644 --- a/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean +++ b/Mathlib/MeasureTheory/Function/LpSeminorm/Basic.lean @@ -335,7 +335,7 @@ theorem eLpNorm_indicator_eq_restrict {f : α → E} {s : Set α} (hs : Measurab ← ENNReal.essSup_indicator_eq_essSup_restrict hs, ENNReal.coe_indicator, nnnorm_indicator_eq_indicator_nnnorm] · rcases eq_or_ne p 0 with rfl | hp₀; · simp - simp only [eLpNorm_eq_lintegral_rpow_nnnorm hp₀ hp, ← lintegral_indicator _ hs, + simp only [eLpNorm_eq_lintegral_rpow_nnnorm hp₀ hp, ← lintegral_indicator hs, ENNReal.coe_indicator, nnnorm_indicator_eq_indicator_nnnorm] congr with x by_cases hx : x ∈ s <;> simp [ENNReal.toReal_pos, *] @@ -1273,7 +1273,7 @@ theorem le_eLpNorm_of_bddBelow (hp : p ≠ 0) (hp' : p ≠ ∞) {f : α → F} ( one_div, ENNReal.le_rpow_inv_iff (ENNReal.toReal_pos hp hp'), ENNReal.mul_rpow_of_nonneg _ _ ENNReal.toReal_nonneg, ← ENNReal.rpow_mul, inv_mul_cancel₀ (ENNReal.toReal_pos hp hp').ne.symm, ENNReal.rpow_one, ← setLIntegral_const, - ← lintegral_indicator _ hs] + ← lintegral_indicator hs] refine lintegral_mono_ae ?_ filter_upwards [hf] with x hx by_cases hxs : x ∈ s diff --git a/Mathlib/MeasureTheory/Function/LpSpace.lean b/Mathlib/MeasureTheory/Function/LpSpace.lean index 12414c825abe8b..a20a1c45824a73 100644 --- a/Mathlib/MeasureTheory/Function/LpSpace.lean +++ b/Mathlib/MeasureTheory/Function/LpSpace.lean @@ -616,7 +616,7 @@ theorem eLpNorm_indicator_eq_eLpNorm_restrict {f : α → F} (hs : MeasurableSet simp_rw [eLpNorm_eq_lintegral_rpow_nnnorm hp_zero hp_top] suffices (∫⁻ x, (‖s.indicator f x‖₊ : ℝ≥0∞) ^ p.toReal ∂μ) = ∫⁻ x in s, (‖f x‖₊ : ℝ≥0∞) ^ p.toReal ∂μ by rw [this] - rw [← lintegral_indicator _ hs] + rw [← lintegral_indicator hs] congr simp_rw [nnnorm_indicator_eq_indicator_nnnorm, ENNReal.coe_indicator] have h_zero : (fun x => x ^ p.toReal) (0 : ℝ≥0∞) = 0 := by diff --git a/Mathlib/MeasureTheory/Group/FundamentalDomain.lean b/Mathlib/MeasureTheory/Group/FundamentalDomain.lean index b7e676a68b71b8..993b79332bb456 100644 --- a/Mathlib/MeasureTheory/Group/FundamentalDomain.lean +++ b/Mathlib/MeasureTheory/Group/FundamentalDomain.lean @@ -317,7 +317,7 @@ theorem measure_set_eq (hs : IsFundamentalDomain G s μ) (ht : IsFundamentalDoma refine hs.setLIntegral_eq ht (Set.indicator A fun _ => 1) fun g x ↦ ?_ convert (Set.indicator_comp_right (g • · : α → α) (g := fun _ ↦ (1 : ℝ≥0∞))).symm rw [hA g] - simpa [Measure.restrict_apply hA₀, lintegral_indicator _ hA₀] using this + simpa [Measure.restrict_apply hA₀, lintegral_indicator hA₀] using this /-- If `s` and `t` are two fundamental domains of the same action, then their measures are equal. -/ @[to_additive "If `s` and `t` are two fundamental domains of the same action, then their measures diff --git a/Mathlib/MeasureTheory/Group/Prod.lean b/Mathlib/MeasureTheory/Group/Prod.lean index 38b8691d5bc0d7..29e7a7bd7f9340 100644 --- a/Mathlib/MeasureTheory/Group/Prod.lean +++ b/Mathlib/MeasureTheory/Group/Prod.lean @@ -221,7 +221,7 @@ theorem absolutelyContinuous_map_div_left (g : G) : μ ≪ map (fun h => g / h) @[to_additive "This is the computation performed in the proof of [Halmos, §60 Th. A]."] theorem measure_mul_lintegral_eq [IsMulLeftInvariant ν] (sm : MeasurableSet s) (f : G → ℝ≥0∞) (hf : Measurable f) : (μ s * ∫⁻ y, f y ∂ν) = ∫⁻ x, ν ((fun z => z * x) ⁻¹' s) * f x⁻¹ ∂μ := by - rw [← setLIntegral_one, ← lintegral_indicator _ sm, + rw [← setLIntegral_one, ← lintegral_indicator sm, ← lintegral_lintegral_mul (measurable_const.indicator sm).aemeasurable hf.aemeasurable, ← lintegral_lintegral_mul_inv μ ν] swap @@ -233,7 +233,7 @@ theorem measure_mul_lintegral_eq [IsMulLeftInvariant ν] (sm : MeasurableSet s) have : ∀ x y, s.indicator (fun _ : G => (1 : ℝ≥0∞)) (y * x) = ((fun z => z * x) ⁻¹' s).indicator (fun b : G => 1) y := by intro x y; symm; convert indicator_comp_right (M := ℝ≥0∞) fun y => y * x using 2; ext1; rfl - simp_rw [this, lintegral_mul_const _ (ms _), lintegral_indicator _ (measurable_mul_const _ sm), + simp_rw [this, lintegral_mul_const _ (ms _), lintegral_indicator (measurable_mul_const _ sm), setLIntegral_one] /-- Any two nonzero left-invariant measures are absolutely continuous w.r.t. each other. -/ @@ -262,11 +262,11 @@ theorem ae_measure_preimage_mul_right_lt_top (hμs : μ' s ≠ ∞) : simp only [ν'.inv_apply] at h3A apply ae_lt_top (measurable_measure_mul_right ν' sm) have h1 := measure_mul_lintegral_eq μ' ν' sm (A⁻¹.indicator 1) (measurable_one.indicator hA.inv) - rw [lintegral_indicator _ hA.inv] at h1 + rw [lintegral_indicator hA.inv] at h1 simp_rw [Pi.one_apply, setLIntegral_one, ← image_inv, indicator_image inv_injective, image_inv, ← indicator_mul_right _ fun x => ν' ((fun y => y * x) ⁻¹' s), Function.comp, Pi.one_apply, mul_one] at h1 - rw [← lintegral_indicator _ hA, ← h1] + rw [← lintegral_indicator hA, ← h1] exact ENNReal.mul_ne_top hμs h3A.ne @[to_additive] @@ -320,7 +320,7 @@ theorem measure_mul_measure_eq (s t : Set G) (h2s : ν' s ≠ 0) (h3s : ν' s (measurable_const.indicator ht) have h2 := measure_lintegral_div_measure μ' ν' hs h2s h3s (t.indicator fun _ => 1) (measurable_const.indicator ht) - rw [lintegral_indicator _ ht, setLIntegral_one] at h1 h2 + rw [lintegral_indicator ht, setLIntegral_one] at h1 h2 rw [← h1, mul_left_comm, h2] /-- Left invariant Borel measures on a measurable group are unique (up to a scalar). -/ diff --git a/Mathlib/MeasureTheory/Integral/IntegrableOn.lean b/Mathlib/MeasureTheory/Integral/IntegrableOn.lean index ae1b813c974c15..68ca4ecc4d917c 100644 --- a/Mathlib/MeasureTheory/Integral/IntegrableOn.lean +++ b/Mathlib/MeasureTheory/Integral/IntegrableOn.lean @@ -227,7 +227,7 @@ theorem MeasurePreserving.integrableOn_image [MeasurableSpace β] {e : α → β theorem integrable_indicator_iff (hs : MeasurableSet s) : Integrable (indicator s f) μ ↔ IntegrableOn f s μ := by simp [IntegrableOn, Integrable, HasFiniteIntegral, nnnorm_indicator_eq_indicator_nnnorm, - ENNReal.coe_indicator, lintegral_indicator _ hs, aestronglyMeasurable_indicator_iff hs] + ENNReal.coe_indicator, lintegral_indicator hs, aestronglyMeasurable_indicator_iff hs] theorem IntegrableOn.integrable_indicator (h : IntegrableOn f s μ) (hs : MeasurableSet s) : Integrable (indicator s f) μ := diff --git a/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean b/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean index d2bec25790e579..bcdccb8f63e40e 100644 --- a/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean +++ b/Mathlib/MeasureTheory/Integral/IntegralEqImproper.lean @@ -361,7 +361,7 @@ private theorem lintegral_tendsto_of_monotone_of_nat {φ : ℕ → Set α} (hφ indicator_le_indicator_of_subset (hmono hij) (fun x => zero_le <| f x) x 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 f (hφ.measurableSet n) + lintegral_indicator (hφ.measurableSet n) _ theorem AECover.lintegral_tendsto_of_nat {φ : ℕ → Set α} (hφ : AECover μ atTop φ) {f : α → ℝ≥0∞} (hfm : AEMeasurable f μ) : Tendsto (∫⁻ x in φ ·, f x ∂μ) atTop (𝓝 <| ∫⁻ x, f x ∂μ) := by diff --git a/Mathlib/MeasureTheory/Integral/Layercake.lean b/Mathlib/MeasureTheory/Integral/Layercake.lean index ccdbcf47487abc..17be63bb0326bb 100644 --- a/Mathlib/MeasureTheory/Integral/Layercake.lean +++ b/Mathlib/MeasureTheory/Integral/Layercake.lean @@ -122,9 +122,9 @@ theorem lintegral_comp_eq_lintegral_meas_le_mul_of_measurable_of_sigmaFinite congr exact intervalIntegral.integral_of_le (f_nn ω) rw [lintegral_congr integrand_eq] - simp_rw [← lintegral_indicator (fun t => ENNReal.ofReal (g t)) measurableSet_Ioc] + simp_rw [← lintegral_indicator measurableSet_Ioc] -- Porting note: was part of `simp_rw` on the previous line, but didn't trigger. - rw [← lintegral_indicator _ measurableSet_Ioi, lintegral_lintegral_swap] + rw [← lintegral_indicator measurableSet_Ioi, lintegral_lintegral_swap] · apply congr_arg funext s have aux₁ : diff --git a/Mathlib/MeasureTheory/Integral/Lebesgue.lean b/Mathlib/MeasureTheory/Integral/Lebesgue.lean index 5be3b2d1f299b2..511c11d6a00ddf 100644 --- a/Mathlib/MeasureTheory/Integral/Lebesgue.lean +++ b/Mathlib/MeasureTheory/Integral/Lebesgue.lean @@ -757,7 +757,7 @@ theorem lintegral_indicator_le (f : α → ℝ≥0∞) (s : Set α) : simpa [H] using hg x @[simp] -theorem lintegral_indicator (f : α → ℝ≥0∞) {s : Set α} (hs : MeasurableSet s) : +theorem lintegral_indicator {s : Set α} (hs : MeasurableSet s) (f : α → ℝ≥0∞) : ∫⁻ a, s.indicator f a ∂μ = ∫⁻ a in s, f a ∂μ := by apply le_antisymm (lintegral_indicator_le f s) simp only [lintegral, ← restrict_lintegral_eq_lintegral_restrict _ hs, iSup_subtype'] @@ -765,20 +765,20 @@ theorem lintegral_indicator (f : α → ℝ≥0∞) {s : Set α} (hs : Measurabl refine ⟨⟨φ.restrict s, fun x => ?_⟩, le_rfl⟩ simp [hφ x, hs, indicator_le_indicator] -lemma setLIntegral_indicator (f : α → ℝ≥0∞) {s t : Set α} (hs : MeasurableSet s) : +lemma setLIntegral_indicator {s t : Set α} (hs : MeasurableSet s) (f : α → ℝ≥0∞) : ∫⁻ a in t, s.indicator f a ∂μ = ∫⁻ a in s ∩ t, f a ∂μ := by - rw [lintegral_indicator _ hs, Measure.restrict_restrict hs] + rw [lintegral_indicator hs, Measure.restrict_restrict hs] -theorem lintegral_indicator₀ (f : α → ℝ≥0∞) {s : Set α} (hs : NullMeasurableSet s μ) : +theorem lintegral_indicator₀ {s : Set α} (hs : NullMeasurableSet s μ) (f : α → ℝ≥0∞) : ∫⁻ a, s.indicator f a ∂μ = ∫⁻ a in s, f a ∂μ := by rw [← lintegral_congr_ae (indicator_ae_eq_of_ae_eq_set hs.toMeasurable_ae_eq), - lintegral_indicator _ (measurableSet_toMeasurable _ _), + lintegral_indicator (measurableSet_toMeasurable _ _), Measure.restrict_congr_set hs.toMeasurable_ae_eq] lemma setLIntegral_indicator₀ (f : α → ℝ≥0∞) {s t : Set α} (hs : NullMeasurableSet s (μ.restrict t)) : ∫⁻ a in t, s.indicator f a ∂μ = ∫⁻ a in s ∩ t, f a ∂μ := by - rw [lintegral_indicator₀ _ hs, Measure.restrict_restrict₀ hs] + rw [lintegral_indicator₀ hs, Measure.restrict_restrict₀ hs] theorem lintegral_indicator_const_le (s : Set α) (c : ℝ≥0∞) : ∫⁻ a, s.indicator (fun _ => c) a ∂μ ≤ c * μ s := @@ -786,7 +786,7 @@ theorem lintegral_indicator_const_le (s : Set α) (c : ℝ≥0∞) : theorem lintegral_indicator_const₀ {s : Set α} (hs : NullMeasurableSet s μ) (c : ℝ≥0∞) : ∫⁻ a, s.indicator (fun _ => c) a ∂μ = c * μ s := by - rw [lintegral_indicator₀ _ hs, setLIntegral_const] + rw [lintegral_indicator₀ hs, setLIntegral_const] theorem lintegral_indicator_const {s : Set α} (hs : MeasurableSet s) (c : ℝ≥0∞) : ∫⁻ a, s.indicator (fun _ => c) a ∂μ = c * μ s := @@ -872,7 +872,7 @@ lemma lintegral_le_meas {s : Set α} {f : α → ℝ≥0∞} (hf : ∀ a, f a lemma setLIntegral_le_meas {s t : Set α} (hs : MeasurableSet s) {f : α → ℝ≥0∞} (hf : ∀ a ∈ s, a ∈ t → f a ≤ 1) (hf' : ∀ a ∈ s, a ∉ t → f a = 0) : ∫⁻ a in s, f a ∂μ ≤ μ t := by - rw [← lintegral_indicator _ hs] + rw [← lintegral_indicator hs] refine lintegral_le_meas (fun a ↦ ?_) (by aesop) by_cases has : a ∈ s <;> [by_cases hat : a ∈ t; skip] <;> simp [*] @@ -1909,7 +1909,7 @@ theorem lintegral_trim {μ : Measure α} (hm : m ≤ m0) {f : α → ℝ≥0∞} refine @Measurable.ennreal_induction α m (fun f => ∫⁻ a, f a ∂μ.trim hm = ∫⁻ a, f a ∂μ) ?_ ?_ ?_ f hf · intro c s hs - rw [lintegral_indicator _ hs, lintegral_indicator _ (hm s hs), setLIntegral_const, + rw [lintegral_indicator hs, lintegral_indicator (hm s hs), setLIntegral_const, setLIntegral_const] suffices h_trim_s : μ.trim hm s = μ s by rw [h_trim_s] exact trim_measurableSet_eq hm hs diff --git a/Mathlib/MeasureTheory/Integral/SetIntegral.lean b/Mathlib/MeasureTheory/Integral/SetIntegral.lean index 0174fcb3cd94f0..76b9b535d4c5cd 100644 --- a/Mathlib/MeasureTheory/Integral/SetIntegral.lean +++ b/Mathlib/MeasureTheory/Integral/SetIntegral.lean @@ -1475,7 +1475,7 @@ variable [MeasurableSpace X] [PseudoEMetricSpace X] theorem measure_le_lintegral_thickenedIndicatorAux (μ : Measure X) {E : Set X} (E_mble : MeasurableSet E) (δ : ℝ) : μ E ≤ ∫⁻ x, (thickenedIndicatorAux δ E x : ℝ≥0∞) ∂μ := by convert_to lintegral μ (E.indicator fun _ => (1 : ℝ≥0∞)) ≤ lintegral μ (thickenedIndicatorAux δ E) - · rw [lintegral_indicator _ E_mble] + · rw [lintegral_indicator E_mble] simp only [lintegral_one, Measure.restrict_apply, MeasurableSet.univ, univ_inter] · apply lintegral_mono apply indicator_le_thickenedIndicatorAux diff --git a/Mathlib/MeasureTheory/Measure/GiryMonad.lean b/Mathlib/MeasureTheory/Measure/GiryMonad.lean index 502d9433a781a6..5f92026d9e1e71 100644 --- a/Mathlib/MeasureTheory/Measure/GiryMonad.lean +++ b/Mathlib/MeasureTheory/Measure/GiryMonad.lean @@ -182,7 +182,7 @@ theorem dirac_bind {f : α → Measure β} (hf : Measurable f) (a : α) : bind ( @[simp] theorem bind_dirac {m : Measure α} : bind m dirac = m := by ext1 s hs - simp only [bind_apply hs measurable_dirac, dirac_apply' _ hs, lintegral_indicator 1 hs, + simp only [bind_apply hs measurable_dirac, dirac_apply' _ hs, lintegral_indicator hs, Pi.one_apply, lintegral_one, restrict_apply, MeasurableSet.univ, univ_inter] @[simp] diff --git a/Mathlib/MeasureTheory/Measure/HasOuterApproxClosed.lean b/Mathlib/MeasureTheory/Measure/HasOuterApproxClosed.lean index d824d0aecc8adb..6fe5d37bd096ff 100644 --- a/Mathlib/MeasureTheory/Measure/HasOuterApproxClosed.lean +++ b/Mathlib/MeasureTheory/Measure/HasOuterApproxClosed.lean @@ -80,7 +80,7 @@ theorem measure_of_cont_bdd_of_tendsto_filter_indicator {ι : Type*} {L : Filter convert tendsto_lintegral_nn_filter_of_le_const μ fs_bdd fs_lim have aux : ∀ ω, indicator E (fun _ ↦ (1 : ℝ≥0∞)) ω = ↑(indicator E (fun _ ↦ (1 : ℝ≥0)) ω) := fun ω ↦ by simp only [ENNReal.coe_indicator, ENNReal.coe_one] - simp_rw [← aux, lintegral_indicator _ E_mble] + simp_rw [← aux, lintegral_indicator E_mble] simp only [lintegral_one, Measure.restrict_apply, MeasurableSet.univ, univ_inter] /-- If a sequence of bounded continuous functions tends to the indicator of a measurable set and @@ -162,7 +162,7 @@ approximating sequence to the indicator of the set. -/ theorem measure_le_lintegral [MeasurableSpace X] [OpensMeasurableSpace X] (μ : Measure X) (n : ℕ) : μ F ≤ ∫⁻ x, (hF.apprSeq n x : ℝ≥0∞) ∂μ := by convert_to ∫⁻ x, (F.indicator (fun _ ↦ (1 : ℝ≥0∞))) x ∂μ ≤ ∫⁻ x, hF.apprSeq n x ∂μ - · rw [lintegral_indicator _ hF.measurableSet] + · rw [lintegral_indicator hF.measurableSet] simp only [lintegral_one, MeasurableSet.univ, Measure.restrict_apply, univ_inter] · apply lintegral_mono intro x diff --git a/Mathlib/MeasureTheory/Measure/WithDensity.lean b/Mathlib/MeasureTheory/Measure/WithDensity.lean index f7b67208ce3065..d343307b3e3fc1 100644 --- a/Mathlib/MeasureTheory/Measure/WithDensity.lean +++ b/Mathlib/MeasureTheory/Measure/WithDensity.lean @@ -170,7 +170,7 @@ theorem withDensity_tsum {ι : Type*} [Countable ι] {f : ι → α → ℝ≥0 theorem withDensity_indicator {s : Set α} (hs : MeasurableSet s) (f : α → ℝ≥0∞) : μ.withDensity (s.indicator f) = (μ.restrict s).withDensity f := by ext1 t ht - rw [withDensity_apply _ ht, lintegral_indicator _ hs, restrict_comm hs, ← + rw [withDensity_apply _ ht, lintegral_indicator hs, restrict_comm hs, ← withDensity_apply _ ht] theorem withDensity_indicator_one {s : Set α} (hs : MeasurableSet s) : diff --git a/Mathlib/Probability/Distributions/Uniform.lean b/Mathlib/Probability/Distributions/Uniform.lean index fca2b2cafde427..43f54dab8c27db 100644 --- a/Mathlib/Probability/Distributions/Uniform.lean +++ b/Mathlib/Probability/Distributions/Uniform.lean @@ -155,7 +155,7 @@ theorem mul_pdf_integrable (hcs : IsCompact s) (huX : IsUniform X s ℙ) : set ind := (volume s)⁻¹ • (1 : ℝ → ℝ≥0∞) have : ∀ x, ↑‖x‖₊ * s.indicator ind x = s.indicator (fun x => ‖x‖₊ * ind x) x := fun x => (s.indicator_mul_right (fun x => ↑‖x‖₊) ind).symm - simp only [ind, this, lintegral_indicator _ hcs.measurableSet, mul_one, Algebra.id.smul_eq_mul, + simp only [ind, this, lintegral_indicator hcs.measurableSet, mul_one, Algebra.id.smul_eq_mul, Pi.one_apply, Pi.smul_apply] rw [lintegral_mul_const _ measurable_nnnorm.coe_nnreal_ennreal] exact ENNReal.mul_ne_top (setLIntegral_lt_top_of_isCompact hnt.2 hcs continuous_nnnorm).ne diff --git a/Mathlib/Probability/Integration.lean b/Mathlib/Probability/Integration.lean index ad5bc0600a1698..3d42e69819c637 100644 --- a/Mathlib/Probability/Integration.lean +++ b/Mathlib/Probability/Integration.lean @@ -51,8 +51,8 @@ theorem lintegral_mul_indicator_eq_lintegral_mul_lintegral_indicator {Mf mΩ : M apply @Measurable.ennreal_induction _ Mf · intro c' s' h_meas_s' simp_rw [← inter_indicator_mul] - rw [lintegral_indicator _ (MeasurableSet.inter (hMf _ h_meas_s') h_meas_T), - lintegral_indicator _ (hMf _ h_meas_s'), lintegral_indicator _ h_meas_T] + rw [lintegral_indicator (MeasurableSet.inter (hMf _ h_meas_s') h_meas_T), + lintegral_indicator (hMf _ h_meas_s'), lintegral_indicator h_meas_T] simp only [measurable_const, lintegral_const, univ_inter, lintegral_const_mul, MeasurableSet.univ, Measure.restrict_apply] rw [IndepSets_iff] at h_ind diff --git a/Mathlib/Probability/Kernel/Composition.lean b/Mathlib/Probability/Kernel/Composition.lean index 7fbfe68d509e19..fd42f53736b76a 100644 --- a/Mathlib/Probability/Kernel/Composition.lean +++ b/Mathlib/Probability/Kernel/Composition.lean @@ -323,7 +323,7 @@ theorem compProd_restrict {s : Set β} {t : Set γ} (hs : MeasurableSet s) (ht : · simp only [h, true_and, Set.inter_def, Set.mem_setOf] · simp only [h, false_and, and_false, Set.setOf_false, measure_empty] simp_rw [this] - rw [lintegral_indicator _ hs] + rw [lintegral_indicator hs] theorem compProd_restrict_left {s : Set β} (hs : MeasurableSet s) : Kernel.restrict κ hs ⊗ₖ η = Kernel.restrict (κ ⊗ₖ η) (hs.prod MeasurableSet.univ) := by diff --git a/Mathlib/Probability/Kernel/Disintegration/Basic.lean b/Mathlib/Probability/Kernel/Disintegration/Basic.lean index 0b385aef785472..85c938f894937d 100644 --- a/Mathlib/Probability/Kernel/Disintegration/Basic.lean +++ b/Mathlib/Probability/Kernel/Disintegration/Basic.lean @@ -79,7 +79,7 @@ private lemma IsCondKernel.apply_of_ne_zero_of_measurableSet [MeasurableSingleto have : Prod.mk a ⁻¹' (Prod.mk x '' s) = ∅ := by ext y; simp [Ne.symm hax] simp only [this, measure_empty] simp_rw [this] - rw [MeasureTheory.lintegral_indicator _ (measurableSet_singleton x)] + rw [MeasureTheory.lintegral_indicator (measurableSet_singleton x)] simp only [Measure.restrict_singleton, lintegral_smul_measure, lintegral_dirac] rw [← mul_assoc, ENNReal.inv_mul_cancel hx (measure_ne_top _ _), one_mul] diff --git a/Mathlib/Probability/Kernel/Disintegration/Integral.lean b/Mathlib/Probability/Kernel/Disintegration/Integral.lean index 026257adcaf926..6f9b34c32006f2 100644 --- a/Mathlib/Probability/Kernel/Disintegration/Integral.lean +++ b/Mathlib/Probability/Kernel/Disintegration/Integral.lean @@ -53,7 +53,7 @@ lemma setLIntegral_condKernel_eq_measure_prod (a : α) {s : Set β} (hs : Measur intro b by_cases hb : b ∈ s <;> simp [hb] simp_rw [this] - rw [lintegral_indicator _ hs] + rw [lintegral_indicator hs] @[deprecated (since := "2024-06-29")] alias set_lintegral_condKernel_eq_measure_prod := setLIntegral_condKernel_eq_measure_prod @@ -172,7 +172,7 @@ lemma setLIntegral_condKernel_eq_measure_prod {s : Set β} (hs : MeasurableSet s intro b by_cases hb : b ∈ s <;> simp [hb] simp_rw [this] - rw [lintegral_indicator _ hs] + rw [lintegral_indicator hs] @[deprecated (since := "2024-06-29")] alias set_lintegral_condKernel_eq_measure_prod := setLIntegral_condKernel_eq_measure_prod diff --git a/Mathlib/Probability/Kernel/Disintegration/Unique.lean b/Mathlib/Probability/Kernel/Disintegration/Unique.lean index e1b79719abfe15..3a2d73da4ca976 100644 --- a/Mathlib/Probability/Kernel/Disintegration/Unique.lean +++ b/Mathlib/Probability/Kernel/Disintegration/Unique.lean @@ -50,7 +50,7 @@ theorem eq_condKernel_of_measure_eq_compProd' (κ : Kernel α Ω) [IsSFiniteKern refine ae_eq_of_forall_setLIntegral_eq_of_sigmaFinite (Kernel.measurable_coe κ hs) (Kernel.measurable_coe ρ.condKernel hs) (fun t ht _ ↦ ?_) conv_rhs => rw [Measure.setLIntegral_condKernel_eq_measure_prod ht hs, hκ] - simp only [Measure.compProd_apply (ht.prod hs), Set.mem_prod, ← lintegral_indicator _ ht] + simp only [Measure.compProd_apply (ht.prod hs), Set.mem_prod, ← lintegral_indicator ht] congr with x by_cases hx : x ∈ t all_goals simp [hx] diff --git a/Mathlib/Probability/Kernel/MeasureCompProd.lean b/Mathlib/Probability/Kernel/MeasureCompProd.lean index b2bf06645a1a66..9e4b40f0b17730 100644 --- a/Mathlib/Probability/Kernel/MeasureCompProd.lean +++ b/Mathlib/Probability/Kernel/MeasureCompProd.lean @@ -61,7 +61,7 @@ lemma compProd_apply [SFinite μ] [IsSFiniteKernel κ] {s : Set (α × β)} (hs lemma compProd_apply_prod [SFinite μ] [IsSFiniteKernel κ] {s : Set α} {t : Set β} (hs : MeasurableSet s) (ht : MeasurableSet t) : (μ ⊗ₘ κ) (s ×ˢ t) = ∫⁻ a in s, κ a t ∂μ := by - rw [compProd_apply (hs.prod ht), ← lintegral_indicator _ hs] + rw [compProd_apply (hs.prod ht), ← lintegral_indicator hs] congr with a classical rw [Set.indicator_apply] From b33faadf563e7b3d6b9578d89a7f04292fc0f86d Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Thu, 17 Oct 2024 02:58:15 +0000 Subject: [PATCH 253/425] chore(Topology/Group): move `QuotientGroup` to a new file (#17473) --- Mathlib.lean | 1 + .../Constructions/Polish/Basic.lean | 5 +- .../MeasureTheory/Measure/Haar/Quotient.lean | 2 +- Mathlib/Topology/Algebra/Group/Basic.lean | 141 +----------------- Mathlib/Topology/Algebra/Group/Quotient.lean | 133 +++++++++++++++++ Mathlib/Topology/Algebra/Module/Basic.lean | 2 +- Mathlib/Topology/Algebra/OpenSubgroup.lean | 1 + .../Topology/Algebra/ProperAction/Basic.lean | 1 + Mathlib/Topology/Algebra/Ring/Ideal.lean | 1 + Mathlib/Topology/Algebra/UniformGroup.lean | 2 +- .../Topology/Compactness/LocallyCompact.lean | 14 ++ 11 files changed, 158 insertions(+), 145 deletions(-) create mode 100644 Mathlib/Topology/Algebra/Group/Quotient.lean diff --git a/Mathlib.lean b/Mathlib.lean index 5c43f1b7e519b0..1ecdac31212ba1 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4499,6 +4499,7 @@ import Mathlib.Topology.Algebra.FilterBasis import Mathlib.Topology.Algebra.Group.Basic import Mathlib.Topology.Algebra.Group.Compact import Mathlib.Topology.Algebra.Group.OpenMapping +import Mathlib.Topology.Algebra.Group.Quotient import Mathlib.Topology.Algebra.Group.SubmonoidClosure import Mathlib.Topology.Algebra.Group.TopologicalAbelianization import Mathlib.Topology.Algebra.GroupCompletion diff --git a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean index 721c0f2411c57a..02c0d1b8c30a65 100644 --- a/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/Polish/Basic.lean @@ -631,10 +631,7 @@ instance CosetSpace.borelSpace {G : Type*} [TopologicalSpace G] [PolishSpace G] instance QuotientGroup.borelSpace {G : Type*} [TopologicalSpace G] [PolishSpace G] [Group G] [TopologicalGroup G] [MeasurableSpace G] [BorelSpace G] {N : Subgroup G} [N.Normal] [IsClosed (N : Set G)] : BorelSpace (G ⧸ N) := - -- Porting note: 1st and 3rd `haveI`s were not needed in Lean 3 - haveI := Subgroup.t3_quotient_of_isClosed N - haveI := QuotientGroup.secondCountableTopology (Γ := N) - Quotient.borelSpace + ⟨continuous_mk.map_eq_borel mk_surjective⟩ namespace MeasureTheory diff --git a/Mathlib/MeasureTheory/Measure/Haar/Quotient.lean b/Mathlib/MeasureTheory/Measure/Haar/Quotient.lean index 6cb8d92d7d95f0..e552fa14c32864 100644 --- a/Mathlib/MeasureTheory/Measure/Haar/Quotient.lean +++ b/Mathlib/MeasureTheory/Measure/Haar/Quotient.lean @@ -57,7 +57,7 @@ instance QuotientGroup.measurableSMul {G : Type*} [Group G] {Γ : Subgroup G} [M [TopologicalSpace G] [TopologicalGroup G] [BorelSpace G] [BorelSpace (G ⧸ Γ)] : MeasurableSMul G (G ⧸ Γ) where measurable_const_smul g := (continuous_const_smul g).measurable - measurable_smul_const x := (QuotientGroup.continuous_smul₁ x).measurable + measurable_smul_const _ := (continuous_id.smul continuous_const).measurable end diff --git a/Mathlib/Topology/Algebra/Group/Basic.lean b/Mathlib/Topology/Algebra/Group/Basic.lean index 6ea401ab9a9493..bb19df20f74015 100644 --- a/Mathlib/Topology/Algebra/Group/Basic.lean +++ b/Mathlib/Topology/Algebra/Group/Basic.lean @@ -3,13 +3,9 @@ Copyright (c) 2017 Johannes Hölzl. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Johannes Hölzl, Mario Carneiro, Patrick Massot -/ -import Mathlib.GroupTheory.GroupAction.ConjAct -import Mathlib.GroupTheory.GroupAction.Quotient -import Mathlib.Topology.Algebra.Monoid -import Mathlib.Topology.Algebra.Constructions -import Mathlib.Topology.Maps.OpenQuotient +import Mathlib.Algebra.Group.Subgroup.Pointwise import Mathlib.Algebra.Order.Archimedean.Basic -import Mathlib.GroupTheory.QuotientGroup.Basic +import Mathlib.Topology.Algebra.Monoid /-! # Topological groups @@ -847,87 +843,6 @@ theorem TopologicalGroup.exists_antitone_basis_nhds_one [FirstCountableTopology end TopologicalGroup -namespace QuotientGroup - -variable [TopologicalSpace G] [Group G] - -@[to_additive] -instance instTopologicalSpace (N : Subgroup G) : TopologicalSpace (G ⧸ N) := - instTopologicalSpaceQuotient - -@[to_additive] -instance [CompactSpace G] (N : Subgroup G) : CompactSpace (G ⧸ N) := - Quotient.compactSpace - -@[to_additive] -theorem quotientMap_mk (N : Subgroup G) : QuotientMap (mk : G → G ⧸ N) := - quotientMap_quot_mk - -@[to_additive] -theorem continuous_mk {N : Subgroup G} : Continuous (mk : G → G ⧸ N) := - continuous_quot_mk - -section ContinuousMul - -variable [ContinuousMul G] {N : Subgroup G} - -@[to_additive] -theorem isOpenMap_coe : IsOpenMap ((↑) : G → G ⧸ N) := isOpenMap_quotient_mk'_mul - -@[to_additive] -theorem isOpenQuotientMap_mk : IsOpenQuotientMap (mk : G → G ⧸ N) := - MulAction.isOpenQuotientMap_quotientMk - -@[to_additive (attr := simp)] -theorem dense_preimage_mk {s : Set (G ⧸ N)} : Dense ((↑) ⁻¹' s : Set G) ↔ Dense s := - isOpenQuotientMap_mk.dense_preimage_iff - -@[to_additive] -theorem dense_image_mk {s : Set G} : - Dense (mk '' s : Set (G ⧸ N)) ↔ Dense (s * (N : Set G)) := by - rw [← dense_preimage_mk, preimage_image_mk_eq_mul] - -@[to_additive] -instance instContinuousSMul : ContinuousSMul G (G ⧸ N) where - continuous_smul := by - rw [← (IsOpenQuotientMap.id.prodMap isOpenQuotientMap_mk).continuous_comp_iff] - exact continuous_mk.comp continuous_mul - -variable (N) - -/-- Neighborhoods in the quotient are precisely the map of neighborhoods in the prequotient. -/ -@[to_additive - "Neighborhoods in the quotient are precisely the map of neighborhoods in the prequotient."] -theorem nhds_eq (x : G) : 𝓝 (x : G ⧸ N) = Filter.map (↑) (𝓝 x) := - (isOpenQuotientMap_mk.map_nhds_eq _).symm - -@[to_additive] -instance instFirstCountableTopology [FirstCountableTopology G] : - FirstCountableTopology (G ⧸ N) where - nhds_generated_countable := mk_surjective.forall.2 fun x ↦ nhds_eq N x ▸ inferInstance - -@[to_additive (attr := deprecated (since := "2024-08-05"))] -theorem nhds_one_isCountablyGenerated [FirstCountableTopology G] [N.Normal] : - (𝓝 (1 : G ⧸ N)).IsCountablyGenerated := - inferInstance - -end ContinuousMul - -variable [TopologicalGroup G] (N : Subgroup G) - -@[to_additive] -instance instTopologicalGroup [N.Normal] : TopologicalGroup (G ⧸ N) where - continuous_mul := by - rw [← (isOpenQuotientMap_mk.prodMap isOpenQuotientMap_mk).continuous_comp_iff] - exact continuous_mk.comp continuous_mul - continuous_inv := continuous_inv.quotient_map' _ - -@[to_additive (attr := deprecated (since := "2024-08-05"))] -theorem _root_.topologicalGroup_quotient [N.Normal] : TopologicalGroup (G ⧸ N) := - instTopologicalGroup N - -end QuotientGroup - /-- A typeclass saying that `p : G × G ↦ p.1 - p.2` is a continuous function. This property automatically holds for topological additive groups but it also holds, e.g., for `ℝ≥0`. -/ class ContinuousSub (G : Type*) [TopologicalSpace G] [Sub G] : Prop where @@ -1250,13 +1165,6 @@ theorem IsClosed.mul_right_of_isCompact (ht : IsClosed t) (hs : IsCompact s) : rw [← image_op_smul] exact IsClosed.smul_left_of_isCompact ht (hs.image continuous_op) -@[to_additive] -theorem QuotientGroup.isClosedMap_coe {H : Subgroup G} (hH : IsCompact (H : Set G)) : - IsClosedMap ((↑) : G → G ⧸ H) := by - intro t ht - rw [← (quotientMap_mk H).isClosed_preimage, preimage_image_mk_eq_mul] - exact ht.mul_right_of_isCompact hH - @[to_additive] lemma subset_mul_closure_one {G} [MulOneClass G] [TopologicalSpace G] (s : Set G) : s ⊆ s * (closure {1} : Set G) := by @@ -1382,13 +1290,6 @@ theorem exists_closed_nhds_one_inv_eq_mul_subset {U : Set G} (hU : U ∈ 𝓝 1) variable (S : Subgroup G) [Subgroup.Normal S] [IsClosed (S : Set G)] -@[to_additive] -instance Subgroup.t3_quotient_of_isClosed (S : Subgroup G) [Subgroup.Normal S] - [hS : IsClosed (S : Set G)] : T3Space (G ⧸ S) := by - rw [← QuotientGroup.ker_mk' S] at hS - haveI := TopologicalGroup.t1Space (G ⧸ S) (quotientMap_quotient_mk'.isClosed_preimage.mp hS) - infer_instance - /-- A subgroup `S` of a topological group `G` acts on `G` properly discontinuously on the left, if it is discrete in the sense that `S ∩ K` is finite for all compact `K`. (See also `DiscreteTopology`.) -/ @@ -1618,18 +1519,6 @@ theorem exists_isCompact_isClosed_nhds_one [WeaklyLocallyCompactSpace G] : let ⟨K, hK₁, hKcomp, hKcl⟩ := exists_mem_nhds_isCompact_isClosed (1 : G) ⟨K, hKcomp, hKcl, hK₁⟩ -/-- A quotient of a locally compact group is locally compact. -/ -@[to_additive] -instance [LocallyCompactSpace G] (N : Subgroup G) : LocallyCompactSpace (G ⧸ N) := by - refine ⟨fun x n hn ↦ ?_⟩ - let π := ((↑) : G → G ⧸ N) - have C : Continuous π := continuous_quotient_mk' - obtain ⟨y, rfl⟩ : ∃ y, π y = x := Quot.exists_rep x - have : π ⁻¹' n ∈ 𝓝 y := preimage_nhds_coinduced hn - rcases local_compact_nhds this with ⟨s, s_mem, hs, s_comp⟩ - exact ⟨π '' s, QuotientGroup.isOpenMap_coe.image_mem_nhds s_mem, mapsTo'.mp hs, - s_comp.image C⟩ - end section @@ -1665,30 +1554,6 @@ instance {G} [TopologicalSpace G] [AddGroup G] [TopologicalAddGroup G] : TopologicalGroup (Multiplicative G) where continuous_inv := @continuous_neg G _ _ _ -section Quotient - -variable [Group G] [TopologicalSpace G] [ContinuousMul G] {Γ : Subgroup G} - -@[to_additive] -instance QuotientGroup.continuousConstSMul : ContinuousConstSMul G (G ⧸ Γ) where - continuous_const_smul g := by - convert ((@continuous_const _ _ _ _ g).mul continuous_id).quotient_map' _ - -@[to_additive] -theorem QuotientGroup.continuous_smul₁ (x : G ⧸ Γ) : Continuous fun g : G => g • x := by - induction x using QuotientGroup.induction_on - exact continuous_quotient_mk'.comp (continuous_mul_right _) - -/-- The quotient of a second countable topological group by a subgroup is second countable. -/ -@[to_additive - "The quotient of a second countable additive topological group by a subgroup is second - countable."] -instance QuotientGroup.secondCountableTopology [SecondCountableTopology G] : - SecondCountableTopology (G ⧸ Γ) := - ContinuousConstSMul.secondCountableTopology - -end Quotient - /-- If `G` is a group with topological `⁻¹`, then it is homeomorphic to its units. -/ @[to_additive " If `G` is an additive group with topological negation, then it is homeomorphic to its additive units."] @@ -1944,4 +1809,4 @@ theorem coinduced_continuous {α β : Type*} [t : TopologicalSpace α] [Group β end GroupTopology -set_option linter.style.longFile 2100 +set_option linter.style.longFile 2000 diff --git a/Mathlib/Topology/Algebra/Group/Quotient.lean b/Mathlib/Topology/Algebra/Group/Quotient.lean new file mode 100644 index 00000000000000..08cb4e12c8933d --- /dev/null +++ b/Mathlib/Topology/Algebra/Group/Quotient.lean @@ -0,0 +1,133 @@ +/- +Copyright (c) 2017 Johannes Hölzl. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Johannes Hölzl, Mario Carneiro, Patrick Massot, Yury Kudryashov +-/ +import Mathlib.GroupTheory.GroupAction.Quotient +import Mathlib.GroupTheory.QuotientGroup.Basic +import Mathlib.Topology.Algebra.Group.Basic +import Mathlib.Topology.Maps.OpenQuotient + +/-! +# Topology on the quotient group + +In this file we define topology on `G ⧸ N`, where `N` is a subgroup of `G`, +and prove basic properties of this topology. +-/ + +open scoped Pointwise Topology + +variable {G : Type*} [TopologicalSpace G] [Group G] + +namespace QuotientGroup + +@[to_additive] +instance instTopologicalSpace (N : Subgroup G) : TopologicalSpace (G ⧸ N) := + instTopologicalSpaceQuotient + +@[to_additive] +instance [CompactSpace G] (N : Subgroup G) : CompactSpace (G ⧸ N) := + Quotient.compactSpace + +@[to_additive] +theorem quotientMap_mk (N : Subgroup G) : QuotientMap (mk : G → G ⧸ N) := + quotientMap_quot_mk + +@[to_additive] +theorem continuous_mk {N : Subgroup G} : Continuous (mk : G → G ⧸ N) := + continuous_quot_mk + +section ContinuousMul + +variable [ContinuousMul G] {N : Subgroup G} + +@[to_additive] +theorem isOpenMap_coe : IsOpenMap ((↑) : G → G ⧸ N) := isOpenMap_quotient_mk'_mul + +@[to_additive] +theorem isOpenQuotientMap_mk : IsOpenQuotientMap (mk : G → G ⧸ N) := + MulAction.isOpenQuotientMap_quotientMk + +@[to_additive (attr := simp)] +theorem dense_preimage_mk {s : Set (G ⧸ N)} : Dense ((↑) ⁻¹' s : Set G) ↔ Dense s := + isOpenQuotientMap_mk.dense_preimage_iff + +@[to_additive] +theorem dense_image_mk {s : Set G} : + Dense (mk '' s : Set (G ⧸ N)) ↔ Dense (s * (N : Set G)) := by + rw [← dense_preimage_mk, preimage_image_mk_eq_mul] + +@[to_additive] +instance instContinuousSMul : ContinuousSMul G (G ⧸ N) where + continuous_smul := by + rw [← (IsOpenQuotientMap.id.prodMap isOpenQuotientMap_mk).continuous_comp_iff] + exact continuous_mk.comp continuous_mul + +@[to_additive] +instance instContinuousConstSMul : ContinuousConstSMul G (G ⧸ N) := inferInstance + +/-- A quotient of a locally compact group is locally compact. -/ +@[to_additive] +instance instLocallyCompactSpace [LocallyCompactSpace G] (N : Subgroup G) : + LocallyCompactSpace (G ⧸ N) := + QuotientGroup.isOpenQuotientMap_mk.locallyCompactSpace + +@[to_additive (attr := deprecated (since := "2024-10-05"))] +theorem continuous_smul₁ (x : G ⧸ N) : Continuous fun g : G => g • x := + continuous_id.smul continuous_const + +variable (N) + +/-- Neighborhoods in the quotient are precisely the map of neighborhoods in the prequotient. -/ +@[to_additive + "Neighborhoods in the quotient are precisely the map of neighborhoods in the prequotient."] +theorem nhds_eq (x : G) : 𝓝 (x : G ⧸ N) = Filter.map (↑) (𝓝 x) := + (isOpenQuotientMap_mk.map_nhds_eq _).symm + +@[to_additive] +instance instFirstCountableTopology [FirstCountableTopology G] : + FirstCountableTopology (G ⧸ N) where + nhds_generated_countable := mk_surjective.forall.2 fun x ↦ nhds_eq N x ▸ inferInstance + +/-- The quotient of a second countable topological group by a subgroup is second countable. -/ +@[to_additive + "The quotient of a second countable additive topological group by a subgroup is second + countable."] +instance instSecondCountableTopology [SecondCountableTopology G] : + SecondCountableTopology (G ⧸ N) := + ContinuousConstSMul.secondCountableTopology + +@[to_additive (attr := deprecated (since := "2024-08-05"))] +theorem nhds_one_isCountablyGenerated [FirstCountableTopology G] [N.Normal] : + (𝓝 (1 : G ⧸ N)).IsCountablyGenerated := + inferInstance + +end ContinuousMul + +variable [TopologicalGroup G] (N : Subgroup G) + +@[to_additive] +instance instTopologicalGroup [N.Normal] : TopologicalGroup (G ⧸ N) where + continuous_mul := by + rw [← (isOpenQuotientMap_mk.prodMap isOpenQuotientMap_mk).continuous_comp_iff] + exact continuous_mk.comp continuous_mul + continuous_inv := continuous_inv.quotient_map' _ + +@[to_additive (attr := deprecated (since := "2024-08-05"))] +theorem _root_.topologicalGroup_quotient [N.Normal] : TopologicalGroup (G ⧸ N) := + instTopologicalGroup N + +@[to_additive] +theorem isClosedMap_coe {H : Subgroup G} (hH : IsCompact (H : Set G)) : + IsClosedMap ((↑) : G → G ⧸ H) := by + intro t ht + rw [← (quotientMap_mk H).isClosed_preimage, preimage_image_mk_eq_mul] + exact ht.mul_right_of_isCompact hH + +@[to_additive] +instance instT3Space [N.Normal] [hN : IsClosed (N : Set G)] : T3Space (G ⧸ N) := by + rw [← QuotientGroup.ker_mk' N] at hN + haveI := TopologicalGroup.t1Space (G ⧸ N) ((quotientMap_mk N).isClosed_preimage.mp hN) + infer_instance + +end QuotientGroup diff --git a/Mathlib/Topology/Algebra/Module/Basic.lean b/Mathlib/Topology/Algebra/Module/Basic.lean index c5fd7f2684f753..1ed9c07b215fed 100644 --- a/Mathlib/Topology/Algebra/Module/Basic.lean +++ b/Mathlib/Topology/Algebra/Module/Basic.lean @@ -2393,7 +2393,7 @@ instance continuousSMul_quotient [TopologicalSpace R] [TopologicalAddGroup M] [C instance t3_quotient_of_isClosed [TopologicalAddGroup M] [IsClosed (S : Set M)] : T3Space (M ⧸ S) := letI : IsClosed (S.toAddSubgroup : Set M) := ‹_› - S.toAddSubgroup.t3_quotient_of_isClosed + QuotientAddGroup.instT3Space S.toAddSubgroup end Submodule diff --git a/Mathlib/Topology/Algebra/OpenSubgroup.lean b/Mathlib/Topology/Algebra/OpenSubgroup.lean index 99c3a4c276f10f..843e91673869b0 100644 --- a/Mathlib/Topology/Algebra/OpenSubgroup.lean +++ b/Mathlib/Topology/Algebra/OpenSubgroup.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Johan Commelin, Nailin Guan -/ import Mathlib.RingTheory.Ideal.Basic +import Mathlib.Topology.Algebra.Group.Quotient import Mathlib.Topology.Algebra.Ring.Basic import Mathlib.Topology.Sets.Opens diff --git a/Mathlib/Topology/Algebra/ProperAction/Basic.lean b/Mathlib/Topology/Algebra/ProperAction/Basic.lean index 55f73de488d07f..fa7a99510f216a 100644 --- a/Mathlib/Topology/Algebra/ProperAction/Basic.lean +++ b/Mathlib/Topology/Algebra/ProperAction/Basic.lean @@ -5,6 +5,7 @@ Authors: Anatole Dedeker, Etienne Marion, Florestan Martin-Baillon, Vincent Guir -/ import Mathlib.Topology.Algebra.MulAction import Mathlib.Topology.Maps.Proper.Basic +import Mathlib.Topology.Maps.OpenQuotient /-! # Proper group action diff --git a/Mathlib/Topology/Algebra/Ring/Ideal.lean b/Mathlib/Topology/Algebra/Ring/Ideal.lean index aa3cf06eb57a12..c72e3ee7afefa6 100644 --- a/Mathlib/Topology/Algebra/Ring/Ideal.lean +++ b/Mathlib/Topology/Algebra/Ring/Ideal.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Patrick Massot -/ import Mathlib.Topology.Algebra.Ring.Basic +import Mathlib.Topology.Algebra.Group.Quotient import Mathlib.RingTheory.Ideal.Quotient /-! diff --git a/Mathlib/Topology/Algebra/UniformGroup.lean b/Mathlib/Topology/Algebra/UniformGroup.lean index c05bd7340d340a..1c3bc90dfda28e 100644 --- a/Mathlib/Topology/Algebra/UniformGroup.lean +++ b/Mathlib/Topology/Algebra/UniformGroup.lean @@ -7,7 +7,7 @@ import Mathlib.Topology.UniformSpace.UniformConvergence import Mathlib.Topology.UniformSpace.UniformEmbedding import Mathlib.Topology.UniformSpace.CompleteSeparated import Mathlib.Topology.UniformSpace.Compact -import Mathlib.Topology.Algebra.Group.Basic +import Mathlib.Topology.Algebra.Group.Quotient import Mathlib.Topology.DiscreteSubset import Mathlib.Tactic.Abel diff --git a/Mathlib/Topology/Compactness/LocallyCompact.lean b/Mathlib/Topology/Compactness/LocallyCompact.lean index e0c44089ecd15a..8d10e1ce3da2ef 100644 --- a/Mathlib/Topology/Compactness/LocallyCompact.lean +++ b/Mathlib/Topology/Compactness/LocallyCompact.lean @@ -45,6 +45,13 @@ protected theorem IsClosed.weaklyLocallyCompactSpace [WeaklyLocallyCompactSpace {s : Set X} (hs : IsClosed s) : WeaklyLocallyCompactSpace s := (closedEmbedding_subtype_val hs).weaklyLocallyCompactSpace +theorem IsOpenQuotientMap.weaklyLocallyCompactSpace [WeaklyLocallyCompactSpace X] + {f : X → Y} (hf : IsOpenQuotientMap f) : WeaklyLocallyCompactSpace Y where + exists_compact_mem_nhds := by + refine hf.surjective.forall.2 fun x ↦ ?_ + rcases exists_compact_mem_nhds x with ⟨K, hKc, hKx⟩ + exact ⟨f '' K, hKc.image hf.continuous, hf.isOpenMap.image_mem_nhds hKx⟩ + /-- In a weakly locally compact space, every compact set is contained in the interior of a compact set. -/ theorem exists_compact_superset [WeaklyLocallyCompactSpace X] {K : Set X} (hK : IsCompact K) : @@ -166,6 +173,13 @@ theorem exists_compact_between [LocallyCompactSpace X] {K U : Set X} (hK : IsCom let ⟨L, hKL, hL, hLU⟩ := exists_mem_nhdsSet_isCompact_mapsTo continuous_id hK hU h_KU ⟨L, hL, subset_interior_iff_mem_nhdsSet.2 hKL, hLU⟩ +theorem IsOpenQuotientMap.locallyCompactSpace [LocallyCompactSpace X] {f : X → Y} + (hf : IsOpenQuotientMap f) : LocallyCompactSpace Y where + local_compact_nhds := by + refine hf.surjective.forall.2 fun x U hU ↦ ?_ + rcases local_compact_nhds (hf.continuous.continuousAt hU) with ⟨K, hKx, hKU, hKc⟩ + exact ⟨f '' K, hf.isOpenMap.image_mem_nhds hKx, image_subset_iff.2 hKU, hKc.image hf.continuous⟩ + /-- If `f` is a topology inducing map with a locally compact codomain and a locally closed range, then the domain of `f` is a locally compact space. -/ theorem Inducing.locallyCompactSpace [LocallyCompactSpace Y] {f : X → Y} (hf : Inducing f) From 03d86393034e2ce5511542b7a2caa3315bbbd74d Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 14:28:22 +1100 Subject: [PATCH 254/425] shake --- Mathlib/Deprecated/Aliases.lean | 1 - Mathlib/Lean/Expr/Basic.lean | 1 - Mathlib/Tactic/GeneralizeProofs.lean | 1 + Mathlib/Tactic/Says.lean | 1 - Mathlib/Tactic/Simps/Basic.lean | 1 - 5 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Mathlib/Deprecated/Aliases.lean b/Mathlib/Deprecated/Aliases.lean index 5e63adabb80058..6266e7c3f17d2a 100644 --- a/Mathlib/Deprecated/Aliases.lean +++ b/Mathlib/Deprecated/Aliases.lean @@ -5,7 +5,6 @@ Authors: Kim Morrison -/ import Mathlib.Init import Batteries.Tactic.Alias -import Batteries.Data.String.Basic /-! Deprecated aliases can be dumped here if they are no longer used in Mathlib, diff --git a/Mathlib/Lean/Expr/Basic.lean b/Mathlib/Lean/Expr/Basic.lean index 02701a1fb4c6db..57caa17facbf9a 100644 --- a/Mathlib/Lean/Expr/Basic.lean +++ b/Mathlib/Lean/Expr/Basic.lean @@ -6,7 +6,6 @@ Floris van Doorn, Edward Ayers, Arthur Paulino -/ import Mathlib.Init import Lean.Meta.Tactic.Rewrite -import Batteries.Lean.Expr import Batteries.Tactic.Alias import Lean.Elab.Binders diff --git a/Mathlib/Tactic/GeneralizeProofs.lean b/Mathlib/Tactic/GeneralizeProofs.lean index 645637ae46a0f3..72f6d093d52336 100644 --- a/Mathlib/Tactic/GeneralizeProofs.lean +++ b/Mathlib/Tactic/GeneralizeProofs.lean @@ -6,6 +6,7 @@ Authors: Alex J. Best, Kyle Miller import Lean.Elab.Tactic.Config import Lean.Elab.Tactic.Location import Mathlib.Lean.Expr.Basic +import Batteries.Lean.Expr /-! # The `generalize_proofs` tactic diff --git a/Mathlib/Tactic/Says.lean b/Mathlib/Tactic/Says.lean index 29bd33ed183cf1..ef529b606b0b6f 100644 --- a/Mathlib/Tactic/Says.lean +++ b/Mathlib/Tactic/Says.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Kim Morrison -/ import Mathlib.Init -import Batteries.Data.String.Basic import Lean.Meta.Tactic.TryThis import Batteries.Linter.UnreachableTactic import Qq.Match diff --git a/Mathlib/Tactic/Simps/Basic.lean b/Mathlib/Tactic/Simps/Basic.lean index 1caba0e4825aba..c8e9901c99ec77 100644 --- a/Mathlib/Tactic/Simps/Basic.lean +++ b/Mathlib/Tactic/Simps/Basic.lean @@ -6,7 +6,6 @@ Authors: Floris van Doorn import Lean.Elab.Tactic.Simp import Lean.Elab.App import Mathlib.Tactic.Simps.NotationClass -import Batteries.Data.String.Basic import Mathlib.Lean.Expr.Basic /-! From f62d5ef15596719fc825341206087c50936330f4 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 14:31:03 +1100 Subject: [PATCH 255/425] fix --- Mathlib/Tactic/Says.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/Tactic/Says.lean b/Mathlib/Tactic/Says.lean index ef529b606b0b6f..e2d5e9007ad3f9 100644 --- a/Mathlib/Tactic/Says.lean +++ b/Mathlib/Tactic/Says.lean @@ -6,6 +6,7 @@ Authors: Kim Morrison import Mathlib.Init import Lean.Meta.Tactic.TryThis import Batteries.Linter.UnreachableTactic +import Batteries.Data.String.Basic import Qq.Match /-! From 0fd677f123901f4fc95df3551224fcb7686678c5 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 14:34:36 +1100 Subject: [PATCH 256/425] fix --- Mathlib/Tactic/Simps/Basic.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/Tactic/Simps/Basic.lean b/Mathlib/Tactic/Simps/Basic.lean index c8e9901c99ec77..75ebfae3d5a00e 100644 --- a/Mathlib/Tactic/Simps/Basic.lean +++ b/Mathlib/Tactic/Simps/Basic.lean @@ -5,6 +5,7 @@ Authors: Floris van Doorn -/ import Lean.Elab.Tactic.Simp import Lean.Elab.App +import Batteries.Data.String.Basic import Mathlib.Tactic.Simps.NotationClass import Mathlib.Lean.Expr.Basic From b1267a6b11cd3e2d499cd090a22e38adfed751e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Thu, 17 Oct 2024 03:45:31 +0000 Subject: [PATCH 257/425] feat: sigma-algebra of cylinder events (#17833) From GibbsMeasure Co-authored-by: Kin Yau James Wong --- .../Constructions/Cylinders.lean | 81 ++++++++++++++++++- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/Mathlib/MeasureTheory/Constructions/Cylinders.lean b/Mathlib/MeasureTheory/Constructions/Cylinders.lean index 3ef19d096a73e0..1f30b5fc6437d6 100644 --- a/Mathlib/MeasureTheory/Constructions/Cylinders.lean +++ b/Mathlib/MeasureTheory/Constructions/Cylinders.lean @@ -1,7 +1,7 @@ /- Copyright (c) 2023 Rémy Degenne. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Rémy Degenne, Peter Pfaffelhuber +Authors: Rémy Degenne, Peter Pfaffelhuber, Yaël Dillies, Kin Yau James Wong -/ import Mathlib.MeasureTheory.PiSystem import Mathlib.Order.OmegaCompletePartialOrder @@ -29,6 +29,8 @@ a product set. all `i` in the finset defining the box, the projection to `α i` belongs to `C i`. The main application of this is with `C i = {s : Set (α i) | MeasurableSet s}`. * `measurableCylinders`: set of all cylinders with measurable base sets. +* `cylinderEvents Δ`: The σ-algebra of cylinder events on `Δ`. It is the smallest σ-algebra making + the projections on the `i`-th coordinate continuous for all `i ∈ Δ`. ## Main statements @@ -39,7 +41,7 @@ a product set. -/ -open Set +open Function Set namespace MeasureTheory @@ -361,4 +363,79 @@ theorem generateFrom_measurableCylinders : end cylinders +/-! ### Cylinder events as a sigma-algebra -/ + +section cylinderEvents + +variable {α ι : Type*} {π : ι → Type*} {mα : MeasurableSpace α} [m : ∀ i, MeasurableSpace (π i)] + {Δ Δ₁ Δ₂ : Set ι} {i : ι} + +/-- The σ-algebra of cylinder events on `Δ`. It is the smallest σ-algebra making the projections +on the `i`-th coordinate continuous for all `i ∈ Δ`. -/ +def cylinderEvents (Δ : Set ι) : MeasurableSpace (∀ i, π i) := ⨆ i ∈ Δ, (m i).comap fun σ ↦ σ i + +@[simp] lemma cylinderEvents_univ : cylinderEvents (π := π) univ = MeasurableSpace.pi := by + simp [cylinderEvents, MeasurableSpace.pi] + +@[gcongr] +lemma cylinderEvents_mono (h : Δ₁ ⊆ Δ₂) : cylinderEvents (π := π) Δ₁ ≤ cylinderEvents Δ₂ := + biSup_mono h + +lemma cylinderEvents_le_pi : cylinderEvents (π := π) Δ ≤ MeasurableSpace.pi := by + simpa using cylinderEvents_mono (subset_univ _) + +lemma measurable_cylinderEvents_iff {g : α → ∀ i, π i} : + @Measurable _ _ _ (cylinderEvents Δ) g ↔ ∀ ⦃i⦄, i ∈ Δ → Measurable fun a ↦ g a i := by + simp_rw [measurable_iff_comap_le, cylinderEvents, MeasurableSpace.comap_iSup, + MeasurableSpace.comap_comp, Function.comp_def, iSup_le_iff] + +@[fun_prop, aesop safe 100 apply (rule_sets := [Measurable])] +lemma measurable_cylinderEvent_apply (hi : i ∈ Δ) : + Measurable[cylinderEvents Δ] fun f : ∀ i, π i => f i := + measurable_cylinderEvents_iff.1 measurable_id hi + +@[aesop safe 100 apply (rule_sets := [Measurable])] +lemma Measurable.eval_cylinderEvents {g : α → ∀ i, π i} (hi : i ∈ Δ) + (hg : @Measurable _ _ _ (cylinderEvents Δ) g) : Measurable fun a ↦ g a i := + (measurable_cylinderEvent_apply hi).comp hg + +@[fun_prop, aesop safe 100 apply (rule_sets := [Measurable])] +lemma measurable_cylinderEvents_lambda (f : α → ∀ i, π i) (hf : ∀ i, Measurable fun a ↦ f a i) : + Measurable f := + measurable_pi_iff.mpr hf + +/-- The function `(f, x) ↦ update f a x : (Π a, π a) × π a → Π a, π a` is measurable. -/ +lemma measurable_update_cylinderEvents' [DecidableEq ι] : + @Measurable _ _ (.prod (cylinderEvents Δ) (m i)) (cylinderEvents Δ) + (fun p : (∀ i, π i) × π i ↦ update p.1 i p.2) := by + rw [measurable_cylinderEvents_iff] + intro j hj + dsimp [update] + split_ifs with h + · subst h + dsimp + exact measurable_snd + · exact measurable_cylinderEvents_iff.1 measurable_fst hj + +lemma measurable_uniqueElim_cylinderEvents [Unique ι] : + Measurable (uniqueElim : π (default : ι) → ∀ i, π i) := by + simp_rw [measurable_pi_iff, Unique.forall_iff, uniqueElim_default]; exact measurable_id + +/-- The function `update f a : π a → Π a, π a` is always measurable. +This doesn't require `f` to be measurable. +This should not be confused with the statement that `update f a x` is measurable. -/ +@[measurability] +lemma measurable_update_cylinderEvents (f : ∀ a : ι, π a) {a : ι} [DecidableEq ι] : + @Measurable _ _ _ (cylinderEvents Δ) (update f a) := + measurable_update_cylinderEvents'.comp measurable_prod_mk_left + +lemma measurable_update_cylinderEvents_left {a : ι} [DecidableEq ι] {x : π a} : + @Measurable _ _ (cylinderEvents Δ) (cylinderEvents Δ) (update · a x) := + measurable_update_cylinderEvents'.comp measurable_prod_mk_right + +lemma measurable_restrict_cylinderEvents (Δ : Set ι) : + Measurable[cylinderEvents (π := π) Δ] (restrict Δ) := by + rw [@measurable_pi_iff]; exact fun i ↦ measurable_cylinderEvent_apply i.2 + +end cylinderEvents end MeasureTheory From 08804ac5cc5dca54e6979de8388f59c937b60e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Thu, 17 Oct 2024 03:53:08 +0000 Subject: [PATCH 258/425] =?UTF-8?q?chore(SetTheory/Ordinal/Arithmetic):=20?= =?UTF-8?q?`omega0=5FisLimit`=20=E2=86=92=20`isLimit=5Fomega0`=20(#17744)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I missed this rename in #17673. --- Mathlib/SetTheory/Cardinal/Aleph.lean | 6 +++--- Mathlib/SetTheory/Cardinal/Arithmetic.lean | 2 +- Mathlib/SetTheory/Cardinal/Cofinality.lean | 12 ++++++------ Mathlib/SetTheory/Ordinal/Arithmetic.lean | 20 +++++++++++++------- Mathlib/SetTheory/Ordinal/Notation.lean | 14 +++++++------- Mathlib/SetTheory/Ordinal/Principal.lean | 10 +++++----- 6 files changed, 35 insertions(+), 29 deletions(-) diff --git a/Mathlib/SetTheory/Cardinal/Aleph.lean b/Mathlib/SetTheory/Cardinal/Aleph.lean index 7a654d0363135c..090dd44cb90c6b 100644 --- a/Mathlib/SetTheory/Cardinal/Aleph.lean +++ b/Mathlib/SetTheory/Cardinal/Aleph.lean @@ -249,7 +249,7 @@ theorem aleph'_limit {o : Ordinal} (ho : o.IsLimit) : aleph' o = ⨆ a : Iio o, @[simp] theorem aleph'_omega0 : aleph' ω = ℵ₀ := eq_of_forall_ge_iff fun c => by - simp only [aleph'_le_of_limit omega0_isLimit, lt_omega0, exists_imp, aleph0_le] + simp only [aleph'_le_of_limit isLimit_omega0, lt_omega0, exists_imp, aleph0_le] exact forall_swap.trans (forall_congr' fun n => by simp only [forall_eq, aleph'_nat]) @[deprecated (since := "2024-09-30")] @@ -333,12 +333,12 @@ instance nonempty_toType_aleph (o : Ordinal) : Nonempty (ℵ_ o).ord.toType := b exact fun h => (ord_injective h).not_gt (aleph_pos o) theorem ord_aleph_isLimit (o : Ordinal) : (ℵ_ o).ord.IsLimit := - ord_isLimit <| aleph0_le_aleph _ + isLimit_ord <| aleph0_le_aleph _ instance (o : Ordinal) : NoMaxOrder (ℵ_ o).ord.toType := toType_noMax_of_succ_lt (ord_aleph_isLimit o).2 -theorem exists_aleph {c : Cardinal} : ℵ₀ ≤ c ↔ ∃ o, c = aleph o := +theorem exists_aleph {c : Cardinal} : ℵ₀ ≤ c ↔ ∃ o, c = ℵ_ o := ⟨fun h => ⟨aleph'.symm c - ω, by rw [aleph_eq_aleph', Ordinal.add_sub_cancel_of_le, aleph'.apply_symm_apply] diff --git a/Mathlib/SetTheory/Cardinal/Arithmetic.lean b/Mathlib/SetTheory/Cardinal/Arithmetic.lean index 4bb8721a053d7a..4dfd399fb40da9 100644 --- a/Mathlib/SetTheory/Cardinal/Arithmetic.lean +++ b/Mathlib/SetTheory/Cardinal/Arithmetic.lean @@ -82,7 +82,7 @@ theorem mul_eq_self {c : Cardinal} (h : ℵ₀ ≤ c) : c * c = c := by · exact (mul_lt_aleph0 qo qo).trans_le ol · suffices (succ (typein LT.lt (g p))).card < ⟦α⟧ from (IH _ this qo).trans_lt this rw [← lt_ord] - apply (ord_isLimit ol).2 + apply (isLimit_ord ol).2 rw [mk'_def, e] apply typein_lt_type diff --git a/Mathlib/SetTheory/Cardinal/Cofinality.lean b/Mathlib/SetTheory/Cardinal/Cofinality.lean index 5f1d484af9be79..cbf48de84b8779 100644 --- a/Mathlib/SetTheory/Cardinal/Cofinality.lean +++ b/Mathlib/SetTheory/Cardinal/Cofinality.lean @@ -681,7 +681,7 @@ theorem aleph_cof {o : Ordinal} (ho : o.IsLimit) : (aleph o).ord.cof = o.cof := @[simp] theorem cof_omega0 : cof ω = ℵ₀ := - (aleph0_le_cof.2 omega0_isLimit).antisymm' <| by + (aleph0_le_cof.2 isLimit_omega0).antisymm' <| by rw [← card_omega0] apply cof_le_card @@ -862,7 +862,7 @@ theorem mk_bounded_subset {α : Type*} (h : ∀ x < #α, (2^x) < #α) {r : α · refine @mk_le_of_injective α _ (fun x => Subtype.mk {x} ?_) ?_ · apply bounded_singleton rw [← hr] - apply ord_isLimit ha + apply isLimit_ord ha · intro a b hab simpa [singleton_eq_singleton_iff] using hab @@ -881,7 +881,7 @@ theorem mk_subset_mk_lt_cof {α : Type*} (h : ∀ x < #α, (2^x) < #α) : exact lt_cof_type hs · refine @mk_le_of_injective α _ (fun x => Subtype.mk {x} ?_) ?_ · rw [mk_singleton] - exact one_lt_aleph0.trans_le (aleph0_le_cof.2 (ord_isLimit h'.aleph0_le)) + exact one_lt_aleph0.trans_le (aleph0_le_cof.2 (isLimit_ord h'.aleph0_le)) · intro a b hab simpa [singleton_eq_singleton_iff] using hab @@ -917,7 +917,7 @@ theorem isRegular_succ {c : Cardinal.{u}} (h : ℵ₀ ≤ c) : IsRegular (succ c (by cases' Quotient.exists_rep (@succ Cardinal _ _ c) with α αe; simp only [mk'_def] at αe rcases ord_eq α with ⟨r, wo, re⟩ - have := ord_isLimit (h.trans (le_succ _)) + have := isLimit_ord (h.trans (le_succ _)) rw [← αe, re] at this ⊢ rcases cof_eq' r this with ⟨S, H, Se⟩ rw [← Se] @@ -1123,7 +1123,7 @@ theorem derivFamily_lt_ord_lift {ι} {f : ι → Ordinal → Ordinal} {c} (hc : rw [derivFamily_succ] exact nfpFamily_lt_ord_lift hω (by rwa [hc.cof_eq]) hf - ((ord_isLimit hc.1).2 _ (hb ((lt_succ b).trans hb'))) + ((isLimit_ord hc.1).2 _ (hb ((lt_succ b).trans hb'))) | H₃ b hb H => intro hb' rw [derivFamily_limit f hb] @@ -1170,7 +1170,7 @@ theorem univ_inaccessible : IsInaccessible univ.{u, v} := theorem lt_power_cof {c : Cardinal.{u}} : ℵ₀ ≤ c → c < (c^cof c.ord) := Quotient.inductionOn c fun α h => by rcases ord_eq α with ⟨r, wo, re⟩ - have := ord_isLimit h + have := isLimit_ord h rw [mk'_def, re] at this ⊢ rcases cof_eq' r this with ⟨S, H, Se⟩ have := sum_lt_prod (fun a : S => #{ x // r x a }) (fun _ => #α) fun i => ?_ diff --git a/Mathlib/SetTheory/Ordinal/Arithmetic.lean b/Mathlib/SetTheory/Ordinal/Arithmetic.lean index d8239b6b16acc5..90d58666720d45 100644 --- a/Mathlib/SetTheory/Ordinal/Arithmetic.lean +++ b/Mathlib/SetTheory/Ordinal/Arithmetic.lean @@ -2263,13 +2263,16 @@ theorem one_lt_omega0 : 1 < ω := by simpa only [Nat.cast_one] using nat_lt_omeg @[deprecated (since := "2024-09-30")] alias one_lt_omega := one_lt_omega0 -theorem omega0_isLimit : IsLimit ω := +theorem isLimit_omega0 : IsLimit ω := ⟨omega0_ne_zero, fun o h => by let ⟨n, e⟩ := lt_omega0.1 h rw [e]; exact nat_lt_omega0 (n + 1)⟩ +@[deprecated (since := "2024-10-14")] +alias omega0_isLimit := isLimit_omega0 + @[deprecated (since := "2024-09-30")] -alias omega_isLimit := omega0_isLimit +alias omega_isLimit := isLimit_omega0 theorem omega0_le {o : Ordinal} : ω ≤ o ↔ ∀ n : ℕ, ↑n ≤ o := ⟨fun h n => (nat_lt_omega0 _).le.trans h, fun H => @@ -2306,14 +2309,14 @@ theorem isLimit_iff_omega0_dvd {a : Ordinal} : IsLimit a ↔ a ≠ 0 ∧ ω ∣ refine ⟨fun l => ⟨l.1, ⟨a / ω, le_antisymm ?_ (mul_div_le _ _)⟩⟩, fun h => ?_⟩ · refine (limit_le l).2 fun x hx => le_of_lt ?_ rw [← div_lt omega0_ne_zero, ← succ_le_iff, le_div omega0_ne_zero, mul_succ, - add_le_of_limit omega0_isLimit] + add_le_of_limit isLimit_omega0] intro b hb rcases lt_omega0.1 hb with ⟨n, rfl⟩ exact (add_le_add_right (mul_div_le _ _) _).trans (lt_sub.1 <| nat_lt_limit (isLimit_sub l hx) _).le · rcases h with ⟨a0, b, rfl⟩ - refine isLimit_mul_left omega0_isLimit (Ordinal.pos_iff_ne_zero.2 <| mt ?_ a0) + refine isLimit_mul_left isLimit_omega0 (Ordinal.pos_iff_ne_zero.2 <| mt ?_ a0) intro e simp only [e, mul_zero] @@ -2394,7 +2397,7 @@ namespace Cardinal open Ordinal -theorem ord_isLimit {c} (co : ℵ₀ ≤ c) : (ord c).IsLimit := by +theorem isLimit_ord {c} (co : ℵ₀ ≤ c) : (ord c).IsLimit := by refine ⟨fun h => aleph0_ne_zero ?_, fun a => lt_imp_lt_of_le_imp_le fun h => ?_⟩ · rw [← Ordinal.le_zero, ord_le] at h simpa only [card_zero, nonpos_iff_eq_zero] using co.trans h @@ -2403,10 +2406,13 @@ theorem ord_isLimit {c} (co : ℵ₀ ≤ c) : (ord c).IsLimit := by rw [← ord_le, ← le_succ_of_isLimit, ord_le] · exact co.trans h · rw [ord_aleph0] - exact Ordinal.omega0_isLimit + exact Ordinal.isLimit_omega0 + +@[deprecated (since := "2024-10-14")] +alias ord_isLimit := isLimit_ord theorem noMaxOrder {c} (h : ℵ₀ ≤ c) : NoMaxOrder c.ord.toType := - toType_noMax_of_succ_lt (ord_isLimit h).2 + toType_noMax_of_succ_lt (isLimit_ord h).2 end Cardinal diff --git a/Mathlib/SetTheory/Ordinal/Notation.lean b/Mathlib/SetTheory/Ordinal/Notation.lean index 9df8635093a8b6..050c6b4f8f6534 100644 --- a/Mathlib/SetTheory/Ordinal/Notation.lean +++ b/Mathlib/SetTheory/Ordinal/Notation.lean @@ -577,7 +577,7 @@ theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = rep rw [← mul_assoc] congr 2 have := mt repr_inj.1 e0 - rw [add_mul_limit ao (isLimit_opow_left omega0_isLimit this), mul_assoc, + rw [add_mul_limit ao (isLimit_opow_left isLimit_omega0 this), mul_assoc, mul_omega0_dvd (natCast_pos.2 n₁.pos) (nat_lt_omega0 _)] simpa using opow_dvd_opow ω (one_le_iff_ne_zero.2 this) @@ -790,7 +790,7 @@ theorem repr_opow_aux₁ {e a} [Ne : NF e] [Na : NF a] {a' : Ordinal} (e0 : repr have := omega0_le_oadd e n a rw [repr] at this refine le_antisymm ?_ (opow_le_opow_left _ this) - apply (opow_le_of_limit ((opow_pos _ omega0_pos).trans_le this).ne' omega0_isLimit).2 + apply (opow_le_of_limit ((opow_pos _ omega0_pos).trans_le this).ne' isLimit_omega0).2 intro b l have := (No.below_of_lt (lt_succ _)).repr_lt rw [repr] at this @@ -801,8 +801,8 @@ theorem repr_opow_aux₁ {e a} [Ne : NF e] [Na : NF a] {a' : Ordinal} (e0 : repr · apply (mul_le_mul_left' (le_succ b) _).trans rw [← add_one_eq_succ, add_mul_succ _ (one_add_of_omega0_le h), add_one_eq_succ, succ_le_iff, Ordinal.mul_lt_mul_iff_left (Ordinal.pos_iff_ne_zero.2 e0)] - exact omega0_isLimit.2 _ l - · apply (principal_mul_omega0 (omega0_isLimit.2 _ h) l).le.trans + exact isLimit_omega0.2 _ l + · apply (principal_mul_omega0 (isLimit_omega0.2 _ h) l).le.trans simpa using mul_le_mul_right' (one_le_iff_ne_zero.2 e0) ω section @@ -966,7 +966,7 @@ private theorem exists_lt_add {α} [hα : Nonempty α] {o : Ordinal} {f : α → private theorem exists_lt_mul_omega0' {o : Ordinal} ⦃a⦄ (h : a < o * ω) : ∃ i : ℕ, a < o * ↑i + o := by - obtain ⟨i, hi, h'⟩ := (lt_mul_of_limit omega0_isLimit).1 h + obtain ⟨i, hi, h'⟩ := (lt_mul_of_limit isLimit_omega0).1 h obtain ⟨i, rfl⟩ := lt_omega0.1 hi exact ⟨i, h'.trans_le (le_add_right _ _)⟩ @@ -1025,13 +1025,13 @@ theorem fundamentalSequence_has_prop (o) : FundamentalSequenceProp o (fundamenta · exact ⟨rfl, inferInstance⟩ · have := opow_pos (repr a') omega0_pos refine - ⟨isLimit_mul this omega0_isLimit, fun i => + ⟨isLimit_mul this isLimit_omega0, fun i => ⟨this, ?_, fun H => @NF.oadd_zero _ _ (iha.2 H.fst)⟩, exists_lt_mul_omega0'⟩ rw [← mul_succ, ← natCast_succ, Ordinal.mul_lt_mul_iff_left this] apply nat_lt_omega0 · have := opow_pos (repr a') omega0_pos refine - ⟨isLimit_add _ (isLimit_mul this omega0_isLimit), fun i => ⟨this, ?_, ?_⟩, + ⟨isLimit_add _ (isLimit_mul this isLimit_omega0), fun i => ⟨this, ?_, ?_⟩, exists_lt_add exists_lt_mul_omega0'⟩ · rw [← mul_succ, ← natCast_succ, Ordinal.mul_lt_mul_iff_left this] apply nat_lt_omega0 diff --git a/Mathlib/SetTheory/Ordinal/Principal.lean b/Mathlib/SetTheory/Ordinal/Principal.lean index d58c0eff2dd351..5e32abd578e7de 100644 --- a/Mathlib/SetTheory/Ordinal/Principal.lean +++ b/Mathlib/SetTheory/Ordinal/Principal.lean @@ -194,7 +194,7 @@ theorem add_omega0_opow {a b : Ordinal} (h : a < ω ^ b) : a + ω ^ b = ω ^ b : · rw [opow_zero, ← succ_zero, lt_succ_iff, Ordinal.le_zero] at h rw [h, zero_add] · rw [opow_succ] at h - rcases (lt_mul_of_limit omega0_isLimit).1 h with ⟨x, xo, ax⟩ + rcases (lt_mul_of_limit isLimit_omega0).1 h with ⟨x, xo, ax⟩ apply (add_le_add_right ax.le _).trans rw [opow_succ, ← mul_add, add_omega0 xo] · rcases (lt_opow_of_limit omega0_ne_zero l).1 h with ⟨x, xb, ax⟩ @@ -228,7 +228,7 @@ theorem principal_add_iff_zero_or_omega0_opow {o : Ordinal} : fun ⟨b, e⟩ => e.symm ▸ fun a => add_omega0_opow⟩ have := H _ h have := lt_opow_succ_log_self one_lt_omega0 o - rw [opow_succ, lt_mul_of_limit omega0_isLimit] at this + rw [opow_succ, lt_mul_of_limit isLimit_omega0] at this rcases this with ⟨a, ao, h'⟩ rcases lt_omega0.1 ao with ⟨n, rfl⟩ clear ao @@ -347,7 +347,7 @@ theorem mul_lt_omega0_opow {a b c : Ordinal} (c0 : 0 < c) (ha : a < ω ^ c) (hb · exact (lt_irrefl _).elim c0 · rw [opow_succ] at ha obtain ⟨n, hn, an⟩ := - ((isNormal_mul_right <| opow_pos _ omega0_pos).limit_lt omega0_isLimit).1 ha + ((isNormal_mul_right <| opow_pos _ omega0_pos).limit_lt isLimit_omega0).1 ha apply (mul_le_mul_right' (le_of_lt an) _).trans_lt rw [opow_succ, mul_assoc, mul_lt_mul_iff_left (opow_pos _ omega0_pos)] exact principal_mul_omega0 hn hb @@ -366,7 +366,7 @@ theorem mul_omega0_opow_opow {a b : Ordinal} (a0 : 0 < a) (h : a < ω ^ ω ^ b) exact mul_omega0 a0 h · apply le_antisymm · obtain ⟨x, xb, ax⟩ := - (lt_opow_of_limit omega0_ne_zero (isLimit_opow_left omega0_isLimit b0)).1 h + (lt_opow_of_limit omega0_ne_zero (isLimit_opow_left isLimit_omega0 b0)).1 h apply (mul_le_mul_right' (le_of_lt ax) _).trans rw [← opow_add, add_omega0_opow xb] · conv_lhs => rw [← one_mul (ω ^ _)] @@ -442,7 +442,7 @@ theorem principal_opow_omega0 : Principal (· ^ ·) ω := fun a b ha hb => alias principal_opow_omega := principal_opow_omega0 theorem opow_omega0 {a : Ordinal} (a1 : 1 < a) (h : a < ω) : a ^ ω = ω := - ((opow_le_of_limit (one_le_iff_ne_zero.1 <| le_of_lt a1) omega0_isLimit).2 fun _ hb => + ((opow_le_of_limit (one_le_iff_ne_zero.1 <| le_of_lt a1) isLimit_omega0).2 fun _ hb => (principal_opow_omega0 h hb).le).antisymm (right_le_opow _ a1) From 8e52ebf89bc31f366f732f12e4ed932eeecf442e Mon Sep 17 00:00:00 2001 From: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com> Date: Thu, 17 Oct 2024 04:14:09 +0000 Subject: [PATCH 259/425] chore: move differentiability of Gamma to a new file (#17775) --- Mathlib.lean | 1 + Mathlib/Analysis/MellinInversion.lean | 1 + .../SpecialFunctions/Gamma/Basic.lean | 85 +------------ .../SpecialFunctions/Gamma/BohrMollerup.lean | 1 + .../SpecialFunctions/Gamma/Deriv.lean | 117 ++++++++++++++++++ 5 files changed, 122 insertions(+), 83 deletions(-) create mode 100644 Mathlib/Analysis/SpecialFunctions/Gamma/Deriv.lean diff --git a/Mathlib.lean b/Mathlib.lean index 1ecdac31212ba1..14f4a5f1fa41b0 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1347,6 +1347,7 @@ import Mathlib.Analysis.SpecialFunctions.Gamma.Basic import Mathlib.Analysis.SpecialFunctions.Gamma.Beta import Mathlib.Analysis.SpecialFunctions.Gamma.BohrMollerup import Mathlib.Analysis.SpecialFunctions.Gamma.Deligne +import Mathlib.Analysis.SpecialFunctions.Gamma.Deriv import Mathlib.Analysis.SpecialFunctions.Gaussian.FourierTransform import Mathlib.Analysis.SpecialFunctions.Gaussian.GaussianIntegral import Mathlib.Analysis.SpecialFunctions.Gaussian.PoissonSummation diff --git a/Mathlib/Analysis/MellinInversion.lean b/Mathlib/Analysis/MellinInversion.lean index c9680254f0421c..758a80e2575a86 100644 --- a/Mathlib/Analysis/MellinInversion.lean +++ b/Mathlib/Analysis/MellinInversion.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Lawrence Wu -/ import Mathlib.Analysis.Fourier.Inversion +import Mathlib.Analysis.MellinTransform /-! # Mellin inversion formula diff --git a/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean b/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean index 685bc7386b0d04..8a5e577497057d 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gamma/Basic.lean @@ -3,8 +3,8 @@ Copyright (c) 2022 David Loeffler. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: David Loeffler -/ +import Mathlib.Analysis.SpecialFunctions.ImproperIntegrals import Mathlib.MeasureTheory.Integral.ExpDecay -import Mathlib.Analysis.MellinTransform /-! # The Gamma function @@ -24,15 +24,12 @@ set it to be `0` by convention.) * `Complex.Gamma_eq_integral`: for `0 < re s`, `Γ(s)` agrees with Euler's integral. * `Complex.Gamma_add_one`: for all `s : ℂ` with `s ≠ 0`, we have `Γ (s + 1) = s Γ(s)`. * `Complex.Gamma_nat_eq_factorial`: for all `n : ℕ` we have `Γ (n + 1) = n!`. -* `Complex.differentiableAt_Gamma`: `Γ` is complex-differentiable at all `s : ℂ` with - `s ∉ {-n : n ∈ ℕ}`. ## Gamma function: main statements (real case) * `Real.Gamma`: the `Γ` function (of a real variable). * Real counterparts of all the properties of the complex Gamma function listed above: - `Real.Gamma_eq_integral`, `Real.Gamma_add_one`, `Real.Gamma_nat_eq_factorial`, - `Real.differentiableAt_Gamma`. + `Real.Gamma_eq_integral`, `Real.Gamma_add_one`, `Real.Gamma_nat_eq_factorial`. ## Tags @@ -395,79 +392,6 @@ lemma integral_cpow_mul_exp_neg_mul_Ioi {a : ℂ} {r : ℝ} (ha : 0 < a.re) (hr end GammaDef -/-! Now check that the `Γ` function is differentiable, wherever this makes sense. -/ - - -section GammaHasDeriv - -/-- Rewrite the Gamma integral as an example of a Mellin transform. -/ -theorem GammaIntegral_eq_mellin : GammaIntegral = mellin fun x => ↑(Real.exp (-x)) := - funext fun s => by simp only [mellin, GammaIntegral, smul_eq_mul, mul_comm] - -/-- The derivative of the `Γ` integral, at any `s ∈ ℂ` with `1 < re s`, is given by the Mellin -transform of `log t * exp (-t)`. -/ -theorem hasDerivAt_GammaIntegral {s : ℂ} (hs : 0 < s.re) : - HasDerivAt GammaIntegral (∫ t : ℝ in Ioi 0, t ^ (s - 1) * (Real.log t * Real.exp (-t))) s := by - rw [GammaIntegral_eq_mellin] - convert (mellin_hasDerivAt_of_isBigO_rpow (E := ℂ) _ _ (lt_add_one _) _ hs).2 - · refine (Continuous.continuousOn ?_).locallyIntegrableOn measurableSet_Ioi - exact continuous_ofReal.comp (Real.continuous_exp.comp continuous_neg) - · rw [← isBigO_norm_left] - simp_rw [Complex.norm_eq_abs, abs_ofReal, ← Real.norm_eq_abs, isBigO_norm_left] - simpa only [neg_one_mul] using (isLittleO_exp_neg_mul_rpow_atTop zero_lt_one _).isBigO - · simp_rw [neg_zero, rpow_zero] - refine isBigO_const_of_tendsto (?_ : Tendsto _ _ (𝓝 (1 : ℂ))) one_ne_zero - rw [(by simp : (1 : ℂ) = Real.exp (-0))] - exact (continuous_ofReal.comp (Real.continuous_exp.comp continuous_neg)).continuousWithinAt - -theorem differentiableAt_GammaAux (s : ℂ) (n : ℕ) (h1 : 1 - s.re < n) (h2 : ∀ m : ℕ, s ≠ -m) : - DifferentiableAt ℂ (GammaAux n) s := by - induction' n with n hn generalizing s - · refine (hasDerivAt_GammaIntegral ?_).differentiableAt - rw [Nat.cast_zero] at h1; linarith - · dsimp only [GammaAux] - specialize hn (s + 1) - have a : 1 - (s + 1).re < ↑n := by - rw [Nat.cast_succ] at h1; rw [Complex.add_re, Complex.one_re]; linarith - have b : ∀ m : ℕ, s + 1 ≠ -m := by - intro m; have := h2 (1 + m) - contrapose! this - rw [← eq_sub_iff_add_eq] at this - simpa using this - refine DifferentiableAt.div (DifferentiableAt.comp _ (hn a b) ?_) ?_ ?_ - · rw [differentiableAt_add_const_iff (1 : ℂ)]; exact differentiableAt_id - · exact differentiableAt_id - · simpa using h2 0 - -theorem differentiableAt_Gamma (s : ℂ) (hs : ∀ m : ℕ, s ≠ -m) : DifferentiableAt ℂ Gamma s := by - let n := ⌊1 - s.re⌋₊ + 1 - have hn : 1 - s.re < n := mod_cast Nat.lt_floor_add_one (1 - s.re) - apply (differentiableAt_GammaAux s n hn hs).congr_of_eventuallyEq - let S := {t : ℂ | 1 - t.re < n} - have : S ∈ 𝓝 s := by - rw [mem_nhds_iff]; use S - refine ⟨Subset.rfl, ?_, hn⟩ - have : S = re ⁻¹' Ioi (1 - n : ℝ) := by - ext; rw [preimage, Ioi, mem_setOf_eq, mem_setOf_eq, mem_setOf_eq]; exact sub_lt_comm - rw [this] - exact Continuous.isOpen_preimage continuous_re _ isOpen_Ioi - apply eventuallyEq_of_mem this - intro t ht; rw [mem_setOf_eq] at ht - apply Gamma_eq_GammaAux; linarith - -end GammaHasDeriv - -/-- At `s = 0`, the Gamma function has a simple pole with residue 1. -/ -theorem tendsto_self_mul_Gamma_nhds_zero : Tendsto (fun z : ℂ => z * Gamma z) (𝓝[≠] 0) (𝓝 1) := by - rw [show 𝓝 (1 : ℂ) = 𝓝 (Gamma (0 + 1)) by simp only [zero_add, Complex.Gamma_one]] - convert (Tendsto.mono_left _ nhdsWithin_le_nhds).congr' - (eventuallyEq_of_mem self_mem_nhdsWithin Complex.Gamma_add_one) using 1 - refine ContinuousAt.comp (g := Gamma) ?_ (continuous_id.add continuous_const).continuousAt - refine (Complex.differentiableAt_Gamma _ fun m => ?_).continuousAt - rw [zero_add, ← ofReal_natCast, ← ofReal_neg, ← ofReal_one, Ne, ofReal_inj] - refine (lt_of_le_of_lt ?_ zero_lt_one).ne' - exact neg_nonpos.mpr (Nat.cast_nonneg _) - end Complex namespace Real @@ -606,9 +530,4 @@ theorem Gamma_ne_zero {s : ℝ} (hs : ∀ m : ℕ, s ≠ -m) : Gamma s ≠ 0 := theorem Gamma_eq_zero_iff (s : ℝ) : Gamma s = 0 ↔ ∃ m : ℕ, s = -m := ⟨by contrapose!; exact Gamma_ne_zero, by rintro ⟨m, rfl⟩; exact Gamma_neg_nat_eq_zero m⟩ -theorem differentiableAt_Gamma {s : ℝ} (hs : ∀ m : ℕ, s ≠ -m) : DifferentiableAt ℝ Gamma s := by - refine (Complex.differentiableAt_Gamma _ ?_).hasDerivAt.real_of_complex.differentiableAt - simp_rw [← Complex.ofReal_natCast, ← Complex.ofReal_neg, Ne, Complex.ofReal_inj] - exact hs - end Real diff --git a/Mathlib/Analysis/SpecialFunctions/Gamma/BohrMollerup.lean b/Mathlib/Analysis/SpecialFunctions/Gamma/BohrMollerup.lean index c9f1f89b0bd5a3..f777ccb89b1bb9 100644 --- a/Mathlib/Analysis/SpecialFunctions/Gamma/BohrMollerup.lean +++ b/Mathlib/Analysis/SpecialFunctions/Gamma/BohrMollerup.lean @@ -3,6 +3,7 @@ Copyright (c) 2023 David Loeffler. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: David Loeffler -/ +import Mathlib.Analysis.SpecialFunctions.Gamma.Deriv import Mathlib.Analysis.SpecialFunctions.Gaussian.GaussianIntegral /-! # Convexity properties of the Gamma function diff --git a/Mathlib/Analysis/SpecialFunctions/Gamma/Deriv.lean b/Mathlib/Analysis/SpecialFunctions/Gamma/Deriv.lean new file mode 100644 index 00000000000000..8488967aba4307 --- /dev/null +++ b/Mathlib/Analysis/SpecialFunctions/Gamma/Deriv.lean @@ -0,0 +1,117 @@ +/- +Copyright (c) 2022 David Loeffler. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: David Loeffler +-/ +import Mathlib.Analysis.MellinTransform +import Mathlib.Analysis.SpecialFunctions.Gamma.Basic + +/-! +# Derivative of the Gamma function + +This file shows that the (complex) `Γ` function is complex-differentiable at all `s : ℂ` with +`s ∉ {-n : n ∈ ℕ}`, as well as the real counterpart. + +## Main results + +* `Complex.differentiableAt_Gamma`: `Γ` is complex-differentiable at all `s : ℂ` with + `s ∉ {-n : n ∈ ℕ}`. +* `Real.differentiableAt_Gamma`: `Γ` is real-differentiable at all `s : ℝ` with + `s ∉ {-n : n ∈ ℕ}`. + +## Tags + +Gamma +-/ + + +noncomputable section + +open Filter Set Real Asymptotics +open scoped Topology + +namespace Complex + +/-! Now check that the `Γ` function is differentiable, wherever this makes sense. -/ + + +section GammaHasDeriv + +/-- Rewrite the Gamma integral as an example of a Mellin transform. -/ +theorem GammaIntegral_eq_mellin : GammaIntegral = mellin fun x => ↑(Real.exp (-x)) := + funext fun s => by simp only [mellin, GammaIntegral, smul_eq_mul, mul_comm] + +/-- The derivative of the `Γ` integral, at any `s ∈ ℂ` with `1 < re s`, is given by the Mellin +transform of `log t * exp (-t)`. -/ +theorem hasDerivAt_GammaIntegral {s : ℂ} (hs : 0 < s.re) : + HasDerivAt GammaIntegral (∫ t : ℝ in Ioi 0, t ^ (s - 1) * (Real.log t * Real.exp (-t))) s := by + rw [GammaIntegral_eq_mellin] + convert (mellin_hasDerivAt_of_isBigO_rpow (E := ℂ) _ _ (lt_add_one _) _ hs).2 + · refine (Continuous.continuousOn ?_).locallyIntegrableOn measurableSet_Ioi + exact continuous_ofReal.comp (Real.continuous_exp.comp continuous_neg) + · rw [← isBigO_norm_left] + simp_rw [Complex.norm_eq_abs, abs_ofReal, ← Real.norm_eq_abs, isBigO_norm_left] + simpa only [neg_one_mul] using (isLittleO_exp_neg_mul_rpow_atTop zero_lt_one _).isBigO + · simp_rw [neg_zero, rpow_zero] + refine isBigO_const_of_tendsto (?_ : Tendsto _ _ (𝓝 (1 : ℂ))) one_ne_zero + rw [(by simp : (1 : ℂ) = Real.exp (-0))] + exact (continuous_ofReal.comp (Real.continuous_exp.comp continuous_neg)).continuousWithinAt + +theorem differentiableAt_GammaAux (s : ℂ) (n : ℕ) (h1 : 1 - s.re < n) (h2 : ∀ m : ℕ, s ≠ -m) : + DifferentiableAt ℂ (GammaAux n) s := by + induction' n with n hn generalizing s + · refine (hasDerivAt_GammaIntegral ?_).differentiableAt + rw [Nat.cast_zero] at h1; linarith + · dsimp only [GammaAux] + specialize hn (s + 1) + have a : 1 - (s + 1).re < ↑n := by + rw [Nat.cast_succ] at h1; rw [Complex.add_re, Complex.one_re]; linarith + have b : ∀ m : ℕ, s + 1 ≠ -m := by + intro m; have := h2 (1 + m) + contrapose! this + rw [← eq_sub_iff_add_eq] at this + simpa using this + refine DifferentiableAt.div (DifferentiableAt.comp _ (hn a b) ?_) ?_ ?_ + · rw [differentiableAt_add_const_iff (1 : ℂ)]; exact differentiableAt_id + · exact differentiableAt_id + · simpa using h2 0 + +theorem differentiableAt_Gamma (s : ℂ) (hs : ∀ m : ℕ, s ≠ -m) : DifferentiableAt ℂ Gamma s := by + let n := ⌊1 - s.re⌋₊ + 1 + have hn : 1 - s.re < n := mod_cast Nat.lt_floor_add_one (1 - s.re) + apply (differentiableAt_GammaAux s n hn hs).congr_of_eventuallyEq + let S := {t : ℂ | 1 - t.re < n} + have : S ∈ 𝓝 s := by + rw [mem_nhds_iff]; use S + refine ⟨Subset.rfl, ?_, hn⟩ + have : S = re ⁻¹' Ioi (1 - n : ℝ) := by + ext; rw [preimage, Ioi, mem_setOf_eq, mem_setOf_eq, mem_setOf_eq]; exact sub_lt_comm + rw [this] + exact Continuous.isOpen_preimage continuous_re _ isOpen_Ioi + apply eventuallyEq_of_mem this + intro t ht; rw [mem_setOf_eq] at ht + apply Gamma_eq_GammaAux; linarith + +end GammaHasDeriv + +/-- At `s = 0`, the Gamma function has a simple pole with residue 1. -/ +theorem tendsto_self_mul_Gamma_nhds_zero : Tendsto (fun z : ℂ => z * Gamma z) (𝓝[≠] 0) (𝓝 1) := by + rw [show 𝓝 (1 : ℂ) = 𝓝 (Gamma (0 + 1)) by simp only [zero_add, Complex.Gamma_one]] + convert (Tendsto.mono_left _ nhdsWithin_le_nhds).congr' + (eventuallyEq_of_mem self_mem_nhdsWithin Complex.Gamma_add_one) using 1 + refine ContinuousAt.comp (g := Gamma) ?_ (continuous_id.add continuous_const).continuousAt + refine (Complex.differentiableAt_Gamma _ fun m => ?_).continuousAt + rw [zero_add, ← ofReal_natCast, ← ofReal_neg, ← ofReal_one, Ne, ofReal_inj] + refine (lt_of_le_of_lt ?_ zero_lt_one).ne' + exact neg_nonpos.mpr (Nat.cast_nonneg _) + +end Complex + +namespace Real + +theorem differentiableAt_Gamma {s : ℝ} (hs : ∀ m : ℕ, s ≠ -m) : DifferentiableAt ℝ Gamma s := by + refine (Complex.differentiableAt_Gamma _ ?_).hasDerivAt.real_of_complex.differentiableAt + simp_rw [← Complex.ofReal_natCast, ← Complex.ofReal_neg, Ne, Complex.ofReal_inj] + exact hs + +end Real From e553fb0852ed7000d6b34eb25bb6d9a83ee069c4 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 15:26:52 +1100 Subject: [PATCH 260/425] shake update --- scripts/noshake.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/noshake.json b/scripts/noshake.json index 96b77d34aeb98d..e8328c65a83a7f 100644 --- a/scripts/noshake.json +++ b/scripts/noshake.json @@ -213,6 +213,8 @@ "Mathlib.Tactic.Tauto": ["Mathlib.Logic.Basic"], "Mathlib.Tactic.TFAE": ["Mathlib.Data.List.TFAE", "Mathlib.Tactic.Have"], "Mathlib.Tactic.Subsingleton": ["Mathlib.Logic.Basic", "Std.Logic"], + "Mathlib.Tactic.Simps.Basic": ["Batteries.Data.String.Basic"], + "Mathlib.Tactic.Says": ["Batteries.Data.String.Basic"], "Mathlib.Tactic.ReduceModChar": ["Mathlib.Data.ZMod.Basic", "Mathlib.RingTheory.Polynomial.Basic"], "Mathlib.Tactic.ProxyType": ["Mathlib.Logic.Equiv.Defs"], From 6bcc518e8f9569a23b8cd02942066bcb5a6aae1b Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 04:44:25 +0000 Subject: [PATCH 261/425] chore: use funext_iff instead of the alias Function.funext_iff (#17847) Not sure why we were using this alias in the first place. --- Archive/Wiedijk100Theorems/Partition.lean | 2 +- Mathlib/Algebra/BigOperators/Ring.lean | 2 +- Mathlib/Algebra/Divisibility/Prod.lean | 2 +- Mathlib/Algebra/Group/Pi/Lemmas.lean | 4 ++-- Mathlib/Algebra/Homology/Functor.lean | 4 ++-- Mathlib/Algebra/LinearRecurrence.lean | 2 +- Mathlib/Algebra/Module/ZLattice/Basic.lean | 2 +- Mathlib/Algebra/Order/BigOperators/Group/Finset.lean | 4 ++-- Mathlib/Algebra/Polynomial/Smeval.lean | 2 +- Mathlib/Analysis/Calculus/LagrangeMultipliers.lean | 4 ++-- Mathlib/Analysis/InnerProductSpace/OfNorm.lean | 2 +- .../Analysis/Normed/Operator/WeakOperatorTopology.lean | 2 +- Mathlib/Analysis/SpecialFunctions/Complex/Arg.lean | 2 +- Mathlib/CategoryTheory/GradedObject.lean | 2 +- Mathlib/CategoryTheory/Pi/Basic.lean | 2 +- Mathlib/CategoryTheory/Sites/LocallySurjective.lean | 2 +- Mathlib/CategoryTheory/Sites/Types.lean | 2 +- Mathlib/CategoryTheory/Types.lean | 2 +- Mathlib/Combinatorics/Additive/AP/Three/Behrend.lean | 2 +- Mathlib/Combinatorics/HalesJewett.lean | 2 +- Mathlib/Combinatorics/Hall/Basic.lean | 2 +- Mathlib/Combinatorics/SimpleGraph/Basic.lean | 2 +- Mathlib/Combinatorics/SimpleGraph/Circulant.lean | 4 ++-- Mathlib/Combinatorics/SimpleGraph/Turan.lean | 2 +- Mathlib/Computability/TMToPartrec.lean | 2 +- Mathlib/Data/Fin/Basic.lean | 4 ++-- Mathlib/Data/Finset/NAry.lean | 2 +- Mathlib/Data/Finset/Sort.lean | 2 +- Mathlib/Data/Fintype/Basic.lean | 2 +- Mathlib/Data/Fintype/Pi.lean | 6 +++--- Mathlib/Data/FunLike/Basic.lean | 2 +- Mathlib/Data/Matrix/ColumnRowPartitioned.lean | 4 ++-- Mathlib/Data/Multiset/Basic.lean | 2 +- Mathlib/Data/Real/GoldenRatio.lean | 2 +- Mathlib/Data/Set/Image.lean | 2 +- Mathlib/Data/W/Basic.lean | 2 +- Mathlib/FieldTheory/Finite/Polynomial.lean | 2 +- Mathlib/GroupTheory/CommutingProbability.lean | 2 +- Mathlib/GroupTheory/FreeGroup/IsFreeGroup.lean | 2 +- Mathlib/GroupTheory/GroupAction/FixedPoints.lean | 2 +- Mathlib/GroupTheory/HNNExtension.lean | 2 +- Mathlib/GroupTheory/Perm/DomMulAct.lean | 2 +- Mathlib/GroupTheory/PushoutI.lean | 6 +++--- Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean | 2 +- Mathlib/LinearAlgebra/AffineSpace/Independent.lean | 2 +- Mathlib/LinearAlgebra/Dual.lean | 2 +- Mathlib/LinearAlgebra/Matrix/DotProduct.lean | 6 +++--- Mathlib/LinearAlgebra/Pi.lean | 4 ++-- Mathlib/LinearAlgebra/QuadraticForm/Prod.lean | 2 +- Mathlib/Logic/Function/Basic.lean | 2 +- Mathlib/MeasureTheory/Measure/VectorMeasure.lean | 2 +- Mathlib/ModelTheory/Basic.lean | 6 +++--- Mathlib/ModelTheory/ElementaryMaps.lean | 2 +- Mathlib/ModelTheory/Syntax.lean | 2 +- Mathlib/NumberTheory/NumberField/House.lean | 10 +++++----- Mathlib/Order/RelSeries.lean | 2 +- Mathlib/Probability/ProbabilityMassFunction/Basic.lean | 2 +- .../GroupCohomology/LowDegree.lean | 10 +++++----- Mathlib/RingTheory/HahnSeries/Addition.lean | 4 ++-- Mathlib/RingTheory/HahnSeries/Basic.lean | 2 +- Mathlib/RingTheory/HahnSeries/Multiplication.lean | 6 +++--- Mathlib/RingTheory/Ideal/Maps.lean | 2 +- Mathlib/RingTheory/Idempotents.lean | 2 +- Mathlib/RingTheory/WittVector/Defs.lean | 2 +- Mathlib/RingTheory/WittVector/IsPoly.lean | 4 ++-- Mathlib/Topology/Algebra/Module/Basic.lean | 2 +- Mathlib/Topology/Homotopy/Product.lean | 2 +- Mathlib/Topology/LocallyConstant/Basic.lean | 2 +- Mathlib/Topology/TietzeExtension.lean | 2 +- test/instance_diamonds.lean | 8 ++++---- 70 files changed, 101 insertions(+), 101 deletions(-) diff --git a/Archive/Wiedijk100Theorems/Partition.lean b/Archive/Wiedijk100Theorems/Partition.lean index 1045104e58395c..689d098bcd228d 100644 --- a/Archive/Wiedijk100Theorems/Partition.lean +++ b/Archive/Wiedijk100Theorems/Partition.lean @@ -216,7 +216,7 @@ theorem partialGF_prop (α : Type*) [CommSemiring α] (n : ℕ) (s : Finset ℕ) intro a; exact Nat.lt_irrefl 0 (hs 0 (hp₂.2 0 a)) intro a; exact Nat.lt_irrefl 0 (hs 0 (hp₁.2 0 a)) · rw [← mul_left_inj' hi] - rw [Function.funext_iff] at h + rw [funext_iff] at h exact h.2 i · simp only [φ, mem_filter, mem_finsuppAntidiag, mem_univ, exists_prop, true_and, and_assoc] rintro f ⟨hf, hf₃, hf₄⟩ diff --git a/Mathlib/Algebra/BigOperators/Ring.lean b/Mathlib/Algebra/BigOperators/Ring.lean index 8ffa27de019be8..ffe59a97cc2ff6 100644 --- a/Mathlib/Algebra/BigOperators/Ring.lean +++ b/Mathlib/Algebra/BigOperators/Ring.lean @@ -168,7 +168,7 @@ theorem prod_add (f g : ι → α) (s : Finset ι) : (fun t _ a _ => a ∈ t) (by simp) (by simp [Classical.em]) - (by simp_rw [mem_filter, Function.funext_iff, eq_iff_iff, mem_pi, mem_insert]; tauto) + (by simp_rw [mem_filter, funext_iff, eq_iff_iff, mem_pi, mem_insert]; tauto) (by simp_rw [Finset.ext_iff, @mem_filter _ _ (id _), mem_powerset]; tauto) (fun a _ ↦ by simp only [prod_ite, filter_attach', prod_map, Function.Embedding.coeFn_mk, diff --git a/Mathlib/Algebra/Divisibility/Prod.lean b/Mathlib/Algebra/Divisibility/Prod.lean index 5eda6b629ea047..355b2cfd6033da 100644 --- a/Mathlib/Algebra/Divisibility/Prod.lean +++ b/Mathlib/Algebra/Divisibility/Prod.lean @@ -33,7 +33,7 @@ instance [DecompositionMonoid G₁] [DecompositionMonoid G₂] : DecompositionMo exact ⟨(a₁, a₂), (a₁', a₂'), ⟨h₁, h₂⟩, ⟨h₁', h₂'⟩, Prod.ext eq₁ eq₂⟩ theorem pi_dvd_iff {x y : ∀ i, G i} : x ∣ y ↔ ∀ i, x i ∣ y i := by - simp_rw [dvd_def, Function.funext_iff, Classical.skolem]; rfl + simp_rw [dvd_def, funext_iff, Classical.skolem]; rfl instance [∀ i, DecompositionMonoid (G i)] : DecompositionMonoid (∀ i, G i) where primal a b c h := by diff --git a/Mathlib/Algebra/Group/Pi/Lemmas.lean b/Mathlib/Algebra/Group/Pi/Lemmas.lean index a344930fb34fa6..1dee66ec01d1b6 100644 --- a/Mathlib/Algebra/Group/Pi/Lemmas.lean +++ b/Mathlib/Algebra/Group/Pi/Lemmas.lean @@ -70,7 +70,7 @@ def Pi.mulHom {γ : Type w} [∀ i, Mul (f i)] [Mul γ] (g : ∀ i, γ →ₙ* f theorem Pi.mulHom_injective {γ : Type w} [Nonempty I] [∀ i, Mul (f i)] [Mul γ] (g : ∀ i, γ →ₙ* f i) (hg : ∀ i, Function.Injective (g i)) : Function.Injective (Pi.mulHom g) := fun _ _ h => let ⟨i⟩ := ‹Nonempty I› - hg i ((Function.funext_iff.mp h : _) i) + hg i ((funext_iff.mp h : _) i) /-- A family of monoid homomorphisms `f a : γ →* β a` defines a monoid homomorphism `Pi.monoidHom f : γ →* Π a, β a` given by `Pi.monoidHom f x b = f b x`. -/ @@ -337,7 +337,7 @@ theorem SemiconjBy.pi {x y z : ∀ i, f i} (h : ∀ i, SemiconjBy (x i) (y i) (z @[to_additive] theorem Pi.semiconjBy_iff {x y z : ∀ i, f i} : - SemiconjBy x y z ↔ ∀ i, SemiconjBy (x i) (y i) (z i) := Function.funext_iff + SemiconjBy x y z ↔ ∀ i, SemiconjBy (x i) (y i) (z i) := funext_iff @[to_additive] theorem Commute.pi {x y : ∀ i, f i} (h : ∀ i, Commute (x i) (y i)) : Commute x y := .pi h diff --git a/Mathlib/Algebra/Homology/Functor.lean b/Mathlib/Algebra/Homology/Functor.lean index 59cf2538f199cf..7560ad47ae5ed7 100644 --- a/Mathlib/Algebra/Homology/Functor.lean +++ b/Mathlib/Algebra/Homology/Functor.lean @@ -37,11 +37,11 @@ def asFunctor {T : Type*} [Category T] (C : HomologicalComplex (T ⥤ V) c) : d := fun i j => (C.d i j).app t d_comp_d' := fun i j k _ _ => by have := C.d_comp_d i j k - rw [NatTrans.ext_iff, Function.funext_iff] at this + rw [NatTrans.ext_iff, funext_iff] at this exact this t shape := fun i j h => by have := C.shape _ _ h - rw [NatTrans.ext_iff, Function.funext_iff] at this + rw [NatTrans.ext_iff, funext_iff] at this exact this t } map h := { f := fun i => (C.X i).map h diff --git a/Mathlib/Algebra/LinearRecurrence.lean b/Mathlib/Algebra/LinearRecurrence.lean index b3b5648ee9db01..182a96ce2cf20c 100644 --- a/Mathlib/Algebra/LinearRecurrence.lean +++ b/Mathlib/Algebra/LinearRecurrence.lean @@ -138,7 +138,7 @@ def toInit : E.solSpace ≃ₗ[α] Fin E.order → α where simp invFun u := ⟨E.mkSol u, E.is_sol_mkSol u⟩ left_inv u := by ext n; symm; apply E.eq_mk_of_is_sol_of_eq_init u.2; intro k; rfl - right_inv u := Function.funext_iff.mpr fun n ↦ E.mkSol_eq_init u n + right_inv u := funext_iff.mpr fun n ↦ E.mkSol_eq_init u n /-- Two solutions are equal iff they are equal on `range E.order`. -/ theorem sol_eq_of_eq_init (u v : ℕ → α) (hu : E.IsSolution u) (hv : E.IsSolution v) : diff --git a/Mathlib/Algebra/Module/ZLattice/Basic.lean b/Mathlib/Algebra/Module/ZLattice/Basic.lean index a436852b2ab88a..f5d850e0a404e2 100644 --- a/Mathlib/Algebra/Module/ZLattice/Basic.lean +++ b/Mathlib/Algebra/Module/ZLattice/Basic.lean @@ -276,7 +276,7 @@ theorem discreteTopology_pi_basisFun [Finite ι] : refine discreteTopology_iff_isOpen_singleton_zero.mpr ⟨Metric.ball 0 1, Metric.isOpen_ball, ?_⟩ ext x rw [Set.mem_preimage, mem_ball_zero_iff, pi_norm_lt_iff zero_lt_one, Set.mem_singleton_iff] - simp_rw [← coe_eq_zero, Function.funext_iff, Pi.zero_apply, Real.norm_eq_abs] + simp_rw [← coe_eq_zero, funext_iff, Pi.zero_apply, Real.norm_eq_abs] refine forall_congr' (fun i => ?_) rsuffices ⟨y, hy⟩ : ∃ (y : ℤ), (y : ℝ) = (x : ι → ℝ) i · rw [← hy, ← Int.cast_abs, ← Int.cast_one, Int.cast_lt, Int.abs_lt_one_iff, Int.cast_eq_zero] diff --git a/Mathlib/Algebra/Order/BigOperators/Group/Finset.lean b/Mathlib/Algebra/Order/BigOperators/Group/Finset.lean index d5cdc6b8f86e75..8593406fe5e679 100644 --- a/Mathlib/Algebra/Order/BigOperators/Group/Finset.lean +++ b/Mathlib/Algebra/Order/BigOperators/Group/Finset.lean @@ -519,11 +519,11 @@ lemma one_le_prod (hf : 1 ≤ f) : 1 ≤ ∏ i, f i := Finset.one_le_prod' fun _ @[to_additive] lemma prod_eq_one_iff_of_one_le (hf : 1 ≤ f) : ∏ i, f i = 1 ↔ f = 1 := - (Finset.prod_eq_one_iff_of_one_le' fun i _ ↦ hf i).trans <| by simp [Function.funext_iff] + (Finset.prod_eq_one_iff_of_one_le' fun i _ ↦ hf i).trans <| by simp [funext_iff] @[to_additive] lemma prod_eq_one_iff_of_le_one (hf : f ≤ 1) : ∏ i, f i = 1 ↔ f = 1 := - (Finset.prod_eq_one_iff_of_le_one' fun i _ ↦ hf i).trans <| by simp [Function.funext_iff] + (Finset.prod_eq_one_iff_of_le_one' fun i _ ↦ hf i).trans <| by simp [funext_iff] end OrderedCommMonoid diff --git a/Mathlib/Algebra/Polynomial/Smeval.lean b/Mathlib/Algebra/Polynomial/Smeval.lean index d24a7089bfc93d..91d57a909fcc32 100644 --- a/Mathlib/Algebra/Polynomial/Smeval.lean +++ b/Mathlib/Algebra/Polynomial/Smeval.lean @@ -133,7 +133,7 @@ theorem smeval.linearMap_apply : smeval.linearMap R x p = p.smeval x := rfl theorem leval_coe_eq_smeval {R : Type*} [Semiring R] (r : R) : ⇑(leval r) = fun p => p.smeval r := by - rw [Function.funext_iff] + rw [funext_iff] intro rw [leval_apply, smeval_def, eval_eq_sum] rfl diff --git a/Mathlib/Analysis/Calculus/LagrangeMultipliers.lean b/Mathlib/Analysis/Calculus/LagrangeMultipliers.lean index faa6e1df7770b9..64e2efb39c8750 100644 --- a/Mathlib/Analysis/Calculus/LagrangeMultipliers.lean +++ b/Mathlib/Analysis/Calculus/LagrangeMultipliers.lean @@ -106,7 +106,7 @@ theorem IsLocalExtrOn.exists_multipliers_of_hasStrictFDerivAt {ι : Type*} [Fint ∃ (Λ : ι → ℝ) (Λ₀ : ℝ), (Λ, Λ₀) ≠ 0 ∧ (∑ i, Λ i • f' i) + Λ₀ • φ' = 0 := by letI := Classical.decEq ι replace hextr : IsLocalExtrOn φ {x | (fun i => f i x) = fun i => f i x₀} x₀ := by - simpa only [Function.funext_iff] using hextr + simpa only [funext_iff] using hextr rcases hextr.exists_linear_map_of_hasStrictFDerivAt (hasStrictFDerivAt_pi.2 fun i => hf' i) hφ' with ⟨Λ, Λ₀, h0, hsum⟩ @@ -132,5 +132,5 @@ theorem IsLocalExtrOn.linear_dependent_of_hasStrictFDerivAt {ι : Type*} [Finite rcases hextr.exists_multipliers_of_hasStrictFDerivAt hf' hφ' with ⟨Λ, Λ₀, hΛ, hΛf⟩ refine ⟨Option.elim' Λ₀ Λ, ?_, ?_⟩ · simpa [add_comm] using hΛf - · simpa only [Function.funext_iff, not_and_or, or_comm, Option.exists, Prod.mk_eq_zero, Ne, + · simpa only [funext_iff, not_and_or, or_comm, Option.exists, Prod.mk_eq_zero, Ne, not_forall] using hΛ diff --git a/Mathlib/Analysis/InnerProductSpace/OfNorm.lean b/Mathlib/Analysis/InnerProductSpace/OfNorm.lean index e2e23c0b46a9de..b62522a0e45d6f 100644 --- a/Mathlib/Analysis/InnerProductSpace/OfNorm.lean +++ b/Mathlib/Analysis/InnerProductSpace/OfNorm.lean @@ -194,7 +194,7 @@ private theorem rat_prop (r : ℚ) : innerProp' E (r : 𝕜) := by private theorem real_prop (r : ℝ) : innerProp' E (r : 𝕜) := by intro x y revert r - rw [← Function.funext_iff] + rw [← funext_iff] refine Rat.isDenseEmbedding_coe_real.dense.equalizer ?_ ?_ (funext fun X => ?_) · exact (continuous_ofReal.smul continuous_const).inner_ continuous_const · exact (continuous_conj.comp continuous_ofReal).mul continuous_const diff --git a/Mathlib/Analysis/Normed/Operator/WeakOperatorTopology.lean b/Mathlib/Analysis/Normed/Operator/WeakOperatorTopology.lean index 45dfa1892cbcc6..202618cf94cd60 100644 --- a/Mathlib/Analysis/Normed/Operator/WeakOperatorTopology.lean +++ b/Mathlib/Analysis/Normed/Operator/WeakOperatorTopology.lean @@ -175,7 +175,7 @@ lemma continuous_of_dual_apply_continuous {α : Type*} [TopologicalSpace α] {g lemma embedding_inducingFn : Embedding (inducingFn 𝕜 E F) := by refine Function.Injective.embedding_induced fun A B hAB => ?_ rw [ContinuousLinearMapWOT.ext_dual_iff] - simpa [Function.funext_iff] using hAB + simpa [funext_iff] using hAB open Filter in /-- The defining property of the weak operator topology: a function `f` tends to diff --git a/Mathlib/Analysis/SpecialFunctions/Complex/Arg.lean b/Mathlib/Analysis/SpecialFunctions/Complex/Arg.lean index b7b5fa601494d6..0086e643a19b85 100644 --- a/Mathlib/Analysis/SpecialFunctions/Complex/Arg.lean +++ b/Mathlib/Analysis/SpecialFunctions/Complex/Arg.lean @@ -597,7 +597,7 @@ theorem continuousAt_arg_coe_angle (h : x ≠ 0) : ContinuousAt ((↑) ∘ arg : by_cases hs : x ∈ slitPlane · exact Real.Angle.continuous_coe.continuousAt.comp (continuousAt_arg hs) · rw [← Function.comp_id (((↑) : ℝ → Real.Angle) ∘ arg), - (Function.funext_iff.2 fun _ => (neg_neg _).symm : (id : ℂ → ℂ) = Neg.neg ∘ Neg.neg), ← + (funext_iff.2 fun _ => (neg_neg _).symm : (id : ℂ → ℂ) = Neg.neg ∘ Neg.neg), ← Function.comp_assoc] refine ContinuousAt.comp ?_ continuous_neg.continuousAt suffices ContinuousAt (Function.update (((↑) ∘ arg) ∘ Neg.neg : ℂ → Real.Angle) 0 π) (-x) by diff --git a/Mathlib/CategoryTheory/GradedObject.lean b/Mathlib/CategoryTheory/GradedObject.lean index c3fd1e2c4e0aa0..b5344653826c99 100644 --- a/Mathlib/CategoryTheory/GradedObject.lean +++ b/Mathlib/CategoryTheory/GradedObject.lean @@ -158,7 +158,7 @@ abbrev comap {I J : Type*} (h : J → I) : GradedObject I C ⥤ GradedObject J C -- Porting note: added to ease the port, this is a special case of `Functor.eqToHom_proj` @[simp] theorem eqToHom_proj {I : Type*} {x x' : GradedObject I C} (h : x = x') (i : I) : - (eqToHom h : x ⟶ x') i = eqToHom (Function.funext_iff.mp h i) := by + (eqToHom h : x ⟶ x') i = eqToHom (funext_iff.mp h i) := by subst h rfl diff --git a/Mathlib/CategoryTheory/Pi/Basic.lean b/Mathlib/CategoryTheory/Pi/Basic.lean index beeb60fcf3da4f..8515247f7d5ba3 100644 --- a/Mathlib/CategoryTheory/Pi/Basic.lean +++ b/Mathlib/CategoryTheory/Pi/Basic.lean @@ -206,7 +206,7 @@ section EqToHom @[simp] theorem eqToHom_proj {x x' : ∀ i, C i} (h : x = x') (i : I) : - (eqToHom h : x ⟶ x') i = eqToHom (Function.funext_iff.mp h i) := by + (eqToHom h : x ⟶ x') i = eqToHom (funext_iff.mp h i) := by subst h rfl diff --git a/Mathlib/CategoryTheory/Sites/LocallySurjective.lean b/Mathlib/CategoryTheory/Sites/LocallySurjective.lean index 06a7da7304b54e..289d2db4e05a64 100644 --- a/Mathlib/CategoryTheory/Sites/LocallySurjective.lean +++ b/Mathlib/CategoryTheory/Sites/LocallySurjective.lean @@ -93,7 +93,7 @@ instance {F G : Cᵒᵖ ⥤ A} (f : F ⟶ G) [IsLocallySurjective J f] : theorem isLocallySurjective_iff_imagePresheaf_sheafify_eq_top {F G : Cᵒᵖ ⥤ A} (f : F ⟶ G) : IsLocallySurjective J f ↔ (imagePresheaf (whiskerRight f (forget A))).sheafify J = ⊤ := by - simp only [Subpresheaf.ext_iff, Function.funext_iff, Set.ext_iff, top_subpresheaf_obj, + simp only [Subpresheaf.ext_iff, funext_iff, Set.ext_iff, top_subpresheaf_obj, Set.top_eq_univ, Set.mem_univ, iff_true] exact ⟨fun H _ => H.imageSieve_mem, fun H => ⟨H _⟩⟩ diff --git a/Mathlib/CategoryTheory/Sites/Types.lean b/Mathlib/CategoryTheory/Sites/Types.lean index b1ba30f51c8e27..ecbb98c1d2d6fc 100644 --- a/Mathlib/CategoryTheory/Sites/Types.lean +++ b/Mathlib/CategoryTheory/Sites/Types.lean @@ -172,6 +172,6 @@ theorem typesGrothendieckTopology_eq_canonical : have : (fun _ => ULift.up true) = fun _ => ULift.up false := (hs PUnit fun _ => x).isSeparatedFor.ext fun β f hf => funext fun y => hsx.elim <| S.2 hf fun _ => y - simp [Function.funext_iff] at this + simp [funext_iff] at this end CategoryTheory diff --git a/Mathlib/CategoryTheory/Types.lean b/Mathlib/CategoryTheory/Types.lean index a084aa296a6af6..01484dc45c6dca 100644 --- a/Mathlib/CategoryTheory/Types.lean +++ b/Mathlib/CategoryTheory/Types.lean @@ -117,7 +117,7 @@ lemma sections_property {F : J ⥤ Type w} (s : (F.sections : Type _)) s.property f lemma sections_ext_iff {F : J ⥤ Type w} {x y : F.sections} : x = y ↔ ∀ j, x.val j = y.val j := - Subtype.ext_iff.trans Function.funext_iff + Subtype.ext_iff.trans funext_iff variable (J) diff --git a/Mathlib/Combinatorics/Additive/AP/Three/Behrend.lean b/Mathlib/Combinatorics/Additive/AP/Three/Behrend.lean index 076f7c450bcdee..14728c20ba5795 100644 --- a/Mathlib/Combinatorics/Additive/AP/Three/Behrend.lean +++ b/Mathlib/Combinatorics/Additive/AP/Three/Behrend.lean @@ -102,7 +102,7 @@ quadrant. -/ def sphere (n d k : ℕ) : Finset (Fin n → ℕ) := (box n d).filter fun x => ∑ i, x i ^ 2 = k -theorem sphere_zero_subset : sphere n d 0 ⊆ 0 := fun x => by simp [sphere, Function.funext_iff] +theorem sphere_zero_subset : sphere n d 0 ⊆ 0 := fun x => by simp [sphere, funext_iff] @[simp] theorem sphere_zero_right (n k : ℕ) : sphere (n + 1) 0 k = ∅ := by simp [sphere] diff --git a/Mathlib/Combinatorics/HalesJewett.lean b/Mathlib/Combinatorics/HalesJewett.lean index 04d6ee1658e639..76bb5d7812114a 100644 --- a/Mathlib/Combinatorics/HalesJewett.lean +++ b/Mathlib/Combinatorics/HalesJewett.lean @@ -138,7 +138,7 @@ variable {η' α' ι' : Type*} def reindex (l : Subspace η α ι) (eη : η ≃ η') (eα : α ≃ α') (eι : ι ≃ ι') : Subspace η' α' ι' where idxFun i := (l.idxFun <| eι.symm i).map eα eη proper e := (eι.exists_congr fun i ↦ by cases h : idxFun l i <;> - simp [*, Function.funext_iff, Equiv.eq_symm_apply]).1 <| l.proper <| eη.symm e + simp [*, funext_iff, Equiv.eq_symm_apply]).1 <| l.proper <| eη.symm e @[simp] lemma reindex_apply (l : Subspace η α ι) (eη : η ≃ η') (eα : α ≃ α') (eι : ι ≃ ι') (x i) : l.reindex eη eα eι x i = eα (l (eα.symm ∘ x ∘ eη) <| eι.symm i) := by diff --git a/Mathlib/Combinatorics/Hall/Basic.lean b/Mathlib/Combinatorics/Hall/Basic.lean index 70a89a8ee97907..0d0b9a82657a95 100644 --- a/Mathlib/Combinatorics/Hall/Basic.lean +++ b/Mathlib/Combinatorics/Hall/Basic.lean @@ -100,7 +100,7 @@ instance hallMatchingsOn.finite {ι : Type u} {α : Type v} (t : ι → Finset apply Finite.of_injective g intro f f' h ext a - rw [Function.funext_iff] at h + rw [funext_iff] at h simpa [g] using h a /-- This is the version of **Hall's Marriage Theorem** in terms of indexed diff --git a/Mathlib/Combinatorics/SimpleGraph/Basic.lean b/Mathlib/Combinatorics/SimpleGraph/Basic.lean index 008ba18f37ef67..69de374b0e114a 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Basic.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Basic.lean @@ -355,7 +355,7 @@ instance [Subsingleton V] : Unique (SimpleGraph V) where uniq G := by ext a b; have := Subsingleton.elim a b; simp [this] instance [Nontrivial V] : Nontrivial (SimpleGraph V) := - ⟨⟨⊥, ⊤, fun h ↦ not_subsingleton V ⟨by simpa only [← adj_inj, Function.funext_iff, bot_adj, + ⟨⟨⊥, ⊤, fun h ↦ not_subsingleton V ⟨by simpa only [← adj_inj, funext_iff, bot_adj, top_adj, ne_eq, eq_iff_iff, false_iff, not_not] using h⟩⟩⟩ section Decidable diff --git a/Mathlib/Combinatorics/SimpleGraph/Circulant.lean b/Mathlib/Combinatorics/SimpleGraph/Circulant.lean index 121f720ec7a12b..99106b3256d7b3 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Circulant.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Circulant.lean @@ -72,11 +72,11 @@ 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, Function.funext_iff] + simp only [SimpleGraph.ext_iff, funext_iff] decide theorem cycleGraph_three_eq_top : cycleGraph 3 = ⊤ := by - simp only [SimpleGraph.ext_iff, Function.funext_iff] + simp only [SimpleGraph.ext_iff, funext_iff] decide theorem cycleGraph_one_adj {u v : Fin 1} : ¬(cycleGraph 1).Adj u v := by diff --git a/Mathlib/Combinatorics/SimpleGraph/Turan.lean b/Mathlib/Combinatorics/SimpleGraph/Turan.lean index 45760dc0bd670a..08ab8e530a2c03 100644 --- a/Mathlib/Combinatorics/SimpleGraph/Turan.lean +++ b/Mathlib/Combinatorics/SimpleGraph/Turan.lean @@ -72,7 +72,7 @@ lemma turanGraph_zero : turanGraph n 0 = ⊤ := by @[simp] theorem turanGraph_eq_top : turanGraph n r = ⊤ ↔ r = 0 ∨ n ≤ r := by - simp_rw [SimpleGraph.ext_iff, Function.funext_iff, turanGraph, top_adj, eq_iff_iff, not_iff_not] + simp_rw [SimpleGraph.ext_iff, funext_iff, turanGraph, top_adj, eq_iff_iff, not_iff_not] refine ⟨fun h ↦ ?_, ?_⟩ · contrapose! h use ⟨0, (Nat.pos_of_ne_zero h.1).trans h.2⟩, ⟨r, h.2⟩ diff --git a/Mathlib/Computability/TMToPartrec.lean b/Mathlib/Computability/TMToPartrec.lean index a19ae0a5453fde..440884be0810cb 100644 --- a/Mathlib/Computability/TMToPartrec.lean +++ b/Mathlib/Computability/TMToPartrec.lean @@ -883,7 +883,7 @@ instance Λ'.instInhabited : Inhabited Λ' := instance Λ'.instDecidableEq : DecidableEq Λ' := fun a b => by induction a generalizing b <;> cases b <;> first | apply Decidable.isFalse; rintro ⟨⟨⟩⟩; done - | exact decidable_of_iff' _ (by simp [Function.funext_iff]; rfl) + | exact decidable_of_iff' _ (by simp [funext_iff]; rfl) /-- The type of TM2 statements used by this machine. -/ def Stmt' := diff --git a/Mathlib/Data/Fin/Basic.lean b/Mathlib/Data/Fin/Basic.lean index 7b7b730d2913b7..715342aa569631 100644 --- a/Mathlib/Data/Fin/Basic.lean +++ b/Mathlib/Data/Fin/Basic.lean @@ -171,7 +171,7 @@ then they coincide (in the heq sense). -/ protected theorem heq_fun_iff {α : Sort*} {k l : ℕ} (h : k = l) {f : Fin k → α} {g : Fin l → α} : HEq f g ↔ ∀ i : Fin k, f i = g ⟨(i : ℕ), h ▸ i.2⟩ := by subst h - simp [Function.funext_iff] + simp [funext_iff] /-- Assume `k = l` and `k' = l'`. If two functions `Fin k → Fin k' → α` and `Fin l → Fin l' → α` are equal on each pair, @@ -181,7 +181,7 @@ protected theorem heq_fun₂_iff {α : Sort*} {k l k' l' : ℕ} (h : k = l) (h' HEq f g ↔ ∀ (i : Fin k) (j : Fin k'), f i j = g ⟨(i : ℕ), h ▸ i.2⟩ ⟨(j : ℕ), h' ▸ j.2⟩ := by subst h subst h' - simp [Function.funext_iff] + simp [funext_iff] /-- Two elements of `Fin k` and `Fin l` are heq iff their values in `ℕ` coincide. This requires `k = l`. For the left implication without this assumption, see `val_eq_val_of_heq`. -/ diff --git a/Mathlib/Data/Finset/NAry.lean b/Mathlib/Data/Finset/NAry.lean index 97c9c4284cbd7d..db73633e28a15f 100644 --- a/Mathlib/Data/Finset/NAry.lean +++ b/Mathlib/Data/Finset/NAry.lean @@ -582,7 +582,7 @@ variable {ι : Type*} {α β γ : ι → Type*} [DecidableEq ι] [Fintype ι] [ lemma piFinset_image₂ (f : ∀ i, α i → β i → γ i) (s : ∀ i, Finset (α i)) (t : ∀ i, Finset (β i)) : piFinset (fun i ↦ image₂ (f i) (s i) (t i)) = image₂ (fun a b i ↦ f _ (a i) (b i)) (piFinset s) (piFinset t) := by - ext; simp only [mem_piFinset, mem_image₂, Classical.skolem, forall_and, Function.funext_iff] + ext; simp only [mem_piFinset, mem_image₂, Classical.skolem, forall_and, funext_iff] end Fintype diff --git a/Mathlib/Data/Finset/Sort.lean b/Mathlib/Data/Finset/Sort.lean index 361e4f3721a7fe..923e35810f214e 100644 --- a/Mathlib/Data/Finset/Sort.lean +++ b/Mathlib/Data/Finset/Sort.lean @@ -219,7 +219,7 @@ theorem orderEmbOfFin_unique {s : Finset α} {k : ℕ} (h : s.card = k) {f : Fin the increasing bijection `orderEmbOfFin s h`. -/ theorem orderEmbOfFin_unique' {s : Finset α} {k : ℕ} (h : s.card = k) {f : Fin k ↪o α} (hfs : ∀ x, f x ∈ s) : f = s.orderEmbOfFin h := - RelEmbedding.ext <| Function.funext_iff.1 <| orderEmbOfFin_unique h hfs f.strictMono + RelEmbedding.ext <| funext_iff.1 <| orderEmbOfFin_unique h hfs f.strictMono /-- Two parametrizations `orderEmbOfFin` of the same set take the same value on `i` and `j` if and only if `i = j`. Since they can be defined on a priori not defeq types `Fin k` and `Fin l` diff --git a/Mathlib/Data/Fintype/Basic.lean b/Mathlib/Data/Fintype/Basic.lean index 0ff3b973f0141f..997a6dd16aeb40 100644 --- a/Mathlib/Data/Fintype/Basic.lean +++ b/Mathlib/Data/Fintype/Basic.lean @@ -376,7 +376,7 @@ namespace Fintype instance decidablePiFintype {α} {β : α → Type*} [∀ a, DecidableEq (β a)] [Fintype α] : DecidableEq (∀ a, β a) := fun f g => decidable_of_iff (∀ a ∈ @Fintype.elems α _, f a = g a) - (by simp [Function.funext_iff, Fintype.complete]) + (by simp [funext_iff, Fintype.complete]) instance decidableForallFintype {p : α → Prop} [DecidablePred p] [Fintype α] : Decidable (∀ a, p a) := diff --git a/Mathlib/Data/Fintype/Pi.lean b/Mathlib/Data/Fintype/Pi.lean index 99a88bda7004a6..c32f9bbfd62b6c 100644 --- a/Mathlib/Data/Fintype/Pi.lean +++ b/Mathlib/Data/Fintype/Pi.lean @@ -25,7 +25,7 @@ analogue of `Finset.pi` where the base finset is `univ` (but formally they are n there is an additional condition `i ∈ Finset.univ` in the `Finset.pi` definition). -/ def piFinset (t : ∀ a, Finset (δ a)) : Finset (∀ a, δ a) := (Finset.univ.pi t).map ⟨fun f a => f a (mem_univ a), fun _ _ => - by simp (config := {contextual := true}) [Function.funext_iff]⟩ + by simp (config := {contextual := true}) [funext_iff]⟩ @[simp] theorem mem_piFinset {t : ∀ a, Finset (δ a)} {f : ∀ a, δ a} : f ∈ piFinset t ↔ ∀ a, f a ∈ t a := by @@ -69,7 +69,7 @@ lemma piFinset_of_isEmpty [IsEmpty α] (s : ∀ a, Finset (γ a)) : piFinset s = @[simp] theorem piFinset_singleton (f : ∀ i, δ i) : piFinset (fun i => {f i} : ∀ i, Finset (δ i)) = {f} := - ext fun _ => by simp only [Function.funext_iff, Fintype.mem_piFinset, mem_singleton] + ext fun _ => by simp only [funext_iff, Fintype.mem_piFinset, mem_singleton] theorem piFinset_subsingleton {f : ∀ i, Finset (δ i)} (hf : ∀ i, (f i : Set (δ i)).Subsingleton) : (Fintype.piFinset f : Set (∀ i, δ i)).Subsingleton := fun _ ha _ hb => @@ -83,7 +83,7 @@ theorem piFinset_disjoint_of_disjoint (t₁ t₂ : ∀ a, Finset (δ a)) {a : α lemma piFinset_image [∀ a, DecidableEq (δ a)] (f : ∀ a, γ a → δ a) (s : ∀ a, Finset (γ a)) : piFinset (fun a ↦ (s a).image (f a)) = (piFinset s).image fun b a ↦ f _ (b a) := by - ext; simp only [mem_piFinset, mem_image, Classical.skolem, forall_and, Function.funext_iff] + ext; simp only [mem_piFinset, mem_image, Classical.skolem, forall_and, funext_iff] lemma eval_image_piFinset_subset (t : ∀ a, Finset (δ a)) (a : α) [DecidableEq (δ a)] : ((piFinset t).image fun f ↦ f a) ⊆ t a := image_subset_iff.2 fun _x hx ↦ mem_piFinset.1 hx _ diff --git a/Mathlib/Data/FunLike/Basic.lean b/Mathlib/Data/FunLike/Basic.lean index 3a04435a85ca6f..afcc1b7e13a252 100644 --- a/Mathlib/Data/FunLike/Basic.lean +++ b/Mathlib/Data/FunLike/Basic.lean @@ -194,7 +194,7 @@ theorem ext (f g : F) (h : ∀ x : α, f x = g x) : f = g := DFunLike.coe_injective' (funext h) theorem ext_iff {f g : F} : f = g ↔ ∀ x, f x = g x := - coe_fn_eq.symm.trans Function.funext_iff + coe_fn_eq.symm.trans funext_iff protected theorem congr_fun {f g : F} (h₁ : f = g) (x : α) : f x = g x := congr_fun (congr_arg _ h₁) x diff --git a/Mathlib/Data/Matrix/ColumnRowPartitioned.lean b/Mathlib/Data/Matrix/ColumnRowPartitioned.lean index 1fef44043ba64a..67906c2b869f0c 100644 --- a/Mathlib/Data/Matrix/ColumnRowPartitioned.lean +++ b/Mathlib/Data/Matrix/ColumnRowPartitioned.lean @@ -108,12 +108,12 @@ lemma fromRows_toRows (A : Matrix (m₁ ⊕ m₂) n R) : fromRows A.toRows₁ A. lemma fromRows_inj : Function.Injective2 (@fromRows R m₁ m₂ n) := by intros x1 x2 y1 y2 - simp only [Function.funext_iff, ← Matrix.ext_iff] + simp only [funext_iff, ← Matrix.ext_iff] aesop lemma fromColumns_inj : Function.Injective2 (@fromColumns R m n₁ n₂) := by intros x1 x2 y1 y2 - simp only [Function.funext_iff, ← Matrix.ext_iff] + simp only [funext_iff, ← Matrix.ext_iff] aesop lemma fromColumns_ext_iff (A₁ : Matrix m n₁ R) (A₂ : Matrix m n₂ R) (B₁ : Matrix m n₁ R) diff --git a/Mathlib/Data/Multiset/Basic.lean b/Mathlib/Data/Multiset/Basic.lean index 7dc4316f0e993a..8f15a338625d13 100644 --- a/Mathlib/Data/Multiset/Basic.lean +++ b/Mathlib/Data/Multiset/Basic.lean @@ -1421,7 +1421,7 @@ instance decidableDforallMultiset {p : ∀ a ∈ m, Prop} [_hp : ∀ (a) (h : a /-- decidable equality for functions whose domain is bounded by multisets -/ instance decidableEqPiMultiset {β : α → Type*} [∀ a, DecidableEq (β a)] : DecidableEq (∀ a ∈ m, β a) := fun f g => - decidable_of_iff (∀ (a) (h : a ∈ m), f a h = g a h) (by simp [Function.funext_iff]) + decidable_of_iff (∀ (a) (h : a ∈ m), f a h = g a h) (by simp [funext_iff]) /-- If `p` is a decidable predicate, so is the existence of an element in a multiset satisfying `p`. -/ diff --git a/Mathlib/Data/Real/GoldenRatio.lean b/Mathlib/Data/Real/GoldenRatio.lean index 42e9c2559ca889..2518fadf3188ae 100644 --- a/Mathlib/Data/Real/GoldenRatio.lean +++ b/Mathlib/Data/Real/GoldenRatio.lean @@ -201,7 +201,7 @@ theorem Real.coe_fib_eq' : /-- Binet's formula as a dependent equality. -/ theorem Real.coe_fib_eq : ∀ n, (Nat.fib n : ℝ) = (φ ^ n - ψ ^ n) / √5 := by - rw [← Function.funext_iff, Real.coe_fib_eq'] + rw [← funext_iff, Real.coe_fib_eq'] /-- Relationship between the Fibonacci Sequence, Golden Ratio and its conjugate's exponents --/ theorem fib_golden_conj_exp (n : ℕ) : Nat.fib (n + 1) - φ * Nat.fib n = ψ ^ n := by diff --git a/Mathlib/Data/Set/Image.lean b/Mathlib/Data/Set/Image.lean index b0d95b24f93818..071d9c15c3f6c4 100644 --- a/Mathlib/Data/Set/Image.lean +++ b/Mathlib/Data/Set/Image.lean @@ -634,7 +634,7 @@ theorem range_subset_iff : range f ⊆ s ↔ ∀ y, f y ∈ s := theorem range_subset_range_iff_exists_comp {f : α → γ} {g : β → γ} : range f ⊆ range g ↔ ∃ h : α → β, f = g ∘ h := by - simp only [range_subset_iff, mem_range, Classical.skolem, Function.funext_iff, (· ∘ ·), eq_comm] + simp only [range_subset_iff, mem_range, Classical.skolem, funext_iff, (· ∘ ·), eq_comm] theorem range_eq_iff (f : α → β) (s : Set β) : range f = s ↔ (∀ a, f a ∈ s) ∧ ∀ b ∈ s, ∃ a, f a = b := by diff --git a/Mathlib/Data/W/Basic.lean b/Mathlib/Data/W/Basic.lean index a2b73e07e8871d..7c1f339cc49d04 100644 --- a/Mathlib/Data/W/Basic.lean +++ b/Mathlib/Data/W/Basic.lean @@ -103,7 +103,7 @@ theorem infinite_of_nonempty_of_isEmpty (a b : α) [ha : Nonempty (β a)] [he : · cases' m with m · simp_all · refine congr_arg Nat.succ (ih ?_) - simp_all [Function.funext_iff]⟩ + simp_all [funext_iff]⟩ variable [∀ a : α, Fintype (β a)] diff --git a/Mathlib/FieldTheory/Finite/Polynomial.lean b/Mathlib/FieldTheory/Finite/Polynomial.lean index a5a76e1726feb4..36dd816621f74e 100644 --- a/Mathlib/FieldTheory/Finite/Polynomial.lean +++ b/Mathlib/FieldTheory/Finite/Polynomial.lean @@ -99,7 +99,7 @@ end CommRing variable [Field K] theorem eval_indicator_apply_eq_zero (a b : σ → K) (h : a ≠ b) : eval a (indicator b) = 0 := by - obtain ⟨i, hi⟩ : ∃ i, a i ≠ b i := by rwa [Ne, Function.funext_iff, not_forall] at h + obtain ⟨i, hi⟩ : ∃ i, a i ≠ b i := by rwa [Ne, funext_iff, not_forall] at h simp only [indicator, map_prod, map_sub, map_one, map_pow, eval_X, eval_C, sub_self, Finset.prod_eq_zero_iff] refine ⟨i, Finset.mem_univ _, ?_⟩ diff --git a/Mathlib/GroupTheory/CommutingProbability.lean b/Mathlib/GroupTheory/CommutingProbability.lean index 3f168c3c283058..df8f7702b7fddb 100644 --- a/Mathlib/GroupTheory/CommutingProbability.lean +++ b/Mathlib/GroupTheory/CommutingProbability.lean @@ -47,7 +47,7 @@ theorem commProb_prod (M' : Type*) [Mul M'] : commProb (M × M') = commProb M * theorem commProb_pi {α : Type*} (i : α → Type*) [Fintype α] [∀ a, Mul (i a)] : commProb (∀ a, i a) = ∏ a, commProb (i a) := by simp_rw [commProb_def, Finset.prod_div_distrib, Finset.prod_pow, ← Nat.cast_prod, - ← Nat.card_pi, Commute, SemiconjBy, Function.funext_iff] + ← Nat.card_pi, Commute, SemiconjBy, funext_iff] congr 2 exact Nat.card_congr ⟨fun x a => ⟨⟨x.1.1 a, x.1.2 a⟩, x.2 a⟩, fun x => ⟨⟨fun a => (x a).1.1, fun a => (x a).1.2⟩, fun a => (x a).2⟩, fun x => rfl, fun x => rfl⟩ diff --git a/Mathlib/GroupTheory/FreeGroup/IsFreeGroup.lean b/Mathlib/GroupTheory/FreeGroup/IsFreeGroup.lean index 5999f4a20b7215..e3a6f25954b2b1 100644 --- a/Mathlib/GroupTheory/FreeGroup/IsFreeGroup.lean +++ b/Mathlib/GroupTheory/FreeGroup/IsFreeGroup.lean @@ -214,7 +214,7 @@ 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. -/ theorem unique_lift (f : Generators G → H) : ∃! F : G →* H, ∀ a, F (of a) = f a := by - simpa only [Function.funext_iff] using lift.symm.bijective.existsUnique f + 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 diff --git a/Mathlib/GroupTheory/GroupAction/FixedPoints.lean b/Mathlib/GroupTheory/GroupAction/FixedPoints.lean index 070b3e8dd30e2c..a8a5bc7b71b559 100644 --- a/Mathlib/GroupTheory/GroupAction/FixedPoints.lean +++ b/Mathlib/GroupTheory/GroupAction/FixedPoints.lean @@ -237,7 +237,7 @@ then `fixedBy α m = Set.univ` implies that `m = 1`. -/ then `fixedBy α m = Set.univ` implies that `m = 1`."] theorem fixedBy_eq_univ_iff_eq_one {m : M} : fixedBy α m = Set.univ ↔ m = 1 := by rw [← (smul_left_injective' (M := M) (α := α)).eq_iff, Set.eq_univ_iff_forall] - simp_rw [Function.funext_iff, one_smul, mem_fixedBy] + simp_rw [funext_iff, one_smul, mem_fixedBy] /-- If the image of the `(fixedBy α g)ᶜ` set by the pointwise action of `h: G` diff --git a/Mathlib/GroupTheory/HNNExtension.lean b/Mathlib/GroupTheory/HNNExtension.lean index 551403b5170c4e..a4d0b7d277511d 100644 --- a/Mathlib/GroupTheory/HNNExtension.lean +++ b/Mathlib/GroupTheory/HNNExtension.lean @@ -595,7 +595,7 @@ theorem of_injective : Function.Injective (of : G → HNNExtension G A B φ) := (f := ((· • ·) : HNNExtension G A B φ → NormalWord d → NormalWord d)) ?_ intros _ _ h exact eq_of_smul_eq_smul (fun w : NormalWord d => - by simp_all [Function.funext_iff, of_smul_eq_smul]) + by simp_all [funext_iff, of_smul_eq_smul]) namespace ReducedWord diff --git a/Mathlib/GroupTheory/Perm/DomMulAct.lean b/Mathlib/GroupTheory/Perm/DomMulAct.lean index 5d730372bcddfa..4db961f2237134 100644 --- a/Mathlib/GroupTheory/Perm/DomMulAct.lean +++ b/Mathlib/GroupTheory/Perm/DomMulAct.lean @@ -139,7 +139,7 @@ theorem stabilizer_card': rw [refl_apply, ← Subtype.coe_inj] simp only [φ, Set.val_codRestrict_apply] · intro g - simp only [Function.funext_iff] + simp only [funext_iff] apply forall_congr' intro a simp only [Function.comp_apply, φ, ← Subtype.coe_inj, Set.val_codRestrict_apply] diff --git a/Mathlib/GroupTheory/PushoutI.lean b/Mathlib/GroupTheory/PushoutI.lean index 47fa6da660134a..0f672f3da1e259 100644 --- a/Mathlib/GroupTheory/PushoutI.lean +++ b/Mathlib/GroupTheory/PushoutI.lean @@ -152,7 +152,7 @@ def homEquiv : invFun := fun f => lift f.1.1 f.1.2 f.2, left_inv := fun _ => hom_ext (by simp [DFunLike.ext_iff]) (by simp [DFunLike.ext_iff]) - right_inv := fun ⟨⟨_, _⟩, _⟩ => by simp [DFunLike.ext_iff, Function.funext_iff] } + right_inv := fun ⟨⟨_, _⟩, _⟩ => by simp [DFunLike.ext_iff, funext_iff] } /-- The map from the coproduct into the pushout -/ def ofCoprodI : CoprodI G →* PushoutI φ := @@ -596,7 +596,7 @@ theorem of_injective (hφ : ∀ i, Function.Injective (φ i)) (i : ι) : (f := ((· • ·) : PushoutI φ → NormalWord d → NormalWord d)) ?_ intros _ _ h exact eq_of_smul_eq_smul (fun w : NormalWord d => - by simp_all [Function.funext_iff, of_smul_eq_smul]) + by simp_all [funext_iff, of_smul_eq_smul]) theorem base_injective (hφ : ∀ i, Function.Injective (φ i)) : Function.Injective (base φ) := by @@ -607,7 +607,7 @@ theorem base_injective (hφ : ∀ i, Function.Injective (φ i)) : (f := ((· • ·) : PushoutI φ → NormalWord d → NormalWord d)) ?_ intros _ _ h exact eq_of_smul_eq_smul (fun w : NormalWord d => - by simp_all [Function.funext_iff, base_smul_eq_smul]) + by simp_all [funext_iff, base_smul_eq_smul]) section Reduced diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean index ef82d9e40a82ce..edeab9e15af306 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean @@ -703,7 +703,7 @@ theorem pi_comp (g : P3 →ᵃ[k] P1) : (pi fp).comp g = pi (fun i => (fp i).com rfl theorem pi_eq_zero : pi fv = 0 ↔ ∀ i, fv i = 0 := by - simp only [AffineMap.ext_iff, Function.funext_iff, pi_apply] + simp only [AffineMap.ext_iff, funext_iff, pi_apply] exact forall_comm theorem pi_zero : pi (fun _ ↦ 0 : (i : ι) → P1 →ᵃ[k] φv i) = 0 := by diff --git a/Mathlib/LinearAlgebra/AffineSpace/Independent.lean b/Mathlib/LinearAlgebra/AffineSpace/Independent.lean index 24d2fdd76c35b7..0fe67bc39f3f97 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Independent.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Independent.lean @@ -908,7 +908,7 @@ theorem centroid_eq_iff [CharZero k] {n : ℕ} (s : Simplex k P n) {fs₁ fs₂ (affineIndependent_iff_indicator_eq_of_affineCombination_eq k s.points).1 s.independent _ _ _ _ (fs₁.sum_centroidWeightsIndicator_eq_one_of_card_eq_add_one k h₁) (fs₂.sum_centroidWeightsIndicator_eq_one_of_card_eq_add_one k h₂) h - simp_rw [Finset.coe_univ, Set.indicator_univ, Function.funext_iff, + simp_rw [Finset.coe_univ, Set.indicator_univ, funext_iff, Finset.centroidWeightsIndicator_def, Finset.centroidWeights, h₁, h₂] at ha ext i specialize ha i diff --git a/Mathlib/LinearAlgebra/Dual.lean b/Mathlib/LinearAlgebra/Dual.lean index 5d556906e958ab..0dfa5a4d643f0c 100644 --- a/Mathlib/LinearAlgebra/Dual.lean +++ b/Mathlib/LinearAlgebra/Dual.lean @@ -1228,7 +1228,7 @@ instance (W : Submodule R M) : FunLike (W.dualAnnihilator) M R where coe φ := φ.val coe_injective' φ ψ h := by ext - simp only [Function.funext_iff] at h + simp only [funext_iff] at h exact h _ @[simp] diff --git a/Mathlib/LinearAlgebra/Matrix/DotProduct.lean b/Mathlib/LinearAlgebra/Matrix/DotProduct.lean index 3a313af6368d57..bb06aeea3eee8a 100644 --- a/Mathlib/LinearAlgebra/Matrix/DotProduct.lean +++ b/Mathlib/LinearAlgebra/Matrix/DotProduct.lean @@ -88,7 +88,7 @@ variable [Fintype m] [Fintype n] [Fintype p] @[simp] theorem dotProduct_self_eq_zero [LinearOrderedRing R] {v : n → R} : dotProduct v v = 0 ↔ v = 0 := (Finset.sum_eq_zero_iff_of_nonneg fun i _ => mul_self_nonneg (v i)).trans <| by - simp [Function.funext_iff] + simp [funext_iff] section StarOrderedRing @@ -110,13 +110,13 @@ variable [NoZeroDivisors R] @[simp] theorem dotProduct_star_self_eq_zero {v : n → R} : dotProduct (star v) v = 0 ↔ v = 0 := (Fintype.sum_eq_zero_iff_of_nonneg fun _ => star_mul_self_nonneg _).trans <| - by simp [Function.funext_iff, mul_eq_zero] + by simp [funext_iff, mul_eq_zero] /-- Note that this applies to `ℂ` via `RCLike.toStarOrderedRing`. -/ @[simp] theorem dotProduct_self_star_eq_zero {v : n → R} : dotProduct v (star v) = 0 ↔ v = 0 := (Fintype.sum_eq_zero_iff_of_nonneg fun _ => mul_star_self_nonneg _).trans <| - by simp [Function.funext_iff, mul_eq_zero] + by simp [funext_iff, mul_eq_zero] @[simp] lemma conjTranspose_mul_self_eq_zero {n} {A : Matrix m n R} : Aᴴ * A = 0 ↔ A = 0 := diff --git a/Mathlib/LinearAlgebra/Pi.lean b/Mathlib/LinearAlgebra/Pi.lean index 89740b2d0a89e1..079b058aab3d16 100644 --- a/Mathlib/LinearAlgebra/Pi.lean +++ b/Mathlib/LinearAlgebra/Pi.lean @@ -462,8 +462,8 @@ def piOptionEquivProd {ι : Type*} {M : Option ι → Type*} [(i : Option ι) [(i : Option ι) → Module R (M i)] : ((i : Option ι) → M i) ≃ₗ[R] M none × ((i : ι) → M (some i)) := { Equiv.piOptionEquivProd with - map_add' := by simp [Function.funext_iff] - map_smul' := by simp [Function.funext_iff] } + map_add' := by simp [funext_iff] + map_smul' := by simp [funext_iff] } variable (ι M) (S : Type*) [Fintype ι] [DecidableEq ι] [Semiring S] [AddCommMonoid M] [Module R M] [Module S M] [SMulCommClass R S M] diff --git a/Mathlib/LinearAlgebra/QuadraticForm/Prod.lean b/Mathlib/LinearAlgebra/QuadraticForm/Prod.lean index 891097a9ae0b61..20c4468b0c0514 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/Prod.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/Prod.lean @@ -303,7 +303,7 @@ theorem Equivalent.pi [Fintype ι] {Q : ∀ i, QuadraticMap R (Mᵢ i) P} /-- If a family is anisotropic then its components must be. The converse is not true. -/ theorem anisotropic_of_pi [Fintype ι] {Q : ∀ i, QuadraticMap R (Mᵢ i) P} (h : (pi Q).Anisotropic) : ∀ i, (Q i).Anisotropic := by - simp_rw [Anisotropic, pi_apply, Function.funext_iff, Pi.zero_apply] at h + simp_rw [Anisotropic, pi_apply, funext_iff, Pi.zero_apply] at h intro i x hx classical have := h (Pi.single i x) ?_ i diff --git a/Mathlib/Logic/Function/Basic.lean b/Mathlib/Logic/Function/Basic.lean index 131ecb1c0731d4..a7cb654f6a4e79 100644 --- a/Mathlib/Logic/Function/Basic.lean +++ b/Mathlib/Logic/Function/Basic.lean @@ -893,7 +893,7 @@ lemma forall_existsUnique_iff {r : α → β → Prop} : if and only if it is `(f · = ·)` for some function `f`. -/ lemma forall_existsUnique_iff' {r : α → β → Prop} : (∀ a, ∃! b, r a b) ↔ ∃ f : α → β, r = (f · = ·) := by - simp [forall_existsUnique_iff, Function.funext_iff] + simp [forall_existsUnique_iff, funext_iff] /-- A symmetric relation `r : α → α → Prop` is "function-like" (for each `a` there exists a unique `b` such that `r a b`) diff --git a/Mathlib/MeasureTheory/Measure/VectorMeasure.lean b/Mathlib/MeasureTheory/Measure/VectorMeasure.lean index d6bc3aa0248e0f..06d029fc3a63bc 100644 --- a/Mathlib/MeasureTheory/Measure/VectorMeasure.lean +++ b/Mathlib/MeasureTheory/Measure/VectorMeasure.lean @@ -96,7 +96,7 @@ theorem coe_injective : @Function.Injective (VectorMeasure α M) (Set α → M) congr theorem ext_iff' (v w : VectorMeasure α M) : v = w ↔ ∀ i : Set α, v i = w i := by - rw [← coe_injective.eq_iff, Function.funext_iff] + rw [← coe_injective.eq_iff, funext_iff] theorem ext_iff (v w : VectorMeasure α M) : v = w ↔ ∀ i : Set α, MeasurableSet i → v i = w i := by constructor diff --git a/Mathlib/ModelTheory/Basic.lean b/Mathlib/ModelTheory/Basic.lean index baa0ada8d42712..6846aee6eb65c7 100644 --- a/Mathlib/ModelTheory/Basic.lean +++ b/Mathlib/ModelTheory/Basic.lean @@ -379,7 +379,7 @@ instance funLike : FunLike (M ↪[L] N) M N where cases g congr ext x - exact Function.funext_iff.1 h x + exact funext_iff.1 h x instance embeddingLike : EmbeddingLike (M ↪[L] N) M N where injective' f := f.toEmbedding.injective @@ -416,7 +416,7 @@ theorem coe_injective : @Function.Injective (M ↪[L] N) (M → N) (↑) cases g congr ext x - exact Function.funext_iff.1 h x + exact funext_iff.1 h x @[ext] theorem ext ⦃f g : M ↪[L] N⦄ (h : ∀ x, f x = g x) : f = g := @@ -537,7 +537,7 @@ instance : EquivLike (M ≃[L] N) M N where cases g simp only [mk.injEq] ext x - exact Function.funext_iff.1 h₁ x + exact funext_iff.1 h₁ x instance : StrongHomClass L (M ≃[L] N) M N where map_fun := map_fun' diff --git a/Mathlib/ModelTheory/ElementaryMaps.lean b/Mathlib/ModelTheory/ElementaryMaps.lean index 54428842a22a51..f774228f18d50d 100644 --- a/Mathlib/ModelTheory/ElementaryMaps.lean +++ b/Mathlib/ModelTheory/ElementaryMaps.lean @@ -65,7 +65,7 @@ instance instFunLike : FunLike (M ↪ₑ[L] N) M N where cases g simp only [ElementaryEmbedding.mk.injEq] ext x - exact Function.funext_iff.1 h x + exact funext_iff.1 h x instance : CoeFun (M ↪ₑ[L] N) fun _ => M → N := DFunLike.hasCoeToFun diff --git a/Mathlib/ModelTheory/Syntax.lean b/Mathlib/ModelTheory/Syntax.lean index 24c9794e5cfbdb..a70ace4f16815b 100644 --- a/Mathlib/ModelTheory/Syntax.lean +++ b/Mathlib/ModelTheory/Syntax.lean @@ -85,7 +85,7 @@ instance instDecidableEq [DecidableEq α] [∀ n, DecidableEq (L.Functions n)] : letI : DecidableEq (L.Term α) := instDecidableEq decidable_of_iff (f = h ▸ g ∧ ∀ i : Fin m, xs i = ys (Fin.cast h i)) <| by subst h - simp [Function.funext_iff] + simp [funext_iff] else .isFalse <| by simp [h] | .var _, .func _ _ | .func _ _, .var _ => .isFalse <| by simp diff --git a/Mathlib/NumberTheory/NumberField/House.lean b/Mathlib/NumberTheory/NumberField/House.lean index d56eb4d18c6684..18b9930964456c 100644 --- a/Mathlib/NumberTheory/NumberField/House.lean +++ b/Mathlib/NumberTheory/NumberField/House.lean @@ -132,7 +132,7 @@ include ha in private theorem asiegel_ne_0 : asiegel K a ≠ 0 := by simp (config := { unfoldPartialApp := true }) only [asiegel, a'] simp only [ne_eq] - rw [Function.funext_iff]; intros hs + rw [funext_iff]; intros hs simp only [Prod.forall] at hs; apply ha rw [← Matrix.ext_iff]; intros k' l @@ -141,7 +141,7 @@ private theorem asiegel_ne_0 : asiegel K a ≠ 0 := by have := ((newBasis K).repr.map_eq_zero_iff (x := (a k' l * (newBasis K) b))).1 <| by ext b' specialize hs b' - rw [Function.funext_iff] at hs + rw [funext_iff] at hs simp only [Prod.forall] at hs apply hs simp only [mul_eq_zero] at this @@ -157,7 +157,7 @@ private theorem ξ_ne_0 : ξ K x ≠ 0 := by intro H apply hxl ext ⟨l, r⟩ - rw [Function.funext_iff] at H + rw [funext_iff] at H have hblin := Basis.linearIndependent (newBasis K) simp only [zsmul_eq_mul, Fintype.linearIndependent_iff] at hblin exact hblin (fun r ↦ x (l,r)) (H _) r @@ -175,9 +175,9 @@ private theorem ξ_mulVec_eq_0 : a *ᵥ ξ K x = 0 := by have lin_0 : ∀ u, ∑ r, ∑ l, (a' K a k l r u * x (l, r) : 𝓞 K) = 0 := by intros u have hξ := ξ_ne_0 K x hxl - rw [Ne, Function.funext_iff, not_forall] at hξ + rw [Ne, funext_iff, not_forall] at hξ rcases hξ with ⟨l, hξ⟩ - rw [Function.funext_iff] at hmulvec0 + rw [funext_iff] at hmulvec0 specialize hmulvec0 ⟨k, u⟩ simp only [Fintype.sum_prod_type, mulVec, dotProduct, asiegel] at hmulvec0 rw [sum_comm] at hmulvec0 diff --git a/Mathlib/Order/RelSeries.lean b/Mathlib/Order/RelSeries.lean index d01a0e54fc8eef..b2c41395b294b7 100644 --- a/Mathlib/Order/RelSeries.lean +++ b/Mathlib/Order/RelSeries.lean @@ -704,7 +704,7 @@ def injStrictMono (n : ℕ) : simp_rw [Subtype.mk_eq_mk, Sigma.mk.inj_iff, heq_eq_eq, true_and] have feq := fun i ↦ congr($(e).toFun i) simp_rw [mk_toFun lf f mf, mk_toFun lf g mg, mk_length lf f mf] at feq - rwa [Function.funext_iff] + rwa [funext_iff] /-- For two preorders `α, β`, if `f : α → β` is strictly monotonic, then a strict chain of `α` diff --git a/Mathlib/Probability/ProbabilityMassFunction/Basic.lean b/Mathlib/Probability/ProbabilityMassFunction/Basic.lean index a28a889e12f1a1..14593d136558ba 100644 --- a/Mathlib/Probability/ProbabilityMassFunction/Basic.lean +++ b/Mathlib/Probability/ProbabilityMassFunction/Basic.lean @@ -165,7 +165,7 @@ theorem toOuterMeasure_inj {p q : PMF α} : p.toOuterMeasure = q.toOuterMeasure theorem toOuterMeasure_apply_eq_zero_iff : p.toOuterMeasure s = 0 ↔ Disjoint p.support s := by rw [toOuterMeasure_apply, ENNReal.tsum_eq_zero] - exact Function.funext_iff.symm.trans Set.indicator_eq_zero' + exact funext_iff.symm.trans Set.indicator_eq_zero' theorem toOuterMeasure_apply_eq_one_iff : p.toOuterMeasure s = 1 ↔ p.support ⊆ s := by refine (p.toOuterMeasure_apply s).symm ▸ ⟨fun h a hap => ?_, fun h => ?_⟩ diff --git a/Mathlib/RepresentationTheory/GroupCohomology/LowDegree.lean b/Mathlib/RepresentationTheory/GroupCohomology/LowDegree.lean index c2cc073aa0dca2..e5fead4c21a6df 100644 --- a/Mathlib/RepresentationTheory/GroupCohomology/LowDegree.lean +++ b/Mathlib/RepresentationTheory/GroupCohomology/LowDegree.lean @@ -98,7 +98,7 @@ def dZero : A →ₗ[k] G → A where theorem dZero_ker_eq_invariants : LinearMap.ker (dZero A) = invariants A.ρ := by ext x - simp only [LinearMap.mem_ker, mem_invariants, ← @sub_eq_zero _ _ _ x, Function.funext_iff] + simp only [LinearMap.mem_ker, mem_invariants, ← @sub_eq_zero _ _ _ x, funext_iff] rfl @[simp] theorem dZero_eq_zero [A.IsTrivial] : dZero A = 0 := by @@ -226,7 +226,7 @@ variable {A} theorem mem_oneCocycles_def (f : G → A) : f ∈ oneCocycles A ↔ ∀ g h : G, A.ρ g (f h) - f (g * h) + f g = 0 := LinearMap.mem_ker.trans <| by - rw [Function.funext_iff] + rw [funext_iff] simp only [dOne_apply, Pi.zero_apply, Prod.forall] theorem mem_oneCocycles_iff (f : G → A) : @@ -277,7 +277,7 @@ theorem mem_twoCocycles_def (f : G × G → A) : f ∈ twoCocycles A ↔ ∀ g h j : G, A.ρ g (f (h, j)) - f (g * h, j) + f (g, h * j) - f (g, h) = 0 := LinearMap.mem_ker.trans <| by - rw [Function.funext_iff] + rw [funext_iff] simp only [dTwo_apply, Prod.mk.eta, Pi.zero_apply, Prod.forall] theorem mem_twoCocycles_iff (f : G × G → A) : @@ -491,7 +491,7 @@ def twoCoboundariesOfIsTwoCoboundary {f : G × G → A} (hf : IsTwoCoboundary f) theorem isTwoCoboundary_of_twoCoboundaries (f : twoCoboundaries (Rep.ofDistribMulAction k G A)) : IsTwoCoboundary (A := A) f.1.1 := by rcases mem_range_of_mem_twoCoboundaries f.2 with ⟨x, hx⟩ - exact ⟨x, fun g h => Function.funext_iff.1 hx (g, h)⟩ + exact ⟨x, fun g h => funext_iff.1 hx (g, h)⟩ end ofDistribMulAction @@ -616,7 +616,7 @@ theorem isMulTwoCoboundary_of_twoCoboundaries (f : twoCoboundaries (Rep.ofMulDistribMulAction G M)) : IsMulTwoCoboundary (M := M) (Additive.toMul ∘ f.1.1) := by rcases mem_range_of_mem_twoCoboundaries f.2 with ⟨x, hx⟩ - exact ⟨x, fun g h => Function.funext_iff.1 hx (g, h)⟩ + exact ⟨x, fun g h => funext_iff.1 hx (g, h)⟩ end ofMulDistribMulAction diff --git a/Mathlib/RingTheory/HahnSeries/Addition.lean b/Mathlib/RingTheory/HahnSeries/Addition.lean index 61a63a5fceb4a0..3daeb21892dcef 100644 --- a/Mathlib/RingTheory/HahnSeries/Addition.lean +++ b/Mathlib/RingTheory/HahnSeries/Addition.lean @@ -102,7 +102,7 @@ lemma addOppositeEquiv_orderTop (x : HahnSeries Γ (Rᵃᵒᵖ)) : simp only [orderTop, AddOpposite.unop_op, mk_eq_zero, AddEquivClass.map_eq_zero_iff, addOppositeEquiv_support, ne_eq] simp only [addOppositeEquiv_apply, AddOpposite.unop_op, mk_eq_zero, zero_coeff] - simp_rw [HahnSeries.ext_iff, Function.funext_iff] + simp_rw [HahnSeries.ext_iff, funext_iff] simp only [Pi.zero_apply, AddOpposite.unop_eq_zero_iff, zero_coeff] @[simp] @@ -116,7 +116,7 @@ lemma addOppositeEquiv_leadingCoeff (x : HahnSeries Γ (Rᵃᵒᵖ)) : simp only [leadingCoeff, AddOpposite.unop_op, mk_eq_zero, AddEquivClass.map_eq_zero_iff, addOppositeEquiv_support, ne_eq] simp only [addOppositeEquiv_apply, AddOpposite.unop_op, mk_eq_zero, zero_coeff] - simp_rw [HahnSeries.ext_iff, Function.funext_iff] + simp_rw [HahnSeries.ext_iff, funext_iff] simp only [Pi.zero_apply, AddOpposite.unop_eq_zero_iff, zero_coeff] split <;> rfl diff --git a/Mathlib/RingTheory/HahnSeries/Basic.lean b/Mathlib/RingTheory/HahnSeries/Basic.lean index b063204680d7fd..29586b2758fadb 100644 --- a/Mathlib/RingTheory/HahnSeries/Basic.lean +++ b/Mathlib/RingTheory/HahnSeries/Basic.lean @@ -427,7 +427,7 @@ theorem embDomain_single {f : Γ ↪o Γ'} {g : Γ} {r : R} : theorem embDomain_injective {f : Γ ↪o Γ'} : Function.Injective (embDomain f : HahnSeries Γ R → HahnSeries Γ' R) := fun x y xy => by ext g - rw [HahnSeries.ext_iff, Function.funext_iff] at xy + rw [HahnSeries.ext_iff, funext_iff] at xy have xyg := xy (f g) rwa [embDomain_coeff, embDomain_coeff] at xyg diff --git a/Mathlib/RingTheory/HahnSeries/Multiplication.lean b/Mathlib/RingTheory/HahnSeries/Multiplication.lean index 153ac24993c5d2..11ac4db05c9d90 100644 --- a/Mathlib/RingTheory/HahnSeries/Multiplication.lean +++ b/Mathlib/RingTheory/HahnSeries/Multiplication.lean @@ -535,7 +535,7 @@ instance instNoZeroSMulDivisors {Γ} [LinearOrderedCancelAddCommMonoid Γ] [Zero eq_zero_or_eq_zero_of_smul_eq_zero {x y} hxy := by contrapose! hxy simp only [ne_eq] - rw [HahnModule.ext_iff, Function.funext_iff, not_forall] + rw [HahnModule.ext_iff, funext_iff, not_forall] refine ⟨x.order + ((of R).symm y).order, ?_⟩ rw [smul_coeff_order_add_order x y, of_symm_zero, HahnSeries.zero_coeff, smul_eq_zero, not_or] constructor @@ -644,7 +644,7 @@ theorem C_one : C (1 : R) = (1 : HahnSeries Γ R) := theorem C_injective : Function.Injective (C : R → HahnSeries Γ R) := by intro r s rs - rw [HahnSeries.ext_iff, Function.funext_iff] at rs + rw [HahnSeries.ext_iff, funext_iff] at rs have h := rs 0 rwa [C_apply, single_coeff_same, C_apply, single_coeff_same] at h @@ -756,7 +756,7 @@ instance [Nontrivial Γ] [Nontrivial R] : Nontrivial (Subalgebra R (HahnSeries refine ⟨single a 1, ?_⟩ simp only [Algebra.mem_bot, not_exists, Set.mem_range, iff_true, Algebra.mem_top] intro x - rw [HahnSeries.ext_iff, Function.funext_iff, not_forall] + rw [HahnSeries.ext_iff, funext_iff, not_forall] refine ⟨a, ?_⟩ rw [single_coeff_same, algebraMap_apply, C_apply, single_coeff_of_ne ha] exact zero_ne_one⟩⟩ diff --git a/Mathlib/RingTheory/Ideal/Maps.lean b/Mathlib/RingTheory/Ideal/Maps.lean index 687a565ce36b9d..faa5fc206c934d 100644 --- a/Mathlib/RingTheory/Ideal/Maps.lean +++ b/Mathlib/RingTheory/Ideal/Maps.lean @@ -570,7 +570,7 @@ theorem ker_ne_top [Nontrivial S] (f : F) : ker f ≠ ⊤ := lemma _root_.Pi.ker_ringHom {ι : Type*} {R : ι → Type*} [∀ i, Semiring (R i)] (φ : ∀ i, S →+* R i) : ker (Pi.ringHom φ) = ⨅ i, ker (φ i) := by ext x - simp [mem_ker, Ideal.mem_iInf, Function.funext_iff] + simp [mem_ker, Ideal.mem_iInf, funext_iff] @[simp] theorem ker_rangeSRestrict (f : R →+* S) : ker f.rangeSRestrict = ker f := diff --git a/Mathlib/RingTheory/Idempotents.lean b/Mathlib/RingTheory/Idempotents.lean index c2dd1724dad6fe..958157f3ad00b8 100644 --- a/Mathlib/RingTheory/Idempotents.lean +++ b/Mathlib/RingTheory/Idempotents.lean @@ -402,7 +402,7 @@ lemma CompleteOrthogonalIdempotents.bijective_pi (he : CompleteOrthogonalIdempot refine ⟨?_, he.1.surjective_pi⟩ rw [injective_iff_map_eq_zero] intro x hx - simp [Function.funext_iff, Ideal.Quotient.eq_zero_iff_mem, Ideal.mem_span_singleton] at hx + simp [funext_iff, Ideal.Quotient.eq_zero_iff_mem, Ideal.mem_span_singleton] at hx suffices ∀ s : Finset I, (∏ i in s, (1 - e i)) * x = x by rw [← this Finset.univ, he.prod_one_sub, zero_mul] refine fun s ↦ Finset.induction_on s (by simp) ?_ diff --git a/Mathlib/RingTheory/WittVector/Defs.lean b/Mathlib/RingTheory/WittVector/Defs.lean index 53b4f06f4f2d88..50034046601423 100644 --- a/Mathlib/RingTheory/WittVector/Defs.lean +++ b/Mathlib/RingTheory/WittVector/Defs.lean @@ -72,7 +72,7 @@ theorem ext {x y : 𝕎 R} (h : ∀ n, x.coeff n = y.coeff n) : x = y := by cases x cases y simp only at h - simp [Function.funext_iff, h] + simp [funext_iff, h] variable (p) diff --git a/Mathlib/RingTheory/WittVector/IsPoly.lean b/Mathlib/RingTheory/WittVector/IsPoly.lean index da0cac3cda9426..69617badd66945 100644 --- a/Mathlib/RingTheory/WittVector/IsPoly.lean +++ b/Mathlib/RingTheory/WittVector/IsPoly.lean @@ -113,7 +113,7 @@ theorem poly_eq_of_wittPolynomial_bind_eq' [Fact p.Prime] (f g : ℕ → MvPolyn (h : ∀ n, bind₁ f (wittPolynomial p _ n) = bind₁ g (wittPolynomial p _ n)) : f = g := by ext1 n apply MvPolynomial.map_injective (Int.castRingHom ℚ) Int.cast_injective - rw [← Function.funext_iff] at h + rw [← funext_iff] at h replace h := congr_arg (fun fam => bind₁ (MvPolynomial.map (Int.castRingHom ℚ) ∘ fam) (xInTermsOfW p ℚ n)) h simpa only [Function.comp_def, map_bind₁, map_wittPolynomial, ← bind₁_bind₁, @@ -123,7 +123,7 @@ theorem poly_eq_of_wittPolynomial_bind_eq [Fact p.Prime] (f g : ℕ → MvPolyno (h : ∀ n, bind₁ f (wittPolynomial p _ n) = bind₁ g (wittPolynomial p _ n)) : f = g := by ext1 n apply MvPolynomial.map_injective (Int.castRingHom ℚ) Int.cast_injective - rw [← Function.funext_iff] at h + rw [← funext_iff] at h replace h := congr_arg (fun fam => bind₁ (MvPolynomial.map (Int.castRingHom ℚ) ∘ fam) (xInTermsOfW p ℚ n)) h simpa only [Function.comp_def, map_bind₁, map_wittPolynomial, ← bind₁_bind₁, diff --git a/Mathlib/Topology/Algebra/Module/Basic.lean b/Mathlib/Topology/Algebra/Module/Basic.lean index 1ed9c07b215fed..3a3b76145aaeba 100644 --- a/Mathlib/Topology/Algebra/Module/Basic.lean +++ b/Mathlib/Topology/Algebra/Module/Basic.lean @@ -1134,7 +1134,7 @@ theorem pi_apply (f : ∀ i, M →L[R] φ i) (c : M) (i : ι) : pi f c i = f i c rfl theorem pi_eq_zero (f : ∀ i, M →L[R] φ i) : pi f = 0 ↔ ∀ i, f i = 0 := by - simp only [ContinuousLinearMap.ext_iff, pi_apply, Function.funext_iff] + simp only [ContinuousLinearMap.ext_iff, pi_apply, funext_iff] exact forall_swap theorem pi_zero : pi (fun _ => 0 : ∀ i, M →L[R] φ i) = 0 := diff --git a/Mathlib/Topology/Homotopy/Product.lean b/Mathlib/Topology/Homotopy/Product.lean index a898bde525861e..cc848a691b5043 100644 --- a/Mathlib/Topology/Homotopy/Product.lean +++ b/Mathlib/Topology/Homotopy/Product.lean @@ -72,7 +72,7 @@ def HomotopyRel.pi (homotopies : ∀ i : I, HomotopyRel (f i) (g i) S) : prop' := by intro t x hx dsimp only [coe_mk, pi_eval, toFun_eq_coe, HomotopyWith.coe_toContinuousMap] - simp only [Function.funext_iff, ← forall_and] + simp only [funext_iff, ← forall_and] intro i exact (homotopies i).prop' t x hx } diff --git a/Mathlib/Topology/LocallyConstant/Basic.lean b/Mathlib/Topology/LocallyConstant/Basic.lean index 401cf78da5d19a..916e783447b5b0 100644 --- a/Mathlib/Topology/LocallyConstant/Basic.lean +++ b/Mathlib/Topology/LocallyConstant/Basic.lean @@ -358,7 +358,7 @@ def unflip {X α β : Type*} [Finite α] [TopologicalSpace X] (f : α → Locall toFun x a := f a x isLocallyConstant := IsLocallyConstant.iff_isOpen_fiber.2 fun g => by have : (fun (x : X) (a : α) => f a x) ⁻¹' {g} = ⋂ a : α, f a ⁻¹' {g a} := by - ext; simp [Function.funext_iff] + ext; simp [funext_iff] rw [this] exact isOpen_iInter_of_finite fun a => (f a).isLocallyConstant _ diff --git a/Mathlib/Topology/TietzeExtension.lean b/Mathlib/Topology/TietzeExtension.lean index c707446315731c..9a2271b7f12022 100644 --- a/Mathlib/Topology/TietzeExtension.lean +++ b/Mathlib/Topology/TietzeExtension.lean @@ -321,7 +321,7 @@ theorem exists_extension_forall_exists_le_ge_of_closedEmbedding [Nonempty X] (f rcases hle.eq_or_lt with (rfl | hlt) · have : ∀ x, f x = a := by simpa using hmem use const Y a - simp [this, Function.funext_iff] + simp [this, funext_iff] -- Put `c = (a + b) / 2`. Then `a < c < b` and `c - a = b - c`. set c := (a + b) / 2 have hac : a < c := left_lt_add_div_two.2 hlt diff --git a/test/instance_diamonds.lean b/test/instance_diamonds.lean index f26a6b719c7ffd..8ced918dadd0da 100644 --- a/test/instance_diamonds.lean +++ b/test/instance_diamonds.lean @@ -153,7 +153,7 @@ 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) intro h - simp only [SMul.ext_iff, @SMul.smul_eq_hSMul _ _ (_), Function.funext_iff, DFunLike.ext_iff] at 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 classical rw [comapSMul_single, smul_apply, smul_eq_mul, mul_one, single_eq_same, smul_eq_mul, @@ -167,7 +167,7 @@ example {k : Type _} [Semiring k] [Nontrivial kˣ] : obtain ⟨u : kˣ, hu⟩ := exists_ne (1 : kˣ) haveI : Nontrivial k := ⟨⟨u, 1, Units.ext.ne hu⟩⟩ intro h - simp only [SMul.ext_iff, @SMul.smul_eq_hSMul _ _ (_), Function.funext_iff, DFunLike.ext_iff] at 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 classical rw [comapSMul_single, smul_apply, Units.smul_def, smul_eq_mul, mul_one, single_eq_same, @@ -191,14 +191,14 @@ open Polynomial example [Semiring R] [Nontrivial R] : Polynomial.hasSMulPi _ _ ≠ (Pi.instSMul : SMul R[X] (R → R[X])) := by intro h - simp_rw [SMul.ext_iff, @SMul.smul_eq_hSMul _ _ (_), Function.funext_iff, Polynomial.ext_iff] at h + simp_rw [SMul.ext_iff, @SMul.smul_eq_hSMul _ _ (_), funext_iff, Polynomial.ext_iff] at h simpa using h X 1 1 0 /-- `Polynomial.hasSMulPi'` forms a diamond with `Pi.instSMul`. -/ example [CommSemiring R] [Nontrivial R] : Polynomial.hasSMulPi' _ _ _ ≠ (Pi.instSMul : SMul R[X] (R → R[X])) := by intro h - simp_rw [SMul.ext_iff, @SMul.smul_eq_hSMul _ _ (_), Function.funext_iff, Polynomial.ext_iff] at h + simp_rw [SMul.ext_iff, @SMul.smul_eq_hSMul _ _ (_), funext_iff, Polynomial.ext_iff] at h simpa using h X 1 1 0 -- fails `with_reducible_and_instances` #10906 From 0e689acf472c726630c8cf86b71c73bcd7f48f28 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 15:46:45 +1100 Subject: [PATCH 262/425] revert some changes --- Mathlib/Data/List/Join.lean | 4 ++-- Mathlib/Data/List/Permutation.lean | 6 ++---- Mathlib/Data/List/Range.lean | 1 - 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Mathlib/Data/List/Join.lean b/Mathlib/Data/List/Join.lean index 06de9847135582..8c6ed6907be8b1 100644 --- a/Mathlib/Data/List/Join.lean +++ b/Mathlib/Data/List/Join.lean @@ -60,7 +60,7 @@ theorem take_sum_flatten' (L : List (List α)) (i : ℕ) : L.flatten.take (Nat.sum ((L.map length).take i)) = (L.take i).flatten := by induction L generalizing i · simp - · cases i <;> simp [take_append, *, Nat.sum_nil, Nat.sum_cons] + · cases i <;> simp [take_append, *] @[deprecated (since := "2024-10-25")] alias take_sum_join' := take_sum_flatten' @@ -72,7 +72,7 @@ theorem drop_sum_flatten' (L : List (List α)) (i : ℕ) : L.flatten.drop (Nat.sum ((L.map length).take i)) = (L.drop i).flatten := by induction L generalizing i · simp - · cases i <;> simp [drop_append, *, Nat.sum_nil, Nat.sum_cons] + · cases i <;> simp [drop_append, *] @[deprecated (since := "2024-10-25")] alias drop_sum_join' := drop_sum_flatten' diff --git a/Mathlib/Data/List/Permutation.lean b/Mathlib/Data/List/Permutation.lean index 7ee0c30e78a5aa..f03f62f158c499 100644 --- a/Mathlib/Data/List/Permutation.lean +++ b/Mathlib/Data/List/Permutation.lean @@ -187,22 +187,20 @@ theorem mem_foldr_permutationsAux2 {t : α} {ts : List α} {r L : List (List α) simp only [mem_permutationsAux2', ← this, or_comm, and_left_comm, mem_append, mem_bind, append_assoc, cons_append, exists_prop] -set_option linter.deprecated false in theorem length_foldr_permutationsAux2 (t : α) (ts : List α) (r L : List (List α)) : length (foldr (fun y r => (permutationsAux2 t ts r y id).2) r L) = Nat.sum (map length L) + length r := by simp [foldr_permutationsAux2, Function.comp_def, length_permutationsAux2, length_bind'] -set_option linter.deprecated false in theorem length_foldr_permutationsAux2' (t : α) (ts : List α) (r L : List (List α)) (n) (H : ∀ l ∈ L, length l = n) : length (foldr (fun y r => (permutationsAux2 t ts r y id).2) r L) = n * length L + length r := by rw [length_foldr_permutationsAux2, (_ : Nat.sum (map length L) = n * length L)] induction' L with l L ih - · simp [Nat.sum_nil] + · simp have sum_map : Nat.sum (map length L) = n * length L := ih fun l m => H l (mem_cons_of_mem _ m) have length_l : length l = n := H _ (mem_cons_self _ _) - simp [sum_map, length_l, Nat.mul_add, Nat.add_comm, mul_succ, Nat.sum_cons] + simp [sum_map, length_l, Nat.mul_add, Nat.add_comm, mul_succ] @[simp] theorem permutationsAux_nil (is : List α) : permutationsAux [] is = [] := by diff --git a/Mathlib/Data/List/Range.lean b/Mathlib/Data/List/Range.lean index 874f3b958de269..f1e03a895c1e49 100644 --- a/Mathlib/Data/List/Range.lean +++ b/Mathlib/Data/List/Range.lean @@ -148,7 +148,6 @@ lemma ranges_flatten' : ∀ l : List ℕ, l.ranges.flatten = range (Nat.sum l) @[deprecated (since := "2024-10-15")] alias ranges_join' := ranges_flatten' -set_option linter.deprecated false in /-- Any entry of any member of `l.ranges` is strictly smaller than `Nat.sum l`. See `List.mem_mem_ranges_iff_lt_sum` for the version about `List.sum`. -/ lemma mem_mem_ranges_iff_lt_natSum (l : List ℕ) {n : ℕ} : From b6b41ed9f31f5ce6a657f699439698ae4a4439e4 Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Thu, 17 Oct 2024 05:14:29 +0000 Subject: [PATCH 263/425] Update lean-toolchain for testing https://github.com/leanprover/lean4/pull/5746 --- lake-manifest.json | 4 ++-- lakefile.lean | 2 +- lean-toolchain | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index ec4819dd4811ac..ef031f34157789 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,10 +5,10 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "acc9722fa789363b2c7cd0c0e3ee69a9048b459a", + "rev": "202d2e8b271e0f48b3e70533c7e2dbe44725479e", "name": "batteries", "manifestFile": "lake-manifest.json", - "inputRev": "nightly-testing", + "inputRev": "lean-pr-testing-5746", "inherited": false, "configFile": "lakefile.lean"}, {"url": "https://github.com/leanprover-community/quote4", diff --git a/lakefile.lean b/lakefile.lean index bb806c24f85559..13dcf29bcf9645 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -7,7 +7,7 @@ open Lake DSL ## Mathlib dependencies on upstream projects -/ -require "leanprover-community" / "batteries" @ git "nightly-testing" +require "leanprover-community" / "batteries" @ git "lean-pr-testing-5746" require "leanprover-community" / "Qq" @ git "master" require "leanprover-community" / "aesop" @ git "nightly-testing" require "leanprover-community" / "proofwidgets" @ git "v0.0.44-pre" diff --git a/lean-toolchain b/lean-toolchain index c7e012c64aaed0..f77d9d498b979f 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-16 +leanprover/lean4-pr-releases:pr-release-5746 From 91529560a9b0d0b1da0991450f5b1e2584ad5493 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 05:23:32 +0000 Subject: [PATCH 264/425] chore: cleanup in Data/String/Basic (#17846) --- Mathlib/Data/String/Basic.lean | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Mathlib/Data/String/Basic.lean b/Mathlib/Data/String/Basic.lean index 6d86ef5ed7a826..d77a4e02a1f334 100644 --- a/Mathlib/Data/String/Basic.lean +++ b/Mathlib/Data/String/Basic.lean @@ -6,7 +6,6 @@ Authors: Mario Carneiro import Batteries.Data.String.Lemmas import Mathlib.Data.List.Lex import Mathlib.Data.Char -import Mathlib.Tactic.AdaptationNote import Mathlib.Algebra.Order.Group.Nat /-! @@ -17,6 +16,8 @@ Supplementary theorems about the `String` type. namespace String +@[simp] theorem endPos_empty : "".endPos = 0 := rfl + /-- `<` on string iterators. This coincides with `<` on strings as lists. -/ def ltb (s₁ s₂ : Iterator) : Bool := if s₂.hasNext then @@ -76,13 +77,11 @@ theorem lt_iff_toList_lt : ∀ {s₁ s₂ : String}, s₁ < s₂ ↔ s₁.toList · unfold ltb; decide · rename_i c₂ cs₂; apply iff_of_true · unfold ltb - #adaptation_note /-- v4.7.0-rc1 exclude reduceMk from simp -/ - simp [-reduceMk, Iterator.hasNext, Char.utf8Size_pos] + simp [Iterator.hasNext, Char.utf8Size_pos] · apply List.nil_lt_cons · rename_i c₁ cs₁ ih; apply iff_of_false · unfold ltb - #adaptation_note /-- v4.7.0-rc1 exclude reduceMk from simp -/ - simp [-reduceMk, Iterator.hasNext] + simp [Iterator.hasNext] · apply not_lt_of_lt; apply List.nil_lt_cons · rename_i c₁ cs₁ ih c₂ cs₂; unfold ltb simp only [Iterator.hasNext, Pos.byteIdx_zero, endPos, utf8ByteSize, utf8ByteSize.go, From 6abb96a271c94a4866460bc6cff5bdbaf33e42fd Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 16:58:44 +1100 Subject: [PATCH 265/425] bump batteries for leanprover/lean4#5746 --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index ef031f34157789..127b8db21bfc4c 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "202d2e8b271e0f48b3e70533c7e2dbe44725479e", + "rev": "7247feec5ef25dd66f2eaf847e95fd02d077fb8c", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "lean-pr-testing-5746", From 95d4d082bb8466eae74c9aacbc8f4af7f45fc320 Mon Sep 17 00:00:00 2001 From: mathlib4-update-dependencies-bot <150093616+mathlib-bors@users.noreply.github.com> Date: Thu, 17 Oct 2024 06:03:15 +0000 Subject: [PATCH 266/425] chore: update Mathlib dependencies 2024-10-17 (#17852) 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 d4790a02b8a62f..968440a4a1bb73 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "422d1a5f608fccafeddab9748e8038ef346b59bf", + "rev": "d011c00010429728fab0bb3675b13f4bce63539e", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 85ed7203205500c2398c798b6695f0b0fcc22f8b Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 17:17:35 +1100 Subject: [PATCH 267/425] fixes for leanprover/lean4#5746 --- Mathlib/Algebra/BigOperators/Group/List.lean | 30 ++++++++++++++++---- Mathlib/Data/List/Join.lean | 19 +++++++++++++ Mathlib/Data/List/ProdSigma.lean | 2 ++ Mathlib/Data/List/Range.lean | 6 ++-- 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Group/List.lean b/Mathlib/Algebra/BigOperators/Group/List.lean index 127d0e01260bc3..d5b9c7230c86d4 100644 --- a/Mathlib/Algebra/BigOperators/Group/List.lean +++ b/Mathlib/Algebra/BigOperators/Group/List.lean @@ -636,14 +636,25 @@ end MonoidHom end MonoidHom -@[simp] lemma Nat.sum_eq_listSum (l : List ℕ) : Nat.sum l = l.sum := rfl +set_option linter.deprecated false in +@[simp, deprecated (since := "2024-10-17")] +lemma Nat.sum_eq_listSum (l : List ℕ) : Nat.sum l = l.sum := rfl namespace List lemma length_sigma {σ : α → Type*} (l₁ : List α) (l₂ : ∀ a, List (σ a)) : - length (l₁.sigma l₂) = (l₁.map fun a ↦ length (l₂ a)).sum := by simp [length_sigma'] + length (l₁.sigma l₂) = (l₁.map fun a ↦ length (l₂ a)).sum := by + induction' l₁ with x l₁ IH + · rfl + · simp only [sigma_cons, length_append, length_map, IH, map, sum_cons] -lemma ranges_flatten (l : List ℕ) : l.ranges.flatten = range l.sum := by simp [ranges_flatten'] +lemma ranges_flatten : ∀ (l : List ℕ), l.ranges.flatten = range l.sum + | [] => rfl + | a :: l => by simp only [flatten, ← map_flatten, ranges_flatten, sum_cons, range_add] + +/-- The members of `l.ranges` have no duplicate -/ +theorem ranges_nodup {l s : List ℕ} (hs : s ∈ ranges l) : s.Nodup := + (List.pairwise_flatten.mp <| by rw [ranges_flatten]; exact nodup_range _).1 s hs @[deprecated (since := "2024-10-15")] alias ranges_join := ranges_flatten @@ -667,7 +678,9 @@ lemma count_bind [BEq β] (l : List α) (f : α → List β) (x : β) : first `i` sublists, is the same as taking the flatten of the first `i` sublists. -/ lemma take_sum_flatten (L : List (List α)) (i : ℕ) : L.flatten.take ((L.map length).take i).sum = (L.take i).flatten := by - simpa using take_sum_flatten' _ _ + induction L generalizing i + · simp + · cases i <;> simp [take_append, *] @[deprecated (since := "2024-10-15")] alias take_sum_join := take_sum_flatten @@ -675,7 +688,9 @@ lemma take_sum_flatten (L : List (List α)) (i : ℕ) : first `i` sublists, is the same as taking the join after dropping the first `i` sublists. -/ lemma drop_sum_flatten (L : List (List α)) (i : ℕ) : L.flatten.drop ((L.map length).take i).sum = (L.drop i).flatten := by - simpa using drop_sum_flatten' _ _ + induction L generalizing i + · simp + · cases i <;> simp [take_append, *] @[deprecated (since := "2024-10-15")] alias drop_sum_join := drop_sum_flatten @@ -684,7 +699,10 @@ original sublist of index `i` if `A` is the sum of the lengths of sublists of in `B` is the sum of the lengths of sublists of index `≤ i`. -/ lemma drop_take_succ_flatten_eq_getElem (L : List (List α)) (i : Nat) (h : i < L.length) : (L.flatten.take ((L.map length).take (i + 1)).sum).drop ((L.map length).take i).sum = L[i] := by - simpa using drop_take_succ_flatten_eq_getElem' _ _ _ + have : (L.map length).take i = ((L.take (i + 1)).map length).take i := by + simp [map_take, take_take, Nat.min_eq_left] + simp only [this, length_map, take_sum_flatten, drop_sum_flatten, + drop_take_succ_eq_cons_getElem, h, flatten, append_nil] @[deprecated (since := "2024-06-11")] alias drop_take_succ_join_eq_getElem := drop_take_succ_flatten_eq_getElem diff --git a/Mathlib/Data/List/Join.lean b/Mathlib/Data/List/Join.lean index 06de9847135582..c4167a250dc9fb 100644 --- a/Mathlib/Data/List/Join.lean +++ b/Mathlib/Data/List/Join.lean @@ -19,13 +19,17 @@ variable {α β : Type*} namespace List +set_option linter.deprecated false in /-- See `List.length_flatten` for the corresponding statement using `List.sum`. -/ +@[deprecated length_flatten (since := "2024-10-17")] lemma length_flatten' (L : List (List α)) : length (flatten L) = Nat.sum (map length L) := by induction L <;> [rfl; simp only [*, flatten, map, Nat.sum_cons, length_append]] @[deprecated (since := "2024-10-25")] alias length_join' := length_flatten' +set_option linter.deprecated false in /-- See `List.countP_flatten` for the corresponding statement using `List.sum`. -/ +@[deprecated countP_flatten (since := "2024-10-17")] lemma countP_flatten' (p : α → Bool) : ∀ L : List (List α), countP p L.flatten = Nat.sum (L.map (countP p)) | [] => rfl @@ -33,29 +37,39 @@ lemma countP_flatten' (p : α → Bool) : @[deprecated (since := "2024-10-25")] alias countP_join' := countP_flatten' +set_option linter.deprecated false in /-- See `List.count_flatten` for the corresponding statement using `List.sum`. -/ +@[deprecated count_flatten (since := "2024-10-17")] lemma count_flatten' [BEq α] (L : List (List α)) (a : α) : L.flatten.count a = Nat.sum (L.map (count a)) := countP_flatten' _ _ @[deprecated (since := "2024-10-25")] alias count_join' := count_flatten' +set_option linter.deprecated false in /-- See `List.length_bind` for the corresponding statement using `List.sum`. -/ +@[deprecated "Use `List.length_bind`." (since := "2024-10-17")] lemma length_bind' (l : List α) (f : α → List β) : length (l.bind f) = Nat.sum (map (length ∘ f) l) := by rw [List.bind, length_flatten', map_map] +set_option linter.deprecated false in /-- See `List.countP_bind` for the corresponding statement using `List.sum`. -/ +@[deprecated "Use `List.countP_bind`." (since := "2024-10-17")] lemma countP_bind' (p : β → Bool) (l : List α) (f : α → List β) : countP p (l.bind f) = Nat.sum (map (countP p ∘ f) l) := by rw [List.bind, countP_flatten', map_map] +set_option linter.deprecated false in /-- See `List.count_bind` for the corresponding statement using `List.sum`. -/ +@[deprecated "Use `List.count_bind`." (since := "2024-10-17")] lemma count_bind' [BEq β] (l : List α) (f : α → List β) (x : β) : count x (l.bind f) = Nat.sum (map (count x ∘ f) l) := countP_bind' _ _ _ +set_option linter.deprecated false in /-- In a join, taking the first elements up to an index which is the sum of the lengths of the first `i` sublists, is the same as taking the join of the first `i` sublists. See `List.take_sum_flatten` for the corresponding statement using `List.sum`. -/ +@[deprecated "Use `List.take_sum_flatten`." (since := "2024-10-17")] theorem take_sum_flatten' (L : List (List α)) (i : ℕ) : L.flatten.take (Nat.sum ((L.map length).take i)) = (L.take i).flatten := by induction L generalizing i @@ -64,10 +78,12 @@ theorem take_sum_flatten' (L : List (List α)) (i : ℕ) : @[deprecated (since := "2024-10-25")] alias take_sum_join' := take_sum_flatten' +set_option linter.deprecated false in /-- In a join, dropping all the elements up to an index which is the sum of the lengths of the first `i` sublists, is the same as taking the join after dropping the first `i` sublists. See `List.drop_sum_flatten` for the corresponding statement using `List.sum`. -/ +@[deprecated "Use `List.drop_sum_flatten`." (since := "2024-10-17")] theorem drop_sum_flatten' (L : List (List α)) (i : ℕ) : L.flatten.drop (Nat.sum ((L.map length).take i)) = (L.drop i).flatten := by induction L generalizing i @@ -91,11 +107,13 @@ theorem drop_take_succ_eq_cons_get (L : List α) (i : Fin L.length) : (L.take (i + 1)).drop i = [get L i] := by simp [drop_take_succ_eq_cons_getElem] +set_option linter.deprecated false in /-- In a flatten of sublists, taking the slice between the indices `A` and `B - 1` gives back the original sublist of index `i` if `A` is the sum of the lengths of sublists of index `< i`, and `B` is the sum of the lengths of sublists of index `≤ i`. See `List.drop_take_succ_flatten_eq_getElem` for the corresponding statement using `List.sum`. -/ +@[deprecated "Use `List.drop_take_succ_flatten_eq_getElem`." (since := "2024-10-17")] theorem drop_take_succ_flatten_eq_getElem' (L : List (List α)) (i : Nat) (h : i < L.length) : (L.flatten.take (Nat.sum ((L.map length).take (i + 1)))).drop (Nat.sum ((L.map length).take i)) = L[i] := by @@ -107,6 +125,7 @@ theorem drop_take_succ_flatten_eq_getElem' (L : List (List α)) (i : Nat) (h : i @[deprecated (since := "2024-10-15")] alias drop_take_succ_join_eq_getElem' := drop_take_succ_flatten_eq_getElem' +set_option linter.deprecated false in @[deprecated drop_take_succ_flatten_eq_getElem' (since := "2024-06-11")] theorem drop_take_succ_join_eq_get' (L : List (List α)) (i : Fin L.length) : (L.flatten.take (Nat.sum ((L.map length).take (i + 1)))).drop diff --git a/Mathlib/Data/List/ProdSigma.lean b/Mathlib/Data/List/ProdSigma.lean index 5b55bac8afedbf..0006f4f21b2436 100644 --- a/Mathlib/Data/List/ProdSigma.lean +++ b/Mathlib/Data/List/ProdSigma.lean @@ -74,7 +74,9 @@ theorem mem_sigma {l₁ : List α} {l₂ : ∀ a, List (σ a)} {a : α} {b : σ simp [List.sigma, mem_bind, mem_map, exists_prop, exists_and_left, and_left_comm, exists_eq_left, heq_iff_eq, exists_eq_right] +set_option linter.deprecated false in /-- See `List.length_sigma` for the corresponding statement using `List.sum`. -/ +@[deprecated "Use `List.length_sigma`." (since := "2024-10-17")] theorem length_sigma' (l₁ : List α) (l₂ : ∀ a, List (σ a)) : length (l₁.sigma l₂) = Nat.sum (l₁.map fun a ↦ length (l₂ a)) := by induction' l₁ with x l₁ IH diff --git a/Mathlib/Data/List/Range.lean b/Mathlib/Data/List/Range.lean index 874f3b958de269..0b4918b7a6de22 100644 --- a/Mathlib/Data/List/Range.lean +++ b/Mathlib/Data/List/Range.lean @@ -141,7 +141,9 @@ theorem ranges_length (l : List ℕ) : intro s _ simp only [Function.comp_apply, length_map] +set_option linter.deprecated false in /-- See `List.ranges_flatten` for the version about `List.sum`. -/ +@[deprecated "Use `List.ranges_flatten`." (since := "2024-10-17")] lemma ranges_flatten' : ∀ l : List ℕ, l.ranges.flatten = range (Nat.sum l) | [] => rfl | a :: l => by simp only [Nat.sum_cons, flatten, ← map_flatten, ranges_flatten', range_add] @@ -155,10 +157,6 @@ lemma mem_mem_ranges_iff_lt_natSum (l : List ℕ) {n : ℕ} : (∃ s ∈ l.ranges, n ∈ s) ↔ n < Nat.sum l := by rw [← mem_range, ← ranges_flatten', mem_flatten] -/-- The members of `l.ranges` have no duplicate -/ -theorem ranges_nodup {l s : List ℕ} (hs : s ∈ ranges l) : s.Nodup := - (List.pairwise_flatten.mp <| by rw [ranges_flatten']; exact nodup_range _).1 s hs - end Ranges end List From a880896130ab2cf6a2cb74b09f6b1dd82e761423 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 17:43:00 +1100 Subject: [PATCH 268/425] chore: adaptations for nightly-2024-10-16 (#17851) Co-authored-by: leanprover-community-mathlib4-bot Co-authored-by: Kyle Miller --- Mathlib/Algebra/BigOperators/Group/List.lean | 13 ++++++------- Mathlib/Algebra/Group/Pi/Basic.lean | 1 - Mathlib/Combinatorics/Enumerative/Composition.lean | 2 +- Mathlib/Data/List/DropRight.lean | 2 +- Mathlib/Data/List/Range.lean | 2 +- Mathlib/Data/List/TFAE.lean | 1 - Mathlib/Data/Nat/Factorization/Defs.lean | 3 --- Mathlib/Data/Nat/Factors.lean | 2 -- Mathlib/Deprecated/Aliases.lean | 1 - Mathlib/GroupTheory/Coxeter/Inversion.lean | 4 ++-- Mathlib/Lean/Expr/Basic.lean | 1 - Mathlib/Logic/Relation.lean | 9 --------- Mathlib/Order/Basic.lean | 1 - Mathlib/Tactic/ApplyFun.lean | 9 ++++++--- Mathlib/Tactic/Convert.lean | 3 ++- Mathlib/Tactic/Core.lean | 3 +-- Mathlib/Tactic/GeneralizeProofs.lean | 1 + Mathlib/Tactic/Says.lean | 2 +- Mathlib/Tactic/Simps/Basic.lean | 2 +- Mathlib/Tactic/Tauto.lean | 1 - lake-manifest.json | 10 +++++----- lakefile.lean | 4 ++-- lean-toolchain | 2 +- scripts/noshake.json | 6 ++---- test/DefEqTransformations.lean | 2 +- 25 files changed, 34 insertions(+), 53 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Group/List.lean b/Mathlib/Algebra/BigOperators/Group/List.lean index 98736553e4b0f9..127d0e01260bc3 100644 --- a/Mathlib/Algebra/BigOperators/Group/List.lean +++ b/Mathlib/Algebra/BigOperators/Group/List.lean @@ -32,8 +32,8 @@ section Defs /-- Product of a list. -`List.prod [a, b, c] = a * (b * (c * 1))` -/ -@[to_additive "Sum of a list.\n\n`List.sum [a, b, c] = a + (b + (c + 0))`"] +`List.prod [a, b, c] = ((1 * a) * b) * c` -/ +@[to_additive existing] def prod {α} [Mul α] [One α] : List α → α := foldr (· * ·) 1 @@ -56,12 +56,12 @@ section Mul variable [Mul M] [One M] {l : List M} {a : M} -@[to_additive (attr := simp)] +@[to_additive existing, simp] theorem prod_nil : ([] : List M).prod = 1 := rfl -@[to_additive (attr := simp)] -theorem prod_cons : (a :: l).prod = a * l.prod := rfl +@[to_additive existing, simp] +theorem prod_cons {a} {l : List M} : (a :: l).prod = a * l.prod := rfl @[to_additive] lemma prod_induction @@ -654,12 +654,11 @@ lemma mem_mem_ranges_iff_lt_sum (l : List ℕ) {n : ℕ} : @[simp] theorem length_bind (l : List α) (f : α → List β) : length (List.bind l f) = sum (map (length ∘ f) l) := by - rw [List.bind, length_flatten, map_map, Nat.sum_eq_listSum] + rw [List.bind, length_flatten, map_map] lemma countP_bind (p : β → Bool) (l : List α) (f : α → List β) : countP p (l.bind f) = sum (map (countP p ∘ f) l) := by rw [List.bind, countP_flatten, map_map] - simp lemma count_bind [BEq β] (l : List α) (f : α → List β) (x : β) : count x (l.bind f) = sum (map (count x ∘ f) l) := countP_bind _ _ _ diff --git a/Mathlib/Algebra/Group/Pi/Basic.lean b/Mathlib/Algebra/Group/Pi/Basic.lean index 7a88ae8220a12e..b455b861786e4c 100644 --- a/Mathlib/Algebra/Group/Pi/Basic.lean +++ b/Mathlib/Algebra/Group/Pi/Basic.lean @@ -8,7 +8,6 @@ import Mathlib.Data.Prod.Basic import Mathlib.Data.Sum.Basic import Mathlib.Logic.Unique import Mathlib.Tactic.Spread -import Batteries.Tactic.Classical /-! # Instances and theorems on pi types diff --git a/Mathlib/Combinatorics/Enumerative/Composition.lean b/Mathlib/Combinatorics/Enumerative/Composition.lean index 3f06a1f76284ac..83c31afe5582d6 100644 --- a/Mathlib/Combinatorics/Enumerative/Composition.lean +++ b/Mathlib/Combinatorics/Enumerative/Composition.lean @@ -636,7 +636,7 @@ theorem getElem_splitWrtCompositionAux (l : List α) (ns : List ℕ) {i : ℕ} simp · simp only [splitWrtCompositionAux, getElem_cons_succ, IH, take, sum_cons, Nat.add_eq, add_zero, splitAt_eq, drop_take, drop_drop] - rw [add_comm (sum _) n, Nat.add_sub_add_left] + rw [Nat.add_sub_add_left] /-- The `i`-th sublist in the splitting of a list `l` along a composition `c`, is the slice of `l` between the indices `c.sizeUpTo i` and `c.sizeUpTo (i+1)`, i.e., the indices in the `i`-th diff --git a/Mathlib/Data/List/DropRight.lean b/Mathlib/Data/List/DropRight.lean index 10638f80de52e0..f55afc95cdd9f4 100644 --- a/Mathlib/Data/List/DropRight.lean +++ b/Mathlib/Data/List/DropRight.lean @@ -212,7 +212,7 @@ theorem rtakeWhile_idempotent (p : α → Bool) (l : List α) : rtakeWhile_eq_self_iff.mpr fun _ => mem_rtakeWhile_imp lemma rdrop_add (i j : ℕ) : (l.rdrop i).rdrop j = l.rdrop (i + j) := by - simp_rw [rdrop_eq_reverse_drop_reverse, reverse_reverse, drop_drop, Nat.add_comm] + simp_rw [rdrop_eq_reverse_drop_reverse, reverse_reverse, drop_drop] @[simp] lemma rdrop_append_length {l₁ l₂ : List α} : diff --git a/Mathlib/Data/List/Range.lean b/Mathlib/Data/List/Range.lean index bd491ba6ccd4ab..f1e03a895c1e49 100644 --- a/Mathlib/Data/List/Range.lean +++ b/Mathlib/Data/List/Range.lean @@ -144,7 +144,7 @@ theorem ranges_length (l : List ℕ) : /-- See `List.ranges_flatten` for the version about `List.sum`. -/ lemma ranges_flatten' : ∀ l : List ℕ, l.ranges.flatten = range (Nat.sum l) | [] => rfl - | a :: l => by simp only [sum_cons, flatten, ← map_flatten, ranges_flatten', range_add] + | a :: l => by simp only [Nat.sum_cons, flatten, ← map_flatten, ranges_flatten', range_add] @[deprecated (since := "2024-10-15")] alias ranges_join' := ranges_flatten' diff --git a/Mathlib/Data/List/TFAE.lean b/Mathlib/Data/List/TFAE.lean index 3dd02febe8c138..24e43d9612f033 100644 --- a/Mathlib/Data/List/TFAE.lean +++ b/Mathlib/Data/List/TFAE.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Johan Commelin, Simon Hudon -/ import Batteries.Data.List.Lemmas -import Batteries.Tactic.Classical import Mathlib.Tactic.TypeStar /-! diff --git a/Mathlib/Data/Nat/Factorization/Defs.lean b/Mathlib/Data/Nat/Factorization/Defs.lean index fb64f3dd9d2d66..d87a08e80720e6 100644 --- a/Mathlib/Data/Nat/Factorization/Defs.lean +++ b/Mathlib/Data/Nat/Factorization/Defs.lean @@ -35,9 +35,6 @@ with a normalization function, and then deduplicated. The basics of this have b -/ --- Workaround for lean4#2038 -attribute [-instance] instBEqNat - open Nat Finset List Finsupp namespace Nat diff --git a/Mathlib/Data/Nat/Factors.lean b/Mathlib/Data/Nat/Factors.lean index df65aa467ceea3..132785107afc0e 100644 --- a/Mathlib/Data/Nat/Factors.lean +++ b/Mathlib/Data/Nat/Factors.lean @@ -29,8 +29,6 @@ open Nat namespace Nat -attribute [instance 0] instBEqNat - /-- `primeFactorsList n` is the prime factorization of `n`, listed in increasing order. -/ def primeFactorsList : ℕ → List ℕ | 0 => [] diff --git a/Mathlib/Deprecated/Aliases.lean b/Mathlib/Deprecated/Aliases.lean index 5e63adabb80058..6266e7c3f17d2a 100644 --- a/Mathlib/Deprecated/Aliases.lean +++ b/Mathlib/Deprecated/Aliases.lean @@ -5,7 +5,6 @@ Authors: Kim Morrison -/ import Mathlib.Init import Batteries.Tactic.Alias -import Batteries.Data.String.Basic /-! Deprecated aliases can be dumped here if they are no longer used in Mathlib, diff --git a/Mathlib/GroupTheory/Coxeter/Inversion.lean b/Mathlib/GroupTheory/Coxeter/Inversion.lean index 18946d5bd27dcd..c5c613cf20c6a5 100644 --- a/Mathlib/GroupTheory/Coxeter/Inversion.lean +++ b/Mathlib/GroupTheory/Coxeter/Inversion.lean @@ -401,8 +401,8 @@ theorem IsReduced.nodup_rightInvSeq {ω : List B} (rω : cs.IsReduced ω) : List rw [h₂, cs.getD_rightInvSeq, cs.getD_rightInvSeq, (Nat.sub_add_cancel (by omega) : j' - 1 + 1 = j'), eraseIdx_eq_take_drop_succ, drop_append_eq_append_drop, drop_of_length_le (by simp [j_lt_j'.le]), length_take, - drop_drop, nil_append, min_eq_left_of_lt (j_lt_j'.trans j'_lt_length), ← add_assoc, - Nat.sub_add_cancel (by omega), mul_left_inj, mul_right_inj] + drop_drop, nil_append, min_eq_left_of_lt (j_lt_j'.trans j'_lt_length), Nat.add_comm, + ← add_assoc, Nat.sub_add_cancel (by omega), mul_left_inj, mul_right_inj] congr 2 show get? (take j ω ++ drop (j + 1) ω) (j' - 1) = get? ω j' rw [get?_eq_getElem?, get?_eq_getElem?, diff --git a/Mathlib/Lean/Expr/Basic.lean b/Mathlib/Lean/Expr/Basic.lean index 02701a1fb4c6db..57caa17facbf9a 100644 --- a/Mathlib/Lean/Expr/Basic.lean +++ b/Mathlib/Lean/Expr/Basic.lean @@ -6,7 +6,6 @@ Floris van Doorn, Edward Ayers, Arthur Paulino -/ import Mathlib.Init import Lean.Meta.Tactic.Rewrite -import Batteries.Lean.Expr import Batteries.Tactic.Alias import Lean.Elab.Binders diff --git a/Mathlib/Logic/Relation.lean b/Mathlib/Logic/Relation.lean index 93afac58af7093..0e8c56a80eb73a 100644 --- a/Mathlib/Logic/Relation.lean +++ b/Mathlib/Logic/Relation.lean @@ -689,15 +689,6 @@ theorem Quot.eqvGen_sound (H : EqvGen r a b) : Quot.mk r a = Quot.mk r b := (fun _ _ _ _ _ IH₁ IH₂ ↦ Eq.trans IH₁ IH₂) H -instance Quotient.decidableEq {α : Sort*} {s : Setoid α} [d : ∀ a b : α, Decidable (a ≈ b)] : - DecidableEq (Quotient s) := - fun q₁ q₂ : Quotient s ↦ - Quotient.recOnSubsingleton₂ q₁ q₂ - (fun a₁ a₂ ↦ - match (d a₁ a₂) with - | (isTrue h₁) => isTrue (Quotient.sound h₁) - | (isFalse h₂) => isFalse (fun h ↦ absurd (Quotient.exact h) h₂)) - theorem Equivalence.eqvGen_iff (h : Equivalence r) : EqvGen r a b ↔ r a b := Iff.intro (by diff --git a/Mathlib/Order/Basic.lean b/Mathlib/Order/Basic.lean index f7a234670ae36b..b090a893ae8119 100644 --- a/Mathlib/Order/Basic.lean +++ b/Mathlib/Order/Basic.lean @@ -11,7 +11,6 @@ import Mathlib.Tactic.Spread import Mathlib.Tactic.Convert import Mathlib.Tactic.SimpRw import Batteries.Data.Sum.Lemmas -import Batteries.Tactic.Classical /-! # Basic definitions about `≤` and `<` diff --git a/Mathlib/Tactic/ApplyFun.lean b/Mathlib/Tactic/ApplyFun.lean index 2b55685474bb7d..26fe30001d7f64 100644 --- a/Mathlib/Tactic/ApplyFun.lean +++ b/Mathlib/Tactic/ApplyFun.lean @@ -28,7 +28,8 @@ def applyFunHyp (f : Term) (using? : Option Term) (h : FVarId) (g : MVarId) : let d ← h.getDecl let (prf, newGoals) ← match (← whnfR (← instantiateMVars d.type)).getAppFnArgs with | (``Eq, #[_, lhs, rhs]) => do - let (eq', gs) ← withCollectingNewGoalsFrom (tagSuffix := `apply_fun) <| + let (eq', gs) ← + withCollectingNewGoalsFrom (parentTag := ← g.getTag) (tagSuffix := `apply_fun) <| withoutRecover <| runTermElab <| do let f ← Term.elabTerm f none let lhs' ← Term.elabAppArgs f #[] #[.expr lhs] none false false @@ -126,7 +127,8 @@ def applyFunTarget (f : Term) (using? : Option Term) (g : MVarId) : TacticM (Lis -- handle applying a two-argument theorem whose first argument is f let handle (thm : Name) : TacticM (List MVarId) := do let ng ← mkFreshExprMVar none - let (pf, gs) ← withCollectingNewGoalsFrom (tagSuffix := `apply_fun) <| + let (pf, gs) ← + withCollectingNewGoalsFrom (parentTag := ← g.getTag) (tagSuffix := `apply_fun) <| withoutRecover <| runTermElab do -- This coerces `f` to be a function as necessary: let pf ← Term.elabTermEnsuringType (← `($(mkIdent thm) $f $(← Term.exprToSyntax ng))) @@ -151,7 +153,8 @@ def applyFunTarget (f : Term) (using? : Option Term) (g : MVarId) : TacticM (Lis let ginj ← mkFreshExprSyntheticOpaqueMVar (← mkFreshTypeMVar) (appendTag (← g.getTag) `inj) -- `withCollectingNewGoalsFrom` does not expect the goal to be closed, so here is "the goal" let gDefer ← mkFreshExprMVar (← g.getType) - let (_, gs) ← withCollectingNewGoalsFrom (tagSuffix := `apply_fun) <| + let (_, gs) ← + withCollectingNewGoalsFrom (parentTag := ← g.getTag) (tagSuffix := `apply_fun) <| withoutRecover <| runTermElab do let inj ← Term.elabTerm (← ``(Function.Injective $f)) none _ ← isDefEq (← inferType ginj) inj diff --git a/Mathlib/Tactic/Convert.lean b/Mathlib/Tactic/Convert.lean index c0dcc20b97221b..17baa946a72000 100644 --- a/Mathlib/Tactic/Convert.lean +++ b/Mathlib/Tactic/Convert.lean @@ -126,7 +126,8 @@ Returns stuck metavariables as additional goals. -/ def elabTermForConvert (term : Syntax) (expectedType? : Option Expr) : TacticM (Expr × List MVarId) := do - withCollectingNewGoalsFrom (allowNaturalHoles := true) (tagSuffix := `convert) do + withCollectingNewGoalsFrom (parentTag := ← getMainTag) (tagSuffix := `convert) + (allowNaturalHoles := true) do -- Allow typeclass inference failures since these will be inferred by unification -- or else become new goals withTheReader Term.Context (fun ctx => { ctx with ignoreTCFailures := true }) do diff --git a/Mathlib/Tactic/Core.lean b/Mathlib/Tactic/Core.lean index 1aeb2717c5047e..fc6cf43ed4dc64 100644 --- a/Mathlib/Tactic/Core.lean +++ b/Mathlib/Tactic/Core.lean @@ -19,7 +19,7 @@ open Lean.Elab.Tactic namespace Lean -open Elab +open Elab Meta /-- Return the modifiers of declaration `nm` with (optional) docstring `newDoc`. @@ -69,7 +69,6 @@ def toPreDefinition (nm newNm : Name) (newType newValue : Expr) (newDoc : Option def setProtected {m : Type → Type} [MonadEnv m] (nm : Name) : m Unit := modifyEnv (addProtected · nm) -open private getIntrosSize from Lean.Meta.Tactic.Intro in /-- Introduce variables, giving them names from a specified list. -/ def MVarId.introsWithBinderIdents (g : MVarId) (ids : List (TSyntax ``binderIdent)) : diff --git a/Mathlib/Tactic/GeneralizeProofs.lean b/Mathlib/Tactic/GeneralizeProofs.lean index 645637ae46a0f3..72f6d093d52336 100644 --- a/Mathlib/Tactic/GeneralizeProofs.lean +++ b/Mathlib/Tactic/GeneralizeProofs.lean @@ -6,6 +6,7 @@ Authors: Alex J. Best, Kyle Miller import Lean.Elab.Tactic.Config import Lean.Elab.Tactic.Location import Mathlib.Lean.Expr.Basic +import Batteries.Lean.Expr /-! # The `generalize_proofs` tactic diff --git a/Mathlib/Tactic/Says.lean b/Mathlib/Tactic/Says.lean index 29bd33ed183cf1..e2d5e9007ad3f9 100644 --- a/Mathlib/Tactic/Says.lean +++ b/Mathlib/Tactic/Says.lean @@ -4,9 +4,9 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Kim Morrison -/ import Mathlib.Init -import Batteries.Data.String.Basic import Lean.Meta.Tactic.TryThis import Batteries.Linter.UnreachableTactic +import Batteries.Data.String.Basic import Qq.Match /-! diff --git a/Mathlib/Tactic/Simps/Basic.lean b/Mathlib/Tactic/Simps/Basic.lean index 1caba0e4825aba..75ebfae3d5a00e 100644 --- a/Mathlib/Tactic/Simps/Basic.lean +++ b/Mathlib/Tactic/Simps/Basic.lean @@ -5,8 +5,8 @@ Authors: Floris van Doorn -/ import Lean.Elab.Tactic.Simp import Lean.Elab.App -import Mathlib.Tactic.Simps.NotationClass import Batteries.Data.String.Basic +import Mathlib.Tactic.Simps.NotationClass import Mathlib.Lean.Expr.Basic /-! diff --git a/Mathlib/Tactic/Tauto.lean b/Mathlib/Tactic/Tauto.lean index 14285f3eb54287..f68a5143bdf0d4 100644 --- a/Mathlib/Tactic/Tauto.lean +++ b/Mathlib/Tactic/Tauto.lean @@ -8,7 +8,6 @@ import Mathlib.Tactic.Core import Mathlib.Lean.Elab.Tactic.Basic import Mathlib.Logic.Basic import Qq -import Batteries.Tactic.Classical /-! The `tauto` tactic. diff --git a/lake-manifest.json b/lake-manifest.json index 824bd6242b29c2..ec4819dd4811ac 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "4def8ae307885daef61c66aa5fa95b6377aa5eff", + "rev": "acc9722fa789363b2c7cd0c0e3ee69a9048b459a", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "nightly-testing", @@ -25,20 +25,20 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "b20a88676fd00affb90cbc9f1ff004ae588103b3", + "rev": "6503af80a441d6d5351e60e6256b45d135d46d50", "name": "aesop", "manifestFile": "lake-manifest.json", - "inputRev": "master", + "inputRev": "nightly-testing", "inherited": false, "configFile": "lakefile.toml"}, {"url": "https://github.com/leanprover-community/ProofWidgets4", "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "cd20dae87c48495f0220663014dff11671597fcf", + "rev": "032cf93147e1fc5af7cbddc1075acea78c89a075", "name": "proofwidgets", "manifestFile": "lake-manifest.json", - "inputRev": "v0.0.43-pre", + "inputRev": "v0.0.44-pre", "inherited": false, "configFile": "lakefile.lean"}, {"url": "https://github.com/leanprover/lean4-cli", diff --git a/lakefile.lean b/lakefile.lean index 43fc8e761b4b93..bb806c24f85559 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -9,8 +9,8 @@ open Lake DSL require "leanprover-community" / "batteries" @ git "nightly-testing" require "leanprover-community" / "Qq" @ git "master" -require "leanprover-community" / "aesop" @ git "master" -require "leanprover-community" / "proofwidgets" @ git "v0.0.43" +require "leanprover-community" / "aesop" @ git "nightly-testing" +require "leanprover-community" / "proofwidgets" @ git "v0.0.44-pre" require "leanprover-community" / "importGraph" @ git "main" require "leanprover-community" / "LeanSearchClient" @ git "main" from git "https://github.com/leanprover-community/LeanSearchClient" @ "main" diff --git a/lean-toolchain b/lean-toolchain index af6a54a1b05087..c7e012c64aaed0 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-15 +leanprover/lean4:nightly-2024-10-16 diff --git a/scripts/noshake.json b/scripts/noshake.json index 75da1806f1ee3e..e8328c65a83a7f 100644 --- a/scripts/noshake.json +++ b/scripts/noshake.json @@ -73,7 +73,6 @@ "Mathlib.Tactic.CategoryTheory.Elementwise", "Mathlib.Tactic.CategoryTheory.Slice", "Mathlib.Tactic.Choose", - "Mathlib.Tactic.Classical", "Mathlib.Tactic.Clean", "Mathlib.Tactic.ClearExcept", "Mathlib.Tactic.ClearExclamation", @@ -214,6 +213,8 @@ "Mathlib.Tactic.Tauto": ["Mathlib.Logic.Basic"], "Mathlib.Tactic.TFAE": ["Mathlib.Data.List.TFAE", "Mathlib.Tactic.Have"], "Mathlib.Tactic.Subsingleton": ["Mathlib.Logic.Basic", "Std.Logic"], + "Mathlib.Tactic.Simps.Basic": ["Batteries.Data.String.Basic"], + "Mathlib.Tactic.Says": ["Batteries.Data.String.Basic"], "Mathlib.Tactic.ReduceModChar": ["Mathlib.Data.ZMod.Basic", "Mathlib.RingTheory.Polynomial.Basic"], "Mathlib.Tactic.ProxyType": ["Mathlib.Logic.Equiv.Defs"], @@ -325,7 +326,6 @@ "Mathlib.Order.RelClasses": ["Batteries.WF"], "Mathlib.Order.Filter.ListTraverse": ["Mathlib.Control.Traversable.Instances"], - "Mathlib.Order.Basic": ["Batteries.Tactic.Classical"], "Mathlib.NumberTheory.Harmonic.Defs": ["Mathlib.Algebra.Order.BigOperators.Ring.Finset", "Mathlib.Algebra.Order.Field.Basic"], @@ -361,7 +361,6 @@ ["Batteries.Tactic.Init", "Mathlib.Logic.Function.Defs"], "Mathlib.Data.Nat.Find": ["Batteries.WF"], "Mathlib.Data.Multiset.Bind": ["Mathlib.Algebra.GroupWithZero.Action.Defs"], - "Mathlib.Data.List.TFAE": ["Batteries.Tactic.Classical"], "Mathlib.Data.List.Range": ["Batteries.Data.Nat.Lemmas"], "Mathlib.Data.List.ProdSigma": ["Batteries.Data.Nat.Lemmas", "Mathlib.Data.List.Basic"], @@ -422,7 +421,6 @@ "Mathlib.Algebra.Homology.ModuleCat": ["Mathlib.Algebra.Homology.Homotopy"], "Mathlib.Algebra.Group.Units.Basic": ["Mathlib.Tactic.Subsingleton"], "Mathlib.Algebra.Group.Units": ["Mathlib.Tactic.Subsingleton"], - "Mathlib.Algebra.Group.Pi.Basic": ["Batteries.Tactic.Classical"], "Mathlib.Algebra.Group.Defs": ["Mathlib.Data.Int.Notation"], "Mathlib.Algebra.GeomSum": ["Mathlib.Algebra.Order.BigOperators.Ring.Finset"], "Mathlib.Algebra.Category.Ring.Basic": diff --git a/test/DefEqTransformations.lean b/test/DefEqTransformations.lean index 496e641a680f8f..095b6a8bf70920 100644 --- a/test/DefEqTransformations.lean +++ b/test/DefEqTransformations.lean @@ -119,7 +119,7 @@ example : 1 + 2 = 2 + 1 := by example (m n : Nat) : (m == n) = true := by unfold_projs - guard_target =ₛ Nat.beq m n = true + guard_target =ₛ decide (m = n) = true exact test_sorry example {α : Type u} (f : α → α) (a : α) : From fff90ff17cddd549055f6f16b81b5009ef25099d Mon Sep 17 00:00:00 2001 From: Dagur Asgeirsson Date: Thu, 17 Oct 2024 06:44:29 +0000 Subject: [PATCH 269/425] feat(CategoryTheory/Limits): generalize universes in `Preserves.Filtered` and add `Reflects` classes (#17537) --- .../Limits/Preserves/Filtered.lean | 233 ++++++++++++++++-- 1 file changed, 214 insertions(+), 19 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Preserves/Filtered.lean b/Mathlib/CategoryTheory/Limits/Preserves/Filtered.lean index 932826e7f60e0f..d1ad0cedcd3f63 100644 --- a/Mathlib/CategoryTheory/Limits/Preserves/Filtered.lean +++ b/Mathlib/CategoryTheory/Limits/Preserves/Filtered.lean @@ -11,8 +11,6 @@ import Mathlib.CategoryTheory.Filtered.Basic Typically forgetful functors from algebraic categories preserve filtered colimits (although not general colimits). See e.g. `Algebra/Category/MonCat/FilteredColimits`. -## Future work -This could be generalised to allow diagrams in lower universes. -/ @@ -22,7 +20,7 @@ open CategoryTheory.Functor namespace CategoryTheory.Limits -universe v u₁ u₂ u₃ +universe w' w₂' w w₂ v u₁ u₂ u₃ -- declare the `v`'s first; see `CategoryTheory.Category` for an explanation variable {C : Type u₁} [Category.{v} C] @@ -30,39 +28,236 @@ variable {D : Type u₂} [Category.{v} D] variable {E : Type u₃} [Category.{v} E] variable {J : Type v} [SmallCategory J] {K : J ⥤ C} +section FilteredColimits + +section Preserves + +-- This should be used with explicit universe variables. +/-- `PreservesFilteredColimitsOfSize.{w', w} F` means that `F` sends all colimit cocones over any +filtered diagram `J ⥤ C` to colimit cocones, where `J : Type w` with `[Category.{w'} J]`. -/ +@[nolint checkUnivs, pp_with_univ] +class PreservesFilteredColimitsOfSize (F : C ⥤ D) where + preserves_filtered_colimits : + ∀ (J : Type w) [Category.{w'} J] [IsFiltered J], PreservesColimitsOfShape J F + /-- A functor is said to preserve filtered colimits, if it preserves all colimits of shape `J`, where -`J` is a filtered category. +`J` is a filtered category which is small relative to the universe in which morphisms of the source +live. -/ -class PreservesFilteredColimits (F : C ⥤ D) : Type max u₁ u₂ (v + 1) where - preserves_filtered_colimits : - ∀ (J : Type v) [SmallCategory J] [IsFiltered J], PreservesColimitsOfShape J F +abbrev PreservesFilteredColimits (F : C ⥤ D) : Type max u₁ u₂ (v + 1) := + PreservesFilteredColimitsOfSize.{v, v} F -attribute [instance 100] PreservesFilteredColimits.preserves_filtered_colimits +attribute [instance 100] PreservesFilteredColimitsOfSize.preserves_filtered_colimits instance (priority := 100) PreservesColimits.preservesFilteredColimits (F : C ⥤ D) - [PreservesColimits F] : PreservesFilteredColimits F where + [PreservesColimitsOfSize.{w, w'} F] : PreservesFilteredColimitsOfSize.{w, w'} F where preserves_filtered_colimits _ := inferInstance -instance compPreservesFilteredColimits (F : C ⥤ D) (G : D ⥤ E) [PreservesFilteredColimits F] - [PreservesFilteredColimits G] : PreservesFilteredColimits (F ⋙ G) where +instance compPreservesFilteredColimits (F : C ⥤ D) (G : D ⥤ E) + [PreservesFilteredColimitsOfSize.{w, w'} F] [PreservesFilteredColimitsOfSize.{w, w'} G] : + PreservesFilteredColimitsOfSize.{w, w'} (F ⋙ G) where preserves_filtered_colimits _ := inferInstance -/-- A functor is said to preserve cofiltered limits, if it preserves all limits of shape `J`, where -`J` is a cofiltered category. +/-- A functor preserving larger filtered colimits also preserves smaller filtered colimits. -/ +noncomputable def preservesFilteredColimitsOfSizeOfUnivLE (F : C ⥤ D) [UnivLE.{w, w'}] + [UnivLE.{w₂, w₂'}] [PreservesFilteredColimitsOfSize.{w', w₂'} F] : + PreservesFilteredColimitsOfSize.{w, w₂} F where + preserves_filtered_colimits J _ _ := by + let e := ((ShrinkHoms.equivalence J).trans <| Shrink.equivalence _).symm + haveI := IsFiltered.of_equivalence e.symm + exact preservesColimitsOfShapeOfEquiv e F + +/-- +`PreservesFilteredColimitsOfSizeShrink.{w, w'} F` tries to obtain +`PreservesFilteredColimitsOfSize.{w, w'} F` from some other `PreservesFilteredColimitsOfSize F`. +-/ +noncomputable def preservesFilteredColimitsOfSizeShrink (F : C ⥤ D) + [PreservesFilteredColimitsOfSize.{max w w₂, max w' w₂'} F] : + PreservesFilteredColimitsOfSize.{w, w'} F := + preservesFilteredColimitsOfSizeOfUnivLE.{max w w₂, max w' w₂'} F + +/-- +Preserving filtered colimits at any universe implies preserving filtered colimits at universe `0`. +-/ +noncomputable def preservesSmallestFilteredColimitsOfPreservesFilteredColimits (F : C ⥤ D) + [PreservesFilteredColimitsOfSize.{w', w} F] : PreservesFilteredColimitsOfSize.{0, 0} F := + preservesFilteredColimitsOfSizeShrink F + +end Preserves + +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. -/ +@[nolint checkUnivs, pp_with_univ] +class ReflectsFilteredColimitsOfSize (F : C ⥤ D) where + reflects_filtered_colimits : + ∀ (J : Type w) [Category.{w'} J] [IsFiltered J], ReflectsColimitsOfShape J F + +/-- +A functor is said to reflect filtered colimits, if it reflects all colimits of shape `J`, where +`J` is a filtered category which is small relative to the universe in which morphisms of the source +live. +-/ +abbrev ReflectsFilteredColimits (F : C ⥤ D) : Type max u₁ u₂ (v + 1) := + ReflectsFilteredColimitsOfSize.{v, v} F + +attribute [instance 100] ReflectsFilteredColimitsOfSize.reflects_filtered_colimits + +instance (priority := 100) ReflectsColimits.reflectsFilteredColimits (F : C ⥤ D) + [ReflectsColimitsOfSize.{w, w'} F] : ReflectsFilteredColimitsOfSize.{w, w'} F where + reflects_filtered_colimits _ := inferInstance + +instance compReflectsFilteredColimits (F : C ⥤ D) (G : D ⥤ E) + [ReflectsFilteredColimitsOfSize.{w, w'} F] [ReflectsFilteredColimitsOfSize.{w, w'} G] : + ReflectsFilteredColimitsOfSize.{w, w'} (F ⋙ G) where + reflects_filtered_colimits _ := inferInstance + +/-- A functor reflecting larger filtered colimits also reflects smaller filtered colimits. -/ +noncomputable def reflectsFilteredColimitsOfSizeOfUnivLE (F : C ⥤ D) [UnivLE.{w, w'}] + [UnivLE.{w₂, w₂'}] [ReflectsFilteredColimitsOfSize.{w', w₂'} F] : + ReflectsFilteredColimitsOfSize.{w, w₂} F where + reflects_filtered_colimits J _ _ := by + let e := ((ShrinkHoms.equivalence J).trans <| Shrink.equivalence _).symm + haveI := IsFiltered.of_equivalence e.symm + exact reflectsColimitsOfShapeOfEquiv e F + +/-- +`ReflectsFilteredColimitsOfSizeShrink.{w, w'} F` tries to obtain +`ReflectsFilteredColimitsOfSize.{w, w'} F` from some other `ReflectsFilteredColimitsOfSize F`. -/ -class PreservesCofilteredLimits (F : C ⥤ D) : Type max u₁ u₂ (v + 1) where +noncomputable def reflectsFilteredColimitsOfSizeShrink (F : C ⥤ D) + [ReflectsFilteredColimitsOfSize.{max w w₂, max w' w₂'} F] : + ReflectsFilteredColimitsOfSize.{w, w'} F := + reflectsFilteredColimitsOfSizeOfUnivLE.{max w w₂, max w' w₂'} F + +/-- +Reflecting filtered colimits at any universe implies reflecting filtered colimits at universe `0`. +-/ +noncomputable def reflectsSmallestFilteredColimitsOfReflectsFilteredColimits (F : C ⥤ D) + [ReflectsFilteredColimitsOfSize.{w', w} F] : ReflectsFilteredColimitsOfSize.{0, 0} F := + reflectsFilteredColimitsOfSizeShrink F + +end Reflects + +end FilteredColimits + +section CofilteredLimits + +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]`. -/ +@[nolint checkUnivs, pp_with_univ] +class PreservesCofilteredLimitsOfSize (F : C ⥤ D) where preserves_cofiltered_limits : - ∀ (J : Type v) [SmallCategory J] [IsCofiltered J], PreservesLimitsOfShape J F + ∀ (J : Type w) [Category.{w'} J] [IsCofiltered J], PreservesLimitsOfShape J F + +/-- +A functor is said to preserve cofiltered limits, if it preserves all limits of shape `J`, where +`J` is a cofiltered category which is small relative to the universe in which morphisms of the +source live. +-/ +abbrev PreservesCofilteredLimits (F : C ⥤ D) : Type max u₁ u₂ (v + 1) := + PreservesCofilteredLimitsOfSize.{v, v} F -attribute [instance 100] PreservesCofilteredLimits.preserves_cofiltered_limits +attribute [instance 100] PreservesCofilteredLimitsOfSize.preserves_cofiltered_limits instance (priority := 100) PreservesLimits.preservesCofilteredLimits (F : C ⥤ D) - [PreservesLimits F] : PreservesCofilteredLimits F where + [PreservesLimitsOfSize.{w, w'} F] : PreservesCofilteredLimitsOfSize.{w, w'} F where preserves_cofiltered_limits _ := inferInstance -instance compPreservesCofilteredLimits (F : C ⥤ D) (G : D ⥤ E) [PreservesCofilteredLimits F] - [PreservesCofilteredLimits G] : PreservesCofilteredLimits (F ⋙ G) where +instance compPreservesCofilteredLimits (F : C ⥤ D) (G : D ⥤ E) + [PreservesCofilteredLimitsOfSize.{w, w'} F] [PreservesCofilteredLimitsOfSize.{w, w'} G] : + PreservesCofilteredLimitsOfSize.{w, w'} (F ⋙ G) where preserves_cofiltered_limits _ := inferInstance +/-- A functor preserving larger cofiltered limits also preserves smaller cofiltered limits. -/ +noncomputable def preservesCofilteredLimitsOfSizeOfUnivLE (F : C ⥤ D) [UnivLE.{w, w'}] + [UnivLE.{w₂, w₂'}] [PreservesCofilteredLimitsOfSize.{w', w₂'} F] : + PreservesCofilteredLimitsOfSize.{w, w₂} F where + preserves_cofiltered_limits J _ _ := by + let e := ((ShrinkHoms.equivalence J).trans <| Shrink.equivalence _).symm + haveI := IsCofiltered.of_equivalence e.symm + exact preservesLimitsOfShapeOfEquiv e F + +/-- +`PreservesCofilteredLimitsOfSizeShrink.{w, w'} F` tries to obtain +`PreservesCofilteredLimitsOfSize.{w, w'} F` from some other `PreservesCofilteredLimitsOfSize F`. +-/ +noncomputable def preservesCofilteredLimitsOfSizeShrink (F : C ⥤ D) + [PreservesCofilteredLimitsOfSize.{max w w₂, max w' w₂'} F] : + PreservesCofilteredLimitsOfSize.{w, w'} F := + preservesCofilteredLimitsOfSizeOfUnivLE.{max w w₂, max w' w₂'} F + +/-- +Preserving cofiltered limits at any universe implies preserving cofiltered limits at universe `0`. +-/ +noncomputable def preservesSmallestCofilteredLimitsOfPreservesCofilteredLimits (F : C ⥤ D) + [PreservesCofilteredLimitsOfSize.{w', w} F] : PreservesCofilteredLimitsOfSize.{0, 0} F := + preservesCofilteredLimitsOfSizeShrink F + +end Preserves + +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. -/ +@[nolint checkUnivs, pp_with_univ] +class ReflectsCofilteredLimitsOfSize (F : C ⥤ D) where + reflects_cofiltered_limits : + ∀ (J : Type w) [Category.{w'} J] [IsCofiltered J], ReflectsLimitsOfShape J F + +/-- +A functor is said to reflect cofiltered limits, if it reflects all limits of shape `J`, where +`J` is a cofiltered category which is small relative to the universe in which morphisms of the +source live. +-/ +abbrev ReflectsCofilteredLimits (F : C ⥤ D) : Type max u₁ u₂ (v + 1) := + ReflectsCofilteredLimitsOfSize.{v, v} F + +attribute [instance 100] ReflectsCofilteredLimitsOfSize.reflects_cofiltered_limits + +instance (priority := 100) ReflectsLimits.reflectsCofilteredLimits (F : C ⥤ D) + [ReflectsLimitsOfSize.{w, w'} F] : ReflectsCofilteredLimitsOfSize.{w, w'} F where + reflects_cofiltered_limits _ := inferInstance + +instance compReflectsCofilteredLimits (F : C ⥤ D) (G : D ⥤ E) + [ReflectsCofilteredLimitsOfSize.{w, w'} F] [ReflectsCofilteredLimitsOfSize.{w, w'} G] : + ReflectsCofilteredLimitsOfSize.{w, w'} (F ⋙ G) where + reflects_cofiltered_limits _ := inferInstance + +/-- A functor reflecting larger cofiltered limits also reflects smaller cofiltered limits. -/ +noncomputable def reflectsCofilteredLimitsOfSizeOfUnivLE (F : C ⥤ D) [UnivLE.{w, w'}] + [UnivLE.{w₂, w₂'}] [ReflectsCofilteredLimitsOfSize.{w', w₂'} F] : + ReflectsCofilteredLimitsOfSize.{w, w₂} F where + reflects_cofiltered_limits J _ _ := by + let e := ((ShrinkHoms.equivalence J).trans <| Shrink.equivalence _).symm + haveI := IsCofiltered.of_equivalence e.symm + exact reflectsLimitsOfShapeOfEquiv e F + +/-- +`ReflectsCofilteredLimitsOfSizeShrink.{w, w'} F` tries to obtain +`ReflectsCofilteredLimitsOfSize.{w, w'} F` from some other `ReflectsCofilteredLimitsOfSize F`. +-/ +noncomputable def reflectsCofilteredLimitsOfSizeShrink (F : C ⥤ D) + [ReflectsCofilteredLimitsOfSize.{max w w₂, max w' w₂'} F] : + ReflectsCofilteredLimitsOfSize.{w, w'} F := + reflectsCofilteredLimitsOfSizeOfUnivLE.{max w w₂, max w' w₂'} F + +/-- +Reflecting cofiltered limits at any universe implies reflecting cofiltered limits at universe `0`. +-/ +noncomputable def reflectsSmallestCofilteredLimitsOfReflectsCofilteredLimits (F : C ⥤ D) + [ReflectsCofilteredLimitsOfSize.{w', w} F] : ReflectsCofilteredLimitsOfSize.{0, 0} F := + reflectsCofilteredLimitsOfSizeShrink F + +end Reflects + +end CofilteredLimits + end CategoryTheory.Limits From b6fd8b449c9037527638f3a6a4e32943e29d27a3 Mon Sep 17 00:00:00 2001 From: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com> Date: Thu, 17 Oct 2024 07:04:05 +0000 Subject: [PATCH 270/425] doc: fix some issues under RepresentationTheory (#16409) --- Mathlib/RepresentationTheory/Action/Basic.lean | 2 +- Mathlib/RepresentationTheory/Basic.lean | 13 ++++++------- Mathlib/RepresentationTheory/Character.lean | 4 ++-- .../RepresentationTheory/GroupCohomology/Basic.lean | 4 ++-- .../GroupCohomology/Resolution.lean | 6 +++--- 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Mathlib/RepresentationTheory/Action/Basic.lean b/Mathlib/RepresentationTheory/Action/Basic.lean index 4c1ae310a58124..f70ce1fb09e29a 100644 --- a/Mathlib/RepresentationTheory/Action/Basic.lean +++ b/Mathlib/RepresentationTheory/Action/Basic.lean @@ -16,7 +16,7 @@ import Mathlib.CategoryTheory.Conj The prototypical example is `V = ModuleCat R`, where `Action (ModuleCat R) G` is the category of `R`-linear representations of `G`. -We check `Action V G ≌ (singleObj G ⥤ V)`, +We check `Action V G ≌ (CategoryTheory.singleObj G ⥤ V)`, and construct the restriction functors `res {G H : MonCat} (f : G ⟶ H) : Action V H ⥤ Action V G`. -/ diff --git a/Mathlib/RepresentationTheory/Basic.lean b/Mathlib/RepresentationTheory/Basic.lean index 979151b7da5074..ec67d8f8cb6692 100644 --- a/Mathlib/RepresentationTheory/Basic.lean +++ b/Mathlib/RepresentationTheory/Basic.lean @@ -13,11 +13,10 @@ representations. ## Main definitions - * Representation.Representation - * Representation.character - * Representation.tprod - * Representation.linHom - * Representation.dual + * `Representation` + * `Representation.tprod` + * `Representation.linHom` + * `Representation.dual` ## Implementation notes @@ -26,7 +25,7 @@ homomorphisms `G →* (V →ₗ[k] V)`. We use the abbreviation `Representation` The theorem `asAlgebraHom_def` constructs a module over the group `k`-algebra of `G` (implemented as `MonoidAlgebra k G`) corresponding to a representation. If `ρ : Representation k G V`, this -module can be accessed via `ρ.asModule`. Conversely, given a `MonoidAlgebra k G-module `M` +module can be accessed via `ρ.asModule`. Conversely, given a `MonoidAlgebra k G`-module `M`, `M.ofModule` is the associociated representation seen as a homomorphism. -/ @@ -449,7 +448,7 @@ theorem dual_apply (g : G) : (dual ρV) g = Module.Dual.transpose (R := k) (ρV rfl /-- Given $k$-modules $V, W$, there is a homomorphism $φ : V^* ⊗ W → Hom_k(V, W)$ -(implemented by `LinearAlgebra.Contraction.dualTensorHom`). +(implemented by `dualTensorHom` in `Mathlib.LinearAlgebra.Contraction`). Given representations of $G$ on $V$ and $W$,there are representations of $G$ on $V^* ⊗ W$ and on $Hom_k(V, W)$. This lemma says that $φ$ is $G$-linear. diff --git a/Mathlib/RepresentationTheory/Character.lean b/Mathlib/RepresentationTheory/Character.lean index b68c19284a62c3..5479f9417977f8 100644 --- a/Mathlib/RepresentationTheory/Character.lean +++ b/Mathlib/RepresentationTheory/Character.lean @@ -19,8 +19,8 @@ is the theorem `char_orthonormal` ## Implementation notes -Irreducible representations are implemented categorically, using the `Simple` class defined in -`Mathlib.CategoryTheory.Simple` +Irreducible representations are implemented categorically, using the `CategoryTheory.Simple` class +defined in `Mathlib.CategoryTheory.Simple` ## TODO * Once we have the monoidal closed structure on `FdRep k G` and a better API for the rigid diff --git a/Mathlib/RepresentationTheory/GroupCohomology/Basic.lean b/Mathlib/RepresentationTheory/GroupCohomology/Basic.lean index 3d60e4b43bfb41..4e6c54c0981d08 100644 --- a/Mathlib/RepresentationTheory/GroupCohomology/Basic.lean +++ b/Mathlib/RepresentationTheory/GroupCohomology/Basic.lean @@ -30,8 +30,8 @@ $\mathrm{H}^n(G, A) \cong \mathrm{Ext}^n(k, A),$ where $\mathrm{Ext}$ is taken i `Rep k G`. To talk about cohomology in low degree, please see the file -`RepresentationTheory.GroupCohomology.LowDegree`, which gives simpler expressions for `H⁰, H¹, H²` -than the definition `groupCohomology` in this file. +`Mathlib.RepresentationTheory.GroupCohomology.LowDegree`, which gives simpler expressions for +`H⁰`, `H¹`, `H²` than the definition `groupCohomology` in this file. ## Main definitions diff --git a/Mathlib/RepresentationTheory/GroupCohomology/Resolution.lean b/Mathlib/RepresentationTheory/GroupCohomology/Resolution.lean index c99ba8f5afb4ec..b43c932f7d3bc4 100644 --- a/Mathlib/RepresentationTheory/GroupCohomology/Resolution.lean +++ b/Mathlib/RepresentationTheory/GroupCohomology/Resolution.lean @@ -23,9 +23,9 @@ This allows us to define a `k[G]`-basis on `k[Gⁿ⁺¹]`, by mapping the natura We then define the standard resolution of `k` as a trivial representation, by taking the alternating face map complex associated to an appropriate simplicial `k`-linear -`G`-representation. This simplicial object is the `linearization` of the simplicial `G`-set given -by the universal cover of the classifying space of `G`, `EG`. We prove this simplicial `G`-set `EG` -is isomorphic to the Čech nerve of the natural arrow of `G`-sets `G ⟶ {pt}`. +`G`-representation. This simplicial object is the `Rep.linearization` of the simplicial `G`-set +given by the universal cover of the classifying space of `G`, `EG`. We prove this simplicial +`G`-set `EG` is isomorphic to the Čech nerve of the natural arrow of `G`-sets `G ⟶ {pt}`. We then use this isomorphism to deduce that as a complex of `k`-modules, the standard resolution of `k` as a trivial `G`-representation is homotopy equivalent to the complex with `k` at 0 and 0 From efad68b785a481b7e8631e18eea0bc305c0414a9 Mon Sep 17 00:00:00 2001 From: Christopher Hoskin Date: Thu, 17 Oct 2024 07:12:41 +0000 Subject: [PATCH 271/425] feat(Analysis/LocallyConvex/AbsConvex): Define the Absolutely Convex Hull (#17029) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Defines the absolutely convex (or disked) hull of a subset of a locally convex space and proves a number of standard properties, including: - (subject to suitable conditions) the absolutely convex hull equals the convex hull of the balanced hull. - In a real vector space the absolutely convex hull of `s` equals the convex hull of `s ∪ -s` Co-authored-by: Christopher Hoskin --- Mathlib/Analysis/LocallyConvex/AbsConvex.lean | 192 ++++++++++++++++-- .../LocallyConvex/BalancedCoreHull.lean | 14 ++ Mathlib/Analysis/LocallyConvex/Basic.lean | 3 + 3 files changed, 197 insertions(+), 12 deletions(-) diff --git a/Mathlib/Analysis/LocallyConvex/AbsConvex.lean b/Mathlib/Analysis/LocallyConvex/AbsConvex.lean index 5cf175db643ff2..f9e44391da1b4c 100644 --- a/Mathlib/Analysis/LocallyConvex/AbsConvex.lean +++ b/Mathlib/Analysis/LocallyConvex/AbsConvex.lean @@ -10,23 +10,33 @@ import Mathlib.Analysis.Convex.Gauge /-! # Absolutely convex sets -A set is called absolutely convex or disked if it is convex and balanced. -The importance of absolutely convex sets comes from the fact that every locally convex +A set `s` in an commutative monoid `E` is called absolutely convex or disked if it is convex and +balanced. The importance of absolutely convex sets comes from the fact that every locally convex topological vector space has a basis consisting of absolutely convex sets. ## Main definitions +* `absConvexHull`: the absolutely convex hull of a set `s` is the smallest absolutely convex set + containing `s`. * `gaugeSeminormFamily`: the seminorm family induced by all open absolutely convex neighborhoods of zero. ## Main statements +* `absConvexHull_eq_convexHull_balancedHull`: when the locally convex space is a module, the + absolutely convex hull of a set `s` equals the convex hull of the balanced hull of `s`. +* `convexHull_union_neg_eq_absConvexHull`: the convex hull of `s ∪ -s` is the absolute convex hull + of `s`. * `with_gaugeSeminormFamily`: the topology of a locally convex space is induced by the family `gaugeSeminormFamily`. -## TODO +## Implementation notes -* Define the disked hull +Mathlib's definition of `Convex` requires the scalars to be an `OrderedSemiring` whereas the +definition of `Balanced` requires the scalars to be a `SeminormedRing`. Mathlib doesn't currently +have a concept of a semi-normed ordered ring, so we define a set as `AbsConvex` if it is balanced +over a `SeminormedRing` `𝕜` and convex over `ℝ`, assuming `IsScalarTower ℝ 𝕜 E` and +`SMulCommClass ℝ 𝕜 E` where required. ## Tags @@ -40,6 +50,104 @@ open NNReal Pointwise Topology variable {𝕜 E F G ι : Type*} +section AbsolutelyConvex + +variable (𝕜) [SeminormedRing 𝕜] [SMul 𝕜 E] [SMul ℝ E] [AddCommMonoid E] +/-- A set is absolutely convex if it is balanced and convex. Mathlib's definition of `Convex` +requires the scalars to be an `OrderedSemiring` whereas the definition of `Balanced` requires the +scalars to be a `SeminormedRing`. Mathlib doesn't currently have a concept of a semi-normed ordered +ring, so we define a set as `AbsConvex` if it is balanced over a `SeminormedRing` `𝕜` and convex +over `ℝ`. -/ +def AbsConvex (s : Set E) : Prop := Balanced 𝕜 s ∧ Convex ℝ s + +variable {𝕜} + +theorem AbsConvex.empty : AbsConvex 𝕜 (∅ : Set E) := ⟨balanced_empty, convex_empty⟩ + +theorem AbsConvex.univ : AbsConvex 𝕜 (univ : Set E) := ⟨balanced_univ, convex_univ⟩ + +theorem AbsConvex.inter {s t : Set E} (hs : AbsConvex 𝕜 s) (ht : AbsConvex 𝕜 t) : + AbsConvex 𝕜 (s ∩ t) := ⟨hs.1.inter ht.1, hs.2.inter ht.2⟩ + +theorem AbsConvex.sInter {S : Set (Set E)} (h : ∀ s ∈ S, AbsConvex 𝕜 s) : AbsConvex 𝕜 (⋂₀ S) := + ⟨.sInter fun s hs => (h s hs).1, convex_sInter fun s hs => (h s hs).2⟩ + +theorem AbsConvex.iInter {ι : Sort*} {s : ι → Set E} (h : ∀ i, AbsConvex 𝕜 (s i)) : + AbsConvex 𝕜 (⋂ i, s i) := + sInter_range s ▸ AbsConvex.sInter <| forall_mem_range.2 h + +variable (𝕜) + +/-- The absolute convex hull of a set `s` is the minimal absolute convex set that includes `s`. -/ +@[simps! isClosed] +def absConvexHull : ClosureOperator (Set E) := + .ofCompletePred (AbsConvex 𝕜) fun _ ↦ .sInter + +variable {𝕜} {s : Set E} + +theorem subset_absConvexHull : s ⊆ absConvexHull 𝕜 s := + (absConvexHull 𝕜).le_closure s + +theorem absConvex_absConvexHull : AbsConvex 𝕜 (absConvexHull 𝕜 s) := + (absConvexHull 𝕜).isClosed_closure s + +theorem balanced_absConvexHull : Balanced 𝕜 (absConvexHull 𝕜 s) := + absConvex_absConvexHull.1 + +theorem convex_absConvexHull : Convex ℝ (absConvexHull 𝕜 s) := + absConvex_absConvexHull.2 + +variable (𝕜 s) in +theorem absConvexHull_eq_iInter : + absConvexHull 𝕜 s = ⋂ (t : Set E) (_ : s ⊆ t) (_ : AbsConvex 𝕜 t), t := by + simp [absConvexHull, iInter_subtype, iInter_and] + +variable {t : Set E} {x y : E} + +theorem mem_absConvexHull_iff : x ∈ absConvexHull 𝕜 s ↔ ∀ t, s ⊆ t → AbsConvex 𝕜 t → x ∈ t := by + simp_rw [absConvexHull_eq_iInter, mem_iInter] + +theorem absConvexHull_min : s ⊆ t → AbsConvex 𝕜 t → absConvexHull 𝕜 s ⊆ t := + (absConvexHull 𝕜).closure_min + +theorem AbsConvex.absConvexHull_subset_iff (ht : AbsConvex 𝕜 t) : absConvexHull 𝕜 s ⊆ t ↔ s ⊆ t := + (show (absConvexHull 𝕜).IsClosed t from ht).closure_le_iff + +@[mono, gcongr] +theorem absConvexHull_mono (hst : s ⊆ t) : absConvexHull 𝕜 s ⊆ absConvexHull 𝕜 t := + (absConvexHull 𝕜).monotone hst + +lemma absConvexHull_eq_self : absConvexHull 𝕜 s = s ↔ AbsConvex 𝕜 s := + (absConvexHull 𝕜).isClosed_iff.symm + +alias ⟨_, AbsConvex.absConvexHull_eq⟩ := absConvexHull_eq_self + +@[simp] +theorem absConvexHull_univ : absConvexHull 𝕜 (univ : Set E) = univ := + ClosureOperator.closure_top (absConvexHull 𝕜) + +@[simp] +theorem absConvexHull_empty : absConvexHull 𝕜 (∅ : Set E) = ∅ := + AbsConvex.empty.absConvexHull_eq + +@[simp] +theorem absConvexHull_eq_empty : absConvexHull 𝕜 s = ∅ ↔ s = ∅ := by + constructor + · intro h + rw [← Set.subset_empty_iff, ← h] + exact subset_absConvexHull + · rintro rfl + exact absConvexHull_empty + +@[simp] +theorem absConvexHull_nonempty : (absConvexHull 𝕜 s).Nonempty ↔ s.Nonempty := by + rw [nonempty_iff_ne_empty, nonempty_iff_ne_empty, Ne, Ne] + exact not_congr absConvexHull_eq_empty + +protected alias ⟨_, Set.Nonempty.absConvexHull⟩ := absConvexHull_nonempty + +end AbsolutelyConvex + section NontriviallyNormedField variable (𝕜 E) {s : Set E} @@ -47,8 +155,8 @@ variable [NontriviallyNormedField 𝕜] [AddCommGroup E] [Module 𝕜 E] variable [Module ℝ E] [SMulCommClass ℝ 𝕜 E] variable [TopologicalSpace E] [LocallyConvexSpace ℝ E] [ContinuousSMul 𝕜 E] -theorem nhds_basis_abs_convex : - (𝓝 (0 : E)).HasBasis (fun s : Set E => s ∈ 𝓝 (0 : E) ∧ Balanced 𝕜 s ∧ Convex ℝ s) id := by +theorem nhds_hasBasis_absConvex : + (𝓝 (0 : E)).HasBasis (fun s : Set E => s ∈ 𝓝 (0 : E) ∧ AbsConvex 𝕜 s) id := by refine (LocallyConvexSpace.convex_basis_zero ℝ E).to_hasBasis (fun s hs => ?_) fun s hs => ⟨s, ⟨hs.1, hs.2.2⟩, rfl.subset⟩ @@ -59,9 +167,9 @@ theorem nhds_basis_abs_convex : variable [ContinuousSMul ℝ E] [TopologicalAddGroup E] -theorem nhds_basis_abs_convex_open : - (𝓝 (0 : E)).HasBasis (fun s => (0 : E) ∈ s ∧ IsOpen s ∧ Balanced 𝕜 s ∧ Convex ℝ s) id := by - refine (nhds_basis_abs_convex 𝕜 E).to_hasBasis ?_ ?_ +theorem nhds_hasBasis_absConvex_open : + (𝓝 (0 : E)).HasBasis (fun s => (0 : E) ∈ s ∧ IsOpen s ∧ AbsConvex 𝕜 s) id := by + refine (nhds_hasBasis_absConvex 𝕜 E).to_hasBasis ?_ ?_ · rintro s ⟨hs_nhds, hs_balanced, hs_convex⟩ refine ⟨interior s, ?_, interior_subset⟩ exact @@ -72,6 +180,66 @@ theorem nhds_basis_abs_convex_open : end NontriviallyNormedField +section + +variable (𝕜) [NontriviallyNormedField 𝕜] +variable [AddCommGroup E] [Module ℝ E] [Module 𝕜 E] + +theorem absConvexHull_add_subset {s t : Set E} : + absConvexHull 𝕜 (s + t) ⊆ absConvexHull 𝕜 s + absConvexHull 𝕜 t := + absConvexHull_min (add_subset_add subset_absConvexHull subset_absConvexHull) + ⟨Balanced.add balanced_absConvexHull balanced_absConvexHull, + Convex.add convex_absConvexHull convex_absConvexHull⟩ + +theorem absConvexHull_eq_convexHull_balancedHull [SMulCommClass ℝ 𝕜 E] {s : Set E} : + absConvexHull 𝕜 s = convexHull ℝ (balancedHull 𝕜 s) := le_antisymm + (absConvexHull_min + ((subset_convexHull ℝ s).trans (convexHull_mono (subset_balancedHull 𝕜))) + ⟨Balanced.convexHull (balancedHull.balanced s), convex_convexHull ..⟩) + (convexHull_min (balanced_absConvexHull.balancedHull_subset_of_subset subset_absConvexHull) + convex_absConvexHull) + +/-- In general, equality doesn't hold here - e.g. consider `s := {(-1, 1), (1, 1)}` in `ℝ²`. -/ +theorem balancedHull_convexHull_subseteq_absConvexHull {s : Set E} : + balancedHull 𝕜 (convexHull ℝ s) ⊆ absConvexHull 𝕜 s := + balanced_absConvexHull.balancedHull_subset_of_subset + (convexHull_min subset_absConvexHull convex_absConvexHull) + +end + +section + +variable [AddCommGroup E] [Module ℝ E] + +lemma balancedHull_subset_convexHull_union_neg {s : Set E} : + balancedHull ℝ s ⊆ convexHull ℝ (s ∪ -s) := by + intro a ha + obtain ⟨r, hr, y, hy, rfl⟩ := mem_balancedHull_iff.1 ha + apply segment_subset_convexHull (mem_union_left (-s) hy) (mem_union_right _ (neg_mem_neg.mpr hy)) + refine ⟨(1 + r)/2, (1 - r)/2, ?_, ?_⟩ + · rw [← zero_div 2] + exact (div_le_div_right zero_lt_two).mpr (neg_le_iff_add_nonneg'.mp (neg_le_of_abs_le hr)) + · constructor + · rw [← zero_div 2] + exact (div_le_div_right zero_lt_two).mpr (sub_nonneg_of_le (le_of_max_le_left hr)) + · constructor + · ring_nf + · rw [smul_neg, ← sub_eq_add_neg, ← sub_smul] + apply congrFun (congrArg HSMul.hSMul _) y + ring_nf + +@[simp] +theorem convexHull_union_neg_eq_absConvexHull {s : Set E} : + convexHull ℝ (s ∪ -s) = absConvexHull ℝ s := by + rw [absConvexHull_eq_convexHull_balancedHull] + exact le_antisymm (convexHull_mono (union_subset (subset_balancedHull ℝ) + (fun _ _ => by rw [mem_balancedHull_iff]; use -1; aesop))) + (by + rw [← Convex.convexHull_eq (convex_convexHull ℝ (s ∪ -s))] + exact convexHull_mono balancedHull_subset_convexHull_union_neg) + +end + section AbsolutelyConvexSets variable [TopologicalSpace E] [AddCommMonoid E] [Zero E] [SeminormedRing 𝕜] @@ -80,7 +248,7 @@ variable (𝕜 E) /-- The type of absolutely convex open sets. -/ def AbsConvexOpenSets := - { s : Set E // (0 : E) ∈ s ∧ IsOpen s ∧ Balanced 𝕜 s ∧ Convex ℝ s } + { s : Set E // (0 : E) ∈ s ∧ IsOpen s ∧ AbsConvex 𝕜 s } noncomputable instance AbsConvexOpenSets.instCoeTC : CoeTC (AbsConvexOpenSets 𝕜 E) (Set E) := ⟨Subtype.val⟩ @@ -139,7 +307,7 @@ variable [SMulCommClass ℝ 𝕜 E] [LocallyConvexSpace ℝ E] /-- 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 _ ?_ - refine (nhds_basis_abs_convex_open 𝕜 E).to_hasBasis (fun s hs => ?_) fun s hs => ?_ + refine (nhds_hasBasis_absConvex_open 𝕜 E).to_hasBasis (fun s hs => ?_) fun s hs => ?_ · refine ⟨s, ⟨?_, rfl.subset⟩⟩ convert (gaugeSeminormFamily _ _).basisSets_singleton_mem ⟨s, hs⟩ one_pos rw [gaugeSeminormFamily_ball, Subtype.coe_mk] @@ -152,7 +320,7 @@ theorem with_gaugeSeminormFamily : WithSeminorms (gaugeSeminormFamily 𝕜 E) := ⟨mem_iInter₂.mpr fun _ _ => by simp [Seminorm.mem_ball_zero, hr], isOpen_biInter_finset fun S _ => ?_, balanced_iInter₂ fun _ _ => Seminorm.balanced_ball_zero _ _, - convex_iInter₂ fun _ _ => Seminorm.convex_ball _ _ _⟩ + convex_iInter₂ fun _ _ => Seminorm.convex_ball ..⟩ -- The only nontrivial part is to show that the ball is open have hr' : r = ‖(r : 𝕜)‖ * 1 := by simp [abs_of_pos hr] have hr'' : (r : 𝕜) ≠ 0 := by simp [hr.ne'] diff --git a/Mathlib/Analysis/LocallyConvex/BalancedCoreHull.lean b/Mathlib/Analysis/LocallyConvex/BalancedCoreHull.lean index 08b82218840f49..bf2b65c776bf03 100644 --- a/Mathlib/Analysis/LocallyConvex/BalancedCoreHull.lean +++ b/Mathlib/Analysis/LocallyConvex/BalancedCoreHull.lean @@ -104,6 +104,14 @@ theorem Balanced.balancedHull_subset_of_subset (ht : Balanced 𝕜 t) (h : s ⊆ obtain ⟨r, hr, y, hy, rfl⟩ := mem_balancedHull_iff.1 hx exact ht.smul_mem hr (h hy) +@[mono, gcongr] +theorem balancedHull_mono (hst : s ⊆ t) : balancedHull 𝕜 s ⊆ balancedHull 𝕜 t := by + intro x hx + rw [mem_balancedHull_iff] at * + obtain ⟨r, hr₁, hr₂⟩ := hx + use r + exact ⟨hr₁, smul_set_mono hst hr₂⟩ + end SMul section Module @@ -133,6 +141,12 @@ theorem balancedHull.balanced (s : Set E) : Balanced 𝕜 (balancedHull 𝕜 s) rw [← smul_assoc] at hx exact ⟨a • r, (SeminormedRing.norm_mul _ _).trans (mul_le_one₀ ha (norm_nonneg r) hr), hx⟩ +open Balanced in +theorem balancedHull_add_subset [NormOneClass 𝕜] {t : Set E} : + balancedHull 𝕜 (s + t) ⊆ balancedHull 𝕜 s + balancedHull 𝕜 t := + balancedHull_subset_of_subset (add (balancedHull.balanced _) (balancedHull.balanced _)) + (add_subset_add (subset_balancedHull _) (subset_balancedHull _)) + end Module end SeminormedRing diff --git a/Mathlib/Analysis/LocallyConvex/Basic.lean b/Mathlib/Analysis/LocallyConvex/Basic.lean index b8e661ddf003f1..ffe0e4d997485d 100644 --- a/Mathlib/Analysis/LocallyConvex/Basic.lean +++ b/Mathlib/Analysis/LocallyConvex/Basic.lean @@ -95,6 +95,9 @@ theorem balanced_iUnion₂ {f : ∀ i, κ i → Set E} (h : ∀ i j, Balanced Balanced 𝕜 (⋃ (i) (j), f i j) := balanced_iUnion fun _ => balanced_iUnion <| h _ +theorem Balanced.sInter {S : Set (Set E)} (h : ∀ s ∈ S, Balanced 𝕜 s) : Balanced 𝕜 (⋂₀ S) := + fun _ _ => (smul_set_sInter_subset ..).trans (fun _ _ => by aesop) + theorem balanced_iInter {f : ι → Set E} (h : ∀ i, Balanced 𝕜 (f i)) : Balanced 𝕜 (⋂ i, f i) := fun _a ha => (smul_set_iInter_subset _ _).trans <| iInter_mono fun _ => h _ _ ha From 4f4f4ec65ea3234d6eb302a3356ef2376cc5afa3 Mon Sep 17 00:00:00 2001 From: Hannah Fechtner <123216642+hannahfechtner@users.noreply.github.com> Date: Thu, 17 Oct 2024 07:12:43 +0000 Subject: [PATCH 272/425] feat(Algebra/FreeMonoid/Basic): define length, symbols, membership, reversing, induction principles (#17180) add these properties for future use in the braid monoid (I have avoided duplicating the List API when possible, ex: using FreeMonoid.lift. These are the remaining properties I need to add) Co-authored-by: Hannah Fechtner --- Mathlib/Algebra/FreeMonoid/Basic.lean | 147 ++++++++++++++++++ .../Algebra/Group/Submonoid/Membership.lean | 6 +- Mathlib/Control/Fold.lean | 7 +- Mathlib/GroupTheory/Coprod/Basic.lean | 12 +- 4 files changed, 160 insertions(+), 12 deletions(-) diff --git a/Mathlib/Algebra/FreeMonoid/Basic.lean b/Mathlib/Algebra/FreeMonoid/Basic.lean index c2a87d24b37d2d..3ad679d33b048e 100644 --- a/Mathlib/Algebra/FreeMonoid/Basic.lean +++ b/Mathlib/Algebra/FreeMonoid/Basic.lean @@ -106,6 +106,69 @@ theorem toList_of_mul (x : α) (xs : FreeMonoid α) : toList (of x * xs) = x :: @[to_additive] theorem of_injective : Function.Injective (@of α) := List.singleton_injective +/-! ### Length -/ + +section Length +variable {a : FreeMonoid α} + +/-- The length of a free monoid element: 1.length = 0 and (a * b).length = a.length + b.length -/ +@[to_additive "The length of an additive free monoid element: 1.length = 0 and (a + b).length = + a.length + b.length"] +def length (a : FreeMonoid α) : ℕ := List.length a + +@[to_additive (attr := simp)] +theorem length_one : length (1 : FreeMonoid α) = 0 := rfl + +@[to_additive (attr := simp)] +theorem length_eq_zero : length a = 0 ↔ a = 1 := List.length_eq_zero + +@[to_additive (attr := simp)] +theorem length_of (m : α) : length (of m) = 1 := rfl + +@[to_additive existing] +theorem length_eq_one : length a = 1 ↔ ∃ m, a = FreeMonoid.of m := + List.length_eq_one + +@[to_additive] +theorem length_eq_two {v : FreeMonoid α} : + v.length = 2 ↔ ∃ c d, v = FreeMonoid.of c * FreeMonoid.of d := List.length_eq_two + +@[to_additive (attr := simp)] +theorem length_mul (a b : FreeMonoid α) : (a * b).length = a.length + b.length := + List.length_append _ _ + +@[to_additive] +theorem of_ne_one (a : α) : of a ≠ 1 := by + intro h + have := congrArg FreeMonoid.length h + simp only [length_of, length_one, Nat.succ_ne_self] at this + +end Length + +section Mem +variable {m : α} + +/-- Membership in a free monoid element -/ +@[to_additive "Membership in a free monoid element"] +def mem (a : FreeMonoid α) (m : α) := m ∈ toList a + +@[to_additive] +instance : Membership α (FreeMonoid α) := ⟨mem⟩ + +@[to_additive] +theorem not_mem_one : ¬ m ∈ (1 : FreeMonoid α) := List.not_mem_nil _ + +@[to_additive (attr := simp)] +theorem mem_of {n : α} : m ∈ of n ↔ m = n := List.mem_singleton + +@[to_additive] +theorem mem_of_self : m ∈ of m := List.mem_singleton_self _ + +@[to_additive (attr := simp)] +theorem mem_mul {a b : FreeMonoid α} : m ∈ (a * b) ↔ m ∈ a ∨ m ∈ b := List.mem_append + +end Mem + /-- Recursor for `FreeMonoid` using `1` and `FreeMonoid.of x * xs` instead of `[]` and `x :: xs`. -/ @[to_additive (attr := elab_as_elim, induction_eliminator) "Recursor for `FreeAddMonoid` using `0` and @@ -123,6 +186,27 @@ theorem recOn_of_mul {C : FreeMonoid α → Sort*} (x : α) (xs : FreeMonoid α) (ih : ∀ x xs, C xs → C (of x * xs)) : @recOn α C (of x * xs) h0 ih = ih x xs (recOn xs h0 ih) := rfl +/-! ### Induction -/ + +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 + +/-- 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 + +end induction_principles + /-- A version of `List.cases_on` for `FreeMonoid` using `1` and `FreeMonoid.of x * xs` instead of `[]` and `x :: xs`. -/ @[to_additive (attr := elab_as_elim, cases_eliminator) @@ -220,6 +304,10 @@ theorem of_smul (f : α → β → β) (x : α) (y : β) : (haveI := mkMulAction f of x • y) = f x y := rfl +/-! ### map -/ + +section Map +variable {f : α → β} {a b : FreeMonoid α} /-- The unique monoid homomorphism `FreeMonoid α →* FreeMonoid β` that sends each `of x` to `of (f x)`. -/ @[to_additive "The unique additive monoid homomorphism `FreeAddMonoid α →+ FreeAddMonoid β` @@ -232,6 +320,15 @@ def map (f : α → β) : FreeMonoid α →* FreeMonoid β where @[to_additive (attr := simp)] 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 + +@[to_additive] +theorem map_map {α₁ : Type*} {g : α₁ → α} {x : FreeMonoid α₁} : + map f (map g x) = map (f ∘ g) x := by + unfold map + simp only [MonoidHom.coe_mk, OneHom.coe_mk, toList_ofList, List.map_map] + @[to_additive] theorem toList_map (f : α → β) (xs : FreeMonoid α) : toList (map f xs) = xs.toList.map f := rfl @@ -254,4 +351,54 @@ instance uniqueUnits : Unique (FreeMonoid α)ˣ where have : toList u.val ++ toList u.inv = [] := DFunLike.congr_arg toList u.val_inv (List.append_eq_nil.mp this).1 +@[to_additive (attr := simp)] +theorem map_surjective {f : α → β} : Function.Surjective (map f) ↔ Function.Surjective f := by + constructor + · intro fs d + rcases fs (FreeMonoid.of d) with ⟨b, hb⟩ + induction' b using FreeMonoid.inductionOn' with head _ _ + · have H := congr_arg length hb + simp only [length_one, length_of, Nat.zero_ne_one, map_one] at H + simp only [map_mul, map_of] at hb + use head + have H := congr_arg length hb + simp only [length_mul, length_of, add_right_eq_self, length_eq_zero] at H + rw [H, mul_one] at hb + exact FreeMonoid.of_injective hb + intro fs d + induction' d using FreeMonoid.inductionOn' with head tail ih + · use 1 + rfl + specialize fs head + rcases fs with ⟨a, rfl⟩ + rcases ih with ⟨b, rfl⟩ + use FreeMonoid.of a * b + rfl + +end Map + +/-! ### reverse -/ + +section Reverse +/-- reverses the symbols in a free monoid element -/ +@[to_additive "reverses the symbols in an additive free monoid element"] +def reverse : FreeMonoid α → FreeMonoid α := List.reverse + +@[to_additive (attr := simp)] +theorem reverse_of (a : α) : reverse (of a) = of a := rfl + +@[to_additive] +theorem reverse_mul {a b : FreeMonoid α} : reverse (a * b) = reverse b * reverse a := + List.reverse_append _ _ + +@[to_additive (attr := simp)] +theorem reverse_reverse {a : FreeMonoid α} : reverse (reverse a) = a := by + apply List.reverse_reverse + +@[to_additive (attr := simp)] +theorem length_reverse {a : FreeMonoid α} : a.reverse.length = a.length := + List.length_reverse _ + +end Reverse + end FreeMonoid diff --git a/Mathlib/Algebra/Group/Submonoid/Membership.lean b/Mathlib/Algebra/Group/Submonoid/Membership.lean index 632e86eea4ba5f..2c5e76300f6472 100644 --- a/Mathlib/Algebra/Group/Submonoid/Membership.lean +++ b/Mathlib/Algebra/Group/Submonoid/Membership.lean @@ -356,9 +356,9 @@ theorem closure_induction_left {s : Set M} {p : (m : M) → m ∈ closure s → p x h := by simp_rw [closure_eq_mrange] at h obtain ⟨l, rfl⟩ := h - induction l with - | h0 => exact one - | ih x y ih => + induction l using FreeMonoid.inductionOn' with + | one => exact one + | mul_of 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/Control/Fold.lean b/Mathlib/Control/Fold.lean index 711e71a9106354..62e4e80dddadbb 100644 --- a/Mathlib/Control/Fold.lean +++ b/Mathlib/Control/Fold.lean @@ -301,9 +301,10 @@ theorem toList_spec (xs : t α) : toList xs = FreeMonoid.toList (foldMap FreeMon calc FreeMonoid.toList (foldMap FreeMonoid.of xs) = FreeMonoid.toList (foldMap FreeMonoid.of xs).reverse.reverse := by - simp only [List.reverse_reverse] - _ = FreeMonoid.toList (List.foldr cons [] (foldMap FreeMonoid.of xs).reverse).reverse := by - simp only [List.foldr_eta] + simp only [FreeMonoid.reverse_reverse] + _ = (List.foldr cons [] (foldMap FreeMonoid.of xs).toList.reverse).reverse := by + simp only [FreeMonoid.reverse_reverse, List.foldr_reverse, List.foldl_flip_cons_eq_append, + List.append_nil, List.reverse_reverse] _ = (unop (Foldl.ofFreeMonoid (flip cons) (foldMap FreeMonoid.of xs)) []).reverse := by #adaptation_note /-- nightly-2024-03-16: simp was simp [flip, List.foldr_reverse, Foldl.ofFreeMonoid, unop_op] -/ diff --git a/Mathlib/GroupTheory/Coprod/Basic.lean b/Mathlib/GroupTheory/Coprod/Basic.lean index 2349d4a1dad9bf..169ff1d0e0bc63 100644 --- a/Mathlib/GroupTheory/Coprod/Basic.lean +++ b/Mathlib/GroupTheory/Coprod/Basic.lean @@ -191,9 +191,9 @@ theorem induction_on' {C : M ∗ N → Prop} (m : M ∗ N) (inl_mul : ∀ m x, C x → C (inl m * x)) (inr_mul : ∀ n x, C x → C (inr n * x)) : C m := by rcases mk_surjective m with ⟨x, rfl⟩ - induction x with - | h0 => exact one - | ih x xs ih => + induction x using FreeMonoid.inductionOn' with + | one => exact one + | mul_of x xs ih => cases x with | inl m => simpa using inl_mul m _ ih | inr n => simpa using inr_mul n _ ih @@ -573,9 +573,9 @@ theorem mk_of_inv_mul : ∀ x : G ⊕ H, mk (of (x.map Inv.inv Inv.inv)) * mk (o theorem con_inv_mul_cancel (x : FreeMonoid (G ⊕ H)) : coprodCon G H (ofList (x.toList.map (Sum.map Inv.inv Inv.inv)).reverse * x) 1 := by rw [← mk_eq_mk, map_mul, map_one] - induction x with - | h0 => simp [map_one mk] -- TODO: fails without `[map_one mk]` - | ih x xs ihx => + induction x using FreeMonoid.inductionOn' with + | one => simp + | mul_of x xs ihx => simp only [toList_of_mul, map_cons, reverse_cons, ofList_append, map_mul, ihx, ofList_singleton] rwa [mul_assoc, ← mul_assoc (mk (of _)), mk_of_inv_mul, one_mul] From dc48f47da5a6275c7d25a00cf82c2684af1e754d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 17 Oct 2024 07:12:44 +0000 Subject: [PATCH 273/425] feat(CategoryTheory/Products): an ext lemma for morphisms in product categories (#17721) Until now, in order to check an identity of morphisms in a product category, we had to do `dsimp; ext`. Now, `ext` would also work, which shall ease automation in some future applications. --- Mathlib/CategoryTheory/Abelian/NonPreadditive.lean | 4 ++-- Mathlib/CategoryTheory/Closed/Ideal.lean | 2 +- Mathlib/CategoryTheory/Generator.lean | 2 +- Mathlib/CategoryTheory/Limits/Connected.lean | 4 ++-- .../CategoryTheory/Limits/Shapes/NormalMono/Equalizers.lean | 4 ++-- Mathlib/CategoryTheory/Monad/Products.lean | 2 +- Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean | 2 +- Mathlib/CategoryTheory/Products/Basic.lean | 5 +++++ 8 files changed, 15 insertions(+), 10 deletions(-) diff --git a/Mathlib/CategoryTheory/Abelian/NonPreadditive.lean b/Mathlib/CategoryTheory/Abelian/NonPreadditive.lean index 680956963fe88c..810dadb3c8117c 100644 --- a/Mathlib/CategoryTheory/Abelian/NonPreadditive.lean +++ b/Mathlib/CategoryTheory/Abelian/NonPreadditive.lean @@ -232,12 +232,12 @@ instance epi_r {A : C} : Epi (r A) := by let hp1 : IsLimit (KernelFork.ofι (prod.lift (𝟙 A) (0 : A ⟶ A)) hlp) := by refine Fork.IsLimit.mk _ (fun s => Fork.ι s ≫ Limits.prod.fst) ?_ ?_ · intro s - apply prod.hom_ext <;> simp + 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 _ _) apply (cancel_mono (prod.lift (𝟙 A) (0 : A ⟶ A))).1 convert h - apply prod.hom_ext <;> simp + apply Limits.prod.hom_ext <;> simp let hp2 : IsColimit (CokernelCofork.ofπ (Limits.prod.snd : A ⨯ A ⟶ A) hlp) := epiIsCokernelOfKernel _ hp1 apply NormalMonoCategory.epi_of_zero_cancel diff --git a/Mathlib/CategoryTheory/Closed/Ideal.lean b/Mathlib/CategoryTheory/Closed/Ideal.lean index da5c0efda1a01b..588c491499a4f2 100644 --- a/Mathlib/CategoryTheory/Closed/Ideal.lean +++ b/Mathlib/CategoryTheory/Closed/Ideal.lean @@ -204,7 +204,7 @@ theorem bijection_symm_apply_id (A B : C) : rw [prod.comp_lift_assoc, prod.lift_snd, prod.lift_fst_assoc, prod.lift_fst_comp_snd_comp, ← Adjunction.eq_unit_comp_map_iff, Iso.comp_inv_eq, assoc] rw [PreservesLimitPair.iso_hom i ((reflector i).obj A) ((reflector i).obj B)] - apply prod.hom_ext + apply Limits.prod.hom_ext · rw [Limits.prod.map_fst, assoc, assoc, prodComparison_fst, ← i.map_comp, prodComparison_fst] apply (reflectorAdjunction i).unit.naturality · rw [Limits.prod.map_snd, assoc, assoc, prodComparison_snd, ← i.map_comp, prodComparison_snd] diff --git a/Mathlib/CategoryTheory/Generator.lean b/Mathlib/CategoryTheory/Generator.lean index 0424d4339d3869..91d5fd94172526 100644 --- a/Mathlib/CategoryTheory/Generator.lean +++ b/Mathlib/CategoryTheory/Generator.lean @@ -509,7 +509,7 @@ theorem isCoseparator_prod (G H : C) [HasBinaryProduct G H] : refine ⟨fun h X Y u v huv => ?_, fun h => (isCoseparator_def _).2 fun X Y u v huv => h _ _ fun Z hZ g => ?_⟩ - · refine h.def _ _ fun g => prod.hom_ext ?_ ?_ + · refine h.def _ _ fun g => Limits.prod.hom_ext ?_ ?_ · simpa using huv G (by simp) (g ≫ Limits.prod.fst) · simpa using huv H (by simp) (g ≫ Limits.prod.snd) · simp only [Set.mem_insert_iff, Set.mem_singleton_iff] at hZ diff --git a/Mathlib/CategoryTheory/Limits/Connected.lean b/Mathlib/CategoryTheory/Limits/Connected.lean index 82a4900695c0d7..712b12fbf11488 100644 --- a/Mathlib/CategoryTheory/Limits/Connected.lean +++ b/Mathlib/CategoryTheory/Limits/Connected.lean @@ -95,12 +95,12 @@ noncomputable def prodPreservesConnectedLimits [IsConnected J] (X : C) : { lift := fun s => prod.lift (s.π.app (Classical.arbitrary _) ≫ Limits.prod.fst) (l.lift (forgetCone s)) fac := fun s j => by - apply prod.hom_ext + apply Limits.prod.hom_ext · erw [assoc, limMap_π, comp_id, limit.lift_π] exact (nat_trans_from_is_connected (s.π ≫ γ₁ X) j (Classical.arbitrary _)).symm · simp [← l.fac (forgetCone s) j] uniq := fun s m L => by - apply prod.hom_ext + apply Limits.prod.hom_ext · erw [limit.lift_π, ← L (Classical.arbitrary J), assoc, limMap_π, comp_id] rfl · rw [limit.lift_π] diff --git a/Mathlib/CategoryTheory/Limits/Shapes/NormalMono/Equalizers.lean b/Mathlib/CategoryTheory/Limits/Shapes/NormalMono/Equalizers.lean index c71d6af56f0d8a..67d189d906d5d7 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/NormalMono/Equalizers.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/NormalMono/Equalizers.lean @@ -55,7 +55,7 @@ def pullback_of_mono {X Y Z : C} (a : X ⟶ Z) (b : Y ⟶ Z) [Mono a] [Mono b] : PullbackCone.IsLimit.mk _ (fun s => kernel.lift (prod.lift f g) (PullbackCone.snd s ≫ b) <| - prod.hom_ext + Limits.prod.hom_ext (calc ((PullbackCone.snd s ≫ b) ≫ prod.lift f g) ≫ Limits.prod.fst = PullbackCone.snd s ≫ b ≫ f := by simp only [prod.lift_fst, Category.assoc] @@ -125,7 +125,7 @@ def hasLimit_parallelPair {X Y : C} (f g : X ⟶ Y) : HasLimit (parallelPair f g Fork.IsLimit.mk _ (fun s => pullback.lift (Fork.ι s) (Fork.ι s) <| - prod.hom_ext (by simp only [prod.lift_fst, Category.assoc]) + Limits.prod.hom_ext (by simp only [prod.lift_fst, Category.assoc]) (by simp only [prod.comp_lift, Fork.condition s])) (fun s => by simp) fun s m h => pullback.hom_ext (by simpa only [pullback.lift_fst] using h) diff --git a/Mathlib/CategoryTheory/Monad/Products.lean b/Mathlib/CategoryTheory/Monad/Products.lean index 2a42c1d2a6ff17..16ba3d6f08034a 100644 --- a/Mathlib/CategoryTheory/Monad/Products.lean +++ b/Mathlib/CategoryTheory/Monad/Products.lean @@ -73,7 +73,7 @@ def coalgebraEquivOver : Coalgebra (prodComonad X) ≌ Over X where functor := coalgebraToOver X inverse := overToCoalgebra X unitIso := NatIso.ofComponents fun A => - Coalgebra.isoMk (Iso.refl _) (prod.hom_ext (by simp) (by simpa using A.counit)) + Coalgebra.isoMk (Iso.refl _) (Limits.prod.hom_ext (by simp) (by simpa using A.counit)) counitIso := NatIso.ofComponents fun f => Over.isoMk (Iso.refl _) end diff --git a/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean b/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean index 09ea239996ebd3..9e49dda0d93bf0 100644 --- a/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean +++ b/Mathlib/CategoryTheory/Monoidal/OfHasFiniteProducts.lean @@ -73,7 +73,7 @@ open scoped MonoidalCategory @[ext] theorem tensor_ext {X Y Z : C} (f g : X ⟶ Y ⊗ Z) (w₁ : f ≫ prod.fst = g ≫ prod.fst) (w₂ : f ≫ prod.snd = g ≫ prod.snd) : f = g := - prod.hom_ext w₁ w₂ + Limits.prod.hom_ext w₁ w₂ @[simp] theorem tensorUnit : 𝟙_ C = ⊤_ C := rfl diff --git a/Mathlib/CategoryTheory/Products/Basic.lean b/Mathlib/CategoryTheory/Products/Basic.lean index 83d4a027d4ac08..dac0c3fe043ce9 100644 --- a/Mathlib/CategoryTheory/Products/Basic.lean +++ b/Mathlib/CategoryTheory/Products/Basic.lean @@ -45,6 +45,11 @@ instance prod : Category.{max v₁ v₂} (C × D) where id X := ⟨𝟙 X.1, 𝟙 X.2⟩ comp f g := (f.1 ≫ g.1, f.2 ≫ g.2) +@[ext] +lemma prod.hom_ext {X Y : C × D} {f g : X ⟶ Y} (h₁ : f.1 = g.1) (h₂ : f.2 = g.2) : f = g := by + dsimp + ext <;> assumption + /-- Two rfl lemmas that cannot be generated by `@[simps]`. -/ @[simp] theorem prod_id (X : C) (Y : D) : 𝟙 (X, Y) = (𝟙 X, 𝟙 Y) := From 8e804ebb030600c8d597aeb073a0b902f63cde14 Mon Sep 17 00:00:00 2001 From: Matthew Robert Ballard Date: Thu, 17 Oct 2024 07:12:45 +0000 Subject: [PATCH 274/425] chore(ZMod.Basic): remove unnecessary `nolint` (#17840) This does not trigger the `unusedHavesSuffices` linter. --- Mathlib/Data/ZMod/Basic.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/Data/ZMod/Basic.lean b/Mathlib/Data/ZMod/Basic.lean index d7eb347c8deeed..b8c5302f15179c 100644 --- a/Mathlib/Data/ZMod/Basic.lean +++ b/Mathlib/Data/ZMod/Basic.lean @@ -780,7 +780,6 @@ def inv : ∀ n : ℕ, ZMod n → ZMod n instance (n : ℕ) : Inv (ZMod n) := ⟨inv n⟩ -@[nolint unusedHavesSuffices] theorem inv_zero : ∀ n : ℕ, (0 : ZMod n)⁻¹ = 0 | 0 => Int.sign_zero | n + 1 => From 9caf52848a187af346984fdd790422b60183b41f Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 07:12:46 +0000 Subject: [PATCH 275/425] chore: cleanup in Data/Prod/Basic (#17841) --- Mathlib/Data/List/NatAntidiagonal.lean | 2 +- Mathlib/Data/List/Sublists.lean | 2 +- Mathlib/Data/Multiset/Antidiagonal.lean | 2 +- Mathlib/Data/Prod/Basic.lean | 15 +++++---------- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/Mathlib/Data/List/NatAntidiagonal.lean b/Mathlib/Data/List/NatAntidiagonal.lean index 3d11150f01d9e3..b7ccdccf19f709 100644 --- a/Mathlib/Data/List/NatAntidiagonal.lean +++ b/Mathlib/Data/List/NatAntidiagonal.lean @@ -60,7 +60,7 @@ theorem nodup_antidiagonal (n : ℕ) : Nodup (antidiagonal n) := theorem antidiagonal_succ {n : ℕ} : antidiagonal (n + 1) = (0, n + 1) :: (antidiagonal n).map (Prod.map Nat.succ id) := by simp only [antidiagonal, range_succ_eq_map, map_cons, Nat.add_succ_sub_one, - Nat.add_zero, id, eq_self_iff_true, Nat.sub_zero, map_map, Prod.map_mk] + Nat.add_zero, id, eq_self_iff_true, Nat.sub_zero, map_map, Prod.map_apply] apply congr rfl (congr rfl _) ext; simp diff --git a/Mathlib/Data/List/Sublists.lean b/Mathlib/Data/List/Sublists.lean index 5521bdab8a956a..bbe9b5bfedc30f 100644 --- a/Mathlib/Data/List/Sublists.lean +++ b/Mathlib/Data/List/Sublists.lean @@ -378,7 +378,7 @@ theorem revzip_sublists (l : List α) : ∀ l₁ l₂, (l₁, l₂) ∈ revzip l · intro l₁ l₂ h rw [sublists_concat, reverse_append, zip_append (by simp), ← map_reverse, zip_map_right, zip_map_left] at * - simp only [Prod.mk.inj_iff, mem_map, mem_append, Prod.map_mk, Prod.exists] at h + simp only [Prod.mk.inj_iff, mem_map, mem_append, Prod.map_apply, Prod.exists] at h rcases h with (⟨l₁, l₂', h, rfl, rfl⟩ | ⟨l₁', l₂, h, rfl, rfl⟩) · rw [← append_assoc] exact (ih _ _ h).append_right _ diff --git a/Mathlib/Data/Multiset/Antidiagonal.lean b/Mathlib/Data/Multiset/Antidiagonal.lean index df02ceb0f2f418..dea72ad65efc7c 100644 --- a/Mathlib/Data/Multiset/Antidiagonal.lean +++ b/Mathlib/Data/Multiset/Antidiagonal.lean @@ -82,7 +82,7 @@ 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 a s hs · simp only [antidiagonal_zero, powerset_zero, Multiset.zero_sub, map_singleton] - · simp_rw [antidiagonal_cons, powerset_cons, map_add, hs, map_map, Function.comp, Prod.map_mk, + · simp_rw [antidiagonal_cons, powerset_cons, map_add, hs, map_map, Function.comp, Prod.map_apply, id, sub_cons, erase_cons_head] rw [add_comm] congr 1 diff --git a/Mathlib/Data/Prod/Basic.lean b/Mathlib/Data/Prod/Basic.lean index 125f987461805d..2fbd64bdcf1818 100644 --- a/Mathlib/Data/Prod/Basic.lean +++ b/Mathlib/Data/Prod/Basic.lean @@ -42,25 +42,20 @@ theorem snd_comp_mk (x : α) : Prod.snd ∘ (Prod.mk x : β → α × β) = id : theorem fst_comp_mk (x : α) : Prod.fst ∘ (Prod.mk x : β → α × β) = Function.const β x := rfl -@[simp, mfld_simps] -theorem map_mk (f : α → γ) (g : β → δ) (a : α) (b : β) : map f g (a, b) = (f a, g b) := - rfl +@[deprecated (since := "2024-10-17")] alias map_mk := map_apply + +attribute [mfld_simps] map_apply -- This was previously a `simp` lemma, but no longer is on the basis that it destructures the pair. -- See `map_apply`, `map_fst`, and `map_snd` for slightly weaker lemmas in the `simp` set. theorem map_apply' (f : α → γ) (g : β → δ) (p : α × β) : map f g p = (f p.1, g p.2) := rfl -#adaptation_note -/-- -After `nightly-2024-06-23`, the explicitness of `map_fst` and `map_snd` will be fixed and we can -change this back to `funext <| map_fst f g`. Also in `map_snd'` below. --/ theorem map_fst' (f : α → γ) (g : β → δ) : Prod.fst ∘ map f g = f ∘ Prod.fst := - funext <| @map_fst (f := f) (g := g) + funext <| map_fst f g theorem map_snd' (f : α → γ) (g : β → δ) : Prod.snd ∘ map f g = g ∘ Prod.snd := - funext <| @map_snd (f := f) (g := g) + funext <| map_snd f g /-- Composing a `Prod.map` with another `Prod.map` is equal to a single `Prod.map` of composed functions. From abde41d4f96c622fe866005b4b410f3cb3767183 Mon Sep 17 00:00:00 2001 From: mathlib4-update-dependencies-bot <150093616+mathlib-bors@users.noreply.github.com> Date: Thu, 17 Oct 2024 07:52:57 +0000 Subject: [PATCH 276/425] chore: update Mathlib dependencies 2024-10-17 (#17856) 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 968440a4a1bb73..1dc73cf0afe47b 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "d011c00010429728fab0bb3675b13f4bce63539e", + "rev": "cc0bc876eeef0518ddc1c8d3bd6f48cc83e68901", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 91aba2b09f9c06c8dc6318d8ceef362ac0fe526b Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Thu, 17 Oct 2024 08:24:19 +0000 Subject: [PATCH 277/425] chore: bump to nightly-2024-10-17 --- lean-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lean-toolchain b/lean-toolchain index c7e012c64aaed0..22d46f9584c417 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-16 +leanprover/lean4:nightly-2024-10-17 From 21bb8348b419e6365e8b174cebc3ce95714da087 Mon Sep 17 00:00:00 2001 From: Dagur Asgeirsson Date: Thu, 17 Oct 2024 08:31:01 +0000 Subject: [PATCH 278/425] feat(Condensed): characterisation of discrete (light) condensed sets and modules (#14027) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR provides a characterization of discrete condensed sets and modules, both in the light setting and the classical one. * Six equivalent conditions on a condensed set X to be discrete 1. The counit of the discrete-underlying adjunction applied to X is an isomorphism 2. X is in the essential image of the constant sheaf functor `Type (u+1) ⥤ CondensedSet.{u}` 3. X is in the essential image of the functor `Type (u+1) ⥤ CondensedSet.{u}` which takes a set to the sheaf of locally constant maps into it. 4. The counit of the locally-constant-underlying adjunction applied to X is an isomorphism. 5. X restricted to the coherent site of profinite sets is discrete as a sheaf 6. For every profinite set S written as a limit of finite sets, X maps S to the corresponding colimit. * A condensed module over a ring is discrete if and only if its underlying condensed set is, and therefore the analogues of the equivalent conditions above also characterize condensed modules as discrete * The analogues for the above for light condensed sets and modules --- Mathlib.lean | 1 + .../Category/ModuleCat/FilteredColimits.lean | 5 +- .../Condensed/Discrete/Characterization.lean | 264 ++++++++++++++++++ 3 files changed, 269 insertions(+), 1 deletion(-) create mode 100644 Mathlib/Condensed/Discrete/Characterization.lean diff --git a/Mathlib.lean b/Mathlib.lean index 14f4a5f1fa41b0..39bb6b56e139be 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2078,6 +2078,7 @@ import Mathlib.Computability.TuringMachine import Mathlib.Condensed.Basic import Mathlib.Condensed.CartesianClosed import Mathlib.Condensed.Discrete.Basic +import Mathlib.Condensed.Discrete.Characterization import Mathlib.Condensed.Discrete.Colimit import Mathlib.Condensed.Discrete.LocallyConstant import Mathlib.Condensed.Discrete.Module diff --git a/Mathlib/Algebra/Category/ModuleCat/FilteredColimits.lean b/Mathlib/Algebra/Category/ModuleCat/FilteredColimits.lean index 16abcd32472832..58c0fe8253d3aa 100644 --- a/Mathlib/Algebra/Category/ModuleCat/FilteredColimits.lean +++ b/Mathlib/Algebra/Category/ModuleCat/FilteredColimits.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Justus Springer -/ import Mathlib.Algebra.Category.Grp.FilteredColimits -import Mathlib.Algebra.Category.ModuleCat.Basic +import Mathlib.Algebra.Category.ModuleCat.Colimits /-! # The forgetful functor from `R`-modules preserves filtered colimits. @@ -184,6 +184,9 @@ instance forgetPreservesFilteredColimits : PreservesFilteredColimits (forget (Mo Limits.compPreservesFilteredColimits (forget₂ (ModuleCat R) AddCommGrp) (forget AddCommGrp) +instance forgetReflectsFilteredColimits : ReflectsFilteredColimits (forget (ModuleCat.{u} R)) where + reflects_filtered_colimits _ := { reflectsColimit := reflectsColimitOfReflectsIsomorphisms _ _ } + end end ModuleCat.FilteredColimits diff --git a/Mathlib/Condensed/Discrete/Characterization.lean b/Mathlib/Condensed/Discrete/Characterization.lean new file mode 100644 index 00000000000000..04c5cbbfc2c170 --- /dev/null +++ b/Mathlib/Condensed/Discrete/Characterization.lean @@ -0,0 +1,264 @@ +/- +Copyright (c) 2024 Dagur Asgeirsson. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Dagur Asgeirsson +-/ +import Mathlib.Condensed.Discrete.Colimit +import Mathlib.Condensed.Discrete.Module +/-! + +# Characterizing discrete condensed sets and `R`-modules. + +This file proves a characterization of discrete condensed sets, discrete condensed `R`-modules over +a ring `R`, discrete light condensed sets, and discrete light condensed `R`-modules over a ring `R`. +see `CondensedSet.isDiscrete_tfae`, `CondensedMod.isDiscrete_tfae`, `LightCondSet.isDiscrete_tfae`, +and `LightCondMod.isDiscrete_tfae`. + +Informally, we can say: The following conditions characterize a condensed set `X` as discrete +(`CondensedSet.isDiscrete_tfae`): + +1. There exists a set `X'` and an isomorphism `X ≅ cst X'`, where `cst X'` denotes the constant + sheaf on `X'`. +2. The counit induces an isomorphism `cst X(*) ⟶ X`. +3. There exists a set `X'` and an isomorphism `X ≅ LocallyConstant · X'`. +4. The counit induces an isomorphism `LocallyConstant · X(*) ⟶ X`. +5. For every profinite set `S = limᵢSᵢ`, the canonical map `colimᵢX(Sᵢ) ⟶ X(S)` is an isomorphism. + +The analogues for light condensed sets, condensed `R`-modules over any ring, and light +condensed `R`-modules are nearly identical (`CondensedMod.isDiscrete_tfae`, +`LightCondSet.isDiscrete_tfae`, and `LightCondMod.isDiscrete_tfae`). +-/ + +universe u + +open CategoryTheory Limits Functor FintypeCat + +attribute [local instance] ConcreteCategory.instFunLike + +namespace Condensed + +variable {C : Type*} [Category C] [HasWeakSheafify (coherentTopology CompHaus.{u}) C] + +/-- +A condensed object is *discrete* if it is constant as a sheaf, i.e. isomorphic to a constant sheaf. +-/ +abbrev IsDiscrete (X : Condensed.{u} C) := X.IsConstant (coherentTopology CompHaus) + +end Condensed + +namespace CondensedSet + +open CompHausLike.LocallyConstant + +lemma mem_locallyContant_essImage_of_isColimit_mapCocone (X : CondensedSet.{u}) + (h : ∀ S : Profinite.{u}, IsColimit <| + (profiniteToCompHaus.op ⋙ X.val).mapCocone S.asLimitCone.op) : + X ∈ CondensedSet.LocallyConstant.functor.essImage := by + let e : CondensedSet.{u} ≌ Sheaf (coherentTopology Profinite) _ := + (Condensed.ProfiniteCompHaus.equivalence (Type (u + 1))).symm + let i : (e.functor.obj X).val ≅ (e.functor.obj (LocallyConstant.functor.obj _)).val := + Condensed.isoLocallyConstantOfIsColimit _ h + exact ⟨_, ⟨e.functor.preimageIso ((sheafToPresheaf _ _).preimageIso i.symm)⟩⟩ + +/-- +`CondensedSet.LocallyConstant.functor` is left adjoint to the forgetful functor from condensed +sets to sets. +-/ +noncomputable abbrev LocallyConstant.adjunction : + CondensedSet.LocallyConstant.functor ⊣ Condensed.underlying (Type (u+1)) := + CompHausLike.LocallyConstant.adjunction _ _ + +open Condensed + +open CondensedSet.LocallyConstant List in +theorem isDiscrete_tfae (X : CondensedSet.{u}) : + TFAE + [ X.IsDiscrete + , IsIso ((Condensed.discreteUnderlyingAdj _).counit.app X) + , X ∈ (Condensed.discrete _).essImage + , X ∈ CondensedSet.LocallyConstant.functor.essImage + , IsIso (CondensedSet.LocallyConstant.adjunction.counit.app X) + , Sheaf.IsConstant (coherentTopology Profinite) + ((Condensed.ProfiniteCompHaus.equivalence _).inverse.obj X) + , ∀ S : Profinite.{u}, Nonempty + (IsColimit <| (profiniteToCompHaus.op ⋙ X.val).mapCocone S.asLimitCone.op) + ] := by + tfae_have 1 ↔ 2 := Sheaf.isConstant_iff_isIso_counit_app _ _ _ + tfae_have 1 ↔ 3 := ⟨fun ⟨h⟩ ↦ h, fun h ↦ ⟨h⟩⟩ + tfae_have 1 ↔ 4 := Sheaf.isConstant_iff_mem_essImage _ CompHaus.isTerminalPUnit adjunction _ + tfae_have 1 ↔ 5 := + have : functor.Faithful := inferInstance + have : functor.Full := inferInstance + -- These `have` statements above shouldn't be needed, but they are. + Sheaf.isConstant_iff_isIso_counit_app' _ CompHaus.isTerminalPUnit adjunction _ + tfae_have 1 ↔ 6 := + (Sheaf.isConstant_iff_of_equivalence (coherentTopology Profinite) + (coherentTopology CompHaus) profiniteToCompHaus Profinite.isTerminalPUnit + CompHaus.isTerminalPUnit _).symm + tfae_have 7 → 4 := fun h ↦ + mem_locallyContant_essImage_of_isColimit_mapCocone X (fun S ↦ (h S).some) + tfae_have 4 → 7 := fun ⟨Y, ⟨i⟩⟩ S ↦ + ⟨IsColimit.mapCoconeEquiv (isoWhiskerLeft profiniteToCompHaus.op + ((sheafToPresheaf _ _).mapIso i)) + (Condensed.isColimitLocallyConstantPresheafDiagram Y S)⟩ + tfae_finish + +end CondensedSet + +namespace CondensedMod + +variable (R : Type (u+1)) [Ring R] + +lemma isDiscrete_iff_isDiscrete_forget (M : CondensedMod R) : + M.IsDiscrete ↔ ((Condensed.forget R).obj M).IsDiscrete := + Sheaf.isConstant_iff_forget (coherentTopology CompHaus) + (forget (ModuleCat R)) M CompHaus.isTerminalPUnit + +instance : HasLimitsOfSize.{u, u+1} (ModuleCat.{u+1} R) := + hasLimitsOfSizeShrink.{u, u+1, u+1, u+1} _ + +open CondensedMod.LocallyConstant List in +theorem isDiscrete_tfae (M : CondensedMod.{u} R) : + TFAE + [ M.IsDiscrete + , IsIso ((Condensed.discreteUnderlyingAdj _).counit.app M) + , M ∈ (Condensed.discrete _).essImage + , M ∈ (CondensedMod.LocallyConstant.functor R).essImage + , IsIso ((CondensedMod.LocallyConstant.adjunction R).counit.app M) + , Sheaf.IsConstant (coherentTopology Profinite) + ((Condensed.ProfiniteCompHaus.equivalence _).inverse.obj M) + , ∀ S : Profinite.{u}, Nonempty + (IsColimit <| (profiniteToCompHaus.op ⋙ M.val).mapCocone S.asLimitCone.op) + ] := by + tfae_have 1 ↔ 2 := Sheaf.isConstant_iff_isIso_counit_app _ _ _ + tfae_have 1 ↔ 3 := ⟨fun ⟨h⟩ ↦ h, fun h ↦ ⟨h⟩⟩ + tfae_have 1 ↔ 4 := Sheaf.isConstant_iff_mem_essImage _ CompHaus.isTerminalPUnit (adjunction R) _ + tfae_have 1 ↔ 5 := + have : (functor R).Faithful := inferInstance + have : (functor R).Full := inferInstance + -- These `have` statements above shouldn't be needed, but they are. + Sheaf.isConstant_iff_isIso_counit_app' _ CompHaus.isTerminalPUnit (adjunction R) _ + tfae_have 1 ↔ 6 := + (Sheaf.isConstant_iff_of_equivalence (coherentTopology Profinite) + (coherentTopology CompHaus) profiniteToCompHaus Profinite.isTerminalPUnit + CompHaus.isTerminalPUnit _).symm + tfae_have 7 → 1 := by + intro h + rw [isDiscrete_iff_isDiscrete_forget, ((CondensedSet.isDiscrete_tfae _).out 0 6:)] + intro S + letI : PreservesFilteredColimitsOfSize.{u, u} (forget (ModuleCat R)) := + preservesFilteredColimitsOfSizeShrink.{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)) := + reflectsFilteredColimitsOfSizeShrink.{u, u+1, u, u+1} _ + exact ⟨isColimitOfReflects (forget (ModuleCat R)) (h S).some⟩ + tfae_finish + +end CondensedMod + +namespace LightCondensed + +variable {C : Type*} [Category C] [HasWeakSheafify (coherentTopology LightProfinite.{u}) C] + +/-- +A light condensed object is *discrete* if it is constant as a sheaf, i.e. isomorphic to a constant +sheaf. +-/ +abbrev IsDiscrete (X : LightCondensed.{u} C) := X.IsConstant (coherentTopology LightProfinite) + +end LightCondensed + +namespace LightCondSet + +lemma mem_locallyContant_essImage_of_isColimit_mapCocone (X : LightCondSet.{u}) + (h : ∀ S : LightProfinite.{u}, IsColimit <| + X.val.mapCocone (coconeRightOpOfCone S.asLimitCone)) : + X ∈ LightCondSet.LocallyConstant.functor.essImage := by + let i : X.val ≅ (LightCondSet.LocallyConstant.functor.obj _).val := + LightCondensed.isoLocallyConstantOfIsColimit _ h + exact ⟨_, ⟨((sheafToPresheaf _ _).preimageIso i.symm)⟩⟩ + +/-- +`LightCondSet.LocallyConstant.functor` is left adjoint to the forgetful functor from light condensed +sets to sets. +-/ +noncomputable abbrev LocallyConstant.adjunction : + LightCondSet.LocallyConstant.functor ⊣ LightCondensed.underlying (Type u) := + CompHausLike.LocallyConstant.adjunction _ _ + +open LightCondSet.LocallyConstant List in +theorem isDiscrete_tfae (X : LightCondSet.{u}) : + TFAE + [ X.IsDiscrete + , IsIso ((LightCondensed.discreteUnderlyingAdj _).counit.app X) + , X ∈ (LightCondensed.discrete _).essImage + , X ∈ LightCondSet.LocallyConstant.functor.essImage + , IsIso (LightCondSet.LocallyConstant.adjunction.counit.app X) + , ∀ S : LightProfinite.{u}, Nonempty + (IsColimit <| X.val.mapCocone (coconeRightOpOfCone S.asLimitCone)) + ] := by + tfae_have 1 ↔ 2 := Sheaf.isConstant_iff_isIso_counit_app _ _ _ + tfae_have 1 ↔ 3 := ⟨fun ⟨h⟩ ↦ h, fun h ↦ ⟨h⟩⟩ + tfae_have 1 ↔ 4 := Sheaf.isConstant_iff_mem_essImage _ LightProfinite.isTerminalPUnit adjunction X + tfae_have 1 ↔ 5 := + have : functor.Faithful := inferInstance + have : functor.Full := inferInstance + -- These `have` statements above shouldn't be needed, but they are. + Sheaf.isConstant_iff_isIso_counit_app' _ LightProfinite.isTerminalPUnit adjunction X + tfae_have 6 → 4 := fun h ↦ + mem_locallyContant_essImage_of_isColimit_mapCocone X (fun S ↦ (h S).some) + tfae_have 4 → 6 := fun ⟨Y, ⟨i⟩⟩ S ↦ + ⟨IsColimit.mapCoconeEquiv ((sheafToPresheaf _ _).mapIso i) + (LightCondensed.isColimitLocallyConstantPresheafDiagram Y S)⟩ + tfae_finish + +end LightCondSet + +namespace LightCondMod + +variable (R : Type u) [Ring R] + +lemma isDiscrete_iff_isDiscrete_forget (M : LightCondMod R) : + M.IsDiscrete ↔ ((LightCondensed.forget R).obj M).IsDiscrete := + Sheaf.isConstant_iff_forget (coherentTopology LightProfinite) + (forget (ModuleCat R)) M LightProfinite.isTerminalPUnit + +open LightCondMod.LocallyConstant List in +theorem isDiscrete_tfae (M : LightCondMod.{u} R) : + TFAE + [ M.IsDiscrete + , IsIso ((LightCondensed.discreteUnderlyingAdj _).counit.app M) + , M ∈ (LightCondensed.discrete _).essImage + , M ∈ (LightCondMod.LocallyConstant.functor R).essImage + , IsIso ((LightCondMod.LocallyConstant.adjunction R).counit.app M) + , ∀ S : LightProfinite.{u}, Nonempty + (IsColimit <| M.val.mapCocone (coconeRightOpOfCone S.asLimitCone)) + ] := by + tfae_have 1 ↔ 2 := Sheaf.isConstant_iff_isIso_counit_app _ _ _ + tfae_have 1 ↔ 3 := ⟨fun ⟨h⟩ ↦ h, fun h ↦ ⟨h⟩⟩ + tfae_have 1 ↔ 4 := Sheaf.isConstant_iff_mem_essImage _ + LightProfinite.isTerminalPUnit (adjunction R) _ + tfae_have 1 ↔ 5 := + have : (functor R).Faithful := inferInstance + have : (functor R).Full := inferInstance + -- These `have` statements above shouldn't be needed, but they are. + Sheaf.isConstant_iff_isIso_counit_app' _ LightProfinite.isTerminalPUnit (adjunction R) _ + tfae_have 6 → 1 := by + intro h + rw [isDiscrete_iff_isDiscrete_forget, ((LightCondSet.isDiscrete_tfae _).out 0 5:)] + intro S + letI : PreservesFilteredColimitsOfSize.{0, 0} (forget (ModuleCat R)) := + preservesFilteredColimitsOfSizeShrink.{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)) := + reflectsFilteredColimitsOfSizeShrink.{0, u, 0, u} _ + exact ⟨isColimitOfReflects (forget (ModuleCat R)) (h S).some⟩ + tfae_finish + +end LightCondMod From 9dba3dd644fa6310b6d1f0a7143491803d5005a4 Mon Sep 17 00:00:00 2001 From: EdwardWatine <02ewatine@gmail.com> Date: Thu, 17 Oct 2024 08:31:03 +0000 Subject: [PATCH 279/425] feat: define the ordinary hypergeometric function (#17455) Add the definition of the ordinary hypergeometric series, and show that its radius is one. Part of this requires an additional theorem about ascPochhammer, which is found in the Pochhammer file. Closely follows the exponential series definition. #15966 Co-authored-by: Alvan Caleb Arulandu --- Mathlib.lean | 2 + Mathlib/Analysis/Analytic/OfScalars.lean | 131 +++++++++++ .../OrdinaryHypergeometric.lean | 209 ++++++++++++++++++ Mathlib/Analysis/SpecificLimits/RCLike.lean | 15 ++ Mathlib/RingTheory/Polynomial/Pochhammer.lean | 40 +++- 5 files changed, 394 insertions(+), 3 deletions(-) create mode 100644 Mathlib/Analysis/Analytic/OfScalars.lean create mode 100644 Mathlib/Analysis/SpecialFunctions/OrdinaryHypergeometric.lean diff --git a/Mathlib.lean b/Mathlib.lean index 39bb6b56e139be..1170098fd659e0 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -942,6 +942,7 @@ import Mathlib.Analysis.Analytic.Inverse import Mathlib.Analysis.Analytic.IsolatedZeros import Mathlib.Analysis.Analytic.Linear import Mathlib.Analysis.Analytic.Meromorphic +import Mathlib.Analysis.Analytic.OfScalars import Mathlib.Analysis.Analytic.Polynomial import Mathlib.Analysis.Analytic.RadiusLiminf import Mathlib.Analysis.Analytic.Uniqueness @@ -1363,6 +1364,7 @@ import Mathlib.Analysis.SpecialFunctions.Log.ERealExp import Mathlib.Analysis.SpecialFunctions.Log.Monotone import Mathlib.Analysis.SpecialFunctions.Log.NegMulLog import Mathlib.Analysis.SpecialFunctions.NonIntegrable +import Mathlib.Analysis.SpecialFunctions.OrdinaryHypergeometric import Mathlib.Analysis.SpecialFunctions.PolarCoord import Mathlib.Analysis.SpecialFunctions.PolynomialExp import Mathlib.Analysis.SpecialFunctions.Polynomials diff --git a/Mathlib/Analysis/Analytic/OfScalars.lean b/Mathlib/Analysis/Analytic/OfScalars.lean new file mode 100644 index 00000000000000..531079814dcc61 --- /dev/null +++ b/Mathlib/Analysis/Analytic/OfScalars.lean @@ -0,0 +1,131 @@ +/- +Copyright (c) 2024 Edward Watine. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Edward Watine +-/ +import Mathlib.Analysis.Analytic.Basic + + +/-! +# Scalar series + +This file contains API for analytic functions `∑ cᵢ • xⁱ` defined in terms of scalars +`c₀, c₁, c₂, …`. +## Main definitions / results: + * `FormalMultilinearSeries.ofScalars`: the formal power series `∑ cᵢ • xⁱ`. + * `FormalMultilinearSeries.ofScalars_radius_eq_of_tendsto`: the ratio test for an analytic function + defined in terms of a formal power series `∑ cᵢ • xⁱ`. +-/ + +namespace FormalMultilinearSeries + +section Field + +variable {𝕜 : Type*} (E : Type*) [Field 𝕜] [Ring E] [Algebra 𝕜 E] [TopologicalSpace E] + [TopologicalRing E] (c : ℕ → 𝕜) + +/-- Formal power series of `∑ cᵢ • xⁱ` for some scalar field `𝕜` and ring algebra `E`-/ +def ofScalars : FormalMultilinearSeries 𝕜 E E := + fun n ↦ c n • ContinuousMultilinearMap.mkPiAlgebraFin 𝕜 n E + +variable {E} + +/-- The sum of the formal power series. Takes the value `0` outside the radius of convergence. -/ +noncomputable def ofScalarsSum (x : E) := (ofScalars E c).sum x + +theorem ofScalars_apply_eq (x : E) (n : ℕ) : + ofScalars E c n (fun _ ↦ x) = c n • x ^ n := by + simp [ofScalars] + +/-- This naming follows the convention of `NormedSpace.expSeries_apply_eq'`. -/ +theorem ofScalars_apply_eq' (x : E) : + (fun n ↦ ofScalars E c n (fun _ ↦ x)) = fun n ↦ c n • x ^ n := by + simp [ofScalars] + +theorem ofScalars_sum_eq (x : E) : ofScalarsSum c x = + ∑' n, c n • x ^ n := tsum_congr fun n => ofScalars_apply_eq c x n + +theorem ofScalarsSum_eq_tsum : ofScalarsSum c = + fun (x : E) => ∑' n : ℕ, c n • x ^ n := funext (ofScalars_sum_eq c) + +@[simp] +theorem ofScalars_op [T2Space E] (x : E) : + ofScalarsSum c (MulOpposite.op x) = MulOpposite.op (ofScalarsSum c x) := by + simp [ofScalars, ofScalars_sum_eq, ← MulOpposite.op_pow, ← MulOpposite.op_smul, tsum_op] + +@[simp] +theorem ofScalars_unop [T2Space E] (x : Eᵐᵒᵖ) : + ofScalarsSum c (MulOpposite.unop x) = MulOpposite.unop (ofScalarsSum c x) := by + simp [ofScalars, ofScalars_sum_eq, ← MulOpposite.unop_pow, ← MulOpposite.unop_smul, tsum_unop] + +@[simp] +theorem ofScalars_eq_zero [Nontrivial E] (n : ℕ) : ofScalars E c n = 0 ↔ c n = 0 := by + rw [ofScalars, smul_eq_zero (c := c n) (x := ContinuousMultilinearMap.mkPiAlgebraFin 𝕜 n E)] + refine or_iff_left (ContinuousMultilinearMap.ext_iff.1.mt <| not_forall_of_exists_not ?_) + use fun _ ↦ 1 + simp + +end Field + +section Normed + +open Filter +open scoped Topology + +variable {𝕜 : Type*} (E : Type*) [NontriviallyNormedField 𝕜] [NormedRing E] + [NormedAlgebra 𝕜 E] (c : ℕ → 𝕜) (n : ℕ) + +theorem ofScalars_norm_eq_mul : + ‖ofScalars E c n‖ = ‖c n‖ * ‖ContinuousMultilinearMap.mkPiAlgebraFin 𝕜 n E‖ := by + rw [ofScalars, norm_smul (c n) (ContinuousMultilinearMap.mkPiAlgebraFin 𝕜 n E)] + +theorem ofScalars_norm_le (hn : n > 0) : ‖ofScalars E c n‖ ≤ ‖c n‖ := by + simp only [ofScalars_norm_eq_mul] + exact (mul_le_of_le_one_right (norm_nonneg _) + (ContinuousMultilinearMap.norm_mkPiAlgebraFin_le_of_pos hn)) + +@[simp] +theorem ofScalars_norm [NormOneClass E] : ‖ofScalars E c n‖ = ‖c n‖ := by + simp [ofScalars_norm_eq_mul] + +/-- The radius of convergence of a scalar series is the inverse of the ratio of the norms of the +coefficients. -/ +theorem ofScalars_radius_eq_inv_of_tendsto [NormOneClass E] {r : NNReal} (hr : r ≠ 0) + (hc : Tendsto (fun n ↦ ‖c n.succ‖ / ‖c n‖) atTop (𝓝 r)) : + (ofScalars E c).radius = ENNReal.ofNNReal r⁻¹ := by + have hc' {r' : NNReal} (hr' : (r' : ℝ) ≠ 0) : + Tendsto (fun n ↦ ‖‖ofScalars E c (n + 1)‖ * r' ^ (n + 1)‖ / + ‖‖ofScalars E c n‖ * r' ^ n‖) atTop (𝓝 ↑(r' * r)) := by + simp_rw [norm_mul, norm_norm, ofScalars_norm, mul_div_mul_comm, ← norm_div, pow_succ, + mul_div_right_comm, div_self (pow_ne_zero _ hr'), one_mul, norm_div, NNReal.norm_eq] + exact mul_comm r' r ▸ Filter.Tendsto.mul hc tendsto_const_nhds + apply le_antisymm <;> refine ENNReal.le_of_forall_nnreal_lt (fun r' hr' ↦ ?_) + · rw [ENNReal.coe_le_coe, NNReal.le_inv_iff_mul_le hr] + have := FormalMultilinearSeries.summable_norm_mul_pow _ hr' + contrapose! this + have hrz : (r' : ℝ) ≠ 0 := by aesop + apply not_summable_of_ratio_test_tendsto_gt_one this + exact hc' (by aesop) + · rw [ENNReal.coe_lt_coe, NNReal.lt_inv_iff_mul_lt hr] at hr' + by_cases hrz : r' = 0 + · simp [hrz] + · apply FormalMultilinearSeries.le_radius_of_summable_norm + refine summable_of_ratio_test_tendsto_lt_one hr' ?_ <| hc' (NNReal.coe_ne_zero.2 hrz) + refine (Tendsto.eventually_ne hc (NNReal.coe_ne_zero.2 hr)).mp (Eventually.of_forall ?_) + simp_rw [div_ne_zero_iff, ofScalars_norm, mul_ne_zero_iff] + aesop + +/-- A convenience lemma restating the result of `ofScalars_radius_eq_inv_of_tendsto` under +the inverse ratio. -/ +theorem ofScalars_radius_eq_of_tendsto [NormOneClass E] {r : NNReal} (hr : r ≠ 0) + (hc : Tendsto (fun n ↦ ‖c n‖ / ‖c n.succ‖) atTop (𝓝 r)) : + (ofScalars E c).radius = ENNReal.ofNNReal r := by + 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 (continuousAt_inv₀ <| NNReal.coe_ne_zero.mpr hr).tendsto.comp hc + simp + +end Normed + +end FormalMultilinearSeries diff --git a/Mathlib/Analysis/SpecialFunctions/OrdinaryHypergeometric.lean b/Mathlib/Analysis/SpecialFunctions/OrdinaryHypergeometric.lean new file mode 100644 index 00000000000000..bbbd460e9abe3a --- /dev/null +++ b/Mathlib/Analysis/SpecialFunctions/OrdinaryHypergeometric.lean @@ -0,0 +1,209 @@ +/- +Copyright (c) 2024 Edward Watine. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Edward Watine +-/ +import Mathlib.Analysis.Analytic.OfScalars +import Mathlib.Analysis.SpecificLimits.RCLike + +/-! +# Ordinary hypergeometric function in a Banach algebra + +In this file, we define `ordinaryHypergeometric`, the _ordinary_ or _Gaussian_ hypergeometric +function in a topological algebra `𝔸` over a field `𝕂` given by: $$ +_2\mathrm{F}_1(a\ b\ c : \mathbb{K}, x : \mathbb{A}) = \sum_{n=0}^{\infty}\frac{(a)_n(b)_n}{(c)_n} +\frac{x^n}{n!} \,, +$$ +with $(a)_n$ is the ascending Pochhammer symbol (see `ascPochhammer`). + +This file contains the basic definitions over a general field `𝕂` and notation for `₂F₁`, +as well as showing that terms of the series are zero if any of the `(a b c : 𝕂)` are sufficiently +large non-positive integers, rendering the series finite. In this file "sufficiently large" means +that `-n < a` for the `n`-th term, and similarly for `b` and `c`. + +- `ordinaryHypergeometricSeries` is the `FormalMultilinearSeries` given above for some `(a b c : 𝕂)` +- `ordinaryHypergeometric` is the sum of the series for some `(x : 𝔸)` +- `ordinaryHypergeometricSeries_eq_zero_of_nonpos_int` shows that the `n`-th term of the series is +zero if any of the parameters are sufficiently large non-positive integers + +## `[RCLike 𝕂]` + +If we have `[RCLike 𝕂]`, then we show that the latter result is an iff, and hence prove that the +radius of convergence of the series is unity if the series is infinite, or `⊤` otherwise. + +- `ordinaryHypergeometricSeries_eq_zero_iff` is iff variant of +`ordinaryHypergeometricSeries_eq_zero_of_nonpos_int` +- `ordinaryHypergeometricSeries_radius_eq_one` proves that the radius of convergence of the +`ordinaryHypergeometricSeries` is unity under non-trivial parameters + +## Notation + +`₂F₁` is notation for `ordinaryHypergeometric`. + +## References + +See . + +## Tags + +hypergeometric, gaussian, ordinary +-/ + +open Nat FormalMultilinearSeries + +section Field + +variable {𝕂 : Type*} (𝔸 : Type*) [Field 𝕂] [Ring 𝔸] [Algebra 𝕂 𝔸] [TopologicalSpace 𝔸] + [TopologicalRing 𝔸] + +/-- The coefficients in the ordinary hypergeometric sum. -/ +noncomputable abbrev ordinaryHypergeometricCoefficient (a b c : 𝕂) (n : ℕ) := ((n !⁻¹ : 𝕂) * + (ascPochhammer 𝕂 n).eval a * (ascPochhammer 𝕂 n).eval b * ((ascPochhammer 𝕂 n).eval c)⁻¹) + +/-- `ordinaryHypergeometricSeries 𝔸 (a b c : 𝕂)` is a `FormalMultilinearSeries`. +Its sum is the `ordinaryHypergeometric` map. -/ +noncomputable def ordinaryHypergeometricSeries (a b c : 𝕂) : FormalMultilinearSeries 𝕂 𝔸 𝔸 := + ofScalars 𝔸 (ordinaryHypergeometricCoefficient a b c) + +variable {𝔸} (a b c : 𝕂) + +/-- `ordinaryHypergeometric (a b c : 𝕂) : 𝔸 → 𝔸` is the ordinary hypergeometric map, defined as the +sum of the `FormalMultilinearSeries` `ordinaryHypergeometricSeries 𝔸 a b c`. + +Note that this takes the junk value `0` outside the radius of convergence. +-/ +noncomputable def ordinaryHypergeometric (x : 𝔸) : 𝔸 := + (ordinaryHypergeometricSeries 𝔸 a b c).sum x + +@[inherit_doc] +notation "₂F₁" => ordinaryHypergeometric + +theorem ordinaryHypergeometricSeries_apply_eq (x : 𝔸) (n : ℕ) : + (ordinaryHypergeometricSeries 𝔸 a b c n fun _ => x) = + ((n !⁻¹ : 𝕂) * (ascPochhammer 𝕂 n).eval a * (ascPochhammer 𝕂 n).eval b * + ((ascPochhammer 𝕂 n).eval c)⁻¹ ) • x ^ n := by + rw [ordinaryHypergeometricSeries, ofScalars_apply_eq] + +/-- This naming follows the convention of `NormedSpace.expSeries_apply_eq'`. -/ +theorem ordinaryHypergeometricSeries_apply_eq' (x : 𝔸) : + (fun n => ordinaryHypergeometricSeries 𝔸 a b c n fun _ => x) = + fun n => ((n !⁻¹ : 𝕂) * (ascPochhammer 𝕂 n).eval a * (ascPochhammer 𝕂 n).eval b * + ((ascPochhammer 𝕂 n).eval c)⁻¹ ) • x ^ n := by + rw [ordinaryHypergeometricSeries, ofScalars_apply_eq'] + +theorem ordinaryHypergeometric_sum_eq (x : 𝔸) : (ordinaryHypergeometricSeries 𝔸 a b c).sum x = + ∑' n : ℕ, ((n !⁻¹ : 𝕂) * (ascPochhammer 𝕂 n).eval a * (ascPochhammer 𝕂 n).eval b * + ((ascPochhammer 𝕂 n).eval c)⁻¹ ) • x ^ n := + tsum_congr fun n => ordinaryHypergeometricSeries_apply_eq a b c x n + +theorem ordinaryHypergeometric_eq_tsum : ₂F₁ a b c = + fun (x : 𝔸) => ∑' n : ℕ, ((n !⁻¹ : 𝕂) * (ascPochhammer 𝕂 n).eval a * + (ascPochhammer 𝕂 n).eval b * ((ascPochhammer 𝕂 n).eval c)⁻¹ ) • x ^ n := + funext (ordinaryHypergeometric_sum_eq a b c) + +theorem ordinaryHypergeometricSeries_apply_zero (n : ℕ) : + (ordinaryHypergeometricSeries 𝔸 a b c n fun _ => 0) = Pi.single (f := fun _ => 𝔸) 0 1 n := by + rw [ordinaryHypergeometricSeries, ofScalars_apply_eq, ordinaryHypergeometricCoefficient] + cases n <;> simp + +@[simp] +theorem ordinaryHypergeometric_zero : ₂F₁ a b c (0 : 𝔸) = 1 := by + simp [ordinaryHypergeometric_eq_tsum, ← ordinaryHypergeometricSeries_apply_eq, + ordinaryHypergeometricSeries_apply_zero] + +theorem ordinaryHypergeometricSeries_symm : + ordinaryHypergeometricSeries 𝔸 a b c = ordinaryHypergeometricSeries 𝔸 b a c := by + unfold ordinaryHypergeometricSeries ordinaryHypergeometricCoefficient + simp [mul_assoc, mul_left_comm] + +/-- If any parameter to the series is a sufficiently large nonpositive integer, then the series +term is zero. -/ +lemma ordinaryHypergeometricSeries_eq_zero_of_neg_nat {n k : ℕ} (habc : k = -a ∨ k = -b ∨ k = -c) + (hk : k < n) : ordinaryHypergeometricSeries 𝔸 a b c n = 0 := by + rw [ordinaryHypergeometricSeries, ofScalars] + rcases habc with h | h | h + all_goals + ext + simp [(ascPochhammer_eval_eq_zero_iff n _).2 ⟨k, hk, h⟩] + +end Field + +section RCLike + +open Asymptotics Filter Real Set Nat + +open scoped Topology + +variable {𝕂 : Type*} (𝔸 : Type*) [RCLike 𝕂] [NormedDivisionRing 𝔸] [NormedAlgebra 𝕂 𝔸] + (a b c : 𝕂) + +theorem ordinaryHypergeometric_radius_top_of_neg_nat₁ {k : ℕ} : + (ordinaryHypergeometricSeries 𝔸 (-(k : 𝕂)) b c).radius = ⊤ := by + refine FormalMultilinearSeries.radius_eq_top_of_forall_image_add_eq_zero _ (1 + k) fun n ↦ ?_ + exact ordinaryHypergeometricSeries_eq_zero_of_neg_nat (-(k : 𝕂)) b c (by aesop) (by omega) + +theorem ordinaryHypergeometric_radius_top_of_neg_nat₂ {k : ℕ} : + (ordinaryHypergeometricSeries 𝔸 a (-(k : 𝕂)) c).radius = ⊤ := by + rw [ordinaryHypergeometricSeries_symm] + exact ordinaryHypergeometric_radius_top_of_neg_nat₁ 𝔸 a c + +theorem ordinaryHypergeometric_radius_top_of_neg_nat₃ {k : ℕ} : + (ordinaryHypergeometricSeries 𝔸 a b (-(k : 𝕂))).radius = ⊤ := by + refine FormalMultilinearSeries.radius_eq_top_of_forall_image_add_eq_zero _ (1 + k) fun n ↦ ?_ + exact ordinaryHypergeometricSeries_eq_zero_of_neg_nat a b (-(k : 𝕂)) (by aesop) (by omega) + +/-- An iff variation on `ordinaryHypergeometricSeries_eq_zero_of_nonpos_int` for `[RCLike 𝕂]`. -/ +lemma ordinaryHypergeometricSeries_eq_zero_iff (n : ℕ) : + ordinaryHypergeometricSeries 𝔸 a b c n = 0 ↔ ∃ k < n, k = -a ∨ k = -b ∨ k = -c := by + refine ⟨fun h ↦ ?_, fun zero ↦ ?_⟩ + · rw [ordinaryHypergeometricSeries, ofScalars_eq_zero] at h + simp only [_root_.mul_eq_zero, inv_eq_zero] at h + rcases h with ((hn | h) | h) | h + · simp [Nat.factorial_ne_zero] at hn + all_goals + obtain ⟨kn, hkn, hn⟩ := (ascPochhammer_eval_eq_zero_iff _ _).1 h + exact ⟨kn, hkn, by tauto⟩ + · obtain ⟨_, h, hn⟩ := zero + exact ordinaryHypergeometricSeries_eq_zero_of_neg_nat a b c hn h + +theorem ordinaryHypergeometricSeries_norm_div_succ_norm (n : ℕ) + (habc : ∀ kn < n, (↑kn ≠ -a ∧ ↑kn ≠ -b ∧ ↑kn ≠ -c)) : + ‖ordinaryHypergeometricCoefficient a b c n‖ / ‖ordinaryHypergeometricCoefficient a b c n.succ‖ + = ‖a + n‖⁻¹ * ‖b + n‖⁻¹ * ‖c + n‖ * ‖1 + (n : 𝕂)‖ := by + simp only [mul_inv_rev, factorial_succ, cast_mul, cast_add, + cast_one, ascPochhammer_succ_eval, norm_mul, norm_inv] + calc + _ = ‖Polynomial.eval a (ascPochhammer 𝕂 n)‖ * ‖Polynomial.eval a (ascPochhammer 𝕂 n)‖⁻¹ * + ‖Polynomial.eval b (ascPochhammer 𝕂 n)‖ * ‖Polynomial.eval b (ascPochhammer 𝕂 n)‖⁻¹ * + ‖Polynomial.eval c (ascPochhammer 𝕂 n)‖⁻¹⁻¹ * ‖Polynomial.eval c (ascPochhammer 𝕂 n)‖⁻¹ * + ‖(n ! : 𝕂)‖⁻¹⁻¹ * ‖(n ! : 𝕂)‖⁻¹ * ‖a + n‖⁻¹ * ‖b + n‖⁻¹ * ‖c + n‖⁻¹⁻¹ * + ‖1 + (n : 𝕂)‖⁻¹⁻¹ := by ring_nf + _ = _ := by + simp only [inv_inv] + repeat rw [DivisionRing.mul_inv_cancel, one_mul] + all_goals + rw [norm_ne_zero_iff] + any_goals + apply (ascPochhammer_eval_eq_zero_iff n _).not.2 + push_neg + exact fun kn hkn ↦ by simp [habc kn hkn] + exact cast_ne_zero.2 (factorial_ne_zero n) + +/-- The radius of convergence of `ordinaryHypergeometricSeries` is unity if none of the parameters +are non-positive integers. -/ +theorem ordinaryHypergeometricSeries_radius_eq_one + (habc : ∀ kn : ℕ, ↑kn ≠ -a ∧ ↑kn ≠ -b ∧ ↑kn ≠ -c) : + (ordinaryHypergeometricSeries 𝔸 a b c).radius = 1 := by + convert ofScalars_radius_eq_of_tendsto 𝔸 _ one_ne_zero ?_ + suffices Tendsto (fun k : ℕ ↦ (a + k)⁻¹ * (b + k)⁻¹ * (c + k) * ((1 : 𝕂) + k)) atTop (𝓝 1) by + simp_rw [ordinaryHypergeometricSeries_norm_div_succ_norm a b c _ (fun n _ ↦ habc n)] + simp [← norm_mul, ← norm_inv] + convert Filter.Tendsto.norm this + exact norm_one.symm + have (k : ℕ) : (a + k)⁻¹ * (b + k)⁻¹ * (c + k) * ((1 : 𝕂) + k) = + (c + k) / (a + k) * ((1 + k) / (b + k)) := by field_simp + simp_rw [this] + apply (mul_one (1 : 𝕂)) ▸ Filter.Tendsto.mul <;> + convert RCLike.tendsto_add_mul_div_add_mul_atTop_nhds _ _ (1 : 𝕂) one_ne_zero <;> simp + +end RCLike diff --git a/Mathlib/Analysis/SpecificLimits/RCLike.lean b/Mathlib/Analysis/SpecificLimits/RCLike.lean index 287d854e7d39d0..2f82b7954f8821 100644 --- a/Mathlib/Analysis/SpecificLimits/RCLike.lean +++ b/Mathlib/Analysis/SpecificLimits/RCLike.lean @@ -22,3 +22,18 @@ theorem RCLike.tendsto_inverse_atTop_nhds_zero_nat : simp @[deprecated (since := "2024-01-16")] alias RCLike.tendsto_inverse_atTop_nhds_0_nat := RCLike.tendsto_inverse_atTop_nhds_zero_nat + +variable {𝕜} + +theorem RCLike.tendsto_add_mul_div_add_mul_atTop_nhds (a b c : 𝕜) {d : 𝕜} (hd : d ≠ 0) : + Tendsto (fun k : ℕ ↦ (a + c * k) / (b + d * k)) atTop (𝓝 (c / d)) := by + apply Filter.Tendsto.congr' + case f₁ => exact fun k ↦ (a * (↑k)⁻¹ + c) / (b * (↑k)⁻¹ + d) + refine (eventually_ne_atTop 0).mp (Eventually.of_forall ?_) + · intro h hx + field_simp [hx] + · apply Filter.Tendsto.div _ _ hd + all_goals + apply zero_add (_ : 𝕜) ▸ Filter.Tendsto.add_const _ _ + apply mul_zero (_ : 𝕜) ▸ Filter.Tendsto.const_mul _ _ + exact RCLike.tendsto_inverse_atTop_nhds_zero_nat 𝕜 diff --git a/Mathlib/RingTheory/Polynomial/Pochhammer.lean b/Mathlib/RingTheory/Polynomial/Pochhammer.lean index a96e49ebd3495d..fcb2365cac7b28 100644 --- a/Mathlib/RingTheory/Polynomial/Pochhammer.lean +++ b/Mathlib/RingTheory/Polynomial/Pochhammer.lean @@ -3,9 +3,7 @@ Copyright (c) 2020 Kim Morrison. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Kim Morrison -/ -import Mathlib.Algebra.Polynomial.Degree.Definitions -import Mathlib.Algebra.Polynomial.Eval -import Mathlib.Algebra.Polynomial.Monic +import Mathlib.Algebra.CharP.Defs import Mathlib.Algebra.Polynomial.RingDivision import Mathlib.Tactic.Abel @@ -24,6 +22,8 @@ that are focused on `Nat` can be found in `Data.Nat.Factorial` as `Nat.ascFactor As with many other families of polynomials, even though the coefficients are always in `ℕ` or `ℤ` , we define the polynomial with coefficients in any `[Semiring S]` or `[Ring R]`. +In an integral domain `S`, we show that `ascPochhammer S n` is zero iff +`n` is a sufficiently large non-positive integer. ## TODO @@ -372,4 +372,38 @@ theorem descPochhammer_int_eq_ascFactorial (a b : ℕ) : rw [← Nat.cast_add, descPochhammer_eval_eq_descFactorial ℤ (a + b) b, Nat.add_descFactorial_eq_ascFactorial] +variable {R} + +/-- The Pochhammer polynomial of degree `n` has roots at `0`, `-1`, ..., `-(n - 1)`. -/ +theorem ascPochhammer_eval_neg_coe_nat_of_lt {n k : ℕ} (h : k < n) : + (ascPochhammer R n).eval (-(k : R)) = 0 := by + induction n with + | zero => contradiction + | succ n ih => + rw [ascPochhammer_succ_eval] + rcases lt_trichotomy k n with hkn | rfl | hkn + · simp [ih hkn] + · simp + · omega + +/-- Over an integral domain, the Pochhammer polynomial of degree `n` has roots *only* at +`0`, `-1`, ..., `-(n - 1)`. -/ +@[simp] +theorem ascPochhammer_eval_eq_zero_iff [IsDomain R] + (n : ℕ) (r : R) : (ascPochhammer R n).eval r = 0 ↔ ∃ k < n, k = -r := by + refine ⟨fun zero' ↦ ?_, fun hrn ↦ ?_⟩ + · induction n with + | zero => simp only [ascPochhammer_zero, Polynomial.eval_one, one_ne_zero] at zero' + | succ n ih => + rw [ascPochhammer_succ_eval, mul_eq_zero] at zero' + cases zero' with + | inl h => + obtain ⟨rn, hrn, rrn⟩ := ih h + exact ⟨rn, by omega, rrn⟩ + | inr h => + exact ⟨n, lt_add_one n, eq_neg_of_add_eq_zero_right h⟩ + · obtain ⟨rn, hrn, rnn⟩ := hrn + convert ascPochhammer_eval_neg_coe_nat_of_lt hrn + simp [rnn] + end Ring From c41f54d5da1cfb4821b762dadca0723eaf0de39e Mon Sep 17 00:00:00 2001 From: Oliver Nash Date: Thu, 17 Oct 2024 08:31:04 +0000 Subject: [PATCH 280/425] feat: generalise `LieModule.independent_genWeightSpace` to any family of compatible endomorphisms (#17654) Also create new file to group together results about simultaneous (generalised) eigenspaces. Co-authored-by: Oliver Nash <7734364+ocfnash@users.noreply.github.com> --- Mathlib.lean | 1 + Mathlib/Algebra/Lie/Weights/Basic.lean | 49 +---- Mathlib/LinearAlgebra/Eigenspace/Basic.lean | 32 --- Mathlib/LinearAlgebra/Eigenspace/Pi.lean | 193 ++++++++++++++++++ .../Eigenspace/Triangularizable.lean | 51 ----- 5 files changed, 200 insertions(+), 126 deletions(-) create mode 100644 Mathlib/LinearAlgebra/Eigenspace/Pi.lean diff --git a/Mathlib.lean b/Mathlib.lean index 1170098fd659e0..1595a1b1c093b2 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3033,6 +3033,7 @@ import Mathlib.LinearAlgebra.Dual import Mathlib.LinearAlgebra.Eigenspace.Basic import Mathlib.LinearAlgebra.Eigenspace.Matrix import Mathlib.LinearAlgebra.Eigenspace.Minpoly +import Mathlib.LinearAlgebra.Eigenspace.Pi import Mathlib.LinearAlgebra.Eigenspace.Semisimple import Mathlib.LinearAlgebra.Eigenspace.Triangularizable import Mathlib.LinearAlgebra.Eigenspace.Zero diff --git a/Mathlib/Algebra/Lie/Weights/Basic.lean b/Mathlib/Algebra/Lie/Weights/Basic.lean index e0f030da4caccf..1d5d4302ac4267 100644 --- a/Mathlib/Algebra/Lie/Weights/Basic.lean +++ b/Mathlib/Algebra/Lie/Weights/Basic.lean @@ -6,7 +6,7 @@ Authors: Oliver Nash import Mathlib.Algebra.Ring.Divisibility.Lemmas import Mathlib.Algebra.Lie.Nilpotent import Mathlib.Algebra.Lie.Engel -import Mathlib.LinearAlgebra.Eigenspace.Triangularizable +import Mathlib.LinearAlgebra.Eigenspace.Pi import Mathlib.RingTheory.Artinian import Mathlib.LinearAlgebra.Trace import Mathlib.LinearAlgebra.FreeModule.PID @@ -650,48 +650,11 @@ lemma injOn_genWeightSpace [NoZeroSMulDivisors R M] : See also `LieModule.independent_genWeightSpace'`. -/ lemma independent_genWeightSpace [NoZeroSMulDivisors R M] : - CompleteLattice.Independent fun (χ : L → R) ↦ genWeightSpace M χ := by - classical - suffices ∀ χ (s : Finset (L → R)) (_ : χ ∉ s), - Disjoint (genWeightSpace M χ) (s.sup fun (χ : L → R) ↦ genWeightSpace M χ) by - simpa only [CompleteLattice.independent_iff_supIndep_of_injOn (injOn_genWeightSpace R L M), - Finset.supIndep_iff_disjoint_erase] using fun s χ _ ↦ this _ _ (s.not_mem_erase χ) - intro χ₁ s - induction s using Finset.induction_on with - | empty => simp - | insert _n ih => - rename_i χ₂ s - intro hχ₁₂ - obtain ⟨hχ₁₂ : χ₁ ≠ χ₂, hχ₁ : χ₁ ∉ s⟩ := by rwa [Finset.mem_insert, not_or] at hχ₁₂ - specialize ih hχ₁ - rw [Finset.sup_insert, disjoint_iff, LieSubmodule.eq_bot_iff] - rintro x ⟨hx, hx'⟩ - simp only [SetLike.mem_coe, LieSubmodule.mem_coeSubmodule] at hx hx' - suffices x ∈ genWeightSpace M χ₂ by - rw [← LieSubmodule.mem_bot (R := R) (L := L), ← (disjoint_genWeightSpace R L M hχ₁₂).eq_bot] - exact ⟨hx, this⟩ - obtain ⟨y, hy, z, hz, rfl⟩ := (LieSubmodule.mem_sup _ _ _).mp hx'; clear hx' - suffices ∀ l, ∃ (k : ℕ), - ((toEnd R L M l - algebraMap R (Module.End R M) (χ₂ l)) ^ k) (y + z) ∈ - genWeightSpace M χ₁ ⊓ Finset.sup s fun χ ↦ genWeightSpace M χ by - simpa only [ih.eq_bot, LieSubmodule.mem_bot, mem_genWeightSpace] using this - intro l - let g : Module.End R M := toEnd R L M l - algebraMap R (Module.End R M) (χ₂ l) - obtain ⟨k, hk : (g ^ k) y = 0⟩ := (mem_genWeightSpace _ _ _).mp hy l - refine ⟨k, (LieSubmodule.mem_inf _ _ _).mp ⟨?_, ?_⟩⟩ - · exact LieSubmodule.mapsTo_pow_toEnd_sub_algebraMap _ hx - · rw [map_add, hk, zero_add] - suffices (s.sup fun χ ↦ genWeightSpace M χ : Submodule R M).map (g ^ k) ≤ - s.sup fun χ ↦ genWeightSpace M χ by - refine this (Submodule.mem_map_of_mem ?_) - simp_rw [← LieSubmodule.mem_coeSubmodule, Finset.sup_eq_iSup, - LieSubmodule.iSup_coe_toSubmodule, ← Finset.sup_eq_iSup] at hz - exact hz - simp_rw [Finset.sup_eq_iSup, Submodule.map_iSup (ι := L → R), Submodule.map_iSup (ι := _ ∈ s), - LieSubmodule.iSup_coe_toSubmodule] - refine iSup₂_mono fun χ _ ↦ ?_ - rintro - ⟨u, hu, rfl⟩ - exact LieSubmodule.mapsTo_pow_toEnd_sub_algebraMap _ hu + CompleteLattice.Independent fun χ : L → R ↦ genWeightSpace M χ := by + simp only [LieSubmodule.independent_iff_coe_toSubmodule, genWeightSpace, + LieSubmodule.iInf_coe_toSubmodule] + exact Module.End.independent_iInf_maxGenEigenspace_of_forall_mapsTo (toEnd R L M) + (fun x y φ z ↦ (genWeightSpaceOf M φ y).lie_mem) lemma independent_genWeightSpace' [NoZeroSMulDivisors R M] : CompleteLattice.Independent fun χ : Weight R L M ↦ genWeightSpace M χ := diff --git a/Mathlib/LinearAlgebra/Eigenspace/Basic.lean b/Mathlib/LinearAlgebra/Eigenspace/Basic.lean index e2e7aa9fcb4c9f..a66604891270fb 100644 --- a/Mathlib/LinearAlgebra/Eigenspace/Basic.lean +++ b/Mathlib/LinearAlgebra/Eigenspace/Basic.lean @@ -787,38 +787,6 @@ 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] -/-- Given a family of endomorphisms `i ↦ f i`, a family of candidate eigenvalues `i ↦ μ i`, and a -submodule `p` which is invariant wrt every `f i`, the intersection of `p` with the simultaneous -maximal generalised eigenspace (taken over all `i`), is the same as the simultaneous maximal -generalised eigenspace of the `f i` restricted to `p`. -/ -lemma _root_.Submodule.inf_iInf_maxGenEigenspace_of_forall_mapsTo {ι : Type*} {μ : ι → R} - (f : ι → End R M) (p : Submodule R M) (hfp : ∀ i, MapsTo (f i) p p) : - p ⊓ ⨅ i, (f i).maxGenEigenspace (μ i) = - (⨅ i, maxGenEigenspace ((f i).restrict (hfp i)) (μ i)).map p.subtype := by - cases isEmpty_or_nonempty ι - · simp [iInf_of_isEmpty] - · simp_rw [inf_iInf, maxGenEigenspace_def, ((f _).genEigenspace _).mono.directed_le.inf_iSup_eq, - p.inf_genEigenspace _ (hfp _), ← Submodule.map_iSup, Submodule.map_iInf _ p.injective_subtype] - -/-- Given a family of endomorphisms `i ↦ f i`, a family of candidate eigenvalues `i ↦ μ i`, and a -distinguished index `i` whose maximal generalised `μ i`-eigenspace is invariant wrt every `f j`, -taking simultaneous maximal generalised eigenspaces is unaffected by first restricting to the -distinguished generalised `μ i`-eigenspace. -/ -lemma iInf_maxGenEigenspace_restrict_map_subtype_eq - {ι : Type*} {μ : ι → R} (i : ι) (f : ι → End R M) - (h : ∀ j, MapsTo (f j) ((f i).maxGenEigenspace (μ i)) ((f i).maxGenEigenspace (μ i))) : - letI p := (f i).maxGenEigenspace (μ i) - letI q (j : ι) := maxGenEigenspace ((f j).restrict (h j)) (μ j) - (⨅ j, q j).map p.subtype = ⨅ j, (f j).maxGenEigenspace (μ j) := by - have : Nonempty ι := ⟨i⟩ - set p := (f i).maxGenEigenspace (μ i) - have : ⨅ j, (f j).maxGenEigenspace (μ j) = p ⊓ ⨅ j, (f j).maxGenEigenspace (μ j) := by - refine le_antisymm ?_ inf_le_right - simpa only [le_inf_iff, le_refl, and_true] using iInf_le _ _ - rw [Submodule.map_iInf _ p.injective_subtype, this, Submodule.inf_iInf] - simp_rw [maxGenEigenspace_def, Submodule.map_iSup, - ((f _).genEigenspace _).mono.directed_le.inf_iSup_eq, p.inf_genEigenspace (f _) (h _)] - 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/Pi.lean b/Mathlib/LinearAlgebra/Eigenspace/Pi.lean new file mode 100644 index 00000000000000..3eeacc0153eb75 --- /dev/null +++ b/Mathlib/LinearAlgebra/Eigenspace/Pi.lean @@ -0,0 +1,193 @@ +/- +Copyright (c) 2024 Oliver Nash. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Oliver Nash +-/ +import Mathlib.LinearAlgebra.Eigenspace.Triangularizable + +/-! +# Simultaneous eigenvectors and eigenvalues for families of endomorphisms + +In finite dimensions, the theory of simultaneous eigenvalues for a family of linear endomorphisms +`i ↦ f i` enjoys similar properties to that of a single endomorphism, provided the family obeys a +compatibilty condition. This condition is that the maximum generalised eigenspaces of each +endomorphism are invariant under the action of all members of the family. It is trivially satisfied +for commuting endomorphisms but there are important more general situations where it also holds +(e.g., representations of nilpotent Lie algebras). + +## Main definitions / results + * `Module.End.independent_iInf_maxGenEigenspace_of_forall_mapsTo`: the simultaneous generalised + eigenspaces of a compatible family of endomorphisms are independent. + * `Module.End.iSup_iInf_maxGenEigenspace_eq_top_of_forall_mapsTo`: in finite dimensions, the + simultaneous generalised eigenspaces of a compatible family of endomorphisms span if the same + is true of each map individually. + +-/ + +open Function Set + +namespace Module.End + +variable {ι R K M : Type*} [CommRing R] [Field K] [AddCommGroup M] [Module R M] [Module K M] + (f : ι → End R M) + +theorem mem_iInf_maxGenEigenspace_iff (χ : ι → R) (m : M) : + m ∈ ⨅ i, (f i).maxGenEigenspace (χ i) ↔ ∀ j, ∃ k : ℕ, ((f j - χ j • ↑1) ^ k) m = 0 := by + simp + +/-- Given a family of endomorphisms `i ↦ f i`, a family of candidate eigenvalues `i ↦ μ i`, and a +submodule `p` which is invariant wrt every `f i`, the intersection of `p` with the simultaneous +maximal generalised eigenspace (taken over all `i`), is the same as the simultaneous maximal +generalised eigenspace of the `f i` restricted to `p`. -/ +lemma _root_.Submodule.inf_iInf_maxGenEigenspace_of_forall_mapsTo {μ : ι → R} + (p : Submodule R M) (hfp : ∀ i, MapsTo (f i) p p) : + p ⊓ ⨅ i, (f i).maxGenEigenspace (μ i) = + (⨅ i, maxGenEigenspace ((f i).restrict (hfp i)) (μ i)).map p.subtype := by + cases isEmpty_or_nonempty ι + · simp [iInf_of_isEmpty] + · simp_rw [inf_iInf, maxGenEigenspace_def, ((f _).genEigenspace _).mono.directed_le.inf_iSup_eq, + p.inf_genEigenspace _ (hfp _), ← Submodule.map_iSup, Submodule.map_iInf _ p.injective_subtype] + +/-- Given a family of endomorphisms `i ↦ f i`, a family of candidate eigenvalues `i ↦ μ i`, and a +distinguished index `i` whose maximal generalised `μ i`-eigenspace is invariant wrt every `f j`, +taking simultaneous maximal generalised eigenspaces is unaffected by first restricting to the +distinguished generalised `μ i`-eigenspace. -/ +lemma iInf_maxGenEigenspace_restrict_map_subtype_eq + {μ : ι → R} (i : ι) + (h : ∀ j, MapsTo (f j) ((f i).maxGenEigenspace (μ i)) ((f i).maxGenEigenspace (μ i))) : + letI p := (f i).maxGenEigenspace (μ i) + letI q (j : ι) := maxGenEigenspace ((f j).restrict (h j)) (μ j) + (⨅ j, q j).map p.subtype = ⨅ j, (f j).maxGenEigenspace (μ j) := by + have : Nonempty ι := ⟨i⟩ + set p := (f i).maxGenEigenspace (μ i) + have : ⨅ j, (f j).maxGenEigenspace (μ j) = p ⊓ ⨅ j, (f j).maxGenEigenspace (μ j) := by + refine le_antisymm ?_ inf_le_right + simpa only [le_inf_iff, le_refl, and_true] using iInf_le _ _ + rw [Submodule.map_iInf _ p.injective_subtype, this, Submodule.inf_iInf] + simp_rw [maxGenEigenspace_def, Submodule.map_iSup, + ((f _).genEigenspace _).mono.directed_le.inf_iSup_eq, p.inf_genEigenspace (f _) (h _)] + +variable [NoZeroSMulDivisors R M] + +lemma disjoint_iInf_maxGenEigenspace {χ₁ χ₂ : ι → R} (h : χ₁ ≠ χ₂) : + Disjoint (⨅ i, (f i).maxGenEigenspace (χ₁ i)) (⨅ i, (f i).maxGenEigenspace (χ₂ i)) := by + obtain ⟨j, hj⟩ : ∃ j, χ₁ j ≠ χ₂ j := Function.ne_iff.mp h + exact (End.disjoint_unifEigenspace (f j) hj ⊤ ⊤).mono (iInf_le _ j) (iInf_le _ j) + +lemma injOn_iInf_maxGenEigenspace : + InjOn (fun χ : ι → R ↦ ⨅ i, (f i).maxGenEigenspace (χ i)) + {χ | ⨅ i, (f i).maxGenEigenspace (χ i) ≠ ⊥} := by + rintro χ₁ _ χ₂ + hχ₂ (hχ₁₂ : ⨅ i, (f i).maxGenEigenspace (χ₁ i) = ⨅ i, (f i).maxGenEigenspace (χ₂ i)) + contrapose! hχ₂ + simpa [hχ₁₂] using disjoint_iInf_maxGenEigenspace f hχ₂ + +lemma independent_iInf_maxGenEigenspace_of_forall_mapsTo + (h : ∀ i j φ, MapsTo (f i) ((f j).maxGenEigenspace φ) ((f j).maxGenEigenspace φ)) : + CompleteLattice.Independent fun χ : ι → R ↦ ⨅ i, (f i).maxGenEigenspace (χ i) := by + replace h (l : ι) (χ : ι → R) : + MapsTo (f l) (⨅ i, (f i).maxGenEigenspace (χ i)) (⨅ i, (f i).maxGenEigenspace (χ i)) := by + intro x hx + simp only [iInf_eq_iInter, mem_iInter, SetLike.mem_coe] at hx ⊢ + exact fun i ↦ h l i (χ i) (hx i) + classical + suffices ∀ χ (s : Finset (ι → R)) (_ : χ ∉ s), + Disjoint (⨅ i, (f i).maxGenEigenspace (χ i)) + (s.sup fun (χ : ι → R) ↦ ⨅ i, (f i).maxGenEigenspace (χ i)) by + simpa only [CompleteLattice.independent_iff_supIndep_of_injOn (injOn_iInf_maxGenEigenspace f), + Finset.supIndep_iff_disjoint_erase] using fun s χ _ ↦ this _ _ (s.not_mem_erase χ) + intro χ₁ s + induction s using Finset.induction_on with + | empty => simp + | insert _n ih => + rename_i χ₂ s + intro hχ₁₂ + obtain ⟨hχ₁₂ : χ₁ ≠ χ₂, hχ₁ : χ₁ ∉ s⟩ := by rwa [Finset.mem_insert, not_or] at hχ₁₂ + specialize ih hχ₁ + rw [Finset.sup_insert, disjoint_iff, Submodule.eq_bot_iff] + rintro x ⟨hx, hx'⟩ + simp only [SetLike.mem_coe] at hx hx' + suffices x ∈ ⨅ i, (f i).maxGenEigenspace (χ₂ i) by + rw [← Submodule.mem_bot (R := R), ← (disjoint_iInf_maxGenEigenspace f hχ₁₂).eq_bot] + exact ⟨hx, this⟩ + obtain ⟨y, hy, z, hz, rfl⟩ := Submodule.mem_sup.mp hx'; clear hx' + suffices ∀ l, ∃ (k : ℕ), + ((f l - algebraMap R (Module.End R M) (χ₂ l)) ^ k) (y + z) ∈ + (⨅ i, (f i).maxGenEigenspace (χ₁ i)) ⊓ + Finset.sup s fun χ ↦ ⨅ i, (f i).maxGenEigenspace (χ i) by + simpa [ih.eq_bot, Submodule.mem_bot] using this + intro l + let g : Module.End R M := f l - algebraMap R (Module.End R M) (χ₂ l) + obtain ⟨k, hk : (g ^ k) y = 0⟩ := (mem_iInf_maxGenEigenspace_iff _ _ _).mp hy l + have aux (f : End R M) (φ : R) (k : ℕ) (p : Submodule R M) (hp : MapsTo f p p) : + MapsTo ((f - algebraMap R (Module.End R M) φ) ^ k) p p := by + rw [LinearMap.coe_pow] + exact MapsTo.iterate (fun m hm ↦ p.sub_mem (hp hm) (p.smul_mem _ hm)) k + refine ⟨k, Submodule.mem_inf.mp ⟨?_, ?_⟩⟩ + · refine aux (f l) (χ₂ l) k (⨅ i, (f i).maxGenEigenspace (χ₁ i)) ?_ hx + simp only [Submodule.iInf_coe] + exact h l χ₁ + · rw [map_add, hk, zero_add] + suffices (s.sup fun χ ↦ (⨅ i, (f i).maxGenEigenspace (χ i))).map (g ^ k) ≤ + s.sup fun χ ↦ (⨅ i, (f i).maxGenEigenspace (χ i)) by + refine this (Submodule.mem_map_of_mem ?_) + simp_rw [Finset.sup_eq_iSup, ← Finset.sup_eq_iSup] at hz + exact hz + simp_rw [Finset.sup_eq_iSup, Submodule.map_iSup (ι := ι → R), Submodule.map_iSup (ι := _ ∈ s)] + refine iSup₂_mono fun χ _ ↦ ?_ + rintro - ⟨u, hu, rfl⟩ + refine aux (f l) (χ₂ l) k (⨅ i, (f i).maxGenEigenspace (χ i)) ?_ hu + simp only [Submodule.iInf_coe] + exact h l χ + +/-- Given a family of endomorphisms `i ↦ f i` which are compatible in the sense that every maximal +generalised eigenspace of `f i` is invariant wrt `f j`, if each `f i` is triangularizable, the +family is simultaneously triangularizable. -/ +lemma iSup_iInf_maxGenEigenspace_eq_top_of_forall_mapsTo [FiniteDimensional K M] + (f : ι → End K M) + (h : ∀ i j φ, MapsTo (f i) ((f j).maxGenEigenspace φ) ((f j).maxGenEigenspace φ)) + (h' : ∀ i, ⨆ μ, (f i).maxGenEigenspace μ = ⊤) : + ⨆ χ : ι → K, ⨅ i, (f i).maxGenEigenspace (χ i) = ⊤ := by + generalize h_dim : finrank K M = n + induction n using Nat.strongRecOn generalizing M with | ind n ih => ?_ + obtain this | ⟨i : ι, hy : ¬ ∃ φ, (f i).maxGenEigenspace φ = ⊤⟩ := + forall_or_exists_not (fun j : ι ↦ ∃ φ : K, (f j).maxGenEigenspace φ = ⊤) + · choose χ hχ using this + replace hχ : ⨅ i, (f i).maxGenEigenspace (χ i) = ⊤ := by simpa + simp_rw [eq_top_iff] at hχ ⊢ + exact le_trans hχ <| le_iSup (fun χ : ι → K ↦ ⨅ i, (f i).maxGenEigenspace (χ i)) χ + · replace hy : ∀ φ, finrank K ((f i).maxGenEigenspace φ) < n := fun φ ↦ by + simp_rw [not_exists, ← lt_top_iff_ne_top] at hy; exact h_dim ▸ Submodule.finrank_lt (hy φ) + have hi (j : ι) (φ : K) : + MapsTo (f j) ((f i).maxGenEigenspace φ) ((f i).maxGenEigenspace φ) := by + exact h j i φ + replace ih (φ : K) : + ⨆ χ : ι → K, ⨅ j, maxGenEigenspace ((f j).restrict (hi j φ)) (χ j) = ⊤ := by + apply ih _ (hy φ) + · intro j k μ + exact mapsTo_restrict_maxGenEigenspace_restrict_of_mapsTo (f j) (f k) _ _ (h j k μ) + · simp_rw [maxGenEigenspace_def] at h' ⊢ + exact fun j ↦ Module.End.iSup_genEigenspace_restrict_eq_top _ (h' j) + · rfl + replace ih (φ : K) : + ⨆ (χ : ι → K) (_ : χ i = φ), ⨅ j, maxGenEigenspace ((f j).restrict (hi j φ)) (χ j) = ⊤ := by + suffices ∀ χ : ι → K, χ i ≠ φ → ⨅ j, maxGenEigenspace ((f j).restrict (hi j φ)) (χ j) = ⊥ by + specialize ih φ; rw [iSup_split, biSup_congr this] at ih; simpa using ih + intro χ hχ + rw [eq_bot_iff, ← ((f i).maxGenEigenspace φ).ker_subtype, LinearMap.ker, + ← Submodule.map_le_iff_le_comap, ← Submodule.inf_iInf_maxGenEigenspace_of_forall_mapsTo, + ← disjoint_iff_inf_le] + simp_rw [maxGenEigenspace_def] + exact ((f i).disjoint_iSup_genEigenspace hχ.symm).mono_right (iInf_le _ i) + replace ih (φ : K) : + ⨆ (χ : ι → K) (_ : χ i = φ), ⨅ j, maxGenEigenspace (f j) (χ j) = + maxGenEigenspace (f i) φ := by + have (χ : ι → K) (hχ : χ i = φ) : ⨅ j, maxGenEigenspace (f j) (χ j) = + (⨅ j, maxGenEigenspace ((f j).restrict (hi j φ)) (χ j)).map + ((f i).maxGenEigenspace φ).subtype := by + rw [← hχ, iInf_maxGenEigenspace_restrict_map_subtype_eq] + simp_rw [biSup_congr this, ← Submodule.map_iSup, ih, Submodule.map_top, + Submodule.range_subtype] + simpa only [← ih, iSup_comm (ι := K), iSup_iSup_eq_right] using h' i + +end Module.End diff --git a/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean b/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean index 03e4ac0132b669..e619e168195641 100644 --- a/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean +++ b/Mathlib/LinearAlgebra/Eigenspace/Triangularizable.lean @@ -222,54 +222,3 @@ theorem Module.End.iSup_genEigenspace_restrict_eq_top simp_rw [Submodule.inf_genEigenspace f p h, Submodule.comap_subtype_self, ← Submodule.map_iSup, Submodule.comap_map_eq_of_injective h_inj] at this exact this.symm - -/-- Given a family of endomorphisms `i ↦ f i` which are compatible in the sense that every maximal -generalised eigenspace of `f i` is invariant wrt `f j`, if each `f i` is triangularizable, the -family is simultaneously triangularizable. -/ -lemma Module.End.iSup_iInf_maxGenEigenspace_eq_top_of_forall_mapsTo - {ι : Type*} [FiniteDimensional K V] - (f : ι → End K V) - (h : ∀ i j φ, MapsTo (f i) ((f j).maxGenEigenspace φ) ((f j).maxGenEigenspace φ)) - (h' : ∀ i, ⨆ μ, (f i).maxGenEigenspace μ = ⊤) : - ⨆ χ : ι → K, ⨅ i, (f i).maxGenEigenspace (χ i) = ⊤ := by - generalize h_dim : finrank K V = n - induction n using Nat.strongRecOn generalizing V with | ind n ih => ?_ - obtain this | ⟨i : ι, hy : ¬ ∃ φ, (f i).maxGenEigenspace φ = ⊤⟩ := - forall_or_exists_not (fun j : ι ↦ ∃ φ : K, (f j).maxGenEigenspace φ = ⊤) - · choose χ hχ using this - replace hχ : ⨅ i, (f i).maxGenEigenspace (χ i) = ⊤ := by simpa - simp_rw [eq_top_iff] at hχ ⊢ - exact le_trans hχ <| le_iSup (fun χ : ι → K ↦ ⨅ i, (f i).maxGenEigenspace (χ i)) χ - · replace hy : ∀ φ, finrank K ((f i).maxGenEigenspace φ) < n := fun φ ↦ by - simp_rw [not_exists, ← lt_top_iff_ne_top] at hy; exact h_dim ▸ Submodule.finrank_lt (hy φ) - have hi (j : ι) (φ : K) : - MapsTo (f j) ((f i).maxGenEigenspace φ) ((f i).maxGenEigenspace φ) := by - exact h j i φ - replace ih (φ : K) : - ⨆ χ : ι → K, ⨅ j, maxGenEigenspace ((f j).restrict (hi j φ)) (χ j) = ⊤ := by - apply ih _ (hy φ) - · intro j k μ - exact mapsTo_restrict_maxGenEigenspace_restrict_of_mapsTo (f j) (f k) _ _ (h j k μ) - · simp_rw [maxGenEigenspace_def] at h' ⊢ - exact fun j ↦ Module.End.iSup_genEigenspace_restrict_eq_top _ (h' j) - · rfl - replace ih (φ : K) : - ⨆ (χ : ι → K) (_ : χ i = φ), ⨅ j, maxGenEigenspace ((f j).restrict (hi j φ)) (χ j) = ⊤ := by - suffices ∀ χ : ι → K, χ i ≠ φ → ⨅ j, maxGenEigenspace ((f j).restrict (hi j φ)) (χ j) = ⊥ by - specialize ih φ; rw [iSup_split, biSup_congr this] at ih; simpa using ih - intro χ hχ - rw [eq_bot_iff, ← ((f i).maxGenEigenspace φ).ker_subtype, LinearMap.ker, - ← Submodule.map_le_iff_le_comap, ← Submodule.inf_iInf_maxGenEigenspace_of_forall_mapsTo, - ← disjoint_iff_inf_le] - simp_rw [maxGenEigenspace_def] - exact ((f i).disjoint_iSup_genEigenspace hχ.symm).mono_right (iInf_le _ i) - replace ih (φ : K) : - ⨆ (χ : ι → K) (_ : χ i = φ), ⨅ j, maxGenEigenspace (f j) (χ j) = - maxGenEigenspace (f i) φ := by - have (χ : ι → K) (hχ : χ i = φ) : ⨅ j, maxGenEigenspace (f j) (χ j) = - (⨅ j, maxGenEigenspace ((f j).restrict (hi j φ)) (χ j)).map - ((f i).maxGenEigenspace φ).subtype := by - rw [← hχ, iInf_maxGenEigenspace_restrict_map_subtype_eq] - simp_rw [biSup_congr this, ← Submodule.map_iSup, ih, Submodule.map_top, - Submodule.range_subtype] - simpa only [← ih, iSup_comm (ι := K), iSup_iSup_eq_right] using h' i From b1ec18a85983bb1edd81b603b996cd9f9f7ee8df Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Thu, 17 Oct 2024 08:31:05 +0000 Subject: [PATCH 281/425] feat(CategoryTheory/Sites): pretopology induced by a morphism property (#17736) Introduces the pretopology induced by a morphism property satisfying sufficient stability properties. --- Mathlib.lean | 1 + .../MorphismProperty/Composition.lean | 20 ++++++ .../MorphismProperty/Limits.lean | 10 +++ .../Sites/MorphismProperty.lean | 66 +++++++++++++++++++ 4 files changed, 97 insertions(+) create mode 100644 Mathlib/CategoryTheory/Sites/MorphismProperty.lean diff --git a/Mathlib.lean b/Mathlib.lean index 1595a1b1c093b2..d978b6190e81c7 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1905,6 +1905,7 @@ import Mathlib.CategoryTheory.Sites.LocallyFullyFaithful import Mathlib.CategoryTheory.Sites.LocallyInjective import Mathlib.CategoryTheory.Sites.LocallySurjective import Mathlib.CategoryTheory.Sites.MayerVietorisSquare +import Mathlib.CategoryTheory.Sites.MorphismProperty import Mathlib.CategoryTheory.Sites.NonabelianCohomology.H1 import Mathlib.CategoryTheory.Sites.OneHypercover import Mathlib.CategoryTheory.Sites.Over diff --git a/Mathlib/CategoryTheory/MorphismProperty/Composition.lean b/Mathlib/CategoryTheory/MorphismProperty/Composition.lean index aff2f87e7acc04..13fd8d28c5d309 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Composition.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Composition.lean @@ -49,6 +49,10 @@ instance inverseImage {P : MorphismProperty D} [P.ContainsIdentities] (F : C ⥤ (P.inverseImage F).ContainsIdentities where id_mem X := by simpa only [← F.map_id] using P.id_mem (F.obj X) +instance inf {P Q : MorphismProperty C} [P.ContainsIdentities] [Q.ContainsIdentities] : + (P ⊓ Q).ContainsIdentities where + id_mem X := ⟨P.id_mem X, Q.id_mem X⟩ + end ContainsIdentities instance Prod.containsIdentities {C₁ C₂ : Type*} [Category C₁] [Category C₂] @@ -61,6 +65,14 @@ instance Pi.containsIdentities {J : Type w} {C : J → Type u} (pi W).ContainsIdentities := ⟨fun _ _ => MorphismProperty.id_mem _ _⟩ +lemma of_isIso (P : MorphismProperty C) [P.ContainsIdentities] [P.RespectsIso] {X Y : C} (f : X ⟶ Y) + [IsIso f] : P f := + Category.id_comp f ▸ RespectsIso.postcomp P f (𝟙 X) (P.id_mem X) + +lemma isomorphisms_le_of_containsIdentities (P : MorphismProperty C) [P.ContainsIdentities] + [P.RespectsIso] : + isomorphisms C ≤ P := fun _ _ f (_ : IsIso f) ↦ P.of_isIso f + /-- A morphism property satisfies `IsStableUnderComposition` if the composition of two such morphisms still falls in the class. -/ class IsStableUnderComposition (P : MorphismProperty C) : Prop where @@ -78,6 +90,11 @@ instance IsStableUnderComposition.unop {P : MorphismProperty Cᵒᵖ} [P.IsStabl P.unop.IsStableUnderComposition where comp_mem f g hf hg := P.comp_mem g.op f.op hg hf +instance IsStableUnderComposition.inf {P Q : MorphismProperty C} [P.IsStableUnderComposition] + [Q.IsStableUnderComposition] : + (P ⊓ Q).IsStableUnderComposition where + comp_mem f g hf hg := ⟨P.comp_mem f g hf.left hg.left, Q.comp_mem f g hf.right hg.right⟩ + /-- A morphism property is `StableUnderInverse` if the inverse of a morphism satisfying the property still falls in the class. -/ def StableUnderInverse (P : MorphismProperty C) : Prop := @@ -167,6 +184,9 @@ instance : (epimorphisms C).IsMultiplicative where instance {P : MorphismProperty D} [P.IsMultiplicative] (F : C ⥤ D) : (P.inverseImage F).IsMultiplicative where +instance inf {P Q : MorphismProperty C} [P.IsMultiplicative] [Q.IsMultiplicative] : + (P ⊓ Q).IsMultiplicative where + end IsMultiplicative /-- A class of morphisms `W` has the two-out-of-three property if whenever two out diff --git a/Mathlib/CategoryTheory/MorphismProperty/Limits.lean b/Mathlib/CategoryTheory/MorphismProperty/Limits.lean index 7352e3fdd289a3..97d95f0510ebd7 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Limits.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Limits.lean @@ -163,6 +163,16 @@ theorem StableUnderBaseChange.op {P : MorphismProperty C} (hP : StableUnderBaseC theorem StableUnderBaseChange.unop {P : MorphismProperty Cᵒᵖ} (hP : StableUnderBaseChange P) : StableUnderCobaseChange P.unop := fun _ _ _ _ _ _ _ _ sq hf => hP sq.op hf +lemma StableUnderBaseChange.inf {P Q : MorphismProperty C} (hP : StableUnderBaseChange P) + (hQ : StableUnderBaseChange Q) : + StableUnderBaseChange (P ⊓ Q) := + fun _ _ _ _ _ _ _ _ hp hg ↦ ⟨hP hp hg.left, hQ hp hg.right⟩ + +lemma StableUnderCobaseChange.inf {P Q : MorphismProperty C} (hP : StableUnderCobaseChange P) + (hQ : StableUnderCobaseChange Q) : + StableUnderCobaseChange (P ⊓ Q) := + fun _ _ _ _ _ _ _ _ hp hg ↦ ⟨hP hp hg.left, hQ hp hg.right⟩ + section variable (W : MorphismProperty C) diff --git a/Mathlib/CategoryTheory/Sites/MorphismProperty.lean b/Mathlib/CategoryTheory/Sites/MorphismProperty.lean new file mode 100644 index 00000000000000..d840eb5deaf0ff --- /dev/null +++ b/Mathlib/CategoryTheory/Sites/MorphismProperty.lean @@ -0,0 +1,66 @@ +/- +Copyright (c) 2024 Christian Merten. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christian Merten +-/ +import Mathlib.CategoryTheory.MorphismProperty.Limits +import Mathlib.CategoryTheory.Sites.Pretopology + +/-! +# The site induced by a morphism property + +Let `C` be a category with pullbacks and `P` be a multiplicative morphism property which is +stable under base change. Then `P` induces a pretopology, where coverings are given by presieves +whose elements satisfy `P`. + +Standard examples of pretopologies in algebraic geometry, such as the étale site, are obtained from +this construction by intersecting with the pretopology of surjective families. + +-/ + +namespace CategoryTheory + +open Limits + +variable {C : Type*} [Category C] [HasPullbacks C] + +namespace MorphismProperty + +/-- If `P` is a multiplicative morphism property which is stable under base change on a category +`C` with pullbacks, then `P` induces a pretopology, where coverings are given by presieves whose +elements satisfy `P`. -/ +def pretopology (P : MorphismProperty C) [P.IsMultiplicative] (hPb : P.StableUnderBaseChange) : + Pretopology C where + coverings X S := ∀ {Y : C} {f : Y ⟶ X}, S f → P f + has_isos X Y f h Z g hg := by + cases hg + haveI : P.RespectsIso := hPb.respectsIso + exact P.of_isIso f + pullbacks X Y f S hS Z g hg := by + obtain ⟨Z, g, hg⟩ := hg + apply hPb.snd g f (hS hg) + transitive X S Ti hS hTi Y f hf := by + obtain ⟨Z, g, h, H, H', rfl⟩ := hf + exact comp_mem _ _ _ (hTi h H H') (hS H) + +/-- To a morphism property `P` satisfying the conditions of `MorphismProperty.pretopology`, we +associate the Grothendieck topology generated by `P.pretopology`. -/ +abbrev grothendieckTopology (P : MorphismProperty C) [P.IsMultiplicative] + (hPb : P.StableUnderBaseChange) : GrothendieckTopology C := + (P.pretopology hPb).toGrothendieck + +variable {P Q : MorphismProperty C} + [P.IsMultiplicative] (hPb : P.StableUnderBaseChange) + [Q.IsMultiplicative] (hQb : Q.StableUnderBaseChange) + +lemma pretopology_le (hPQ : P ≤ Q) : P.pretopology hPb ≤ Q.pretopology hQb := + fun _ _ hS _ f hf ↦ hPQ f (hS hf) + +variable (P Q) in +lemma pretopology_inf : + (P ⊓ Q).pretopology (hPb.inf hQb) = P.pretopology hPb ⊓ Q.pretopology hQb := by + ext X S + exact ⟨fun hS ↦ ⟨fun hf ↦ (hS hf).left, fun hf ↦ (hS hf).right⟩, + fun h ↦ fun hf ↦ ⟨h.left hf, h.right hf⟩⟩ + +end CategoryTheory.MorphismProperty From 9800ff6dbcb799b3fe7c7cb25eb570e77893f4ee Mon Sep 17 00:00:00 2001 From: Wojciech Nawrocki Date: Thu, 17 Oct 2024 08:31:07 +0000 Subject: [PATCH 282/425] feat(LinearAlgebra/Matrix): characterize ideals in matrix rings (#17750) - Define left and two-sided ideals in a matrix ring. - Show that two-sided matrix ideals are order-isomorphic to two-sided ideals in the base ring. This code is taken from FLT, from [here](https://github.com/ImperialCollegeLondon/FLT/blob/daac491a4fa817ec39595e0a5ce2240ceed940fc/FLT/for_mathlib/CrazySimple.lean). Co-authored-by: Wojciech Nawrocki --- Mathlib.lean | 1 + Mathlib/LinearAlgebra/Matrix/Ideal.lean | 203 ++++++++++++++++++++++++ 2 files changed, 204 insertions(+) create mode 100644 Mathlib/LinearAlgebra/Matrix/Ideal.lean diff --git a/Mathlib.lean b/Mathlib.lean index d978b6190e81c7..cb62c7d0053296 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3089,6 +3089,7 @@ import Mathlib.LinearAlgebra.Matrix.GeneralLinearGroup.Defs import Mathlib.LinearAlgebra.Matrix.Gershgorin import Mathlib.LinearAlgebra.Matrix.Hermitian import Mathlib.LinearAlgebra.Matrix.HermitianFunctionalCalculus +import Mathlib.LinearAlgebra.Matrix.Ideal import Mathlib.LinearAlgebra.Matrix.InvariantBasisNumber import Mathlib.LinearAlgebra.Matrix.IsDiag import Mathlib.LinearAlgebra.Matrix.LDL diff --git a/Mathlib/LinearAlgebra/Matrix/Ideal.lean b/Mathlib/LinearAlgebra/Matrix/Ideal.lean new file mode 100644 index 00000000000000..2d0f2ed989b041 --- /dev/null +++ b/Mathlib/LinearAlgebra/Matrix/Ideal.lean @@ -0,0 +1,203 @@ +/- +Copyright (c) 2024 Jujian Zhang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jujian Zhang, Wojciech Nawrocki +-/ +import Mathlib.Data.Matrix.Basis +import Mathlib.RingTheory.TwoSidedIdeal.Operations + +/-! +# Ideals in a matrix ring + +This file defines left (resp. two-sided) ideals in a matrix semiring (resp. ring) +over left (resp. two-sided) ideals in the base semiring (resp. ring). + +## Main results + +* `TwoSidedIdeal.equivMatricesOver` and `TwoSidedIdeal.orderIsoMatricesOver` + establish an order isomorphism between two-sided ideals in $R$ and those in $Mₙ(R)$. +-/ + +/-! ### Left ideals in a matrix ring -/ + +namespace Ideal +open Matrix + +variable {R : Type*} [Semiring R] + (n : Type*) [Fintype n] [DecidableEq n] + +/-- The left ideal of matrices with entries in `I ≤ R`. -/ +def matricesOver (I : Ideal R) : Ideal (Matrix n n R) where + carrier := { M | ∀ i j, M i j ∈ I } + add_mem' ha hb i j := I.add_mem (ha i j) (hb i j) + zero_mem' _ _ := I.zero_mem + smul_mem' M N hN := by + intro i j + rw [smul_eq_mul, mul_apply] + apply sum_mem + intro k _ + apply I.mul_mem_left _ (hN k j) + +@[simp] +theorem mem_matricesOver (I : Ideal R) (M : Matrix n n R) : + M ∈ I.matricesOver n ↔ ∀ i j, M i j ∈ I := by rfl + +theorem matricesOver_monotone : Monotone (matricesOver (R := R) n) := + fun _ _ IJ _ MI i j => IJ (MI i j) + +theorem matricesOver_strictMono_of_nonempty [Nonempty n] : + StrictMono (matricesOver (R := R) n) := + matricesOver_monotone n |>.strictMono_of_injective <| fun I J eq => by + ext x + have : (∀ _ _, x ∈ I) ↔ (∀ _ _, x ∈ J) := congr((Matrix.of fun _ _ => x) ∈ $eq) + simpa only [forall_const] using this + +@[simp] +theorem matricesOver_bot : (⊥ : Ideal R).matricesOver n = ⊥ := by + ext M + simp only [mem_matricesOver, mem_bot] + constructor + · intro H; ext; apply H + · intro H; simp [H] + +@[simp] +theorem matricesOver_top : (⊤ : Ideal R).matricesOver n = ⊤ := by + ext; simp + +end Ideal + +/-! ### Two-sided ideals in a matrix ring -/ + +namespace TwoSidedIdeal +open Matrix + +variable {R : Type*} [Ring R] + (n : Type*) [Fintype n] + +/-- The two-sided ideal of matrices with entries in `I ≤ R`. -/ +def matricesOver (I : TwoSidedIdeal R) : TwoSidedIdeal (Matrix n n R) := + TwoSidedIdeal.mk' { M | ∀ i j, M i j ∈ I } + (fun _ _ => I.zero_mem) + (fun ha hb i j => I.add_mem (ha i j) (hb i j)) + (fun ha i j => I.neg_mem (ha i j)) + (fun ha i j => by + rw [mul_apply] + apply sum_mem + intro k _ + apply I.mul_mem_left _ _ (ha k j)) + (fun ha i j => by + rw [mul_apply] + apply sum_mem + intro k _ + apply I.mul_mem_right _ _ (ha i k)) + +@[simp] +lemma mem_matricesOver (I : TwoSidedIdeal R) (M : Matrix n n R) : + M ∈ I.matricesOver n ↔ ∀ i j, M i j ∈ I := by + simp [matricesOver] + +theorem matricesOver_monotone : Monotone (matricesOver (R := R) n) := + fun _ _ IJ _ MI i j => IJ (MI i j) + +theorem matricesOver_strictMono_of_nonempty [h : Nonempty n] : + StrictMono (matricesOver (R := R) n) := + matricesOver_monotone n |>.strictMono_of_injective <| fun I J eq => by + ext x + have : _ ↔ _ := congr((Matrix.of fun _ _ => x) ∈ $eq) + simpa only [mem_matricesOver, of_apply, forall_const] using this + +@[simp] +theorem matricesOver_bot : (⊥ : TwoSidedIdeal R).matricesOver n = ⊥ := by + ext M + simp only [mem_matricesOver, mem_bot] + constructor + · intro H; ext; apply H + · intro H; simp [H] + +@[simp] +theorem matricesOver_top : (⊤ : TwoSidedIdeal R).matricesOver n = ⊤ := by + ext; simp + +theorem asIdeal_matricesOver [DecidableEq n] (I : TwoSidedIdeal R) : + asIdeal (I.matricesOver n) = (asIdeal I).matricesOver n := by + ext; simp + +variable {n : Type*} [Fintype n] [DecidableEq n] + +/-- +Two-sided ideals in $R$ correspond bijectively to those in $Mₙ(R)$. +Given an ideal $I ≤ R$, we send it to $Mₙ(I)$. +Given an ideal $J ≤ Mₙ(R)$, we send it to $\{Nᵢⱼ ∣ ∃ N ∈ J\}$. +-/ +@[simps] +def equivMatricesOver (i j : n) : TwoSidedIdeal R ≃ TwoSidedIdeal (Matrix n n R) where + toFun I := I.matricesOver n + invFun J := TwoSidedIdeal.mk' + { N i j | N ∈ J } + ⟨0, J.zero_mem, rfl⟩ + (by rintro _ _ ⟨x, hx, rfl⟩ ⟨y, hy, rfl⟩; exact ⟨x + y, J.add_mem hx hy, rfl⟩) + (by rintro _ ⟨x, hx, rfl⟩; exact ⟨-x, J.neg_mem hx, rfl⟩) + (by + rintro x _ ⟨y, hy, rfl⟩ + exact ⟨diagonal (fun _ ↦ x) * y, J.mul_mem_left _ _ hy, by simp⟩) + (by + rintro _ y ⟨x, hx, rfl⟩ + exact ⟨x * diagonal (fun _ ↦ y), J.mul_mem_right _ _ hx, by simp⟩) + right_inv J := SetLike.ext fun x ↦ by + simp only [mem_mk', Set.mem_image, SetLike.mem_coe, mem_matricesOver] + constructor + · intro h + choose y hy1 hy2 using h + rw [matrix_eq_sum_stdBasisMatrix x] + refine sum_mem fun k _ ↦ sum_mem fun l _ ↦ ?_ + suffices + stdBasisMatrix k l (x k l) = + stdBasisMatrix k i 1 * y k l * stdBasisMatrix j l 1 by + rw [this] + exact J.mul_mem_right _ _ (J.mul_mem_left _ _ <| hy1 _ _) + ext a b + by_cases hab : a = k ∧ b = l + · rcases hab with ⟨ha, hb⟩ + subst ha hb + simp only [stdBasisMatrix, and_self, ↓reduceIte, StdBasisMatrix.mul_right_apply_same, + StdBasisMatrix.mul_left_apply_same, one_mul, mul_one] + rw [hy2 a b] + · conv_lhs => + dsimp [stdBasisMatrix] + rw [if_neg (by tauto)] + rw [not_and_or] at hab + rcases hab with ha | hb + · rw [mul_assoc, StdBasisMatrix.mul_left_apply_of_ne (h := ha)] + · rw [StdBasisMatrix.mul_right_apply_of_ne (hbj := hb)] + · intro hx k l + refine ⟨stdBasisMatrix i k 1 * x * stdBasisMatrix l j 1, + J.mul_mem_right _ _ (J.mul_mem_left _ _ hx), ?_⟩ + rw [StdBasisMatrix.mul_right_apply_same, StdBasisMatrix.mul_left_apply_same, + mul_one, one_mul] + left_inv I := SetLike.ext fun x ↦ by + simp only [mem_mk', Set.mem_image, SetLike.mem_coe, mem_matricesOver] + constructor + · intro h + choose y hy1 hy2 using h + exact hy2 ▸ hy1 _ _ + · intro h + exact ⟨of fun _ _ => x, by simp [h], rfl⟩ + +/-- +Two-sided ideals in $R$ are order-isomorphic with those in $Mₙ(R)$. +See also `equivMatricesOver`. +-/ +@[simps!] +def orderIsoMatricesOver (i j : n) : TwoSidedIdeal R ≃o TwoSidedIdeal (Matrix n n R) where + __ := equivMatricesOver i j + map_rel_iff' {I J} := by + simp only [equivMatricesOver_apply] + constructor + · intro le x xI + specialize @le (of fun _ _ => x) (by simp [xI]) + letI : Inhabited n := ⟨i⟩ + simpa using le + · intro IJ M MI i j + exact IJ <| MI i j + +end TwoSidedIdeal From ffb2f0dbf80ad18fa75f85bd0facee6737b59acf Mon Sep 17 00:00:00 2001 From: Riccardo Brasca Date: Thu, 17 Oct 2024 08:31:08 +0000 Subject: [PATCH 283/425] feat: add `Module.finrank_quotient_add_finrank_le` (#17782) --- Mathlib/LinearAlgebra/Dimension/Finite.lean | 9 +++++++++ Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/Mathlib/LinearAlgebra/Dimension/Finite.lean b/Mathlib/LinearAlgebra/Dimension/Finite.lean index 90c82db1cfcc3c..bf110e9d64974b 100644 --- a/Mathlib/LinearAlgebra/Dimension/Finite.lean +++ b/Mathlib/LinearAlgebra/Dimension/Finite.lean @@ -7,6 +7,7 @@ import Mathlib.Algebra.Module.Torsion import Mathlib.SetTheory.Cardinal.Cofinality import Mathlib.LinearAlgebra.FreeModule.Finite.Basic import Mathlib.LinearAlgebra.Dimension.StrongRankCondition +import Mathlib.LinearAlgebra.Dimension.Constructions /-! # Conditions for rank to be finite @@ -426,6 +427,14 @@ theorem Module.finrank_zero_iff [NoZeroSMulDivisors R M] : rw [← rank_zero_iff (R := R), ← finrank_eq_rank] norm_cast +/-- 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 := 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 + end StrongRankCondition theorem Module.finrank_eq_zero_of_rank_eq_zero (h : Module.rank R M = 0) : diff --git a/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean b/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean index 26dc00965d15b0..7b753996882f1f 100644 --- a/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean +++ b/Mathlib/LinearAlgebra/Dimension/StrongRankCondition.lean @@ -443,6 +443,13 @@ noncomputable instance {R M : Type*} [DivisionRing R] [AddCommGroup M] [Module R theorem finrank_eq_rank [Module.Finite R M] : ↑(finrank R M) = Module.rank R M := by rw [Module.finrank, cast_toNat_of_lt_aleph0 (rank_lt_aleph0 R M)] +/-- If `M` is finite, then `finrank N = rank N` for all `N : Submodule M`. Note that +such an `N` need not be finitely generated. -/ +protected theorem _root_.Submodule.finrank_eq_rank [Module.Finite R M] (N : Submodule R M) : + finrank R N = Module.rank R N := by + rw [finrank, Cardinal.cast_toNat_of_lt_aleph0] + exact lt_of_le_of_lt (Submodule.rank_le N) (rank_lt_aleph0 R M) + end Module open Module From 7b3af7ebd252c921171d5d635a03288f91264ba5 Mon Sep 17 00:00:00 2001 From: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com> Date: Thu, 17 Oct 2024 08:51:30 +0000 Subject: [PATCH 284/425] chore: adjust set_range_forget_map_inclusion' to the statement that is really needed (#17278) --- Mathlib/Topology/Category/TopCat/Opens.lean | 10 +++++----- scripts/no_lints_prime_decls.txt | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Mathlib/Topology/Category/TopCat/Opens.lean b/Mathlib/Topology/Category/TopCat/Opens.lean index 41c2df48911b05..eb8eb48fb88be5 100644 --- a/Mathlib/Topology/Category/TopCat/Opens.lean +++ b/Mathlib/Topology/Category/TopCat/Opens.lean @@ -335,22 +335,22 @@ theorem functor_obj_map_obj {X Y : TopCat} {f : X ⟶ Y} (hf : IsOpenMap f) (U : exact ⟨x, hx, rfl⟩ -- Porting note: added to ease the proof of `functor_map_eq_inf` -lemma set_range_forget_map_inclusion' {X : TopCat} (U : Opens X) : - Set.range ((forget TopCat).map (inclusion' U)) = (U : Set X) := by +lemma set_range_inclusion' {X : TopCat} (U : Opens X) : + Set.range (inclusion' U) = (U : Set X) := by ext x constructor · rintro ⟨x, rfl⟩ exact x.2 · intro h exact ⟨⟨x, h⟩, rfl⟩ +@[deprecated (since := "2024-09-07")] alias set_range_forget_map_inclusion' := set_range_inclusion' @[simp] theorem functor_map_eq_inf {X : TopCat} (U V : Opens X) : U.openEmbedding.isOpenMap.functor.obj ((Opens.map U.inclusion').obj V) = V ⊓ U := by ext1 - refine Set.image_preimage_eq_inter_range.trans ?_ - erw [set_range_forget_map_inclusion' U] - rfl + simp only [IsOpenMap.functor_obj_coe, map_coe, coe_inf, + Set.image_preimage_eq_inter_range, set_range_inclusion' U] theorem map_functor_eq' {X U : TopCat} (f : U ⟶ X) (hf : OpenEmbedding f) (V) : ((Opens.map f).obj <| hf.isOpenMap.functor.obj V) = V := diff --git a/scripts/no_lints_prime_decls.txt b/scripts/no_lints_prime_decls.txt index b2fa718c5be982..8affabbf01733e 100644 --- a/scripts/no_lints_prime_decls.txt +++ b/scripts/no_lints_prime_decls.txt @@ -4652,6 +4652,7 @@ TopologicalSpace.Opens.map_functor_eq' TopologicalSpace.Opens.map_id_obj' TopologicalSpace.Opens.openEmbedding' TopologicalSpace.Opens.set_range_forget_map_inclusion' +TopologicalSpace.Opens.set_range_inclusion' TopologicalSpace.SecondCountableTopology.mk' Topology.WithScott.isOpen_iff_isUpperSet_and_scottHausdorff_open' top_sdiff' From c1d3ebd51a1725828121397ad4a8f36aba2f3a07 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Thu, 17 Oct 2024 08:51:31 +0000 Subject: [PATCH 285/425] chore: clean up "was simp" porting notes (#17827) Go through all the files with porting notes along the lines of "was `simp`", "was `simp_rw`", "used to be `simp`" and try to: * Restore original, if possible; * Use another cleaner way to solve the issue; * Delete the note if it's not worth going back to the old version; * Renumber the note if it's a more applicable issue (#11119 in particular); * Or not touch the note if it's still relevant. Co-authored-by: grunweg --- .../Algebra/Category/ModuleCat/Adjunctions.lean | 11 +++-------- Mathlib/Algebra/Module/LinearMap/Prod.lean | 4 +--- Mathlib/Algebra/Polynomial/Coeff.lean | 1 - Mathlib/Analysis/Calculus/Implicit.lean | 6 +----- Mathlib/Analysis/Normed/Group/AddTorsor.lean | 6 ++---- Mathlib/Analysis/Normed/Lp/PiLp.lean | 1 - Mathlib/Analysis/RCLike/Basic.lean | 12 ++++++------ Mathlib/Data/Finsupp/AList.lean | 3 +-- Mathlib/Data/Seq/WSeq.lean | 2 -- .../Geometry/Euclidean/Angle/Oriented/Basic.lean | 15 ++------------- Mathlib/Geometry/Euclidean/MongePoint.lean | 12 ++---------- Mathlib/GroupTheory/Perm/Fin.lean | 2 +- .../LinearAlgebra/AffineSpace/Combination.lean | 8 ++------ Mathlib/LinearAlgebra/Alternating/Basic.lean | 4 +--- .../LinearAlgebra/CliffordAlgebra/Grading.lean | 3 +-- Mathlib/LinearAlgebra/Determinant.lean | 4 +--- Mathlib/LinearAlgebra/Isomorphisms.lean | 4 +--- .../Constructions/Prod/Integral.lean | 2 -- Mathlib/MeasureTheory/Group/Integral.lean | 9 +++------ .../NumberTheory/Cyclotomic/PrimitiveRoots.lean | 9 +++------ Mathlib/RingTheory/DedekindDomain/PID.lean | 1 - Mathlib/RingTheory/DedekindDomain/SInteger.lean | 4 +--- Mathlib/SetTheory/Cardinal/Basic.lean | 2 +- Mathlib/Topology/Algebra/Module/Basic.lean | 6 +----- Mathlib/Topology/Instances/AddCircle.lean | 4 +--- 25 files changed, 35 insertions(+), 100 deletions(-) diff --git a/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean b/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean index 2abebe30399c0a..c3f9a38ef087e7 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean @@ -317,9 +317,7 @@ def lift (F : C ⥤ D) : Free R C ⥤ D where map_id := by dsimp [CategoryTheory.categoryFree]; simp map_comp {X Y Z} f g := by apply Finsupp.induction_linear f - · -- Porting note (#10959): simp used to be able to close this goal - dsimp - rw [Limits.zero_comp, sum_zero_index, Limits.zero_comp] + · simp · intro f₁ f₂ w₁ w₂ rw [add_comp] dsimp at * @@ -331,9 +329,7 @@ def lift (F : C ⥤ D) : Free R C ⥤ D where · intros; simp only [add_smul] · intro f' r apply Finsupp.induction_linear g - · -- Porting note (#10959): simp used to be able to close this goal - dsimp - rw [Limits.comp_zero, sum_zero_index, Limits.comp_zero] + · simp · intro f₁ f₂ w₁ w₂ rw [comp_add] dsimp at * @@ -376,8 +372,7 @@ def ext {F G : Free R C ⥤ D} [F.Additive] [F.Linear R] [G.Additive] [G.Linear (by intro X Y f apply Finsupp.induction_linear f - · -- Porting note (#10959): simp used to be able to close this goal - rw [Functor.map_zero, Limits.zero_comp, Functor.map_zero, Limits.comp_zero] + · simp · intro f₁ f₂ w₁ w₂ -- Porting note: Using rw instead of simp rw [Functor.map_add, add_comp, w₁, w₂, Functor.map_add, comp_add] diff --git a/Mathlib/Algebra/Module/LinearMap/Prod.lean b/Mathlib/Algebra/Module/LinearMap/Prod.lean index c21bf6e0c5a842..5b80a635be778c 100644 --- a/Mathlib/Algebra/Module/LinearMap/Prod.lean +++ b/Mathlib/Algebra/Module/LinearMap/Prod.lean @@ -35,9 +35,7 @@ theorem isLinearMap_sub [AddCommGroup M] [Module R M] : IsLinearMap R fun x : M × M => x.1 - x.2 := by apply IsLinearMap.mk · intro x y - -- porting note (#10745): was `simp [add_comm, add_left_comm, sub_eq_add_neg]` - rw [Prod.fst_add, Prod.snd_add] - abel + simp [add_comm, add_assoc, add_left_comm, sub_eq_add_neg] · intro x y simp [smul_sub] diff --git a/Mathlib/Algebra/Polynomial/Coeff.lean b/Mathlib/Algebra/Polynomial/Coeff.lean index a0550adae74d17..3d6efd887e11ee 100644 --- a/Mathlib/Algebra/Polynomial/Coeff.lean +++ b/Mathlib/Algebra/Polynomial/Coeff.lean @@ -104,7 +104,6 @@ lemma coeff_list_sum_map {ι : Type*} (l : List ι) (f : ι → R[X]) (n : ℕ) theorem coeff_sum [Semiring S] (n : ℕ) (f : ℕ → R → S[X]) : coeff (p.sum f) n = p.sum fun a b => coeff (f a b) n := by rcases p with ⟨⟩ - -- porting note (#10745): was `simp [Polynomial.sum, support, coeff]`. simp [Polynomial.sum, support_ofFinsupp, coeff_ofFinsupp] /-- Decomposes the coefficient of the product `p * q` as a sum diff --git a/Mathlib/Analysis/Calculus/Implicit.lean b/Mathlib/Analysis/Calculus/Implicit.lean index 2e323d8872a829..01a204f86c4db2 100644 --- a/Mathlib/Analysis/Calculus/Implicit.lean +++ b/Mathlib/Analysis/Calculus/Implicit.lean @@ -190,11 +190,7 @@ theorem implicitFunction_hasStrictFDerivAt (g'inv : G →L[𝕜] E) convert this.comp (φ.rightFun φ.pt) ((hasStrictFDerivAt_const _ _).prod (hasStrictFDerivAt_id _)) -- Porting note: added parentheses to help `simp` simp only [ContinuousLinearMap.ext_iff, (ContinuousLinearMap.comp_apply)] at hg'inv hg'invf ⊢ - -- porting note (#10745): was `simp [ContinuousLinearEquiv.eq_symm_apply]`; - -- both `simp` and `rw` fail here, `erw` works - intro x - erw [ContinuousLinearEquiv.eq_symm_apply] - simp [*] + simp [ContinuousLinearEquiv.eq_symm_apply, *] end ImplicitFunctionData diff --git a/Mathlib/Analysis/Normed/Group/AddTorsor.lean b/Mathlib/Analysis/Normed/Group/AddTorsor.lean index c4b97754790bb9..e3a3f8109709e6 100644 --- a/Mathlib/Analysis/Normed/Group/AddTorsor.lean +++ b/Mathlib/Analysis/Normed/Group/AddTorsor.lean @@ -44,8 +44,7 @@ variable {α V P W Q : Type*} [SeminormedAddCommGroup V] [PseudoMetricSpace P] [ instance (priority := 100) NormedAddTorsor.to_isometricVAdd : IsometricVAdd V P := ⟨fun c => Isometry.of_dist_eq fun x y => by - -- porting note (#10745): was `simp [NormedAddTorsor.dist_eq_norm']` - rw [NormedAddTorsor.dist_eq_norm', NormedAddTorsor.dist_eq_norm', vadd_vsub_vadd_cancel_left]⟩ + simp [NormedAddTorsor.dist_eq_norm']⟩ /-- A `SeminormedAddCommGroup` is a `NormedAddTorsor` over itself. -/ instance (priority := 100) SeminormedAddCommGroup.toNormedAddTorsor : NormedAddTorsor V V where @@ -99,8 +98,7 @@ theorem nndist_vadd_cancel_right (v₁ v₂ : V) (x : P) : nndist (v₁ +ᵥ x) @[simp] theorem dist_vadd_left (v : V) (x : P) : dist (v +ᵥ x) x = ‖v‖ := by - -- porting note (#10745): was `simp [dist_eq_norm_vsub V _ x]` - rw [dist_eq_norm_vsub V _ x, vadd_vsub] + simp [dist_eq_norm_vsub V _ x] @[simp] theorem nndist_vadd_left (v : V) (x : P) : nndist (v +ᵥ x) x = ‖v‖₊ := diff --git a/Mathlib/Analysis/Normed/Lp/PiLp.lean b/Mathlib/Analysis/Normed/Lp/PiLp.lean index 2fed648aba0904..3902519c5b489f 100644 --- a/Mathlib/Analysis/Normed/Lp/PiLp.lean +++ b/Mathlib/Analysis/Normed/Lp/PiLp.lean @@ -825,7 +825,6 @@ theorem edist_equiv_symm_single_same (i : ι) (b₁ b₂ : β i) : ((WithLp.equiv p (∀ i, β i)).symm (Pi.single i b₁)) ((WithLp.equiv p (∀ i, β i)).symm (Pi.single i b₂)) = edist b₁ b₂ := by - -- Porting note: was `simpa using` simp only [edist_nndist, nndist_equiv_symm_single_same p β i b₁ b₂] end Single diff --git a/Mathlib/Analysis/RCLike/Basic.lean b/Mathlib/Analysis/RCLike/Basic.lean index 076e45a1a3a711..7db8b7b8d59731 100644 --- a/Mathlib/Analysis/RCLike/Basic.lean +++ b/Mathlib/Analysis/RCLike/Basic.lean @@ -262,7 +262,7 @@ theorem I_im (z : K) : im z * im (I : K) = im z := @[simp, rclike_simps] theorem I_im' (z : K) : im (I : K) * im z = im z := by rw [mul_comm, I_im] -@[rclike_simps] -- porting note (#10618): was `simp` +@[rclike_simps] -- porting note (#11119): was `simp` theorem I_mul_re (z : K) : re (I * z) = -im z := by simp only [I_re, zero_sub, I_im', zero_mul, mul_re] @@ -394,7 +394,7 @@ theorem normSq_one : normSq (1 : K) = 1 := theorem normSq_nonneg (z : K) : 0 ≤ normSq z := add_nonneg (mul_self_nonneg _) (mul_self_nonneg _) -@[rclike_simps] -- porting note (#10618): was `simp` +@[rclike_simps] -- porting note (#11119): was `simp` theorem normSq_eq_zero {z : K} : normSq z = 0 ↔ z = 0 := map_eq_zero _ @@ -409,7 +409,7 @@ theorem normSq_neg (z : K) : normSq (-z) = normSq z := by simp only [normSq_eq_d theorem normSq_conj (z : K) : normSq (conj z) = normSq z := by simp only [normSq_apply, neg_mul, mul_neg, neg_neg, rclike_simps] -@[rclike_simps] -- porting note (#10618): was `simp` +@[rclike_simps] -- porting note (#11119): was `simp` theorem normSq_mul (z w : K) : normSq (z * w) = normSq z * normSq w := map_mul _ z w @@ -466,7 +466,7 @@ theorem div_im (z w : K) : im (z / w) = im z * re w / normSq w - re z * im w / n simp only [div_eq_mul_inv, mul_assoc, sub_eq_add_neg, add_comm, neg_mul, mul_neg, map_neg, rclike_simps] -@[rclike_simps] -- porting note (#10618): was `simp` +@[rclike_simps] -- porting note (#11119): was `simp` theorem conj_inv (x : K) : conj x⁻¹ = (conj x)⁻¹ := star_inv' _ @@ -506,11 +506,11 @@ theorem inv_I : (I : K)⁻¹ = -I := by @[simp, rclike_simps] theorem div_I (z : K) : z / I = -(z * I) := by rw [div_eq_mul_inv, inv_I, mul_neg] -@[rclike_simps] -- porting note (#10618): was `simp` +@[rclike_simps] -- porting note (#11119): was `simp` theorem normSq_inv (z : K) : normSq z⁻¹ = (normSq z)⁻¹ := map_inv₀ normSq z -@[rclike_simps] -- porting note (#10618): was `simp` +@[rclike_simps] -- porting note (#11119): was `simp` theorem normSq_div (z w : K) : normSq (z / w) = normSq z / normSq w := map_div₀ normSq z w diff --git a/Mathlib/Data/Finsupp/AList.lean b/Mathlib/Data/Finsupp/AList.lean index d7f3418427f67f..4946a43826403e 100644 --- a/Mathlib/Data/Finsupp/AList.lean +++ b/Mathlib/Data/Finsupp/AList.lean @@ -103,8 +103,7 @@ theorem insert_lookupFinsupp [DecidableEq α] (l : AList fun _x : α => M) (a : theorem singleton_lookupFinsupp (a : α) (m : M) : (singleton a m).lookupFinsupp = Finsupp.single a m := by classical - -- porting note (#10745): was `simp [← AList.insert_empty]` but timeout issues - simp only [← AList.insert_empty, insert_lookupFinsupp, empty_lookupFinsupp, Finsupp.zero_update] + simp [← AList.insert_empty] @[simp] theorem _root_.Finsupp.toAList_lookupFinsupp (f : α →₀ M) : f.toAList.lookupFinsupp = f := by diff --git a/Mathlib/Data/Seq/WSeq.lean b/Mathlib/Data/Seq/WSeq.lean index d6bd6ad6701cad..5b57888ef3f6e9 100644 --- a/Mathlib/Data/Seq/WSeq.lean +++ b/Mathlib/Data/Seq/WSeq.lean @@ -627,7 +627,6 @@ theorem dropn_cons (a : α) (s) (n) : drop (cons a s) (n + 1) = drop s n := by induction n with | zero => simp [drop] | succ n n_ih => - -- porting note (#10745): was `simp [*, drop]`. simp [drop, ← n_ih] @[simp] @@ -875,7 +874,6 @@ theorem exists_get?_of_mem {s : WSeq α} {a} (h : a ∈ s) : ∃ n, some a ∈ g apply ret_mem · cases' h with n h exists n + 1 - -- porting note (#10745): was `simp [get?]`. simpa [get?] · intro s' h cases' h with n h diff --git a/Mathlib/Geometry/Euclidean/Angle/Oriented/Basic.lean b/Mathlib/Geometry/Euclidean/Angle/Oriented/Basic.lean index 3f2938cdce408f..0ad26516219b68 100644 --- a/Mathlib/Geometry/Euclidean/Angle/Oriented/Basic.lean +++ b/Mathlib/Geometry/Euclidean/Angle/Oriented/Basic.lean @@ -757,19 +757,8 @@ outside of that proof. -/ theorem oangle_smul_add_right_eq_zero_or_eq_pi_iff {x y : V} (r : ℝ) : o.oangle x (r • x + y) = 0 ∨ o.oangle x (r • x + y) = π ↔ o.oangle x y = 0 ∨ o.oangle x y = π := by - simp_rw [oangle_eq_zero_or_eq_pi_iff_not_linearIndependent, Fintype.not_linearIndependent_iff] - -- Porting note: at this point all occurrences of the bound variable `i` are of type - -- `Fin (Nat.succ (Nat.succ 0))`, but `Fin.sum_univ_two` and `Fin.exists_fin_two` expect it to be - -- `Fin 2` instead. Hence all the `conv`s. - -- Was `simp_rw [Fin.sum_univ_two, Fin.exists_fin_two]` - conv_lhs => enter [1, g, 1, 1, 2, i]; tactic => change Fin 2 at i - conv_lhs => enter [1, g]; rw [Fin.sum_univ_two] - conv_rhs => enter [1, g, 1, 1, 2, i]; tactic => change Fin 2 at i - conv_rhs => enter [1, g]; rw [Fin.sum_univ_two] - conv_lhs => enter [1, g, 2, 1, i]; tactic => change Fin 2 at i - conv_lhs => enter [1, g]; rw [Fin.exists_fin_two] - conv_rhs => enter [1, g, 2, 1, i]; tactic => change Fin 2 at i - conv_rhs => enter [1, g]; rw [Fin.exists_fin_two] + simp_rw [oangle_eq_zero_or_eq_pi_iff_not_linearIndependent, Fintype.not_linearIndependent_iff, + Fin.sum_univ_two, Fin.exists_fin_two] refine ⟨fun h => ?_, fun h => ?_⟩ · rcases h with ⟨m, h, hm⟩ change m 0 • x + m 1 • (r • x + y) = 0 at h diff --git a/Mathlib/Geometry/Euclidean/MongePoint.lean b/Mathlib/Geometry/Euclidean/MongePoint.lean index fbf488bef44b30..d829d76dfb4ef8 100644 --- a/Mathlib/Geometry/Euclidean/MongePoint.lean +++ b/Mathlib/Geometry/Euclidean/MongePoint.lean @@ -502,16 +502,8 @@ theorem dist_orthocenter_reflection_circumcenter (t : Triangle ℝ P) {i₁ i₂ ∃ i₃, univ \ ({i₁, i₂} : Finset (Fin 3)) = {i₃} ∧ i₃ ≠ i₁ ∧ i₃ ≠ i₂ := by -- Porting note (#11043): was `decide!` fin_cases i₁ <;> fin_cases i₂ <;> simp at h <;> decide - -- Porting note: Original proof was `simp_rw [← sum_sdiff hu, hi₃]; simp [hi₃₁, hi₃₂]; norm_num` - rw [← sum_sdiff hu, ← sum_sdiff hu, hi₃, sum_singleton, ← sum_sdiff hu, hi₃] - split_ifs with h - · exact (h.elim hi₃₁ hi₃₂).elim - simp only [zero_add, Nat.cast_one, inv_one, sub_zero, one_mul, pointsWithCircumcenter_point, - sum_singleton, h, ite_false, dist_self, mul_zero, mem_singleton, true_or, ite_true, sub_self, - zero_mul, implies_true, sum_insert_of_eq_zero_if_not_mem, or_true, add_zero, div_one, - sub_neg_eq_add, pointsWithCircumcenter_eq_circumcenter, dist_circumcenter_eq_circumradius, - sum_const_zero, dist_circumcenter_eq_circumradius', mul_one, neg_add_rev, add_self_div_two] - norm_num + simp_rw [← sum_sdiff hu, hi₃] + norm_num [hi₃₁, hi₃₂] /-- The distance from the orthocenter to the reflection of the circumcenter in a side equals the circumradius, variant using a diff --git a/Mathlib/GroupTheory/Perm/Fin.lean b/Mathlib/GroupTheory/Perm/Fin.lean index 7df1d1ceaefbeb..6d0fa972e68ea1 100644 --- a/Mathlib/GroupTheory/Perm/Fin.lean +++ b/Mathlib/GroupTheory/Perm/Fin.lean @@ -151,7 +151,7 @@ theorem cycleRange_of_gt {n : ℕ} {i j : Fin n.succ} (h : i < j) : cycleRange i theorem cycleRange_of_le {n : ℕ} {i j : Fin n.succ} (h : j ≤ i) : cycleRange i j = if j = i then 0 else j + 1 := by cases n - · exact Subsingleton.elim (α := Fin 1) _ _ --Porting note; was `simp` + · subsingleton have : j = (Fin.castLE (Nat.succ_le_of_lt i.is_lt)) ⟨j, lt_of_le_of_lt h (Nat.lt_succ_self i)⟩ := by simp ext diff --git a/Mathlib/LinearAlgebra/AffineSpace/Combination.lean b/Mathlib/LinearAlgebra/AffineSpace/Combination.lean index 8d58836617812d..c3adfc82235fd8 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/Combination.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/Combination.lean @@ -935,10 +935,7 @@ theorem affineCombination_mem_affineSpan [Nontrivial k] {s : Finset ι} {w : ι have hv : s.affineCombination k p w -ᵥ p i1 ∈ (affineSpan k (Set.range p)).direction := by rw [direction_affineSpan, ← hw1s, Finset.affineCombination_vsub] apply weightedVSub_mem_vectorSpan - -- Porting note: Rest was `simp [Pi.sub_apply, h, hw1]`, - -- but `Pi.sub_apply` transforms the goal into nonsense - change (Finset.sum s fun i => w i - w1 i) = 0 - simp only [Finset.sum_sub_distrib, h, hw1, sub_self] + simp [Pi.sub_apply, h, hw1] rw [← vsub_vadd (s.affineCombination k p w) (p i1)] exact AffineSubspace.vadd_mem_of_mem_direction hv (mem_affineSpan k (Set.mem_range_self _)) @@ -1019,8 +1016,7 @@ theorem eq_affineCombination_of_mem_affineSpan {p1 : P} {p : ι → P} s'.affineCombination_of_eq_one_of_eq_zero w0 p (Finset.mem_insert_self _ _) (Function.update_same _ _ _) fun _ _ hne => Function.update_noteq hne _ _ refine ⟨s', w0 + w', ?_, ?_⟩ - · -- Porting note: proof was `simp [Pi.add_apply, Finset.sum_add_distrib, hw0, h']` - simp only [Pi.add_apply, Finset.sum_add_distrib, hw0, h', add_zero] + · simp [Pi.add_apply, Finset.sum_add_distrib, hw0, h'] · rw [add_comm, ← Finset.weightedVSub_vadd_affineCombination, hw0s, hs', vsub_vadd] theorem eq_affineCombination_of_mem_affineSpan_of_fintype [Fintype ι] {p1 : P} {p : ι → P} diff --git a/Mathlib/LinearAlgebra/Alternating/Basic.lean b/Mathlib/LinearAlgebra/Alternating/Basic.lean index 69536a10962b01..994b3b3d983dbc 100644 --- a/Mathlib/LinearAlgebra/Alternating/Basic.lean +++ b/Mathlib/LinearAlgebra/Alternating/Basic.lean @@ -491,9 +491,7 @@ theorem add_compLinearMap (f₁ f₂ : M [⋀^ι]→ₗ[R] N) (g : M₂ →ₗ[R theorem compLinearMap_zero [Nonempty ι] (f : M [⋀^ι]→ₗ[R] N) : f.compLinearMap (0 : M₂ →ₗ[R] M) = 0 := by ext - -- Porting note: Was `simp_rw [.., ← Pi.zero_def, map_zero, zero_apply]`. - simp_rw [compLinearMap_apply, LinearMap.zero_apply, ← Pi.zero_def, zero_apply] - exact map_zero f + simp_rw [compLinearMap_apply, LinearMap.zero_apply, ← Pi.zero_def, map_zero, zero_apply] /-- Composing an alternating map with the identity linear map in each argument. -/ @[simp] diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/Grading.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/Grading.lean index e5f6c2be853838..145bb1e7b4a151 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/Grading.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/Grading.lean @@ -214,8 +214,7 @@ theorem odd_induction {P : ∀ x, x ∈ evenOdd Q 1 → Prop} (zero_add (1 : ZMod 2) ▸ SetLike.mul_mem_graded (ι_mul_ι_mem_evenOdd_zero Q m₁ m₂) hx)) (x : CliffordAlgebra Q) (hx : x ∈ evenOdd Q 1) : P x hx := by refine evenOdd_induction _ _ (motive := P) (fun ιv => ?_) add ι_mul_ι_mul x hx - -- Porting note: was `simp_rw [ZMod.val_one, pow_one]`, lean4#1926 - intro h; rw [ZMod.val_one, pow_one] at h; revert h + simp_rw [ZMod.val_one, pow_one] rintro ⟨v, rfl⟩ exact ι v diff --git a/Mathlib/LinearAlgebra/Determinant.lean b/Mathlib/LinearAlgebra/Determinant.lean index dc9936ab62f2ac..c33431bdc1398c 100644 --- a/Mathlib/LinearAlgebra/Determinant.lean +++ b/Mathlib/LinearAlgebra/Determinant.lean @@ -599,9 +599,7 @@ theorem Basis.det_unitsSMul (e : Basis ι R M) (w : ι → Rˣ) : (↑(∏ i, w i)⁻¹ : R) • Matrix.det fun i j => e.repr (f j) i simp only [e.repr_unitsSMul] convert Matrix.det_mul_column (fun i => (↑(w i)⁻¹ : R)) fun i j => e.repr (f j) i - -- porting note (#10745): was `simp [← Finset.prod_inv_distrib]` - simp only [← Finset.prod_inv_distrib] - norm_cast + simp [← Finset.prod_inv_distrib] /-- The determinant of a basis constructed by `unitsSMul` is the product of the given units. -/ @[simp] diff --git a/Mathlib/LinearAlgebra/Isomorphisms.lean b/Mathlib/LinearAlgebra/Isomorphisms.lean index 54a39b6372052a..998bbedc53b52d 100644 --- a/Mathlib/LinearAlgebra/Isomorphisms.lean +++ b/Mathlib/LinearAlgebra/Isomorphisms.lean @@ -120,9 +120,7 @@ theorem quotientInfEquivSupQuotient_symm_apply_left (p p' : Submodule R M) (x : -- @[simp] -- Porting note (#10618): simp can prove this theorem quotientInfEquivSupQuotient_symm_apply_eq_zero_iff {p p' : Submodule R M} {x : ↥(p ⊔ p')} : (quotientInfEquivSupQuotient p p').symm (Submodule.Quotient.mk x) = 0 ↔ (x : M) ∈ p' := - (LinearEquiv.symm_apply_eq _).trans <| by - -- porting note (#10745): was `simp`. - rw [_root_.map_zero, Quotient.mk_eq_zero, mem_comap, Submodule.coe_subtype] + (LinearEquiv.symm_apply_eq _).trans <| by simp theorem quotientInfEquivSupQuotient_symm_apply_right (p p' : Submodule R M) {x : ↥(p ⊔ p')} (hx : (x : M) ∈ p') : (quotientInfEquivSupQuotient p p').symm (Submodule.Quotient.mk x) diff --git a/Mathlib/MeasureTheory/Constructions/Prod/Integral.lean b/Mathlib/MeasureTheory/Constructions/Prod/Integral.lean index 25d335405cc0f8..c86c172d3f6b78 100644 --- a/Mathlib/MeasureTheory/Constructions/Prod/Integral.lean +++ b/Mathlib/MeasureTheory/Constructions/Prod/Integral.lean @@ -153,7 +153,6 @@ theorem integrable_measure_prod_mk_left {s : Set (α × β)} (hs : MeasurableSet refine ⟨(measurable_measure_prod_mk_left hs).ennreal_toReal.aemeasurable.aestronglyMeasurable, ?_⟩ simp_rw [HasFiniteIntegral, ennnorm_eq_ofReal toReal_nonneg] convert h2s.lt_top using 1 - -- Porting note: was `simp_rw` rw [prod_apply hs] apply lintegral_congr_ae filter_upwards [ae_measure_lt_top hs h2s] with x hx @@ -426,7 +425,6 @@ theorem integral_prod (f : α × β → E) (hf : Integrable f (μ.prod ν)) : integral_indicator (measurable_prod_mk_left hs), setIntegral_const, integral_smul_const, integral_toReal (measurable_measure_prod_mk_left hs).aemeasurable (ae_measure_lt_top hs h2s.ne)] - -- Porting note: was `simp_rw` rw [prod_apply hs] · rintro f g - i_f i_g hf hg simp_rw [integral_add' i_f i_g, integral_integral_add' i_f i_g, hf, hg] diff --git a/Mathlib/MeasureTheory/Group/Integral.lean b/Mathlib/MeasureTheory/Group/Integral.lean index 665790505f3cd4..31e10db1f25bb7 100644 --- a/Mathlib/MeasureTheory/Group/Integral.lean +++ b/Mathlib/MeasureTheory/Group/Integral.lean @@ -68,9 +68,7 @@ theorem integral_mul_right_eq_self [IsMulRightInvariant μ] (f : G → E) (g : G @[to_additive] -- Porting note: was `@[simp]` theorem integral_div_right_eq_self [IsMulRightInvariant μ] (f : G → E) (g : G) : (∫ x, f (x / g) ∂μ) = ∫ x, f x ∂μ := by - simp_rw [div_eq_mul_inv] - -- Porting note: was `simp_rw` - rw [integral_mul_right_eq_self f g⁻¹] + simp_rw [div_eq_mul_inv, integral_mul_right_eq_self f g⁻¹] /-- If some left-translate of a function negates it, then the integral of the function with respect to a left-invariant measure is 0. -/ @@ -123,9 +121,8 @@ theorem integrable_comp_div_left (f : G → F) [IsInvInvariant μ] [IsMulLeftInv @[to_additive] -- Porting note: was `@[simp]` theorem integral_div_left_eq_self (f : G → E) (μ : Measure G) [IsInvInvariant μ] [IsMulLeftInvariant μ] (x' : G) : (∫ x, f (x' / x) ∂μ) = ∫ x, f x ∂μ := by - simp_rw [div_eq_mul_inv] - -- Porting note: was `simp_rw` - rw [integral_inv_eq_self (fun x => f (x' * x)) μ, integral_mul_left_eq_self f x'] + simp_rw [div_eq_mul_inv, integral_inv_eq_self (fun x => f (x' * x)) μ, + integral_mul_left_eq_self f x'] end MeasurableMul diff --git a/Mathlib/NumberTheory/Cyclotomic/PrimitiveRoots.lean b/Mathlib/NumberTheory/Cyclotomic/PrimitiveRoots.lean index 0d5dc764a96e23..0e8d24cf92d007 100644 --- a/Mathlib/NumberTheory/Cyclotomic/PrimitiveRoots.lean +++ b/Mathlib/NumberTheory/Cyclotomic/PrimitiveRoots.lean @@ -489,8 +489,7 @@ theorem norm_pow_sub_one_two {k : ℕ} (hζ : IsPrimitiveRoot ζ (2 ^ (k + 1))) have H : (-1 : L) - (1 : L) = algebraMap K L (-2) := by simp only [map_neg, map_ofNat] ring --- Porting note: `simpa using hirr` was `simp [hirr]`. - replace hirr : Irreducible (cyclotomic ((2 : ℕ+) ^ (k + 1) : ℕ+) K) := by simpa using hirr + replace hirr : Irreducible (cyclotomic ((2 : ℕ+) ^ (k + 1) : ℕ+) K) := by simp [hirr] -- Porting note: the proof is slightly different because of coercions. rw [this.eq_neg_one_of_two_right, H, Algebra.norm_algebraMap, IsCyclotomicExtension.finrank L hirr, pow_coe, show ((2 : ℕ+) : ℕ) = 2 from rfl, @@ -506,10 +505,8 @@ theorem norm_sub_one_two {k : ℕ} (hζ : IsPrimitiveRoot ζ (2 ^ k)) (hk : 2 simp only [← coe_lt_coe, one_coe, pow_coe] nth_rw 1 [← pow_one 2] exact pow_lt_pow_right one_lt_two (lt_of_lt_of_le one_lt_two hk) --- Porting note: `simpa using hirr` was `simp [hirr]`_ - replace hirr : Irreducible (cyclotomic ((2 : ℕ+) ^ k : ℕ+) K) := by simpa using hirr --- Porting note: `simpa using hζ` was `simp [hζ]`_ - replace hζ : IsPrimitiveRoot ζ (2 ^ k : ℕ+) := by simpa using hζ + replace hirr : Irreducible (cyclotomic ((2 : ℕ+) ^ k : ℕ+) K) := by simp [hirr] + replace hζ : IsPrimitiveRoot ζ (2 ^ k : ℕ+) := by simp [hζ] obtain ⟨k₁, hk₁⟩ := exists_eq_succ_of_ne_zero (lt_of_lt_of_le zero_lt_two hk).ne.symm -- Porting note: the proof is slightly different because of coercions. simpa [hk₁, show ((2 : ℕ+) : ℕ) = 2 from rfl] using sub_one_norm_eq_eval_cyclotomic hζ this hirr diff --git a/Mathlib/RingTheory/DedekindDomain/PID.lean b/Mathlib/RingTheory/DedekindDomain/PID.lean index 258435cca7f9ae..6bc5095ed0a68f 100644 --- a/Mathlib/RingTheory/DedekindDomain/PID.lean +++ b/Mathlib/RingTheory/DedekindDomain/PID.lean @@ -42,7 +42,6 @@ theorem Ideal.eq_span_singleton_of_mem_of_not_mem_sq_of_not_mem_prime_ne {P : Id exact hxP2 (zero_mem _) by_cases hP0 : P = ⊥ · subst hP0 - -- Porting note: was `simpa using hxP2` but that hypothesis didn't even seem relevant in Lean 3 rwa [eq_comm, span_singleton_eq_bot, ← mem_bot] have hspan0 : span ({x} : Set R) ≠ ⊥ := mt Ideal.span_singleton_eq_bot.mp hx0 have span_le := (Ideal.span_singleton_le_iff_mem _).mpr x_mem diff --git a/Mathlib/RingTheory/DedekindDomain/SInteger.lean b/Mathlib/RingTheory/DedekindDomain/SInteger.lean index b80cad635c1d7d..83b4fe6cf90212 100644 --- a/Mathlib/RingTheory/DedekindDomain/SInteger.lean +++ b/Mathlib/RingTheory/DedekindDomain/SInteger.lean @@ -69,9 +69,7 @@ def integer : Subalgebra R K := theorem integer_eq : (S.integer K).toSubring = ⨅ (v) (_ : v ∉ S), (v : HeightOneSpectrum R).valuation.valuationSubring.toSubring := - SetLike.ext' <| by - -- Porting note: was `simpa only [integer, Subring.copy_eq]` - ext; simp + SetLike.ext' <| by ext; simp theorem integer_valuation_le_one (x : S.integer K) {v : HeightOneSpectrum R} (hv : v ∉ S) : v.valuation (x : K) ≤ 1 := diff --git a/Mathlib/SetTheory/Cardinal/Basic.lean b/Mathlib/SetTheory/Cardinal/Basic.lean index cf4dfeb391b9ee..8c37e772ce499d 100644 --- a/Mathlib/SetTheory/Cardinal/Basic.lean +++ b/Mathlib/SetTheory/Cardinal/Basic.lean @@ -1380,7 +1380,7 @@ theorem mk_finset_of_fintype [Fintype α] : #(Finset α) = 2 ^ Fintype.card α : theorem card_le_of_finset {α} (s : Finset α) : (s.card : Cardinal) ≤ #α := @mk_coe_finset _ s ▸ mk_set_le _ --- Porting note: was `simp`. LHS is not normal form. +-- Porting note (#11119): was `simp`. LHS is not normal form. -- @[simp, norm_cast] @[norm_cast] theorem natCast_pow {m n : ℕ} : (↑(m ^ n) : Cardinal) = (↑m : Cardinal) ^ (↑n : Cardinal) := by diff --git a/Mathlib/Topology/Algebra/Module/Basic.lean b/Mathlib/Topology/Algebra/Module/Basic.lean index 3a3b76145aaeba..451dff66e30df3 100644 --- a/Mathlib/Topology/Algebra/Module/Basic.lean +++ b/Mathlib/Topology/Algebra/Module/Basic.lean @@ -1186,11 +1186,7 @@ def iInfKerProjEquiv {I J : Set ι} [DecidablePred fun i => i ∈ I] (hd : Disjo continuous_invFun := Continuous.subtype_mk (continuous_pi fun i => by - -- Porting note: Was `dsimp`. - change - Continuous (⇑(if h : i ∈ I then LinearMap.proj (R := R) (ι := ↥I) - (φ := fun i : ↥I => φ i) ⟨i, h⟩ else - (0 : ((i : I) → φ i) →ₗ[R] φ i))) + dsimp split_ifs <;> [apply continuous_apply; exact continuous_zero]) _ diff --git a/Mathlib/Topology/Instances/AddCircle.lean b/Mathlib/Topology/Instances/AddCircle.lean index 3295ee564f992c..969b2df626d4d1 100644 --- a/Mathlib/Topology/Instances/AddCircle.lean +++ b/Mathlib/Topology/Instances/AddCircle.lean @@ -591,9 +591,7 @@ homeomorphism of topological spaces. -/ def homeoIccQuot [TopologicalSpace 𝕜] [OrderTopology 𝕜] : 𝕋 ≃ₜ Quot (EndpointIdent p a) where toEquiv := equivIccQuot p a continuous_toFun := by - -- Porting note: was `simp_rw` - rw [quotientMap_quotient_mk'.continuous_iff] - simp_rw [continuous_iff_continuousAt, + simp_rw [quotientMap_quotient_mk'.continuous_iff, continuous_iff_continuousAt, continuousAt_iff_continuous_left_right] intro x; constructor on_goal 1 => erw [equivIccQuot_comp_mk_eq_toIocMod] From 402539e198cca9e794758c2ea3586a9e875d315b Mon Sep 17 00:00:00 2001 From: Andrew Yang Date: Thu, 17 Oct 2024 09:17:43 +0000 Subject: [PATCH 286/425] feat(Topology): set of generic points of generic components (#15407) Co-authored-by: Andrew Yang <36414270+erdOne@users.noreply.github.com> --- Mathlib/AlgebraicGeometry/FunctionField.lean | 6 +- Mathlib/Topology/Irreducible.lean | 5 + Mathlib/Topology/Sober.lean | 99 ++++++++++++++++++-- 3 files changed, 98 insertions(+), 12 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/FunctionField.lean b/Mathlib/AlgebraicGeometry/FunctionField.lean index 1b998330cf3664..242c360e3de84f 100644 --- a/Mathlib/AlgebraicGeometry/FunctionField.lean +++ b/Mathlib/AlgebraicGeometry/FunctionField.lean @@ -51,7 +51,7 @@ noncomputable instance [IsIntegral X] : Field X.functionField := by intro ha replace ha := ne_of_apply_ne _ ha have hs : genericPoint X ∈ RingedSpace.basicOpen _ s := by - rw [← SetLike.mem_coe, (genericPoint_spec X).mem_open_set_iff, Set.top_eq_univ, + rw [← SetLike.mem_coe, (genericPoint_spec X).mem_open_set_iff, Set.univ_inter, Set.nonempty_iff_ne_empty, Ne, ← Opens.coe_bot, ← SetLike.ext'_iff] · erw [basicOpen_eq_bot_iff] exact ha @@ -79,7 +79,7 @@ theorem genericPoint_eq_of_isOpenImmersion {X Y : Scheme} (f : X ⟶ Y) [H : IsO apply ((genericPoint_spec Y).eq _).symm convert (genericPoint_spec X).image (show Continuous f.base by fun_prop) symm - rw [eq_top_iff, Set.top_eq_univ, Set.top_eq_univ] + rw [← Set.univ_subset_iff] convert subset_closure_inter_of_isPreirreducible_of_isOpen _ H.base_open.isOpen_range _ · rw [Set.univ_inter, Set.image_univ] · apply PreirreducibleSpace.isPreirreducible_univ (X := Y) @@ -107,7 +107,7 @@ theorem genericPoint_eq_bot_of_affine (R : CommRingCat) [IsDomain R] : apply (genericPoint_spec (Spec R)).eq rw [isGenericPoint_def] rw [← PrimeSpectrum.zeroLocus_vanishingIdeal_eq_closure, PrimeSpectrum.vanishingIdeal_singleton] - rw [Set.top_eq_univ, ← PrimeSpectrum.zeroLocus_singleton_zero] + rw [← PrimeSpectrum.zeroLocus_singleton_zero] rfl instance functionField_isFractionRing_of_affine (R : CommRingCat.{u}) [IsDomain R] : diff --git a/Mathlib/Topology/Irreducible.lean b/Mathlib/Topology/Irreducible.lean index 8a868fe36faa70..17b268468df10a 100644 --- a/Mathlib/Topology/Irreducible.lean +++ b/Mathlib/Topology/Irreducible.lean @@ -212,6 +212,11 @@ instance (priority := 100) {X} [Infinite X] : IrreducibleSpace (CofiniteTopology simpa only [compl_union, compl_compl] using ((hu hu').union (hv hv')).infinite_compl.nonempty toNonempty := (inferInstance : Nonempty X) +theorem irreducibleComponents_eq_singleton [IrreducibleSpace X] : + irreducibleComponents X = {univ} := + Set.ext fun _ ↦ IsGreatest.maximal_iff (s := IsIrreducible (X := X)) + ⟨IrreducibleSpace.isIrreducible_univ X, fun _ _ ↦ Set.subset_univ _⟩ + /-- A set `s` is irreducible if and only if for every finite collection of open sets all of whose members intersect `s`, `s` also intersects the intersection of the entire collection diff --git a/Mathlib/Topology/Sober.lean b/Mathlib/Topology/Sober.lean index a4717443959a5d..82c12d98222d64 100644 --- a/Mathlib/Topology/Sober.lean +++ b/Mathlib/Topology/Sober.lean @@ -19,6 +19,7 @@ stated via `[QuasiSober α] [T0Space α]`. * `IsGenericPoint` : `x` is the generic point of `S` if `S` is the closure of `x`. * `QuasiSober` : A space is quasi-sober if every irreducible closed subset has a generic point. +* `genericPoints` : The set of generic points of irreducible components. -/ @@ -108,14 +109,28 @@ noncomputable def IsIrreducible.genericPoint [QuasiSober α] {S : Set α} (hS : α := (QuasiSober.sober hS.closure isClosed_closure).choose -theorem IsIrreducible.genericPoint_spec [QuasiSober α] {S : Set α} (hS : IsIrreducible S) : +theorem IsIrreducible.isGenericPoint_genericPoint_closure + [QuasiSober α] {S : Set α} (hS : IsIrreducible S) : IsGenericPoint hS.genericPoint (closure S) := (QuasiSober.sober hS.closure isClosed_closure).choose_spec +theorem IsIrreducible.isGenericPoint_genericPoint [QuasiSober α] {S : Set α} + (hS : IsIrreducible S) (hS' : IsClosed S) : + IsGenericPoint hS.genericPoint S := by + convert hS.isGenericPoint_genericPoint_closure; exact hS'.closure_eq.symm + @[simp] theorem IsIrreducible.genericPoint_closure_eq [QuasiSober α] {S : Set α} (hS : IsIrreducible S) : closure ({hS.genericPoint} : Set α) = closure S := - hS.genericPoint_spec + hS.isGenericPoint_genericPoint_closure + +theorem IsIrreducible.closure_genericPoint [QuasiSober α] {S : Set α} + (hS : IsIrreducible S) (hS' : IsClosed S) : + closure ({hS.genericPoint} : Set α) = S := + hS.isGenericPoint_genericPoint_closure.trans hS'.closure_eq + +@[deprecated (since := "2024-10-03")] +alias IsIrreducible.genericPoint_spec := IsIrreducible.isGenericPoint_genericPoint_closure variable (α) @@ -124,18 +139,18 @@ noncomputable def genericPoint [QuasiSober α] [IrreducibleSpace α] : α := (IrreducibleSpace.isIrreducible_univ α).genericPoint theorem genericPoint_spec [QuasiSober α] [IrreducibleSpace α] : - IsGenericPoint (genericPoint α) ⊤ := by - simpa using (IrreducibleSpace.isIrreducible_univ α).genericPoint_spec + IsGenericPoint (genericPoint α) univ := by + simpa using (IrreducibleSpace.isIrreducible_univ α).isGenericPoint_genericPoint_closure @[simp] theorem genericPoint_closure [QuasiSober α] [IrreducibleSpace α] : - closure ({genericPoint α} : Set α) = ⊤ := + closure ({genericPoint α} : Set α) = univ := genericPoint_spec α variable {α} theorem genericPoint_specializes [QuasiSober α] [IrreducibleSpace α] (x : α) : genericPoint α ⤳ x := - (IsIrreducible.genericPoint_spec _).specializes (by simp) + (IsIrreducible.isGenericPoint_genericPoint_closure _).specializes (by simp) attribute [local instance] specializationOrder @@ -149,7 +164,7 @@ noncomputable def irreducibleSetEquivPoints [QuasiSober α] [T0Space α] : simp only [IsIrreducible.genericPoint_closure_eq, TopologicalSpace.IrreducibleCloseds.coe_mk, closure_eq_iff_isClosed.mpr s.3] rfl - right_inv x := isIrreducible_singleton.closure.genericPoint_spec.eq + right_inv x := isIrreducible_singleton.closure.isGenericPoint_genericPoint_closure.eq (by rw [closure_closure]; exact isGenericPoint_closure) map_rel_iff' := by rintro ⟨s, hs, hs'⟩ ⟨t, ht, ht'⟩ @@ -204,12 +219,13 @@ theorem quasiSober_of_open_cover (S : Set (Set α)) (hS : ∀ s : S, IsOpen (s : h.2.preimage (hS ⟨U, hU⟩).openEmbedding_subtype_val replace H : IsIrreducible ((↑) ⁻¹' t : Set U) := ⟨⟨⟨x, hU'⟩, by simpa using hx⟩, H⟩ use H.genericPoint - have := continuous_subtype_val.closure_preimage_subset _ H.genericPoint_spec.mem + have := continuous_subtype_val.closure_preimage_subset _ H.isGenericPoint_genericPoint_closure.mem rw [h'.closure_eq] at this apply le_antisymm · apply h'.closure_subset_iff.mpr simpa using this - rw [← image_singleton, ← closure_image_closure continuous_subtype_val, H.genericPoint_spec.def] + rw [← image_singleton, ← closure_image_closure continuous_subtype_val, + H.isGenericPoint_genericPoint_closure.def] refine (subset_closure_inter_of_isPreirreducible_of_isOpen h.2 (hS ⟨U, hU⟩) ⟨x, hx, hU'⟩).trans (closure_mono ?_) rw [inter_comm t, ← Subtype.image_preimage_coe] @@ -222,3 +238,68 @@ instance (priority := 100) T2Space.quasiSober [T2Space α] : QuasiSober α where exact ⟨x, closure_singleton⟩ end Sober + +section genericPoints + +variable (α) in +/-- The set of generic points of irreducible components. -/ +def genericPoints : Set α := { x | closure {x} ∈ irreducibleComponents α } + +namespace genericPoints + +/-- The irreducible component of a generic point -/ +def component (x : genericPoints α) : irreducibleComponents α := + ⟨closure {x.1}, x.2⟩ + +lemma isGenericPoint (x : genericPoints α) : IsGenericPoint x.1 (component x).1 := rfl + +lemma component_injective [T0Space α] : Function.Injective (component (α := α)) := + fun x y e ↦ Subtype.ext ((isGenericPoint x).eq (e ▸ isGenericPoint y)) + +/-- The generic point of an irreducible component. -/ +noncomputable +def ofComponent [QuasiSober α] (x : irreducibleComponents α) : genericPoints α := + ⟨x.2.1.genericPoint, show _ ∈ irreducibleComponents α from + (x.2.1.isGenericPoint_genericPoint (isClosed_of_mem_irreducibleComponents x.1 x.2)).symm ▸ x.2⟩ + +lemma isGenericPoint_ofComponent [QuasiSober α] (x : irreducibleComponents α) : + IsGenericPoint (ofComponent x).1 x := + x.2.1.isGenericPoint_genericPoint (isClosed_of_mem_irreducibleComponents x.1 x.2) + +@[simp] +lemma component_ofComponent [QuasiSober α] (x : irreducibleComponents α) : + component (ofComponent x) = x := + Subtype.ext (isGenericPoint_ofComponent x) + +@[simp] +lemma ofComponent_component [T0Space α] [QuasiSober α] (x : genericPoints α) : + ofComponent (component x) = x := + component_injective (component_ofComponent _) + +lemma component_surjective [QuasiSober α] : Function.Surjective (component (α := α)) := + Function.HasRightInverse.surjective ⟨ofComponent, component_ofComponent⟩ + +lemma finite [T0Space α] (h : (irreducibleComponents α).Finite) : (genericPoints α).Finite := + @Finite.of_injective _ _ h _ component_injective + +/-- In a sober space, the generic points corresponds bijectively to irreducible components -/ +@[simps] +noncomputable +def equiv [T0Space α] [QuasiSober α] : genericPoints α ≃ irreducibleComponents α := + ⟨component, ofComponent, ofComponent_component, component_ofComponent⟩ + +lemma closure [QuasiSober α] : closure (genericPoints α) = Set.univ := by + refine Set.eq_univ_iff_forall.mpr fun x ↦ Set.subset_def.mp ?_ x mem_irreducibleComponent + refine (isGenericPoint_ofComponent + ⟨_, irreducibleComponent_mem_irreducibleComponents x⟩).symm.trans_subset (closure_mono ?_) + exact Set.singleton_subset_iff.mpr (ofComponent _).2 + +end genericPoints + +lemma genericPoints_eq_singleton [QuasiSober α] [IrreducibleSpace α] [T0Space α] : + genericPoints α = {genericPoint α} := by + ext x + rw [genericPoints, irreducibleComponents_eq_singleton] + exact ⟨((genericPoint_spec α).eq · |>.symm), (· ▸ genericPoint_spec α)⟩ + +end genericPoints From d8ceed52a92e5b0ba56911202c89d75114ce9d1b Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Thu, 17 Oct 2024 09:39:27 +0000 Subject: [PATCH 287/425] feat(AlgebraicGeometry): smooth morphisms of schemes (#14161) We say a morphism of schemes is smooth (of relative dimension `n`) if for every point of the source there exist affine open neighborhoods of the point and its image such that the induced ring map is standard smooth (of relative dimension `n`). These notions are local on the source and the target and satisfy the standard stability properties. This contribution was created as part of the AIM workshop "Formalizing algebraic geometry" in June 2024. --- Mathlib.lean | 1 + .../Morphisms/RingHomProperties.lean | 70 ++++++++ .../AlgebraicGeometry/Morphisms/Smooth.lean | 167 ++++++++++++++++++ 3 files changed, 238 insertions(+) create mode 100644 Mathlib/AlgebraicGeometry/Morphisms/Smooth.lean diff --git a/Mathlib.lean b/Mathlib.lean index cb62c7d0053296..9005c78e9dcb79 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -870,6 +870,7 @@ import Mathlib.AlgebraicGeometry.Morphisms.QuasiCompact import Mathlib.AlgebraicGeometry.Morphisms.QuasiSeparated import Mathlib.AlgebraicGeometry.Morphisms.RingHomProperties import Mathlib.AlgebraicGeometry.Morphisms.Separated +import Mathlib.AlgebraicGeometry.Morphisms.Smooth import Mathlib.AlgebraicGeometry.Morphisms.UnderlyingMap import Mathlib.AlgebraicGeometry.Morphisms.UniversallyClosed import Mathlib.AlgebraicGeometry.Noetherian diff --git a/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean b/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean index 8e9613ac56f3a2..06bd0001fe507c 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/RingHomProperties.lean @@ -163,6 +163,63 @@ theorem sourceAffineLocally_isLocal (h₁ : RingHom.RespectsIso P) rwa [IsAffineOpen.appLE_eq_away_map f (isAffineOpen_top Y) U.2, ← h₁.is_localization_away_iff] at this +open RingHom + +variable {P} {X Y : Scheme.{u}} {f : X ⟶ Y} + +/-- 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₁`). -/ +lemma exists_basicOpen_le_appLE_of_appLE_of_isAffine + (hPa : StableUnderCompositionWithLocalizationAway P) (hPl : LocalizationPreserves P) + (x : X) (U₁ : Y.affineOpens) (U₂ : Y.affineOpens) (V₁ : X.affineOpens) (V₂ : X.affineOpens) + (hx₁ : x ∈ V₁.1) (hx₂ : x ∈ V₂.1) (e₂ : V₂.1 ≤ f ⁻¹ᵁ U₂.1) (h₂ : P (f.appLE U₂ V₂ e₂)) + (hfx₁ : f.base x ∈ U₁.1) : + ∃ (r : Γ(Y, U₁)) (s : Γ(X, V₁)) (_ : x ∈ X.basicOpen s) + (e : X.basicOpen s ≤ f ⁻¹ᵁ Y.basicOpen r), P (f.appLE (Y.basicOpen r) (X.basicOpen s) e) := by + obtain ⟨r, r', hBrr', hBfx⟩ := exists_basicOpen_le_affine_inter U₁.2 U₂.2 (f.base x) + ⟨hfx₁, e₂ hx₂⟩ + have ha : IsAffineOpen (X.basicOpen (f.appLE U₂ V₂ e₂ r')) := V₂.2.basicOpen _ + 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 ers : X.basicOpen s ≤ f ⁻¹ᵁ Y.basicOpen r := by + rw [hBss', hBrr'] + apply le_trans (X.basicOpen_le _) + simp [Scheme.Hom.appLE] + have heq : f.appLE (Y.basicOpen r') (X.basicOpen s') (hBrr' ▸ hBss' ▸ ers) = + f.appLE (Y.basicOpen r') (X.basicOpen (f.appLE U₂ V₂ e₂ r')) (by simp [Scheme.Hom.appLE]) ≫ + algebraMap _ _ := by + simp only [Scheme.Hom.appLE, homOfLE_leOfHom, CommRingCat.comp_apply, Category.assoc] + congr + apply X.presheaf.map_comp + refine ⟨r, s, hBx, ers, ?_⟩ + · rw [f.appLE_congr _ hBrr' hBss' P, heq] + apply hPa.left _ s' _ + rw [U₂.2.appLE_eq_away_map f V₂.2] + exact hPl.away _ h₂ + +/-- If `P` holds for `f` over affine opens `U₂` of `Y` and `V₂` of `X` and `U₁` (resp. `V₁`) are +open neighborhoods of `x` (resp. `f.base x`), then `P` also holds for `f` over some affine open +`U'` of `Y` (resp. `V'` of `X`) that is contained in `U₁` (resp. `V₁`). -/ +lemma exists_affineOpens_le_appLE_of_appLE + (hPa : StableUnderCompositionWithLocalizationAway P) (hPl : LocalizationPreserves P) + (x : X) (U₁ : Y.Opens) (U₂ : Y.affineOpens) (V₁ : X.Opens) (V₂ : X.affineOpens) + (hx₁ : x ∈ V₁) (hx₂ : x ∈ V₂.1) (e₂ : V₂.1 ≤ f ⁻¹ᵁ U₂.1) (h₂ : P (f.appLE U₂ V₂ e₂)) + (hfx₁ : f.base x ∈ U₁.1) : + ∃ (U' : Y.affineOpens) (V' : X.affineOpens) (_ : U'.1 ≤ U₁) (_ : V'.1 ≤ V₁) (_ : x ∈ V'.1) + (e : V'.1 ≤ f⁻¹ᵁ U'.1), P (f.appLE U' V' e) := by + obtain ⟨r, hBr, hBfx⟩ := U₂.2.exists_basicOpen_le ⟨f.base x, hfx₁⟩ (e₂ hx₂) + obtain ⟨s, hBs, hBx⟩ := V₂.2.exists_basicOpen_le ⟨x, hx₁⟩ hx₂ + obtain ⟨r', s', hBx', e', hf'⟩ := exists_basicOpen_le_appLE_of_appLE_of_isAffine hPa hPl x + ⟨Y.basicOpen r, U₂.2.basicOpen _⟩ U₂ ⟨X.basicOpen s, V₂.2.basicOpen _⟩ V₂ hBx hx₂ e₂ h₂ hBfx + exact ⟨⟨Y.basicOpen r', (U₂.2.basicOpen _).basicOpen _⟩, + ⟨X.basicOpen s', (V₂.2.basicOpen _).basicOpen _⟩, le_trans (Y.basicOpen_le _) hBr, + le_trans (X.basicOpen_le _) hBs, hBx', e', hf'⟩ + end affineLocally /-- @@ -475,6 +532,19 @@ lemma iff_exists_appLE : P f ↔ haveI : HasRingHomProperty P Q := inst apply (isLocal_ringHomProperty P (Q := Q)).respectsIso +omit [HasRingHomProperty P Q] in +lemma locally_of_iff (hQl : LocalizationPreserves Q) + (hQa : StableUnderCompositionWithLocalizationAway Q) + (h : ∀ {X Y : Scheme.{u}} (f : X ⟶ Y), 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)) : HasRingHomProperty P (Locally Q) where + isLocal_ringHomProperty := locally_propertyIsLocal hQl hQa + eq_affineLocally' := by + haveI : 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.respectsIso] + end HasRingHomProperty end AlgebraicGeometry diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Smooth.lean b/Mathlib/AlgebraicGeometry/Morphisms/Smooth.lean new file mode 100644 index 00000000000000..31d2f234dbb6d6 --- /dev/null +++ b/Mathlib/AlgebraicGeometry/Morphisms/Smooth.lean @@ -0,0 +1,167 @@ +/- +Copyright (c) 2024 Christian Merten. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christian Merten +-/ +import Mathlib.AlgebraicGeometry.Morphisms.RingHomProperties +import Mathlib.RingTheory.RingHom.StandardSmooth + +/-! + +# Smooth morphisms + +A morphism of schemes `f : X ⟶ Y` is smooth (of relative dimension `n`) if for each `x : X` there +exists an affine open neighborhood `V` of `x` and an affine open neighborhood `U` of +`f.base x` with `V ≤ f ⁻¹ᵁ U` such that the induced map `Γ(Y, U) ⟶ Γ(X, V)` is +standard smooth (of relative dimension `n`). + +In other words, smooth (resp. smooth of relative dimension `n`) for scheme morphisms is associated +to the property of ring homomorphisms `Locally IsStandardSmooth` +(resp. `Locally (IsStandardSmoothOfRelativeDimension n)`). + +## Implementation details + +- Our definition is equivalent to defining `IsSmooth` as the associated scheme morphism property of +the property of ring maps induced by `Algebra.Smooth`. The equivalence will follow from the +equivalence of `Locally IsStandardSmooth` and `Algebra.IsSmooth`, but the latter is a (hard) TODO. + +The reason why we choose the definition via `IsStandardSmooth`, is because verifying that +`Algebra.IsSmooth` is local in the sense of `RingHom.PropertyIsLocal` is a (hard) TODO. + +- The definition `RingHom.IsStandardSmooth` depends on universe levels for the generators and +relations. For morphisms of schemes we set both to `0` to avoid unnecessary complications. + +## Notes + +This contribution was created as part of the AIM workshop "Formalizing algebraic geometry" in +June 2024. + +-/ + + +noncomputable section + +open CategoryTheory + +universe t w v u + +namespace AlgebraicGeometry + +open RingHom + +variable (n m : ℕ) {X Y : Scheme.{u}} (f : X ⟶ Y) + +/-- +A morphism of schemes `f : X ⟶ Y` is smooth if for each `x : X` there +exists an affine open neighborhood `V` of `x` and an affine open neighborhood `U` of +`f.base x` with `V ≤ f ⁻¹ᵁ U` such that the induced map `Γ(Y, U) ⟶ Γ(X, V)` is +standard smooth. +-/ +@[mk_iff] +class IsSmooth : Prop where + exists_isStandardSmooth : ∀ (x : X), ∃ (U : Y.affineOpens) (V : X.affineOpens) (_ : x ∈ V.1) + (e : V.1 ≤ f ⁻¹ᵁ U.1), IsStandardSmooth.{0, 0} (f.appLE U V e) + +/-- The property of scheme morphisms `IsSmooth` is associated with the ring +homomorphism property `Locally IsStandardSmooth.{0, 0}`. -/ +instance : HasRingHomProperty @IsSmooth (Locally IsStandardSmooth.{0, 0}) := by + apply HasRingHomProperty.locally_of_iff + · exact isStandardSmooth_localizationPreserves + · exact isStandardSmooth_stableUnderCompositionWithLocalizationAway + · intro X Y f + rw [isSmooth_iff] + +/-- Being smooth is stable under composition. -/ +instance : MorphismProperty.IsStableUnderComposition @IsSmooth := + HasRingHomProperty.stableUnderComposition <| locally_stableUnderComposition + isStandardSmooth_respectsIso isStandardSmooth_localizationPreserves + isStandardSmooth_stableUnderComposition + +/-- The composition of smooth morphisms is smooth. -/ +instance isSmooth_comp {Z : Scheme.{u}} (g : Y ⟶ Z) [IsSmooth f] [IsSmooth g] : + IsSmooth (f ≫ g) := + MorphismProperty.comp_mem _ f g ‹IsSmooth f› ‹IsSmooth g› + +/-- Smooth of relative dimension `n` is stable under base change. -/ +lemma isSmooth_stableUnderBaseChange : MorphismProperty.StableUnderBaseChange @IsSmooth := + HasRingHomProperty.stableUnderBaseChange <| locally_stableUnderBaseChange + isStandardSmooth_respectsIso isStandardSmooth_stableUnderBaseChange + +/-- +A morphism of schemes `f : X ⟶ Y` is smooth of relative dimension `n` if for each `x : X` there +exists an affine open neighborhood `V` of `x` and an affine open neighborhood `U` of +`f.base x` with `V ≤ f ⁻¹ᵁ U` such that the induced map `Γ(Y, U) ⟶ Γ(X, V)` is +standard smooth of relative dimension `n`. +-/ +@[mk_iff] +class IsSmoothOfRelativeDimension : Prop where + exists_isStandardSmoothOfRelativeDimension : ∀ (x : X), ∃ (U : Y.affineOpens) + (V : X.affineOpens) (_ : x ∈ V.1) (e : V.1 ≤ f ⁻¹ᵁ U.1), + IsStandardSmoothOfRelativeDimension.{0, 0} n (f.appLE U V e) + +/-- If `f` is smooth of any relative dimension, it is smooth. -/ +lemma IsSmoothOfRelativeDimension.isSmooth [IsSmoothOfRelativeDimension n f] : IsSmooth f where + exists_isStandardSmooth x := by + obtain ⟨U, V, hx, e, hf⟩ := exists_isStandardSmoothOfRelativeDimension (n := n) (f := f) x + exact ⟨U, V, hx, e, hf.isStandardSmooth⟩ + +/-- The property of scheme morphisms `IsSmoothOfRelativeDimension n` is associated with the ring +homomorphism property `Locally (IsStandardSmoothOfRelativeDimension.{0, 0} n)`. -/ +instance : HasRingHomProperty (@IsSmoothOfRelativeDimension n) + (Locally (IsStandardSmoothOfRelativeDimension.{0, 0} n)) := by + apply HasRingHomProperty.locally_of_iff + · exact isStandardSmoothOfRelativeDimension_localizationPreserves n + · exact isStandardSmoothOfRelativeDimension_stableUnderCompositionWithLocalizationAway n + · intro X Y f + rw [isSmoothOfRelativeDimension_iff] + +/-- Smooth of relative dimension `n` is stable under base change. -/ +lemma isSmoothOfRelativeDimension_stableUnderBaseChange : + MorphismProperty.StableUnderBaseChange (@IsSmoothOfRelativeDimension n) := + HasRingHomProperty.stableUnderBaseChange <| locally_stableUnderBaseChange + isStandardSmoothOfRelativeDimension_respectsIso + (isStandardSmoothOfRelativeDimension_stableUnderBaseChange n) + +/-- Open immersions are smooth of relative dimension `0`. -/ +instance (priority := 900) [IsOpenImmersion f] : IsSmoothOfRelativeDimension 0 f := + HasRingHomProperty.of_isOpenImmersion + (locally_holdsForLocalizationAway <| + isStandardSmoothOfRelativeDimension_holdsForLocalizationAway).containsIdentities + +/-- Open immersions are smooth. -/ +instance (priority := 900) [IsOpenImmersion f] : IsSmooth f := + IsSmoothOfRelativeDimension.isSmooth 0 f + +/-- If `f` is smooth of relative dimension `n` and `g` is smooth of relative dimension +`m`, then `f ≫ g` is smooth of relative dimension `n + m`. -/ +instance isSmoothOfRelativeDimension_comp {Z : Scheme.{u}} (g : Y ⟶ Z) + [hf : IsSmoothOfRelativeDimension n f] [hg : IsSmoothOfRelativeDimension m g] : + IsSmoothOfRelativeDimension (n + m) (f ≫ g) where + exists_isStandardSmoothOfRelativeDimension x := by + obtain ⟨U₂, V₂, hfx₂, e₂, hf₂⟩ := hg.exists_isStandardSmoothOfRelativeDimension (f.base x) + obtain ⟨U₁', V₁', hx₁', e₁', hf₁'⟩ := hf.exists_isStandardSmoothOfRelativeDimension x + obtain ⟨r, s, hx₁, e₁, hf₁⟩ := exists_basicOpen_le_appLE_of_appLE_of_isAffine + (isStandardSmoothOfRelativeDimension_stableUnderCompositionWithLocalizationAway n) + (isStandardSmoothOfRelativeDimension_localizationPreserves n) + x V₂ U₁' V₁' V₁' hx₁' hx₁' e₁' hf₁' hfx₂ + have e : X.basicOpen s ≤ (f ≫ g) ⁻¹ᵁ U₂ := + le_trans e₁ <| f.preimage_le_preimage_of_le <| le_trans (Y.basicOpen_le r) e₂ + have heq : (f ≫ g).appLE U₂ (X.basicOpen s) e = g.appLE U₂ V₂ e₂ ≫ + algebraMap Γ(Y, V₂) Γ(Y, Y.basicOpen r) ≫ f.appLE (Y.basicOpen r) (X.basicOpen s) e₁ := by + rw [RingHom.algebraMap_toAlgebra, g.appLE_map_assoc, Scheme.appLE_comp_appLE] + refine ⟨U₂, ⟨X.basicOpen s, V₁'.2.basicOpen s⟩, hx₁, e, heq ▸ ?_⟩ + apply IsStandardSmoothOfRelativeDimension.comp ?_ hf₂ + haveI : IsLocalization.Away r Γ(Y, Y.basicOpen r) := V₂.2.isLocalization_basicOpen r + exact (isStandardSmoothOfRelativeDimension_stableUnderCompositionWithLocalizationAway n).right + _ r _ hf₁ + +instance {Z : Scheme.{u}} (g : Y ⟶ Z) [IsSmoothOfRelativeDimension 0 f] + [IsSmoothOfRelativeDimension 0 g] : + IsSmoothOfRelativeDimension 0 (f ≫ g) := + inferInstanceAs <| IsSmoothOfRelativeDimension (0 + 0) (f ≫ g) + +/-- Smooth of relative dimension `0` is stable under composition. -/ +instance : MorphismProperty.IsStableUnderComposition (@IsSmoothOfRelativeDimension 0) where + comp_mem _ _ _ _ := inferInstance + +end AlgebraicGeometry From c199a0e22d7561cee51596b0230955f96f882153 Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Thu, 17 Oct 2024 09:39:28 +0000 Subject: [PATCH 288/425] feat(AlgebraicGeometry): closed immersions with affine target (#15038) Shows that closed immersions are affine morphisms inducing affine locally surjective maps on sections. --- Mathlib/Algebra/Category/Ring/Basic.lean | 10 ++ Mathlib/Algebra/GroupWithZero/Basic.lean | 5 + Mathlib/AlgebraicGeometry/AffineScheme.lean | 15 ++ .../Morphisms/ClosedImmersion.lean | 136 +++++++++++++++++- .../Morphisms/QuasiCompact.lean | 14 ++ .../Morphisms/QuasiSeparated.lean | 26 ++++ Mathlib/AlgebraicGeometry/ResidueField.lean | 15 ++ Mathlib/AlgebraicGeometry/Scheme.lean | 8 ++ Mathlib/Geometry/RingedSpace/Basic.lean | 15 ++ .../LocallyRingedSpace/ResidueField.lean | 6 + Mathlib/RingTheory/Localization/Defs.lean | 18 +++ Mathlib/Topology/Category/TopCat/Basic.lean | 12 ++ Mathlib/Topology/Homeomorph.lean | 10 ++ 13 files changed, 286 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Category/Ring/Basic.lean b/Mathlib/Algebra/Category/Ring/Basic.lean index 718c2490097f56..801518f945a60f 100644 --- a/Mathlib/Algebra/Category/Ring/Basic.lean +++ b/Mathlib/Algebra/Category/Ring/Basic.lean @@ -584,6 +584,16 @@ theorem commRingIsoToRingEquiv_symm_toRingHom {X Y : CommRingCat} (i : X ≅ Y) ext rfl +@[simp] +lemma commRingIsoToRingEquiv_apply {X Y : CommRingCat} (i : X ≅ Y) (x : X) : + i.commRingCatIsoToRingEquiv x = i.hom x := + rfl + +@[simp] +lemma commRingIsoToRingEquiv_symm_apply {X Y : CommRingCat} (i : X ≅ Y) (y : Y) : + i.commRingCatIsoToRingEquiv.symm y = i.inv y := + rfl + end CategoryTheory.Iso /-- Ring equivalences between `RingCat`s are the same as (isomorphic to) isomorphisms in diff --git a/Mathlib/Algebra/GroupWithZero/Basic.lean b/Mathlib/Algebra/GroupWithZero/Basic.lean index da8ba43a46d397..64fdcf4a2b3375 100644 --- a/Mathlib/Algebra/GroupWithZero/Basic.lean +++ b/Mathlib/Algebra/GroupWithZero/Basic.lean @@ -156,6 +156,11 @@ lemma ne_zero_pow (hn : n ≠ 0) (ha : a ^ n ≠ 0) : a ≠ 0 := by rintro rfl; lemma zero_pow_eq_zero [Nontrivial M₀] : (0 : M₀) ^ n = 0 ↔ n ≠ 0 := ⟨by rintro h rfl; simp at h, zero_pow⟩ +lemma pow_mul_eq_zero_of_le {a b : M₀} {m n : ℕ} (hmn : m ≤ n) + (h : a ^ m * b = 0) : a ^ n * b = 0 := by + rw [show n = n - m + m by omega, pow_add, mul_assoc, h] + simp + variable [NoZeroDivisors M₀] lemma pow_eq_zero : ∀ {n}, a ^ n = 0 → a = 0 diff --git a/Mathlib/AlgebraicGeometry/AffineScheme.lean b/Mathlib/AlgebraicGeometry/AffineScheme.lean index 731a32691323c1..0859e4051faef8 100644 --- a/Mathlib/AlgebraicGeometry/AffineScheme.lean +++ b/Mathlib/AlgebraicGeometry/AffineScheme.lean @@ -651,6 +651,15 @@ theorem isLocalization_stalk (x : U) : subst this exact hU.isLocalization_stalk' y hx +lemma stalkMap_injective (f : X ⟶ Y) {U : Opens Y} (hU : IsAffineOpen U) (x : X) + (hx : f.base x ∈ U) + (h : ∀ g, f.stalkMap x (Y.presheaf.germ U (f.base x) hx g) = 0 → + Y.presheaf.germ U (f.base x) hx g = 0) : + Function.Injective (f.stalkMap x) := by + letI := Y.presheaf.algebra_section_stalk ⟨f.base x, hx⟩ + apply (hU.isLocalization_stalk ⟨f.base x, hx⟩).injective_of_map_algebraMap_zero + exact h + /-- The basic open set of a section `f` on an affine open as an `X.affineOpens`. -/ @[simps] def _root_.AlgebraicGeometry.Scheme.affineBasicOpen @@ -701,6 +710,12 @@ theorem self_le_basicOpen_union_iff (s : Set Γ(X, U)) : end IsAffineOpen +lemma stalkMap_injective_of_isAffine {X Y : Scheme} (f : X ⟶ Y) [IsAffine Y] (x : X) + (h : ∀ g, f.stalkMap x (Y.presheaf.Γgerm (f.base x) g) = 0 → + Y.presheaf.Γgerm (f.base x) g = 0) : + Function.Injective (f.stalkMap x) := + (isAffineOpen_top Y).stalkMap_injective f x trivial h + /-- 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. diff --git a/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean b/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean index 592f5829e66faa..c78e3b86d608da 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean @@ -3,8 +3,11 @@ Copyright (c) 2023 Jonas van der Schaaf. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Amelia Livingston, Christian Merten, Jonas van der Schaaf -/ -import Mathlib.AlgebraicGeometry.Morphisms.QuasiCompact import Mathlib.AlgebraicGeometry.Morphisms.Preimmersion +import Mathlib.AlgebraicGeometry.Morphisms.QuasiSeparated +import Mathlib.AlgebraicGeometry.Morphisms.RingHomProperties +import Mathlib.AlgebraicGeometry.ResidueField +import Mathlib.RingTheory.RingHom.Surjective /-! @@ -19,8 +22,6 @@ is a closed immersion and the induced morphisms of stalks are all surjective. ## TODO -* Show closed immersions of affines are induced by surjective ring maps -* Show closed immersions are stable under pullback * Show closed immersions are precisely the proper monomorphisms * Define closed immersions of locally ringed spaces, where we also assume that the kernel of `O_X → f_*O_Y` is locally generated by sections as an `O_X`-module, and relate it to this file. See @@ -30,7 +31,7 @@ is a closed immersion and the induced morphisms of stalks are all surjective. universe v u -open CategoryTheory +open CategoryTheory TopologicalSpace Opposite namespace AlgebraicGeometry @@ -137,8 +138,135 @@ instance {X Y : Scheme} (f : X ⟶ Y) [IsClosedImmersion f] : QuasiCompact f whe end IsClosedImmersion +section Affine + +variable {X Y : Scheme.{u}} [IsAffine Y] {f : X ⟶ Y} + +open IsClosedImmersion LocallyRingedSpace + +/-- If `f : X ⟶ Y` is a morphism of schemes with quasi-compact source and affine target, `f` +has a closed image and `f` induces an injection on global sections, then +`f` is surjective. -/ +lemma surjective_of_isClosed_range_of_injective [CompactSpace X] + (hfcl : IsClosed (Set.range f.base)) (hfinj : Function.Injective (f.app ⊤)) : + Function.Surjective f.base := by + obtain ⟨I, hI⟩ := (Scheme.eq_zeroLocus_of_isClosed_of_isAffine Y (Set.range f.base)).mp hfcl + let 𝒰 : X.OpenCover := X.affineCover.finiteSubcover + haveI (i : 𝒰.J) : IsAffine (𝒰.obj i) := Scheme.isAffine_affineCover X _ + apply Set.range_iff_surjective.mp + apply hI ▸ (Scheme.zeroLocus_eq_top_iff_subset_nilradical _).mpr + intro s hs + simp only [AddSubsemigroup.mem_carrier, AddSubmonoid.mem_toSubsemigroup, + Submodule.mem_toAddSubmonoid, SetLike.mem_coe, mem_nilradical, ← IsNilpotent.map_iff hfinj] + refine Scheme.isNilpotent_of_isNilpotent_cover _ 𝒰 (fun i ↦ ?_) + rw [Scheme.isNilpotent_iff_basicOpen_eq_bot] + rw [Scheme.basicOpen_eq_bot_iff_forall_evaluation_eq_zero] + intro x + suffices h : f.base ((𝒰.map i).base x.val) ∉ Y.basicOpen s by + erw [← Scheme.Γevaluation_naturality_apply (𝒰.map i ≫ f)] + simpa only [Scheme.comp_base, TopCat.coe_comp, Function.comp_apply, + Scheme.residueFieldMap_comp, CommRingCat.comp_apply, map_eq_zero, + Scheme.evaluation_eq_zero_iff_not_mem_basicOpen] + exact (Y.mem_zeroLocus_iff I _).mp (hI ▸ Set.mem_range_self ((𝒰.map i).base x.val)) s hs + +/-- 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] + (hfopen : IsOpenMap f.base) (hfinj₁ : Function.Injective f.base) + (hfinj₂ : Function.Injective (f.app ⊤)) (x : X) : + Function.Injective (f.stalkMap x) := by + let φ : Γ(Y, ⊤) ⟶ Γ(X, ⊤) := f.app ⊤ + let 𝒰 : X.OpenCover := X.affineCover.finiteSubcover + have (i : 𝒰.J) : IsAffine (𝒰.obj i) := Scheme.isAffine_affineCover X _ + let res (i : 𝒰.J) : Γ(X, ⊤) ⟶ Γ(𝒰.obj i, ⊤) := (𝒰.map i).app ⊤ + refine stalkMap_injective_of_isAffine _ _ (fun (g : Γ(Y, ⊤)) h ↦ ?_) + rw [TopCat.Presheaf.Γgerm, Scheme.stalkMap_germ_apply] at h + obtain ⟨U, w, (hx : x ∈ U), hg⟩ := + X.toRingedSpace.exists_res_eq_zero_of_germ_eq_zero ⊤ (φ g) ⟨x, trivial⟩ h + obtain ⟨_, ⟨s, rfl⟩, hyv, bsle⟩ := Opens.isBasis_iff_nbhd.mp (isBasis_basicOpen Y) + (show f.base x ∈ ⟨f.base '' U.carrier, hfopen U.carrier U.is_open'⟩ from ⟨x, by simpa⟩) + let W (i : 𝒰.J) : TopologicalSpace.Opens (𝒰.obj i) := (𝒰.obj i).basicOpen ((res i) (φ s)) + have hwle (i : 𝒰.J) : W i ≤ (𝒰.map i)⁻¹ᵁ U := by + show ((𝒰.obj i).basicOpen ((𝒰.map i ≫ f).app ⊤ s)) ≤ _ + rw [← Scheme.preimage_basicOpen, Scheme.comp_coeBase, Opens.map_comp_obj] + refine Scheme.Hom.preimage_le_preimage_of_le _ + (le_trans (f.preimage_le_preimage_of_le bsle) (le_of_eq ?_)) + simp [Set.preimage_image_eq _ hfinj₁] + have h0 (i : 𝒰.J) : (𝒰.map i).appLE _ (W i) (by simp) (φ g) = 0 := by + rw [← Scheme.Hom.appLE_map _ _ (homOfLE <| hwle i).op, ← Scheme.Hom.map_appLE _ le_rfl w.op] + simp only [CommRingCat.coe_comp_of, RingHom.coe_comp, Function.comp_apply] + erw [hg] + simp only [map_zero] + have h1 (i : 𝒰.J) : ∃ n, (res i) (φ (s ^ n * g)) = 0 := by + obtain ⟨n, hn⟩ := exists_of_res_zero_of_qcqs_of_top (s := ((res i) (φ s))) (h0 i) + exact ⟨n, by rwa [map_mul, map_mul, map_pow, map_pow]⟩ + have h2 : ∃ n, ∀ i, (res i) (φ (s ^ n * g)) = 0 := by + choose fn hfn using h1 + refine ⟨Finset.sup Finset.univ fn, fun i ↦ ?_⟩ + rw [map_mul, map_pow, map_mul, map_pow] + simp only [map_mul, map_pow, map_mul, map_pow] at hfn + apply pow_mul_eq_zero_of_le (Finset.le_sup (Finset.mem_univ i)) (hfn i) + obtain ⟨n, hn⟩ := h2 + apply germ_eq_zero_of_pow_mul_eq_zero (U := ⊤) ⟨f.base x, trivial⟩ hyv + rw [RingHom.injective_iff_ker_eq_bot, RingHom.ker_eq_bot_iff_eq_zero] at hfinj₂ + exact hfinj₂ _ (Scheme.zero_of_zero_cover _ _ hn) + +namespace IsClosedImmersion + +/-- 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] + (hf : Function.Injective (f.app ⊤)) : IsIso f := (isIso_iff_stalk_iso f).mpr <| + have : CompactSpace X := (closedEmbedding f).compactSpace + have hiso : IsIso f.base := TopCat.isIso_of_bijective_of_isClosedMap _ + ⟨(closedEmbedding f).inj, + surjective_of_isClosed_range_of_injective ((closedEmbedding f).isClosed_range) hf⟩ + ((closedEmbedding f).isClosedMap) + ⟨hiso, fun x ↦ (ConcreteCategory.isIso_iff_bijective _).mpr + ⟨stalkMap_injective_of_isOpenMap_of_injective ((TopCat.homeoOfIso (asIso f.base)).isOpenMap) + (closedEmbedding f).inj hf _, f.stalkMap_surjective x⟩⟩ + +variable (f) + +/-- If `f` is a closed immersion with affine target, the source is affine and +the induced map on global sections is surjective. -/ +theorem isAffine_surjective_of_isAffine [IsClosedImmersion f] : + IsAffine X ∧ Function.Surjective (f.app ⊤) := by + haveI i : IsClosedImmersion f := inferInstance + rw [← affineTargetImageFactorization_comp f] at i ⊢ + haveI := of_surjective_of_isAffine (affineTargetImageInclusion f) + (affineTargetImageInclusion_app_surjective f) + haveI := IsClosedImmersion.of_comp (affineTargetImageFactorization f) + (affineTargetImageInclusion f) + haveI := isIso_of_injective_of_isAffine (affineTargetImageFactorization_app_injective f) + exact ⟨isAffine_of_isIso (affineTargetImageFactorization f), + (ConcreteCategory.bijective_of_isIso + ((affineTargetImageFactorization f).app ⊤)).surjective.comp <| + affineTargetImageInclusion_app_surjective f⟩ + +end IsClosedImmersion + +end Affine + /-- Being a closed immersion is local at the target. -/ instance IsClosedImmersion.isLocalAtTarget : IsLocalAtTarget @IsClosedImmersion := eq_inf ▸ inferInstance +/-- 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 + (fun X Y f ↦ IsAffine X ∧ Function.Surjective (f.app ⊤)) := by + convert HasAffineProperty.of_isLocalAtTarget @IsClosedImmersion + refine ⟨fun ⟨h₁, h₂⟩ ↦ of_surjective_of_isAffine _ h₂, by apply isAffine_surjective_of_isAffine⟩ + +/-- Being a closed immersion is stable under base change. -/ +lemma IsClosedImmersion.stableUnderBaseChange : + MorphismProperty.StableUnderBaseChange @IsClosedImmersion := by + apply HasAffineProperty.stableUnderBaseChange + haveI := HasAffineProperty.isLocal_affineProperty @IsClosedImmersion + apply AffineTargetMorphismProperty.StableUnderBaseChange.mk + intro X Y S _ _ f g ⟨ha, hsurj⟩ + exact ⟨inferInstance, RingHom.surjective_stableUnderBaseChange.pullback_fst_app_top _ + RingHom.surjective_respectsIso f _ hsurj⟩ + end AlgebraicGeometry diff --git a/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean b/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean index 2e50b205e0b3e6..13bfe53b9c827a 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean @@ -272,6 +272,13 @@ lemma Scheme.isNilpotent_iff_basicOpen_eq_bot_of_isCompact {X : Scheme.{u}} rw [mul_one] at hn use n +/-- A global section of a quasi-compact scheme is nilpotent if and only if its associated +basic open is empty. -/ +lemma Scheme.isNilpotent_iff_basicOpen_eq_bot {X : Scheme.{u}} + [CompactSpace X] (f : Γ(X, ⊤)) : + IsNilpotent f ↔ X.basicOpen f = ⊥ := + isNilpotent_iff_basicOpen_eq_bot_of_isCompact (U := ⊤) (CompactSpace.isCompact_univ) f + /-- The zero locus of a set of sections over a compact open of a scheme is `X` if and only if `s` is contained in the nilradical of `Γ(X, U)`. -/ lemma Scheme.zeroLocus_eq_top_iff_subset_nilradical_of_isCompact {X : Scheme.{u}} {U : X.Opens} @@ -280,4 +287,11 @@ lemma Scheme.zeroLocus_eq_top_iff_subset_nilradical_of_isCompact {X : Scheme.{u} simp [Scheme.zeroLocus_def, ← Scheme.isNilpotent_iff_basicOpen_eq_bot_of_isCompact hU, ← mem_nilradical, Set.subset_def] +/-- The zero locus of a set of sections over a compact open of a scheme is `X` if and only if +`s` is contained in the nilradical of `Γ(X, U)`. -/ +lemma Scheme.zeroLocus_eq_top_iff_subset_nilradical {X : Scheme.{u}} + [CompactSpace X] (s : Set Γ(X, ⊤)) : + X.zeroLocus s = ⊤ ↔ s ⊆ nilradical Γ(X, ⊤) := + zeroLocus_eq_top_iff_subset_nilradical_of_isCompact (U := ⊤) (CompactSpace.isCompact_univ) s + end AlgebraicGeometry diff --git a/Mathlib/AlgebraicGeometry/Morphisms/QuasiSeparated.lean b/Mathlib/AlgebraicGeometry/Morphisms/QuasiSeparated.lean index be7e03dfc20b17..fffb3c4c1f9e11 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/QuasiSeparated.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/QuasiSeparated.lean @@ -347,6 +347,32 @@ theorem is_localization_basicOpen_of_qcqs {X : Scheme} {U : X.Opens} (hU : IsCom refine ⟨⟨_, n, rfl⟩, ?_⟩ simpa [mul_comm z] using e +lemma exists_of_res_eq_of_qcqs {X : Scheme.{u}} {U : TopologicalSpace.Opens X} + (hU : IsCompact U.carrier) (hU' : IsQuasiSeparated U.carrier) + {f g s : Γ(X, U)} (hfg : f |_ X.basicOpen s = g |_ X.basicOpen s) : + ∃ n, s ^ n * f = s ^ n * g := by + obtain ⟨n, hc⟩ := (is_localization_basicOpen_of_qcqs hU hU' s).exists_of_eq s hfg + use n + +lemma exists_of_res_eq_of_qcqs_of_top {X : Scheme.{u}} [CompactSpace X] [QuasiSeparatedSpace X] + {f g s : Γ(X, ⊤)} (hfg : f |_ X.basicOpen s = g |_ X.basicOpen s) : + ∃ n, s ^ n * f = s ^ n * g := + exists_of_res_eq_of_qcqs (U := ⊤) CompactSpace.isCompact_univ isQuasiSeparated_univ hfg + +lemma exists_of_res_zero_of_qcqs {X : Scheme.{u}} {U : TopologicalSpace.Opens X} + (hU : IsCompact U.carrier) (hU' : IsQuasiSeparated U.carrier) + {f s : Γ(X, U)} (hf : f |_ X.basicOpen s = 0) : + ∃ n, s ^ n * f = 0 := by + suffices h : ∃ n, s ^ n * f = s ^ n * 0 by + simpa using h + apply exists_of_res_eq_of_qcqs hU hU' + simpa + +lemma exists_of_res_zero_of_qcqs_of_top {X : Scheme} [CompactSpace X] [QuasiSeparatedSpace X] + {f s : Γ(X, ⊤)} (hf : f |_ X.basicOpen s = 0) : + ∃ n, s ^ n * f = 0 := + exists_of_res_zero_of_qcqs (U := ⊤) CompactSpace.isCompact_univ isQuasiSeparated_univ hf + /-- If `U` is qcqs, then `Γ(X, D(f)) ≃ Γ(X, U)_f` for every `f : Γ(X, U)`. This is known as the **Qcqs lemma** in [R. Vakil, *The rising sea*][RisingSea]. -/ theorem isIso_ΓSpec_adjunction_unit_app_basicOpen {X : Scheme} [CompactSpace X] diff --git a/Mathlib/AlgebraicGeometry/ResidueField.lean b/Mathlib/AlgebraicGeometry/ResidueField.lean index dc139a1ac5f989..a429de3ad31746 100644 --- a/Mathlib/AlgebraicGeometry/ResidueField.lean +++ b/Mathlib/AlgebraicGeometry/ResidueField.lean @@ -77,6 +77,10 @@ lemma evaluation_ne_zero_iff_mem_basicOpen (x : X) (hx : x ∈ U) (f : Γ(X, U)) X.evaluation U x hx f ≠ 0 ↔ x ∈ X.basicOpen f := by simp +lemma basicOpen_eq_bot_iff_forall_evaluation_eq_zero (f : X.presheaf.obj (op U)) : + X.basicOpen f = ⊥ ↔ ∀ (x : U), X.evaluation U x x.property f = 0 := + X.toLocallyRingedSpace.basicOpen_eq_bot_iff_forall_evaluation_eq_zero f + variable {X Y : Scheme.{u}} (f : X ⟶ Y) @@ -121,6 +125,17 @@ lemma evaluation_naturality_apply {V : Opens Y} (x : X) (hx : f.base x ∈ V) (s X.evaluation (f ⁻¹ᵁ V) x hx (f.app V s) := LocallyRingedSpace.evaluation_naturality_apply f.1 ⟨x, hx⟩ s +@[reassoc] +lemma Γevaluation_naturality (x : X) : + Y.Γevaluation (f.base x) ≫ f.residueFieldMap x = + f.c.app (op ⊤) ≫ X.Γevaluation x := + LocallyRingedSpace.Γevaluation_naturality f.toLRSHom x + +lemma Γevaluation_naturality_apply (x : X) (a : Y.presheaf.obj (op ⊤)) : + f.residueFieldMap x (Y.Γevaluation (f.base x) a) = + X.Γevaluation x (f.c.app (op ⊤) a) := + LocallyRingedSpace.Γevaluation_naturality_apply f.toLRSHom x a + instance [IsOpenImmersion f] (x) : IsIso (f.residueFieldMap x) := (LocalRing.ResidueField.mapEquiv (asIso (f.stalkMap x)).commRingCatIsoToRingEquiv).toCommRingCatIso.isIso_hom diff --git a/Mathlib/AlgebraicGeometry/Scheme.lean b/Mathlib/AlgebraicGeometry/Scheme.lean index 546fea88d15d5b..b958a149bf9ecc 100644 --- a/Mathlib/AlgebraicGeometry/Scheme.lean +++ b/Mathlib/AlgebraicGeometry/Scheme.lean @@ -604,6 +604,14 @@ theorem Scheme.Spec_map_presheaf_map_eqToHom {X : Scheme} {U V : X.Opens} (h : U refine (Scheme.congr_app this _).trans ?_ simp [eqToHom_map] +lemma germ_eq_zero_of_pow_mul_eq_zero {X : Scheme.{u}} {U : Opens X} (x : U) {f s : Γ(X, U)} + (hx : x.val ∈ X.basicOpen s) {n : ℕ} (hf : s ^ n * f = 0) : X.presheaf.germ U x x.2 f = 0 := by + rw [Scheme.mem_basicOpen] at hx + have hu : IsUnit (X.presheaf.germ _ x x.2 (s ^ n)) := by + rw [map_pow] + exact IsUnit.pow n hx + rw [← hu.mul_right_eq_zero, ← map_mul, hf, map_zero] + @[reassoc (attr := simp)] lemma Scheme.iso_hom_base_inv_base {X Y : Scheme.{u}} (e : X ≅ Y) : e.hom.base ≫ e.inv.base = 𝟙 _ := diff --git a/Mathlib/Geometry/RingedSpace/Basic.lean b/Mathlib/Geometry/RingedSpace/Basic.lean index a1960cb7b79700..4a89dde97d9c9b 100644 --- a/Mathlib/Geometry/RingedSpace/Basic.lean +++ b/Mathlib/Geometry/RingedSpace/Basic.lean @@ -41,12 +41,27 @@ namespace RingedSpace open SheafedSpace +@[simp] +lemma res_zero {X : RingedSpace.{u}} {U V : TopologicalSpace.Opens X} + (hUV : U ≤ V) : (0 : X.presheaf.obj (op V)) |_ U = 0 := + map_zero _ + variable (X : RingedSpace) -- Porting note (#10670): this was not necessary in mathlib3 instance : CoeSort RingedSpace Type* where coe X := X.carrier +/-- If the germ of a section `f` is zero in the stalk at `x`, then `f` is zero on some neighbourhood +around `x`. -/ +lemma exists_res_eq_zero_of_germ_eq_zero (U : Opens X) (f : X.presheaf.obj (op U)) (x : U) + (h : X.presheaf.germ U x.val x.property f = 0) : + ∃ (V : Opens X) (i : V ⟶ U) (_ : x.1 ∈ V), X.presheaf.map i.op f = 0 := by + have h1 : X.presheaf.germ U x.val x.property f = X.presheaf.germ U x.val x.property 0 := by simpa + obtain ⟨V, hv, i, _, hv4⟩ := TopCat.Presheaf.germ_eq X.presheaf x.1 x.2 x.2 f 0 h1 + use V, i, hv + simpa using hv4 + /-- 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/ResidueField.lean b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean index b09ad64961538a..89243a71df33e9 100644 --- a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean +++ b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean @@ -68,6 +68,12 @@ lemma evaluation_ne_zero_iff_mem_basicOpen (x : U) (f : X.presheaf.obj (op U)) : X.evaluation x f ≠ 0 ↔ x.val ∈ X.toRingedSpace.basicOpen f := by simp +lemma basicOpen_eq_bot_iff_forall_evaluation_eq_zero (f : X.presheaf.obj (op U)) : + X.toRingedSpace.basicOpen f = ⊥ ↔ ∀ (x : U), X.evaluation x f = 0 := by + simp only [evaluation_eq_zero_iff_not_mem_basicOpen, Subtype.forall] + exact ⟨fun h ↦ h ▸ fun a _ hc ↦ hc, + fun h ↦ eq_bot_iff.mpr <| fun a ha ↦ h a (X.toRingedSpace.basicOpen_le f ha) ha⟩ + @[simp] lemma Γevaluation_eq_zero_iff_not_mem_basicOpen (x : X) (f : X.presheaf.obj (op ⊤)) : X.Γevaluation x f = 0 ↔ x ∉ X.toRingedSpace.basicOpen f := diff --git a/Mathlib/RingTheory/Localization/Defs.lean b/Mathlib/RingTheory/Localization/Defs.lean index 4206bfa0fece7f..4a4ae21fb03035 100644 --- a/Mathlib/RingTheory/Localization/Defs.lean +++ b/Mathlib/RingTheory/Localization/Defs.lean @@ -528,6 +528,14 @@ theorem lift_injective_iff : Injective (lift hg : S → P) ↔ ∀ x y, algebraMap R S x = algebraMap R S y ↔ g x = g y := (toLocalizationMap M S).lift_injective_iff hg +variable (M) in +include M in +lemma injective_iff_map_algebraMap_eq {T} [CommRing T] (f : S →+* T) : + Function.Injective f ↔ ∀ x y, + algebraMap R S x = algebraMap R S y ↔ f (algebraMap R S x) = f (algebraMap R S y) := by + rw [← IsLocalization.lift_of_comp (M := M) f, IsLocalization.lift_injective_iff] + simp + section Map variable {T : Submonoid P} {Q : Type*} [CommSemiring Q] @@ -828,6 +836,16 @@ namespace IsLocalization variable {K : Type*} [IsLocalization M S] +include M in +lemma injective_of_map_algebraMap_zero {T} [CommRing T] (f : S →+* T) + (h : ∀ x, f (algebraMap R S x) = 0 → algebraMap R S x = 0) : + Function.Injective f := by + rw [IsLocalization.injective_iff_map_algebraMap_eq M] + refine fun x y ↦ ⟨fun hz ↦ hz ▸ rfl, fun hz ↦ ?_⟩ + rw [← sub_eq_zero, ← map_sub, ← map_sub] at hz + apply h at hz + rwa [map_sub, sub_eq_zero] at hz + theorem to_map_eq_zero_iff {x : R} (hM : M ≤ nonZeroDivisors R) : algebraMap R S x = 0 ↔ x = 0 := by rw [← (algebraMap R S).map_zero] constructor <;> intro h diff --git a/Mathlib/Topology/Category/TopCat/Basic.lean b/Mathlib/Topology/Category/TopCat/Basic.lean index ab44aa713d2eb0..468168d5c7fb56 100644 --- a/Mathlib/Topology/Category/TopCat/Basic.lean +++ b/Mathlib/Topology/Category/TopCat/Basic.lean @@ -161,6 +161,18 @@ theorem of_homeoOfIso {X Y : TopCat.{u}} (f : X ≅ Y) : isoOfHomeo (homeoOfIso ext rfl +lemma isIso_of_bijective_of_isOpenMap {X Y : TopCat.{u}} (f : X ⟶ Y) + (hfbij : Function.Bijective f) (hfcl : IsOpenMap f) : IsIso f := + let e : X ≃ₜ Y := Homeomorph.homeomorphOfContinuousOpen + (Equiv.ofBijective f hfbij) f.continuous hfcl + inferInstanceAs <| IsIso (TopCat.isoOfHomeo e).hom + +lemma isIso_of_bijective_of_isClosedMap {X Y : TopCat.{u}} (f : X ⟶ Y) + (hfbij : Function.Bijective f) (hfcl : IsClosedMap f) : IsIso f := + let e : X ≃ₜ Y := Homeomorph.homeomorphOfContinuousClosed + (Equiv.ofBijective f hfbij) f.continuous hfcl + inferInstanceAs <| IsIso (TopCat.isoOfHomeo e).hom + -- Porting note: simpNF requested partially simped version below theorem openEmbedding_iff_comp_isIso {X Y Z : TopCat} (f : X ⟶ Y) (g : Y ⟶ Z) [IsIso g] : OpenEmbedding (f ≫ g) ↔ OpenEmbedding f := diff --git a/Mathlib/Topology/Homeomorph.lean b/Mathlib/Topology/Homeomorph.lean index 9daf8a9d2be4cc..09be530f7a37a9 100644 --- a/Mathlib/Topology/Homeomorph.lean +++ b/Mathlib/Topology/Homeomorph.lean @@ -417,6 +417,16 @@ def homeomorphOfContinuousOpen (e : X ≃ Y) (h₁ : Continuous e) (h₂ : IsOpe apply e.image_eq_preimage toEquiv := e +/-- If a bijective map `e : X ≃ Y` is continuous and closed, then it is a homeomorphism. -/ +def homeomorphOfContinuousClosed (e : X ≃ Y) (h₁ : Continuous e) (h₂ : IsClosedMap e) : X ≃ₜ Y where + continuous_toFun := h₁ + continuous_invFun := by + rw [continuous_iff_isClosed] + intro s hs + convert ← h₂ s hs using 1 + apply e.image_eq_preimage + toEquiv := e + @[simp] theorem homeomorphOfContinuousOpen_apply (e : X ≃ Y) (h₁ : Continuous e) (h₂ : IsOpenMap e) : ⇑(homeomorphOfContinuousOpen e h₁ h₂) = e := rfl From 035f251efa085d58f145e0d72477526d100c271e Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Thu, 17 Oct 2024 09:39:30 +0000 Subject: [PATCH 289/425] chore: clean up "was rw" porting notes (#17822) If they can be fixed, do so. If they are about changing `rw` to `erw`, refer to #11224 instead. Otherwise, only keep the note if the new proof is actually less idiomatic. None of the original "was rw" notes remain, so: Closes: #10691 --- Mathlib/Algebra/MonoidAlgebra/Defs.lean | 2 -- Mathlib/Algebra/Order/ToIntervalMod.lean | 2 +- Mathlib/Algebra/Polynomial/Laurent.lean | 2 +- Mathlib/AlgebraicGeometry/OpenImmersion.lean | 4 ++-- Mathlib/Data/DFinsupp/Interval.lean | 1 - Mathlib/LinearAlgebra/Alternating/DomCoprod.lean | 2 +- Mathlib/LinearAlgebra/CliffordAlgebra/EvenEquiv.lean | 2 +- Mathlib/Probability/Kernel/MeasurableIntegral.lean | 2 +- Mathlib/RingTheory/Localization/Ideal.lean | 4 +--- 9 files changed, 8 insertions(+), 13 deletions(-) diff --git a/Mathlib/Algebra/MonoidAlgebra/Defs.lean b/Mathlib/Algebra/MonoidAlgebra/Defs.lean index 5f5174af5e9458..7125b7d636d97c 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Defs.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Defs.lean @@ -633,7 +633,6 @@ def singleOneRingHom [Semiring k] [MulOneClass G] : k →+* MonoidAlgebra k G := { Finsupp.singleAddHom 1 with map_one' := rfl map_mul' := fun x y => by - -- Porting note (#10691): Was `rw`. simp only [ZeroHom.toFun_eq_coe, AddMonoidHom.toZeroHom_coe, singleAddHom_apply, single_mul_single, mul_one] } @@ -1367,7 +1366,6 @@ section Algebra def singleZeroRingHom [Semiring k] [AddMonoid G] : k →+* k[G] := { Finsupp.singleAddHom 0 with map_one' := rfl - -- Porting note (#10691): Was `rw`. map_mul' := fun x y => by simp only [singleAddHom, single_mul_single, zero_add] } /-- If two ring homomorphisms from `k[G]` are equal on all `single a 1` diff --git a/Mathlib/Algebra/Order/ToIntervalMod.lean b/Mathlib/Algebra/Order/ToIntervalMod.lean index 260764b5fe69c8..0080b14e43fd5e 100644 --- a/Mathlib/Algebra/Order/ToIntervalMod.lean +++ b/Mathlib/Algebra/Order/ToIntervalMod.lean @@ -760,7 +760,7 @@ private theorem toIxxMod_total' (a b c : α) : Thus if a ≠ b and b ≠ c then ({a-b} + {b-c}) + ({c-b} + {b-a}) = 2 * period, so one of `{a-b} + {b-c}` and `{c-b} + {b-a}` must be `≤ period` -/ have := congr_arg₂ (· + ·) (toIcoMod_add_toIocMod_zero hp a b) (toIcoMod_add_toIocMod_zero hp c b) - simp only [add_add_add_comm] at this -- Porting note (#10691): Was `rw` + simp only [add_add_add_comm] at this rw [_root_.add_comm (toIocMod _ _ _), add_add_add_comm, ← two_nsmul] at this replace := min_le_of_add_le_two_nsmul this.le rw [min_le_iff] at this diff --git a/Mathlib/Algebra/Polynomial/Laurent.lean b/Mathlib/Algebra/Polynomial/Laurent.lean index c139a6417371f7..949d81ecba0315 100644 --- a/Mathlib/Algebra/Polynomial/Laurent.lean +++ b/Mathlib/Algebra/Polynomial/Laurent.lean @@ -297,7 +297,7 @@ def trunc : R[T;T⁻¹] →+ R[X] := 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 rw [← single_eq_C_mul_T, trunc, AddMonoidHom.coe_comp, Function.comp_apply] - -- Porting note (#10691): was `rw` + -- Porting note (#11224): was `rw` erw [comapDomain.addMonoidHom_apply Int.ofNat_injective] rw [toFinsuppIso_apply] -- Porting note: rewrote proof below relative to mathlib3. diff --git a/Mathlib/AlgebraicGeometry/OpenImmersion.lean b/Mathlib/AlgebraicGeometry/OpenImmersion.lean index 75394dff9384f0..7b3769c5084045 100644 --- a/Mathlib/AlgebraicGeometry/OpenImmersion.lean +++ b/Mathlib/AlgebraicGeometry/OpenImmersion.lean @@ -488,7 +488,7 @@ theorem range_pullback_snd_of_left : rw [← show _ = (pullback.snd f g).base from PreservesPullback.iso_hom_snd Scheme.forgetToTop f g, TopCat.coe_comp, Set.range_comp, Set.range_iff_surjective.mpr, ← @Set.preimage_univ _ _ (pullback.fst f.base g.base)] - -- Porting note (#10691): was `rw` + -- Porting note (#11224): was `rw` · erw [TopCat.pullback_snd_image_fst_preimage] rw [Set.image_univ] rfl @@ -505,7 +505,7 @@ theorem range_pullback_fst_of_right : rw [← show _ = (pullback.fst g f).base from PreservesPullback.iso_hom_fst Scheme.forgetToTop g f, TopCat.coe_comp, Set.range_comp, Set.range_iff_surjective.mpr, ← @Set.preimage_univ _ _ (pullback.snd g.base f.base)] - -- Porting note (#10691): was `rw` + -- Porting note (#11224): was `rw` · erw [TopCat.pullback_fst_image_snd_preimage] rw [Set.image_univ] rfl diff --git a/Mathlib/Data/DFinsupp/Interval.lean b/Mathlib/Data/DFinsupp/Interval.lean index 8588c90c875255..73f9fad8750ec2 100644 --- a/Mathlib/Data/DFinsupp/Interval.lean +++ b/Mathlib/Data/DFinsupp/Interval.lean @@ -102,7 +102,6 @@ def rangeIcc (f g : Π₀ i, α i) : Π₀ i, Finset (α i) where (Multiset.not_mem_mono (Multiset.Le.subset <| Multiset.le_add_right _ _) h) have hg : g i = 0 := (gs.prop i).resolve_left (Multiset.not_mem_mono (Multiset.Le.subset <| Multiset.le_add_left _ _) h) - -- Porting note: was rw, but was rewriting under lambda, so changed to simp_rw simp_rw [hf, hg] exact Icc_self _⟩ diff --git a/Mathlib/LinearAlgebra/Alternating/DomCoprod.lean b/Mathlib/LinearAlgebra/Alternating/DomCoprod.lean index 847afe49e999ee..001f2f17ef8d57 100644 --- a/Mathlib/LinearAlgebra/Alternating/DomCoprod.lean +++ b/Mathlib/LinearAlgebra/Alternating/DomCoprod.lean @@ -57,7 +57,7 @@ def domCoprod.summand (a : Mᵢ [⋀^ιa]→ₗ[R'] N₁) (b : Mᵢ [⋀^ιb]→ TensorProduct.smul_tmul'] simp only [Sum.map_inr, Perm.sumCongrHom_apply, Perm.sumCongr_apply, Sum.map_inl, Function.comp_apply, Perm.coe_mul] - -- Porting note (#10691): was `rw`. + -- Porting note (#11224): was `rw`. erw [← a.map_congr_perm fun i => v (σ₁ _), ← b.map_congr_perm fun i => v (σ₁ _)] theorem domCoprod.summand_mk'' (a : Mᵢ [⋀^ιa]→ₗ[R'] N₁) (b : Mᵢ [⋀^ιb]→ₗ[R'] N₂) diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/EvenEquiv.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/EvenEquiv.lean index d699e29ff8b2d2..119f96a21ae0df 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/EvenEquiv.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/EvenEquiv.lean @@ -117,7 +117,7 @@ def toEven : CliffordAlgebra Q →ₐ[R] CliffordAlgebra.even (Q' Q) := by theorem toEven_ι (m : M) : (toEven Q (ι Q m) : CliffordAlgebra (Q' Q)) = e0 Q * v Q m := by rw [toEven, CliffordAlgebra.lift_ι_apply] - -- Porting note (#10691): was `rw` + -- Porting note (#11224): was `rw` erw [LinearMap.codRestrict_apply] rw [LinearMap.coe_comp, Function.comp_apply, LinearMap.mulLeft_apply] diff --git a/Mathlib/Probability/Kernel/MeasurableIntegral.lean b/Mathlib/Probability/Kernel/MeasurableIntegral.lean index dc0acc26cac82a..b35f6f0a1fcab0 100644 --- a/Mathlib/Probability/Kernel/MeasurableIntegral.lean +++ b/Mathlib/Probability/Kernel/MeasurableIntegral.lean @@ -166,7 +166,7 @@ theorem _root_.Measurable.lintegral_kernel_prod_right {f : α → β → ℝ≥0 (fun a => ∫⁻ b, g₁ (a, b) ∂κ a) + fun a => ∫⁻ b, g₂ (a, b) ∂κ a := by ext1 a rw [Pi.add_apply] - -- Porting note (#10691): was `rw` (`Function.comp` reducibility) + -- Porting note (#11224): was `rw` (`Function.comp` reducibility) erw [lintegral_add_left (g₁.measurable.comp measurable_prod_mk_left)] simp_rw [Function.comp_apply] rw [h_add] diff --git a/Mathlib/RingTheory/Localization/Ideal.lean b/Mathlib/RingTheory/Localization/Ideal.lean index 990c36d781bd65..dfcf60e25dc37f 100644 --- a/Mathlib/RingTheory/Localization/Ideal.lean +++ b/Mathlib/RingTheory/Localization/Ideal.lean @@ -201,9 +201,7 @@ theorem surjective_quotientMap_of_maximal_of_localization {I : Ideal S} [I.IsPri (Ideal.Quotient.eq_zero_iff_mem.2 (Ideal.mem_comap.2 (Ideal.Quotient.eq_zero_iff_mem.1 hn)))) (_root_.trans hn ?_)) - -- Porting note (#10691): was `rw`, but this took extremely long. - refine Eq.trans ?_ (RingHom.map_mul (Ideal.Quotient.mk I) (algebraMap R S m) (mk' S 1 ⟨m, hm⟩)) - rw [← mk'_eq_mul_mk'_one, mk'_self, RingHom.map_one] + rw [← map_mul, ← mk'_eq_mul_mk'_one, mk'_self, RingHom.map_one] open nonZeroDivisors From 578f813cc02e2a32b30cd3541cf32aebd7e374b7 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 21:40:02 +1100 Subject: [PATCH 290/425] bump deps --- lake-manifest.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index cec2db26457efb..f9e1e3e5725ba0 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "e33ad27c3f9a358c2dd50f15b80a8a86297b7132", + "rev": "389fb58a2ff92e1ede0db37b1fedcb9a6162df94", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "nightly-testing", @@ -25,7 +25,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "6503af80a441d6d5351e60e6256b45d135d46d50", + "rev": "068d4e4dc7cec9a9a724311db12d0138316c1005", "name": "aesop", "manifestFile": "lake-manifest.json", "inputRev": "nightly-testing", From d0c179f29ce4d67c61cda93d8c7b5e309fe3a4b9 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 21:43:06 +1100 Subject: [PATCH 291/425] bump deps --- Mathlib/CategoryTheory/Pi/Basic.lean | 1 - Mathlib/Combinatorics/Quiver/Symmetric.lean | 1 - Mathlib/Control/Bifunctor.lean | 1 - Mathlib/Data/Sum/Basic.lean | 1 - Mathlib/Data/TwoPointing.lean | 1 - Mathlib/Order/Basic.lean | 1 - lake-manifest.json | 4 ++-- lakefile.lean | 2 +- 8 files changed, 3 insertions(+), 9 deletions(-) diff --git a/Mathlib/CategoryTheory/Pi/Basic.lean b/Mathlib/CategoryTheory/Pi/Basic.lean index 8515247f7d5ba3..ac868245a46ffb 100644 --- a/Mathlib/CategoryTheory/Pi/Basic.lean +++ b/Mathlib/CategoryTheory/Pi/Basic.lean @@ -6,7 +6,6 @@ Authors: Simon Hudon, Kim Morrison import Mathlib.CategoryTheory.EqToHom import Mathlib.CategoryTheory.NatIso import Mathlib.CategoryTheory.Products.Basic -import Batteries.Data.Sum.Basic /-! # Categories of indexed families of objects. diff --git a/Mathlib/Combinatorics/Quiver/Symmetric.lean b/Mathlib/Combinatorics/Quiver/Symmetric.lean index cf87c843a83f79..bb83a91439731d 100644 --- a/Mathlib/Combinatorics/Quiver/Symmetric.lean +++ b/Mathlib/Combinatorics/Quiver/Symmetric.lean @@ -5,7 +5,6 @@ Authors: David Wärn, Antoine Labelle, Rémi Bottinelli -/ import Mathlib.Combinatorics.Quiver.Path import Mathlib.Combinatorics.Quiver.Push -import Batteries.Data.Sum.Lemmas /-! ## Symmetric quivers and arrow reversal diff --git a/Mathlib/Control/Bifunctor.lean b/Mathlib/Control/Bifunctor.lean index b02897a6225a29..842c976d6369b4 100644 --- a/Mathlib/Control/Bifunctor.lean +++ b/Mathlib/Control/Bifunctor.lean @@ -5,7 +5,6 @@ Authors: Simon Hudon -/ import Mathlib.Control.Functor import Mathlib.Tactic.Common -import Batteries.Data.Sum.Basic /-! # Functors with two arguments diff --git a/Mathlib/Data/Sum/Basic.lean b/Mathlib/Data/Sum/Basic.lean index d65e9ce7874fea..9d3a06cb88f2c4 100644 --- a/Mathlib/Data/Sum/Basic.lean +++ b/Mathlib/Data/Sum/Basic.lean @@ -5,7 +5,6 @@ Authors: Mario Carneiro, Yury Kudryashov -/ import Mathlib.Logic.Function.Basic import Mathlib.Tactic.MkIffOfInductiveProp -import Batteries.Data.Sum.Lemmas /-! # Additional lemmas about sum types diff --git a/Mathlib/Data/TwoPointing.lean b/Mathlib/Data/TwoPointing.lean index a4473d81ef91ca..7ae23440345388 100644 --- a/Mathlib/Data/TwoPointing.lean +++ b/Mathlib/Data/TwoPointing.lean @@ -5,7 +5,6 @@ Authors: Yaël Dillies -/ import Mathlib.Logic.Nontrivial.Defs import Mathlib.Logic.Nonempty -import Batteries.Data.Sum.Lemmas /-! # Two-pointings diff --git a/Mathlib/Order/Basic.lean b/Mathlib/Order/Basic.lean index b090a893ae8119..65028f828718d7 100644 --- a/Mathlib/Order/Basic.lean +++ b/Mathlib/Order/Basic.lean @@ -10,7 +10,6 @@ import Mathlib.Order.Notation import Mathlib.Tactic.Spread import Mathlib.Tactic.Convert import Mathlib.Tactic.SimpRw -import Batteries.Data.Sum.Lemmas /-! # Basic definitions about `≤` and `<` diff --git a/lake-manifest.json b/lake-manifest.json index f9e1e3e5725ba0..e6f556ba275c47 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -55,10 +55,10 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "9b4088ccf0f44ddd7b1132bb1348aef8cf481e12", + "rev": "6b657150b3c7294404ba85f0185391a898432a78", "name": "importGraph", "manifestFile": "lake-manifest.json", - "inputRev": "main", + "inputRev": "nightly-testing", "inherited": false, "configFile": "lakefile.toml"}, {"url": "https://github.com/leanprover-community/LeanSearchClient", diff --git a/lakefile.lean b/lakefile.lean index bb806c24f85559..2433983deedc1f 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -11,7 +11,7 @@ require "leanprover-community" / "batteries" @ git "nightly-testing" require "leanprover-community" / "Qq" @ git "master" require "leanprover-community" / "aesop" @ git "nightly-testing" require "leanprover-community" / "proofwidgets" @ git "v0.0.44-pre" -require "leanprover-community" / "importGraph" @ git "main" +require "leanprover-community" / "importGraph" @ git "nightly-testing" require "leanprover-community" / "LeanSearchClient" @ git "main" from git "https://github.com/leanprover-community/LeanSearchClient" @ "main" From bc5296c0fe5ccb43beb14a75c1648498a7ae37ee Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 21:45:05 +1100 Subject: [PATCH 292/425] bump deps --- lake-manifest.json | 4 ++-- lakefile.lean | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lake-manifest.json b/lake-manifest.json index e6f556ba275c47..00bc5669b6d089 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -15,10 +15,10 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "fa3d73a2cf077f4b14c7840352ac7b08aeb6eb41", + "rev": "0495948fee4b49f9e4757134f6c3c13c6a8d9fa4", "name": "Qq", "manifestFile": "lake-manifest.json", - "inputRev": "master", + "inputRev": "nightly-testing", "inherited": false, "configFile": "lakefile.lean"}, {"url": "https://github.com/leanprover-community/aesop", diff --git a/lakefile.lean b/lakefile.lean index 2433983deedc1f..96aabcff80d6d9 100644 --- a/lakefile.lean +++ b/lakefile.lean @@ -8,7 +8,7 @@ open Lake DSL -/ require "leanprover-community" / "batteries" @ git "nightly-testing" -require "leanprover-community" / "Qq" @ git "master" +require "leanprover-community" / "Qq" @ git "nightly-testing" require "leanprover-community" / "aesop" @ git "nightly-testing" require "leanprover-community" / "proofwidgets" @ git "v0.0.44-pre" require "leanprover-community" / "importGraph" @ git "nightly-testing" From d09d638f1fb28d9fe3c3e6772c02dc2db6683fb6 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 21:49:49 +1100 Subject: [PATCH 293/425] remove upstreamed material on Prod --- Mathlib/Data/Prod/Basic.lean | 50 ------------------------------------ 1 file changed, 50 deletions(-) diff --git a/Mathlib/Data/Prod/Basic.lean b/Mathlib/Data/Prod/Basic.lean index 2fbd64bdcf1818..f42386ead90429 100644 --- a/Mathlib/Data/Prod/Basic.lean +++ b/Mathlib/Data/Prod/Basic.lean @@ -57,20 +57,6 @@ theorem map_fst' (f : α → γ) (g : β → δ) : Prod.fst ∘ map f g = f ∘ theorem map_snd' (f : α → γ) (g : β → δ) : Prod.snd ∘ map f g = g ∘ Prod.snd := funext <| map_snd f g -/-- Composing a `Prod.map` with another `Prod.map` is equal to -a single `Prod.map` of composed functions. --/ -theorem map_comp_map {ε ζ : Type*} (f : α → β) (f' : γ → δ) (g : β → ε) (g' : δ → ζ) : - Prod.map g g' ∘ Prod.map f f' = Prod.map (g ∘ f) (g' ∘ f') := - rfl - -/-- Composing a `Prod.map` with another `Prod.map` is equal to -a single `Prod.map` of composed functions, fully applied. --/ -theorem map_map {ε ζ : Type*} (f : α → β) (f' : γ → δ) (g : β → ε) (g' : δ → ζ) (x : α × γ) : - Prod.map g g' (Prod.map f f' x) = Prod.map (g ∘ f) (g' ∘ f') x := - rfl - -- Porting note: `@[simp]` tag removed because auto-generated `mk.injEq` simplifies LHS -- @[simp] theorem mk.inj_iff {a₁ a₂ : α} {b₁ b₂ : β} : (a₁, b₁) = (a₂, b₂) ↔ a₁ = a₂ ∧ b₁ = b₂ := @@ -95,10 +81,6 @@ theorem map_def {f : α → γ} {g : β → δ} : Prod.map f g = fun p : α × theorem id_prod : (fun p : α × β ↦ (p.1, p.2)) = id := rfl -@[simp] lemma map_id : Prod.map (@id α) (@id β) = id := rfl - -@[simp] lemma map_id' : Prod.map (fun a : α ↦ a) (fun b : β ↦ b) = fun x ↦ x := rfl - @[simp] theorem map_iterate (f : α → α) (g : β → β) (n : ℕ) : (Prod.map f g)^[n] = Prod.map f^[n] g^[n] := by induction n <;> simp [*, Prod.map_comp_map] @@ -117,29 +99,6 @@ theorem fst_injective [Subsingleton β] : Function.Injective (@fst α β) := theorem snd_injective [Subsingleton α] : Function.Injective (@snd α β) := fun _ _ h ↦ Prod.ext (Subsingleton.elim _ _) h -/-- Swap the factors of a product. `swap (a, b) = (b, a)` -/ -def swap : α × β → β × α := fun p ↦ (p.2, p.1) - -@[simp] -theorem swap_swap : ∀ x : α × β, swap (swap x) = x - | ⟨_, _⟩ => rfl - -@[simp] -theorem fst_swap {p : α × β} : (swap p).1 = p.2 := - rfl - -@[simp] -theorem snd_swap {p : α × β} : (swap p).2 = p.1 := - rfl - -@[simp] -theorem swap_prod_mk {a : α} {b : β} : swap (a, b) = (b, a) := - rfl - -@[simp] -theorem swap_swap_eq : swap ∘ swap = @id (α × β) := - funext swap_swap - @[simp] theorem swap_leftInverse : Function.LeftInverse (@swap α β) swap := swap_swap @@ -157,15 +116,6 @@ theorem swap_surjective : Function.Surjective (@swap α β) := theorem swap_bijective : Function.Bijective (@swap α β) := ⟨swap_injective, swap_surjective⟩ -@[simp] -theorem swap_inj {p q : α × β} : swap p = swap q ↔ p = q := - swap_injective.eq_iff - -/--For two functions `f` and `g`, the composition of `Prod.map f g` with `Prod.swap` -is equal to the composition of `Prod.swap` with `Prod.map g f`.-/ -theorem map_comp_swap (f : α → β) (g : γ → δ) : - Prod.map f g ∘ Prod.swap = Prod.swap ∘ Prod.map g f := rfl - theorem _root_.Function.Semiconj.swap_map (f : α → α) (g : β → β) : Function.Semiconj swap (map f g) (map g f) := Function.semiconj_iff_comp_eq.2 (map_comp_swap g f).symm From d951eef6bb39b3b78cbd1fba9c515c3770a9d20a Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Thu, 17 Oct 2024 10:54:51 +0000 Subject: [PATCH 294/425] feat(AlgebraicGeometry): stability properties of separated (#17861) Separated is multiplicative, stable under base change and local at the target. --- .../Morphisms/Separated.lean | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean b/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean index 5831774a682e81..369855b7c262d1 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Separated.lean @@ -16,9 +16,6 @@ A morphism of schemes is separated if its diagonal morphism is a closed immmersi ## TODO -- Show separated is stable under composition and base change (this is immediate if - we show that closed immersions are stable under base change). -- Show separated is local at the target. - Show affine morphisms are separated. -/ @@ -60,6 +57,24 @@ instance : MorphismProperty.RespectsIso @IsSeparated := by instance (priority := 900) [IsSeparated f] : QuasiSeparated f where +instance stableUnderComposition : MorphismProperty.IsStableUnderComposition @IsSeparated := by + rw [isSeparated_eq_diagonal_isClosedImmersion] + exact MorphismProperty.diagonal_isStableUnderComposition IsClosedImmersion.stableUnderBaseChange + +instance {Z : Scheme.{u}} (g : Y ⟶ Z) [IsSeparated f] [IsSeparated g] : IsSeparated (f ≫ g) := + stableUnderComposition.comp_mem f g inferInstance inferInstance + +instance : MorphismProperty.IsMultiplicative @IsSeparated where + id_mem _ := inferInstance + +lemma stableUnderBaseChange : MorphismProperty.StableUnderBaseChange @IsSeparated := by + rw [isSeparated_eq_diagonal_isClosedImmersion] + exact MorphismProperty.StableUnderBaseChange.diagonal IsClosedImmersion.stableUnderBaseChange + +instance : IsLocalAtTarget @IsSeparated := by + rw [isSeparated_eq_diagonal_isClosedImmersion] + infer_instance + end IsSeparated end AlgebraicGeometry From a962c606e4ed8ac56b4750f6c02091ab92cb62a8 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 21:56:13 +1100 Subject: [PATCH 295/425] just use aesop --- Mathlib/Data/Set/Pairwise/Basic.lean | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Mathlib/Data/Set/Pairwise/Basic.lean b/Mathlib/Data/Set/Pairwise/Basic.lean index 7365c110ac476b..3b86a57033f963 100644 --- a/Mathlib/Data/Set/Pairwise/Basic.lean +++ b/Mathlib/Data/Set/Pairwise/Basic.lean @@ -129,9 +129,7 @@ theorem pairwise_union : (s ∪ t).Pairwise r ↔ s.Pairwise r ∧ t.Pairwise r ∧ ∀ a ∈ s, ∀ b ∈ t, a ≠ b → r a b ∧ r b a := by simp only [Set.Pairwise, mem_union, or_imp, forall_and] - exact - ⟨fun H => ⟨H.1.1, H.2.2, H.1.2, fun x hx y hy hne => H.2.1 y hy x hx hne.symm⟩, - fun H => ⟨⟨H.1, H.2.2.1⟩, fun x hx y hy hne => H.2.2.2 y hy x hx hne.symm, H.2.1⟩⟩ + aesop theorem pairwise_union_of_symmetric (hr : Symmetric r) : (s ∪ t).Pairwise r ↔ s.Pairwise r ∧ t.Pairwise r ∧ ∀ a ∈ s, ∀ b ∈ t, a ≠ b → r a b := From 4149cd2afc5591e3b2345c1e231d887c6f8e2789 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 21:57:18 +1100 Subject: [PATCH 296/425] fixes --- Mathlib/Algebra/BigOperators/Group/List.lean | 3 +- Mathlib/Data/List/Permutation.lean | 32 ++++++++++---------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Group/List.lean b/Mathlib/Algebra/BigOperators/Group/List.lean index 8dd8ee04cfbaad..848ef0e0181594 100644 --- a/Mathlib/Algebra/BigOperators/Group/List.lean +++ b/Mathlib/Algebra/BigOperators/Group/List.lean @@ -654,14 +654,13 @@ lemma mem_mem_ranges_iff_lt_sum (l : List ℕ) {n : ℕ} : @[simp] theorem length_flatMap (l : List α) (f : α → List β) : length (List.flatMap l f) = sum (map (length ∘ f) l) := by - rw [List.flatMap, length_flatten, map_map, Nat.sum_eq_listSum] + rw [List.flatMap, length_flatten, map_map] @[deprecated (since := "2024-10-16")] alias length_bind := length_flatMap lemma countP_flatMap (p : β → Bool) (l : List α) (f : α → List β) : countP p (l.flatMap f) = sum (map (countP p ∘ f) l) := by rw [List.flatMap, countP_flatten, map_map] - simp @[deprecated (since := "2024-10-16")] alias countP_bind := countP_flatMap diff --git a/Mathlib/Data/List/Permutation.lean b/Mathlib/Data/List/Permutation.lean index 3048e6fbb49d86..24e912e10a51b3 100644 --- a/Mathlib/Data/List/Permutation.lean +++ b/Mathlib/Data/List/Permutation.lean @@ -319,23 +319,23 @@ private theorem DecEq_eq [DecidableEq α] : rw [Bool.eq_iff_iff, @beq_iff_eq _ (_), decide_eq_true_iff] theorem perm_permutations'Aux_comm (a b : α) (l : List α) : - (permutations'Aux a l).bind (permutations'Aux b) ~ - (permutations'Aux b l).bind (permutations'Aux a) := by + (permutations'Aux a l).flatMap (permutations'Aux b) ~ + (permutations'Aux b l).flatMap (permutations'Aux a) := by induction' l with c l ih · exact Perm.swap [a, b] [b, a] [] - simp only [permutations'Aux, bind_cons, map_cons, map_map, cons_append] + simp only [permutations'Aux, flatMap_cons, map_cons, map_map, cons_append] apply Perm.swap' have : ∀ a b, - (map (cons c) (permutations'Aux a l)).bind (permutations'Aux b) ~ + (map (cons c) (permutations'Aux a l)).flatMap (permutations'Aux b) ~ map (cons b ∘ cons c) (permutations'Aux a l) ++ - map (cons c) ((permutations'Aux a l).bind (permutations'Aux b)) := by + map (cons c) ((permutations'Aux a l).flatMap (permutations'Aux b)) := by intros a' b' - simp only [bind_map, permutations'Aux] - show List.bind (permutations'Aux _ l) (fun a => ([b' :: c :: a] ++ + simp only [flatMap_map, permutations'Aux] + show List.flatMap (permutations'Aux _ l) (fun a => ([b' :: c :: a] ++ map (cons c) (permutations'Aux _ a))) ~ _ - refine (bind_append_perm _ (fun x => [b' :: c :: x]) _).symm.trans ?_ - rw [← map_eq_bind, ← map_bind] + refine (flatMap_append_perm _ (fun x => [b' :: c :: x]) _).symm.trans ?_ + rw [← map_eq_flatMap, ← map_flatMap] exact Perm.refl _ refine (((this _ _).append_left _).trans ?_).trans ((this _ _).append_left _).symm rw [← append_assoc, ← append_assoc] @@ -344,11 +344,11 @@ theorem perm_permutations'Aux_comm (a b : α) (l : List α) : theorem Perm.permutations' {s t : List α} (p : s ~ t) : permutations' s ~ permutations' t := by induction p with | nil => simp - | cons _ _ IH => exact IH.bind_right _ + | cons _ _ IH => exact IH.flatMap_right _ | swap => dsimp - rw [bind_assoc, bind_assoc] - apply Perm.bind_left + rw [flatMap_assoc, flatMap_assoc] + apply Perm.flatMap_left intro l' _ apply perm_permutations'Aux_comm | trans _ _ IH₁ IH₂ => exact IH₁.trans IH₂ @@ -362,10 +362,10 @@ theorem permutations_perm_permutations' (ts : List α) : ts.permutations ~ ts.pe simp only [permutations_append, foldr_permutationsAux2, permutationsAux_nil, permutationsAux_cons, append_nil] refine - (perm_append_comm.trans ((IH₂.bind_right _).append ((IH _ h).map _))).trans + (perm_append_comm.trans ((IH₂.flatMap_right _).append ((IH _ h).map _))).trans (Perm.trans ?_ perm_append_comm.permutations') - rw [map_eq_bind, singleton_append, permutations'] - refine (bind_append_perm _ _ _).trans ?_ + rw [map_eq_flatMap, singleton_append, permutations'] + refine (flatMap_append_perm _ _ _).trans ?_ refine Perm.of_eq ?_ congr funext _ @@ -481,7 +481,7 @@ theorem nodup_permutations (s : List α) (hs : Nodup s) : Nodup s.permutations : induction' hs with x l h h' IH · simp · rw [permutations'] - rw [nodup_bind] + rw [nodup_flatMap] constructor · intro ys hy rw [mem_permutations'] at hy From ffdfcb3ea11c9b7a211a9a6acbb34321f59b8977 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Thu, 17 Oct 2024 22:05:14 +1100 Subject: [PATCH 297/425] fix --- Mathlib/AlgebraicTopology/SimplicialSet/Basic.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Basic.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Basic.lean index b11a417a297e74..f62309533efa9b 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Basic.lean @@ -227,10 +227,10 @@ def edge (n : ℕ) (i a b : Fin (n+1)) (hab : a ≤ b) (H : Finset.card {i, a, b refine ⟨standardSimplex.edge n a b hab, ?range⟩ case range => suffices ∃ x, ¬i = x ∧ ¬a = x ∧ ¬b = x by - simpa only [unop_op, SimplexCategory.len_mk, asOrderHom, SimplexCategory.Hom.toOrderHom_mk, - Set.union_singleton, ne_eq, ← Set.univ_subset_iff, Set.subset_def, Set.mem_univ, - Set.mem_insert_iff, @eq_comm _ _ i, Set.mem_range, forall_true_left, not_forall, not_or, - not_exists, Fin.forall_fin_two] + simpa only [unop_op, len_mk, Nat.reduceAdd, asOrderHom, yoneda_obj_obj, Set.union_singleton, + ne_eq, ← Set.univ_subset_iff, Set.subset_def, Set.mem_univ, Set.mem_insert_iff, + @eq_comm _ _ i, Set.mem_range, forall_const, not_forall, not_or, not_exists, + Fin.forall_fin_two, Fin.isValue] contrapose! H replace H : univ ⊆ {i, a, b} := fun x _ ↦ by simpa [or_iff_not_imp_left, eq_comm] using H x From f2b4116dc35684f4e056b4ba51ddc4050bd13b2f Mon Sep 17 00:00:00 2001 From: "Anne C.A. Baanen" Date: Thu, 17 Oct 2024 13:19:39 +0200 Subject: [PATCH 298/425] `simp` wasn't applying `Sigma.forall`, apparently because this local definition wasn't being unfolded. --- Mathlib/Order/KonigLemma.lean | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/Order/KonigLemma.lean b/Mathlib/Order/KonigLemma.lean index b38fa275198d56..cdaf5ce354e33e 100644 --- a/Mathlib/Order/KonigLemma.lean +++ b/Mathlib/Order/KonigLemma.lean @@ -119,7 +119,7 @@ theorem exists_seq_forall_proj_of_forall_finite {α : ℕ → Type*} [Finite (α rw [show a = b by rwa [π_refl] at hba] } have hcovby : ∀ {a b : αs}, a ⋖ b ↔ a ≤ b ∧ a.1 + 1 = b.1 := by - simp only [covBy_iff_lt_and_eq_or_eq, lt_iff_le_and_ne, ne_eq, Sigma.forall, and_assoc, + simp only [αs, covBy_iff_lt_and_eq_or_eq, lt_iff_le_and_ne, ne_eq, Sigma.forall, and_assoc, and_congr_right_iff, or_iff_not_imp_left] rintro i a j b ⟨h : i ≤ j, rfl : π h b = a⟩ refine ⟨fun ⟨hne, h'⟩ ↦ ?_, ?_⟩ @@ -142,12 +142,12 @@ theorem exists_seq_forall_proj_of_forall_finite {α : ℕ → Type*} [Finite (α obtain ⟨a₀, ha₀, ha₀inf⟩ : ∃ a₀ : αs, a₀.1 = 0 ∧ (Ici a₀).Infinite := by obtain ⟨a₀, ha₀⟩ := Finite.exists_infinite_fiber (fun (a : αs) ↦ π (zero_le a.1) a.2) refine ⟨⟨0, a₀⟩, rfl, (infinite_coe_iff.1 ha₀).mono ?_⟩ - simp only [subset_def, mem_preimage, mem_singleton_iff, mem_Ici, Sigma.forall] + simp only [αs, subset_def, mem_preimage, mem_singleton_iff, mem_Ici, Sigma.forall] exact fun i x h ↦ ⟨zero_le i, h⟩ have hfin : ∀ (a : αs), {x | a ⋖ x}.Finite := by refine fun ⟨i,a⟩ ↦ ((hfin i a).image (fun b ↦ ⟨_,b⟩)).subset ?_ - simp only [hcovby, subset_def, mem_setOf_eq, mem_image, and_imp, Sigma.forall] + simp only [αs, hcovby, subset_def, mem_setOf_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 From d51a8c9ac5f7970ce1d50207a52ff800aa95d956 Mon Sep 17 00:00:00 2001 From: Jujian Zhang Date: Thu, 17 Oct 2024 11:30:00 +0000 Subject: [PATCH 299/425] feat(LinearAlgebra/TensorProduct/Quotient): add some isomorphisms (#17803) Moves: - quotTensorEquivQuotSMul -> TensorProduct.quotTensorEquivQuotSMul - tensorQuotEquivQuotSMul -> TensorProduct.tensorQuotEquivQuotSMul --- Mathlib.lean | 1 + .../LinearAlgebra/TensorProduct/Quotient.lean | 241 ++++++++++++++++++ .../TensorProduct/RightExactness.lean | 79 ------ Mathlib/RingTheory/QuotSMulTop.lean | 1 + 4 files changed, 243 insertions(+), 79 deletions(-) create mode 100644 Mathlib/LinearAlgebra/TensorProduct/Quotient.lean diff --git a/Mathlib.lean b/Mathlib.lean index 9005c78e9dcb79..0439d6b8d5e5fb 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3173,6 +3173,7 @@ import Mathlib.LinearAlgebra.TensorProduct.Matrix import Mathlib.LinearAlgebra.TensorProduct.Opposite import Mathlib.LinearAlgebra.TensorProduct.Pi import Mathlib.LinearAlgebra.TensorProduct.Prod +import Mathlib.LinearAlgebra.TensorProduct.Quotient import Mathlib.LinearAlgebra.TensorProduct.RightExactness import Mathlib.LinearAlgebra.TensorProduct.Subalgebra import Mathlib.LinearAlgebra.TensorProduct.Submodule diff --git a/Mathlib/LinearAlgebra/TensorProduct/Quotient.lean b/Mathlib/LinearAlgebra/TensorProduct/Quotient.lean new file mode 100644 index 00000000000000..f3cea863abf537 --- /dev/null +++ b/Mathlib/LinearAlgebra/TensorProduct/Quotient.lean @@ -0,0 +1,241 @@ +/- +Copyright (c) 2024 Antoine Chambert-Loir. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Antoine Chambert-Loir, Jujian Zhang +-/ + +import Mathlib.RingTheory.Ideal.Operations +import Mathlib.LinearAlgebra.TensorProduct.Basic +import Mathlib.LinearAlgebra.Quotient +import Mathlib.LinearAlgebra.Prod +import Mathlib.RingTheory.Ideal.Quotient + +/-! + +# Interaction between Quotients and Tensor Products + +This file contains constructions that relate quotients and tensor products. +Let `M, N` be `R`-modules, `m ≤ M` and `n ≤ N` be an `R`-submodules and `I ≤ R` an ideal. We prove +the following isomorphisms: + +## Main results +- `TensorProduct.quotientTensorQuotientEquiv`: + `(M ⧸ m) ⊗[R] (N ⧸ n) ≃ₗ[R] (M ⊗[R] N) ⧸ (m ⊗ N ⊔ M ⊗ n)` +- `TensorProduct.quotientTensorEquiv`: + `(M ⧸ m) ⊗[R] N ≃ₗ[R] (M ⊗[R] N) ⧸ (m ⊗ N)` +- `TensorProduct.tensorQuotientEquiv`: + `M ⊗[R] (N ⧸ n) ≃ₗ[R] (M ⊗[R] N) ⧸ (M ⊗ n)` +- `TensorProduct.quotTensorEquivQuotSMul`: + `(R ⧸ I) ⊗[R] M ≃ₗ[R] M ⧸ (I • M)` +- `TensorProduct.tensorQuotEquivQuotSMul`: + `M ⊗[R] (R ⧸ I) ≃ₗ[R] M ⧸ (I • M)` + +## Tags + +Quotient, Tensor Product + +-/ + +namespace TensorProduct + +variable {R M N : Type*} [CommRing R] +variable [AddCommGroup M] [Module R M] [AddCommGroup N] [Module R N] + +attribute [local ext high] ext LinearMap.prod_ext + +/-- +Let `M, N` be `R`-modules, `m ≤ M` and `n ≤ N` be an `R`-submodules. Then we have a linear +isomorphism between tensor products of the quotients and the quotient of the tensor product: +`(M ⧸ m) ⊗[R] (N ⧸ n) ≃ₗ[R] (M ⊗[R] N) ⧸ (m ⊗ N ⊔ M ⊗ n)`. +-/ +noncomputable def quotientTensorQuotientEquiv (m : Submodule R M) (n : Submodule R N) : + (M ⧸ (m : Submodule R M)) ⊗[R] (N ⧸ (n : Submodule R N)) ≃ₗ[R] + (M ⊗[R] N) ⧸ + (LinearMap.range (map m.subtype LinearMap.id) ⊔ + LinearMap.range (map LinearMap.id n.subtype)) := + LinearEquiv.ofLinear + (lift <| Submodule.liftQ _ (LinearMap.flip <| Submodule.liftQ _ + ((mk R (M := M) (N := N)).flip.compr₂ (Submodule.mkQ _)) fun x hx => by + ext y + simp only [LinearMap.compr₂_apply, LinearMap.flip_apply, mk_apply, Submodule.mkQ_apply, + LinearMap.zero_apply, Submodule.Quotient.mk_eq_zero] + exact Submodule.mem_sup_right ⟨y ⊗ₜ ⟨x, hx⟩, rfl⟩) fun x hx => by + ext y + simp only [LinearMap.coe_comp, Function.comp_apply, Submodule.mkQ_apply, LinearMap.flip_apply, + Submodule.liftQ_apply, LinearMap.compr₂_apply, mk_apply, LinearMap.zero_comp, + LinearMap.zero_apply, Submodule.Quotient.mk_eq_zero] + exact Submodule.mem_sup_left ⟨⟨x, hx⟩ ⊗ₜ y, rfl⟩) + (Submodule.liftQ _ (map (Submodule.mkQ _) (Submodule.mkQ _)) fun x hx => by + rw [Submodule.mem_sup] at hx + rcases hx with ⟨_, ⟨a, rfl⟩, _, ⟨b, rfl⟩, rfl⟩ + simp only [LinearMap.mem_ker, map_add] + set f := (map m.mkQ n.mkQ) ∘ₗ (map m.subtype LinearMap.id) + set g := (map m.mkQ n.mkQ) ∘ₗ (map LinearMap.id n.subtype) + have eq : LinearMap.coprod f g = 0 := by + ext x y + · simp [f, Submodule.Quotient.mk_eq_zero _ |>.2 x.2] + · simp [g, Submodule.Quotient.mk_eq_zero _ |>.2 y.2] + exact congr($eq (a, b))) + (by ext; simp) (by ext; simp) + +@[simp] +lemma quotientTensorQuotientEquiv_apply_tmul_mk_tmul_mk + (m : Submodule R M) (n : Submodule R N) (x : M) (y : N) : + quotientTensorQuotientEquiv m n + (Submodule.Quotient.mk x ⊗ₜ[R] Submodule.Quotient.mk y) = + Submodule.Quotient.mk (x ⊗ₜ y) := rfl + +@[simp] +lemma quotientTensorQuotientEquiv_symm_apply_mk_tmul + (m : Submodule R M) (n : Submodule R N) (x : M) (y : N) : + (quotientTensorQuotientEquiv m n).symm (Submodule.Quotient.mk (x ⊗ₜ y)) = + Submodule.Quotient.mk x ⊗ₜ[R] Submodule.Quotient.mk y := rfl + +variable (N) in +/-- +Let `M, N` be `R`-modules, `m ≤ M` be an `R`-submodule. Then we have a linear isomorphism between +tensor products of the quotient and the quotient of the tensor product: +`(M ⧸ m) ⊗[R] N ≃ₗ[R] (M ⊗[R] N) ⧸ (m ⊗ N)`. +-/ +noncomputable def quotientTensorEquiv (m : Submodule R M) : + (M ⧸ (m : Submodule R M)) ⊗[R] N ≃ₗ[R] + (M ⊗[R] N) ⧸ (LinearMap.range (map m.subtype (LinearMap.id : N →ₗ[R] N))) := + congr (LinearEquiv.refl _ _) ((Submodule.quotEquivOfEqBot _ rfl).symm) ≪≫ₗ + quotientTensorQuotientEquiv (N := N) m ⊥ ≪≫ₗ + Submodule.Quotient.equiv _ _ (LinearEquiv.refl _ _) (by + simp only [Submodule.map_sup] + erw [Submodule.map_id, Submodule.map_id] + simp only [sup_eq_left] + rw [map_range_eq_span_tmul, map_range_eq_span_tmul] + aesop) + +@[simp] +lemma quotientTensorEquiv_apply_tmul_mk (m : Submodule R M) (x : M) (y : N) : + quotientTensorEquiv N m (Submodule.Quotient.mk x ⊗ₜ[R] y) = + Submodule.Quotient.mk (x ⊗ₜ y) := + rfl + +@[simp] +lemma quotientTensorEquiv_symm_apply_mk_tmul (m : Submodule R M) (x : M) (y : N) : + (quotientTensorEquiv N m).symm (Submodule.Quotient.mk (x ⊗ₜ y)) = + Submodule.Quotient.mk x ⊗ₜ[R] y := + rfl + +variable (M) in +/-- +Let `M, N` be `R`-modules, `n ≤ N` be an `R`-submodule. Then we have a linear isomorphism between +tensor products of the quotient and the quotient of the tensor product: +`M ⊗[R] (N ⧸ n) ≃ₗ[R] (M ⊗[R] N) ⧸ (M ⊗ n)`. +-/ +noncomputable def tensorQuotientEquiv (n : Submodule R N) : + M ⊗[R] (N ⧸ (n : Submodule R N)) ≃ₗ[R] + (M ⊗[R] N) ⧸ (LinearMap.range (map (LinearMap.id : M →ₗ[R] M) n.subtype)) := + congr ((Submodule.quotEquivOfEqBot _ rfl).symm) (LinearEquiv.refl _ _) ≪≫ₗ + quotientTensorQuotientEquiv (⊥ : Submodule R M) n ≪≫ₗ + Submodule.Quotient.equiv _ _ (LinearEquiv.refl _ _) (by + simp only [Submodule.map_sup] + erw [Submodule.map_id, Submodule.map_id] + simp only [sup_eq_right] + rw [map_range_eq_span_tmul, map_range_eq_span_tmul] + aesop) + +@[simp] +lemma tensorQuotientEquiv_apply_mk_tmul (n : Submodule R N) (x : M) (y : N) : + tensorQuotientEquiv M n (x ⊗ₜ[R] Submodule.Quotient.mk y) = + Submodule.Quotient.mk (x ⊗ₜ y) := + rfl + +@[simp] +lemma tensorQuotientEquiv_symm_apply_tmul_mk (n : Submodule R N) (x : M) (y : N) : + (tensorQuotientEquiv M n).symm (Submodule.Quotient.mk (x ⊗ₜ y)) = + x ⊗ₜ[R] Submodule.Quotient.mk y := + rfl + +variable (M) in +/-- Left tensoring a module with a quotient of the ring is the same as +quotienting that module by the corresponding submodule. -/ +noncomputable def quotTensorEquivQuotSMul (I : Ideal R) : + ((R ⧸ I) ⊗[R] M) ≃ₗ[R] M ⧸ (I • (⊤ : Submodule R M)) := + quotientTensorEquiv M I ≪≫ₗ + Submodule.Quotient.equiv (M := R ⊗[R] M) (N := M) (f := TensorProduct.lid R M) (hf := rfl) ≪≫ₗ + Submodule.Quotient.equiv _ _ (LinearEquiv.refl R M) (by + erw [Submodule.map_id] + rw [TensorProduct.map_range_eq_span_tmul, Submodule.map_span] + refine le_antisymm (Submodule.span_le.2 ?_) (Submodule.map₂_le.2 ?_) + · rintro _ ⟨_, ⟨r, m, rfl⟩, rfl⟩ + simp only [Submodule.coe_subtype, LinearMap.id_coe, id_eq, lid_tmul, SetLike.mem_coe] + apply Submodule.apply_mem_map₂ <;> aesop + · rintro r hr m - + simp only [Submodule.coe_subtype, LinearMap.id_coe, id_eq, Subtype.exists, exists_prop, + LinearMap.lsmul_apply] + refine Submodule.subset_span ?_ + simp only [Set.mem_image, Set.mem_setOf_eq] + exact ⟨r ⊗ₜ m, ⟨r, hr, m, rfl⟩, rfl⟩) + +variable (M) in +/-- Right tensoring a module with a quotient of the ring is the same as +quotienting that module by the corresponding submodule. -/ +noncomputable def tensorQuotEquivQuotSMul (I : Ideal R) : + (M ⊗[R] (R ⧸ I)) ≃ₗ[R] M ⧸ (I • (⊤ : Submodule R M)) := + TensorProduct.comm _ _ _ ≪≫ₗ quotTensorEquivQuotSMul M I + +@[simp] +lemma quotTensorEquivQuotSMul_mk_tmul (I : Ideal R) (r : R) (x : M) : + quotTensorEquivQuotSMul M I (Ideal.Quotient.mk I r ⊗ₜ[R] x) = + Submodule.Quotient.mk (r • x) := + (quotTensorEquivQuotSMul M I).eq_symm_apply.mp <| + Eq.trans (congrArg (· ⊗ₜ[R] x) <| + Eq.trans (congrArg (Ideal.Quotient.mk I) + (Eq.trans (smul_eq_mul R) (mul_one r))).symm <| + Submodule.Quotient.mk_smul I r 1) <| + smul_tmul r _ x + +lemma quotTensorEquivQuotSMul_comp_mkQ_rTensor (I : Ideal R) : + quotTensorEquivQuotSMul M I ∘ₗ I.mkQ.rTensor M = + (I • ⊤ : Submodule R M).mkQ ∘ₗ TensorProduct.lid R M := + TensorProduct.ext' (quotTensorEquivQuotSMul_mk_tmul I) + +@[simp] +lemma quotTensorEquivQuotSMul_symm_mk (I : Ideal R) (x : M) : + (quotTensorEquivQuotSMul M I).symm (Submodule.Quotient.mk x) = 1 ⊗ₜ[R] x := + rfl + +lemma quotTensorEquivQuotSMul_symm_comp_mkQ (I : Ideal R) : + (quotTensorEquivQuotSMul M I).symm ∘ₗ (I • ⊤ : Submodule R M).mkQ = + TensorProduct.mk R (R ⧸ I) M 1 := + LinearMap.ext (quotTensorEquivQuotSMul_symm_mk I) + +lemma quotTensorEquivQuotSMul_comp_mk (I : Ideal R) : + quotTensorEquivQuotSMul M I ∘ₗ TensorProduct.mk R (R ⧸ I) M 1 = + Submodule.mkQ (I • ⊤) := + Eq.symm <| (LinearEquiv.toLinearMap_symm_comp_eq _ _).mp <| + quotTensorEquivQuotSMul_symm_comp_mkQ I + +@[simp] +lemma tensorQuotEquivQuotSMul_tmul_mk (I : Ideal R) (x : M) (r : R) : + tensorQuotEquivQuotSMul M I (x ⊗ₜ[R] Ideal.Quotient.mk I r) = + Submodule.Quotient.mk (r • x) := + quotTensorEquivQuotSMul_mk_tmul I r x + +lemma tensorQuotEquivQuotSMul_comp_mkQ_lTensor (I : Ideal R) : + tensorQuotEquivQuotSMul M I ∘ₗ I.mkQ.lTensor M = + (I • ⊤ : Submodule R M).mkQ ∘ₗ TensorProduct.rid R M := + TensorProduct.ext' (tensorQuotEquivQuotSMul_tmul_mk I) + +@[simp] +lemma tensorQuotEquivQuotSMul_symm_mk (I : Ideal R) (x : M) : + (tensorQuotEquivQuotSMul M I).symm (Submodule.Quotient.mk x) = x ⊗ₜ[R] 1 := + rfl + +lemma tensorQuotEquivQuotSMul_symm_comp_mkQ (I : Ideal R) : + (tensorQuotEquivQuotSMul M I).symm ∘ₗ (I • ⊤ : Submodule R M).mkQ = + (TensorProduct.mk R M (R ⧸ I)).flip 1 := + LinearMap.ext (tensorQuotEquivQuotSMul_symm_mk I) + +lemma tensorQuotEquivQuotSMul_comp_mk (I : Ideal R) : + tensorQuotEquivQuotSMul M I ∘ₗ (TensorProduct.mk R M (R ⧸ I)).flip 1 = + Submodule.mkQ (I • ⊤) := + Eq.symm <| (LinearEquiv.toLinearMap_symm_comp_eq _ _).mp <| + tensorQuotEquivQuotSMul_symm_comp_mkQ I + +end TensorProduct diff --git a/Mathlib/LinearAlgebra/TensorProduct/RightExactness.lean b/Mathlib/LinearAlgebra/TensorProduct/RightExactness.lean index c55c56caf1c8ee..a61f53baf761cb 100644 --- a/Mathlib/LinearAlgebra/TensorProduct/RightExactness.lean +++ b/Mathlib/LinearAlgebra/TensorProduct/RightExactness.lean @@ -6,7 +6,6 @@ Authors: Antoine Chambert-Loir import Mathlib.Algebra.Exact import Mathlib.RingTheory.TensorProduct.Basic -import Mathlib.RingTheory.Ideal.Quotient /-! # Right-exactness properties of tensor product @@ -423,84 +422,6 @@ theorem TensorProduct.mk_surjective (S) [Semiring S] [Algebra R S] rw [Algebra.algebraMap_eq_smul_one, smul_tmul] exact ⟨x • y, rfl⟩ -/-- Left tensoring a module with a quotient of the ring is the same as -quotienting that module by the corresponding submodule. -/ -noncomputable def quotTensorEquivQuotSMul (I : Ideal R) : - (R ⧸ I) ⊗[R] M ≃ₗ[R] M ⧸ (I • ⊤ : Submodule R M) := - (rTensor.equiv M (exact_subtype_mkQ I) I.mkQ_surjective).symm.trans <| - Submodule.Quotient.equiv _ _ (TensorProduct.lid R M) <| - Eq.trans (LinearMap.range_comp _ _).symm <| - Eq.trans ((Submodule.topEquiv.lTensor I).range_comp _).symm <| - Eq.symm <| Eq.trans (map₂_eq_range_lift_comp_mapIncl _ _ _) <| - congrArg _ (TensorProduct.ext' (fun _ _ => rfl)) - -/-- Right tensoring a module with a quotient of the ring is the same as -quotienting that module by the corresponding submodule. -/ -noncomputable def tensorQuotEquivQuotSMul (I : Ideal R) : - M ⊗[R] (R ⧸ I) ≃ₗ[R] M ⧸ (I • ⊤ : Submodule R M) := - TensorProduct.comm R M _ ≪≫ₗ quotTensorEquivQuotSMul M I - -variable {M} - -@[simp] -lemma quotTensorEquivQuotSMul_mk_tmul (I : Ideal R) (r : R) (x : M) : - quotTensorEquivQuotSMul M I (Ideal.Quotient.mk I r ⊗ₜ[R] x) = - Submodule.Quotient.mk (r • x) := - (quotTensorEquivQuotSMul M I).eq_symm_apply.mp <| - Eq.trans (congrArg (· ⊗ₜ[R] x) <| - Eq.trans (congrArg (Ideal.Quotient.mk I) - (Eq.trans (smul_eq_mul R) (mul_one r))).symm <| - Submodule.Quotient.mk_smul I r 1) <| - smul_tmul r _ x - -lemma quotTensorEquivQuotSMul_comp_mkQ_rTensor (I : Ideal R) : - quotTensorEquivQuotSMul M I ∘ₗ I.mkQ.rTensor M = - (I • ⊤ : Submodule R M).mkQ ∘ₗ TensorProduct.lid R M := - TensorProduct.ext' (quotTensorEquivQuotSMul_mk_tmul I) - -@[simp] -lemma quotTensorEquivQuotSMul_symm_mk (I : Ideal R) (x : M) : - (quotTensorEquivQuotSMul M I).symm (Submodule.Quotient.mk x) = 1 ⊗ₜ[R] x := - rfl - -lemma quotTensorEquivQuotSMul_symm_comp_mkQ (I : Ideal R) : - (quotTensorEquivQuotSMul M I).symm ∘ₗ (I • ⊤ : Submodule R M).mkQ = - TensorProduct.mk R (R ⧸ I) M 1 := - LinearMap.ext (quotTensorEquivQuotSMul_symm_mk I) - -lemma quotTensorEquivQuotSMul_comp_mk (I : Ideal R) : - quotTensorEquivQuotSMul M I ∘ₗ TensorProduct.mk R (R ⧸ I) M 1 = - Submodule.mkQ (I • ⊤) := - Eq.symm <| (LinearEquiv.toLinearMap_symm_comp_eq _ _).mp <| - quotTensorEquivQuotSMul_symm_comp_mkQ I - -@[simp] -lemma tensorQuotEquivQuotSMul_tmul_mk (I : Ideal R) (x : M) (r : R) : - tensorQuotEquivQuotSMul M I (x ⊗ₜ[R] Ideal.Quotient.mk I r) = - Submodule.Quotient.mk (r • x) := - quotTensorEquivQuotSMul_mk_tmul I r x - -lemma tensorQuotEquivQuotSMul_comp_mkQ_lTensor (I : Ideal R) : - tensorQuotEquivQuotSMul M I ∘ₗ I.mkQ.lTensor M = - (I • ⊤ : Submodule R M).mkQ ∘ₗ TensorProduct.rid R M := - TensorProduct.ext' (tensorQuotEquivQuotSMul_tmul_mk I) - -@[simp] -lemma tensorQuotEquivQuotSMul_symm_mk (I : Ideal R) (x : M) : - (tensorQuotEquivQuotSMul M I).symm (Submodule.Quotient.mk x) = x ⊗ₜ[R] 1 := - rfl - -lemma tensorQuotEquivQuotSMul_symm_comp_mkQ (I : Ideal R) : - (tensorQuotEquivQuotSMul M I).symm ∘ₗ (I • ⊤ : Submodule R M).mkQ = - (TensorProduct.mk R M (R ⧸ I)).flip 1 := - LinearMap.ext (tensorQuotEquivQuotSMul_symm_mk I) - -lemma tensorQuotEquivQuotSMul_comp_mk (I : Ideal R) : - tensorQuotEquivQuotSMul M I ∘ₗ (TensorProduct.mk R M (R ⧸ I)).flip 1 = - Submodule.mkQ (I • ⊤) := - Eq.symm <| (LinearEquiv.toLinearMap_symm_comp_eq _ _).mp <| - tensorQuotEquivQuotSMul_symm_comp_mkQ I - end Modules section Algebras diff --git a/Mathlib/RingTheory/QuotSMulTop.lean b/Mathlib/RingTheory/QuotSMulTop.lean index 50ffb52e031830..2b2dfe48be1089 100644 --- a/Mathlib/RingTheory/QuotSMulTop.lean +++ b/Mathlib/RingTheory/QuotSMulTop.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Brendan Murphy -/ import Mathlib.LinearAlgebra.TensorProduct.RightExactness +import Mathlib.LinearAlgebra.TensorProduct.Quotient /-! # Reducing a module modulo an element of the ring From 7d50a88f4d70f386ac24e982cf686583e96e2959 Mon Sep 17 00:00:00 2001 From: Junyan Xu Date: Thu, 17 Oct 2024 11:36:58 +0000 Subject: [PATCH 300/425] feat(Algebra): integralClosure as IntermediateField (#14206) + Add lemmas about integrality and membership in an subalgebra of inverse elements. + As a consequence, show the integral closure of a field in a division ring is an intermediate field `IntermediateField.algClosure`. + Golf some lemmas along the way. Co-authored-by: Junyan Xu --- Mathlib/FieldTheory/Adjoin.lean | 55 +++++-------- .../IntermediateField/Algebraic.lean | 24 +++++- .../FieldTheory/IntermediateField/Basic.lean | 30 ++----- Mathlib/FieldTheory/PurelyInseparable.lean | 2 +- .../LinearAlgebra/FiniteDimensional/Defs.lean | 7 +- Mathlib/RingTheory/Algebraic.lean | 2 +- .../IntegralClosure/Algebra/Basic.lean | 17 ++-- .../IsIntegralClosure/Basic.lean | 82 ++++++++++++++++--- 8 files changed, 137 insertions(+), 82 deletions(-) diff --git a/Mathlib/FieldTheory/Adjoin.lean b/Mathlib/FieldTheory/Adjoin.lean index 3fa951422ab8a5..aa48dc241889b9 100644 --- a/Mathlib/FieldTheory/Adjoin.lean +++ b/Mathlib/FieldTheory/Adjoin.lean @@ -70,7 +70,7 @@ section Lattice variable {F : Type*} [Field F] {E : Type*} [Field E] [Algebra F E] @[simp] -theorem adjoin_le_iff {S : Set E} {T : IntermediateField F E} : adjoin F S ≤ T ↔ S ≤ T := +theorem adjoin_le_iff {S : Set E} {T : IntermediateField F E} : adjoin F S ≤ T ↔ S ⊆ T := ⟨fun H => le_trans (le_trans Set.subset_union_right Subfield.subset_closure) H, fun H => (@Subfield.closure_le E _ (Set.range (algebraMap F E) ∪ S) T.toSubfield).mpr (Set.union_subset (IntermediateField.set_range_subset T) H)⟩ @@ -263,7 +263,7 @@ instance isScalarTower_over_bot : IsScalarTower (⊥ : IntermediateField F E) F This is the intermediate field version of `Subalgebra.topEquiv`. -/ @[simps!] def topEquiv : (⊤ : IntermediateField F E) ≃ₐ[F] E := - (Subalgebra.equivOfEq _ _ top_toSubalgebra).trans Subalgebra.topEquiv + Subalgebra.topEquiv -- Porting note: this theorem is now generated by the `@[simps!]` above. @@ -400,24 +400,14 @@ theorem adjoin_subset_adjoin_iff {F' : Type*} [Field F'] [Algebra F' E] {S S' : theorem adjoin_adjoin_left (T : Set E) : (adjoin (adjoin F S) T).restrictScalars _ = adjoin F (S ∪ T) := by rw [SetLike.ext'_iff] - change (↑(adjoin (adjoin F S) T) : Set E) = _ - apply Set.eq_of_subset_of_subset <;> rw [adjoin_subset_adjoin_iff] <;> constructor + change (adjoin (adjoin F S) T : Set E) = _ + apply subset_antisymm <;> rw [adjoin_subset_adjoin_iff] <;> constructor · rintro _ ⟨⟨x, hx⟩, rfl⟩; exact adjoin.mono _ _ _ Set.subset_union_left hx · exact subset_adjoin_of_subset_right _ _ Set.subset_union_right --- Porting note: original proof times out - · rintro x ⟨f, rfl⟩ - refine Subfield.subset_closure ?_ - left - exact ⟨f, rfl⟩ --- Porting note: original proof times out - · refine Set.union_subset (fun x hx => Subfield.subset_closure ?_) - (fun x hx => Subfield.subset_closure ?_) - · left - refine ⟨⟨x, Subfield.subset_closure ?_⟩, rfl⟩ - right - exact hx - · right - exact hx + · exact Set.range_subset_iff.mpr fun f ↦ Subfield.subset_closure (.inl ⟨f, rfl⟩) + · exact Set.union_subset + (fun x hx ↦ Subfield.subset_closure <| .inl ⟨⟨x, Subfield.subset_closure (.inr hx)⟩, rfl⟩) + (fun x hx ↦ Subfield.subset_closure <| .inr hx) @[simp] theorem adjoin_insert_adjoin (x : E) : @@ -435,14 +425,10 @@ theorem adjoin_adjoin_comm (T : Set E) : rw [adjoin_adjoin_left, adjoin_adjoin_left, Set.union_comm] theorem adjoin_map {E' : Type*} [Field E'] [Algebra F E'] (f : E →ₐ[F] E') : - (adjoin F S).map f = adjoin F (f '' S) := by - ext x - show - x ∈ (Subfield.closure (Set.range (algebraMap F E) ∪ S)).map (f : E →+* E') ↔ - x ∈ Subfield.closure (Set.range (algebraMap F E') ∪ f '' S) - rw [RingHom.map_field_closure, Set.image_union, ← Set.range_comp, ← RingHom.coe_comp, - f.comp_algebraMap] - rfl + (adjoin F S).map f = adjoin F (f '' S) := + le_antisymm + (map_le_iff_le_comap.mpr <| adjoin_le_iff.mpr fun x hx ↦ subset_adjoin _ _ ⟨x, hx, rfl⟩) + (adjoin_le_iff.mpr <| Set.monotone_image <| subset_adjoin _ _) @[simp] theorem lift_adjoin (K : IntermediateField F E) (S : Set K) : @@ -510,9 +496,9 @@ theorem eq_adjoin_of_eq_algebra_adjoin (K : IntermediateField F E) (h : K.toSubalgebra = Algebra.adjoin F S) : K = adjoin F S := by apply toSubalgebra_injective rw [h] - refine (adjoin_eq_algebra_adjoin F _ ?_).symm - intro x - convert K.inv_mem (x := x) <;> rw [← h] <;> rfl + refine (adjoin_eq_algebra_adjoin F _ fun x ↦ ?_).symm + rw [← h] + exact K.inv_mem theorem adjoin_eq_top_of_algebra (hS : Algebra.adjoin F S = ⊤) : adjoin F S = ⊤ := top_le_iff.mp (hS.symm.trans_le <| algebra_adjoin_le_adjoin F S) @@ -600,12 +586,9 @@ theorem adjoin_simple_comm (β : E) : F⟮α⟯⟮β⟯.restrictScalars F = F⟮ variable {F} {α} theorem adjoin_algebraic_toSubalgebra {S : Set E} (hS : ∀ x ∈ S, IsAlgebraic F x) : - (IntermediateField.adjoin F S).toSubalgebra = Algebra.adjoin F S := by - simp only [isAlgebraic_iff_isIntegral] at hS - have : Algebra.IsIntegral F (Algebra.adjoin F S) := by - rwa [← le_integralClosure_iff_isIntegral, Algebra.adjoin_le_iff] - have : IsField (Algebra.adjoin F S) := isField_of_isIntegral_of_isField' (Field.toIsField F) - rw [← ((Algebra.adjoin F S).toIntermediateField' this).eq_adjoin_of_eq_algebra_adjoin F S] <;> rfl + (IntermediateField.adjoin F S).toSubalgebra = Algebra.adjoin F S := + adjoin_eq_algebra_adjoin _ _ fun _ ↦ + (Algebra.IsIntegral.adjoin fun x hx ↦ (hS x hx).isIntegral).inv_mem theorem adjoin_simple_toSubalgebra_of_integral (hα : IsIntegral F α) : F⟮α⟯.toSubalgebra = Algebra.adjoin F {α} := by @@ -884,7 +867,7 @@ variable {F : Type*} [Field F] {E : Type*} [Field E] [Algebra F E] {α : E} {S : @[simp] theorem adjoin_eq_bot_iff : adjoin F S = ⊥ ↔ S ⊆ (⊥ : IntermediateField F E) := by - rw [eq_bot_iff, adjoin_le_iff]; rfl + rw [eq_bot_iff, adjoin_le_iff] /- Porting note: this was tagged `simp`. -/ theorem adjoin_simple_eq_bot_iff : F⟮α⟯ = ⊥ ↔ α ∈ (⊥ : IntermediateField F E) := by diff --git a/Mathlib/FieldTheory/IntermediateField/Algebraic.lean b/Mathlib/FieldTheory/IntermediateField/Algebraic.lean index 55ecc961483069..7769f62c1eccb5 100644 --- a/Mathlib/FieldTheory/IntermediateField/Algebraic.lean +++ b/Mathlib/FieldTheory/IntermediateField/Algebraic.lean @@ -18,6 +18,26 @@ open Module variable {K : Type*} {L : Type*} [Field K] [Field L] [Algebra K L] {S : IntermediateField K L} +theorem IntermediateField.coe_isIntegral_iff {R : Type*} [CommRing R] [Algebra R K] [Algebra R L] + [IsScalarTower R K L] {x : S} : IsIntegral R (x : L) ↔ IsIntegral R x := + isIntegral_algHom_iff (S.val.restrictScalars R) Subtype.val_injective + +/-- Turn an algebraic subalgebra into an intermediate field, `Subalgebra.IsAlgebraic` version. -/ +def Subalgebra.IsAlgebraic.toIntermediateField {S : Subalgebra K L} (hS : S.IsAlgebraic) : + IntermediateField K L where + toSubalgebra := S + inv_mem' x hx := Algebra.adjoin_le_iff.mpr + (Set.singleton_subset_iff.mpr hx) (hS x hx).isIntegral.inv_mem_adjoin + +/-- Turn an algebraic subalgebra into an intermediate field, `Algebra.IsAlgebraic` version. -/ +abbrev Algebra.IsAlgebraic.toIntermediateField (S : Subalgebra K L) [Algebra.IsAlgebraic K S] : + IntermediateField K L := (S.isAlgebraic_iff.mpr ‹_›).toIntermediateField + +/-- The algebraic closure of a field `K` in an extension `L`, the subalgebra `integralClosure K L` +upgraded to an intermediate field (when `K` and `L` are both fields). -/ +def algebraicClosure : IntermediateField K L := + Algebra.IsAlgebraic.toIntermediateField (integralClosure K L) + namespace IntermediateField section FiniteDimensional @@ -86,8 +106,8 @@ end FiniteDimensional theorem isAlgebraic_iff {x : S} : IsAlgebraic K x ↔ IsAlgebraic K (x : L) := (isAlgebraic_algebraMap_iff (algebraMap S L).injective).symm -theorem isIntegral_iff {x : S} : IsIntegral K x ↔ IsIntegral K (x : L) := by - rw [← isAlgebraic_iff_isIntegral, isAlgebraic_iff, isAlgebraic_iff_isIntegral] +theorem isIntegral_iff {x : S} : IsIntegral K x ↔ IsIntegral K (x : L) := + (isIntegral_algHom_iff S.val S.val.injective).symm theorem minpoly_eq (x : S) : minpoly K x = minpoly K (x : L) := (minpoly.algebraMap_eq (algebraMap S L).injective x).symm diff --git a/Mathlib/FieldTheory/IntermediateField/Basic.lean b/Mathlib/FieldTheory/IntermediateField/Basic.lean index 31cc6116137552..1c807c53644734 100644 --- a/Mathlib/FieldTheory/IntermediateField/Basic.lean +++ b/Mathlib/FieldTheory/IntermediateField/Basic.lean @@ -6,7 +6,6 @@ Authors: Anne Baanen import Mathlib.Algebra.Field.Subfield import Mathlib.Algebra.Polynomial.AlgebraMap import Mathlib.RingTheory.LocalRing.Basic -import Mathlib.RingTheory.IntegralClosure.IsIntegral.Defs /-! # Intermediate fields @@ -112,10 +111,8 @@ theorem mem_toSubfield (s : IntermediateField K L) (x : L) : x ∈ s.toSubfield definitional equalities. -/ protected def copy (S : IntermediateField K L) (s : Set L) (hs : s = ↑S) : IntermediateField K L where - toSubalgebra := S.toSubalgebra.copy s (hs : s = S.toSubalgebra.carrier) - inv_mem' := - have hs' : (S.toSubalgebra.copy s hs).carrier = S.toSubalgebra.carrier := hs - hs'.symm ▸ S.inv_mem' + toSubalgebra := S.toSubalgebra.copy s hs + inv_mem' := hs.symm ▸ S.inv_mem' @[simp] theorem coe_copy (S : IntermediateField K L) (s : Set L) (hs : s = ↑S) : @@ -341,7 +338,7 @@ instance isScalarTower_mid {R : Type*} [Semiring R] [Algebra L R] [Algebra K R] /-- Specialize `is_scalar_tower_mid` to the common case where the top field is `L` -/ instance isScalarTower_mid' : IsScalarTower K S L := - S.isScalarTower_mid + inferInstance instance {E} [Semiring E] [Algebra L E] : Algebra S E := inferInstanceAs (Algebra S.toSubalgebra E) @@ -468,25 +465,8 @@ instance AlgHom.inhabited : Inhabited (S →ₐ[K] L) := ⟨S.val⟩ theorem aeval_coe {R : Type*} [CommRing R] [Algebra R K] [Algebra R L] [IsScalarTower R K L] - (x : S) (P : R[X]) : aeval (x : L) P = aeval x P := by - refine Polynomial.induction_on' P (fun f g hf hg => ?_) fun n r => ?_ - · rw [aeval_add, aeval_add, AddMemClass.coe_add, hf, hg] - · simp only [MulMemClass.coe_mul, aeval_monomial, SubmonoidClass.coe_pow, mul_eq_mul_right_iff] - left - rfl - -theorem coe_isIntegral_iff {R : Type*} [CommRing R] [Algebra R K] [Algebra R L] - [IsScalarTower R K L] {x : S} : IsIntegral R (x : L) ↔ IsIntegral R x := by - refine ⟨fun h => ?_, fun h => ?_⟩ - · obtain ⟨P, hPmo, hProot⟩ := h - refine ⟨P, hPmo, (injective_iff_map_eq_zero _).1 (algebraMap (↥S) L).injective _ ?_⟩ - letI : IsScalarTower R S L := IsScalarTower.of_algebraMap_eq (congr_fun rfl) - rw [eval₂_eq_eval_map, ← eval₂_at_apply, eval₂_eq_eval_map, Polynomial.map_map, ← - IsScalarTower.algebraMap_eq, ← eval₂_eq_eval_map] - exact hProot - · obtain ⟨P, hPmo, hProot⟩ := h - refine ⟨P, hPmo, ?_⟩ - rw [← aeval_def, aeval_coe, aeval_def, hProot, ZeroMemClass.coe_zero] + (x : S) (P : R[X]) : aeval (x : L) P = aeval x P := + aeval_algHom_apply (S.val.restrictScalars R) x P /-- The map `E → F` when `E` is an intermediate field contained in the intermediate field `F`. diff --git a/Mathlib/FieldTheory/PurelyInseparable.lean b/Mathlib/FieldTheory/PurelyInseparable.lean index 2a1a024969a2d5..bf5f64619ceeff 100644 --- a/Mathlib/FieldTheory/PurelyInseparable.lean +++ b/Mathlib/FieldTheory/PurelyInseparable.lean @@ -667,7 +667,7 @@ if and only if for any `x ∈ S`, `x ^ (q ^ n)` is contained in `F` for some `n theorem isPurelyInseparable_adjoin_iff_pow_mem (q : ℕ) [hF : ExpChar F q] {S : Set E} : IsPurelyInseparable F (adjoin F S) ↔ ∀ x ∈ S, ∃ n : ℕ, x ^ q ^ n ∈ (algebraMap F E).range := by simp_rw [← le_perfectClosure_iff, adjoin_le_iff, ← mem_perfectClosure_iff_pow_mem q, - Set.le_iff_subset, Set.subset_def, SetLike.mem_coe] + Set.subset_def, SetLike.mem_coe] /-- A compositum of two purely inseparable extensions is purely inseparable. -/ instance isPurelyInseparable_sup (L1 L2 : IntermediateField F E) diff --git a/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean b/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean index 6d30b7aa5aa3a8..2bce02c0a50fc6 100644 --- a/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean +++ b/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean @@ -671,18 +671,23 @@ noncomputable def divisionRingOfFiniteDimensional (F K : Type*) [Field F] [Ring 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] - exact (Classical.choose_spec (FiniteDimensional.exists_mul_eq_one F hx):) + exact (Classical.choose_spec (FiniteDimensional.exists_mul_eq_one F hx) :) inv_zero := dif_pos rfl nnqsmul := _ nnqsmul_def := fun _ _ => rfl qsmul := _ qsmul_def := fun _ _ => rfl +lemma FiniteDimensional.isUnit (F : Type*) {K : Type*} [Field F] [Ring K] [IsDomain K] + [Algebra F K] [FiniteDimensional F K] {x : K} (H : x ≠ 0) : IsUnit x := + let _ := divisionRingOfFiniteDimensional F K; H.isUnit + /-- An integral domain that is module-finite as an algebra over a field is a field. -/ 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 toCommRing := h } + end section DivisionRing diff --git a/Mathlib/RingTheory/Algebraic.lean b/Mathlib/RingTheory/Algebraic.lean index 20fba6c16cb72c..86852795792387 100644 --- a/Mathlib/RingTheory/Algebraic.lean +++ b/Mathlib/RingTheory/Algebraic.lean @@ -69,7 +69,7 @@ theorem Algebra.transcendental_iff_not_isAlgebraic : /-- A subalgebra is algebraic if and only if it is algebraic as an algebra. -/ theorem Subalgebra.isAlgebraic_iff (S : Subalgebra R A) : - S.IsAlgebraic ↔ @Algebra.IsAlgebraic R S _ _ S.algebra := by + S.IsAlgebraic ↔ Algebra.IsAlgebraic R S := by delta Subalgebra.IsAlgebraic rw [Subtype.forall', Algebra.isAlgebraic_def] refine forall_congr' fun x => exists_congr fun p => and_congr Iff.rfl ?_ diff --git a/Mathlib/RingTheory/IntegralClosure/Algebra/Basic.lean b/Mathlib/RingTheory/IntegralClosure/Algebra/Basic.lean index 37343ddf2c6112..0f9874f3e5ae84 100644 --- a/Mathlib/RingTheory/IntegralClosure/Algebra/Basic.lean +++ b/Mathlib/RingTheory/IntegralClosure/Algebra/Basic.lean @@ -28,15 +28,22 @@ variable {R A B S : Type*} variable [CommRing R] [CommRing A] [Ring B] [CommRing S] variable [Algebra R A] [Algebra R B] (f : R →+* S) +theorem Subalgebra.isIntegral_iff (S : Subalgebra R A) : + Algebra.IsIntegral R S ↔ ∀ x ∈ S, IsIntegral R x := + Algebra.isIntegral_def.trans <| .trans + (forall_congr' fun _ ↦ (isIntegral_algHom_iff S.val Subtype.val_injective).symm) Subtype.forall + section variable {A B : Type*} [Ring A] [Ring B] [Algebra R A] [Algebra R B] -variable (f : A →ₐ[R] B) (hf : Function.Injective f) -theorem Algebra.IsIntegral.of_injective (hf : Function.Injective f) [Algebra.IsIntegral R B] : - Algebra.IsIntegral R A := +theorem Algebra.IsIntegral.of_injective (f : A →ₐ[R] B) (hf : Function.Injective f) + [Algebra.IsIntegral R B] : Algebra.IsIntegral R A := ⟨fun _ ↦ (isIntegral_algHom_iff f hf).mp (isIntegral _)⟩ +theorem AlgEquiv.isIntegral_iff (e : A ≃ₐ[R] B) : Algebra.IsIntegral R A ↔ Algebra.IsIntegral R B := + ⟨fun h ↦ h.of_injective e.symm e.symm.injective, fun h ↦ h.of_injective e e.injective⟩ + end instance Module.End.isIntegral {M : Type*} [AddCommGroup M] [Module R M] [Module.Finite R M] : @@ -57,8 +64,8 @@ instance Algebra.IsIntegral.of_finite [Module.Finite R B] : Algebra.IsIntegral R /-- If `S` is a sub-`R`-algebra of `A` and `S` is finitely-generated as an `R`-module, then all elements of `S` are integral over `R`. -/ -theorem IsIntegral.of_mem_of_fg {A} [Ring A] [Algebra R A] (S : Subalgebra R A) - (HS : S.toSubmodule.FG) (x : A) (hx : x ∈ S) : IsIntegral R x := +theorem IsIntegral.of_mem_of_fg (S : Subalgebra R B) + (HS : S.toSubmodule.FG) (x : B) (hx : x ∈ S) : IsIntegral R x := have : Module.Finite R S := ⟨(fg_top _).mpr HS⟩ (isIntegral_algHom_iff S.val Subtype.val_injective).mpr (.of_finite R (⟨x, hx⟩ : S)) diff --git a/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean b/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean index 5c9727459cf1a4..59406a95b8ec6c 100644 --- a/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean +++ b/Mathlib/RingTheory/IntegralClosure/IsIntegralClosure/Basic.lean @@ -19,6 +19,58 @@ We prove basic properties of `IsIntegralClosure`. open scoped Classical open Polynomial Submodule +section inv + +open Algebra + +variable {R S : Type*} + +/-- A nonzero element in a domain integral over a field is a unit. -/ +theorem IsIntegral.isUnit [Field R] [Ring S] [IsDomain S] [Algebra R S] {x : S} + (int : IsIntegral R x) (h0 : x ≠ 0) : IsUnit x := + have : FiniteDimensional R (adjoin R {x}) := ⟨(Submodule.fg_top _).mpr int.fg_adjoin_singleton⟩ + (FiniteDimensional.isUnit R (K := adjoin R {x}) + (x := ⟨x, subset_adjoin rfl⟩) <| mt Subtype.ext_iff.mp h0).map (adjoin R {x}).val + +/-- A commutative domain that is an integral algebra over a field is a field. -/ +theorem isField_of_isIntegral_of_isField' [CommRing R] [CommRing S] [IsDomain S] + [Algebra R S] [Algebra.IsIntegral R S] (hR : IsField R) : IsField S where + exists_pair_ne := ⟨0, 1, zero_ne_one⟩ + mul_comm := mul_comm + mul_inv_cancel {x} hx := by + letI := hR.toField + obtain ⟨y, rfl⟩ := (Algebra.IsIntegral.isIntegral (R := R) x).isUnit hx + exact ⟨y.inv, y.val_inv⟩ + +variable [Field R] [DivisionRing S] [Algebra R S] {x : S} {A : Subalgebra R S} + +theorem IsIntegral.inv_mem_adjoin (int : IsIntegral R x) : x⁻¹ ∈ adjoin R {x} := by + obtain rfl | h0 := eq_or_ne x 0 + · rw [inv_zero]; exact Subalgebra.zero_mem _ + have : FiniteDimensional R (adjoin R {x}) := ⟨(Submodule.fg_top _).mpr int.fg_adjoin_singleton⟩ + obtain ⟨⟨y, hy⟩, h1⟩ := FiniteDimensional.exists_mul_eq_one R + (K := adjoin R {x}) (x := ⟨x, subset_adjoin rfl⟩) (mt Subtype.ext_iff.mp h0) + rwa [← mul_left_cancel₀ h0 ((Subtype.ext_iff.mp h1).trans (mul_inv_cancel₀ h0).symm)] + +/-- The inverse of an integral element in a subalgebra of a division ring over a field + also lies in that subalgebra. -/ +theorem IsIntegral.inv_mem (int : IsIntegral R x) (hx : x ∈ A) : x⁻¹ ∈ A := + adjoin_le_iff.mpr (Set.singleton_subset_iff.mpr hx) int.inv_mem_adjoin + +/-- An integral subalgebra of a division ring over a field is closed under inverses. -/ +theorem Algebra.IsIntegral.inv_mem [Algebra.IsIntegral R A] (hx : x ∈ A) : x⁻¹ ∈ A := + ((isIntegral_algHom_iff A.val Subtype.val_injective).mpr <| + Algebra.IsIntegral.isIntegral (⟨x, hx⟩ : A)).inv_mem hx + +/-- The inverse of an integral element in a division ring over a field is also integral. -/ +theorem IsIntegral.inv (int : IsIntegral R x) : IsIntegral R x⁻¹ := + .of_mem_of_fg _ int.fg_adjoin_singleton _ int.inv_mem_adjoin + +theorem IsIntegral.mem_of_inv_mem (int : IsIntegral R x) (inv_mem : x⁻¹ ∈ A) : x ∈ A := by + rw [← inv_inv x]; exact int.inv.inv_mem inv_mem + +end inv + section variable {R A B S : Type*} @@ -78,10 +130,22 @@ theorem le_integralClosure_iff_isIntegral {S : Subalgebra R A} : isIntegral_algebraMap_iff Subtype.coe_injective).trans Algebra.isIntegral_def.symm +theorem Algebra.IsIntegral.adjoin {S : Set A} (hS : ∀ x ∈ S, IsIntegral R x) : + Algebra.IsIntegral R (Algebra.adjoin R S) := + le_integralClosure_iff_isIntegral.mp <| adjoin_le_iff.mpr hS + +theorem integralClosure_eq_top_iff : integralClosure R A = ⊤ ↔ Algebra.IsIntegral R A := by + rw [← top_le_iff, le_integralClosure_iff_isIntegral, + (Subalgebra.topEquiv (R := R) (A := A)).isIntegral_iff] -- explicit arguments for speedup + theorem Algebra.isIntegral_sup {S T : Subalgebra R A} : Algebra.IsIntegral R (S ⊔ T : Subalgebra R A) ↔ Algebra.IsIntegral R S ∧ Algebra.IsIntegral R T := by - simp only [← le_integralClosure_iff_isIntegral, sup_le_iff] + simp_rw [← le_integralClosure_iff_isIntegral, sup_le_iff] + +theorem Algebra.isIntegral_iSup {ι} (S : ι → Subalgebra R A) : + Algebra.IsIntegral R ↑(iSup S) ↔ ∀ i, Algebra.IsIntegral R (S i) := by + simp_rw [← le_integralClosure_iff_isIntegral, iSup_le_iff] /-- Mapping an integral closure along an `AlgEquiv` gives the integral closure. -/ theorem integralClosure_map_algEquiv [Algebra R S] (f : A ≃ₐ[R] S) : @@ -360,6 +424,12 @@ theorem mk'_algebraMap [Algebra R A] [IsScalarTower R A B] (x : R) IsIntegralClosure.mk' A (algebraMap R B x) h = algebraMap R A x := algebraMap_injective A R B <| by rw [algebraMap_mk', ← IsScalarTower.algebraMap_apply] +/-- The integral closure of a field in a commutative domain is always a field. -/ +theorem isField [Algebra R A] [IsScalarTower R A B] [IsDomain A] (hR : IsField R) : + IsField A := + have := IsIntegralClosure.isIntegral_algebra R (A := A) B + isField_of_isIntegral_of_isField' hR + section lift variable (B) {S : Type*} [CommRing S] [Algebra R S] @@ -543,16 +613,6 @@ theorem isField_of_isIntegral_of_isField {R S : Type*} [CommRing R] [CommRing S] ← (injective_iff_map_eq_zero' _).mp hRS, ← aeval_algebraMap_apply_eq_algebraMap_eval] rwa [← eval₂_reverse_eq_zero_iff] at hp -theorem isField_of_isIntegral_of_isField' {R S : Type*} [CommRing R] [CommRing S] [IsDomain S] - [Algebra R S] [Algebra.IsIntegral R S] (hR : IsField R) : IsField S := by - refine ⟨⟨0, 1, zero_ne_one⟩, mul_comm, fun {x} hx ↦ ?_⟩ - have : Module.Finite R (adjoin R {x}) := ⟨(Submodule.fg_top _).mpr - (Algebra.IsIntegral.isIntegral x).fg_adjoin_singleton⟩ - letI := hR.toField - obtain ⟨y, hy⟩ := FiniteDimensional.exists_mul_eq_one R - (K := adjoin R {x}) (x := ⟨x, subset_adjoin rfl⟩) (mt Subtype.ext_iff.mp hx) - exact ⟨y, Subtype.ext_iff.mp hy⟩ - theorem Algebra.IsIntegral.isField_iff_isField {R S : Type*} [CommRing R] [CommRing S] [IsDomain S] [Algebra R S] [Algebra.IsIntegral R S] (hRS : Function.Injective (algebraMap R S)) : IsField R ↔ IsField S := From dc528566839d9a65fe7c84f2c6d2fb17bb49ecbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Calle=20S=C3=B6nne?= Date: Thu, 17 Oct 2024 11:36:59 +0000 Subject: [PATCH 301/425] feat(Algebraize): Fix algebraize tactic (#17839) This fixes algebraize tactic to work better when it is pointing to a (possibly custom) constructor/theorem giving the algebra property from the corresponding ringhom property. As an application we apply this to the new `IsStandardSmooth`, `RingHom` property. --- .../RingTheory/RingHom/StandardSmooth.lean | 16 ++++-- Mathlib/Tactic/Algebraize.lean | 50 +++++++------------ test/algebraize.lean | 34 +++++++++++-- 3 files changed, 60 insertions(+), 40 deletions(-) diff --git a/Mathlib/RingTheory/RingHom/StandardSmooth.lean b/Mathlib/RingTheory/RingHom/StandardSmooth.lean index 8b47fbfe7bf3a1..4bc826b41f2c7c 100644 --- a/Mathlib/RingTheory/RingHom/StandardSmooth.lean +++ b/Mathlib/RingTheory/RingHom/StandardSmooth.lean @@ -31,19 +31,29 @@ namespace RingHom variable {R : Type u} {S : Type v} [CommRing R] [CommRing S] /-- A ring homomorphism `R →+* S` is standard smooth if `S` is standard smooth as `R`-algebra. -/ +@[algebraize RingHom.IsStandardSmooth.toAlgebra] def IsStandardSmooth (f : R →+* S) : Prop := @Algebra.IsStandardSmooth.{t, w} _ _ _ _ f.toAlgebra +/-- Helper lemma for the `algebraize` tactic.-/ +lemma IsStandardSmooth.toAlgebra {f : R →+* S} (hf : IsStandardSmooth.{t, w} f) : + @Algebra.IsStandardSmooth.{t, w} R S _ _ f.toAlgebra := hf + /-- A ring homomorphism `R →+* S` is standard smooth of relative dimension `n` if `S` is standard smooth of relative dimension `n` as `R`-algebra. -/ +@[algebraize RingHom.IsStandardSmoothOfRelativeDimension.toAlgebra] def IsStandardSmoothOfRelativeDimension (f : R →+* S) : Prop := @Algebra.IsStandardSmoothOfRelativeDimension.{t, w} n _ _ _ _ f.toAlgebra +/-- Helper lemma for the `algebraize` tactic.-/ +lemma IsStandardSmoothOfRelativeDimension.toAlgebra {f : R →+* S} + (hf : IsStandardSmoothOfRelativeDimension.{t, w} n f) : + @Algebra.IsStandardSmoothOfRelativeDimension.{t, w} n R S _ _ f.toAlgebra := hf + lemma IsStandardSmoothOfRelativeDimension.isStandardSmooth (f : R →+* S) (hf : IsStandardSmoothOfRelativeDimension.{t, w} n f) : IsStandardSmooth.{t, w} f := by algebraize [f] - letI : Algebra.IsStandardSmoothOfRelativeDimension.{t, w} n R S := hf exact Algebra.IsStandardSmoothOfRelativeDimension.isStandardSmooth n variable {n m} @@ -65,8 +75,6 @@ lemma IsStandardSmooth.comp {g : S →+* T} {f : R →+* S} IsStandardSmooth.{max t t', max w w'} (g.comp f) := by rw [IsStandardSmooth] algebraize [f, g, (g.comp f)] - letI : Algebra.IsStandardSmooth R S := hf - letI : Algebra.IsStandardSmooth S T := hg exact Algebra.IsStandardSmooth.trans.{t, t', w, w'} R S T lemma IsStandardSmoothOfRelativeDimension.comp {g : S →+* T} {f : R →+* S} @@ -75,8 +83,6 @@ lemma IsStandardSmoothOfRelativeDimension.comp {g : S →+* T} {f : R →+* S} IsStandardSmoothOfRelativeDimension.{max t t', max w w'} (n + m) (g.comp f) := by rw [IsStandardSmoothOfRelativeDimension] algebraize [f, g, (g.comp f)] - letI : Algebra.IsStandardSmoothOfRelativeDimension m R S := hf - letI : Algebra.IsStandardSmoothOfRelativeDimension n S T := hg exact Algebra.IsStandardSmoothOfRelativeDimension.trans m n R S T lemma isStandardSmooth_stableUnderComposition : diff --git a/Mathlib/Tactic/Algebraize.lean b/Mathlib/Tactic/Algebraize.lean index 96ceb855e0cb11..1218a802e04ae6 100644 --- a/Mathlib/Tactic/Algebraize.lean +++ b/Mathlib/Tactic/Algebraize.lean @@ -38,10 +38,12 @@ specified declaration should be one of the following: 1. An inductive type (i.e. the `Algebra` property itself), in this case it is assumed that the `RingHom` and the `Algebra` property are definitionally the same, and the tactic will construct the -`Algebra` property by giving the `RingHom` property as a term. -2. A constructor for the `Algebra` property. In this case it is assumed that the `RingHom` property -is the last argument of the constructor, and that no other explicit argument is needed. The tactic -then constructs the `Algebra` property by applying the constructor to the `RingHom` property. +`Algebra` property by giving the `RingHom` property as a term. Due to how this is peformed, we also +need to assume that the `Algebra` property can be constructed only from the homomorphism, so it can +not have any other explicit arguments. +2. A lemma (or constructor) proving the `Algebra` property from the `RingHom` property. In this case +it is assumed that the `RingHom` property is the final argument, and that no other explicit argument +is needed. The tactic then constructs the `Algebra` property by applying the lemma or constructor. Here are three examples of properties tagged with the `algebraize` attribute: ``` @@ -98,9 +100,9 @@ There are two cases for what declaration corresponding to this `Name` can be. 1. An inductive type (i.e. the `Algebra` property itself), in this case it is assumed that the `RingHom` and the `Algebra` property are definitionally the same, and the tactic will construct the `Algebra` property by giving the `RingHom` property as a term. -2. A constructor for the `Algebra` property. In this case it is assumed that the `RingHom` property -is the last argument of the constructor, and that no other explicit argument is needed. The tactic -then constructs the `Algebra` property by applying the constructor to the `RingHom` property. +2. A lemma (or constructor) proving the `Algebra` property from the `RingHom` property. In this case +it is assumed that the `RingHom` property is the final argument, and that no other explicit argument +is needed. The tactic then constructs the `Algebra` property by applying the lemma or constructor. Finally, if no argument is provided to the `algebraize` attribute, it is assumed that the tagged declaration has name `RingHom.Property` and that the corresponding `Algebra` property has name @@ -171,7 +173,8 @@ def addProperties (t : Array Expr) : TacticM Unit := withMainContext do let (nm, args) := decl.type.getAppFnArgs -- Check if the type of the current hypothesis has been tagged with the `algebraize` attribute match Attr.algebraizeAttr.getParam? (← getEnv) nm with - -- If it has, `p` will be the name of the corresponding `Algebra` property (or a constructor) + -- If it has, `p` will either be the name of the corresponding `Algebra` property, or a + -- lemma/constructor. | some p => -- The last argument of the `RingHom` property is assumed to be `f` let f := args[args.size - 1]! @@ -184,42 +187,27 @@ def addProperties (t : Array Expr) : TacticM Unit := withMainContext do /- If the attribute points to the corresponding `Algebra` property itself, we assume that it is definitionally the same as the `RingHom` property. Then, we just need to construct its type and the local declaration will already give a valid term. -/ - match cinfo with - | .inductInfo _ => + if cinfo.isInductive then let pargs := pargs.set! 0 args[0]! let pargs := pargs.set! 1 args[1]! let tp ← mkAppOptM p pargs -- This should be the type `Algebra.Property A B` unless (← synthInstance? tp).isSome do liftMetaTactic fun mvarid => do let nm ← mkFreshBinderNameForTactic `algebraizeInst - let mvar ← mvarid.define nm tp decl.toExpr - let (_, mvar) ← mvar.intro1P + let (_, mvar) ← mvarid.note nm decl.toExpr tp return [mvar] - /- Otherwise, the attribute points to a constructor of the `Algebra` property. In this case, - we assume that the `RingHom` property is the last argument of the constructor (and that - this is all we need to supply explicitly). -/ - | .ctorInfo ctor => - -- construct the desired value + /- Otherwise, the attribute points to a lemma or a constructor for the `Algebra` property. + In this case, we assume that the `RingHom` property is the last argument of the lemma or + constructor (and that this is all we need to supply explicitly). -/ + else let pargs := pargs.set! (n - 1) decl.toExpr let val ← mkAppOptM p pargs - - -- construct the expected type - let alg ← mkAppOptM ``Algebra #[args[0]!, args[1]!, none, none] - let algInst := (← synthInstance? alg) - let mut argsType := Array.mkArray (ctor.numParams) (none : Option Expr) - argsType := argsType.set! 0 args[0]! - argsType := argsType.set! 1 args[1]! - argsType := argsType.set! (ctor.numParams - 1) algInst - let tp := ← mkAppOptM ctor.induct argsType - + let tp ← inferType val unless (← synthInstance? tp).isSome do liftMetaTactic fun mvarid => do let nm ← mkFreshBinderNameForTactic `algebraizeInst - let mvar ← mvarid.define nm tp val - let (_, mvar) ← mvar.intro1P + let (_, mvar) ← mvarid.note nm val return [mvar] - | _ => logError s!"bad argument to `algebraize` attribute: {p}. \ - Only supporting inductive types or constructors." | none => return /-- Configuration for `algebraize`. -/ diff --git a/test/algebraize.lean b/test/algebraize.lean index c2aa17892ab571..1ccd695d0b9205 100644 --- a/test/algebraize.lean +++ b/test/algebraize.lean @@ -38,6 +38,26 @@ an example. -/ def RingHom.testProperty3 {A B : Type*} [CommRing A] [CommRing B] (f : A →+* B) : Prop := f.testProperty1 +/- Test property for when the `RingHom` (and `Algebra`) property have an extra explicit argument, +and hence needs to be created through a lemma. See e.g. +`Algebra.IsStandardSmoothOfRelativeDimension` for an example. -/ +class Algebra.testProperty4 (n : ℕ) (A B : Type*) [CommRing A] [CommRing B] [Algebra A B] : Prop where + out : ∀ m, n = m + +/- Test property for when the `RingHom` (and `Algebra`) property have an extra explicit argument, +and hence needs to be created through a lemma. See e.g. +`Algebra.IsStandardSmoothOfRelativeDimension` for an example. -/ +@[algebraize testProperty4.toAlgebra] +def RingHom.testProperty4 (n : ℕ) {A B : Type*} [CommRing A] [CommRing B] (_ : A →+* B) : Prop := + ∀ m, n = m + +lemma testProperty4.toAlgebra (n : ℕ) {A B : Type*} [CommRing A] [CommRing B] (f : A →+* B) + (hf : f.testProperty4 n) : + letI : Algebra A B := f.toAlgebra + Algebra.testProperty4 n A B := + letI : Algebra A B := f.toAlgebra + { out := hf } + end example_definitions set_option tactic.hygienic false @@ -79,17 +99,23 @@ example (A B C : Type*) [CommRing A] [CommRing B] [CommRing C] (f : A →+* B) ( example (A B : Type*) [CommRing A] [CommRing B] (f : A →+* B) (hf : f.testProperty1) : True := by algebraize [f] - guard_hyp algebraizeInst : Algebra.testProperty1 A B := hf + guard_hyp algebraizeInst : Algebra.testProperty1 A B trivial example (A B : Type*) [CommRing A] [CommRing B] (f : A →+* B) (hf : f.testProperty2) : True := by algebraize [f] - guard_hyp algebraizeInst : Module.testProperty2 A B := hf + guard_hyp algebraizeInst : Module.testProperty2 A B trivial example (A B : Type*) [CommRing A] [CommRing B] (f : A →+* B) (hf : f.testProperty3) : True := by algebraize [f] - guard_hyp algebraizeInst : Algebra.testProperty3 A B := ⟨hf⟩ + guard_hyp algebraizeInst : Algebra.testProperty3 A B + trivial + +example (n : ℕ) (A B : Type*) [CommRing A] [CommRing B] (f : A →+* B) (hf : f.testProperty4 n) : + True := by + algebraize [f] + guard_hyp algebraizeInst : Algebra.testProperty4 n A B trivial /-- Synthesize from morphism property of a composition (and check that tower is also synthesized). -/ @@ -100,6 +126,6 @@ example (A B C : Type*) [CommRing A] [CommRing B] [CommRing C] (f : A →+* B) ( fail_if_success have h : IsScalarTower A B C := inferInstance algebraize [f, g, g.comp f] - guard_hyp algebraizeInst : Algebra.testProperty1 A C := hfg + guard_hyp algebraizeInst : Algebra.testProperty1 A C guard_hyp scalarTowerInst := IsScalarTower.of_algebraMap_eq' rfl trivial From b3a20e86b47ce1c413542d452939b5ec405cfcd0 Mon Sep 17 00:00:00 2001 From: "Anne C.A. Baanen" Date: Thu, 17 Oct 2024 14:06:40 +0200 Subject: [PATCH 302/425] Shake --- Mathlib/Algebra/Group/Pi/Basic.lean | 1 - Mathlib/Data/List/Basic.lean | 1 + Mathlib/Data/Prod/Lex.lean | 1 + Mathlib/Order/Basic.lean | 2 +- 4 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Group/Pi/Basic.lean b/Mathlib/Algebra/Group/Pi/Basic.lean index b455b861786e4c..8a1a493a850368 100644 --- a/Mathlib/Algebra/Group/Pi/Basic.lean +++ b/Mathlib/Algebra/Group/Pi/Basic.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Simon Hudon, Patrick Massot, Eric Wieser -/ import Mathlib.Algebra.Group.Defs -import Mathlib.Data.Prod.Basic import Mathlib.Data.Sum.Basic import Mathlib.Logic.Unique import Mathlib.Tactic.Spread diff --git a/Mathlib/Data/List/Basic.lean b/Mathlib/Data/List/Basic.lean index 05a058e3e8c827..865e3ab7b71bd4 100644 --- a/Mathlib/Data/List/Basic.lean +++ b/Mathlib/Data/List/Basic.lean @@ -8,6 +8,7 @@ import Mathlib.Data.Nat.Defs import Mathlib.Data.Option.Basic import Mathlib.Data.List.Defs import Mathlib.Data.List.Monad +import Mathlib.Data.Prod.Basic import Mathlib.Logic.OpClass import Mathlib.Logic.Unique import Mathlib.Order.Basic diff --git a/Mathlib/Data/Prod/Lex.lean b/Mathlib/Data/Prod/Lex.lean index b0271fecee021d..d2fe2c2018da76 100644 --- a/Mathlib/Data/Prod/Lex.lean +++ b/Mathlib/Data/Prod/Lex.lean @@ -3,6 +3,7 @@ Copyright (c) 2019 Kim Morrison. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Kim Morrison, Minchao Wu -/ +import Mathlib.Data.Prod.Basic import Mathlib.Order.BoundedOrder /-! diff --git a/Mathlib/Order/Basic.lean b/Mathlib/Order/Basic.lean index 65028f828718d7..5b4d2f16800844 100644 --- a/Mathlib/Order/Basic.lean +++ b/Mathlib/Order/Basic.lean @@ -3,12 +3,12 @@ Copyright (c) 2014 Jeremy Avigad. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Jeremy Avigad, Mario Carneiro -/ -import Mathlib.Data.Prod.Basic import Mathlib.Data.Subtype import Mathlib.Order.Defs import Mathlib.Order.Notation import Mathlib.Tactic.Spread import Mathlib.Tactic.Convert +import Mathlib.Tactic.Inhabit import Mathlib.Tactic.SimpRw /-! From 9266f86d046ce02c551f1d9fe9f425dabb44476f Mon Sep 17 00:00:00 2001 From: Jujian Zhang Date: Thu, 17 Oct 2024 12:44:26 +0000 Subject: [PATCH 303/425] feat(RingTheory/Flat/FaithfullyFlat): definition of faithfully flat module (#17805) 1. $M$ is $R$-faithfully flat iff $M$ is flat and $IM \ne M$ for all maximal ideal $I \le R$ 2. prove that this is equivalent to that $M$ is flat and $M \otimes N \ne 0$ whenever $N \ne 0$ --- Mathlib.lean | 1 + Mathlib/RingTheory/Flat/FaithfullyFlat.lean | 168 ++++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 Mathlib/RingTheory/Flat/FaithfullyFlat.lean diff --git a/Mathlib.lean b/Mathlib.lean index 0439d6b8d5e5fb..8c55dc3701c47c 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3941,6 +3941,7 @@ import Mathlib.RingTheory.Flat.Algebra import Mathlib.RingTheory.Flat.Basic import Mathlib.RingTheory.Flat.CategoryTheory import Mathlib.RingTheory.Flat.EquationalCriterion +import Mathlib.RingTheory.Flat.FaithfullyFlat import Mathlib.RingTheory.Flat.Stability import Mathlib.RingTheory.FractionalIdeal.Basic import Mathlib.RingTheory.FractionalIdeal.Extended diff --git a/Mathlib/RingTheory/Flat/FaithfullyFlat.lean b/Mathlib/RingTheory/Flat/FaithfullyFlat.lean new file mode 100644 index 00000000000000..17c82bb7c375d6 --- /dev/null +++ b/Mathlib/RingTheory/Flat/FaithfullyFlat.lean @@ -0,0 +1,168 @@ +/- +Copyright (c) 2024 Judith Ludwig, Florent Schaffhauser. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Judith Ludwig, Florent Schaffhauser, Yunzhou Xie, Jujian Zhang +-/ + +import Mathlib.RingTheory.Flat.Basic +import Mathlib.LinearAlgebra.TensorProduct.Quotient + +/-! +# Faithfully flat modules + +A module `M` over a commutative ring `R` is *faithfully flat* if it is flat and `IM ≠ M` whenever +`I` is a maximal ideal of `R`. + +## Main declaration + +- `Module.FaithfullyFlat`: the predicate asserting that an `R`-module `M` is faithfully flat. + +## Main theorems + +- `Module.FaithfullyFlat.iff_flat_and_proper_ideal`: an `R`-module `M` is faithfully flat iff it is + flat and for all proper ideals `I` of `R`, `I • M ≠ M`. +- `Module.FaithfullyFlat.iff_flat_and_rTensor_faithful`: an `R`-module `M` is faithfully flat iff it + is flat and tensoring with `M` is faithful, i.e. `N ≠ 0` implies `N ⊗ M ≠ 0`. +- `Module.FaithfullyFlat.iff_flat_and_lTensor_faithful`: an `R`-module `M` is faithfully flat iff it + is flat and tensoring with `M` is faithful, i.e. `N ≠ 0` implies `M ⊗ N ≠ 0`. + +- `Module.FaithfullyFlat.self`: the `R`-module `R` is faithfully flat. + +-/ + +universe u v + +open TensorProduct + +namespace Module + +variable (R : Type u) (M : Type v) [CommRing R] [AddCommGroup M] [Module R M] + +/-- +A module `M` over a commutative ring `R` is *faithfully flat* if it is flat and, +for all `R`-module homomorphism `f : N → N'` such that `id ⊗ f = 0`, we have `f = 0`. +-/ +@[mk_iff] class FaithfullyFlat extends Module.Flat R M : Prop where + submodule_ne_top : ∀ ⦃m : Ideal R⦄ (_ : Ideal.IsMaximal m), m • (⊤ : Submodule R M) ≠ ⊤ + +namespace FaithfullyFlat +instance self : FaithfullyFlat R R where + submodule_ne_top m h r := Ideal.eq_top_iff_one _ |>.not.1 h.ne_top <| by + simpa using show 1 ∈ (m • ⊤ : Ideal R) from r.symm ▸ ⟨⟩ + +section proper_ideal + +lemma iff_flat_and_proper_ideal : + FaithfullyFlat R M ↔ + (Flat R M ∧ ∀ (I : Ideal R), I ≠ ⊤ → I • (⊤ : Submodule R M) ≠ ⊤) := by + rw [faithfullyFlat_iff] + refine ⟨fun ⟨flat, h⟩ => ⟨flat, fun I hI r => ?_⟩, fun h => ⟨h.1, fun m hm => h.2 _ hm.ne_top⟩⟩ + obtain ⟨m, hm, le⟩ := I.exists_le_maximal hI + exact h hm <| eq_top_iff.2 <| show ⊤ ≤ m • ⊤ from r ▸ Submodule.smul_mono le (by simp [r]) + +lemma iff_flat_and_ideal_smul_eq_top : + FaithfullyFlat R M ↔ + (Flat R M ∧ ∀ (I : Ideal R), I • (⊤ : Submodule R M) = ⊤ → I = ⊤) := + iff_flat_and_proper_ideal R M |>.trans <| and_congr_right_iff.2 fun _ => iff_of_eq <| + forall_congr fun I => eq_iff_iff.2 <| by tauto + +end proper_ideal + +section faithful + +instance rTensor_nontrivial + [fl: FaithfullyFlat R M] (N : Type*) [AddCommGroup N] [Module R N] [Nontrivial N] : + Nontrivial (N ⊗[R] M) := by + obtain ⟨n, hn⟩ := nontrivial_iff_exists_ne (0 : N) |>.1 inferInstance + let I := (Submodule.span R {n}).annihilator + by_cases I_ne_top : I = ⊤ + · rw [Ideal.eq_top_iff_one, Submodule.mem_annihilator_span_singleton, one_smul] at I_ne_top + contradiction + let inc : R ⧸ I →ₗ[R] N := Submodule.liftQ _ ((LinearMap.lsmul R N).flip n) <| fun r hr => by + simpa only [LinearMap.mem_ker, LinearMap.flip_apply, LinearMap.lsmul_apply, + Submodule.mem_annihilator_span_singleton, I] using hr + have injective_inc : Function.Injective inc := LinearMap.ker_eq_bot.1 <| eq_bot_iff.2 <| by + intro r hr + induction r using Quotient.inductionOn' with | h r => + simpa only [Submodule.Quotient.mk''_eq_mk, Submodule.mem_bot, Submodule.Quotient.mk_eq_zero, + Submodule.mem_annihilator_span_singleton, LinearMap.mem_ker, Submodule.liftQ_apply, + LinearMap.flip_apply, LinearMap.lsmul_apply, I, inc] using hr + have ne_top := iff_flat_and_proper_ideal R M |>.1 fl |>.2 I I_ne_top + refine subsingleton_or_nontrivial _ |>.resolve_left fun rid => ?_ + exact False.elim <| ne_top <| Submodule.subsingleton_quotient_iff_eq_top.1 <| + Function.Injective.comp (g := LinearMap.rTensor M inc) + (fl.toFlat.rTensor_preserves_injective_linearMap inc injective_inc) + ((quotTensorEquivQuotSMul M I).symm.injective) |>.subsingleton + +instance lTensor_nontrivial + [FaithfullyFlat R M] (N : Type*) [AddCommGroup N] [Module R N] [Nontrivial N] : + Nontrivial (M ⊗[R] N) := + TensorProduct.comm R M N |>.toEquiv.nontrivial + +lemma rTensor_reflects_triviality + [FaithfullyFlat R M] (N : Type*) [AddCommGroup N] [Module R N] + [h : Subsingleton (N ⊗[R] M)] : Subsingleton N := by + revert h; change _ → _; contrapose + simp only [not_subsingleton_iff_nontrivial] + intro h + infer_instance + +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 + apply rTensor_reflects_triviality R M + +attribute [-simp] Ideal.Quotient.mk_eq_mk in +lemma iff_flat_and_rTensor_faithful : + FaithfullyFlat R M ↔ + (Flat R M ∧ + ∀ (N : Type max u v) [AddCommGroup N] [Module R N], + Nontrivial N → Nontrivial (N ⊗[R] M)) := by + 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) := + (congr (ULift.moduleEquiv : ULift (R ⧸ m) ≃ₗ[R] R ⧸ m) + (LinearEquiv.refl R M)).symm.toEquiv.nontrivial + have := (quotTensorEquivQuotSMul M m).toEquiv.symm.nontrivial + haveI H : Subsingleton (M ⧸ m • (⊤ : Submodule R M)) := by + rwa [Submodule.subsingleton_quotient_iff_eq_top] + rw [← not_nontrivial_iff_subsingleton] at H + contradiction + +lemma iff_flat_and_rTensor_reflects_triviality : + FaithfullyFlat R M ↔ + (Flat R M ∧ + ∀ (N : Type max u v) [AddCommGroup N] [Module R N], + Subsingleton (N ⊗[R] M) → Subsingleton N) := + iff_flat_and_rTensor_faithful R M |>.trans <| and_congr_right_iff.2 fun _ => iff_of_eq <| + forall_congr fun N => forall_congr fun _ => forall_congr fun _ => iff_iff_eq.1 <| by + simp only [← not_subsingleton_iff_nontrivial]; tauto + +lemma iff_flat_and_lTensor_faithful : + FaithfullyFlat R M ↔ + (Flat R M ∧ + ∀ (N : Type max u v) [AddCommGroup N] [Module R N], + Nontrivial N → Nontrivial (M ⊗[R] N)) := + iff_flat_and_rTensor_faithful R M |>.trans + ⟨fun ⟨flat, faithful⟩ => ⟨flat, fun N _ _ _ => + letI := faithful N inferInstance; (TensorProduct.comm R M N).toEquiv.nontrivial⟩, + fun ⟨flat, faithful⟩ => ⟨flat, fun N _ _ _ => + letI := faithful N inferInstance; (TensorProduct.comm R M N).symm.toEquiv.nontrivial⟩⟩ + +lemma iff_flat_and_lTensor_reflects_triviality : + FaithfullyFlat R M ↔ + (Flat R M ∧ + ∀ (N : Type max u v) [AddCommGroup N] [Module R N], + Subsingleton (M ⊗[R] N) → Subsingleton N) := + iff_flat_and_lTensor_faithful R M |>.trans <| and_congr_right_iff.2 fun _ => iff_of_eq <| + forall_congr fun N => forall_congr fun _ => forall_congr fun _ => iff_iff_eq.1 <| by + simp only [← not_subsingleton_iff_nontrivial]; tauto + +end faithful + +end FaithfullyFlat + +end Module From fa6b2491c26ecf81fcfe648152d07d9faff7a9f0 Mon Sep 17 00:00:00 2001 From: Yuma Mizuno Date: Thu, 17 Oct 2024 12:44:27 +0000 Subject: [PATCH 304/425] chore(LinearAlgebra/LinearIndependent): generalize a section from rings to semirings (#17864) Co-authored-by: Eric Wieser --- Mathlib/LinearAlgebra/LinearIndependent.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/LinearAlgebra/LinearIndependent.lean b/Mathlib/LinearAlgebra/LinearIndependent.lean index c198ef6a8918de..ccd018f0d3ddf5 100644 --- a/Mathlib/LinearAlgebra/LinearIndependent.lean +++ b/Mathlib/LinearAlgebra/LinearIndependent.lean @@ -1183,8 +1183,8 @@ end Module section Nontrivial -variable [Ring R] [Nontrivial R] [AddCommGroup M] [AddCommGroup M'] -variable [Module R M] [NoZeroSMulDivisors R M] [Module R M'] +variable [Semiring R] [Nontrivial R] [AddCommMonoid M] +variable [Module R M] [NoZeroSMulDivisors R M] variable {s t : Set M} theorem linearIndependent_unique_iff (v : ι → M) [Unique ι] : From 0c022ea19db4295764843578cfbcb3aae9347bbb Mon Sep 17 00:00:00 2001 From: Scott Carnahan <128885296+ScottCarnahan@users.noreply.github.com> Date: Thu, 17 Oct 2024 13:07:51 +0000 Subject: [PATCH 305/425] feat (RingTheory/HahnSeries) : coefficient-wise map (#16164) This PR introduces `HahnSeries.map` which applies a zero-preserving map to each coefficient. We more or less copy the `Polynomial.map` API. --- Mathlib/RingTheory/HahnSeries/Addition.lean | 39 ++++++++++++++----- Mathlib/RingTheory/HahnSeries/Basic.lean | 29 +++++++++++--- .../RingTheory/HahnSeries/Multiplication.lean | 26 ++++++++++++- .../RingTheory/HahnSeries/PowerSeries.lean | 6 +-- 4 files changed, 81 insertions(+), 19 deletions(-) diff --git a/Mathlib/RingTheory/HahnSeries/Addition.lean b/Mathlib/RingTheory/HahnSeries/Addition.lean index 3daeb21892dcef..255b47ebace236 100644 --- a/Mathlib/RingTheory/HahnSeries/Addition.lean +++ b/Mathlib/RingTheory/HahnSeries/Addition.lean @@ -28,7 +28,7 @@ open scoped Classical noncomputable section -variable {Γ R : Type*} +variable {Γ Γ' R S U V : Type*} namespace HahnSeries @@ -66,6 +66,10 @@ theorem add_coeff' {x y : HahnSeries Γ R} : (x + y).coeff = x.coeff + y.coeff : theorem add_coeff {x y : HahnSeries Γ R} {a : Γ} : (x + y).coeff a = x.coeff a + y.coeff a := rfl +@[simp] +protected lemma map_add [AddMonoid S] (f : R →+ S) {x y : HahnSeries Γ R} : + ((x + y).map f : HahnSeries Γ S) = x.map f + y.map f := by + ext; simp /-- `addOppositeEquiv` is an additive monoid isomorphism between Hahn series over `Γ` with coefficients in the opposite additive monoid `Rᵃᵒᵖ` @@ -210,7 +214,7 @@ def coeff.addMonoidHom (g : Γ) : HahnSeries Γ R →+ R where section Domain -variable {Γ' : Type*} [PartialOrder Γ'] +variable [PartialOrder Γ'] theorem embDomain_add (f : Γ ↪o Γ') (x y : HahnSeries Γ R) : embDomain f (x + y) = embDomain f x + embDomain f y := by @@ -261,12 +265,9 @@ theorem support_neg {x : HahnSeries Γ R} : (-x).support = x.support := by simp @[simp] -theorem sub_coeff' {x y : HahnSeries Γ R} : (x - y).coeff = x.coeff - y.coeff := by - ext - simp [sub_eq_add_neg] - -theorem sub_coeff {x y : HahnSeries Γ R} {a : Γ} : (x - y).coeff a = x.coeff a - y.coeff a := by - simp +protected lemma map_neg [AddGroup S] (f : R →+ S) {x : HahnSeries Γ R} : + ((-x).map f : HahnSeries Γ S) = -(x.map f) := by + ext; simp theorem orderTop_neg {x : HahnSeries Γ R} : (-x).orderTop = x.orderTop := by simp only [orderTop, support_neg, neg_eq_zero] @@ -277,6 +278,19 @@ theorem order_neg [Zero Γ] {f : HahnSeries Γ R} : (-f).order = f.order := by · simp only [hf, neg_zero] simp only [order, support_neg, neg_eq_zero] +@[simp] +theorem sub_coeff' {x y : HahnSeries Γ R} : (x - y).coeff = x.coeff - y.coeff := by + ext + simp [sub_eq_add_neg] + +theorem sub_coeff {x y : HahnSeries Γ R} {a : Γ} : (x - y).coeff a = x.coeff a - y.coeff a := by + simp + +@[simp] +protected lemma map_sub [AddGroup S] (f : R →+ S) {x y : HahnSeries Γ R} : + ((x - y).map f : HahnSeries Γ S) = x.map f - y.map f := by + ext; simp + theorem min_orderTop_le_orderTop_sub {Γ} [LinearOrder Γ] {x y : HahnSeries Γ R} : min x.orderTop y.orderTop ≤ (x - y).orderTop := by rw [sub_eq_add_neg, ← orderTop_neg (x := y)] @@ -377,7 +391,7 @@ end DistribMulAction section Module -variable [PartialOrder Γ] [Semiring R] {V : Type*} [AddCommMonoid V] [Module R V] +variable [PartialOrder Γ] [Semiring R] [AddCommMonoid V] [Module R V] instance : Module R (HahnSeries Γ V) := { inferInstanceAs (DistribMulAction R (HahnSeries Γ V)) with @@ -401,9 +415,14 @@ def single.linearMap (a : Γ) : V →ₗ[R] HahnSeries Γ V := def coeff.linearMap (g : Γ) : HahnSeries Γ V →ₗ[R] V := { coeff.addMonoidHom g with map_smul' := fun _ _ => rfl } +@[simp] +protected lemma map_smul [AddCommMonoid U] [Module R U] (f : U →ₗ[R] V) {r : R} + {x : HahnSeries Γ U} : (r • x).map f = r • ((x.map f) : HahnSeries Γ V) := by + ext; simp + section Domain -variable {Γ' : Type*} [PartialOrder Γ'] +variable [PartialOrder Γ'] theorem embDomain_smul (f : Γ ↪o Γ') (r : R) (x : HahnSeries Γ R) : embDomain f (r • x) = r • embDomain f x := by diff --git a/Mathlib/RingTheory/HahnSeries/Basic.lean b/Mathlib/RingTheory/HahnSeries/Basic.lean index 29586b2758fadb..7c4261e42f42cf 100644 --- a/Mathlib/RingTheory/HahnSeries/Basic.lean +++ b/Mathlib/RingTheory/HahnSeries/Basic.lean @@ -25,6 +25,8 @@ in the file `RingTheory/LaurentSeries`. coefficient if `x ≠ 0`, and is `⊤` when `x = 0`. * `order x` is a minimal element of `Γ` where `x` has a nonzero coefficient if `x ≠ 0`, and is zero when `x = 0`. +* `map` takes each coefficient of a Hahn series to its target under a zero-preserving map. +* `embDomain` preserves coefficients, but embeds the index set `Γ` in a larger poset. ## References - [J. van der Hoeven, *Operators on Generalized Power Series*][van_der_hoeven] @@ -43,7 +45,7 @@ structure HahnSeries (Γ : Type*) (R : Type*) [PartialOrder Γ] [Zero R] where coeff : Γ → R isPWO_support' : (Function.support coeff).IsPWO -variable {Γ : Type*} {R : Type*} +variable {Γ Γ' R S : Type*} namespace HahnSeries @@ -108,8 +110,20 @@ nonrec theorem support_nonempty_iff {x : HahnSeries Γ R} : x.support.Nonempty theorem support_eq_empty_iff {x : HahnSeries Γ R} : x.support = ∅ ↔ x = 0 := Function.support_eq_empty_iff.trans coeff_fun_eq_zero_iff +/-- The map of Hahn series induced by applying a zero-preserving map to each coefficient. -/ +@[simps] +def map [Zero S] (x : HahnSeries Γ R) {F : Type*} [FunLike F R S] [ZeroHomClass F R S] (f : F) : + HahnSeries Γ S where + coeff g := f (x.coeff g) + isPWO_support' := x.isPWO_support.mono <| Function.support_comp_subset (ZeroHomClass.map_zero f) _ + +@[simp] +protected lemma map_zero [Zero S] (f : ZeroHom R S) : + (0 : HahnSeries Γ R).map f = 0 := by + ext; simp + /-- Change a HahnSeries with coefficients in HahnSeries to a HahnSeries on the Lex product. -/ -def ofIterate {Γ' : Type*} [PartialOrder Γ'] (x : HahnSeries Γ (HahnSeries Γ' R)) : +def ofIterate [PartialOrder Γ'] (x : HahnSeries Γ (HahnSeries Γ' R)) : HahnSeries (Γ ×ₗ Γ') R where coeff := fun g => coeff (coeff x g.1) g.2 isPWO_support' := by @@ -125,7 +139,7 @@ lemma mk_eq_zero (f : Γ → R) (h) : HahnSeries.mk f h = 0 ↔ f = 0 := by rfl /-- Change a Hahn series on a lex product to a Hahn series with coefficients in a Hahn series. -/ -def toIterate {Γ' : Type*} [PartialOrder Γ'] (x : HahnSeries (Γ ×ₗ Γ') R) : +def toIterate [PartialOrder Γ'] (x : HahnSeries (Γ ×ₗ Γ') R) : HahnSeries Γ (HahnSeries Γ' R) where coeff := fun g => { coeff := fun g' => coeff x (g, g') @@ -141,7 +155,7 @@ def toIterate {Γ' : Type*} [PartialOrder Γ'] (x : HahnSeries (Γ ×ₗ Γ') R) /-- The equivalence between iterated Hahn series and Hahn series on the lex product. -/ @[simps] -def iterateEquiv {Γ' : Type*} [PartialOrder Γ'] : +def iterateEquiv [PartialOrder Γ'] : HahnSeries Γ (HahnSeries Γ' R) ≃ HahnSeries (Γ ×ₗ Γ') R where toFun := ofIterate invFun := toIterate @@ -194,6 +208,11 @@ theorem single_ne_zero (h : r ≠ 0) : single a r ≠ 0 := fun con => theorem single_eq_zero_iff {a : Γ} {r : R} : single a r = 0 ↔ r = 0 := map_eq_zero_iff _ <| single_injective a +@[simp] +protected lemma map_single [Zero S] (f : ZeroHom R S) : (single a r).map f = single a (f r) := by + ext g + by_cases h : g = a <;> simp [h] + instance [Nonempty Γ] [Nontrivial R] : Nontrivial (HahnSeries Γ R) := ⟨by obtain ⟨r, s, rs⟩ := exists_pair_ne R @@ -364,7 +383,7 @@ end Order section Domain -variable {Γ' : Type*} [PartialOrder Γ'] +variable [PartialOrder Γ'] open Classical in /-- Extends the domain of a `HahnSeries` by an `OrderEmbedding`. -/ diff --git a/Mathlib/RingTheory/HahnSeries/Multiplication.lean b/Mathlib/RingTheory/HahnSeries/Multiplication.lean index 11ac4db05c9d90..8f62c2deef2dcc 100644 --- a/Mathlib/RingTheory/HahnSeries/Multiplication.lean +++ b/Mathlib/RingTheory/HahnSeries/Multiplication.lean @@ -37,7 +37,7 @@ open Finset Function Pointwise noncomputable section -variable {Γ Γ' R V : Type*} +variable {Γ Γ' R S V : Type*} namespace HahnSeries @@ -74,6 +74,12 @@ theorem order_one [MulZeroOneClass R] : order (1 : HahnSeries Γ R) = 0 := by theorem leadingCoeff_one [MulZeroOneClass R] : (1 : HahnSeries Γ R).leadingCoeff = 1 := by simp [leadingCoeff_eq] +@[simp] +protected lemma map_one [MonoidWithZero R] [MonoidWithZero S] (f : R →*₀ S) : + (1 : HahnSeries Γ R).map f = (1 : HahnSeries Γ S) := by + ext g + by_cases h : g = 0 <;> simp [h] + end HahnSeries /-- We introduce a type alias for `HahnSeries` in order to work with scalar multiplication by @@ -348,6 +354,19 @@ theorem mul_coeff [NonUnitalNonAssocSemiring R] {x y : HahnSeries Γ R} {a : Γ} ∑ ij ∈ addAntidiagonal 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) + {x y : HahnSeries Γ R} : (x * y).map f = (x.map f : HahnSeries Γ S) * (y.map f) := by + ext + simp only [map_coeff, mul_coeff, ZeroHom.coe_coe, 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, ZeroHom.coe_coe, 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, ZeroHom.coe_coe, 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)) + · exact mul_eq_zero_of_right (f (x.coeff gh.1)) (hz h) + theorem mul_coeff_left' [NonUnitalNonAssocSemiring R] {x y : HahnSeries Γ R} {a : Γ} {s : Set Γ} (hs : s.IsPWO) (hxs : x.support ⊆ s) : (x * y).coeff a = @@ -642,6 +661,11 @@ theorem C_zero : C (0 : R) = (0 : HahnSeries Γ R) := theorem C_one : C (1 : R) = (1 : HahnSeries Γ R) := C.map_one +theorem map_C [NonAssocSemiring S] (a : R) (f : R →+* S) : + ((C a).map f : HahnSeries Γ S) = C (f a) := by + ext g + by_cases h : g = 0 <;> simp [h] + theorem C_injective : Function.Injective (C : R → HahnSeries Γ R) := by intro r s rs rw [HahnSeries.ext_iff, funext_iff] at rs diff --git a/Mathlib/RingTheory/HahnSeries/PowerSeries.lean b/Mathlib/RingTheory/HahnSeries/PowerSeries.lean index 094a71acddd64e..7a70d9e119bf87 100644 --- a/Mathlib/RingTheory/HahnSeries/PowerSeries.lean +++ b/Mathlib/RingTheory/HahnSeries/PowerSeries.lean @@ -37,7 +37,7 @@ open Finset Function Pointwise Polynomial noncomputable section -variable {Γ : Type*} {R : Type*} +variable {Γ R : Type*} namespace HahnSeries @@ -113,7 +113,7 @@ theorem ofPowerSeries_C (r : R) : ofPowerSeries Γ R (PowerSeries.C R r) = HahnS single_coeff] split_ifs with hn · subst hn - convert @embDomain_coeff ℕ R _ _ Γ _ _ _ 0 <;> simp + convert embDomain_coeff (a := 0) <;> simp · rw [embDomain_notin_image_support] simp only [not_exists, Set.mem_image, toPowerSeries_symm_apply_coeff, mem_support, PowerSeries.coeff_C] @@ -126,7 +126,7 @@ theorem ofPowerSeries_X : ofPowerSeries Γ R PowerSeries.X = single 1 1 := by simp only [single_coeff, ofPowerSeries_apply, RingHom.coe_mk] split_ifs with hn · rw [hn] - convert @embDomain_coeff ℕ R _ _ Γ _ _ _ 1 <;> simp + convert embDomain_coeff (a := 1) <;> simp · rw [embDomain_notin_image_support] simp only [not_exists, Set.mem_image, toPowerSeries_symm_apply_coeff, mem_support, PowerSeries.coeff_X] From a0d3126672d97e23df807041f3960f375244c9a6 Mon Sep 17 00:00:00 2001 From: Andrew Yang Date: Thu, 17 Oct 2024 13:07:53 +0000 Subject: [PATCH 306/425] feat(RingTheory/Kaehler): the first homology of the cotangent complex (#17559) Co-authored-by: Andrew Yang <36414270+erdOne@users.noreply.github.com> --- .../RingTheory/Kaehler/CotangentComplex.lean | 132 ++++++++++++++++-- 1 file changed, 122 insertions(+), 10 deletions(-) diff --git a/Mathlib/RingTheory/Kaehler/CotangentComplex.lean b/Mathlib/RingTheory/Kaehler/CotangentComplex.lean index 75e250102f8fe6..cd899098a4f462 100644 --- a/Mathlib/RingTheory/Kaehler/CotangentComplex.lean +++ b/Mathlib/RingTheory/Kaehler/CotangentComplex.lean @@ -22,6 +22,10 @@ defined by `I`), we may define the (naive) cotangent complex `I/I² → ⨁ᵢ S - `Algebra.Generators.exact_cotangentComplex_toKaehler`: `I/I² → ⨁ᵢ S dxᵢ → Ω[S/R]` is exact. - `Algebra.Generators.Hom.Sub`: If `f` and `g` are two maps between presentations, `f - g` induces a map `⨁ᵢ S dxᵢ → I/I²` that makes `f` and `g` homotopic. +- `Algebra.Generators.H1Cotangent`: The first homology of the (naive) cotangent complex + of `S` over `R`, induced by a given presentation. +- `Algebra.H1Cotangent`: `H¹(L_{S/R})`, + the first homology of the (naive) cotangent complex of `S` over `R`. -/ open KaehlerDifferential TensorProduct MvPolynomial @@ -83,6 +87,16 @@ attribute [local instance] SMulCommClass.of_commMonoid variable {P P'} +universe w'' u'' v'' + +variable {R'' : Type u''} {S'' : Type v''} [CommRing R''] [CommRing S''] [Algebra R'' S''] +variable {P'' : Generators.{w''} R'' S''} +variable [Algebra R R''] [Algebra S S''] [Algebra R S''] + [IsScalarTower R R'' S''] [IsScalarTower R S S''] +variable [Algebra R' R''] [Algebra S' S''] [Algebra R' S''] + [IsScalarTower R' R'' S''] [IsScalarTower R' S' S''] +variable [IsScalarTower S S' S''] + namespace CotangentSpace /-- @@ -114,16 +128,6 @@ lemma repr_map (f : Hom P P') (i j) : simp only [cotangentSpaceBasis_apply, map_tmul, map_one, Hom.toAlgHom_X, cotangentSpaceBasis_repr_one_tmul] -universe w'' u'' v'' - -variable {R'' : Type u''} {S'' : Type v''} [CommRing R''] [CommRing S''] [Algebra R'' S''] -variable {P'' : Generators.{w''} R'' S''} -variable [Algebra R R''] [Algebra S S''] [Algebra R S''] - [IsScalarTower R R'' S''] [IsScalarTower R S S''] -variable [Algebra R' R''] [Algebra S' S''] [Algebra R' S''] - [IsScalarTower R' R'' S''] [IsScalarTower R' S' S''] -variable [IsScalarTower S S' S''] - @[simp] lemma map_id : CotangentSpace.map (.id P) = LinearMap.id := by @@ -275,6 +279,114 @@ lemma toKaehler_surjective : Function.Surjective P.toKaehler := lemma exact_cotangentComplex_toKaehler : Function.Exact P.cotangentComplex P.toKaehler := exact_kerCotangentToTensor_mapBaseChange _ _ _ P.algebraMap_surjective +variable (P) in +/-- +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 + +variable {P : Generators R S} + +noncomputable +instance : AddCommGroup P.H1Cotangent := by delta Generators.H1Cotangent; infer_instance + +noncomputable +instance {R₀} [CommRing R₀] [Algebra R₀ S] [Module R₀ P.Cotangent] + [IsScalarTower R₀ S P.Cotangent] : Module R₀ P.H1Cotangent := by + delta Generators.H1Cotangent; infer_instance + +@[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 + +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 Generators.H1Cotangent; infer_instance + +lemma subsingleton_h1Cotangent (P : Generators R S) : + Subsingleton P.H1Cotangent ↔ Function.Injective P.cotangentComplex := by + delta Generators.H1Cotangent + rw [← LinearMap.ker_eq_bot, Submodule.eq_bot_iff, subsingleton_iff_forall_eq 0, Subtype.forall'] + simp only [Subtype.ext_iff, Submodule.coe_zero] + +/-- The inclusion of `H¹(L_{S/R})` into the conormal space of a presentation. -/ +@[simps!] def h1Cotangentι : P.H1Cotangent →ₗ[S] P.Cotangent := Submodule.subtype _ + +lemma h1Cotangentι_injective : Function.Injective P.h1Cotangentι := Subtype.val_injective + +@[ext] lemma h1Cotangentι_ext (x y : P.H1Cotangent) (e : x.1 = y.1) : x = y := Subtype.ext e + +/-- +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 ↦ ?_ + simp only [LinearMap.mem_ker, Submodule.restrictScalars_mem] at hx ⊢ + apply_fun (CotangentSpace.map f) at hx + rw [CotangentSpace.map_cotangentComplex] at hx + rw [hx] + exact LinearMap.map_zero _ + +lemma H1Cotangent.map_eq (f g : Hom P P') : map f = map g := by + ext x + simp only [map_apply_coe] + rw [← sub_eq_zero, ← Cotangent.val_sub, ← LinearMap.sub_apply, Cotangent.map_sub_map] + simp only [LinearMap.coe_comp, Function.comp_apply, LinearMap.map_coe_ker, map_zero, + Cotangent.val_zero] + +@[simp] lemma H1Cotangent.map_id : map (.id P) = LinearMap.id := by ext; simp + +lemma H1Cotangent.map_comp [IsScalarTower R R' R''] (f : Hom P P') (g : Hom P' P'') : + map (g.comp f) = (map g).restrictScalars S ∘ₗ map f := by ext; simp [Cotangent.map_comp] + +/-- `H¹(L_{S/R})` is independent of the presentation chosen. -/ +@[simps! apply] +noncomputable +def H1Cotangent.equiv (P : Generators.{w} R S) (P' : Generators.{w'} R S) : + P.H1Cotangent ≃ₗ[S] P'.H1Cotangent where + __ := map default + invFun := map default + left_inv x := + show ((map (defaultHom P' P)) ∘ₗ (map (defaultHom P P'))) x = LinearMap.id x by + rw [← map_id, eq_comm, map_eq _ ((defaultHom P' P).comp (defaultHom P P')), map_comp]; rfl + right_inv x := + show ((map (defaultHom P P')) ∘ₗ (map (defaultHom P' P))) x = LinearMap.id x by + rw [← map_id, eq_comm, map_eq _ ((defaultHom P P').comp (defaultHom P' P)), map_comp]; rfl + end Generators +variable {S' : Type*} [CommRing S'] [Algebra R S'] +variable {T : Type w} [CommRing T] [Algebra R T] [Algebra S T] [IsScalarTower R S T] +variable [Algebra S' T] [IsScalarTower R S' T] + +variable (R S S' T) + +/-- `H¹(L_{S/R})`, the first homology of the (naive) cotangent complex of `S` over `R`. -/ +abbrev H1Cotangent : Type _ := (Generators.self R S).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 := + Generators.H1Cotangent.map (Generators.defaultHom _ _) + +variable {R S S' T} + +/-- `H¹(L_{S/R})` is independent of the presentation chosen. -/ +noncomputable +abbrev Generators.equivH1Cotangent (P : Generators.{w} R S) : + P.H1Cotangent ≃ₗ[S] H1Cotangent R S := + Generators.H1Cotangent.equiv _ _ + end Algebra From 83062057427a0227a6dbb7b07622f1f7e64b7dc2 Mon Sep 17 00:00:00 2001 From: mathlib4-update-dependencies-bot <150093616+mathlib-bors@users.noreply.github.com> Date: Thu, 17 Oct 2024 13:07:54 +0000 Subject: [PATCH 307/425] chore: update Mathlib dependencies 2024-10-17 (#17865) 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 1dc73cf0afe47b..b86cb2dfc481e7 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "cc0bc876eeef0518ddc1c8d3bd6f48cc83e68901", + "rev": "c521f0185f4dd42b6aa4898010d5ba5357c57c9f", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 090e2437af8d263f97b731cf78d012f45e0be700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Thu, 17 Oct 2024 13:44:43 +0000 Subject: [PATCH 308/425] =?UTF-8?q?feat:=20`PosSMulMono=20=E2=84=9A=20?= =?UTF-8?q?=CE=B1=20=E2=86=92=20PosSMulMono=20=E2=84=9A=E2=89=A50=20=CE=B1?= =?UTF-8?q?`=20(#17217)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From LeanAPAP --- Mathlib/Algebra/Order/Module/Rat.lean | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Mathlib/Algebra/Order/Module/Rat.lean b/Mathlib/Algebra/Order/Module/Rat.lean index 0368ae68efa89a..288226c0069632 100644 --- a/Mathlib/Algebra/Order/Module/Rat.lean +++ b/Mathlib/Algebra/Order/Module/Rat.lean @@ -12,6 +12,12 @@ import Mathlib.Data.Rat.Cast.Order variable {α : Type*} +instance PosSMulMono.nnrat_of_rat [Preorder α] [MulAction ℚ α] [PosSMulMono ℚ α] : + PosSMulMono ℚ≥0 α where elim _q hq _a₁ _a₂ ha := smul_le_smul_of_nonneg_left (α := ℚ) ha hq + +instance PosSMulStrictMono.nnrat_of_rat [Preorder α] [MulAction ℚ α] [PosSMulStrictMono ℚ α] : + PosSMulStrictMono ℚ≥0 α where elim _q hq _a₁ _a₂ ha := smul_lt_smul_of_pos_left (α := ℚ) ha hq + section LinearOrderedAddCommGroup variable [LinearOrderedAddCommGroup α] From 4dfa80d4a2b80ed9668f60f14cc147cb335a1c23 Mon Sep 17 00:00:00 2001 From: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com> Date: Thu, 17 Oct 2024 14:00:37 +0000 Subject: [PATCH 309/425] feat: Polynomial.degree_prod_of_monic (#17330) --- Mathlib/Algebra/Polynomial/BigOperators.lean | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Mathlib/Algebra/Polynomial/BigOperators.lean b/Mathlib/Algebra/Polynomial/BigOperators.lean index cef12c507490ae..909aed4291d6ac 100644 --- a/Mathlib/Algebra/Polynomial/BigOperators.lean +++ b/Mathlib/Algebra/Polynomial/BigOperators.lean @@ -193,10 +193,21 @@ theorem natDegree_multiset_prod_of_monic (h : ∀ f ∈ t, Monic f) : assumption · simp +theorem degree_multiset_prod_of_monic [Nontrivial R] (h : ∀ f ∈ t, Monic f) : + t.prod.degree = (t.map degree).sum := by + have : t.prod ≠ 0 := Monic.ne_zero <| by simpa using monic_multiset_prod_of_monic _ _ h + rw [degree_eq_natDegree this, natDegree_multiset_prod_of_monic _ h, Nat.cast_multiset_sum, + Multiset.map_map, Function.comp_def, + Multiset.map_congr rfl (fun f hf => (degree_eq_natDegree (h f hf).ne_zero).symm)] + theorem natDegree_prod_of_monic (h : ∀ i ∈ s, (f i).Monic) : (∏ i ∈ s, f i).natDegree = ∑ i ∈ s, (f i).natDegree := by simpa using natDegree_multiset_prod_of_monic (s.1.map f) (by simpa using h) +theorem degree_prod_of_monic [Nontrivial R] (h : ∀ i ∈ s, (f i).Monic) : + (∏ i ∈ s, f i).degree = ∑ i ∈ s, (f i).degree := by + simpa using degree_multiset_prod_of_monic (s.1.map f) (by simpa using h) + theorem coeff_multiset_prod_of_natDegree_le (n : ℕ) (hl : ∀ p ∈ t, natDegree p ≤ n) : coeff t.prod ((Multiset.card t) * n) = (t.map fun p => coeff p n).prod := by induction t using Quotient.inductionOn From d82cdbff79fdde07da9d4edc86a3d9d4fbc67c13 Mon Sep 17 00:00:00 2001 From: Andrew Yang Date: Thu, 17 Oct 2024 14:30:25 +0000 Subject: [PATCH 310/425] feat(RingTheory/Smooth): Smoothness of product rings. (#15131) --- Mathlib.lean | 1 + Mathlib/Algebra/Algebra/Pi.lean | 9 ++ .../RingTheory/Ideal/QuotientOperations.lean | 6 + Mathlib/RingTheory/Smooth/Pi.lean | 121 ++++++++++++++++++ 4 files changed, 137 insertions(+) create mode 100644 Mathlib/RingTheory/Smooth/Pi.lean diff --git a/Mathlib.lean b/Mathlib.lean index 8c55dc3701c47c..155e528def04fe 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4133,6 +4133,7 @@ import Mathlib.RingTheory.SimpleRing.Basic import Mathlib.RingTheory.SimpleRing.Defs import Mathlib.RingTheory.Smooth.Basic import Mathlib.RingTheory.Smooth.Kaehler +import Mathlib.RingTheory.Smooth.Pi import Mathlib.RingTheory.Smooth.StandardSmooth import Mathlib.RingTheory.Support import Mathlib.RingTheory.SurjectiveOnStalks diff --git a/Mathlib/Algebra/Algebra/Pi.lean b/Mathlib/Algebra/Algebra/Pi.lean index db4ea723211c14..fbdfdb6ca061dc 100644 --- a/Mathlib/Algebra/Algebra/Pi.lean +++ b/Mathlib/Algebra/Algebra/Pi.lean @@ -52,6 +52,15 @@ theorem algebraMap_apply {_ : CommSemiring R} [_s : ∀ i, Semiring (f i)] [∀ -- when each `A i` is an `R i`-algebra, although I'm not sure that it's useful. variable {I} (R) +/-- A family of algebra homomorphisms `g i : A →ₐ[R] f i` defines a ring homomorphism +`Pi.algHom g : A →ₐ[R] Π i, f i` given by `Pi.algHom g x i = f i x`. -/ +@[simps!] +def algHom [CommSemiring R] [s : ∀ i, Semiring (f i)] [∀ i, Algebra R (f i)] + {A : Type*} [Semiring A] [Algebra R A] (g : ∀ i, A →ₐ[R] f i) : + A →ₐ[R] ∀ i, f i where + __ := Pi.ringHom fun i ↦ (g i).toRingHom + commutes' r := by ext; simp + /-- `Function.eval` as an `AlgHom`. The name matches `Pi.evalRingHom`, `Pi.evalMonoidHom`, etc. -/ @[simps] diff --git a/Mathlib/RingTheory/Ideal/QuotientOperations.lean b/Mathlib/RingTheory/Ideal/QuotientOperations.lean index 5fb624f6f21436..efc97f56b89937 100644 --- a/Mathlib/RingTheory/Ideal/QuotientOperations.lean +++ b/Mathlib/RingTheory/Ideal/QuotientOperations.lean @@ -479,6 +479,12 @@ theorem quotientMap_comp_mk {J : Ideal R} {I : Ideal S} {f : R →+* S} (H : J (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] +lemma ker_quotientMap_mk {I J : Ideal R} : + 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, + Ideal.comap_map_of_surjective _ Ideal.Quotient.mk_surjective, + ← RingHom.ker_eq_comap_bot, Ideal.mk_ker, Ideal.map_sup, Ideal.map_quotient_self, bot_sup_eq] + /-- The ring equiv `R/I ≃+* S/J` induced by a ring equiv `f : R ≃+* S`, where `J = f(I)`. -/ @[simps] def quotientEquiv (I : Ideal R) (J : Ideal S) (f : R ≃+* S) (hIJ : J = I.map (f : R →+* S)) : diff --git a/Mathlib/RingTheory/Smooth/Pi.lean b/Mathlib/RingTheory/Smooth/Pi.lean new file mode 100644 index 00000000000000..acebf93edbce43 --- /dev/null +++ b/Mathlib/RingTheory/Smooth/Pi.lean @@ -0,0 +1,121 @@ +/- +Copyright (c) 2024 Andrew Yang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Andrew Yang +-/ +import Mathlib.RingTheory.Idempotents +import Mathlib.RingTheory.Smooth.Basic + +/-! + +# Formal-smoothness of finite products of rings + +## Main result + +- `Algebra.FormallySmooth.pi_iff`: If `I` is finite, `Π i : I, A i` is `R`-formally-smooth + if and only if each `A i` is `R`-formally-smooth. + +-/ + +universe u v + +namespace Algebra.FormallySmooth + +variable {R : Type (max u v)} {I : Type u} (A : I → Type (max u v)) +variable [CommRing R] [∀ i, CommRing (A i)] [∀ i, Algebra R (A i)] + +theorem of_pi [FormallySmooth R (Π i, A i)] (i) : + FormallySmooth R (A i) := by + classical + fapply FormallySmooth.of_split (Pi.evalAlgHom R A i) + apply AlgHom.ofLinearMap + ((Ideal.Quotient.mkₐ R _).toLinearMap.comp (LinearMap.single _ _ i)) + · show Ideal.Quotient.mk _ (Pi.single i 1) = 1 + rw [← (Ideal.Quotient.mk _).map_one, ← sub_eq_zero, ← map_sub, + Ideal.Quotient.eq_zero_iff_mem] + have : Pi.single i 1 - 1 ∈ RingHom.ker (Pi.evalAlgHom R A i).toRingHom := by + simp [RingHom.mem_ker] + convert neg_mem (Ideal.pow_mem_pow this 2) using 1 + simp [pow_two, sub_mul, mul_sub, ← Pi.single_mul] + · intro x y + show Ideal.Quotient.mk _ _ = Ideal.Quotient.mk _ _ * Ideal.Quotient.mk _ _ + simp only [AlgHom.toRingHom_eq_coe, LinearMap.coe_single, Pi.single_mul, map_mul] + · ext x + show (Pi.single i x) i = x + simp + +theorem pi_iff [Finite I] : + FormallySmooth R (Π i, A i) ↔ ∀ i, FormallySmooth R (A i) := by + classical + cases nonempty_fintype I + constructor + · exact fun _ ↦ of_pi A + · intro H + constructor + intros B _ _ J hJ g + have hJ' (x) (hx : x ∈ RingHom.ker (Ideal.Quotient.mk J)) : IsNilpotent x := by + refine ⟨2, show x ^ 2 ∈ (⊥ : Ideal B) from ?_⟩ + rw [← hJ] + exact Ideal.pow_mem_pow (by simpa using hx) 2 + obtain ⟨e, he, he'⟩ := ((CompleteOrthogonalIdempotents.single A).map + g.toRingHom).lift_of_isNilpotent_ker (Ideal.Quotient.mk J) hJ' + 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 _ + __ := 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ₐ _ + (IsScalarTower.toAlgHom R B _) Ideal.le_comap_map + have hι : ∀ i x, ι i x = 0 → (e i) * x = 0 := by + intros i x hix + have : x ∈ (Ideal.span {1 - e i}).map (Ideal.Quotient.mk J) := by + rw [← Ideal.ker_quotientMap_mk]; exact hix + rw [Ideal.map_span, Set.image_singleton, Ideal.mem_span_singleton] at this + obtain ⟨c, rfl⟩ := this + rw [← mul_assoc, ← map_mul, mul_sub, mul_one, (he.idem i).eq, sub_self, map_zero, zero_mul] + have : ∀ i : I, ∃ a : A i →ₐ[R] B ⧸ Ideal.span {1 - e i}, ∀ x, + Ideal.Quotient.mk (J' i) (a x) = ι i (g (Pi.single i x)) := by + intro i + let g' : A i →ₐ[R] (B ⧸ _) ⧸ (J' i) := by + apply AlgHom.ofLinearMap (((ι i).comp g).toLinearMap ∘ₗ LinearMap.single _ _ i) + · suffices Ideal.Quotient.mk (Ideal.span {1 - e i}) (e i) = 1 by simp [ι, ← he', this] + rw [← (Ideal.Quotient.mk _).map_one, eq_comm, Ideal.Quotient.mk_eq_mk_iff_sub_mem, + Ideal.mem_span_singleton] + · intros x y; simp [Pi.single_mul] + obtain ⟨a, ha⟩ := FormallySmooth.comp_surjective (I := J' 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)) + ext x; rw [← AlgHom.toLinearMap_apply, ← AlgHom.toLinearMap_apply]; congr 1 + ext i x + simp only [AlgEquiv.toAlgHom_eq_coe, AlgHom.comp_toLinearMap, AlgEquiv.toAlgHom_toLinearMap, + LinearMap.coe_comp, LinearMap.coe_single, Function.comp_apply, AlgHom.toLinearMap_apply, + AlgEquiv.toLinearMap_apply, Ideal.Quotient.mkₐ_eq_mk] + obtain ⟨y, hy⟩ := Ideal.Quotient.mk_surjective (a i x) + have hy' : Ideal.Quotient.mk (Ideal.span {1 - e i}) (y * e i) = a i x := by + have : Ideal.Quotient.mk (Ideal.span {1 - e i}) (e i) = 1 := by + rw [← (Ideal.Quotient.mk _).map_one, eq_comm, Ideal.Quotient.mk_eq_mk_iff_sub_mem, + Ideal.mem_span_singleton] + rw [map_mul, this, hy, mul_one] + trans Ideal.Quotient.mk J (y * e i) + · congr 1; apply iso.injective; ext j + suffices a j (Pi.single i x j) = Ideal.Quotient.mk _ (y * e i) by simpa using this + by_cases hij : i = j + · subst hij + rw [Pi.single_eq_same, hy'] + · have : Ideal.Quotient.mk (Ideal.span {1 - e j}) (e i) = 0 := by + rw [Ideal.Quotient.eq_zero_iff_mem, Ideal.mem_span_singleton] + refine ⟨e i, by simp [he.ortho (Ne.symm hij), sub_mul]⟩ + rw [Pi.single_eq_of_ne (Ne.symm hij), map_zero, map_mul, this, mul_zero] + · have : ι i (Ideal.Quotient.mk J (y * e i)) = ι i (g (Pi.single i x)) := by + rw [← ha, ← hy'] + simp only [Ideal.quotient_map_mkₐ, IsScalarTower.coe_toAlgHom', + Ideal.Quotient.algebraMap_eq, Ideal.Quotient.mkₐ_eq_mk, ι] + rw [← sub_eq_zero, ← map_sub] at this + replace this := hι _ _ this + rwa [mul_sub, ← map_mul, mul_comm, mul_assoc, (he.idem i).eq, he', ← map_mul, ← Pi.single_mul, + one_mul, sub_eq_zero] at this + +end Algebra.FormallySmooth From e2b89093a1a30606a1de57c265dd8d8d33d3ae2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Thu, 17 Oct 2024 14:30:27 +0000 Subject: [PATCH 311/425] chore: don't export `GroupWithZero.inv_zero` (#17465) Exporting makes it not show as `inv_zero` in the docs search results, meaning it's very non-discoverable. See https://github.com/leanprover/doc-gen4/issues/222. --- Mathlib/Algebra/GroupWithZero/Defs.lean | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/GroupWithZero/Defs.lean b/Mathlib/Algebra/GroupWithZero/Defs.lean index 14ace092e132d4..221f060ebda9a4 100644 --- a/Mathlib/Algebra/GroupWithZero/Defs.lean +++ b/Mathlib/Algebra/GroupWithZero/Defs.lean @@ -182,16 +182,15 @@ Examples include division rings and the ordered monoids that are the target of valuations in general valuation theory. -/ class GroupWithZero (G₀ : Type u) extends MonoidWithZero G₀, DivInvMonoid G₀, Nontrivial G₀ where /-- The inverse of `0` in a group with zero is `0`. -/ - inv_zero : (0 : G₀)⁻¹ = 0 + protected inv_zero : (0 : G₀)⁻¹ = 0 /-- Every nonzero element of a group with zero is invertible. -/ protected mul_inv_cancel (a : G₀) : a ≠ 0 → a * a⁻¹ = 1 -export GroupWithZero (inv_zero) -attribute [simp] inv_zero - section GroupWithZero variable [GroupWithZero G₀] {a : G₀} +@[simp] lemma inv_zero : (0 : G₀)⁻¹ = 0 := GroupWithZero.inv_zero + @[simp] lemma mul_inv_cancel₀ (h : a ≠ 0) : a * a⁻¹ = 1 := GroupWithZero.mul_inv_cancel a h -- See note [lower instance priority] From 58282561d2e928698a6727596a4ad96d74f64766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Thu, 17 Oct 2024 14:30:28 +0000 Subject: [PATCH 312/425] feat: Lagrange's theorem for the pointwise product of a subgroup with a set (#17680) From LeanCamCombi --- Mathlib/GroupTheory/Coset/Card.lean | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Mathlib/GroupTheory/Coset/Card.lean b/Mathlib/GroupTheory/Coset/Card.lean index 67a686a06e9b1a..df9e2e1b9a6678 100644 --- a/Mathlib/GroupTheory/Coset/Card.lean +++ b/Mathlib/GroupTheory/Coset/Card.lean @@ -10,6 +10,8 @@ import Mathlib.SetTheory.Cardinal.Finite # Lagrange's theorem: the order of a subgroup divides the order of the group. -/ +open scoped Pointwise + namespace Subgroup variable {α : Type*} [Group α] @@ -19,6 +21,15 @@ theorem card_eq_card_quotient_mul_card_subgroup (s : Subgroup α) : Nat.card α = Nat.card (α ⧸ s) * Nat.card s := by rw [← Nat.card_prod]; exact Nat.card_congr Subgroup.groupEquivQuotientProdSubgroup +@[to_additive] +lemma card_mul_eq_card_subgroup_mul_card_quotient (s : Subgroup α) (t : Set α) : + Nat.card (t * s : Set α) = Nat.card s * Nat.card (t.image (↑) : Set (α ⧸ s)) := by + rw [← Nat.card_prod, Nat.card_congr] + apply Equiv.trans _ (QuotientGroup.preimageMkEquivSubgroupProdSet _ _) + rw [QuotientGroup.preimage_image_mk] + convert Equiv.refl ↑(t * s) + aesop (add simp [Set.mem_mul]) + /-- **Lagrange's Theorem**: The order of a subgroup divides the order of its ambient group. -/ @[to_additive "**Lagrange's Theorem**: The order of an additive subgroup divides the order of its ambient additive group."] From 436ba3afd94da896fa1d20b511a1469ea5d018c3 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Thu, 17 Oct 2024 14:30:30 +0000 Subject: [PATCH 313/425] chore: remove "instance was not necessary" porting notes (issue #10670) (#17866) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Discussed with @kim-em. These instances are now necessary because instance synthesis now searches with the full discrimination tree, so mismatches in the arguments to instances are scrutinized much harder. This is not likely to be reverted in the future, so the instances remain required. There were a few further occurrences of #10670 for Grp, see e.g. [Grp.instCoeFunHomForallαGroup](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Algebra/Category/Grp/Basic.html#Grp.instCoeFunHomForall%CE%B1Group). These do look like they are unnecessary but removing them breaks a lot of downstream proofs. (I think it's something to do with `coe_of` unfolding `of` causing a mismatch between the expected types, but it's a bit too subtle to deal with easily.) I'll leave those porting notes for the meantime. We need a big refactor cleaning up the concrete category bits of the library anyway. --- Mathlib/Algebra/Category/Grp/Basic.lean | 2 -- Mathlib/Algebra/Category/Grp/Preadditive.lean | 1 - Mathlib/Geometry/RingedSpace/Basic.lean | 1 - Mathlib/Order/Category/NonemptyFinLinOrd.lean | 1 - 4 files changed, 5 deletions(-) diff --git a/Mathlib/Algebra/Category/Grp/Basic.lean b/Mathlib/Algebra/Category/Grp/Basic.lean index 67d5908ffff48e..1c03372df70b36 100644 --- a/Mathlib/Algebra/Category/Grp/Basic.lean +++ b/Mathlib/Algebra/Category/Grp/Basic.lean @@ -112,7 +112,6 @@ instance hasForgetToMonCat : HasForget₂ Grp MonCat := @[to_additive] instance : Coe Grp.{u} MonCat.{u} where coe := (forget₂ Grp MonCat).obj --- porting note (#10670): this instance was not necessary in mathlib @[to_additive] instance (G H : Grp) : One (G ⟶ H) := (inferInstance : One (MonoidHom G H)) @@ -257,7 +256,6 @@ instance hasForgetToCommMonCat : HasForget₂ CommGrp CommMonCat := @[to_additive] instance : Coe CommGrp.{u} CommMonCat.{u} where coe := (forget₂ CommGrp CommMonCat).obj --- porting note (#10670): this instance was not necessary in mathlib @[to_additive] instance (G H : CommGrp) : One (G ⟶ H) := (inferInstance : One (MonoidHom G H)) diff --git a/Mathlib/Algebra/Category/Grp/Preadditive.lean b/Mathlib/Algebra/Category/Grp/Preadditive.lean index 5866733e35b85e..fd7ca0d120ef39 100644 --- a/Mathlib/Algebra/Category/Grp/Preadditive.lean +++ b/Mathlib/Algebra/Category/Grp/Preadditive.lean @@ -16,7 +16,6 @@ universe u namespace AddCommGrp --- porting note (#10670): this instance was not necessary in mathlib instance (P Q : AddCommGrp) : AddCommGroup (P ⟶ Q) := (inferInstance : AddCommGroup (AddMonoidHom P Q)) diff --git a/Mathlib/Geometry/RingedSpace/Basic.lean b/Mathlib/Geometry/RingedSpace/Basic.lean index 4a89dde97d9c9b..a11af973bc8906 100644 --- a/Mathlib/Geometry/RingedSpace/Basic.lean +++ b/Mathlib/Geometry/RingedSpace/Basic.lean @@ -48,7 +48,6 @@ lemma res_zero {X : RingedSpace.{u}} {U V : TopologicalSpace.Opens X} variable (X : RingedSpace) --- Porting note (#10670): this was not necessary in mathlib3 instance : CoeSort RingedSpace Type* where coe X := X.carrier diff --git a/Mathlib/Order/Category/NonemptyFinLinOrd.lean b/Mathlib/Order/Category/NonemptyFinLinOrd.lean index cfa1dab4252005..29ef2f1dc61d2e 100644 --- a/Mathlib/Order/Category/NonemptyFinLinOrd.lean +++ b/Mathlib/Order/Category/NonemptyFinLinOrd.lean @@ -121,7 +121,6 @@ instance {A B : NonemptyFinLinOrd.{u}} : FunLike (A ⟶ B) A B where ext x exact congr_fun h x --- porting note (#10670): this instance was not necessary in mathlib instance {A B : NonemptyFinLinOrd.{u}} : OrderHomClass (A ⟶ B) A B where map_rel f _ _ h := f.monotone h From 12a15447c89cc5bbbfa031af07a954ae31b3bbdf Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Thu, 17 Oct 2024 14:30:31 +0000 Subject: [PATCH 314/425] chore: remove "CoeFun -> FunLike" porting/adaptation notes (#17871) We prefer `FunLike` over `CoeFun` if possible, so we don't care that we made that change during the port. See also #17870 for applying the change that was porting noted consistently across the entirety of Mathlib. --- Mathlib/Algebra/Module/LinearMap/Defs.lean | 2 -- Mathlib/Algebra/MvPolynomial/Basic.lean | 2 -- Mathlib/Analysis/InnerProductSpace/PiL2.lean | 1 - Mathlib/LinearAlgebra/Multilinear/Basic.lean | 1 - Mathlib/NumberTheory/ArithmeticFunction.lean | 1 - Mathlib/Order/Heyting/Hom.lean | 7 ------- Mathlib/Order/Hom/CompleteLattice.lean | 6 ------ Mathlib/RingTheory/RingInvo.lean | 4 ---- Mathlib/Topology/Algebra/Module/Basic.lean | 9 --------- Mathlib/Topology/Category/TopCat/Basic.lean | 6 ------ 10 files changed, 39 deletions(-) diff --git a/Mathlib/Algebra/Module/LinearMap/Defs.lean b/Mathlib/Algebra/Module/LinearMap/Defs.lean index eceefd6b766ab6..0a75f33f5bf9c6 100644 --- a/Mathlib/Algebra/Module/LinearMap/Defs.lean +++ b/Mathlib/Algebra/Module/LinearMap/Defs.lean @@ -216,8 +216,6 @@ lemma coe_coe {F : Type*} [FunLike F M M₃] [SemilinearMapClass F σ M M₃] {f ⇑(f : M →ₛₗ[σ] M₃) = f := rfl --- Porting note: we don't port specialized `CoeFun` instances if there is `DFunLike` instead - /-- The `DistribMulActionHom` underlying a `LinearMap`. -/ def toDistribMulActionHom (f : M →ₛₗ[σ] M₃) : DistribMulActionHom σ.toMonoidHom M M₃ := { f with map_zero' := show f 0 = 0 from map_zero f } diff --git a/Mathlib/Algebra/MvPolynomial/Basic.lean b/Mathlib/Algebra/MvPolynomial/Basic.lean index c5e9e3036cee45..de4f2a12c09bba 100644 --- a/Mathlib/Algebra/MvPolynomial/Basic.lean +++ b/Mathlib/Algebra/MvPolynomial/Basic.lean @@ -509,8 +509,6 @@ 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 - -- Porting note: I changed this from `@CoeFun.coe _ _ (MonoidAlgebra.coeFun _ _) p m` because - -- I think it should work better syntactically. They are defeq. @[simp] theorem mem_support_iff {p : MvPolynomial σ R} {m : σ →₀ ℕ} : m ∈ p.support ↔ p.coeff m ≠ 0 := by diff --git a/Mathlib/Analysis/InnerProductSpace/PiL2.lean b/Mathlib/Analysis/InnerProductSpace/PiL2.lean index 5fb4aa1c202934..2c14b91ede9f15 100644 --- a/Mathlib/Analysis/InnerProductSpace/PiL2.lean +++ b/Mathlib/Analysis/InnerProductSpace/PiL2.lean @@ -306,7 +306,6 @@ theorem repr_injective : cases g congr --- Porting note: `CoeFun` → `FunLike` /-- `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 : 𝕜)) diff --git a/Mathlib/LinearAlgebra/Multilinear/Basic.lean b/Mathlib/LinearAlgebra/Multilinear/Basic.lean index 21a0244972b27d..5fa2ebd1c7ff4f 100644 --- a/Mathlib/LinearAlgebra/Multilinear/Basic.lean +++ b/Mathlib/LinearAlgebra/Multilinear/Basic.lean @@ -106,7 +106,6 @@ variable [Semiring R] [∀ i, AddCommMonoid (M i)] [∀ i, AddCommMonoid (M₁ i [AddCommMonoid M₃] [AddCommMonoid M'] [∀ i, Module R (M i)] [∀ i, Module R (M₁ i)] [Module R M₂] [Module R M₃] [Module R M'] (f f' : MultilinearMap R M₁ M₂) --- Porting note: Replaced CoeFun with FunLike instance instance : FunLike (MultilinearMap R M₁ M₂) (∀ i, M₁ i) M₂ where coe f := f.toFun coe_injective' f g h := by cases f; cases g; cases h; rfl diff --git a/Mathlib/NumberTheory/ArithmeticFunction.lean b/Mathlib/NumberTheory/ArithmeticFunction.lean index 9e6e2e67edaefe..71c09ddd1baad5 100644 --- a/Mathlib/NumberTheory/ArithmeticFunction.lean +++ b/Mathlib/NumberTheory/ArithmeticFunction.lean @@ -92,7 +92,6 @@ section Zero variable [Zero R] --- porting note: used to be `CoeFun` instance : FunLike (ArithmeticFunction R) ℕ R := inferInstanceAs (FunLike (ZeroHom ℕ R) ℕ R) diff --git a/Mathlib/Order/Heyting/Hom.lean b/Mathlib/Order/Heyting/Hom.lean index 6b0940817f6d3c..ab4677d3ab3cb4 100644 --- a/Mathlib/Order/Heyting/Hom.lean +++ b/Mathlib/Order/Heyting/Hom.lean @@ -246,13 +246,6 @@ instance instHeytingHomClass : HeytingHomClass (HeytingHom α β) α β where map_bot f := f.map_bot' map_himp := HeytingHom.map_himp' - --- Porting note: CoeFun undesired here in lean 4 --- /-- Helper instance for when there's too many metavariables to apply `DFunLike.CoeFun` --- directly. -/ --- instance : CoeFun (HeytingHom α β) fun _ => α → β := --- DFunLike.hasCoeToFun - -- @[simp] -- Porting note: not in simp-nf, simp can simplify lhs. Added aux simp lemma theorem toFun_eq_coe {f : HeytingHom α β} : f.toFun = ⇑f := rfl diff --git a/Mathlib/Order/Hom/CompleteLattice.lean b/Mathlib/Order/Hom/CompleteLattice.lean index 8fecfd2875b9bb..125753699728c2 100644 --- a/Mathlib/Order/Hom/CompleteLattice.lean +++ b/Mathlib/Order/Hom/CompleteLattice.lean @@ -592,12 +592,6 @@ def tosSupHom (f : CompleteLatticeHom α β) : sSupHom α β := def toBoundedLatticeHom (f : CompleteLatticeHom α β) : BoundedLatticeHom α β := f --- Porting note: We do not want CoeFun for this in lean 4 --- /-- Helper instance for when there's too many metavariables to apply `fun_like.has_coe_toFun` --- directly. -/ --- instance : CoeFun (CompleteLatticeHom α β) fun _ => α → β := --- DFunLike.hasCoeToFun - lemma toFun_eq_coe (f : CompleteLatticeHom α β) : f.toFun = f := rfl @[simp] lemma coe_tosInfHom (f : CompleteLatticeHom α β) : ⇑f.tosInfHom = f := rfl diff --git a/Mathlib/RingTheory/RingInvo.lean b/Mathlib/RingTheory/RingInvo.lean index 0ebf763f2a467c..86cbcf2eb18f47 100644 --- a/Mathlib/RingTheory/RingInvo.lean +++ b/Mathlib/RingTheory/RingInvo.lean @@ -83,10 +83,6 @@ def mk' (f : R →+* Rᵐᵒᵖ) (involution : ∀ r, (f (f r).unop).unop = r) : right_inv := fun _ => MulOpposite.unop_injective <| involution _ involution' := involution } --- Porting note: removed CoeFun instance, undesired in lean4 --- instance : CoeFun (RingInvo R) fun _ => R → Rᵐᵒᵖ := --- ⟨fun f => f.toRingEquiv.toFun⟩ - @[simp] theorem involution (f : RingInvo R) (x : R) : (f (f x).unop).unop = x := f.involution' x diff --git a/Mathlib/Topology/Algebra/Module/Basic.lean b/Mathlib/Topology/Algebra/Module/Basic.lean index 451dff66e30df3..df022af8914107 100644 --- a/Mathlib/Topology/Algebra/Module/Basic.lean +++ b/Mathlib/Topology/Algebra/Module/Basic.lean @@ -378,10 +378,6 @@ instance continuousSemilinearMapClass : map_continuous f := f.2 map_smulₛₗ f := f.toLinearMap.map_smul' --- see Note [function coercion] -/-- Coerce continuous linear maps to functions. -/ ---instance toFun' : CoeFun (M₁ →SL[σ₁₂] M₂) fun _ => M₁ → M₂ := ⟨DFunLike.coe⟩ - -- porting note (#10618): was `simp`, now `simp only` proves it theorem coe_mk (f : M₁ →ₛₗ[σ₁₂] M₂) (h) : (mk f h : M₁ →ₛₗ[σ₁₂] M₂) = f := rfl @@ -1634,11 +1630,6 @@ instance continuousSemilinearEquivClass : map_continuous := continuous_toFun inv_continuous := continuous_invFun --- see Note [function coercion] --- /-- Coerce continuous linear equivs to maps. -/ --- instance : CoeFun (M₁ ≃SL[σ₁₂] M₂) fun _ => M₁ → M₂ := --- ⟨fun f => f⟩ - theorem coe_apply (e : M₁ ≃SL[σ₁₂] M₂) (b : M₁) : (e : M₁ →SL[σ₁₂] M₂) b = e b := rfl diff --git a/Mathlib/Topology/Category/TopCat/Basic.lean b/Mathlib/Topology/Category/TopCat/Basic.lean index 468168d5c7fb56..8cf13a2f355f49 100644 --- a/Mathlib/Topology/Category/TopCat/Basic.lean +++ b/Mathlib/Topology/Category/TopCat/Basic.lean @@ -47,12 +47,6 @@ instance : CoeSort TopCat Type* where instance topologicalSpaceUnbundled (X : TopCat) : TopologicalSpace X := X.str --- We leave this temporarily as a reminder of the downstream instances #13170 --- -- Porting note: cannot find a coercion to function otherwise --- -- attribute [instance] ConcreteCategory.instFunLike in --- instance (X Y : TopCat.{u}) : CoeFun (X ⟶ Y) fun _ => X → Y where --- coe (f : C(X, Y)) := f - instance instFunLike (X Y : TopCat) : FunLike (X ⟶ Y) X Y := inferInstanceAs <| FunLike C(X, Y) X Y From d0df6356048affd1a0c86f935b0d04bf36a402d4 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 17 Oct 2024 15:03:58 +0000 Subject: [PATCH 315/425] feat(QuotientGroup,Ideal/Quotient): group is finite if quotient is finite (#15425) Does not actually require the subgroup to be normal Also provides a breakdown of the group as the disjoint indexed union of cosets Co-authored-by: Yakov Pechersky --- Mathlib/GroupTheory/Coset/Basic.lean | 21 +++++++++++++++++ Mathlib/GroupTheory/GroupAction/Basic.lean | 23 +++++++++++++++++++ Mathlib/GroupTheory/QuotientGroup/Finite.lean | 5 ++++ Mathlib/RingTheory/Ideal/Quotient.lean | 11 +++++++++ 4 files changed, 60 insertions(+) diff --git a/Mathlib/GroupTheory/Coset/Basic.lean b/Mathlib/GroupTheory/Coset/Basic.lean index d9ede0a36ed677..ab5461c4022dc9 100644 --- a/Mathlib/GroupTheory/Coset/Basic.lean +++ b/Mathlib/GroupTheory/Coset/Basic.lean @@ -458,6 +458,18 @@ theorem preimage_image_mk_eq_mul (N : Subgroup α) (s : Set α) : rw [preimage_image_mk_eq_iUnion_image, iUnion_subtype, ← image2_mul, ← iUnion_image_right] simp only [SetLike.mem_coe] +open MulAction in +@[to_additive] +lemma orbit_mk_eq_smul (x : α) : MulAction.orbitRel.Quotient.orbit (x : α ⧸ s) = x • s := by + ext + rw [orbitRel.Quotient.mem_orbit] + simpa [mem_smul_set_iff_inv_smul_mem, ← leftRel_apply] using Setoid.comm' _ + +@[to_additive] +lemma orbit_eq_out'_smul (x : α ⧸ s) : MulAction.orbitRel.Quotient.orbit x = x.out' • s := by + induction x using QuotientGroup.induction_on + simp only [orbit_mk_eq_smul, ← eq_class_eq_leftCoset, Quotient.out_eq'] + end QuotientGroup namespace Subgroup @@ -706,4 +718,13 @@ noncomputable def preimageMkEquivSubgroupProdSet (s : Subgroup α) (t : Set (α left_inv := fun ⟨a, _⟩ => Subtype.eq <| show _ * _ = a by simp right_inv := fun ⟨⟨a, ha⟩, ⟨x, hx⟩⟩ => by ext <;> simp [ha] +open MulAction in +/-- A group is made up of a disjoint union of cosets of a subgroup. -/ +@[to_additive "An additive group is made up of a disjoint union of cosets of an additive +subgroup."] +lemma univ_eq_iUnion_smul (H : Subgroup α) : + (Set.univ (α := α)) = ⋃ x : α ⧸ H, x.out' • (H : Set _) := by + simp_rw [univ_eq_iUnion_orbit H.op, orbit_eq_out'_smul] + rfl + end QuotientGroup diff --git a/Mathlib/GroupTheory/GroupAction/Basic.lean b/Mathlib/GroupTheory/GroupAction/Basic.lean index cc847556ec7f8d..9f99144a7769a7 100644 --- a/Mathlib/GroupTheory/GroupAction/Basic.lean +++ b/Mathlib/GroupTheory/GroupAction/Basic.lean @@ -108,6 +108,10 @@ lemma snd_mem_orbit_of_mem_orbit {x y : α × β} (h : x ∈ MulAction.orbit M y rcases h with ⟨g, rfl⟩ exact mem_orbit _ _ +@[to_additive] +lemma _root_.Finite.finite_mulAction_orbit [Finite M] (a : α) : Set.Finite (orbit M a) := + Set.finite_range _ + variable (M) @[to_additive] @@ -625,6 +629,25 @@ def selfEquivSigmaOrbits : α ≃ Σω : Ω, orbit G ω.out' := Equiv.sigmaCongrRight fun _ => Equiv.Set.ofEq <| orbitRel.Quotient.orbit_eq_orbit_out _ Quotient.out_eq' +/-- Decomposition of a type `X` as a disjoint union of its orbits under a group action. +Phrased as a set union. See `MulAction.selfEquivSigmaOrbits` for the type isomorphism. -/ +@[to_additive "Decomposition of a type `X` as a disjoint union of its orbits under an additive group +action. Phrased as a set union. See `AddAction.selfEquivSigmaOrbits` for the type isomorphism."] +lemma univ_eq_iUnion_orbit : + Set.univ (α := α) = ⋃ x : Ω, x.orbit := by + ext x + simp only [Set.mem_univ, Set.mem_iUnion, true_iff] + exact ⟨Quotient.mk'' x, by simp⟩ + +@[to_additive] +lemma _root_.Finite.of_finite_mulAction_orbitRel_quotient [Finite G] [Finite Ω] : Finite α := by + rw [(selfEquivSigmaOrbits' G _).finite_iff] + have : ∀ g : Ω, Finite g.orbit := by + intro g + induction g using Quotient.inductionOn' + simpa [Set.finite_coe_iff] using Finite.finite_mulAction_orbit _ + exact Finite.instSigma + variable (β) @[to_additive] diff --git a/Mathlib/GroupTheory/QuotientGroup/Finite.lean b/Mathlib/GroupTheory/QuotientGroup/Finite.lean index 76877f51f87b7b..6d234fdd50c165 100644 --- a/Mathlib/GroupTheory/QuotientGroup/Finite.lean +++ b/Mathlib/GroupTheory/QuotientGroup/Finite.lean @@ -50,4 +50,9 @@ noncomputable def fintypeOfKerOfCodom [Fintype g.ker] : Fintype G := noncomputable def fintypeOfDomOfCoker [Normal f.range] [Fintype <| G ⧸ f.range] : Fintype G := fintypeOfKerLeRange _ (mk' f.range) fun x => (eq_one_iff x).mp +@[to_additive] +lemma _root_.Finite.of_finite_quot_finite_subgroup {H : Subgroup G} [Finite H] [Finite (G ⧸ H)] : + Finite G := + Finite.of_equiv _ (groupEquivQuotientProdSubgroup (s := H)).symm + end Group diff --git a/Mathlib/RingTheory/Ideal/Quotient.lean b/Mathlib/RingTheory/Ideal/Quotient.lean index 3889f7377adb06..182a09a1dac955 100644 --- a/Mathlib/RingTheory/Ideal/Quotient.lean +++ b/Mathlib/RingTheory/Ideal/Quotient.lean @@ -3,6 +3,7 @@ Copyright (c) 2018 Kenny Lau. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Kenny Lau, Chris Hughes, Mario Carneiro, Anne Baanen -/ +import Mathlib.GroupTheory.QuotientGroup.Finite import Mathlib.LinearAlgebra.Quotient import Mathlib.RingTheory.Congruence.Basic import Mathlib.RingTheory.Ideal.Basic @@ -348,4 +349,14 @@ theorem map_pi {ι : Type*} [Finite ι] {ι' : Type w} (x : ι → R) (hi : ∀ end Pi +open scoped Pointwise in +/-- A ring is made up of a disjoint union of cosets of an ideal. -/ +lemma univ_eq_iUnion_image_add {R : Type*} [Ring R] (I : Ideal R) : + (Set.univ (α := R)) = ⋃ x : R ⧸ I, x.out' +ᵥ (I : Set R) := + QuotientAddGroup.univ_eq_iUnion_vadd I.toAddSubgroup + +lemma _root_.Finite.of_finite_quot_finite_ideal {R : Type*} [Ring R] {I : Ideal R} + [hI : Finite I] [h : Finite (R ⧸ I)] : Finite R := + @Finite.of_finite_quot_finite_addSubgroup _ _ _ hI h + end Ideal From 0b86556786ec68a8d3c198f66952df4d3b771cb2 Mon Sep 17 00:00:00 2001 From: FR Date: Thu, 17 Oct 2024 15:03:59 +0000 Subject: [PATCH 316/425] chore(SetTheory/Game/Basic): fix docs (#17121) --- Mathlib/SetTheory/Game/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/SetTheory/Game/Basic.lean b/Mathlib/SetTheory/Game/Basic.lean index 13900670705bd0..3504ce49ac81a3 100644 --- a/Mathlib/SetTheory/Game/Basic.lean +++ b/Mathlib/SetTheory/Game/Basic.lean @@ -247,7 +247,7 @@ Hence we define them here. -/ /-- The product of `x = {xL | xR}` and `y = {yL | yR}` is -`{xL*y + x*yL - xL*yL, xR*y + x*yR - xR*yR | xL*y + x*yR - xL*yR, x*yL + xR*y - xR*yL }`. -/ +`{xL*y + x*yL - xL*yL, xR*y + x*yR - xR*yR | xL*y + x*yR - xL*yR, xR*y + x*yL - xR*yL}`. -/ instance : Mul PGame.{u} := ⟨fun x y => by induction x generalizing y with | mk xl xr _ _ IHxl IHxr => _ From cff08d545656d8cabf918cdcbde50f4f6105ae0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Thu, 17 Oct 2024 15:04:01 +0000 Subject: [PATCH 317/425] chore(Order/Hom): let `gcongr` know about `OrderEmbedding` and `OrderIso` (#17224) From LeanAPAP --- Mathlib/NumberTheory/NumberField/Discriminant.lean | 2 +- Mathlib/Order/Hom/Basic.lean | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Mathlib/NumberTheory/NumberField/Discriminant.lean b/Mathlib/NumberTheory/NumberField/Discriminant.lean index 758d8a99b48ed0..07199e222dcb47 100644 --- a/Mathlib/NumberTheory/NumberField/Discriminant.lean +++ b/Mathlib/NumberTheory/NumberField/Discriminant.lean @@ -308,7 +308,7 @@ theorem minkowskiBound_lt_boundOfDiscBdd : minkowskiBound K ↑1 < boundOfDiscBd coe_mul, ENNReal.coe_pow, coe_ofNat, show sqrt N = (1 : ℝ≥0∞) * sqrt N by rw [one_mul]] gcongr · exact pow_le_one₀ (by positivity) (by norm_num) - · rwa [sqrt_le_sqrt, ← NNReal.coe_le_coe, coe_nnnorm, Int.norm_eq_abs, ← Int.cast_abs, + · rwa [← NNReal.coe_le_coe, coe_nnnorm, Int.norm_eq_abs, ← Int.cast_abs, NNReal.coe_natCast, ← Int.cast_natCast, Int.cast_le] · exact one_le_two · exact rank_le_rankOfDiscrBdd hK diff --git a/Mathlib/Order/Hom/Basic.lean b/Mathlib/Order/Hom/Basic.lean index 96b44c3f6a264c..c9ab0123359da1 100644 --- a/Mathlib/Order/Hom/Basic.lean +++ b/Mathlib/Order/Hom/Basic.lean @@ -148,6 +148,9 @@ protected theorem monotone (f : F) : Monotone f := fun _ _ => map_rel f protected theorem mono (f : F) : Monotone f := fun _ _ => map_rel f +@[gcongr] protected lemma GCongr.mono (f : F) {a b : α} (hab : a ≤ b) : f a ≤ f b := + OrderHomClass.mono f hab + /-- Turn an element of a type `F` satisfying `OrderHomClass F α β` into an actual `OrderHom`. This is declared as the default coercion from `F` to `α →o β`. -/ @[coe] @@ -921,6 +924,8 @@ variable [LE α] [LE β] theorem le_iff_le (e : α ≃o β) {x y : α} : e x ≤ e y ↔ x ≤ y := e.map_rel_iff +@[gcongr] protected alias ⟨_, GCongr.orderIso_apply_le_apply⟩ := le_iff_le + theorem le_symm_apply (e : α ≃o β) {x : α} {y : β} : x ≤ e.symm y ↔ e x ≤ y := e.rel_symm_apply @@ -941,6 +946,8 @@ protected theorem strictMono (e : α ≃o β) : StrictMono e := theorem lt_iff_lt (e : α ≃o β) {x y : α} : e x < e y ↔ x < y := e.toOrderEmbedding.lt_iff_lt +@[gcongr] protected alias ⟨_, GCongr.orderIso_apply_lt_apply⟩ := lt_iff_lt + /-- Converts an `OrderIso` into a `RelIso (<) (<)`. -/ def toRelIsoLT (e : α ≃o β) : ((· < ·) : α → α → Prop) ≃r ((· < ·) : β → β → Prop) := ⟨e.toEquiv, lt_iff_lt e⟩ From cc8cf2ffff4f61b00d30cd82f66d1728e95dc4c3 Mon Sep 17 00:00:00 2001 From: Mario Carneiro Date: Thu, 17 Oct 2024 15:04:03 +0000 Subject: [PATCH 318/425] feat: add `--force` flag to shake (#17453) to disable the `lake build --no-build` step. There have been [reports](https://leanprover.zulipchat.com/#narrow/stream/113488-general/topic/.60lake.20build.20--no-build.60.20at.20.60v4.2E13.2E0-rc3.60.20is.20broken.3F/near/474875999) that this step is somewhat flaky, so this option gives people the ability to skip it without turning off `shake` entirely. Co-authored-by: Mario Carneiro --- Shake/Main.lean | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Shake/Main.lean b/Shake/Main.lean index e5b7645a31d816..20a8f24e116f06 100644 --- a/Shake/Main.lean +++ b/Shake/Main.lean @@ -35,6 +35,9 @@ Arguments: provided module(s) will be checked. Options: + --force + Skips the `lake build --no-build` sanity check + --fix Apply the suggested fixes directly. Make sure you have a clean checkout before running this, so you can review the changes. @@ -380,6 +383,8 @@ def toBitset (s : State) (ns : List Name) : Bitset := structure Args where /-- `--help`: shows the help -/ help : Bool := false + /-- `--force`: skips the `lake build --no-build` sanity check -/ + force : Bool := false /-- `--no-downstream`: disables downstream mode -/ downstream : Bool := true /-- `--gh-style`: output messages that can be parsed by `gh-problem-matcher-wrap` -/ @@ -422,6 +427,7 @@ def main (args : List String) : IO UInt32 := do let rec parseArgs (args : Args) : List String → Args | [] => args | "--help" :: rest => parseArgs { args with help := true } rest + | "--force" :: rest => parseArgs { args with force := true } rest | "--no-downstream" :: rest => parseArgs { args with downstream := false } rest | "--fix" :: rest => parseArgs { args with fix := true } rest | "--explain" :: rest => parseArgs { args with explain := true } rest @@ -438,9 +444,10 @@ def main (args : List String) : IO UInt32 := do IO.println help IO.Process.exit 0 - if (← IO.Process.output { cmd := "lake", args := #["build", "--no-build"] }).exitCode != 0 then - IO.println "There are out of date oleans. Run `lake build` or `lake exe cache get` first" - IO.Process.exit 1 + if !args.force then + if (← IO.Process.output { cmd := "lake", args := #["build", "--no-build"] }).exitCode != 0 then + IO.println "There are out of date oleans. Run `lake build` or `lake exe cache get` first" + IO.Process.exit 1 -- Parse the `--cfg` argument let srcSearchPath ← initSrcSearchPath From 10e0d7deb5528d3e0eb8331b42f15f24b0559767 Mon Sep 17 00:00:00 2001 From: Anatole Dedecker Date: Thu, 17 Oct 2024 15:04:04 +0000 Subject: [PATCH 319/425] feat: seminorms for the product topology (#17493) --- Mathlib/Analysis/LocallyConvex/WithSeminorms.lean | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean b/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean index dff476482e1670..5238beff839923 100644 --- a/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean +++ b/Mathlib/Analysis/LocallyConvex/WithSeminorms.lean @@ -877,13 +877,22 @@ protected def SeminormFamily.sigma {κ : ι → Type*} (p : (i : ι) → Seminor theorem withSeminorms_iInf {κ : ι → Type*} [Nonempty ((i : ι) × κ i)] [∀ i, Nonempty (κ i)] {p : (i : ι) → SeminormFamily 𝕜 E (κ i)} {t : ι → TopologicalSpace E} - [∀ i, @TopologicalAddGroup E (t i) _] (hp : ∀ i, WithSeminorms (topology := t i) (p i)) : + (hp : ∀ i, WithSeminorms (topology := t i) (p i)) : WithSeminorms (topology := ⨅ i, t i) (SeminormFamily.sigma p) := by - have : @TopologicalAddGroup E (⨅ i, t i) _ := topologicalAddGroup_iInf (fun i ↦ inferInstance) + have : ∀ i, @TopologicalAddGroup E (t i) _ := + fun i ↦ @WithSeminorms.topologicalAddGroup _ _ _ _ _ _ _ (t i) _ (hp i) + have : @TopologicalAddGroup E (⨅ i, t i) _ := topologicalAddGroup_iInf inferInstance simp_rw [@SeminormFamily.withSeminorms_iff_topologicalSpace_eq_iInf _ _ _ _ _ _ _ (_)] at hp ⊢ rw [iInf_sigma] exact iInf_congr hp +theorem withSeminorms_pi {κ : ι → Type*} {E : ι → Type*} + [∀ i, AddCommGroup (E i)] [∀ i, Module 𝕜 (E i)] [∀ i, TopologicalSpace (E i)] + [Nonempty ((i : ι) × κ i)] [∀ i, Nonempty (κ i)] {p : (i : ι) → SeminormFamily 𝕜 (E i) (κ i)} + (hp : ∀ i, WithSeminorms (p i)) : + WithSeminorms (SeminormFamily.sigma (fun i ↦ (p i).comp (LinearMap.proj i))) := + withSeminorms_iInf fun i ↦ (LinearMap.proj i).withSeminorms_induced (hp i) + end TopologicalConstructions section TopologicalProperties From 9dd0528bdc2e9987bc51e623517606202d56f143 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Thu, 17 Oct 2024 15:04:05 +0000 Subject: [PATCH 320/425] feat(GroupTheory/Coset/Basic): products, `leftRel` and `rightRel` (#17585) Add lemmas relating `leftRel` and `rightRel` for a (pairwise or indexed) product of subgroups to the corresponding products of setoids. From AperiodicMonotilesLean. --- Mathlib/GroupTheory/Coset/Basic.lean | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Mathlib/GroupTheory/Coset/Basic.lean b/Mathlib/GroupTheory/Coset/Basic.lean index ab5461c4022dc9..e7aa809a354aea 100644 --- a/Mathlib/GroupTheory/Coset/Basic.lean +++ b/Mathlib/GroupTheory/Coset/Basic.lean @@ -262,6 +262,20 @@ instance leftRelDecidable [DecidablePred (· ∈ s)] : DecidableRel (leftRel s). rw [leftRel_eq] exact ‹DecidablePred (· ∈ s)› _ +@[to_additive] +lemma leftRel_prod {β : Type*} [Group β] (s' : Subgroup β) : + leftRel (s.prod s') = (leftRel s).prod (leftRel s') := by + refine Setoid.ext fun x y ↦ ?_ + rw [Setoid.prod_apply] + simp_rw [leftRel_apply] + rfl + +@[to_additive] +lemma leftRel_pi {ι : Type*} {β : ι → Type*} [∀ i, Group (β i)] (s' : ∀ i, Subgroup (β i)) : + leftRel (Subgroup.pi Set.univ s') = @piSetoid _ _ fun i ↦ leftRel (s' i) := by + refine Setoid.ext fun x y ↦ ?_ + simp [Setoid.piSetoid_apply, leftRel_apply, Subgroup.mem_pi] + /-- `α ⧸ s` is the quotient type representing the left cosets of `s`. If `s` is a normal subgroup, `α ⧸ s` is a group -/ @[to_additive "`α ⧸ s` is the quotient type representing the left cosets of `s`. If `s` is a normal @@ -304,6 +318,20 @@ instance rightRelDecidable [DecidablePred (· ∈ s)] : DecidableRel (rightRel s rw [rightRel_eq] exact ‹DecidablePred (· ∈ s)› _ +@[to_additive] +lemma rightRel_prod {β : Type*} [Group β] (s' : Subgroup β) : + rightRel (s.prod s') = (rightRel s).prod (rightRel s') := by + refine Setoid.ext fun x y ↦ ?_ + rw [Setoid.prod_apply] + simp_rw [rightRel_apply] + rfl + +@[to_additive] +lemma rightRel_pi {ι : Type*} {β : ι → Type*} [∀ i, Group (β i)] (s' : ∀ i, Subgroup (β i)) : + rightRel (Subgroup.pi Set.univ s') = @piSetoid _ _ fun i ↦ rightRel (s' i) := by + refine Setoid.ext fun x y ↦ ?_ + simp [Setoid.piSetoid_apply, rightRel_apply, Subgroup.mem_pi] + /-- Right cosets are in bijection with left cosets. -/ @[to_additive "Right cosets are in bijection with left cosets."] def quotientRightRelEquivQuotientLeftRel : Quotient (QuotientGroup.rightRel s) ≃ α ⧸ s where From f66852471cf4c2c6cb3b707dc1e9be6929360662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Thu, 17 Oct 2024 15:04:07 +0000 Subject: [PATCH 321/425] feat: translating the graph of a homomorphism (#17647) From PFR --- Mathlib/Data/Set/Pointwise/SMul.lean | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/Mathlib/Data/Set/Pointwise/SMul.lean b/Mathlib/Data/Set/Pointwise/SMul.lean index e3ed79c944b466..00fe29ebfea631 100644 --- a/Mathlib/Data/Set/Pointwise/SMul.lean +++ b/Mathlib/Data/Set/Pointwise/SMul.lean @@ -406,6 +406,32 @@ lemma smul_set_disjoint_iff : Disjoint (a • s) (a • t) ↔ Disjoint s t := b end Group +section Group +variable [Group α] [CommGroup β] [FunLike F α β] [MonoidHomClass F α β] + +@[to_additive] +lemma smul_graphOn (x : α × β) (s : Set α) (f : F) : + x • s.graphOn f = (x.1 • s).graphOn fun a ↦ x.2 / f x.1 * f a := by + ext ⟨a, b⟩ + simp [mem_smul_set_iff_inv_smul_mem, Prod.ext_iff, and_comm (a := _ = a), inv_mul_eq_iff_eq_mul, + mul_left_comm _ _⁻¹, eq_inv_mul_iff_mul_eq, ← mul_div_right_comm, div_eq_iff_eq_mul, mul_comm b] + +@[to_additive] +lemma smul_graphOn_univ (x : α × β) (f : F) : + x • univ.graphOn f = univ.graphOn fun a ↦ x.2 / f x.1 * f a := by simp [smul_graphOn] + +end Group + +section CommGroup +variable [CommGroup α] + +@[to_additive] lemma smul_div_smul_comm (a : α) (s : Set α) (b : α) (t : Set α) : + a • s / b • t = (a / b) • (s / t) := by + simp_rw [← image_smul, smul_eq_mul, ← singleton_mul, mul_div_mul_comm _ s, + singleton_div_singleton] + +end CommGroup + section GroupWithZero variable [GroupWithZero α] [MulAction α β] {s t : Set β} {a : α} From 1cfdb12acbfe9bb8e0c42aa6a32029b0ecb80b84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Thu, 17 Oct 2024 15:04:08 +0000 Subject: [PATCH 322/425] feat: Over a finite ring, a module is finite iff it is finite dimensional (#17707) From PFR --- Mathlib/FieldTheory/AxGrothendieck.lean | 3 +-- Mathlib/FieldTheory/PrimitiveElement.lean | 2 +- .../LinearAlgebra/FiniteDimensional/Defs.lean | 5 ----- Mathlib/RingTheory/Finiteness.lean | 22 +++++++++++++++++++ .../LocalRing/ResidueField/Basic.lean | 6 ++--- 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/Mathlib/FieldTheory/AxGrothendieck.lean b/Mathlib/FieldTheory/AxGrothendieck.lean index e386e095dad395..9ddfa55c77de33 100644 --- a/Mathlib/FieldTheory/AxGrothendieck.lean +++ b/Mathlib/FieldTheory/AxGrothendieck.lean @@ -48,8 +48,7 @@ theorem ax_grothendieck_of_locally_finite {ι K R : Type*} [Field K] [Finite K] (mem_union_left _ (mem_biUnion.2 ⟨i, mem_univ _, mem_image_of_mem _ hk⟩)) letI := isNoetherian_adjoin_finset s fun x _ => Algebra.IsIntegral.isIntegral (R := K) x letI := Module.IsNoetherian.finite K (Algebra.adjoin K (s : Set R)) - letI : Finite (Algebra.adjoin K (s : Set R)) := - FiniteDimensional.finite_of_finite K (Algebra.adjoin K (s : Set R)) + letI : Finite (Algebra.adjoin K (s : Set R)) := Module.finite_of_finite K -- The restriction of the polynomial map, `ps`, to the subalgebra generated by `s` let res : (ι → Algebra.adjoin K (s : Set R)) → ι → Algebra.adjoin K (s : Set R) := fun x i => ⟨eval (fun j : ι => (x j : R)) (ps i), eval_mem (hs₁ _) fun i => (x i).2⟩ diff --git a/Mathlib/FieldTheory/PrimitiveElement.lean b/Mathlib/FieldTheory/PrimitiveElement.lean index da215b5d8dbf44..09b73357bf4f2a 100644 --- a/Mathlib/FieldTheory/PrimitiveElement.lean +++ b/Mathlib/FieldTheory/PrimitiveElement.lean @@ -63,7 +63,7 @@ theorem exists_primitive_element_of_finite_top [Finite E] : ∃ α : E, F⟮α /-- Primitive element theorem for finite dimensional extension of a finite field. -/ theorem exists_primitive_element_of_finite_bot [Finite F] [FiniteDimensional F E] : ∃ α : E, F⟮α⟯ = ⊤ := - haveI : Finite E := FiniteDimensional.finite_of_finite F E + haveI : Finite E := Module.finite_of_finite F exists_primitive_element_of_finite_top F E end PrimitiveElementFinite diff --git a/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean b/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean index 2bce02c0a50fc6..14b5f34c2a2b3b 100644 --- a/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean +++ b/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean @@ -107,11 +107,6 @@ instance finiteDimensional_pi' {ι : Type*} [Finite ι] (M : ι → Type*) [∀ noncomputable def fintypeOfFintype [Fintype K] [FiniteDimensional K V] : Fintype V := Module.fintypeOfFintype (@finsetBasis K V _ _ _ (iff_fg.2 inferInstance)) -theorem finite_of_finite [Finite K] [FiniteDimensional K V] : Finite V := by - cases nonempty_fintype K - haveI := fintypeOfFintype K V - infer_instance - variable {K V} /-- If a vector space has a finite basis, then it is finite-dimensional. -/ diff --git a/Mathlib/RingTheory/Finiteness.lean b/Mathlib/RingTheory/Finiteness.lean index 1425279d2a6741..264b1bb8d9350f 100644 --- a/Mathlib/RingTheory/Finiteness.lean +++ b/Mathlib/RingTheory/Finiteness.lean @@ -537,6 +537,22 @@ lemma exists_fin' [Module.Finite R M] : ∃ (n : ℕ) (f : (Fin n → R) →ₗ[ refine ⟨n, Basis.constr (Pi.basisFun R _) ℕ s, ?_⟩ rw [← LinearMap.range_eq_top, Basis.constr_range, hs] +variable (R) in +lemma _root_.Module.finite_of_finite [Finite R] [Module.Finite R M] : Finite M := by + obtain ⟨n, f, hf⟩ := exists_fin' R M; exact .of_surjective f hf + +@[deprecated (since := "2024-10-13")] +alias _root_.FiniteDimensional.finite_of_finite := finite_of_finite + +-- See note [lower instance priority] +instance (priority := 100) of_finite [Finite M] : Module.Finite R M := by + cases nonempty_fintype M + exact ⟨⟨Finset.univ, by rw [Finset.coe_univ]; exact Submodule.span_univ⟩⟩ + +/-- A module over a finite ring has finite dimension iff it is finite. -/ +lemma _root_.Module.finite_iff_finite [Finite R] : Module.Finite R M ↔ Finite M := + ⟨fun _ ↦ finite_of_finite R, fun _ ↦ .of_finite⟩ + theorem of_surjective [hM : Module.Finite R M] (f : M →ₗ[R] N) (hf : Surjective f) : Module.Finite R N := ⟨by @@ -620,6 +636,12 @@ instance span_singleton (x : M) : Module.Finite R (R ∙ x) := instance span_finset (s : Finset M) : Module.Finite R (span R (s : Set M)) := ⟨(Submodule.fg_top _).mpr ⟨s, rfl⟩⟩ +lemma _root_.Set.Finite.submoduleSpan [Finite R] {s : Set M} (hs : s.Finite) : + (Submodule.span R s : Set M).Finite := by + lift s to Finset M using hs + rw [Set.Finite, ← Module.finite_iff_finite (R := R)] + dsimp + infer_instance theorem Module.End.isNilpotent_iff_of_finite {R M : Type*} [CommSemiring R] [AddCommMonoid M] [Module R M] [Module.Finite R M] {f : End R M} : diff --git a/Mathlib/RingTheory/LocalRing/ResidueField/Basic.lean b/Mathlib/RingTheory/LocalRing/ResidueField/Basic.lean index 885d727ff53f42..ca824388493096 100644 --- a/Mathlib/RingTheory/LocalRing/ResidueField/Basic.lean +++ b/Mathlib/RingTheory/LocalRing/ResidueField/Basic.lean @@ -166,10 +166,10 @@ instance finiteDimensional_of_noetherian [IsNoetherian R S] : (LinearMap.range_eq_top.mpr Ideal.Quotient.mk_surjective) exact Algebra.algebra_ext _ _ (fun r => rfl) +-- We want to be able to refer to `hfin` +set_option linter.unusedVariables false in lemma finite_of_finite [IsNoetherian R S] (hfin : Finite (ResidueField R)) : - Finite (ResidueField S) := by - have := @finiteDimensional_of_noetherian R S - exact FiniteDimensional.finite_of_finite (ResidueField R) (ResidueField S) + Finite (ResidueField S) := Module.finite_of_finite (ResidueField R) end FiniteDimensional From 0d150bcbee58d7d46b6d72a2ee0f113c00e3ec34 Mon Sep 17 00:00:00 2001 From: Dagur Asgeirsson Date: Thu, 17 Oct 2024 15:04:10 +0000 Subject: [PATCH 323/425] chore(CategoryTheory/Sites): add some tests for sheafcompose instances (#17817) This PR adds a few tests to make sure that there are `HasSheafCompose` instances for the forgetful functor from modules to sets, for different size restrictions on the defining site. --- test/CategoryTheory/Sites/Whiskering.lean | 28 +++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 test/CategoryTheory/Sites/Whiskering.lean diff --git a/test/CategoryTheory/Sites/Whiskering.lean b/test/CategoryTheory/Sites/Whiskering.lean new file mode 100644 index 00000000000000..af2efea006a9d8 --- /dev/null +++ b/test/CategoryTheory/Sites/Whiskering.lean @@ -0,0 +1,28 @@ +import Mathlib.Algebra.Category.ModuleCat.Colimits +import Mathlib.Algebra.Category.ModuleCat.Limits +import Mathlib.Algebra.Category.ModuleCat.FilteredColimits +import Mathlib.CategoryTheory.Sites.Equivalence + +universe u + +open CategoryTheory GrothendieckTopology + +section Small + +variable {C : Type u} [SmallCategory C] (J : GrothendieckTopology C) (R : Type u) [Ring R] + +example : HasSheafCompose J (forget (ModuleCat.{u} R)) := inferInstance + +end Small + +section Large + +variable {C : Type (u+1)} [LargeCategory C] (J : GrothendieckTopology C) + +example (R : Type (u+1)) [Ring R] : HasSheafCompose J (forget (ModuleCat.{u+1} R)) := inferInstance + +variable [EssentiallySmall.{u} C] + +example (R : Type u) [Ring R] : HasSheafCompose J (forget (ModuleCat.{u} R)) := inferInstance + +end Large From c9b69692d65d8b44e452ca4692ed9b04eb5e463f Mon Sep 17 00:00:00 2001 From: Dagur Asgeirsson Date: Thu, 17 Oct 2024 15:04:11 +0000 Subject: [PATCH 324/425] chore(CategoryTheory/Sites): add some tests for preserving sheafification (#17818) This PR adds a few tests to make sure that there are `PreservesSheafification` instances for the forgetful functor from modules to sets, for different size restrictions on the defining site. --- .../Sites/PreservesSheafification.lean | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 test/CategoryTheory/Sites/PreservesSheafification.lean diff --git a/test/CategoryTheory/Sites/PreservesSheafification.lean b/test/CategoryTheory/Sites/PreservesSheafification.lean new file mode 100644 index 00000000000000..813746eb759e59 --- /dev/null +++ b/test/CategoryTheory/Sites/PreservesSheafification.lean @@ -0,0 +1,30 @@ +import Mathlib.Algebra.Category.ModuleCat.Colimits +import Mathlib.Algebra.Category.ModuleCat.Limits +import Mathlib.Algebra.Category.ModuleCat.FilteredColimits +import Mathlib.CategoryTheory.Sites.Equivalence + +universe u + +open CategoryTheory GrothendieckTopology + +section Small + +variable {C : Type u} [SmallCategory C] (J : GrothendieckTopology C) (R : Type u) [Ring R] + +example : PreservesSheafification J (forget (ModuleCat.{u} R)) := inferInstance + +end Small + +section Large + +variable {C : Type (u+1)} [LargeCategory C] (J : GrothendieckTopology C) + +example (R : Type (u+1)) [Ring R] : PreservesSheafification J (forget (ModuleCat.{u+1} R)) := + inferInstance + +variable [EssentiallySmall.{u} C] + +example (R : Type u) [Ring R] : PreservesSheafification J (forget (ModuleCat.{u} R)) := + inferInstance + +end Large From a70b960b28617ef85de0b08c7cb24b3f92dcc964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Thu, 17 Oct 2024 15:04:12 +0000 Subject: [PATCH 325/425] feat: the filtration of cylinder events (#17858) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The exterior σ-algebras of finite sets of `α` form a cofiltration indexed by `Finset α` From GibbsMeasure Co-authored-by: Kin Yau James Wong --- Mathlib/Probability/Process/Filtration.lean | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Mathlib/Probability/Process/Filtration.lean b/Mathlib/Probability/Process/Filtration.lean index cc95366031c1b5..853bae3ead907f 100644 --- a/Mathlib/Probability/Process/Filtration.lean +++ b/Mathlib/Probability/Process/Filtration.lean @@ -3,6 +3,7 @@ Copyright (c) 2021 Kexing Ying. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Kexing Ying, Rémy Degenne -/ +import Mathlib.MeasureTheory.Constructions.Cylinders import Mathlib.MeasureTheory.Function.ConditionalExpectation.Real /-! @@ -328,6 +329,14 @@ alias memℒp_limitProcess_of_snorm_bdd := memℒp_limitProcess_of_eLpNorm_bdd end Limit +variable {α : Type*} + +/-- The exterior σ-algebras of finite sets of `α` form a cofiltration indexed by `Finset α`. -/ +def cylinderEventsCompl : Filtration (Finset α)ᵒᵈ (.pi (π := fun _ : α ↦ Ω)) where + seq Λ := cylinderEvents (↑(OrderDual.ofDual Λ))ᶜ + mono' _ _ h := cylinderEvents_mono <| Set.compl_subset_compl_of_subset h + le' _ := cylinderEvents_le_pi + end Filtration end MeasureTheory From 3f297f53816d8a85d03f8c08b3a7d475dfa51a6b Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Thu, 17 Oct 2024 15:04:13 +0000 Subject: [PATCH 326/425] chore: remove porting notes about adding/removing `@[ext]` attributes (#17873) Discussed with @jcommelin and @kim-em. All of these porting notes are about the change in behaviour of the `ext` tactic and attribute between Lean 3 and Lean 4: in Lean 4 it only accepts lemmas with conclusion `x = y` with `x` and `y` free variables, and only applies these if the types are reducibly equal. Since those behaviours are not likely to change in the future, we don't need to keep these porting notes. I propose that we should keep #11041 since it indicates where these `ext` lemmas have not yet been added. Closes: #5229 Closes: #11182 --- Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean | 1 - Mathlib/Algebra/Group/AddChar.lean | 1 - Mathlib/Algebra/Homology/HomologicalComplex.lean | 1 - Mathlib/Algebra/Polynomial/Laurent.lean | 1 - Mathlib/AlgebraicTopology/SimplexCategory.lean | 1 - Mathlib/AlgebraicTopology/SimplicialSet/Basic.lean | 2 -- Mathlib/AlgebraicTopology/SplitSimplicialObject.lean | 1 - Mathlib/CategoryTheory/Abelian/Pseudoelements.lean | 6 ------ .../Bicategory/NaturalTransformation/Oplax.lean | 1 - Mathlib/CategoryTheory/Comma/Basic.lean | 2 -- Mathlib/CategoryTheory/Comma/StructuredArrow.lean | 4 ---- Mathlib/CategoryTheory/Elements.lean | 1 - Mathlib/CategoryTheory/Endomorphism.lean | 1 - Mathlib/CategoryTheory/Functor/Category.lean | 4 ---- Mathlib/CategoryTheory/Idempotents/Karoubi.lean | 1 - Mathlib/CategoryTheory/Iso.lean | 4 ---- Mathlib/CategoryTheory/Limits/Cones.lean | 2 -- Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean | 2 -- Mathlib/CategoryTheory/Monoidal/Bimod.lean | 1 - Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean | 2 -- Mathlib/CategoryTheory/Monoidal/CommMon_.lean | 2 -- Mathlib/CategoryTheory/Monoidal/Mod_.lean | 1 - Mathlib/CategoryTheory/Monoidal/Mon_.lean | 1 - Mathlib/CategoryTheory/Monoidal/NaturalTransformation.lean | 1 - Mathlib/CategoryTheory/MorphismProperty/IsInvertedBy.lean | 2 -- Mathlib/CategoryTheory/Pi/Basic.lean | 1 - Mathlib/CategoryTheory/Preadditive/Mat.lean | 3 --- Mathlib/CategoryTheory/Sites/Sheaf.lean | 1 - Mathlib/CategoryTheory/Subobject/Basic.lean | 3 --- Mathlib/CategoryTheory/Yoneda.lean | 4 ---- Mathlib/Geometry/RingedSpace/PresheafedSpace.lean | 1 - Mathlib/Geometry/RingedSpace/SheafedSpace.lean | 1 - Mathlib/RepresentationTheory/Action/Basic.lean | 1 - 33 files changed, 61 deletions(-) diff --git a/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean b/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean index c3f9a38ef087e7..7d7e0e34c73afd 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Adjunctions.lean @@ -365,7 +365,6 @@ def embeddingLiftIso (F : C ⥤ D) : embedding R C ⋙ lift R F ≅ F := /-- Two `R`-linear functors out of the `R`-linear completion are isomorphic iff their compositions with the embedding functor are isomorphic. -/ --- Porting note (#11182): used to be @[ext] def ext {F G : Free R C ⥤ D} [F.Additive] [F.Linear R] [G.Additive] [G.Linear R] (α : embedding R C ⋙ F ≅ embedding R C ⋙ G) : F ≅ G := NatIso.ofComponents (fun X => α.app X) diff --git a/Mathlib/Algebra/Group/AddChar.lean b/Mathlib/Algebra/Group/AddChar.lean index f9a1d383c185c8..23df07dbc7f897 100644 --- a/Mathlib/Algebra/Group/AddChar.lean +++ b/Mathlib/Algebra/Group/AddChar.lean @@ -88,7 +88,6 @@ instance instFunLike : FunLike (AddChar A M) A M where coe := AddChar.toFun coe_injective' φ ψ h := by cases φ; cases ψ; congr --- Porting note (#5229): added. @[ext] lemma ext (f g : AddChar A M) (h : ∀ x : A, f x = g x) : f = g := DFunLike.ext f g h diff --git a/Mathlib/Algebra/Homology/HomologicalComplex.lean b/Mathlib/Algebra/Homology/HomologicalComplex.lean index 6ea13712672bd3..441c75acfbc026 100644 --- a/Mathlib/Algebra/Homology/HomologicalComplex.lean +++ b/Mathlib/Algebra/Homology/HomologicalComplex.lean @@ -244,7 +244,6 @@ instance : Category (HomologicalComplex V c) where end --- Porting note (#5229): added because `Hom.ext` is not triggered automatically @[ext] lemma hom_ext {C D : HomologicalComplex V c} (f g : C ⟶ D) (h : ∀ i, f.f i = g.f i) : f = g := by diff --git a/Mathlib/Algebra/Polynomial/Laurent.lean b/Mathlib/Algebra/Polynomial/Laurent.lean index 949d81ecba0315..c231267f42556c 100644 --- a/Mathlib/Algebra/Polynomial/Laurent.lean +++ b/Mathlib/Algebra/Polynomial/Laurent.lean @@ -87,7 +87,6 @@ scoped[LaurentPolynomial] notation:9000 R "[T;T⁻¹]" => LaurentPolynomial R open LaurentPolynomial --- Porting note (#5229): `ext` no longer applies `Finsupp.ext` automatically @[ext] theorem LaurentPolynomial.ext [Semiring R] {p q : R[T;T⁻¹]} (h : ∀ a, p a = q a) : p = q := Finsupp.ext h diff --git a/Mathlib/AlgebraicTopology/SimplexCategory.lean b/Mathlib/AlgebraicTopology/SimplexCategory.lean index ac2101ce20054f..72bc3cc1929136 100644 --- a/Mathlib/AlgebraicTopology/SimplexCategory.lean +++ b/Mathlib/AlgebraicTopology/SimplexCategory.lean @@ -142,7 +142,6 @@ lemma id_toOrderHom (a : SimplexCategory) : lemma comp_toOrderHom {a b c : SimplexCategory} (f : a ⟶ b) (g : b ⟶ c) : (f ≫ g).toOrderHom = g.toOrderHom.comp f.toOrderHom := rfl --- Porting note (#5229): added because `Hom.ext'` is not triggered automatically @[ext] theorem Hom.ext {a b : SimplexCategory} (f g : a ⟶ b) : f.toOrderHom = g.toOrderHom → f = g := diff --git a/Mathlib/AlgebraicTopology/SimplicialSet/Basic.lean b/Mathlib/AlgebraicTopology/SimplicialSet/Basic.lean index b11a417a297e74..32b22e7b91ce50 100644 --- a/Mathlib/AlgebraicTopology/SimplicialSet/Basic.lean +++ b/Mathlib/AlgebraicTopology/SimplicialSet/Basic.lean @@ -57,7 +57,6 @@ instance hasColimits : HasColimits SSet := by dsimp only [SSet] infer_instance --- Porting note (#5229): added an `ext` lemma. @[ext] lemma hom_ext {X Y : SSet} {f g : X ⟶ Y} (w : ∀ n, f.app n = g.app n) : f = g := SimplicialObject.hom_ext _ _ w @@ -354,7 +353,6 @@ simplicial sets. -/ def Truncated.uliftFunctor (k : ℕ) : SSet.Truncated.{u} k ⥤ SSet.Truncated.{max u v} k := (whiskeringRight _ _ _).obj CategoryTheory.uliftFunctor.{v, u} --- Porting note (#5229): added an `ext` lemma. @[ext] lemma Truncated.hom_ext {n : ℕ} {X Y : Truncated n} {f g : X ⟶ Y} (w : ∀ n, f.app n = g.app n) : f = g := diff --git a/Mathlib/AlgebraicTopology/SplitSimplicialObject.lean b/Mathlib/AlgebraicTopology/SplitSimplicialObject.lean index 48c6023dd10539..7d8574e79627f1 100644 --- a/Mathlib/AlgebraicTopology/SplitSimplicialObject.lean +++ b/Mathlib/AlgebraicTopology/SplitSimplicialObject.lean @@ -351,7 +351,6 @@ variable {C} namespace Split --- Porting note (#5229): added as `Hom.ext` is not triggered automatically @[ext] theorem hom_ext {S₁ S₂ : Split C} (Φ₁ Φ₂ : S₁ ⟶ S₂) (h : ∀ n : ℕ, Φ₁.f n = Φ₂.f n) : Φ₁ = Φ₂ := Hom.ext _ _ h diff --git a/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean b/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean index 7c2ed530109620..7bb3ceaced8e1a 100644 --- a/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean +++ b/Mathlib/CategoryTheory/Abelian/Pseudoelements.lean @@ -258,12 +258,6 @@ theorem zero_morphism_ext {P Q : C} (f : P ⟶ Q) : (∀ a, f a = 0) → f = 0 : theorem zero_morphism_ext' {P Q : C} (f : P ⟶ Q) : (∀ a, f a = 0) → 0 = f := Eq.symm ∘ zero_morphism_ext f --- Porting note (#11182): these are no longer valid as `ext` lemmas. --- scoped[Pseudoelement] --- attribute [ext] --- CategoryTheory.Abelian.Pseudoelement.zero_morphism_ext --- CategoryTheory.Abelian.Pseudoelement.zero_morphism_ext' - 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 _⟩ diff --git a/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Oplax.lean b/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Oplax.lean index 2d6217112669a1..ee6b3cb99b45e5 100644 --- a/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Oplax.lean +++ b/Mathlib/CategoryTheory/Bicategory/NaturalTransformation/Oplax.lean @@ -245,7 +245,6 @@ instance category (F G : OplaxFunctor B C) : Category (F ⟶ G) where id := Modification.id comp := Modification.vcomp --- Porting note (#5229): duplicating the `ext` lemma. @[ext] lemma ext {F G : OplaxFunctor B C} {α β : F ⟶ G} {m n : α ⟶ β} (w : ∀ b, m.app b = n.app b) : m = n := by diff --git a/Mathlib/CategoryTheory/Comma/Basic.lean b/Mathlib/CategoryTheory/Comma/Basic.lean index 74eebe08f5cf9f..192ef0e4606e0d 100644 --- a/Mathlib/CategoryTheory/Comma/Basic.lean +++ b/Mathlib/CategoryTheory/Comma/Basic.lean @@ -106,8 +106,6 @@ section variable {X Y Z : Comma L R} {f : X ⟶ Y} {g : Y ⟶ Z} --- Porting note (#5229): this lemma was added because `CommaMorphism.ext` --- was not triggered automatically @[ext] lemma hom_ext (f g : X ⟶ Y) (h₁ : f.left = g.left) (h₂ : f.right = g.right) : f = g := CommaMorphism.ext h₁ h₂ diff --git a/Mathlib/CategoryTheory/Comma/StructuredArrow.lean b/Mathlib/CategoryTheory/Comma/StructuredArrow.lean index 3ee2b719536a81..d86b41669eacf8 100644 --- a/Mathlib/CategoryTheory/Comma/StructuredArrow.lean +++ b/Mathlib/CategoryTheory/Comma/StructuredArrow.lean @@ -51,8 +51,6 @@ def proj (S : D) (T : C ⥤ D) : StructuredArrow S T ⥤ C := variable {S S' S'' : D} {Y Y' Y'' : C} {T T' : C ⥤ D} --- Porting note (#5229): this lemma was added because `Comma.hom_ext` --- was not triggered automatically @[ext] lemma hom_ext {X Y : StructuredArrow S T} (f g : X ⟶ Y) (h : f.right = g.right) : f = g := CommaMorphism.ext (Subsingleton.elim _ _) h @@ -400,8 +398,6 @@ def proj (S : C ⥤ D) (T : D) : CostructuredArrow S T ⥤ C := variable {T T' T'' : D} {Y Y' Y'' : C} {S S' : C ⥤ D} --- Porting note (#5229): this lemma was added because `Comma.hom_ext` --- was not triggered automatically @[ext] lemma hom_ext {X Y : CostructuredArrow S T} (f g : X ⟶ Y) (h : f.left = g.left) : f = g := CommaMorphism.ext h (Subsingleton.elim _ _) diff --git a/Mathlib/CategoryTheory/Elements.lean b/Mathlib/CategoryTheory/Elements.lean index 588561a7941f82..cf261e1d8d7fc0 100644 --- a/Mathlib/CategoryTheory/Elements.lean +++ b/Mathlib/CategoryTheory/Elements.lean @@ -47,7 +47,6 @@ 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⟩ --- Porting note (#5229): added because Sigma.ext would be triggered automatically 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 diff --git a/Mathlib/CategoryTheory/Endomorphism.lean b/Mathlib/CategoryTheory/Endomorphism.lean index 4845f0a202a033..0ab626814ae998 100644 --- a/Mathlib/CategoryTheory/Endomorphism.lean +++ b/Mathlib/CategoryTheory/Endomorphism.lean @@ -114,7 +114,6 @@ def Aut (X : C) := X ≅ X namespace Aut --- Porting note (#5229): added because `Iso.ext` is not triggered automatically @[ext] lemma ext {X : C} {φ₁ φ₂ : Aut X} (h : φ₁.hom = φ₂.hom) : φ₁ = φ₂ := Iso.ext h diff --git a/Mathlib/CategoryTheory/Functor/Category.lean b/Mathlib/CategoryTheory/Functor/Category.lean index e1bd5dc1cfab1b..7a1687ae5667d0 100644 --- a/Mathlib/CategoryTheory/Functor/Category.lean +++ b/Mathlib/CategoryTheory/Functor/Category.lean @@ -48,10 +48,6 @@ instance Functor.category : Category.{max u₁ v₂} (C ⥤ D) where namespace NatTrans --- Porting note (#5229): the behaviour of `ext` has changed here. --- We need to provide a copy of the `NatTrans.ext` lemma, --- written in terms of `F ⟶ G` rather than `NatTrans F G`, --- or `ext` will not retrieve it from the cache. @[ext] theorem ext' {α β : F ⟶ G} (w : α.app = β.app) : α = β := NatTrans.ext w diff --git a/Mathlib/CategoryTheory/Idempotents/Karoubi.lean b/Mathlib/CategoryTheory/Idempotents/Karoubi.lean index abcded134084eb..b08afa205a73aa 100644 --- a/Mathlib/CategoryTheory/Idempotents/Karoubi.lean +++ b/Mathlib/CategoryTheory/Idempotents/Karoubi.lean @@ -101,7 +101,6 @@ theorem hom_ext_iff {P Q : Karoubi C} {f g : P ⟶ Q} : f = g ↔ f.f = g.f := b rw [h] · apply Hom.ext --- Porting note (#5229): added because `Hom.ext` is not triggered automatically @[ext] theorem hom_ext {P Q : Karoubi C} (f g : P ⟶ Q) (h : f.f = g.f) : f = g := by simpa [hom_ext_iff] using h diff --git a/Mathlib/CategoryTheory/Iso.lean b/Mathlib/CategoryTheory/Iso.lean index 7ce50b850ef49b..6e0dd598bc818b 100644 --- a/Mathlib/CategoryTheory/Iso.lean +++ b/Mathlib/CategoryTheory/Iso.lean @@ -305,7 +305,6 @@ instance (priority := 100) mono_of_iso (f : X ⟶ Y) [IsIso f] : Mono f where rw [← Category.comp_id g, ← Category.comp_id h, ← IsIso.hom_inv_id f, ← Category.assoc, w, ← Category.assoc] --- Porting note (#11182): `@[ext]` used to accept lemmas like this. Now we add an aesop rule @[aesop apply safe (rule_sets := [CategoryTheory])] theorem inv_eq_of_hom_inv_id {f : X ⟶ Y} [IsIso f] {g : Y ⟶ X} (hom_inv_id : f ≫ g = 𝟙 X) : inv f = g := by @@ -317,7 +316,6 @@ theorem inv_eq_of_inv_hom_id {f : X ⟶ Y} [IsIso f] {g : Y ⟶ X} (inv_hom_id : apply (cancel_mono f).mp simp [inv_hom_id] --- Porting note (#11182): `@[ext]` used to accept lemmas like this. @[aesop apply safe (rule_sets := [CategoryTheory])] theorem eq_inv_of_hom_inv_id {f : X ⟶ Y} [IsIso f] {g : Y ⟶ X} (hom_inv_id : f ≫ g = 𝟙 X) : g = inv f := @@ -446,12 +444,10 @@ theorem isIso_of_comp_hom_eq_id (g : X ⟶ Y) [IsIso g] {f : Y ⟶ X} (h : f ≫ namespace Iso --- Porting note (#11182): `@[ext]` used to accept lemmas like this. @[aesop apply safe (rule_sets := [CategoryTheory])] theorem inv_ext {f : X ≅ Y} {g : Y ⟶ X} (hom_inv_id : f.hom ≫ g = 𝟙 X) : f.inv = g := ((hom_comp_eq_id f).1 hom_inv_id).symm --- Porting note (#11182): `@[ext]` used to accept lemmas like this. @[aesop apply safe (rule_sets := [CategoryTheory])] theorem inv_ext' {f : X ≅ Y} {g : Y ⟶ X} (hom_inv_id : f.hom ≫ g = 𝟙 X) : g = f.inv := (hom_comp_eq_id f).1 hom_inv_id diff --git a/Mathlib/CategoryTheory/Limits/Cones.lean b/Mathlib/CategoryTheory/Limits/Cones.lean index 098f9f7adcb6a2..36d559c2f7911c 100644 --- a/Mathlib/CategoryTheory/Limits/Cones.lean +++ b/Mathlib/CategoryTheory/Limits/Cones.lean @@ -283,7 +283,6 @@ namespace Cones /-- To give an isomorphism between cones, it suffices to give an isomorphism between their vertices which commutes with the cone maps. -/ --- Porting note (#11182): `@[ext]` used to accept lemmas like this. Now we add an aesop rule @[aesop apply safe (rule_sets := [CategoryTheory]), simps] def ext {c c' : Cone F} (φ : c.pt ≅ c'.pt) (w : ∀ j, c.π.app j = φ.hom ≫ c'.π.app j := by aesop_cat) : c ≅ c' where @@ -484,7 +483,6 @@ namespace Cocones /-- To give an isomorphism between cocones, it suffices to give an isomorphism between their vertices which commutes with the cocone maps. -/ --- Porting note (#11182): `@[ext]` used to accept lemmas like this. Now we add an aesop rule @[aesop apply safe (rule_sets := [CategoryTheory]), simps] def ext {c c' : Cocone F} (φ : c.pt ≅ c'.pt) (w : ∀ j, c.ι.app j ≫ φ.hom = c'.ι.app j := by aesop_cat) : c ≅ c' where diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean b/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean index 2d164996009819..f290e6be943036 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean @@ -122,7 +122,6 @@ namespace Bicones /-- To give an isomorphism between cocones, it suffices to give an isomorphism between their vertices which commutes with the cocone maps. -/ --- Porting note (#11182): `@[ext]` used to accept lemmas like this. Now we add an aesop rule @[aesop apply safe (rule_sets := [CategoryTheory]), simps] def ext {c c' : Bicone F} (φ : c.pt ≅ c'.pt) (wι : ∀ j, c.ι j ≫ φ.hom = c'.ι j := by aesop_cat) @@ -1119,7 +1118,6 @@ namespace BinaryBicones /-- To give an isomorphism between cocones, it suffices to give an isomorphism between their vertices which commutes with the cocone maps. -/ --- Porting note (#11182): `@[ext]` used to accept lemmas like this. Now we add an aesop rule @[aesop apply safe (rule_sets := [CategoryTheory]), simps] def ext {P Q : C} {c c' : BinaryBicone P Q} (φ : c.pt ≅ c'.pt) (winl : c.inl ≫ φ.hom = c'.inl := by aesop_cat) diff --git a/Mathlib/CategoryTheory/Monoidal/Bimod.lean b/Mathlib/CategoryTheory/Monoidal/Bimod.lean index b6d566f92f32a4..6182c9de23c171 100644 --- a/Mathlib/CategoryTheory/Monoidal/Bimod.lean +++ b/Mathlib/CategoryTheory/Monoidal/Bimod.lean @@ -120,7 +120,6 @@ instance : Category (Bimod A B) where id := id' comp f g := comp f g --- Porting note (#5229): added because `Hom.ext` is not triggered automatically @[ext] lemma hom_ext {M N : Bimod A B} (f g : M ⟶ N) (h : f.hom = g.hom) : f = g := Hom.ext h diff --git a/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean b/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean index c0dfcace9f9a67..ee91313dea7f38 100644 --- a/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean +++ b/Mathlib/CategoryTheory/Monoidal/Braided/Basic.lean @@ -399,7 +399,6 @@ def comp (F : LaxBraidedFunctor C D) (G : LaxBraidedFunctor D E) : LaxBraidedFun instance categoryLaxBraidedFunctor : Category (LaxBraidedFunctor C D) := InducedCategory.category LaxBraidedFunctor.toLaxMonoidalFunctor --- Porting note (#5229): added, as `MonoidalNatTrans.ext` does not apply to morphisms. @[ext] lemma ext' {F G : LaxBraidedFunctor C D} {α β : F ⟶ G} (w : ∀ X : C, α.app X = β.app X) : α = β := MonoidalNatTrans.ext (funext w) @@ -463,7 +462,6 @@ def comp (F : BraidedFunctor C D) (G : BraidedFunctor D E) : BraidedFunctor C E instance categoryBraidedFunctor : Category (BraidedFunctor C D) := InducedCategory.category BraidedFunctor.toMonoidalFunctor --- Porting note (#5229): added, as `MonoidalNatTrans.ext` does not apply to morphisms. @[ext] lemma ext' {F G : BraidedFunctor C D} {α β : F ⟶ G} (w : ∀ X : C, α.app X = β.app X) : α = β := MonoidalNatTrans.ext (funext w) diff --git a/Mathlib/CategoryTheory/Monoidal/CommMon_.lean b/Mathlib/CategoryTheory/Monoidal/CommMon_.lean index b8a3c549ea9119..95ff7663a64763 100644 --- a/Mathlib/CategoryTheory/Monoidal/CommMon_.lean +++ b/Mathlib/CategoryTheory/Monoidal/CommMon_.lean @@ -50,8 +50,6 @@ theorem comp_hom {R S T : CommMon_ C} (f : R ⟶ S) (g : S ⟶ T) : Mon_.Hom.hom (f ≫ g) = f.hom ≫ g.hom := rfl --- Porting note (#5229): added because `Mon_.Hom.ext` is not triggered automatically --- for morphisms in `CommMon_ C` @[ext] lemma hom_ext {A B : CommMon_ C} (f g : A ⟶ B) (h : f.hom = g.hom) : f = g := Mon_.Hom.ext h diff --git a/Mathlib/CategoryTheory/Monoidal/Mod_.lean b/Mathlib/CategoryTheory/Monoidal/Mod_.lean index bee5d1a324c2f2..ec6327ca229173 100644 --- a/Mathlib/CategoryTheory/Monoidal/Mod_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Mod_.lean @@ -57,7 +57,6 @@ instance : Category (Mod_ A) where id := id comp f g := comp f g --- Porting note (#5229): added because `Hom.ext` is not triggered automatically @[ext] lemma hom_ext {M N : Mod_ A} (f₁ f₂ : M ⟶ N) (h : f₁.hom = f₂.hom) : f₁ = f₂ := Hom.ext h diff --git a/Mathlib/CategoryTheory/Monoidal/Mon_.lean b/Mathlib/CategoryTheory/Monoidal/Mon_.lean index 82f033d04a0451..fc0cec7c2faf79 100644 --- a/Mathlib/CategoryTheory/Monoidal/Mon_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Mon_.lean @@ -104,7 +104,6 @@ instance : Category (Mon_ C) where id := id comp f g := comp f g --- Porting note (#5229): added, as `Hom.ext` does not apply to a morphism. @[ext] lemma ext {X Y : Mon_ C} {f g : X ⟶ Y} (w : f.hom = g.hom) : f = g := Hom.ext w diff --git a/Mathlib/CategoryTheory/Monoidal/NaturalTransformation.lean b/Mathlib/CategoryTheory/Monoidal/NaturalTransformation.lean index 4d73ab1b96ac53..d41970b4598908 100644 --- a/Mathlib/CategoryTheory/Monoidal/NaturalTransformation.lean +++ b/Mathlib/CategoryTheory/Monoidal/NaturalTransformation.lean @@ -81,7 +81,6 @@ theorem comp_toNatTrans_lax {F G H : LaxMonoidalFunctor C D} {α : F ⟶ G} {β instance categoryMonoidalFunctor : Category (MonoidalFunctor C D) := InducedCategory.category MonoidalFunctor.toLaxMonoidalFunctor --- Porting note (#5229): added, as `MonoidalNatTrans.ext` does not apply to morphisms. @[ext] lemma ext' {F G : LaxMonoidalFunctor C D} {α β : F ⟶ G} (w : ∀ X : C, α.app X = β.app X) : α = β := MonoidalNatTrans.ext (funext w) diff --git a/Mathlib/CategoryTheory/MorphismProperty/IsInvertedBy.lean b/Mathlib/CategoryTheory/MorphismProperty/IsInvertedBy.lean index e4d78ec3864b86..a20da408bc49cb 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/IsInvertedBy.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/IsInvertedBy.lean @@ -104,8 +104,6 @@ lemma FunctorsInverting.ext {W : MorphismProperty C} {F₁ F₂ : FunctorsInvert instance (W : MorphismProperty C) (D : Type*) [Category D] : Category (FunctorsInverting W D) := FullSubcategory.category _ --- Porting note (#5229): add another `@[ext]` lemma --- since `ext` can't see through the definition to use `NatTrans.ext`. @[ext] lemma FunctorsInverting.hom_ext {W : MorphismProperty C} {F₁ F₂ : FunctorsInverting W D} {α β : F₁ ⟶ F₂} (h : α.app = β.app) : α = β := diff --git a/Mathlib/CategoryTheory/Pi/Basic.lean b/Mathlib/CategoryTheory/Pi/Basic.lean index 8515247f7d5ba3..477e2fe2a21e55 100644 --- a/Mathlib/CategoryTheory/Pi/Basic.lean +++ b/Mathlib/CategoryTheory/Pi/Basic.lean @@ -49,7 +49,6 @@ theorem comp_apply {X Y Z : ∀ i, C i} (f : X ⟶ Y) (g : Y ⟶ Z) (i) : (f ≫ g : ∀ i, X i ⟶ Z i) i = f i ≫ g i := rfl --- Porting note (#5229): need to add an additional `ext` lemma. @[ext] lemma ext {X Y : ∀ i, C i} {f g : X ⟶ Y} (w : ∀ i, f i = g i) : f = g := funext (w ·) diff --git a/Mathlib/CategoryTheory/Preadditive/Mat.lean b/Mathlib/CategoryTheory/Preadditive/Mat.lean index 9d44442e07dd38..8ab0b6f6a60636 100644 --- a/Mathlib/CategoryTheory/Preadditive/Mat.lean +++ b/Mathlib/CategoryTheory/Preadditive/Mat.lean @@ -105,7 +105,6 @@ instance : Category.{v₁} (Mat_ C) where simp_rw [Hom.comp, sum_comp, comp_sum, Category.assoc] rw [Finset.sum_comm] --- Porting note (#5229): added because `DMatrix.ext` is not triggered automatically @[ext] theorem hom_ext {M N : Mat_ C} (f g : M ⟶ N) (H : ∀ i j, f i j = g i j) : f = g := DMatrix.ext_iff.mp H @@ -432,7 +431,6 @@ def liftUnique (F : C ⥤ D) [Functor.Additive F] (L : Mat_ C ⥤ D) [Functor.Ad dsimp simpa using α.hom.naturality (f j k) --- Porting note (#11182): removed @[ext] as the statement is not an equality -- TODO is there some uniqueness statement for the natural isomorphism in `liftUnique`? /-- Two additive functors `Mat_ C ⥤ D` are naturally isomorphic if their precompositions with `embedding C` are naturally isomorphic as functors `C ⥤ D`. -/ @@ -505,7 +503,6 @@ section variable {R : Type u} [Semiring R] --- Porting note (#5229): added because `Matrix.ext` is not triggered automatically @[ext] theorem hom_ext {X Y : Mat R} (f g : X ⟶ Y) (h : ∀ i j, f i j = g i j) : f = g := Matrix.ext_iff.mp h diff --git a/Mathlib/CategoryTheory/Sites/Sheaf.lean b/Mathlib/CategoryTheory/Sites/Sheaf.lean index 99d958c7ef6869..10da297aaf6d17 100644 --- a/Mathlib/CategoryTheory/Sites/Sheaf.lean +++ b/Mathlib/CategoryTheory/Sites/Sheaf.lean @@ -332,7 +332,6 @@ instance instCategorySheaf : Category (Sheaf J A) where instance (X : Sheaf J A) : Inhabited (Hom X X) := ⟨𝟙 X⟩ --- Porting note (#5229): added because `Sheaf.Hom.ext` was not triggered automatically @[ext] lemma hom_ext {X Y : Sheaf J A} (x y : X ⟶ Y) (h : x.val = y.val) : x = y := Sheaf.Hom.ext h diff --git a/Mathlib/CategoryTheory/Subobject/Basic.lean b/Mathlib/CategoryTheory/Subobject/Basic.lean index 34c23433816f0f..3afc05fb086540 100644 --- a/Mathlib/CategoryTheory/Subobject/Basic.lean +++ b/Mathlib/CategoryTheory/Subobject/Basic.lean @@ -255,21 +255,18 @@ theorem eq_of_comm {B : C} {X Y : Subobject B} (f : (X : C) ≅ (Y : C)) (w : f.hom ≫ Y.arrow = X.arrow) : X = Y := le_antisymm (le_of_comm f.hom w) <| le_of_comm f.inv <| f.inv_comp_eq.2 w.symm --- Porting note (#11182): removed @[ext] /-- To show that two subobjects are equal, it suffices to exhibit an isomorphism commuting with the arrows. -/ theorem eq_mk_of_comm {B A : C} {X : Subobject B} (f : A ⟶ B) [Mono f] (i : (X : C) ≅ A) (w : i.hom ≫ f = X.arrow) : X = mk f := eq_of_comm (i.trans (underlyingIso f).symm) <| by simp [w] --- Porting note (#11182): removed @[ext] /-- To show that two subobjects are equal, it suffices to exhibit an isomorphism commuting with the arrows. -/ theorem mk_eq_of_comm {B A : C} {X : Subobject B} (f : A ⟶ B) [Mono f] (i : A ≅ (X : C)) (w : i.hom ≫ X.arrow = f) : mk f = X := Eq.symm <| eq_mk_of_comm _ i.symm <| by rw [Iso.symm_hom, Iso.inv_comp_eq, w] --- Porting note (#11182): removed @[ext] /-- To show that two subobjects are equal, it suffices to exhibit an isomorphism commuting with the arrows. -/ theorem mk_eq_mk_of_comm {B A₁ A₂ : C} (f : A₁ ⟶ B) (g : A₂ ⟶ B) [Mono f] [Mono g] (i : A₁ ≅ A₂) diff --git a/Mathlib/CategoryTheory/Yoneda.lean b/Mathlib/CategoryTheory/Yoneda.lean index d056292dbff450..61b37dc22ad224 100644 --- a/Mathlib/CategoryTheory/Yoneda.lean +++ b/Mathlib/CategoryTheory/Yoneda.lean @@ -486,8 +486,6 @@ to `yoneda.op.obj X ⟶ F`, functorially in both `X` and `F`. def yonedaPairing : Cᵒᵖ × (Cᵒᵖ ⥤ Type v₁) ⥤ Type max u₁ v₁ := Functor.prod yoneda.op (𝟭 (Cᵒᵖ ⥤ Type v₁)) ⋙ Functor.hom (Cᵒᵖ ⥤ Type v₁) --- Porting note (#5229): we need to provide this `@[ext]` lemma separately, --- as `ext` will not look through the definition. @[ext] lemma yonedaPairingExt {X : Cᵒᵖ × (Cᵒᵖ ⥤ Type v₁)} {x y : (yonedaPairing C).obj X} (w : ∀ Y, x.app Y = y.app Y) : x = y := @@ -657,8 +655,6 @@ to `coyoneda.rightOp.obj X ⟶ F`, functorially in both `X` and `F`. def coyonedaPairing : C × (C ⥤ Type v₁) ⥤ Type max u₁ v₁ := Functor.prod coyoneda.rightOp (𝟭 (C ⥤ Type v₁)) ⋙ Functor.hom (C ⥤ Type v₁) --- Porting note (#5229): we need to provide this `@[ext]` lemma separately, --- as `ext` will not look through the definition. @[ext] lemma coyonedaPairingExt {X : C × (C ⥤ Type v₁)} {x y : (coyonedaPairing C).obj X} (w : ∀ Y, x.app Y = y.app Y) : x = y := diff --git a/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean b/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean index f4762b2bced5c9..12c2d277fbd66d 100644 --- a/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean +++ b/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean @@ -160,7 +160,6 @@ variable {C} /-- Cast `Hom X Y` as an arrow `X ⟶ Y` of presheaves. -/ abbrev Hom.toPshHom {X Y : PresheafedSpace C} (f : Hom X Y) : X ⟶ Y := f --- Porting note (#5229): adding an `ext` lemma. @[ext (iff := false)] theorem ext {X Y : PresheafedSpace C} (α β : X ⟶ Y) (w : α.base = β.base) (h : α.c ≫ whiskerRight (eqToHom (by rw [w])) _ = β.c) : α = β := diff --git a/Mathlib/Geometry/RingedSpace/SheafedSpace.lean b/Mathlib/Geometry/RingedSpace/SheafedSpace.lean index 7b65ebaffd7eb6..3af5f2d7e91d0c 100644 --- a/Mathlib/Geometry/RingedSpace/SheafedSpace.lean +++ b/Mathlib/Geometry/RingedSpace/SheafedSpace.lean @@ -80,7 +80,6 @@ instance : Category (SheafedSpace C) := show Category (InducedCategory (PresheafedSpace C) SheafedSpace.toPresheafedSpace) by infer_instance --- Porting note (#5229): adding an `ext` lemma. @[ext (iff := false)] theorem ext {X Y : SheafedSpace C} (α β : X ⟶ Y) (w : α.base = β.base) (h : α.c ≫ whiskerRight (eqToHom (by rw [w])) _ = β.c) : α = β := diff --git a/Mathlib/RepresentationTheory/Action/Basic.lean b/Mathlib/RepresentationTheory/Action/Basic.lean index f70ce1fb09e29a..2f15639455bdf4 100644 --- a/Mathlib/RepresentationTheory/Action/Basic.lean +++ b/Mathlib/RepresentationTheory/Action/Basic.lean @@ -111,7 +111,6 @@ instance : Category (Action V G) where id M := Hom.id M comp f g := Hom.comp f g --- Porting note (#5229): added because `Hom.ext` is not triggered automatically @[ext] lemma hom_ext {M N : Action V G} (φ₁ φ₂ : M ⟶ N) (h : φ₁.hom = φ₂.hom) : φ₁ = φ₂ := Hom.ext h From 3ffd5e037b602dd5939615c5556c0464cae46492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Calle=20S=C3=B6nne?= Date: Thu, 17 Oct 2024 15:41:44 +0000 Subject: [PATCH 327/425] feat(MorphismProperty/Presheaf): Add properties of the `relative` morphism property (#16142) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds some basic properties about the "presheaf" morphism property. For example, that it is stable under base change. Co-authored-by: Joël Riou --- .../MorphismProperty/Representable.lean | 58 ++++++++++++++++++- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/Mathlib/CategoryTheory/MorphismProperty/Representable.lean b/Mathlib/CategoryTheory/MorphismProperty/Representable.lean index e2ff92296f5c95..df96aa39de010f 100644 --- a/Mathlib/CategoryTheory/MorphismProperty/Representable.lean +++ b/Mathlib/CategoryTheory/MorphismProperty/Representable.lean @@ -25,9 +25,10 @@ Classically, a morphism `f : F ⟶ G` of presheaves is said to be representable In this file, we define a notion of relative representability which works with respect to any functor, and not just `yoneda`. The fact that a morphism `f : F ⟶ G` between presheaves is -representable in the classical case will then be given by `F.relativelyRepresentable f`. -` +representable in the classical case will then be given by `yoneda.relativelyRepresentable f`. + ## Main definitions + Throughout this file, `F : C ⥤ D` is a functor between categories `C` and `D`. * `Functor.relativelyRepresentable`: A morphism `f : X ⟶ Y` in `D` is said to be relatively @@ -312,7 +313,6 @@ category `Cᵒᵖ ⥤ Type v` satisfies the morphism property `P.presheaf` iff: * The morphism is representable. * For any morphism `g : F.obj a ⟶ G`, the property `P` holds for any represented pullback of `f` by `g`. - This is implemented as a special case of the more general notion of `P.relative`, to the case when the functor `F` is `yoneda`. -/ abbrev presheaf : MorphismProperty (Cᵒᵖ ⥤ Type v₁) := P.relative yoneda @@ -372,6 +372,58 @@ lemma relative_map_iff [F.Faithful] [F.Full] [PreservesLimitsOfShape WalkingCosp P.relative F (F.map f) ↔ P f := ⟨fun hf ↦ of_relative_map hf, fun hf ↦ relative_map hP hf⟩ +/-- If `P' : MorphismProperty C` is satisfied whenever `P` is, then also `P'.relative` is +satisfied whenever `P.relative` is. -/ +lemma relative_monotone {P' : MorphismProperty C} (h : P ≤ P') : + P.relative F ≤ P'.relative F := fun _ _ _ hf ↦ + ⟨hf.rep, fun _ _ g fst snd BC ↦ h _ (hf.property g fst snd BC)⟩ + +section + +variable (P) + +lemma relative_stableUnderBaseChange : StableUnderBaseChange (P.relative F) := + fun _ _ _ _ _ _ _ _ hfBC hg ↦ + ⟨stableUnderBaseChange F hfBC hg.rep, + fun _ _ _ _ _ BC ↦ hg.property _ _ _ (IsPullback.paste_horiz BC hfBC)⟩ + +instance relative_isStableUnderComposition [F.Faithful] [F.Full] [P.IsStableUnderComposition] : + IsStableUnderComposition (P.relative F) where + comp_mem {F G H} f g hf hg := by + refine ⟨comp_mem _ _ _ hf.1 hg.1, fun Z X p fst snd h ↦ ?_⟩ + rw [← hg.1.lift_snd (fst ≫ f) snd (by simpa using h.w)] + refine comp_mem _ _ _ (hf.property (hg.1.fst p) fst _ + (IsPullback.of_bot ?_ ?_ (hg.1.isPullback p))) (hg.property_snd p) + · rw [← Functor.map_comp, lift_snd] + exact h + · symm + apply hg.1.lift_fst + +instance relative_respectsIso : RespectsIso (P.relative F) := + (relative_stableUnderBaseChange P).respectsIso + +instance relative_isMultiplicative [F.Faithful] [F.Full] [P.IsMultiplicative] [P.RespectsIso] : + IsMultiplicative (P.relative F) where + id_mem X := relative.of_exists + (fun Y g ↦ ⟨Y, g, 𝟙 Y, by simpa using IsPullback.of_id_snd, id_mem _ _⟩) + +end + +/-- Morphisms satisfying `(monomorphism C).presheaf` are in particular monomorphisms. -/ +lemma presheaf_monomorphisms_le_monomorphisms : + (monomorphisms C).presheaf ≤ monomorphisms _ := fun F G f hf ↦ by + suffices ∀ {X : C} {a b : yoneda.obj X ⟶ F}, a ≫ f = b ≫ f → a = b from + ⟨fun _ _ h ↦ hom_ext_yoneda (fun _ _ ↦ this (by simp only [assoc, h]))⟩ + intro X a b h + /- It suffices to show that the lifts of `a` and `b` to morphisms + `X ⟶ hf.rep.pullback g` are equal, where `g = a ≫ f = a ≫ f`. -/ + suffices hf.rep.lift (g := a ≫ f) a (𝟙 X) (by simp) = + hf.rep.lift b (𝟙 X) (by simp [← h]) by + simpa using yoneda.congr_map this =≫ (hf.rep.fst (a ≫ f)) + -- This follows from the fact that the induced maps `hf.rep.pullback g ⟶ X` are mono. + have : Mono (hf.rep.snd (a ≫ f)) := hf.property_snd (a ≫ f) + simp only [← cancel_mono (hf.rep.snd (a ≫ f)), lift_snd] + end MorphismProperty end CategoryTheory From 27616824e4ad7714586263171a565683e6a6d7c9 Mon Sep 17 00:00:00 2001 From: Dagur Asgeirsson Date: Thu, 17 Oct 2024 15:41:47 +0000 Subject: [PATCH 328/425] chore(Profinite): remove simp lemma `toProfinite_obj` (#17155) --- Mathlib/Condensed/Discrete/Colimit.lean | 41 ++++++++----------- .../Category/LightProfinite/AsLimit.lean | 3 +- .../Category/LightProfinite/Basic.lean | 2 +- .../Topology/Category/Profinite/Basic.lean | 2 +- 4 files changed, 21 insertions(+), 27 deletions(-) diff --git a/Mathlib/Condensed/Discrete/Colimit.lean b/Mathlib/Condensed/Discrete/Colimit.lean index 2e2de66d0a095a..75f3c6ee7dfebd 100644 --- a/Mathlib/Condensed/Discrete/Colimit.lean +++ b/Mathlib/Condensed/Discrete/Colimit.lean @@ -48,10 +48,7 @@ noncomputable def isColimitLocallyConstantPresheaf (hc : IsLimit c) [∀ i, Epi (h : fi.comap (c.π.app i) = fj.comap (c.π.app j)) obtain ⟨k, ki, kj, _⟩ := IsCofilteredOrEmpty.cone_objs i j refine ⟨⟨k⟩, ki.op, kj.op, ?_⟩ - dsimp only [comp_obj, op_obj, functorToPresheaves_obj_obj, CompHausLike.coe_of, - Functor.comp_map, op_map, Quiver.Hom.unop_op, functorToPresheaves_obj_map] - -- Note: we might want to remove the `simps` attribute from `FintypeCat.toProfinite`; keeping - -- `toProfinite_obj` in the `dsimp` block above causes the following `ext` to fail. + dsimp ext x obtain ⟨x, hx⟩ := ((Profinite.epi_iff_surjective (c.π.app k)).mp inferInstance) x rw [← hx] @@ -237,7 +234,7 @@ def isoFinYoneda : toProfinite.op ⋙ F ≅ finYoneda F := NatIso.ofComponents (fun X ↦ isoFinYonedaComponents F (toProfinite.obj X.unop)) fun _ ↦ by simp only [comp_obj, op_obj, finYoneda_obj, Functor.comp_map, op_map] ext - simp only [toProfinite_obj, types_comp_apply, isoFinYonedaComponents_hom_apply, finYoneda_map, + simp only [types_comp_apply, isoFinYonedaComponents_hom_apply, finYoneda_map, op_obj, Function.comp_apply, ← FunctorToTypes.map_comp_apply] rfl @@ -264,14 +261,14 @@ lemma isoLocallyConstantOfIsColimit_inv (X : Profinite.{u}ᵒᵖ ⥤ Type (u+1)) apply colimit.hom_ext intro ⟨Y, _, g⟩ simp? [locallyConstantIsoFinYoneda, isoFinYoneda, counitApp] says - simp only [comp_obj, CostructuredArrow.proj_obj, op_obj, toProfinite_obj, - functorToPresheaves_obj_obj, CompHausLike.coe_of, isoFinYoneda, locallyConstantIsoFinYoneda, - finYoneda_obj, LocallyConstant.toFun_eq_coe, NatTrans.comp_app, pointwiseLeftKanExtension_obj, - lanPresheafExt_inv, Iso.trans_inv, Iso.symm_inv, whiskerLeft_comp, lanPresheafNatIso_hom_app, - Opposite.op_unop, colimit.map_desc, id_eq, Functor.comp_map, op_map, colimit.ι_desc, - Cocones.precompose_obj_pt, Profinite.Extend.cocone_pt, Cocones.precompose_obj_ι, - Category.assoc, const_obj_obj, whiskerLeft_app, NatIso.ofComponents_hom_app, - NatIso.ofComponents_inv_app, Profinite.Extend.cocone_ι_app, counitApp, colimit.ι_desc_assoc] + simp only [comp_obj, CostructuredArrow.proj_obj, op_obj, functorToPresheaves_obj_obj, + isoFinYoneda, locallyConstantIsoFinYoneda, finYoneda_obj, LocallyConstant.toFun_eq_coe, + NatTrans.comp_app, pointwiseLeftKanExtension_obj, lanPresheafExt_inv, Iso.trans_inv, + Iso.symm_inv, whiskerLeft_comp, lanPresheafNatIso_hom_app, Opposite.op_unop, colimit.map_desc, + id_eq, Functor.comp_map, op_map, colimit.ι_desc, Cocones.precompose_obj_pt, + Profinite.Extend.cocone_pt, Cocones.precompose_obj_ι, Category.assoc, const_obj_obj, + whiskerLeft_app, NatIso.ofComponents_hom_app, NatIso.ofComponents_inv_app, + Profinite.Extend.cocone_ι_app, counitApp, colimit.ι_desc_assoc] erw [(counitApp.{u, u+1} X).naturality] simp only [← Category.assoc] congr @@ -318,8 +315,7 @@ noncomputable def isColimitLocallyConstantPresheaf (hc : IsLimit c) [∀ i, Epi (h : fi.comap (c.π.app i) = fj.comap (c.π.app j)) obtain ⟨k, ki, kj, _⟩ := IsCofilteredOrEmpty.cone_objs i j refine ⟨⟨k⟩, ki.op, kj.op, ?_⟩ - dsimp only [comp_obj, op_obj, functorToPresheaves_obj_obj, CompHausLike.coe_of, - Functor.comp_map, op_map, Quiver.Hom.unop_op, functorToPresheaves_obj_map] + dsimp ext x obtain ⟨x, hx⟩ := ((LightProfinite.epi_iff_surjective (c.π.app k)).mp inferInstance) x rw [← hx] @@ -541,14 +537,13 @@ lemma isoLocallyConstantOfIsColimit_inv (X : LightProfinite.{u}ᵒᵖ ⥤ Type u intro ⟨Y, _, g⟩ simp? [locallyConstantIsoFinYoneda, isoFinYoneda, counitApp] says simp only [comp_obj, CostructuredArrow.proj_obj, op_obj, functorToPresheaves_obj_obj, - toLightProfinite_obj_toTop_α, isoFinYoneda, locallyConstantIsoFinYoneda, finYoneda_obj, - LocallyConstant.toFun_eq_coe, NatTrans.comp_app, pointwiseLeftKanExtension_obj, - lanPresheafExt_inv, Iso.trans_inv, Iso.symm_inv, whiskerLeft_comp, lanPresheafNatIso_hom_app, - Opposite.op_unop, colimit.map_desc, id_eq, Functor.comp_map, op_map, colimit.ι_desc, - Cocones.precompose_obj_pt, LightProfinite.Extend.cocone_pt, Cocones.precompose_obj_ι, - Category.assoc, const_obj_obj, whiskerLeft_app, NatIso.ofComponents_hom_app, - NatIso.ofComponents_inv_app, LightProfinite.Extend.cocone_ι_app, counitApp, - colimit.ι_desc_assoc] + isoFinYoneda, locallyConstantIsoFinYoneda, finYoneda_obj, LocallyConstant.toFun_eq_coe, + NatTrans.comp_app, pointwiseLeftKanExtension_obj, lanPresheafExt_inv, Iso.trans_inv, + Iso.symm_inv, whiskerLeft_comp, lanPresheafNatIso_hom_app, Opposite.op_unop, colimit.map_desc, + id_eq, Functor.comp_map, op_map, colimit.ι_desc, Cocones.precompose_obj_pt, + LightProfinite.Extend.cocone_pt, Cocones.precompose_obj_ι, Category.assoc, const_obj_obj, + whiskerLeft_app, NatIso.ofComponents_hom_app, NatIso.ofComponents_inv_app, + LightProfinite.Extend.cocone_ι_app, counitApp, colimit.ι_desc_assoc] erw [(counitApp.{u, u} X).naturality] simp only [← Category.assoc] congr diff --git a/Mathlib/Topology/Category/LightProfinite/AsLimit.lean b/Mathlib/Topology/Category/LightProfinite/AsLimit.lean index 48104258a6815c..bb092cf45b600a 100644 --- a/Mathlib/Topology/Category/LightProfinite/AsLimit.lean +++ b/Mathlib/Topology/Category/LightProfinite/AsLimit.lean @@ -79,8 +79,7 @@ abbrev proj (n : ℕ) : S ⟶ S.diagram.obj ⟨n⟩ := S.asLimitCone.π.app ⟨n lemma lightToProfinite_map_proj_eq (n : ℕ) : lightToProfinite.map (S.proj n) = (lightToProfinite.obj S).asLimitCone.π.app _ := by - simp? says simp only [toCompHausLike_obj, Functor.comp_obj, - FintypeCat.toLightProfinite_obj_toTop_α, toCompHausLike_map, coe_of] + simp only [toCompHausLike_obj, Functor.comp_obj, toCompHausLike_map, coe_of] let c : Cone (S.diagram ⋙ lightToProfinite) := S.toLightDiagram.cone let hc : IsLimit c := S.toLightDiagram.isLimit exact liftedLimitMapsToOriginal_inv_map_π hc _ diff --git a/Mathlib/Topology/Category/LightProfinite/Basic.lean b/Mathlib/Topology/Category/LightProfinite/Basic.lean index 73dbb2fa55ef62..7d300f39050880 100644 --- a/Mathlib/Topology/Category/LightProfinite/Basic.lean +++ b/Mathlib/Topology/Category/LightProfinite/Basic.lean @@ -100,7 +100,7 @@ attribute [local instance] FintypeCat.discreteTopology /-- The natural functor from `Fintype` to `LightProfinite`, endowing a finite type with the discrete topology. -/ -@[simps!] +@[simps! map_apply] def FintypeCat.toLightProfinite : FintypeCat ⥤ LightProfinite where obj A := LightProfinite.of A map f := ⟨f, by continuity⟩ diff --git a/Mathlib/Topology/Category/Profinite/Basic.lean b/Mathlib/Topology/Category/Profinite/Basic.lean index 1faa3653c9a741..45aaebd8b6c14c 100644 --- a/Mathlib/Topology/Category/Profinite/Basic.lean +++ b/Mathlib/Topology/Category/Profinite/Basic.lean @@ -140,7 +140,7 @@ attribute [local instance] FintypeCat.discreteTopology /-- The natural functor from `Fintype` to `Profinite`, endowing a finite type with the discrete topology. -/ -@[simps] +@[simps map_apply] def FintypeCat.toProfinite : FintypeCat ⥤ Profinite where obj A := Profinite.of A map f := ⟨f, by continuity⟩ From d9aad45391e594b51dfd27fdf9c579e105a0183c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 17 Oct 2024 15:41:48 +0000 Subject: [PATCH 329/425] feat(CategoryTheory/Shift): shifted morphisms in the opposite category (#17546) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When `C` is a triangulated category, we introduce a bijection `ShiftedHom.opEquiv` which identifies `X ⟶ Y⟦n⟧` and `op Y ⟶ (op X)⟦n⟧` for any objects `X` and `Y` in `C`, and `n : ℤ`. Along with the compatibilities that are obtained, this shall be the main ingredient in the construction of the (contravariant) long exact sequence of `Ext` in abelian categories #15092. --- Mathlib.lean | 1 + Mathlib/CategoryTheory/Shift/Basic.lean | 65 +++++++- .../Shift/ShiftedHomOpposite.lean | 155 ++++++++++++++++++ .../CategoryTheory/Triangulated/Opposite.lean | 55 ++++++- .../CategoryTheory/Triangulated/Yoneda.lean | 40 ++++- Mathlib/Combinatorics/Quiver/Basic.lean | 9 + 6 files changed, 320 insertions(+), 5 deletions(-) create mode 100644 Mathlib/CategoryTheory/Shift/ShiftedHomOpposite.lean diff --git a/Mathlib.lean b/Mathlib.lean index 155e528def04fe..b43069a00a0540 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1858,6 +1858,7 @@ import Mathlib.CategoryTheory.Shift.Pullback import Mathlib.CategoryTheory.Shift.Quotient import Mathlib.CategoryTheory.Shift.ShiftSequence import Mathlib.CategoryTheory.Shift.ShiftedHom +import Mathlib.CategoryTheory.Shift.ShiftedHomOpposite import Mathlib.CategoryTheory.Shift.SingleFunctors import Mathlib.CategoryTheory.Sigma.Basic import Mathlib.CategoryTheory.Simple diff --git a/Mathlib/CategoryTheory/Shift/Basic.lean b/Mathlib/CategoryTheory/Shift/Basic.lean index c8b2f4ddfaec90..7acb86cbee29dc 100644 --- a/Mathlib/CategoryTheory/Shift/Basic.lean +++ b/Mathlib/CategoryTheory/Shift/Basic.lean @@ -1,7 +1,7 @@ /- Copyright (c) 2020 Kim Morrison. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Kim Morrison, Johan Commelin, Andrew Yang +Authors: Kim Morrison, Johan Commelin, Andrew Yang, Joël Riou -/ import Mathlib.Algebra.Group.Basic import Mathlib.CategoryTheory.Limits.Preserves.Shapes.Zero @@ -487,6 +487,69 @@ theorem shift_shiftFunctorCompIsoId_neg_add_cancel_inv_app (n : A) (X : C) : end +section + +variable (A) + +lemma shiftFunctorCompIsoId_zero_zero_hom_app (X : C) : + (shiftFunctorCompIsoId C 0 0 (add_zero 0)).hom.app X = + ((shiftFunctorZero C A).hom.app X)⟦0⟧' ≫ (shiftFunctorZero C A).hom.app X := by + simp [shiftFunctorCompIsoId, shiftFunctorAdd'_zero_add_inv_app] + +lemma shiftFunctorCompIsoId_zero_zero_inv_app (X : C) : + (shiftFunctorCompIsoId C 0 0 (add_zero 0)).inv.app X = + (shiftFunctorZero C A).inv.app X ≫ ((shiftFunctorZero C A).inv.app X)⟦0⟧' := by + simp [shiftFunctorCompIsoId, shiftFunctorAdd'_zero_add_hom_app] + +end + +section + +variable (m n p m' n' p' : A) (hm : m' + m = 0) (hn : n' + n = 0) (hp : p' + p = 0) + (h : m + n = p) + +lemma shiftFunctorCompIsoId_add'_inv_app : + (shiftFunctorCompIsoId C p' p hp).inv.app X = + (shiftFunctorCompIsoId C n' n hn).inv.app X ≫ + (shiftFunctorCompIsoId C m' m hm).inv.app (X⟦n'⟧)⟦n⟧' ≫ + (shiftFunctorAdd' C m n p h).inv.app (X⟦n'⟧⟦m'⟧) ≫ + ((shiftFunctorAdd' C n' m' p' + (by rw [← add_left_inj p, hp, ← h, add_assoc, + ← add_assoc m', hm, zero_add, hn])).inv.app X)⟦p⟧' := by + dsimp [shiftFunctorCompIsoId] + simp only [Functor.map_comp, Category.assoc] + congr 1 + erw [← NatTrans.naturality] + dsimp + rw [← cancel_mono ((shiftFunctorAdd' C p' p 0 hp).inv.app X), Iso.hom_inv_id_app, + Category.assoc, Category.assoc, Category.assoc, Category.assoc, + ← shiftFunctorAdd'_assoc_inv_app p' m n n' p 0 + (by rw [← add_left_inj n, hn, add_assoc, h, hp]) h (by rw [add_assoc, h, hp]), + ← Functor.map_comp_assoc, ← Functor.map_comp_assoc, ← Functor.map_comp_assoc, + Category.assoc, Category.assoc, + shiftFunctorAdd'_assoc_inv_app n' m' m p' 0 n' _ _ + (by rw [add_assoc, hm, add_zero]), Iso.hom_inv_id_app_assoc, + ← shiftFunctorAdd'_add_zero_hom_app, Iso.hom_inv_id_app, + Functor.map_id, Category.id_comp, Iso.hom_inv_id_app] + +lemma shiftFunctorCompIsoId_add'_hom_app : + (shiftFunctorCompIsoId C p' p hp).hom.app X = + ((shiftFunctorAdd' C n' m' p' + (by rw [← add_left_inj p, hp, ← h, add_assoc, + ← add_assoc m', hm, zero_add, hn])).hom.app X)⟦p⟧' ≫ + (shiftFunctorAdd' C m n p h).hom.app (X⟦n'⟧⟦m'⟧) ≫ + (shiftFunctorCompIsoId C m' m hm).hom.app (X⟦n'⟧)⟦n⟧' ≫ + (shiftFunctorCompIsoId C n' n hn).hom.app X := by + rw [← cancel_mono ((shiftFunctorCompIsoId C p' p hp).inv.app X), Iso.hom_inv_id_app, + shiftFunctorCompIsoId_add'_inv_app m n p m' n' p' hm hn hp h, + Category.assoc, Category.assoc, Category.assoc, Iso.hom_inv_id_app_assoc, + ← Functor.map_comp_assoc, Iso.hom_inv_id_app] + dsimp + rw [Functor.map_id, Category.id_comp, Iso.hom_inv_id_app_assoc, + ← Functor.map_comp, Iso.hom_inv_id_app, Functor.map_id] + +end + open CategoryTheory.Limits variable [HasZeroMorphisms C] diff --git a/Mathlib/CategoryTheory/Shift/ShiftedHomOpposite.lean b/Mathlib/CategoryTheory/Shift/ShiftedHomOpposite.lean new file mode 100644 index 00000000000000..5f21658547de30 --- /dev/null +++ b/Mathlib/CategoryTheory/Shift/ShiftedHomOpposite.lean @@ -0,0 +1,155 @@ +/- +Copyright (c) 2024 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ + +import Mathlib.CategoryTheory.Triangulated.Opposite +import Mathlib.CategoryTheory.Shift.ShiftedHom + +/-! Shifted morphisms in the opposite category + +If `C` is a category equipped with a shift by `ℤ`, `X` and `Y` are objects +of `C`, and `n : ℤ`, we define a bijection +`ShiftedHom.opEquiv : ShiftedHom X Y n ≃ ShiftedHom (Opposite.op Y) (Opposite.op X) n`. +We also introduce `ShiftedHom.opEquiv'` which produces a bijection +`ShiftedHom X Y a' ≃ (Opposite.op (Y⟦a⟧) ⟶ (Opposite.op X)⟦n⟧)` when `n + a = a'`. +The compatibilities that are obtained shall be used in order to study +the homological functor `preadditiveYoneda.obj B : Cᵒᵖ ⥤ Type _` when `B` is an object +in a pretriangulated category `C`. + +-/ + +namespace CategoryTheory + +open Category Pretriangulated.Opposite Pretriangulated + +variable {C : Type*} [Category C] [HasShift C ℤ] {X Y Z : C} + +namespace ShiftedHom + +/-- The bijection `ShiftedHom X Y n ≃ ShiftedHom (Opposite.op Y) (Opposite.op X) n` when +`n : ℤ`, and `X` and `Y` are objects of a category equipped with a shift by `ℤ`. -/ +noncomputable def opEquiv (n : ℤ) : + ShiftedHom X Y n ≃ ShiftedHom (Opposite.op Y) (Opposite.op X) n := + Quiver.Hom.opEquiv.trans + ((opShiftFunctorEquivalence C n).symm.toAdjunction.homEquiv (Opposite.op Y) (Opposite.op X)) + +lemma opEquiv_symm_apply {n : ℤ} (f : ShiftedHom (Opposite.op Y) (Opposite.op X) n) : + (opEquiv n).symm f = + ((opShiftFunctorEquivalence C n).unitIso.inv.app (Opposite.op X)).unop ≫ f.unop⟦n⟧' := by + rfl + +lemma opEquiv_symm_apply_comp {X Y : C} {a : ℤ} + (f : ShiftedHom (Opposite.op X) (Opposite.op Y) a) {b : ℤ} {Z : C} + (z : ShiftedHom X Z b) {c : ℤ} (h : b + a = c) : + ((ShiftedHom.opEquiv a).symm f).comp z h = + (ShiftedHom.opEquiv a).symm (z.op ≫ f) ≫ + (shiftFunctorAdd' C b a c h).inv.app Z := by + rw [ShiftedHom.opEquiv_symm_apply, ShiftedHom.opEquiv_symm_apply, + ShiftedHom.comp] + dsimp + simp only [assoc, Functor.map_comp] + +lemma opEquiv_symm_comp {a b : ℤ} + (f : ShiftedHom (Opposite.op Z) (Opposite.op Y) a) + (g : ShiftedHom (Opposite.op Y) (Opposite.op X) b) + {c : ℤ} (h : b + a = c) : + (opEquiv _).symm (f.comp g h) = + ((opEquiv _).symm g).comp ((opEquiv _).symm f) (by omega) := by + rw [opEquiv_symm_apply, opEquiv_symm_apply, + opShiftFunctorEquivalence_unitIso_inv_app_eq _ _ _ _ (show a + b = c by omega), comp, comp] + dsimp + rw [assoc, assoc, assoc, assoc, ← Functor.map_comp, ← unop_comp_assoc, + Iso.inv_hom_id_app] + dsimp + rw [assoc, id_comp, Functor.map_comp, ← NatTrans.naturality_assoc, + ← NatTrans.naturality, opEquiv_symm_apply] + dsimp + rw [← Functor.map_comp_assoc, ← Functor.map_comp_assoc, + ← Functor.map_comp_assoc] + rw [← unop_comp_assoc] + erw [← NatTrans.naturality] + rfl + +/-- The bijection `ShiftedHom X Y a' ≃ (Opposite.op (Y⟦a⟧) ⟶ (Opposite.op X)⟦n⟧)` +when integers `n`, `a` and `a'` satisfy `n + a = a'`, and `X` and `Y` are objects +of a category equipped with a shift by `ℤ`. -/ +noncomputable def opEquiv' (n a a' : ℤ) (h : n + a = a') : + ShiftedHom X Y a' ≃ (Opposite.op (Y⟦a⟧) ⟶ (Opposite.op X)⟦n⟧) := + ((shiftFunctorAdd' C a n a' (by omega)).symm.app Y).homToEquiv.symm.trans (opEquiv n) + +lemma opEquiv'_symm_apply {n a : ℤ} (f : Opposite.op (Y⟦a⟧) ⟶ (Opposite.op X)⟦n⟧) + (a' : ℤ) (h : n + a = a') : + (opEquiv' n a a' h).symm f = + (opEquiv n).symm f ≫ (shiftFunctorAdd' C a n a' (by omega)).inv.app _ := + rfl + +lemma opEquiv'_apply {a' : ℤ} (f : ShiftedHom X Y a') (n a : ℤ) (h : n + a = a') : + opEquiv' n a a' h f = + opEquiv n (f ≫ (shiftFunctorAdd' C a n a' (by omega)).hom.app Y) := by + rfl + +lemma opEquiv'_symm_op_opShiftFunctorEquivalence_counitIso_inv_app_op_shift + {n m : ℤ} (f : ShiftedHom X Y n) (g : ShiftedHom Y Z m) + (q : ℤ) (hq : n + m = q) : + (opEquiv' n m q hq).symm + (g.op ≫ (opShiftFunctorEquivalence C n).counitIso.inv.app _ ≫ f.op⟦n⟧') = + f.comp g (by omega) := by + rw [opEquiv'_symm_apply, opEquiv_symm_apply] + dsimp [comp] + apply Quiver.Hom.op_inj + simp only [assoc, Functor.map_comp, op_comp, Quiver.Hom.op_unop, + opShiftFunctorEquivalence_unitIso_inv_naturality] + erw [(opShiftFunctorEquivalence C n).inverse_counitInv_comp_assoc (Opposite.op Y)] + +lemma opEquiv'_symm_comp (f : Y ⟶ X) {n a : ℤ} (x : Opposite.op (Z⟦a⟧) ⟶ (Opposite.op X⟦n⟧)) + (a' : ℤ) (h : n + a = a') : + (opEquiv' n a a' h).symm (x ≫ f.op⟦n⟧') = f ≫ (opEquiv' n a a' h).symm x := + Quiver.Hom.op_inj (by simp [opEquiv'_symm_apply, opEquiv_symm_apply]) + +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 + simp [opEquiv'_symm_apply, opEquiv_symm_apply, shiftFunctorAdd'_add_zero, + opShiftFunctorEquivalence_zero_unitIso_inv_app] + +lemma opEquiv'_add_symm (n m a a' a'' : ℤ) (ha' : n + a = a') (ha'' : m + a' = a'') + (x : (Opposite.op (Y⟦a⟧) ⟶ (Opposite.op X)⟦m + n⟧)) : + (opEquiv' (m + n) a a'' (by omega)).symm x = + (opEquiv' m a' a'' ha'').symm ((opEquiv' n a a' ha').symm + (x ≫ (shiftFunctorAdd Cᵒᵖ m n).hom.app _)).op := by + simp only [opEquiv'_symm_apply, opEquiv_symm_apply, + opShiftFunctorEquivalence_unitIso_inv_app_eq _ _ _ _ (add_comm n m)] + dsimp + simp only [assoc, Functor.map_comp, ← shiftFunctorAdd'_eq_shiftFunctorAdd, + ← NatTrans.naturality_assoc, + shiftFunctorAdd'_assoc_inv_app a n m a' (m + n) a'' (by omega) (by omega) (by omega)] + rfl + +section Preadditive + +variable [Preadditive C] [∀ (n : ℤ), (shiftFunctor C n).Additive] + +@[simp] +lemma opEquiv_symm_add {n : ℤ} (x y : ShiftedHom (Opposite.op Y) (Opposite.op X) n) : + (opEquiv n).symm (x + y) = (opEquiv n).symm x + (opEquiv n).symm y := by + dsimp [opEquiv_symm_apply] + rw [← Preadditive.comp_add, ← Functor.map_add] + rfl + +@[simp] +lemma opEquiv'_symm_add {n a : ℤ} (x y : (Opposite.op (Y⟦a⟧) ⟶ (Opposite.op X)⟦n⟧)) + (a' : ℤ) (h : n + a = a') : + (opEquiv' n a a' h).symm (x + y) = + (opEquiv' n a a' h).symm x + (opEquiv' n a a' h).symm y := by + dsimp [opEquiv'] + erw [opEquiv_symm_add, Iso.homToEquiv_apply, Iso.homToEquiv_apply, Iso.homToEquiv_apply] + rw [Preadditive.add_comp] + rfl + +end Preadditive + +end ShiftedHom + +end CategoryTheory diff --git a/Mathlib/CategoryTheory/Triangulated/Opposite.lean b/Mathlib/CategoryTheory/Triangulated/Opposite.lean index 3b6c6643237620..9e34b1cc2e37fb 100644 --- a/Mathlib/CategoryTheory/Triangulated/Opposite.lean +++ b/Mathlib/CategoryTheory/Triangulated/Opposite.lean @@ -130,8 +130,7 @@ lemma shiftFunctor_op_map (n m : ℤ) (hnm : n + m = 0) {K L : Cᵒᵖ} (φ : K (shiftFunctorOpIso C n m hnm).inv.app L := (NatIso.naturality_2 (shiftFunctorOpIso C n m hnm) φ).symm -variable (C) - +variable (C) in /-- The autoequivalence `Cᵒᵖ ≌ Cᵒᵖ` whose functor is `shiftFunctor Cᵒᵖ n` and whose inverse functor is `(shiftFunctor C n).op`. Do not unfold the definitions of the unit and counit isomorphisms: the compatibilities they satisfy are stated as separate lemmas. -/ @@ -177,7 +176,57 @@ 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 -variable {C} +lemma opShiftFunctorEquivalence_zero_unitIso_hom_app (X : Cᵒᵖ) : + (opShiftFunctorEquivalence C 0).unitIso.hom.app X = + ((shiftFunctorZero C ℤ).hom.app X.unop).op ≫ + (((shiftFunctorZero Cᵒᵖ ℤ).inv.app X).unop⟦(0 : ℤ)⟧').op := by + apply Quiver.Hom.unop_inj + dsimp [opShiftFunctorEquivalence] + rw [shiftFunctorZero_op_inv_app, unop_comp, Quiver.Hom.unop_op, Functor.map_comp, + shiftFunctorCompIsoId_zero_zero_hom_app, assoc] + +lemma opShiftFunctorEquivalence_zero_unitIso_inv_app (X : Cᵒᵖ) : + (opShiftFunctorEquivalence C 0).unitIso.inv.app X = + (((shiftFunctorZero Cᵒᵖ ℤ).hom.app X).unop⟦(0 : ℤ)⟧').op ≫ + ((shiftFunctorZero C ℤ).inv.app X.unop).op := by + apply Quiver.Hom.unop_inj + dsimp [opShiftFunctorEquivalence] + rw [shiftFunctorZero_op_hom_app, unop_comp, Quiver.Hom.unop_op, Functor.map_comp, + shiftFunctorCompIsoId_zero_zero_inv_app, assoc] + +lemma opShiftFunctorEquivalence_unitIso_hom_app_eq (X : Cᵒᵖ) (m n p : ℤ) (h : m + n = p) : + (opShiftFunctorEquivalence C p).unitIso.hom.app X = + (opShiftFunctorEquivalence C n).unitIso.hom.app X ≫ + (((opShiftFunctorEquivalence C m).unitIso.hom.app (X⟦n⟧)).unop⟦n⟧').op ≫ + ((shiftFunctorAdd' C m n p h).hom.app _).op ≫ + (((shiftFunctorAdd' Cᵒᵖ n m p (by omega)).inv.app X).unop⟦p⟧').op := by + dsimp [opShiftFunctorEquivalence] + simp only [shiftFunctorAdd'_op_inv_app _ n m p (by omega) _ _ _ (add_neg_cancel n) + (add_neg_cancel m) (add_neg_cancel p), shiftFunctor_op_map _ _ (add_neg_cancel m), + Category.assoc, Iso.inv_hom_id_app_assoc] + erw [Functor.map_id, Functor.map_id, Functor.map_id, Functor.map_id, + id_comp, id_comp, id_comp, comp_id, comp_id] + dsimp + rw [comp_id, shiftFunctorCompIsoId_add'_hom_app _ _ _ _ _ _ + (neg_add_cancel m) (neg_add_cancel n) (neg_add_cancel p) h] + dsimp + rw [Category.assoc, Category.assoc] + rfl + +lemma opShiftFunctorEquivalence_unitIso_inv_app_eq (X : Cᵒᵖ) (m n p : ℤ) (h : m + n = p) : + (opShiftFunctorEquivalence C p).unitIso.inv.app X = + (((shiftFunctorAdd' Cᵒᵖ n m p (by omega)).hom.app X).unop⟦p⟧').op ≫ + ((shiftFunctorAdd' C m n p h).inv.app _).op ≫ + (((opShiftFunctorEquivalence C m).unitIso.inv.app (X⟦n⟧)).unop⟦n⟧').op ≫ + (opShiftFunctorEquivalence C n).unitIso.inv.app X := by + rw [← cancel_mono ((opShiftFunctorEquivalence C p).unitIso.hom.app X), Iso.inv_hom_id_app, + opShiftFunctorEquivalence_unitIso_hom_app_eq _ _ _ _ h, + Category.assoc, Category.assoc, Category.assoc, Iso.inv_hom_id_app_assoc] + apply Quiver.Hom.unop_inj + dsimp + simp only [Category.assoc, ← Functor.map_comp_assoc, Iso.hom_inv_id_app_assoc, + ← 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] lemma shift_unop_opShiftFunctorEquivalence_counitIso_inv_app (X : Cᵒᵖ) (n : ℤ) : ((opShiftFunctorEquivalence C n).counitIso.inv.app X).unop⟦n⟧' = diff --git a/Mathlib/CategoryTheory/Triangulated/Yoneda.lean b/Mathlib/CategoryTheory/Triangulated/Yoneda.lean index 39ec3c60ebdb18..e136effd690d89 100644 --- a/Mathlib/CategoryTheory/Triangulated/Yoneda.lean +++ b/Mathlib/CategoryTheory/Triangulated/Yoneda.lean @@ -5,6 +5,7 @@ Authors: Joël Riou -/ import Mathlib.Algebra.Homology.ShortComplex.Ab import Mathlib.CategoryTheory.Preadditive.Yoneda.Basic +import Mathlib.CategoryTheory.Shift.ShiftedHomOpposite import Mathlib.CategoryTheory.Triangulated.HomologicalFunctor import Mathlib.CategoryTheory.Triangulated.Opposite @@ -23,7 +24,7 @@ variable {C : Type*} [Category C] [Preadditive C] [HasShift C ℤ] namespace CategoryTheory -open Limits Pretriangulated.Opposite +open Limits Opposite Pretriangulated.Opposite namespace Pretriangulated @@ -62,6 +63,43 @@ lemma preadditiveCoyoneda_homologySequenceδ_apply x ≫ T.mor₃⟦n₀⟧' ≫ (shiftFunctorAdd' C 1 n₀ n₁ (by omega)).inv.app _ := by apply Category.assoc +section + +variable [∀ (n : ℤ), (shiftFunctor C n).Additive] + +noncomputable instance (B : C) : (preadditiveYoneda.obj B).ShiftSequence ℤ where + sequence n := preadditiveYoneda.obj (B⟦n⟧) + isoZero := preadditiveYoneda.mapIso ((shiftFunctorZero C ℤ).app B) + shiftIso n a a' h := NatIso.ofComponents (fun A ↦ AddEquiv.toAddCommGrpIso + { toEquiv := Quiver.Hom.opEquiv.trans (ShiftedHom.opEquiv' n a a' h).symm + map_add' := fun _ _ ↦ ShiftedHom.opEquiv'_symm_add _ _ _ h }) + (by intros; ext; apply ShiftedHom.opEquiv'_symm_comp _ _ _ h) + shiftIso_zero a := by ext; apply ShiftedHom.opEquiv'_zero_add_symm + shiftIso_add n m a a' a'' ha' ha'' := by + ext _ x + exact ShiftedHom.opEquiv'_add_symm n m a a' a'' ha' ha'' x.op + +lemma preadditiveYoneda_shiftMap_apply (B : C) {X Y : Cᵒᵖ} (n : ℤ) (f : X ⟶ Y⟦n⟧) + (a a' : ℤ) (h : n + a = a') (z : X.unop ⟶ B⟦a⟧) : + (preadditiveYoneda.obj B).shiftMap f a a' h z = + ((ShiftedHom.opEquiv _).symm f).comp z (show a + n = a' by omega) := by + symm + apply ShiftedHom.opEquiv_symm_apply_comp + +lemma preadditiveYoneda_homologySequenceδ_apply + (T : Triangle C) (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) {B : C} (x : T.obj₁ ⟶ B⟦n₀⟧) : + (preadditiveYoneda.obj B).homologySequenceδ + ((triangleOpEquivalence _).functor.obj (op T)) n₀ n₁ h x = + T.mor₃ ≫ x⟦(1 : ℤ)⟧' ≫ (shiftFunctorAdd' C n₀ 1 n₁ h).inv.app B := by + simp only [Functor.homologySequenceδ, preadditiveYoneda_shiftMap_apply, + ShiftedHom.comp, ← Category.assoc] + congr 2 + apply (ShiftedHom.opEquiv _).injective + rw [Equiv.apply_symm_apply] + rfl + +end + end Pretriangulated end CategoryTheory diff --git a/Mathlib/Combinatorics/Quiver/Basic.lean b/Mathlib/Combinatorics/Quiver/Basic.lean index f0f77f70aa4b77..78d2fbdeef06ad 100644 --- a/Mathlib/Combinatorics/Quiver/Basic.lean +++ b/Mathlib/Combinatorics/Quiver/Basic.lean @@ -137,6 +137,15 @@ 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`. -/ 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)`. -/ +@[simps] +def Hom.opEquiv {V} [Quiver V] {X Y : V} : + (X ⟶ Y) ≃ (Opposite.op Y ⟶ Opposite.op X) where + toFun := Opposite.op + invFun := Opposite.unop + left_inv _ := rfl + right_inv _ := rfl + /-- A type synonym for a quiver with no arrows. -/ -- Porting note(#5171): this linter isn't ported yet. -- @[nolint has_nonempty_instance] From cbcf4ea1cb4620e09549662684cb12de35d81299 Mon Sep 17 00:00:00 2001 From: David Loeffler Date: Thu, 17 Oct 2024 15:41:50 +0000 Subject: [PATCH 330/425] feat(Analysis/Normed/Group/Ultra): triangle ineq for tsum & tprod (#17584) --- Mathlib/Analysis/Normed/Group/Ultra.lean | 42 ++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/Mathlib/Analysis/Normed/Group/Ultra.lean b/Mathlib/Analysis/Normed/Group/Ultra.lean index 8e83b3535e430f..2b8c5f341691f3 100644 --- a/Mathlib/Analysis/Normed/Group/Ultra.lean +++ b/Mathlib/Analysis/Normed/Group/Ultra.lean @@ -6,6 +6,8 @@ Authors: Yakov Pechersky, David Loeffler import Mathlib.Analysis.Normed.Group.Uniform import Mathlib.Topology.Algebra.Nonarchimedean.Basic import Mathlib.Topology.MetricSpace.Ultra.Basic +import Mathlib.Topology.Algebra.InfiniteSum.Group +import Mathlib.Topology.Algebra.Order.LiminfLimsup /-! # Ultrametric norms @@ -31,6 +33,8 @@ ultrametric, nonarchimedean -/ open Metric NNReal +open scoped BigOperators + namespace IsUltrametricDist section Group @@ -235,6 +239,44 @@ lemma norm_prod_le_of_forall_le_of_nonneg {s : Finset ι} {f : ι → M} {C : lift C to NNReal using h_nonneg exact nnnorm_prod_le_of_forall_le hC +@[to_additive] +lemma norm_tprod_le (f : ι → M) : ‖∏' i, f i‖ ≤ ⨆ i, ‖f i‖ := by + rcases isEmpty_or_nonempty ι with hι | hι + · -- Silly case #1 : the index type is empty + simp only [tprod_empty, norm_one', Real.iSup_of_isEmpty, le_refl] + by_cases h : Multipliable f; swap + · -- Silly case #2 : the product is divergent + rw [tprod_eq_one_of_not_multipliable h, norm_one'] + by_cases h_bd : BddAbove (Set.range fun i ↦ ‖f i‖) + · exact le_ciSup_of_le h_bd hι.some (norm_nonneg' _) + · rw [Real.iSup_of_not_bddAbove h_bd] + -- now the interesting case + have h_bd : BddAbove (Set.range fun i ↦ ‖f i‖) := + h.tendsto_cofinite_one.norm'.bddAbove_range_of_cofinite + refine le_of_tendsto' h.hasProd.norm' (fun s ↦ norm_prod_le_of_forall_le_of_nonneg ?_ ?_) + · exact le_ciSup_of_le h_bd hι.some (norm_nonneg' _) + · exact fun i _ ↦ le_ciSup h_bd i + +@[to_additive] +lemma nnnorm_tprod_le (f : ι → M) : ‖∏' i, f i‖₊ ≤ ⨆ i, ‖f i‖₊ := by + simpa only [← NNReal.coe_le_coe, coe_nnnorm', coe_iSup] using norm_tprod_le f + +@[to_additive] +lemma norm_tprod_le_of_forall_le [Nonempty ι] {f : ι → M} {C : ℝ} (h : ∀ i, ‖f i‖ ≤ C) : + ‖∏' i, f i‖ ≤ C := + (norm_tprod_le f).trans (ciSup_le h) + +@[to_additive] +lemma norm_tprod_le_of_forall_le_of_nonneg {f : ι → M} {C : ℝ} (hC : 0 ≤ C) (h : ∀ i, ‖f i‖ ≤ C) : + ‖∏' i, f i‖ ≤ C := by + rcases isEmpty_or_nonempty ι + · simpa only [tprod_empty, norm_one'] using hC + · exact norm_tprod_le_of_forall_le h + +@[to_additive] +lemma nnnorm_tprod_le_of_forall_le {f : ι → M} {C : ℝ≥0} (h : ∀ i, ‖f i‖₊ ≤ C) : ‖∏' i, f i‖₊ ≤ C := + (nnnorm_tprod_le f).trans (ciSup_le' h) + end CommGroup end IsUltrametricDist From 0456b9a130212be2501255a28f73dbc146e05de2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Thu, 17 Oct 2024 15:41:52 +0000 Subject: [PATCH 331/425] feat: `#s` as notation for `Finset.card s` (#17646) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I believe it is time that we finally introduce this notation. This makes serious finset calculations significantly nicer (see eg #5297) and is standard notation. `|s|` would be an alternative, but absolute value elaboration is very complicated like that, so I would rather not, and `#{x | p x}` looks nicer than `|{x | p x}|` (although in return `|s ∩ t|` looks nicer than `#(s ∩ t)`). I am scoping the notation to the `Finset` namespace to avoid clashes with `Cardinal.mk`, which also uses that notation. --- Mathlib/Data/Finset/Card.lean | 316 +++++++++++++++++----------------- 1 file changed, 161 insertions(+), 155 deletions(-) diff --git a/Mathlib/Data/Finset/Card.lean b/Mathlib/Data/Finset/Card.lean index 653bbfc7a2fe2d..376e7fe70747f2 100644 --- a/Mathlib/Data/Finset/Card.lean +++ b/Mathlib/Data/Finset/Card.lean @@ -12,7 +12,7 @@ This defines the cardinality of a `Finset` and provides induction principles for ## Main declarations -* `Finset.card`: `s.card : ℕ` returns the cardinality of `s : Finset α`. +* `Finset.card`: `#s : ℕ` returns the cardinality of `s : Finset α`. ### Induction principles @@ -36,52 +36,56 @@ namespace Finset variable {s t : Finset α} {a b : α} -/-- `s.card` is the number of elements of `s`, aka its cardinality. -/ +/-- `s.card` is the number of elements of `s`, aka its cardinality. + +The notation `#s` can be accessed in the `Finset` locale. -/ def card (s : Finset α) : ℕ := Multiset.card s.1 -theorem card_def (s : Finset α) : s.card = Multiset.card s.1 := +@[inherit_doc] scoped prefix:arg "#" => Finset.card + +theorem card_def (s : Finset α) : #s = Multiset.card s.1 := rfl -@[simp] lemma card_val (s : Finset α) : Multiset.card s.1 = s.card := rfl +@[simp] lemma card_val (s : Finset α) : Multiset.card s.1 = #s := rfl @[simp] -theorem card_mk {m nodup} : (⟨m, nodup⟩ : Finset α).card = Multiset.card m := +theorem card_mk {m nodup} : #(⟨m, nodup⟩ : Finset α) = Multiset.card m := rfl @[simp] -theorem card_empty : card (∅ : Finset α) = 0 := +theorem card_empty : #(∅ : Finset α) = 0 := rfl @[gcongr] -theorem card_le_card : s ⊆ t → s.card ≤ t.card := +theorem card_le_card : s ⊆ t → #s ≤ #t := Multiset.card_le_card ∘ val_le_iff.mpr @[mono] theorem card_mono : Monotone (@card α) := by apply card_le_card -@[simp] lemma card_eq_zero : s.card = 0 ↔ s = ∅ := Multiset.card_eq_zero.trans val_eq_zero -lemma card_ne_zero : s.card ≠ 0 ↔ s.Nonempty := card_eq_zero.ne.trans nonempty_iff_ne_empty.symm -@[simp] lemma card_pos : 0 < s.card ↔ s.Nonempty := Nat.pos_iff_ne_zero.trans card_ne_zero -@[simp] lemma one_le_card : 1 ≤ s.card ↔ s.Nonempty := card_pos +@[simp] lemma card_eq_zero : #s = 0 ↔ s = ∅ := Multiset.card_eq_zero.trans val_eq_zero +lemma card_ne_zero : #s ≠ 0 ↔ s.Nonempty := card_eq_zero.ne.trans nonempty_iff_ne_empty.symm +@[simp] lemma card_pos : 0 < #s ↔ s.Nonempty := Nat.pos_iff_ne_zero.trans card_ne_zero +@[simp] lemma one_le_card : 1 ≤ #s ↔ s.Nonempty := card_pos alias ⟨_, Nonempty.card_pos⟩ := card_pos alias ⟨_, Nonempty.card_ne_zero⟩ := card_ne_zero -theorem card_ne_zero_of_mem (h : a ∈ s) : s.card ≠ 0 := +theorem card_ne_zero_of_mem (h : a ∈ s) : #s ≠ 0 := (not_congr card_eq_zero).2 <| ne_empty_of_mem h @[simp] -theorem card_singleton (a : α) : card ({a} : Finset α) = 1 := +theorem card_singleton (a : α) : #{a} = 1 := Multiset.card_singleton _ -theorem card_singleton_inter [DecidableEq α] : ({a} ∩ s).card ≤ 1 := by +theorem card_singleton_inter [DecidableEq α] : #({a} ∩ s) ≤ 1 := by cases' Finset.decidableMem a s with h h · simp [Finset.singleton_inter_of_not_mem h] · simp [Finset.singleton_inter_of_mem h] @[simp] -theorem card_cons (h : a ∉ s) : (s.cons a h).card = s.card + 1 := +theorem card_cons (h : a ∉ s) : #(s.cons a h) = #s + 1 := Multiset.card_cons _ _ section InsertErase @@ -89,12 +93,12 @@ section InsertErase variable [DecidableEq α] @[simp] -theorem card_insert_of_not_mem (h : a ∉ s) : (insert a s).card = s.card + 1 := by +theorem card_insert_of_not_mem (h : a ∉ s) : #(insert a s) = #s + 1 := by rw [← cons_eq_insert _ _ h, card_cons] -theorem card_insert_of_mem (h : a ∈ s) : card (insert a s) = s.card := by rw [insert_eq_of_mem h] +theorem card_insert_of_mem (h : a ∈ s) : #(insert a s) = #s := by rw [insert_eq_of_mem h] -theorem card_insert_le (a : α) (s : Finset α) : card (insert a s) ≤ s.card + 1 := by +theorem card_insert_le (a : α) (s : Finset α) : #(insert a s) ≤ #s + 1 := by by_cases h : a ∈ s · rw [insert_eq_of_mem h] exact Nat.le_succ _ @@ -104,43 +108,43 @@ section variable {a b c d e f : α} -theorem card_le_two : card {a, b} ≤ 2 := card_insert_le _ _ +theorem card_le_two : #{a, b} ≤ 2 := card_insert_le _ _ -theorem card_le_three : card {a, b, c} ≤ 3 := +theorem card_le_three : #{a, b, c} ≤ 3 := (card_insert_le _ _).trans (Nat.succ_le_succ card_le_two) -theorem card_le_four : card {a, b, c, d} ≤ 4 := +theorem card_le_four : #{a, b, c, d} ≤ 4 := (card_insert_le _ _).trans (Nat.succ_le_succ card_le_three) -theorem card_le_five : card {a, b, c, d, e} ≤ 5 := +theorem card_le_five : #{a, b, c, d, e} ≤ 5 := (card_insert_le _ _).trans (Nat.succ_le_succ card_le_four) -theorem card_le_six : card {a, b, c, d, e, f} ≤ 6 := +theorem card_le_six : #{a, b, c, d, e, f} ≤ 6 := (card_insert_le _ _).trans (Nat.succ_le_succ card_le_five) end /-- If `a ∈ s` is known, see also `Finset.card_insert_of_mem` and `Finset.card_insert_of_not_mem`. -/ -theorem card_insert_eq_ite : card (insert a s) = if a ∈ s then s.card else s.card + 1 := by +theorem card_insert_eq_ite : #(insert a s) = if a ∈ s then #s else #s + 1 := by by_cases h : a ∈ s · rw [card_insert_of_mem h, if_pos h] · rw [card_insert_of_not_mem h, if_neg h] @[simp] -theorem card_pair_eq_one_or_two : ({a,b} : Finset α).card = 1 ∨ ({a,b} : Finset α).card = 2 := by +theorem card_pair_eq_one_or_two : #{a, b} = 1 ∨ #{a, b} = 2 := by simp [card_insert_eq_ite] tauto @[simp] -theorem card_pair (h : a ≠ b) : ({a, b} : Finset α).card = 2 := by +theorem card_pair (h : a ≠ b) : #{a, b} = 2 := by rw [card_insert_of_not_mem (not_mem_singleton.2 h), card_singleton] @[deprecated (since := "2024-01-04")] alias card_doubleton := Finset.card_pair /-- $\#(s \setminus \{a\}) = \#s - 1$ if $a \in s$. -/ @[simp] -theorem card_erase_of_mem : a ∈ s → (s.erase a).card = s.card - 1 := +theorem card_erase_of_mem : a ∈ s → #(s.erase a) = #s - 1 := Multiset.card_erase_of_mem /-- $\#(s \setminus \{a\}) = \#s - 1$ if $a \in s$. @@ -148,55 +152,57 @@ theorem card_erase_of_mem : a ∈ s → (s.erase a).card = s.card - 1 := so that we don't have to work with `ℕ`-subtraction. -/ @[simp] theorem cast_card_erase_of_mem {R} [AddGroupWithOne R] {s : Finset α} (hs : a ∈ s) : - ((s.erase a).card : R) = s.card - 1 := by + (#(s.erase a) : R) = #s - 1 := by rw [card_erase_of_mem hs, Nat.cast_sub, Nat.cast_one] rw [Nat.add_one_le_iff, Finset.card_pos] exact ⟨a, hs⟩ @[simp] -theorem card_erase_add_one : a ∈ s → (s.erase a).card + 1 = s.card := +theorem card_erase_add_one : a ∈ s → #(s.erase a) + 1 = #s := Multiset.card_erase_add_one -theorem card_erase_lt_of_mem : a ∈ s → (s.erase a).card < s.card := +theorem card_erase_lt_of_mem : a ∈ s → #(s.erase a) < #s := Multiset.card_erase_lt_of_mem -theorem card_erase_le : (s.erase a).card ≤ s.card := +theorem card_erase_le : #(s.erase a) ≤ #s := Multiset.card_erase_le -theorem pred_card_le_card_erase : s.card - 1 ≤ (s.erase a).card := by +theorem pred_card_le_card_erase : #s - 1 ≤ #(s.erase a) := by by_cases h : a ∈ s · exact (card_erase_of_mem h).ge · rw [erase_eq_of_not_mem h] exact Nat.sub_le _ _ /-- If `a ∈ s` is known, see also `Finset.card_erase_of_mem` and `Finset.erase_eq_of_not_mem`. -/ -theorem card_erase_eq_ite : (s.erase a).card = if a ∈ s then s.card - 1 else s.card := +theorem card_erase_eq_ite : #(s.erase a) = if a ∈ s then #s - 1 else #s := Multiset.card_erase_eq_ite end InsertErase @[simp] -theorem card_range (n : ℕ) : (range n).card = n := +theorem card_range (n : ℕ) : #(range n) = n := Multiset.card_range n @[simp] -theorem card_attach : s.attach.card = s.card := +theorem card_attach : #s.attach = #s := Multiset.card_attach end Finset +open scoped Finset + section ToMLListultiset variable [DecidableEq α] (m : Multiset α) (l : List α) -theorem Multiset.card_toFinset : m.toFinset.card = Multiset.card m.dedup := +theorem Multiset.card_toFinset : #m.toFinset = Multiset.card m.dedup := rfl -theorem Multiset.toFinset_card_le : m.toFinset.card ≤ Multiset.card m := +theorem Multiset.toFinset_card_le : #m.toFinset ≤ Multiset.card m := card_le_card <| dedup_le _ theorem Multiset.toFinset_card_of_nodup {m : Multiset α} (h : m.Nodup) : - m.toFinset.card = Multiset.card m := + #m.toFinset = Multiset.card m := congr_arg card <| Multiset.dedup_eq_self.mpr h theorem Multiset.dedup_card_eq_card_iff_nodup {m : Multiset α} : @@ -204,15 +210,15 @@ theorem Multiset.dedup_card_eq_card_iff_nodup {m : Multiset α} : .trans ⟨fun h ↦ eq_of_le_of_card_le (dedup_le m) h.ge, congr_arg _⟩ dedup_eq_self theorem Multiset.toFinset_card_eq_card_iff_nodup {m : Multiset α} : - m.toFinset.card = card m ↔ m.Nodup := dedup_card_eq_card_iff_nodup + #m.toFinset = card m ↔ m.Nodup := dedup_card_eq_card_iff_nodup -theorem List.card_toFinset : l.toFinset.card = l.dedup.length := +theorem List.card_toFinset : #l.toFinset = l.dedup.length := rfl -theorem List.toFinset_card_le : l.toFinset.card ≤ l.length := +theorem List.toFinset_card_le : #l.toFinset ≤ l.length := Multiset.toFinset_card_le ⟦l⟧ -theorem List.toFinset_card_of_nodup {l : List α} (h : l.Nodup) : l.toFinset.card = l.length := +theorem List.toFinset_card_of_nodup {l : List α} (h : l.Nodup) : #l.toFinset = l.length := Multiset.toFinset_card_of_nodup h end ToMLListultiset @@ -222,16 +228,16 @@ namespace Finset variable {s t u : Finset α} {f : α → β} {n : ℕ} @[simp] -theorem length_toList (s : Finset α) : s.toList.length = s.card := by +theorem length_toList (s : Finset α) : s.toList.length = #s := by rw [toList, ← Multiset.coe_card, Multiset.coe_toList, card_def] -theorem card_image_le [DecidableEq β] : (s.image f).card ≤ s.card := by +theorem card_image_le [DecidableEq β] : #(s.image f) ≤ #s := by simpa only [card_map] using (s.1.map f).toFinset_card_le -theorem card_image_of_injOn [DecidableEq β] (H : Set.InjOn f s) : (s.image f).card = s.card := by +theorem card_image_of_injOn [DecidableEq β] (H : Set.InjOn f s) : #(s.image f) = #s := by simp only [card, image_val_of_injOn H, card_map] -theorem injOn_of_card_image_eq [DecidableEq β] (H : (s.image f).card = s.card) : Set.InjOn f s := by +theorem injOn_of_card_image_eq [DecidableEq β] (H : #(s.image f) = #s) : Set.InjOn f s := by rw [card_def, card_def, image, toFinset] at H dsimp only at H have : (s.1.map f).dedup = s.1.map f := by @@ -240,58 +246,58 @@ theorem injOn_of_card_image_eq [DecidableEq β] (H : (s.image f).card = s.card) rw [Multiset.dedup_eq_self] at this exact inj_on_of_nodup_map this -theorem card_image_iff [DecidableEq β] : (s.image f).card = s.card ↔ Set.InjOn f s := +theorem card_image_iff [DecidableEq β] : #(s.image f) = #s ↔ Set.InjOn f s := ⟨injOn_of_card_image_eq, card_image_of_injOn⟩ theorem card_image_of_injective [DecidableEq β] (s : Finset α) (H : Injective f) : - (s.image f).card = s.card := + #(s.image f) = #s := card_image_of_injOn fun _ _ _ _ h => H h theorem fiber_card_ne_zero_iff_mem_image (s : Finset α) (f : α → β) [DecidableEq β] (y : β) : - (s.filter fun x => f x = y).card ≠ 0 ↔ y ∈ s.image f := by + #(s.filter fun x ↦ f x = y) ≠ 0 ↔ y ∈ s.image f := by rw [← Nat.pos_iff_ne_zero, card_pos, fiber_nonempty_iff_mem_image] lemma card_filter_le_iff (s : Finset α) (P : α → Prop) [DecidablePred P] (n : ℕ) : - (s.filter P).card ≤ n ↔ ∀ s' ⊆ s, n < s'.card → ∃ a ∈ s', ¬ P a := + #(s.filter P) ≤ n ↔ ∀ s' ⊆ s, n < #s' → ∃ a ∈ s', ¬ P a := (s.1.card_filter_le_iff P n).trans ⟨fun H s' hs' h ↦ H s'.1 (by aesop) h, fun H s' hs' h ↦ H ⟨s', nodup_of_le hs' s.2⟩ (fun _ hx ↦ subset_of_le hs' hx) h⟩ @[simp] -theorem card_map (f : α ↪ β) : (s.map f).card = s.card := +theorem card_map (f : α ↪ β) : #(s.map f) = #s := Multiset.card_map _ _ @[simp] theorem card_subtype (p : α → Prop) [DecidablePred p] (s : Finset α) : - (s.subtype p).card = (s.filter p).card := by simp [Finset.subtype] + #(s.subtype p) = #(s.filter p) := by simp [Finset.subtype] theorem card_filter_le (s : Finset α) (p : α → Prop) [DecidablePred p] : - (s.filter p).card ≤ s.card := + #(s.filter p) ≤ #s := card_le_card <| filter_subset _ _ -theorem eq_of_subset_of_card_le {s t : Finset α} (h : s ⊆ t) (h₂ : t.card ≤ s.card) : s = t := +theorem eq_of_subset_of_card_le {s t : Finset α} (h : s ⊆ t) (h₂ : #t ≤ #s) : s = t := eq_of_veq <| Multiset.eq_of_le_of_card_le (val_le_iff.mpr h) h₂ -theorem eq_of_superset_of_card_ge (hst : s ⊆ t) (hts : t.card ≤ s.card) : t = s := +theorem eq_of_superset_of_card_ge (hst : s ⊆ t) (hts : #t ≤ #s) : t = s := (eq_of_subset_of_card_le hst hts).symm -theorem subset_iff_eq_of_card_le (h : t.card ≤ s.card) : s ⊆ t ↔ s = t := +theorem subset_iff_eq_of_card_le (h : #t ≤ #s) : s ⊆ t ↔ s = t := ⟨fun hst => eq_of_subset_of_card_le hst h, Eq.subset'⟩ theorem map_eq_of_subset {f : α ↪ α} (hs : s.map f ⊆ s) : s.map f = s := eq_of_subset_of_card_le hs (card_map _).ge -theorem filter_card_eq {p : α → Prop} [DecidablePred p] (h : (s.filter p).card = s.card) (x : α) +theorem filter_card_eq {p : α → Prop} [DecidablePred p] (h : #(s.filter p) = #s) (x : α) (hx : x ∈ s) : p x := by rw [← eq_of_subset_of_card_le (s.filter_subset p) h.ge, mem_filter] at hx exact hx.2 -nonrec lemma card_lt_card (h : s ⊂ t) : s.card < t.card := card_lt_card <| val_lt_iff.2 h +nonrec lemma card_lt_card (h : s ⊂ t) : #s < #t := card_lt_card <| val_lt_iff.2 h lemma card_strictMono : StrictMono (card : Finset α → ℕ) := fun _ _ ↦ card_lt_card theorem card_eq_of_bijective (f : ∀ i, i < n → α) (hf : ∀ a ∈ s, ∃ i, ∃ h : i < n, f i h = a) (hf' : ∀ i (h : i < n), f i h ∈ s) - (f_inj : ∀ i j (hi : i < n) (hj : j < n), f i hi = f j hj → i = j) : s.card = n := by + (f_inj : ∀ i j (hi : i < n) (hj : j < n), f i hi = f j hj → i = j) : #s = n := by classical have : s = (range n).attach.image fun i => f i.1 (mem_range.1 i.2) := by ext a @@ -301,10 +307,10 @@ theorem card_eq_of_bijective (f : ∀ i, i < n → α) (hf : ∀ a ∈ s, ∃ i, · intro ha; obtain ⟨i, hi, rfl⟩ := hf a ha; use i, mem_range.2 hi · rintro ⟨i, hi, rfl⟩; apply hf' calc - s.card = ((range n).attach.image fun i => f i.1 (mem_range.1 i.2)).card := by rw [this] - _ = (range n).attach.card := ?_ - _ = (range n).card := card_attach - _ = n := card_range n + #s = #((range n).attach.image fun i => f i.1 (mem_range.1 i.2)) := by rw [this] + _ = #(range n).attach := ?_ + _ = #(range n) := card_attach + _ = n := card_range n apply card_image_of_injective intro ⟨i, hi⟩ ⟨j, hj⟩ eq exact Subtype.eq <| f_inj i j (mem_range.1 hi) (mem_range.1 hj) eq @@ -321,12 +327,12 @@ The difference with `Finset.card_nbij` is that the bijection is allowed to use m domain, rather than being a non-dependent function. -/ lemma card_bij (i : ∀ a ∈ s, β) (hi : ∀ a ha, i a ha ∈ t) (i_inj : ∀ a₁ ha₁ a₂ ha₂, i a₁ ha₁ = i a₂ ha₂ → a₁ = a₂) - (i_surj : ∀ b ∈ t, ∃ a ha, i a ha = b) : s.card = t.card := by + (i_surj : ∀ b ∈ t, ∃ a ha, i a ha = b) : #s = #t := by classical calc - s.card = s.attach.card := card_attach.symm - _ = (s.attach.image fun a : { a // a ∈ s } => i a.1 a.2).card := Eq.symm ?_ - _ = t.card := ?_ + #s = #s.attach := card_attach.symm + _ = #(s.attach.image fun a ↦ i a.1 a.2) := Eq.symm ?_ + _ = #t := ?_ · apply card_image_of_injective intro ⟨_, _⟩ ⟨_, _⟩ h simpa using i_inj _ _ _ _ h @@ -347,7 +353,7 @@ The difference with `Finset.card_nbij'` is that the bijection and its inverse ar membership of the domains, rather than being non-dependent functions. -/ lemma card_bij' (i : ∀ a ∈ s, β) (j : ∀ a ∈ t, α) (hi : ∀ a ha, i a ha ∈ t) (hj : ∀ a ha, j a ha ∈ s) (left_inv : ∀ a ha, j (i a ha) (hi a ha) = a) - (right_inv : ∀ a ha, i (j a ha) (hj a ha) = a) : s.card = t.card := by + (right_inv : ∀ a ha, i (j a ha) (hj a ha) = a) : #s = #t := by refine card_bij i hi (fun a1 h1 a2 h2 eq ↦ ?_) (fun b hb ↦ ⟨_, hj b hb, right_inv b hb⟩) rw [← left_inv a1 h1, ← left_inv a2 h2] simp only [eq] @@ -360,7 +366,7 @@ injection, rather than by an inverse function. The difference with `Finset.card_bij` is that the bijection is a non-dependent function, rather than being allowed to use membership of the domain. -/ lemma card_nbij (i : α → β) (hi : ∀ a ∈ s, i a ∈ t) (i_inj : (s : Set α).InjOn i) - (i_surj : (s : Set α).SurjOn i t) : s.card = t.card := + (i_surj : (s : Set α).SurjOn i t) : #s = #t := card_bij (fun a _ ↦ i a) hi i_inj (by simpa using i_surj) /-- Reorder a finset. @@ -374,35 +380,35 @@ functions, rather than being allowed to use membership of the domains. The difference with `Finset.card_equiv` is that bijectivity is only required to hold on the domains, rather than on the entire types. -/ lemma card_nbij' (i : α → β) (j : β → α) (hi : ∀ a ∈ s, i a ∈ t) (hj : ∀ a ∈ t, j a ∈ s) - (left_inv : ∀ a ∈ s, j (i a) = a) (right_inv : ∀ a ∈ t, i (j a) = a) : s.card = t.card := + (left_inv : ∀ a ∈ s, j (i a) = a) (right_inv : ∀ a ∈ t, i (j a) = a) : #s = #t := card_bij' (fun a _ ↦ i a) (fun b _ ↦ j b) hi hj left_inv right_inv /-- Specialization of `Finset.card_nbij'` that automatically fills in most arguments. See `Fintype.card_equiv` for the version where `s` and `t` are `univ`. -/ -lemma card_equiv (e : α ≃ β) (hst : ∀ i, i ∈ s ↔ e i ∈ t) : s.card = t.card := by +lemma card_equiv (e : α ≃ β) (hst : ∀ i, i ∈ s ↔ e i ∈ t) : #s = #t := by refine card_nbij' e e.symm ?_ ?_ ?_ ?_ <;> simp [hst] /-- Specialization of `Finset.card_nbij` that automatically fills in most arguments. See `Fintype.card_bijective` for the version where `s` and `t` are `univ`. -/ lemma card_bijective (e : α → β) (he : e.Bijective) (hst : ∀ i, i ∈ s ↔ e i ∈ t) : - s.card = t.card := card_equiv (.ofBijective e he) hst + #s = #t := card_equiv (.ofBijective e he) hst lemma card_le_card_of_injOn (f : α → β) (hf : ∀ a ∈ s, f a ∈ t) (f_inj : (s : Set α).InjOn f) : - s.card ≤ t.card := by + #s ≤ #t := by classical calc - s.card = (s.image f).card := (card_image_of_injOn f_inj).symm - _ ≤ t.card := card_le_card <| image_subset_iff.2 hf + #s = #(s.image f) := (card_image_of_injOn f_inj).symm + _ ≤ #t := card_le_card <| image_subset_iff.2 hf @[deprecated (since := "2024-06-01")] alias card_le_card_of_inj_on := card_le_card_of_injOn -lemma card_le_card_of_surjOn (f : α → β) (hf : Set.SurjOn f s t) : t.card ≤ s.card := by +lemma card_le_card_of_surjOn (f : α → β) (hf : Set.SurjOn f s t) : #t ≤ #s := by classical unfold Set.SurjOn at hf; exact (card_le_card (mod_cast hf)).trans card_image_le /-- If there are more pigeons than pigeonholes, then there are two pigeons in the same pigeonhole. -/ -theorem exists_ne_map_eq_of_card_lt_of_maps_to {t : Finset β} (hc : t.card < s.card) {f : α → β} +theorem exists_ne_map_eq_of_card_lt_of_maps_to {t : Finset β} (hc : #t < #s) {f : α → β} (hf : ∀ a ∈ s, f a ∈ t) : ∃ x ∈ s, ∃ y ∈ s, x ≠ y ∧ f x = f y := by classical by_contra! hz @@ -412,16 +418,16 @@ theorem exists_ne_map_eq_of_card_lt_of_maps_to {t : Finset β} (hc : t.card < s. exact hz x hx y hy lemma le_card_of_inj_on_range (f : ℕ → α) (hf : ∀ i < n, f i ∈ s) - (f_inj : ∀ i < n, ∀ j < n, f i = f j → i = j) : n ≤ s.card := + (f_inj : ∀ i < n, ∀ j < n, f i = f j → i = j) : n ≤ #s := calc - n = card (range n) := (card_range n).symm - _ ≤ s.card := card_le_card_of_injOn f (by simpa only [mem_range]) (by simpa) + n = #(range n) := (card_range n).symm + _ ≤ #s := card_le_card_of_injOn f (by simpa only [mem_range]) (by simpa) lemma surj_on_of_inj_on_of_card_le (f : ∀ a ∈ s, β) (hf : ∀ a ha, f a ha ∈ t) - (hinj : ∀ a₁ a₂ ha₁ ha₂, f a₁ ha₁ = f a₂ ha₂ → a₁ = a₂) (hst : t.card ≤ s.card) : + (hinj : ∀ a₁ a₂ ha₁ ha₂, f a₁ ha₁ = f a₂ ha₂ → a₁ = a₂) (hst : #t ≤ #s) : ∀ b ∈ t, ∃ a ha, b = f a ha := by classical - have h : (s.attach.image fun a : { a // a ∈ s } => f a a.prop).card = s.card := by + have h : #(s.attach.image fun a : s ↦ f a a.2) = #s := by rw [← @card_attach _ s, card_image_of_injective] intro ⟨_, _⟩ ⟨_, _⟩ h exact Subtype.eq <| hinj _ _ _ _ h @@ -431,7 +437,7 @@ lemma surj_on_of_inj_on_of_card_le (f : ∀ a ∈ s, β) (hf : ∀ a ha, f a ha exact fun b a ha hb ↦ ⟨a, ha, hb.symm⟩ theorem inj_on_of_surj_on_of_card_le (f : ∀ a ∈ s, β) (hf : ∀ a ha, f a ha ∈ t) - (hsurj : ∀ b ∈ t, ∃ a ha, f a ha = b) (hst : s.card ≤ t.card) ⦃a₁⦄ (ha₁ : a₁ ∈ s) ⦃a₂⦄ + (hsurj : ∀ b ∈ t, ∃ a ha, f a ha = b) (hst : #s ≤ #t) ⦃a₁⦄ (ha₁ : a₁ ∈ s) ⦃a₂⦄ (ha₂ : a₂ ∈ s) (ha₁a₂ : f a₁ ha₁ = f a₂ ha₂) : a₁ = a₂ := haveI : Inhabited { x // x ∈ s } := ⟨⟨a₁, ha₁⟩⟩ let f' : { x // x ∈ s } → { x // x ∈ t } := fun x => ⟨f x.1 x.2, hf x.1 x.2⟩ @@ -453,7 +459,7 @@ theorem inj_on_of_surj_on_of_card_le (f : ∀ a ∈ s, β) (hf : ∀ a ha, f a h end bij @[simp] -theorem card_disjUnion (s t : Finset α) (h) : (s.disjUnion t h).card = s.card + t.card := +theorem card_disjUnion (s t : Finset α) (h) : #(s.disjUnion t h) = #s + #t := Multiset.card_add _ _ /-! ### Lattice structure -/ @@ -464,23 +470,23 @@ section Lattice variable [DecidableEq α] theorem card_union_add_card_inter (s t : Finset α) : - (s ∪ t).card + (s ∩ t).card = s.card + t.card := + #(s ∪ t) + #(s ∩ t) = #s + #t := Finset.induction_on t (by simp) fun a r har h => by by_cases a ∈ s <;> simp [*, ← add_assoc, add_right_comm _ 1] theorem card_inter_add_card_union (s t : Finset α) : - (s ∩ t).card + (s ∪ t).card = s.card + t.card := by rw [add_comm, card_union_add_card_inter] + #(s ∩ t) + #(s ∪ t) = #s + #t := by rw [add_comm, card_union_add_card_inter] -lemma card_union (s t : Finset α) : (s ∪ t).card = s.card + t.card - (s ∩ t).card := by +lemma card_union (s t : Finset α) : #(s ∪ t) = #s + #t - #(s ∩ t) := by rw [← card_union_add_card_inter, Nat.add_sub_cancel] -lemma card_inter (s t : Finset α) : (s ∩ t).card = s.card + t.card - (s ∪ t).card := by +lemma card_inter (s t : Finset α) : #(s ∩ t) = #s + #t - #(s ∪ t) := by rw [← card_inter_add_card_union, Nat.add_sub_cancel] -theorem card_union_le (s t : Finset α) : (s ∪ t).card ≤ s.card + t.card := +theorem card_union_le (s t : Finset α) : #(s ∪ t) ≤ #s + #t := card_union_add_card_inter s t ▸ Nat.le_add_right _ _ -lemma card_union_eq_card_add_card : (s ∪ t).card = s.card + t.card ↔ Disjoint s t := by +lemma card_union_eq_card_add_card : #(s ∪ t) = #s + #t ↔ Disjoint s t := by rw [← card_union_add_card_inter]; simp [disjoint_iff_inter_eq_empty] @[simp] alias ⟨_, card_union_of_disjoint⟩ := card_union_eq_card_add_card @@ -489,70 +495,70 @@ lemma card_union_eq_card_add_card : (s ∪ t).card = s.card + t.card ↔ Disjoin @[deprecated (since := "2024-02-09")] alias card_disjoint_union := card_union_of_disjoint lemma cast_card_inter [AddGroupWithOne R] : - ((s ∩ t).card : R) = s.card + t.card - (s ∪ t).card := by + (#(s ∩ t) : R) = #s + #t - #(s ∪ t) := by rw [eq_sub_iff_add_eq, ← cast_add, card_inter_add_card_union, cast_add] lemma cast_card_union [AddGroupWithOne R] : - ((s ∪ t).card : R) = s.card + t.card - (s ∩ t).card := by + (#(s ∪ t) : R) = #s + #t - #(s ∩ t) := by rw [eq_sub_iff_add_eq, ← cast_add, card_union_add_card_inter, cast_add] -theorem card_sdiff (h : s ⊆ t) : card (t \ s) = t.card - s.card := by - suffices card (t \ s) = card (t \ s ∪ s) - s.card by rwa [sdiff_union_of_subset h] at this +theorem card_sdiff (h : s ⊆ t) : #(t \ s) = #t - #s := by + suffices #(t \ s) = #(t \ s ∪ s) - #s by rwa [sdiff_union_of_subset h] at this rw [card_union_of_disjoint sdiff_disjoint, Nat.add_sub_cancel_right] -lemma cast_card_sdiff [AddGroupWithOne R] (h : s ⊆ t) : ((t \ s).card : R) = t.card - s.card := by +lemma cast_card_sdiff [AddGroupWithOne R] (h : s ⊆ t) : (#(t \ s) : R) = #t - #s := by rw [card_sdiff h, Nat.cast_sub (card_mono h)] -theorem card_sdiff_add_card_eq_card {s t : Finset α} (h : s ⊆ t) : card (t \ s) + card s = card t := +theorem card_sdiff_add_card_eq_card {s t : Finset α} (h : s ⊆ t) : #(t \ s) + #s = #t := ((Nat.sub_eq_iff_eq_add (card_le_card h)).mp (card_sdiff h).symm).symm -theorem le_card_sdiff (s t : Finset α) : t.card - s.card ≤ card (t \ s) := +theorem le_card_sdiff (s t : Finset α) : #t - #s ≤ #(t \ s) := calc - card t - card s ≤ card t - card (s ∩ t) := + #t - #s ≤ #t - #(s ∩ t) := Nat.sub_le_sub_left (card_le_card inter_subset_left) _ - _ = card (t \ (s ∩ t)) := (card_sdiff inter_subset_right).symm - _ ≤ card (t \ s) := by rw [sdiff_inter_self_right t s] + _ = #(t \ (s ∩ t)) := (card_sdiff inter_subset_right).symm + _ ≤ #(t \ s) := by rw [sdiff_inter_self_right t s] -theorem card_le_card_sdiff_add_card : s.card ≤ (s \ t).card + t.card := +theorem card_le_card_sdiff_add_card : #s ≤ #(s \ t) + #t := Nat.sub_le_iff_le_add.1 <| le_card_sdiff _ _ -theorem card_sdiff_add_card (s t : Finset α) : (s \ t).card + t.card = (s ∪ t).card := by +theorem card_sdiff_add_card (s t : Finset α) : #(s \ t) + #t = #(s ∪ t) := by rw [← card_union_of_disjoint sdiff_disjoint, sdiff_union_self_eq_union] -lemma card_sdiff_comm (h : s.card = t.card) : (s \ t).card = (t \ s).card := - add_left_injective t.card <| by +lemma card_sdiff_comm (h : #s = #t) : #(s \ t) = #(t \ s) := + add_left_injective #t <| by simp_rw [card_sdiff_add_card, ← h, card_sdiff_add_card, union_comm] @[simp] lemma card_sdiff_add_card_inter (s t : Finset α) : - (s \ t).card + (s ∩ t).card = s.card := by + #(s \ t) + #(s ∩ t) = #s := by rw [← card_union_of_disjoint (disjoint_sdiff_inter _ _), sdiff_union_inter] @[simp] lemma card_inter_add_card_sdiff (s t : Finset α) : - (s ∩ t).card + (s \ t).card = s.card := by + #(s ∩ t) + #(s \ t) = #s := by rw [add_comm, card_sdiff_add_card_inter] /-- **Pigeonhole principle** for two finsets inside an ambient finset. -/ theorem inter_nonempty_of_card_lt_card_add_card (hts : t ⊆ s) (hus : u ⊆ s) - (hstu : s.card < t.card + u.card) : (t ∩ u).Nonempty := by + (hstu : #s < #t + #u) : (t ∩ u).Nonempty := by contrapose! hstu calc - _ = (t ∪ u).card := by simp [← card_union_add_card_inter, not_nonempty_iff_eq_empty.1 hstu] - _ ≤ s.card := by gcongr; exact union_subset hts hus + _ = #(t ∪ u) := by simp [← card_union_add_card_inter, not_nonempty_iff_eq_empty.1 hstu] + _ ≤ #s := by gcongr; exact union_subset hts hus end Lattice theorem filter_card_add_filter_neg_card_eq_card (p : α → Prop) [DecidablePred p] [∀ x, Decidable (¬p x)] : - (s.filter p).card + (s.filter (fun a => ¬ p a)).card = s.card := by + #(s.filter p) + #(s.filter fun a ↦ ¬ p a) = #s := by classical rw [← card_union_of_disjoint (disjoint_filter_filter_neg _ _ _), filter_union_filter_neg_eq] /-- 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.card ≤ n) (hnt : n ≤ t.card) : - ∃ u, s ⊆ u ∧ u ⊆ t ∧ card u = n := by +lemma exists_subsuperset_card_eq (hst : s ⊆ t) (hsn : #s ≤ n) (hnt : n ≤ #t) : + ∃ u, s ⊆ u ∧ u ⊆ t ∧ #u = n := by classical refine Nat.decreasingInduction' ?_ hnt ⟨t, by simp [hst]⟩ intro k _ hnk ⟨u, hu₁, hu₂, hu₃⟩ @@ -561,48 +567,48 @@ lemma exists_subsuperset_card_eq (hst : s ⊆ t) (hsn : s.card ≤ n) (hnt : n exact ⟨u.erase a, by simp [subset_erase, erase_subset_iff_of_mem (hu₂ _), *]⟩ /-- We can shrink a set to any smaller size. -/ -lemma exists_subset_card_eq (hns : n ≤ s.card) : ∃ t ⊆ s, t.card = n := by +lemma exists_subset_card_eq (hns : n ≤ #s) : ∃ t ⊆ s, #t = n := by simpa using exists_subsuperset_card_eq s.empty_subset (by simp) hns /-- Given a set `A` and a set `B` inside it, we can shrink `A` to any appropriate size, and keep `B` inside it. -/ @[deprecated exists_subsuperset_card_eq (since := "2024-06-23")] -theorem exists_intermediate_set {A B : Finset α} (i : ℕ) (h₁ : i + card B ≤ card A) (h₂ : B ⊆ A) : - ∃ C : Finset α, B ⊆ C ∧ C ⊆ A ∧ card C = i + card B := +theorem exists_intermediate_set {A B : Finset α} (i : ℕ) (h₁ : i + #B ≤ #A) (h₂ : B ⊆ A) : + ∃ C : Finset α, B ⊆ C ∧ C ⊆ A ∧ #C = i + #B := exists_subsuperset_card_eq h₂ (Nat.le_add_left ..) h₁ /-- We can shrink `A` to any smaller size. -/ @[deprecated exists_subset_card_eq (since := "2024-06-23")] -theorem exists_smaller_set (A : Finset α) (i : ℕ) (h₁ : i ≤ card A) : - ∃ B : Finset α, B ⊆ A ∧ card B = i := exists_subset_card_eq h₁ +theorem exists_smaller_set (A : Finset α) (i : ℕ) (h₁ : i ≤ #A) : + ∃ B : Finset α, B ⊆ A ∧ #B = i := exists_subset_card_eq h₁ -theorem le_card_iff_exists_subset_card : n ≤ s.card ↔ ∃ t ⊆ s, t.card = n := by +theorem le_card_iff_exists_subset_card : n ≤ #s ↔ ∃ t ⊆ s, #t = n := by refine ⟨fun h => ?_, fun ⟨t, hst, ht⟩ => ht ▸ card_le_card hst⟩ exact exists_subset_card_eq h theorem exists_subset_or_subset_of_two_mul_lt_card [DecidableEq α] {X Y : Finset α} {n : ℕ} - (hXY : 2 * n < (X ∪ Y).card) : ∃ C : Finset α, n < C.card ∧ (C ⊆ X ∨ C ⊆ Y) := by - have h₁ : (X ∩ (Y \ X)).card = 0 := Finset.card_eq_zero.mpr (Finset.inter_sdiff_self X Y) - have h₂ : (X ∪ Y).card = X.card + (Y \ X).card := by + (hXY : 2 * n < #(X ∪ Y)) : ∃ C : Finset α, n < #C ∧ (C ⊆ X ∨ C ⊆ Y) := by + have h₁ : #(X ∩ (Y \ X)) = 0 := Finset.card_eq_zero.mpr (Finset.inter_sdiff_self X Y) + have h₂ : #(X ∪ Y) = #X + #(Y \ X) := by rw [← card_union_add_card_inter X (Y \ X), Finset.union_sdiff_self_eq_union, h₁, add_zero] rw [h₂, Nat.two_mul] at hXY - obtain h | h : n < X.card ∨ n < (Y \ X).card := by contrapose! hXY; omega + obtain h | h : n < #X ∨ n < #(Y \ X) := by contrapose! hXY; omega · exact ⟨X, h, Or.inl (Finset.Subset.refl X)⟩ · exact ⟨Y \ X, h, Or.inr sdiff_subset⟩ /-! ### Explicit description of a finset from its card -/ -theorem card_eq_one : s.card = 1 ↔ ∃ a, s = {a} := by +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 _root_.Multiset.toFinset_card_eq_one_iff [DecidableEq α] (s : Multiset α) : - s.toFinset.card = 1 ↔ Multiset.card s ≠ 0 ∧ ∃ a : α, s = Multiset.card s • {a} := by + #s.toFinset = 1 ↔ Multiset.card s ≠ 0 ∧ ∃ a : α, s = Multiset.card s • {a} := by simp_rw [card_eq_one, Multiset.toFinset_eq_singleton_iff, exists_and_left] theorem exists_eq_insert_iff [DecidableEq α] {s t : Finset α} : - (∃ a ∉ s, insert a s = t) ↔ s ⊆ t ∧ s.card + 1 = t.card := by + (∃ a ∉ s, insert a s = t) ↔ s ⊆ t ∧ #s + 1 = #t := by constructor · rintro ⟨a, ha, rfl⟩ exact ⟨subset_insert _ _, (card_insert_of_not_mem ha).symm⟩ @@ -615,7 +621,7 @@ theorem exists_eq_insert_iff [DecidableEq α] {s t : Finset α} : rw [← ha] exact not_mem_sdiff_of_mem_right hs -theorem card_le_one : s.card ≤ 1 ↔ ∀ a ∈ s, ∀ b ∈ s, a = b := by +theorem card_le_one : #s ≤ 1 ↔ ∀ a ∈ s, ∀ b ∈ s, a = b := by obtain rfl | ⟨x, hx⟩ := s.eq_empty_or_nonempty · simp refine (Nat.succ_le_of_lt (card_pos.2 ⟨x, hx⟩)).le_iff_eq.trans (card_eq_one.trans ⟨?_, ?_⟩) @@ -623,14 +629,14 @@ theorem card_le_one : s.card ≤ 1 ↔ ∀ a ∈ s, ∀ b ∈ s, a = b := by simp · exact fun h => ⟨x, eq_singleton_iff_unique_mem.2 ⟨hx, fun y hy => h _ hy _ hx⟩⟩ -theorem card_le_one_iff : s.card ≤ 1 ↔ ∀ {a b}, a ∈ s → b ∈ s → a = b := by +theorem card_le_one_iff : #s ≤ 1 ↔ ∀ {a b}, a ∈ s → b ∈ s → a = b := by rw [card_le_one] tauto -theorem card_le_one_iff_subsingleton_coe : s.card ≤ 1 ↔ Subsingleton (s : Type _) := +theorem card_le_one_iff_subsingleton_coe : #s ≤ 1 ↔ Subsingleton (s : Type _) := card_le_one.trans (s : Set α).subsingleton_coe.symm -theorem card_le_one_iff_subset_singleton [Nonempty α] : s.card ≤ 1 ↔ ∃ x : α, s ⊆ {x} := by +theorem card_le_one_iff_subset_singleton [Nonempty α] : #s ≤ 1 ↔ ∃ x : α, s ⊆ {x} := by refine ⟨fun H => ?_, ?_⟩ · obtain rfl | ⟨x, hx⟩ := s.eq_empty_or_nonempty · exact ⟨Classical.arbitrary α, empty_subset _⟩ @@ -639,32 +645,32 @@ theorem card_le_one_iff_subset_singleton [Nonempty α] : s.card ≤ 1 ↔ ∃ x rw [← card_singleton x] exact card_le_card hx -lemma exists_mem_ne (hs : 1 < s.card) (a : α) : ∃ b ∈ s, b ≠ a := by +lemma exists_mem_ne (hs : 1 < #s) (a : α) : ∃ b ∈ s, b ≠ a := by have : Nonempty α := ⟨a⟩ by_contra! exact hs.not_le (card_le_one_iff_subset_singleton.2 ⟨a, subset_singleton_iff'.2 this⟩) /-- A `Finset` of a subsingleton type has cardinality at most one. -/ -theorem card_le_one_of_subsingleton [Subsingleton α] (s : Finset α) : s.card ≤ 1 := +theorem card_le_one_of_subsingleton [Subsingleton α] (s : Finset α) : #s ≤ 1 := Finset.card_le_one_iff.2 fun {_ _ _ _} => Subsingleton.elim _ _ -theorem one_lt_card : 1 < s.card ↔ ∃ a ∈ s, ∃ b ∈ s, a ≠ b := by +theorem one_lt_card : 1 < #s ↔ ∃ a ∈ s, ∃ b ∈ s, a ≠ b := by rw [← not_iff_not] push_neg exact card_le_one -theorem one_lt_card_iff : 1 < s.card ↔ ∃ a b, a ∈ s ∧ b ∈ s ∧ a ≠ b := by +theorem one_lt_card_iff : 1 < #s ↔ ∃ a b, a ∈ s ∧ b ∈ s ∧ a ≠ b := by rw [one_lt_card] simp only [exists_prop, exists_and_left] -theorem one_lt_card_iff_nontrivial : 1 < s.card ↔ s.Nontrivial := by +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] @[deprecated (since := "2024-02-05")] alias one_lt_card_iff_nontrivial_coe := one_lt_card_iff_nontrivial -theorem exists_ne_of_one_lt_card (hs : 1 < s.card) (a : α) : ∃ b, b ∈ s ∧ b ≠ a := by +theorem exists_ne_of_one_lt_card (hs : 1 < #s) (a : α) : ∃ b, b ∈ s ∧ b ≠ a := by obtain ⟨x, hx, y, hy, hxy⟩ := Finset.one_lt_card.mp hs by_cases ha : y = a · exact ⟨x, hx, ne_of_ne_of_eq hxy ha⟩ @@ -674,8 +680,8 @@ theorem exists_ne_of_one_lt_card (hs : 1 < s.card) (a : α) : ∃ b, b ∈ s ∧ its projection to some factor is nontrivial, and the fibers of the projection are proper subsets. -/ lemma exists_of_one_lt_card_pi {ι : Type*} {α : ι → Type*} [∀ i, DecidableEq (α i)] - {s : Finset (∀ i, α i)} (h : 1 < s.card) : - ∃ i, 1 < (s.image (· i)).card ∧ ∀ ai, s.filter (· i = ai) ⊂ s := by + {s : Finset (∀ i, α i)} (h : 1 < #s) : + ∃ i, 1 < #(s.image (· i)) ∧ ∀ ai, s.filter (· i = ai) ⊂ s := by simp_rw [one_lt_card_iff, Function.ne_iff] at h ⊢ obtain ⟨a1, a2, h1, h2, i, hne⟩ := h refine ⟨i, ⟨_, _, mem_image_of_mem _ h1, mem_image_of_mem _ h2, hne⟩, fun ai => ?_⟩ @@ -684,21 +690,21 @@ lemma exists_of_one_lt_card_pi {ι : Type*} {α : ι → Type*} [∀ i, Decidabl exacts [⟨a1, h1, hne⟩, ⟨a2, h2, hne⟩] theorem card_eq_succ_iff_cons : - s.card = n + 1 ↔ ∃ a t, ∃ (h : a ∉ t), cons a t h = s ∧ t.card = n := + #s = n + 1 ↔ ∃ a t, ∃ (h : a ∉ t), cons a t h = s ∧ #t = n := ⟨cons_induction_on s (by simp) fun a s _ _ _ => ⟨a, s, by simp_all⟩, fun ⟨a, t, _, hs, _⟩ => by simpa [← hs]⟩ section DecidableEq variable [DecidableEq α] -theorem card_eq_succ : s.card = n + 1 ↔ ∃ a t, a ∉ t ∧ insert a t = s ∧ t.card = n := +theorem card_eq_succ : #s = n + 1 ↔ ∃ a t, a ∉ t ∧ insert a t = s ∧ #t = n := ⟨fun h => - let ⟨a, has⟩ := card_pos.mp (h.symm ▸ Nat.zero_lt_succ _ : 0 < s.card) + let ⟨a, has⟩ := card_pos.mp (h.symm ▸ Nat.zero_lt_succ _ : 0 < #s) ⟨a, s.erase a, s.not_mem_erase a, insert_erase has, by simp only [h, card_erase_of_mem has, Nat.add_sub_cancel_right]⟩, fun ⟨_, _, hat, s_eq, n_eq⟩ => s_eq ▸ n_eq ▸ card_insert_of_not_mem hat⟩ -theorem card_eq_two : s.card = 2 ↔ ∃ x y, x ≠ y ∧ s = {x, y} := by +theorem card_eq_two : #s = 2 ↔ ∃ x y, x ≠ y ∧ s = {x, y} := by constructor · rw [card_eq_succ] simp_rw [card_eq_one] @@ -707,7 +713,7 @@ theorem card_eq_two : s.card = 2 ↔ ∃ x y, x ≠ y ∧ s = {x, y} := by · rintro ⟨x, y, h, rfl⟩ exact card_pair h -theorem card_eq_three : s.card = 3 ↔ ∃ x y z, x ≠ y ∧ x ≠ z ∧ y ≠ z ∧ s = {x, y, z} := by +theorem card_eq_three : #s = 3 ↔ ∃ x y z, x ≠ y ∧ x ≠ z ∧ y ≠ z ∧ s = {x, y, z} := by constructor · rw [card_eq_succ] simp_rw [card_eq_two] @@ -720,7 +726,7 @@ theorem card_eq_three : s.card = 3 ↔ ∃ x y z, x ≠ y ∧ x ≠ z ∧ y ≠ end DecidableEq -theorem two_lt_card_iff : 2 < s.card ↔ ∃ a b c, a ∈ s ∧ b ∈ s ∧ c ∈ s ∧ a ≠ b ∧ a ≠ c ∧ b ≠ c := by +theorem two_lt_card_iff : 2 < #s ↔ ∃ a b c, a ∈ s ∧ b ∈ s ∧ c ∈ s ∧ a ≠ b ∧ a ≠ c ∧ b ≠ c := by classical simp_rw [lt_iff_add_one_le, le_card_iff_exists_subset_card, reduceAdd, card_eq_three, ← exists_and_left, exists_comm (α := Finset α)] @@ -730,7 +736,7 @@ theorem two_lt_card_iff : 2 < s.card ↔ ∃ a b c, a ∈ s ∧ b ∈ s ∧ c · rintro ⟨a, b, c, ha, hb, hc, hab, hac, hbc⟩ exact ⟨a, b, c, {a, b, c}, by simp_all [insert_subset_iff]⟩ -theorem two_lt_card : 2 < s.card ↔ ∃ a ∈ s, ∃ b ∈ s, ∃ c ∈ s, a ≠ b ∧ a ≠ c ∧ b ≠ c := by +theorem two_lt_card : 2 < #s ↔ ∃ a ∈ s, ∃ b ∈ s, ∃ c ∈ s, a ≠ b ∧ a ≠ c ∧ b ≠ c := by simp_rw [two_lt_card_iff, exists_and_left] /-! ### Inductions -/ @@ -743,9 +749,9 @@ def strongInduction {p : Finset α → Sort*} (H : ∀ s, (∀ t ⊂ s, p t) → ∀ s : Finset α, p s | s => H s fun t h => - have : t.card < s.card := card_lt_card h + have : #t < #s := card_lt_card h strongInduction H t - termination_by s => Finset.card s + termination_by s => #s @[nolint unusedHavesSuffices] -- Porting note: false positive theorem strongInduction_eq {p : Finset α → Sort*} (H : ∀ s, (∀ t ⊂ s, p t) → p s) @@ -789,25 +795,25 @@ protected lemma Nonempty.strong_induction {p : ∀ s, s.Nonempty → Prop} · refine h₁ hs fun t ht hts ↦ ?_ have := card_lt_card hts exact ht.strong_induction h₀ h₁ -termination_by s => Finset.card s +termination_by s => #s /-- Suppose that, given that `p t` can be defined on all supersets of `s` of cardinality less than `n`, one knows how to define `p s`. Then one can inductively define `p s` for all finsets `s` of cardinality less than `n`, starting from finsets of card `n` and iterating. This can be used either to define data, or to prove properties. -/ def strongDownwardInduction {p : Finset α → Sort*} {n : ℕ} - (H : ∀ t₁, (∀ {t₂ : Finset α}, t₂.card ≤ n → t₁ ⊂ t₂ → p t₂) → t₁.card ≤ n → p t₁) : - ∀ s : Finset α, s.card ≤ n → p s + (H : ∀ t₁, (∀ {t₂ : Finset α}, #t₂ ≤ n → t₁ ⊂ t₂ → p t₂) → #t₁ ≤ n → p t₁) : + ∀ s : Finset α, #s ≤ n → p s | s => H s fun {t} ht h => have := Finset.card_lt_card h - have : n - t.card < n - s.card := by omega + have : n - #t < n - #s := by omega strongDownwardInduction H t ht - termination_by s => n - s.card + termination_by s => n - #s @[nolint unusedHavesSuffices] -- Porting note: false positive theorem strongDownwardInduction_eq {p : Finset α → Sort*} - (H : ∀ t₁, (∀ {t₂ : Finset α}, t₂.card ≤ n → t₁ ⊂ t₂ → p t₂) → t₁.card ≤ n → p t₁) + (H : ∀ t₁, (∀ {t₂ : Finset α}, #t₂ ≤ n → t₁ ⊂ t₂ → p t₂) → #t₁ ≤ n → p t₁) (s : Finset α) : strongDownwardInduction H s = H s fun {t} ht _ => strongDownwardInduction H t ht := by rw [strongDownwardInduction] @@ -815,13 +821,13 @@ theorem strongDownwardInduction_eq {p : Finset α → Sort*} /-- Analogue of `strongDownwardInduction` with order of arguments swapped. -/ @[elab_as_elim] def strongDownwardInductionOn {p : Finset α → Sort*} (s : Finset α) - (H : ∀ t₁, (∀ {t₂ : Finset α}, t₂.card ≤ n → t₁ ⊂ t₂ → p t₂) → t₁.card ≤ n → p t₁) : - s.card ≤ n → p s := + (H : ∀ t₁, (∀ {t₂ : Finset α}, #t₂ ≤ n → t₁ ⊂ t₂ → p t₂) → #t₁ ≤ n → p t₁) : + #s ≤ n → p s := strongDownwardInduction H s @[nolint unusedHavesSuffices] -- Porting note: false positive theorem strongDownwardInductionOn_eq {p : Finset α → Sort*} (s : Finset α) - (H : ∀ t₁, (∀ {t₂ : Finset α}, t₂.card ≤ n → t₁ ⊂ t₂ → p t₂) → t₁.card ≤ n → p t₁) : + (H : ∀ t₁, (∀ {t₂ : Finset α}, #t₂ ≤ n → t₁ ⊂ t₂ → p t₂) → #t₁ ≤ n → p t₁) : s.strongDownwardInductionOn H = H s fun {t} ht _ => t.strongDownwardInductionOn H ht := by dsimp only [strongDownwardInductionOn] rw [strongDownwardInduction] From e007f8f7404b132837d23260b6733539080a0511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Thu, 17 Oct 2024 15:41:53 +0000 Subject: [PATCH 332/425] =?UTF-8?q?feat(LinearAlgebra/Quotient):=20`(?= =?UTF-8?q?=E2=88=80=20a=20:=20=20M=20=E2=A7=B8=20p,=20P=20a)=20=E2=86=94?= =?UTF-8?q?=20=E2=88=80=20a=20:=20M,=20P=20=E2=9F=A6a=E2=9F=A7`=20(#17808)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From PFR --- Mathlib/LinearAlgebra/Quotient.lean | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mathlib/LinearAlgebra/Quotient.lean b/Mathlib/LinearAlgebra/Quotient.lean index 9f3e755dd20ebd..ca687f953d0240 100644 --- a/Mathlib/LinearAlgebra/Quotient.lean +++ b/Mathlib/LinearAlgebra/Quotient.lean @@ -104,6 +104,8 @@ theorem mk_neg : (mk (-x) : M ⧸ p) = -(mk x : M ⧸ p) := theorem mk_sub : (mk (x - y) : M ⧸ p) = (mk x : M ⧸ p) - (mk y : M ⧸ p) := rfl +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) From d2ce9970d101778fc9d13ea498ab229461ed3c07 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Thu, 17 Oct 2024 15:41:55 +0000 Subject: [PATCH 333/425] chore(Analysis): remove unused variables (#17874) These were already unused on the master branch but became exposed to the linter after #17870 changed some `CoeFun` instances. --- Mathlib/Analysis/Analytic/Basic.lean | 2 +- Mathlib/Analysis/Analytic/Inverse.lean | 6 +++--- Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean | 2 +- Mathlib/Analysis/Normed/Algebra/TrivSqZeroExt.lean | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Mathlib/Analysis/Analytic/Basic.lean b/Mathlib/Analysis/Analytic/Basic.lean index 04e001a4a25bcc..35af733c58d756 100644 --- a/Mathlib/Analysis/Analytic/Basic.lean +++ b/Mathlib/Analysis/Analytic/Basic.lean @@ -638,7 +638,7 @@ theorem HasFPowerSeriesWithinOnBall.coeff_zero (hf : HasFPowerSeriesWithinOnBall (v : Fin 0 → E) : pf 0 v = f x := by have v_eq : v = fun i => 0 := Subsingleton.elim _ _ have zero_mem : (0 : E) ∈ EMetric.ball (0 : E) r := by simp [hf.r_pos] - have : ∀ i, i ≠ 0 → (pf i fun j => 0) = 0 := by + have : ∀ i, i ≠ 0 → (pf i fun _ => 0) = 0 := by intro i hi have : 0 < i := pos_iff_ne_zero.2 hi exact ContinuousMultilinearMap.map_coord_zero _ (⟨0, this⟩ : Fin i) rfl diff --git a/Mathlib/Analysis/Analytic/Inverse.lean b/Mathlib/Analysis/Analytic/Inverse.lean index eadc577c91124c..34ad1130c225c6 100644 --- a/Mathlib/Analysis/Analytic/Inverse.lean +++ b/Mathlib/Analysis/Analytic/Inverse.lean @@ -272,7 +272,7 @@ theorem rightInv_coeff (p : FormalMultilinearSeries 𝕜 E F) (i : E ≃L[𝕜] congr (config := { closePost := false }) 1 ext v have N : 0 < n + 2 := by norm_num - have : ((p 1) fun i : Fin 1 => 0) = 0 := ContinuousMultilinearMap.map_zero _ + have : ((p 1) fun _ : Fin 1 => 0) = 0 := ContinuousMultilinearMap.map_zero _ simp [comp_rightInv_aux1 N, lt_irrefl n, this, comp_rightInv_aux2, -Set.toFinset_setOf] /-! ### Coincidence of the left and the right inverse -/ @@ -630,10 +630,10 @@ lemma HasFPowerSeriesAt.eventually_hasSum_of_comp {f : E → F} {g : F → G} simp only [id_eq, eventually_atTop, ge_iff_le] rcases mem_nhds_iff.1 hu with ⟨v, vu, v_open, hv⟩ obtain ⟨a₀, b₀, hab⟩ : ∃ a₀ b₀, ∀ (a b : ℕ), a₀ ≤ a → b₀ ≤ b → - q.partialSum a (p.partialSum b y - (p 0) fun x ↦ 0) ∈ v := by + q.partialSum a (p.partialSum b y - (p 0) fun _ ↦ 0) ∈ v := by simpa using hy (v_open.mem_nhds hv) refine ⟨a₀, fun a ha ↦ ?_⟩ - have : Tendsto (fun b ↦ q.partialSum a (p.partialSum b y - (p 0) fun x ↦ 0)) atTop + have : Tendsto (fun b ↦ q.partialSum a (p.partialSum b y - (p 0) fun _ ↦ 0)) atTop (𝓝 (q.partialSum a (f (x + y) - f x))) := by have : ContinuousAt (q.partialSum a) (f (x + y) - f x) := (partialSum_continuous q a).continuousAt diff --git a/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean b/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean index f5790c73a631f3..cf2ae12780d4c4 100644 --- a/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean +++ b/Mathlib/Analysis/Calculus/IteratedDeriv/Defs.lean @@ -166,7 +166,7 @@ theorem iteratedDerivWithin_succ {x : 𝕜} (hxs : UniqueDiffWithinAt 𝕜 s x) rw [iteratedDerivWithin_eq_iteratedFDerivWithin, iteratedFDerivWithin_succ_apply_left, iteratedFDerivWithin_eq_equiv_comp, LinearIsometryEquiv.comp_fderivWithin _ hxs, derivWithin] change ((ContinuousMultilinearMap.mkPiRing 𝕜 (Fin n) ((fderivWithin 𝕜 - (iteratedDerivWithin n f s) s x : 𝕜 → F) 1) : (Fin n → 𝕜) → F) fun i : Fin n => 1) = + (iteratedDerivWithin n f s) s x : 𝕜 → F) 1) : (Fin n → 𝕜) → F) fun _ : Fin n => 1) = (fderivWithin 𝕜 (iteratedDerivWithin n f s) s x : 𝕜 → F) 1 simp diff --git a/Mathlib/Analysis/Normed/Algebra/TrivSqZeroExt.lean b/Mathlib/Analysis/Normed/Algebra/TrivSqZeroExt.lean index 64ad667b3190a4..c3e4233f09ac94 100644 --- a/Mathlib/Analysis/Normed/Algebra/TrivSqZeroExt.lean +++ b/Mathlib/Analysis/Normed/Algebra/TrivSqZeroExt.lean @@ -115,7 +115,7 @@ variable [T2Space R] [T2Space M] theorem exp_def_of_smul_comm (x : tsze R M) (hx : MulOpposite.op x.fst • x.snd = x.fst • x.snd) : exp 𝕜 x = inl (exp 𝕜 x.fst) + inr (exp 𝕜 x.fst • x.snd) := by simp_rw [exp, FormalMultilinearSeries.sum] - by_cases h : Summable (fun (n : ℕ) => (expSeries 𝕜 R n) fun x_1 ↦ fst x) + by_cases h : Summable (fun (n : ℕ) => (expSeries 𝕜 R n) fun _ ↦ fst x) · refine (hasSum_expSeries_of_smul_comm 𝕜 x hx ?_).tsum_eq exact h.hasSum · rw [tsum_eq_zero_of_not_summable h, zero_smul, inr_zero, inl_zero, zero_add, From d3038070bcab78ca09317951523576e264e9cf84 Mon Sep 17 00:00:00 2001 From: damiano Date: Thu, 17 Oct 2024 16:19:08 +0000 Subject: [PATCH 334/425] chore: another removal of unused variables (#17790) --- Mathlib/Algebra/Field/ULift.lean | 4 +-- Mathlib/Algebra/Group/Action/Basic.lean | 2 +- Mathlib/Algebra/Group/Indicator.lean | 6 ++-- Mathlib/Algebra/Group/Pi/Lemmas.lean | 3 +- Mathlib/Algebra/Group/Submonoid/Defs.lean | 4 --- Mathlib/Algebra/Group/Subsemigroup/Defs.lean | 4 +-- .../Algebra/GroupWithZero/Action/Basic.lean | 2 +- Mathlib/Algebra/GroupWithZero/Action/Pi.lean | 5 +--- Mathlib/Algebra/Module/Defs.lean | 10 +++---- Mathlib/Algebra/Module/Equiv/Defs.lean | 12 +++----- Mathlib/Algebra/Module/LinearMap/Defs.lean | 28 ++++++++----------- Mathlib/Algebra/Module/Pi.lean | 3 -- Mathlib/Algebra/Module/Submodule/Range.lean | 19 ++++++------- Mathlib/Algebra/Order/Interval/Set/Group.lean | 2 +- Mathlib/Algebra/Order/Ring/Abs.lean | 8 +++--- Mathlib/Algebra/Regular/SMul.lean | 3 +- Mathlib/Algebra/Ring/Pi.lean | 3 +- Mathlib/Algebra/Ring/Prod.lean | 2 +- .../Analysis/InnerProductSpace/Symmetric.lean | 10 ++----- .../OperatorNorm/Completeness.lean | 11 ++++---- Mathlib/Data/Fin/VecNotation.lean | 2 +- Mathlib/Data/Int/Cast/Lemmas.lean | 6 ++-- Mathlib/Data/Int/Lemmas.lean | 2 -- Mathlib/Data/Int/Order/Lemmas.lean | 3 -- Mathlib/Data/List/Perm.lean | 2 +- Mathlib/Data/List/Sort.lean | 2 +- Mathlib/Data/Nat/Cast/Order/Ring.lean | 2 +- Mathlib/Dynamics/FixedPoints/Basic.lean | 2 +- .../Geometry/Manifold/Algebra/LieGroup.lean | 7 ++--- .../Manifold/VectorBundle/SmoothSection.lean | 10 ++----- Mathlib/GroupTheory/Congruence/Defs.lean | 4 +-- Mathlib/GroupTheory/CosetCover.lean | 2 +- Mathlib/GroupTheory/DoubleCoset.lean | 2 +- Mathlib/GroupTheory/GroupAction/Hom.lean | 5 +--- Mathlib/GroupTheory/NoncommPiCoprod.lean | 9 ------ Mathlib/GroupTheory/Sylow.lean | 4 +-- Mathlib/LinearAlgebra/Basis/Basic.lean | 15 ++++------ .../LinearAlgebra/FiniteDimensional/Defs.lean | 9 ++---- Mathlib/MeasureTheory/Integral/Bochner.lean | 21 ++++++-------- Mathlib/Order/Bounds/Basic.lean | 2 +- Mathlib/Order/CompleteLattice.lean | 2 +- Mathlib/Order/GaloisConnection.lean | 6 ++-- Mathlib/Order/PiLex.lean | 2 +- .../RingTheory/Localization/Submodule.lean | 9 ++---- Mathlib/Topology/Algebra/Module/Basic.lean | 14 ++++------ 45 files changed, 106 insertions(+), 179 deletions(-) diff --git a/Mathlib/Algebra/Field/ULift.lean b/Mathlib/Algebra/Field/ULift.lean index ccb6baccbc575e..215b218b67831e 100644 --- a/Mathlib/Algebra/Field/ULift.lean +++ b/Mathlib/Algebra/Field/ULift.lean @@ -15,8 +15,8 @@ This file defines instances for field, semifield and related structures on `ULif (Recall `ULift α` is just a "copy" of a type `α` in a higher universe.) -/ -universe u v -variable {α : Type u} {x y : ULift.{v} α} +universe u +variable {α : Type u} namespace ULift diff --git a/Mathlib/Algebra/Group/Action/Basic.lean b/Mathlib/Algebra/Group/Action/Basic.lean index 8515f84bac94f4..0077326ec936b0 100644 --- a/Mathlib/Algebra/Group/Action/Basic.lean +++ b/Mathlib/Algebra/Group/Action/Basic.lean @@ -16,7 +16,7 @@ This file contains lemmas about group actions that require more imports than assert_not_exists MonoidWithZero -variable {α β γ : Type*} +variable {α β : Type*} section MulAction diff --git a/Mathlib/Algebra/Group/Indicator.lean b/Mathlib/Algebra/Group/Indicator.lean index fc2d14cdfb1400..38b9e8ce300213 100644 --- a/Mathlib/Algebra/Group/Indicator.lean +++ b/Mathlib/Algebra/Group/Indicator.lean @@ -33,7 +33,7 @@ assert_not_exists MonoidWithZero open Function -variable {α β ι M N : Type*} +variable {α β M N : Type*} namespace Set @@ -262,7 +262,7 @@ end One section Monoid -variable [MulOneClass M] {s t : Set α} {f g : α → M} {a : α} +variable [MulOneClass M] {s t : Set α} {a : α} @[to_additive] theorem mulIndicator_union_mul_inter_apply (f : α → M) (s t : Set α) (a : α) : @@ -360,7 +360,7 @@ end Monoid section Group -variable {G : Type*} [Group G] {s t : Set α} {f g : α → G} {a : α} +variable {G : Type*} [Group G] {s t : Set α} @[to_additive] theorem mulIndicator_inv' (s : Set α) (f : α → G) : mulIndicator s f⁻¹ = (mulIndicator s f)⁻¹ := diff --git a/Mathlib/Algebra/Group/Pi/Lemmas.lean b/Mathlib/Algebra/Group/Pi/Lemmas.lean index 1dee66ec01d1b6..0f412767df4f91 100644 --- a/Mathlib/Algebra/Group/Pi/Lemmas.lean +++ b/Mathlib/Algebra/Group/Pi/Lemmas.lean @@ -26,8 +26,7 @@ variable {I : Type u} -- The indexing type variable {f : I → Type v} --- The family of types already equipped with instances -variable (x y : ∀ i, f i) (i j : I) +variable (i : I) @[to_additive (attr := simp)] theorem Set.range_one {α β : Type*} [One β] [Nonempty α] : Set.range (1 : α → β) = {1} := diff --git a/Mathlib/Algebra/Group/Submonoid/Defs.lean b/Mathlib/Algebra/Group/Submonoid/Defs.lean index 4f005ea6406956..d1a62b639d86a2 100644 --- a/Mathlib/Algebra/Group/Submonoid/Defs.lean +++ b/Mathlib/Algebra/Group/Submonoid/Defs.lean @@ -47,15 +47,11 @@ submonoid, submonoids assert_not_exists CompleteLattice assert_not_exists MonoidWithZero --- Only needed for notation --- Only needed for notation variable {M : Type*} {N : Type*} -variable {A : Type*} section NonAssoc variable [MulOneClass M] {s : Set M} -variable [AddZeroClass A] {t : Set A} /-- `OneMemClass S M` says `S` is a type of subsets `s ≤ M`, such that `1 ∈ s` for all `s`. -/ class OneMemClass (S : Type*) (M : outParam Type*) [One M] [SetLike S M] : Prop where diff --git a/Mathlib/Algebra/Group/Subsemigroup/Defs.lean b/Mathlib/Algebra/Group/Subsemigroup/Defs.lean index 946d325924172b..aa0008eee16ba4 100644 --- a/Mathlib/Algebra/Group/Subsemigroup/Defs.lean +++ b/Mathlib/Algebra/Group/Subsemigroup/Defs.lean @@ -47,13 +47,11 @@ subsemigroup, subsemigroups assert_not_exists CompleteLattice assert_not_exists MonoidWithZero --- Only needed for notation -variable {M : Type*} {N : Type*} {A : Type*} +variable {M : Type*} {N : Type*} section NonAssoc variable [Mul M] {s : Set M} -variable [Add A] {t : Set A} /-- `MulMemClass S M` says `S` is a type of sets `s : Set M` that are closed under `(*)` -/ class MulMemClass (S : Type*) (M : outParam Type*) [Mul M] [SetLike S M] : Prop where diff --git a/Mathlib/Algebra/GroupWithZero/Action/Basic.lean b/Mathlib/Algebra/GroupWithZero/Action/Basic.lean index f61edb220be6bc..39b682e9f1e618 100644 --- a/Mathlib/Algebra/GroupWithZero/Action/Basic.lean +++ b/Mathlib/Algebra/GroupWithZero/Action/Basic.lean @@ -68,7 +68,7 @@ protected lemma MulAction.surjective₀ (ha : a ≠ 0) : Surjective (a • · : end GroupWithZero section DistribMulAction -variable [Group G] [Monoid M] [AddMonoid A] [DistribMulAction M A] +variable [Group G] [Monoid M] [AddMonoid A] variable (A) /-- Each element of the group defines an additive monoid isomorphism. diff --git a/Mathlib/Algebra/GroupWithZero/Action/Pi.lean b/Mathlib/Algebra/GroupWithZero/Action/Pi.lean index a68e1a97b1d8af..f465f4b4caa562 100644 --- a/Mathlib/Algebra/GroupWithZero/Action/Pi.lean +++ b/Mathlib/Algebra/GroupWithZero/Action/Pi.lean @@ -21,16 +21,13 @@ This file defines instances for `MulActionWithZero` and related structures on `P -/ -universe u v w +universe u v variable {I : Type u} -- The indexing type variable {f : I → Type v} --- The family of types already equipped with instances -variable (x y : ∀ i, f i) (i : I) - namespace Pi instance smulZeroClass (α) {n : ∀ i, Zero <| f i} [∀ i, SMulZeroClass α <| f i] : diff --git a/Mathlib/Algebra/Module/Defs.lean b/Mathlib/Algebra/Module/Defs.lean index f810b34644f19d..a024554de986a6 100644 --- a/Mathlib/Algebra/Module/Defs.lean +++ b/Mathlib/Algebra/Module/Defs.lean @@ -46,7 +46,7 @@ open Function Set universe u v -variable {α R k S M M₂ M₃ ι : Type*} +variable {R S M M₂ : Type*} /-- A module is a generalization of vector spaces to a scalar semiring. It consists of a scalar semiring `R` and an additive monoid of "vectors" `M`, @@ -63,7 +63,7 @@ class Module (R : Type u) (M : Type v) [Semiring R] [AddCommMonoid M] extends section AddCommMonoid -variable [Semiring R] [AddCommMonoid M] [Module R M] (r s : R) (x y : M) +variable [Semiring R] [AddCommMonoid M] [Module R M] (r s : R) (x : M) -- see Note [lower instance priority] /-- A module over a semiring automatically inherits a `MulActionWithZero` structure. -/ @@ -218,7 +218,7 @@ theorem Module.ext' {R : Type*} [Semiring R] {M : Type*} [AddCommMonoid M] (P Q section Module -variable [Ring R] [AddCommGroup M] [Module R M] (r s : R) (x y : M) +variable [Ring R] [AddCommGroup M] [Module R M] (r : R) (x : M) @[simp] theorem neg_smul : -r • x = -(r • x) := @@ -360,7 +360,7 @@ end AddCommMonoid section AddCommGroup -variable [Semiring S] [Ring R] [AddCommGroup M] [Module S M] [Module R M] +variable [Ring R] [AddCommGroup M] [Module R M] section @@ -483,7 +483,7 @@ theorem two_nsmul_eq_zero end Nat -variable [Semiring R] [AddCommMonoid M] [Module R M] +variable [Semiring R] variable (R M) /-- If `M` is an `R`-module with one and `M` has characteristic zero, then `R` has characteristic diff --git a/Mathlib/Algebra/Module/Equiv/Defs.lean b/Mathlib/Algebra/Module/Equiv/Defs.lean index 9a5d7dcbdfd0d0..7d08836e2d79fd 100644 --- a/Mathlib/Algebra/Module/Equiv/Defs.lean +++ b/Mathlib/Algebra/Module/Equiv/Defs.lean @@ -38,11 +38,9 @@ assert_not_exists Pi.module open Function -universe u u' v w x y z - variable {R : Type*} {R₁ : Type*} {R₂ : Type*} {R₃ : Type*} -variable {k : Type*} {K : Type*} {S : Type*} {M : Type*} {M₁ : Type*} {M₂ : Type*} {M₃ : Type*} -variable {N₁ : Type*} {N₂ : Type*} {N₃ : Type*} {N₄ : Type*} {ι : Type*} +variable {S : Type*} {M : Type*} {M₁ : Type*} {M₂ : Type*} {M₃ : Type*} +variable {N₁ : Type*} {N₂ : Type*} section @@ -133,7 +131,6 @@ namespace LinearEquiv section AddCommMonoid -variable {M₄ : Type*} variable [Semiring R] [Semiring S] section @@ -198,7 +195,7 @@ section variable [Semiring R₁] [Semiring R₂] [Semiring R₃] variable [AddCommMonoid M] [AddCommMonoid M₁] [AddCommMonoid M₂] -variable [AddCommMonoid M₃] [AddCommMonoid M₄] +variable [AddCommMonoid M₃] variable [AddCommMonoid N₁] [AddCommMonoid N₂] variable {module_M : Module R M} {module_S_M₂ : Module S M₂} {σ : R →+* S} {σ' : S →+* R} variable {re₁ : RingHomInvPair σ σ'} {re₂ : RingHomInvPair σ' σ} @@ -506,8 +503,7 @@ def _root_.RingEquiv.toSemilinearEquiv (f : R ≃+* S) : toFun := f map_smul' := f.map_mul } -variable [Semiring R₁] [Semiring R₂] [Semiring R₃] -variable [AddCommMonoid M] [AddCommMonoid M₁] [AddCommMonoid M₂] +variable [AddCommMonoid M] /-- An involutive linear map is a linear equivalence. -/ def ofInvolutive {σ σ' : R →+* R} [RingHomInvPair σ σ'] [RingHomInvPair σ' σ] diff --git a/Mathlib/Algebra/Module/LinearMap/Defs.lean b/Mathlib/Algebra/Module/LinearMap/Defs.lean index 0a75f33f5bf9c6..21a6e98c5445a5 100644 --- a/Mathlib/Algebra/Module/LinearMap/Defs.lean +++ b/Mathlib/Algebra/Module/LinearMap/Defs.lean @@ -57,9 +57,9 @@ assert_not_exists Field open Function -universe u u' v w x y z +universe u u' v w -variable {R R₁ R₂ R₃ k S S₃ T M M₁ M₂ M₃ N₁ N₂ N₃ ι : Type*} +variable {R R₁ R₂ R₃ S S₃ T M M₁ M₂ M₃ N₂ N₃ : Type*} /-- A map `f` between modules over a semiring is linear if it satisfies the two properties `f (x + y) = f x + f y` and `f (c • x) = c • f x`. The predicate `IsLinearMap R f` asserts this @@ -194,7 +194,6 @@ variable [Semiring R] [Semiring S] section variable [AddCommMonoid M] [AddCommMonoid M₁] [AddCommMonoid M₂] [AddCommMonoid M₃] -variable [AddCommMonoid N₁] [AddCommMonoid N₂] [AddCommMonoid N₃] variable [Module R M] [Module R M₂] [Module S M₃] variable {σ : R →+* S} @@ -299,15 +298,14 @@ end section variable [AddCommMonoid M] [AddCommMonoid M₁] [AddCommMonoid M₂] [AddCommMonoid M₃] -variable [AddCommMonoid N₁] [AddCommMonoid N₂] [AddCommMonoid N₃] variable [Module R M] [Module R M₂] [Module S M₃] variable (σ : R →+* S) -variable (fₗ gₗ : M →ₗ[R] M₂) (f g : M →ₛₗ[σ] M₃) +variable (fₗ : M →ₗ[R] M₂) (f g : M →ₛₗ[σ] M₃) theorem isLinear : IsLinearMap R fₗ := ⟨fₗ.map_add', fₗ.map_smul'⟩ -variable {fₗ gₗ f g σ} +variable {fₗ f g σ} theorem coe_injective : Injective (DFunLike.coe : (M →ₛₗ[σ] M₃) → _) := DFunLike.coe_injective @@ -323,7 +321,7 @@ protected theorem congr_fun (h : f = g) (x : M) : f x = g x := theorem mk_coe (f : M →ₛₗ[σ] M₃) (h) : (LinearMap.mk f h : M →ₛₗ[σ] M₃) = f := rfl -variable (fₗ gₗ f g) +variable (fₗ f g) protected theorem map_add (x y : M) : f (x + y) = f x + f y := map_add f x y @@ -537,7 +535,7 @@ theorem cancel_left (hf : Injective f) : f.comp g = f.comp g' ↔ g = g' := end -variable [AddCommMonoid M] [AddCommMonoid M₁] [AddCommMonoid M₂] [AddCommMonoid M₃] +variable [AddCommMonoid M] [AddCommMonoid M₂] [AddCommMonoid M₃] /-- If a function `g` is a left and right inverse of a linear map `f`, then `g` is linear itself. -/ def inverse [Module R M] [Module S M₂] {σ : R →+* S} {σ' : S →+* R} [RingHomInvPair σ σ'] @@ -721,12 +719,11 @@ namespace LinearMap section SMul -variable [Semiring R] [Semiring R₂] [Semiring R₃] -variable [AddCommMonoid M] [AddCommMonoid M₂] [AddCommMonoid M₃] -variable [Module R M] [Module R₂ M₂] [Module R₃ M₃] -variable {σ₁₂ : R →+* R₂} {σ₂₃ : R₂ →+* R₃} {σ₁₃ : R →+* R₃} [RingHomCompTriple σ₁₂ σ₂₃ σ₁₃] +variable [Semiring R] [Semiring R₂] +variable [AddCommMonoid M] [AddCommMonoid M₂] +variable [Module R M] [Module R₂ M₂] +variable {σ₁₂ : R →+* R₂} variable [Monoid S] [DistribMulAction S M₂] [SMulCommClass R₂ S M₂] -variable [Monoid S₃] [DistribMulAction S₃ M₃] [SMulCommClass R₃ S₃ M₃] variable [Monoid T] [DistribMulAction T M₂] [SMulCommClass R₂ T M₂] instance : SMul S (M →ₛₗ[σ₁₂] M₂) := @@ -762,9 +759,9 @@ section Arithmetic variable [Semiring R₁] [Semiring R₂] [Semiring R₃] variable [AddCommMonoid M] [AddCommMonoid M₂] [AddCommMonoid M₃] -variable [AddCommGroup N₁] [AddCommGroup N₂] [AddCommGroup N₃] +variable [AddCommGroup N₂] [AddCommGroup N₃] variable [Module R₁ M] [Module R₂ M₂] [Module R₃ M₃] -variable [Module R₁ N₁] [Module R₂ N₂] [Module R₃ N₃] +variable [Module R₂ N₂] [Module R₃ N₃] variable {σ₁₂ : R₁ →+* R₂} {σ₂₃ : R₂ →+* R₃} {σ₁₃ : R₁ →+* R₃} [RingHomCompTriple σ₁₂ σ₂₃ σ₁₃] /-- The constant 0 map is linear. -/ @@ -897,7 +894,6 @@ section SMul variable [Monoid S] [DistribMulAction S M₂] [SMulCommClass R₂ S M₂] variable [Monoid S₃] [DistribMulAction S₃ M₃] [SMulCommClass R₃ S₃ M₃] -variable [Monoid T] [DistribMulAction T M₂] [SMulCommClass R₂ T M₂] instance : DistribMulAction S (M →ₛₗ[σ₁₂] M₂) where one_smul _ := ext fun _ ↦ one_smul _ _ diff --git a/Mathlib/Algebra/Module/Pi.lean b/Mathlib/Algebra/Module/Pi.lean index 002ec529cf8520..1d6a967b8db91a 100644 --- a/Mathlib/Algebra/Module/Pi.lean +++ b/Mathlib/Algebra/Module/Pi.lean @@ -22,9 +22,6 @@ variable {I : Type u} -- The indexing type variable {f : I → Type v} --- The family of types already equipped with instances -variable (x y : ∀ i, f i) (i : I) - namespace Pi theorem _root_.IsSMulRegular.pi {α : Type*} [∀ i, SMul α <| f i] {k : α} diff --git a/Mathlib/Algebra/Module/Submodule/Range.lean b/Mathlib/Algebra/Module/Submodule/Range.lean index 40e7e2b4527896..933cc427c94e9f 100644 --- a/Mathlib/Algebra/Module/Submodule/Range.lean +++ b/Mathlib/Algebra/Module/Submodule/Range.lean @@ -28,7 +28,7 @@ linear algebra, vector space, module, range open Function variable {R : Type*} {R₂ : Type*} {R₃ : Type*} -variable {K : Type*} {K₂ : Type*} +variable {K : Type*} variable {M : Type*} {M₂ : Type*} {M₃ : Type*} variable {V : Type*} {V₂ : Type*} @@ -38,13 +38,11 @@ section AddCommMonoid variable [Semiring R] [Semiring R₂] [Semiring R₃] variable [AddCommMonoid M] [AddCommMonoid M₂] [AddCommMonoid M₃] -variable {σ₁₂ : R →+* R₂} {σ₂₃ : R₂ →+* R₃} {σ₁₃ : R →+* R₃} -variable [RingHomCompTriple σ₁₂ σ₂₃ σ₁₃] variable [Module R M] [Module R₂ M₂] [Module R₃ M₃] open Submodule -variable {σ₂₁ : R₂ →+* R} {τ₁₂ : R →+* R₂} {τ₂₃ : R₂ →+* R₃} {τ₁₃ : R →+* R₃} +variable {τ₁₂ : R →+* R₂} {τ₂₃ : R₂ →+* R₃} {τ₁₃ : R →+* R₃} variable [RingHomCompTriple τ₁₂ τ₂₃ τ₁₃] section @@ -190,11 +188,10 @@ end AddCommMonoid section Ring -variable [Ring R] [Ring R₂] [Ring R₃] -variable [AddCommGroup M] [AddCommGroup M₂] [AddCommGroup M₃] -variable [Module R M] [Module R₂ M₂] [Module R₃ M₃] -variable {τ₁₂ : R →+* R₂} {τ₂₃ : R₂ →+* R₃} {τ₁₃ : R →+* R₃} -variable [RingHomCompTriple τ₁₂ τ₂₃ τ₁₃] +variable [Ring R] [Ring R₂] +variable [AddCommGroup M] [AddCommGroup M₂] +variable [Module R M] [Module R₂ M₂] +variable {τ₁₂ : R →+* R₂} variable {F : Type*} [FunLike F M M₂] [SemilinearMapClass F τ₁₂ M M₂] variable {f : F} @@ -228,7 +225,7 @@ end Ring section Semifield -variable [Semifield K] [Semifield K₂] +variable [Semifield K] variable [AddCommMonoid V] [Module K V] variable [AddCommMonoid V₂] [Module K V₂] @@ -249,7 +246,7 @@ section AddCommMonoid variable [Semiring R] [Semiring R₂] [AddCommMonoid M] [AddCommMonoid M₂] variable [Module R M] [Module R₂ M₂] -variable (p p' : Submodule R M) (q : Submodule R₂ M₂) +variable (p : Submodule R M) variable {τ₁₂ : R →+* R₂} variable {F : Type*} [FunLike F M M₂] [SemilinearMapClass F τ₁₂ M M₂] diff --git a/Mathlib/Algebra/Order/Interval/Set/Group.lean b/Mathlib/Algebra/Order/Interval/Set/Group.lean index a95c3a44af7a11..d9684e57e4eb92 100644 --- a/Mathlib/Algebra/Order/Interval/Set/Group.lean +++ b/Mathlib/Algebra/Order/Interval/Set/Group.lean @@ -19,7 +19,7 @@ namespace Set section OrderedCommGroup -variable [OrderedCommGroup α] {a b c d : α} +variable [OrderedCommGroup α] {a c d : α} /-! `inv_mem_Ixx_iff`, `sub_mem_Ixx_iff` -/ diff --git a/Mathlib/Algebra/Order/Ring/Abs.lean b/Mathlib/Algebra/Order/Ring/Abs.lean index e61b8d4297a316..25cd393bf7434c 100644 --- a/Mathlib/Algebra/Order/Ring/Abs.lean +++ b/Mathlib/Algebra/Order/Ring/Abs.lean @@ -17,7 +17,7 @@ import Mathlib.Data.Nat.Cast.Order.Ring variable {α : Type*} section LinearOrderedAddCommGroup -variable [LinearOrderedCommGroup α] {a b : α} +variable [LinearOrderedCommGroup α] @[to_additive] lemma mabs_zpow (n : ℤ) (a : α) : |a ^ n|ₘ = |a|ₘ ^ |n| := by obtain n0 | n0 := le_total 0 n @@ -34,7 +34,7 @@ lemma odd_abs [LinearOrder α] [Ring α] {a : α} : Odd (abs a) ↔ Odd a := by section LinearOrderedRing -variable [LinearOrderedRing α] {n : ℕ} {a b c : α} +variable [LinearOrderedRing α] {n : ℕ} {a b : α} @[simp] lemma abs_one : |(1 : α)| = 1 := abs_of_pos zero_lt_one @@ -141,7 +141,7 @@ end LinearOrderedRing section LinearOrderedCommRing -variable [LinearOrderedCommRing α] {a b c d : α} +variable [LinearOrderedCommRing α] theorem abs_sub_sq (a b : α) : |a - b| * |a - b| = a * a + b * b - (1 + 1) * a * b := by rw [abs_mul_abs_self] @@ -152,7 +152,7 @@ end LinearOrderedCommRing section -variable [Ring α] [LinearOrder α] {a b : α} +variable [Ring α] [LinearOrder α] @[simp] theorem abs_dvd (a b : α) : |a| ∣ b ↔ a ∣ b := by diff --git a/Mathlib/Algebra/Regular/SMul.lean b/Mathlib/Algebra/Regular/SMul.lean index 5895185e0774c8..3dfb2cff80cf08 100644 --- a/Mathlib/Algebra/Regular/SMul.lean +++ b/Mathlib/Algebra/Regular/SMul.lean @@ -162,8 +162,7 @@ end MonoidSMul section MonoidWithZero -variable [MonoidWithZero R] [MonoidWithZero S] [Zero M] [MulActionWithZero R M] - [MulActionWithZero R S] [MulActionWithZero S M] [IsScalarTower R S M] +variable [MonoidWithZero R] [Zero M] [MulActionWithZero R M] /-- The element `0` is `M`-regular if and only if `M` is trivial. -/ protected theorem subsingleton (h : IsSMulRegular M (0 : R)) : Subsingleton M := diff --git a/Mathlib/Algebra/Ring/Pi.lean b/Mathlib/Algebra/Ring/Pi.lean index 394051c18c7d9b..4c20d456a41b70 100644 --- a/Mathlib/Algebra/Ring/Pi.lean +++ b/Mathlib/Algebra/Ring/Pi.lean @@ -25,8 +25,7 @@ variable {I : Type u} -- The indexing type variable {f : I → Type v} --- The family of types already equipped with instances -variable (x y : ∀ i, f i) (i : I) +variable (i : I) instance distrib [∀ i, Distrib <| f i] : Distrib (∀ i : I, f i) := { add := (· + ·) diff --git a/Mathlib/Algebra/Ring/Prod.lean b/Mathlib/Algebra/Ring/Prod.lean index 2883cf4e33ea0f..67ee0ebf5b1255 100644 --- a/Mathlib/Algebra/Ring/Prod.lean +++ b/Mathlib/Algebra/Ring/Prod.lean @@ -23,7 +23,7 @@ trivial `simp` lemmas, and define the following operations on `RingHom`s and sim -/ -variable {α β R R' S S' T T' : Type*} +variable {R R' S S' T : Type*} namespace Prod diff --git a/Mathlib/Analysis/InnerProductSpace/Symmetric.lean b/Mathlib/Analysis/InnerProductSpace/Symmetric.lean index 9acf7b33a06351..2fcd08ccaa66d9 100644 --- a/Mathlib/Analysis/InnerProductSpace/Symmetric.lean +++ b/Mathlib/Analysis/InnerProductSpace/Symmetric.lean @@ -38,11 +38,8 @@ open ComplexConjugate section Seminormed -variable {𝕜 E E' F G : Type*} [RCLike 𝕜] +variable {𝕜 E : Type*} [RCLike 𝕜] variable [SeminormedAddCommGroup E] [InnerProductSpace 𝕜 E] -variable [SeminormedAddCommGroup F] [InnerProductSpace 𝕜 F] -variable [SeminormedAddCommGroup G] [InnerProductSpace 𝕜 G] -variable [SeminormedAddCommGroup E'] [InnerProductSpace ℝ E'] local notation "⟪" x ", " y "⟫" => @inner 𝕜 _ _ x y @@ -189,11 +186,8 @@ end Seminormed section Normed -variable {𝕜 E E' F G : Type*} [RCLike 𝕜] +variable {𝕜 E : Type*} [RCLike 𝕜] variable [NormedAddCommGroup E] [InnerProductSpace 𝕜 E] -variable [NormedAddCommGroup F] [InnerProductSpace 𝕜 F] -variable [NormedAddCommGroup G] [InnerProductSpace 𝕜 G] -variable [NormedAddCommGroup E'] [InnerProductSpace ℝ E'] local notation "⟪" x ", " y "⟫" => @inner 𝕜 _ _ x y diff --git a/Mathlib/Analysis/NormedSpace/OperatorNorm/Completeness.lean b/Mathlib/Analysis/NormedSpace/OperatorNorm/Completeness.lean index 783b55750d8fb1..4043b6833c43d1 100644 --- a/Mathlib/Analysis/NormedSpace/OperatorNorm/Completeness.lean +++ b/Mathlib/Analysis/NormedSpace/OperatorNorm/Completeness.lean @@ -20,13 +20,12 @@ open Filter hiding map_smul open scoped NNReal Topology Uniformity -- the `ₗ` subscript variables are for special cases about linear (as opposed to semilinear) maps -variable {𝕜 𝕜₂ 𝕜₃ E Eₗ F Fₗ G Gₗ 𝓕 : Type*} -variable [NormedAddCommGroup E] [NormedAddCommGroup F] [NormedAddCommGroup G] - [NormedAddCommGroup Fₗ] +variable {𝕜 𝕜₂ E F Fₗ : Type*} +variable [NormedAddCommGroup E] [NormedAddCommGroup F] [NormedAddCommGroup Fₗ] -variable [NontriviallyNormedField 𝕜] [NontriviallyNormedField 𝕜₂] [NontriviallyNormedField 𝕜₃] - [NormedSpace 𝕜 E] [NormedSpace 𝕜₂ F] [NormedSpace 𝕜₃ G] [NormedSpace 𝕜 Fₗ] (c : 𝕜) - {σ₁₂ : 𝕜 →+* 𝕜₂} {σ₂₃ : 𝕜₂ →+* 𝕜₃} (f g : E →SL[σ₁₂] F) (x y z : E) +variable [NontriviallyNormedField 𝕜] [NontriviallyNormedField 𝕜₂] + [NormedSpace 𝕜 E] [NormedSpace 𝕜₂ F] [NormedSpace 𝕜 Fₗ] + {σ₁₂ : 𝕜 →+* 𝕜₂} (f g : E →SL[σ₁₂] F) namespace ContinuousLinearMap diff --git a/Mathlib/Data/Fin/VecNotation.lean b/Mathlib/Data/Fin/VecNotation.lean index d3b561640f0ae7..c931078da5ce1e 100644 --- a/Mathlib/Data/Fin/VecNotation.lean +++ b/Mathlib/Data/Fin/VecNotation.lean @@ -108,7 +108,7 @@ instance _root_.PiFin.hasRepr [Repr α] : Repr (Fin n → α) where end MatrixNotation -variable {m n o : ℕ} {m' n' o' : Type*} +variable {m n o : ℕ} theorem empty_eq (v : Fin 0 → α) : v = ![] := Subsingleton.elim _ _ diff --git a/Mathlib/Data/Int/Cast/Lemmas.lean b/Mathlib/Data/Int/Cast/Lemmas.lean index da5f6ffae2ed7b..822449e1e3d3b9 100644 --- a/Mathlib/Data/Int/Cast/Lemmas.lean +++ b/Mathlib/Data/Int/Cast/Lemmas.lean @@ -77,7 +77,7 @@ lemma cast_ne_one : (n : α) ≠ 1 ↔ n ≠ 1 := cast_eq_one.not end AddGroupWithOne section NonAssocRing -variable [NonAssocRing α] {a b : α} {n : ℤ} +variable [NonAssocRing α] variable (α) in /-- `coe : ℤ → α` as a `RingHom`. -/ @@ -147,7 +147,7 @@ end SemiconjBy namespace Commute section NonAssocRing -variable [NonAssocRing α] {a b : α} {n : ℤ} +variable [NonAssocRing α] {a : α} {n : ℤ} @[simp] lemma intCast_left : Commute (n : α) a := Int.cast_commute _ _ @@ -159,7 +159,7 @@ variable [NonAssocRing α] {a b : α} {n : ℤ} end NonAssocRing section Ring -variable [Ring α] {a b : α} {n : ℤ} +variable [Ring α] {a b : α} @[simp] lemma intCast_mul_right (h : Commute a b) (m : ℤ) : Commute a (m * b) := SemiconjBy.intCast_mul_right h m diff --git a/Mathlib/Data/Int/Lemmas.lean b/Mathlib/Data/Int/Lemmas.lean index e989bd71419b0e..3842fbb1c3222a 100644 --- a/Mathlib/Data/Int/Lemmas.lean +++ b/Mathlib/Data/Int/Lemmas.lean @@ -37,8 +37,6 @@ theorem succ_natCast_pos (n : ℕ) : 0 < (n : ℤ) + 1 := /-! ### `natAbs` -/ -variable {a b : ℤ} {n : ℕ} - theorem natAbs_eq_iff_sq_eq {a b : ℤ} : a.natAbs = b.natAbs ↔ a ^ 2 = b ^ 2 := by rw [sq, sq] exact natAbs_eq_iff_mul_self_eq diff --git a/Mathlib/Data/Int/Order/Lemmas.lean b/Mathlib/Data/Int/Order/Lemmas.lean index d664a5b284acab..3e9566c7910ff3 100644 --- a/Mathlib/Data/Int/Order/Lemmas.lean +++ b/Mathlib/Data/Int/Order/Lemmas.lean @@ -19,9 +19,6 @@ namespace Int /-! ### nat abs -/ - -variable {a b : ℤ} {n : ℕ} - theorem natAbs_eq_iff_mul_self_eq {a b : ℤ} : a.natAbs = b.natAbs ↔ a * a = b * b := by rw [← abs_eq_iff_mul_self_eq, abs_eq_natAbs, abs_eq_natAbs] exact Int.natCast_inj.symm diff --git a/Mathlib/Data/List/Perm.lean b/Mathlib/Data/List/Perm.lean index 8f5cb1997dd64e..efeb8dd594a060 100644 --- a/Mathlib/Data/List/Perm.lean +++ b/Mathlib/Data/List/Perm.lean @@ -45,7 +45,7 @@ section Rel open Relator -variable {γ : Type*} {δ : Type*} {r : α → β → Prop} {p : γ → δ → Prop} +variable {r : α → β → Prop} local infixr:80 " ∘r " => Relation.Comp diff --git a/Mathlib/Data/List/Sort.lean b/Mathlib/Data/List/Sort.lean index 2b327d5d70ca36..513e81df6f0a39 100644 --- a/Mathlib/Data/List/Sort.lean +++ b/Mathlib/Data/List/Sort.lean @@ -49,7 +49,7 @@ namespace List section Sorted -variable {α : Type u} {β : Type v} {r : α → α → Prop} {s : β → β → Prop} {a : α} {l : List α} +variable {α : Type u} {r : α → α → Prop} {a : α} {l : List α} /-- `Sorted r l` is the same as `List.Pairwise r l`, preferred in the case that `r` is a `<` or `≤`-like relation (transitive and antisymmetric or asymmetric) -/ diff --git a/Mathlib/Data/Nat/Cast/Order/Ring.lean b/Mathlib/Data/Nat/Cast/Order/Ring.lean index b03a53d8607f4a..2f6687f56c7acb 100644 --- a/Mathlib/Data/Nat/Cast/Order/Ring.lean +++ b/Mathlib/Data/Nat/Cast/Order/Ring.lean @@ -12,7 +12,7 @@ import Mathlib.Data.Nat.Cast.Order.Basic -/ -variable {α β : Type*} +variable {α : Type*} namespace Nat diff --git a/Mathlib/Dynamics/FixedPoints/Basic.lean b/Mathlib/Dynamics/FixedPoints/Basic.lean index 9f13fb19bc6cfb..78081cb3487640 100644 --- a/Mathlib/Dynamics/FixedPoints/Basic.lean +++ b/Mathlib/Dynamics/FixedPoints/Basic.lean @@ -27,7 +27,7 @@ open Equiv universe u v -variable {α : Type u} {β : Type v} {f fa g : α → α} {x y : α} {fb : β → β} {m n k : ℕ} {e : Perm α} +variable {α : Type u} {β : Type v} {f fa g : α → α} {x : α} {fb : β → β} {e : Perm α} namespace Function diff --git a/Mathlib/Geometry/Manifold/Algebra/LieGroup.lean b/Mathlib/Geometry/Manifold/Algebra/LieGroup.lean index 8bec2b7fa5b4fa..c054be8efa60bf 100644 --- a/Mathlib/Geometry/Manifold/Algebra/LieGroup.lean +++ b/Mathlib/Geometry/Manifold/Algebra/LieGroup.lean @@ -79,13 +79,10 @@ class LieGroup {𝕜 : Type*} [NontriviallyNormedField 𝕜] {H : Type*} [Topolo section PointwiseDivision variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {H : Type*} [TopologicalSpace H] {E : Type*} - [NormedAddCommGroup E] [NormedSpace 𝕜 E] {I : ModelWithCorners 𝕜 E H} {F : Type*} - [NormedAddCommGroup F] [NormedSpace 𝕜 F] {J : ModelWithCorners 𝕜 F F} {G : Type*} + [NormedAddCommGroup E] [NormedSpace 𝕜 E] {I : ModelWithCorners 𝕜 E H} {G : Type*} [TopologicalSpace G] [ChartedSpace H G] [Group G] [LieGroup I G] {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''] - {I'' : ModelWithCorners 𝕜 E'' H''} {M' : Type*} [TopologicalSpace M'] [ChartedSpace H'' M'] {n : ℕ∞} section @@ -236,7 +233,7 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {H : Type*} [TopologicalS [TopologicalSpace G] [ChartedSpace H G] [Inv G] [Zero G] [SmoothInv₀ I G] {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] {H' : Type*} [TopologicalSpace H'] {I' : ModelWithCorners 𝕜 E' H'} {M : Type*} [TopologicalSpace M] [ChartedSpace H' M] - {n : ℕ∞} {f g : M → G} + {n : ℕ∞} {f : M → G} theorem smoothAt_inv₀ {x : G} (hx : x ≠ 0) : SmoothAt I I (fun y ↦ y⁻¹) x := SmoothInv₀.smoothAt_inv₀ hx diff --git a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean index 10e4fe0a92fe3f..198e5170ad73e4 100644 --- a/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean +++ b/Mathlib/Geometry/Manifold/VectorBundle/SmoothSection.lean @@ -21,12 +21,8 @@ open Bundle Filter Function open scoped Bundle Manifold variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCommGroup E] - [NormedSpace 𝕜 E] {E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] {H : Type*} - [TopologicalSpace H] {H' : Type*} [TopologicalSpace H'] (I : ModelWithCorners 𝕜 E H) - (I' : ModelWithCorners 𝕜 E' H') {M : Type*} [TopologicalSpace M] [ChartedSpace H M] {M' : Type*} - [TopologicalSpace M'] [ChartedSpace H' M'] {E'' : Type*} [NormedAddCommGroup E''] - [NormedSpace 𝕜 E''] {H'' : Type*} [TopologicalSpace H''] {I'' : ModelWithCorners 𝕜 E'' H''} - {M'' : Type*} [TopologicalSpace M''] [ChartedSpace H'' M''] + [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) + {M : Type*} [TopologicalSpace M] [ChartedSpace H M] variable (F : Type*) [NormedAddCommGroup F] [NormedSpace 𝕜 F] -- `F` model fiber @@ -51,7 +47,7 @@ abbrev SmoothSection := namespace ContMDiffSection -variable {I} {I'} {n} {F} {V} +variable {I} {n} {F} {V} instance : DFunLike Cₛ^n⟮I; F, V⟯ M V where coe := ContMDiffSection.toFun diff --git a/Mathlib/GroupTheory/Congruence/Defs.lean b/Mathlib/GroupTheory/Congruence/Defs.lean index c8c38842eee778..ced9c0f1660d13 100644 --- a/Mathlib/GroupTheory/Congruence/Defs.lean +++ b/Mathlib/GroupTheory/Congruence/Defs.lean @@ -584,7 +584,7 @@ end section MulOneClass -variable [MulOneClass M] [MulOneClass N] [MulOneClass P] (c : Con M) +variable [MulOneClass M] (c : Con M) /-- The quotient of a monoid by a congruence relation is a monoid. -/ @[to_additive "The quotient of an `AddMonoid` by an additive congruence relation is @@ -709,7 +709,7 @@ end Monoids section Groups -variable [Group M] [Group N] [Group P] (c : Con M) +variable [Group M] (c : Con M) /-- Multiplicative congruence relations preserve inversion. -/ @[to_additive "Additive congruence relations preserve negation."] diff --git a/Mathlib/GroupTheory/CosetCover.lean b/Mathlib/GroupTheory/CosetCover.lean index 03164c5973c5e7..a8ba591868ffa5 100644 --- a/Mathlib/GroupTheory/CosetCover.lean +++ b/Mathlib/GroupTheory/CosetCover.lean @@ -366,7 +366,7 @@ end Submodule section Subspace -variable {k E ι : Type*} [DivisionRing k] [Infinite k] [AddCommGroup E] [Module k E] +variable {k E : Type*} [DivisionRing k] [Infinite k] [AddCommGroup E] [Module k E] {s : Finset (Subspace k E)} /- A vector space over an infinite field cannot be a finite union of proper subspaces. -/ diff --git a/Mathlib/GroupTheory/DoubleCoset.lean b/Mathlib/GroupTheory/DoubleCoset.lean index 771be71a00bb9a..a7d7e296385104 100644 --- a/Mathlib/GroupTheory/DoubleCoset.lean +++ b/Mathlib/GroupTheory/DoubleCoset.lean @@ -22,7 +22,7 @@ this is the usual left or right quotient of a group by a subgroup. -- Porting note: removed import -- import Mathlib.Tactic.Group -variable {G : Type*} [Group G] {α : Type*} [Mul α] (J : Subgroup G) (g : G) +variable {G : Type*} [Group G] {α : Type*} [Mul α] open MulOpposite open scoped Pointwise diff --git a/Mathlib/GroupTheory/GroupAction/Hom.lean b/Mathlib/GroupTheory/GroupAction/Hom.lean index e2fc5be8f79d8d..fdebbaf6ec0f91 100644 --- a/Mathlib/GroupTheory/GroupAction/Hom.lean +++ b/Mathlib/GroupTheory/GroupAction/Hom.lean @@ -524,13 +524,10 @@ def inverse (f : A →+[M] B₁) (g : B₁ → A) (h₁ : Function.LeftInverse g section Semiring variable (R : Type*) [Semiring R] [MulSemiringAction M R] -variable (R' : Type*) [Ring R'] [MulSemiringAction M R'] variable (S : Type*) [Semiring S] [MulSemiringAction N S] -variable (S' : Type*) [Ring S'] [MulSemiringAction N S'] variable (T : Type*) [Semiring T] [MulSemiringAction P T] -variable {R S M' N'} -variable [AddMonoid M'] [DistribMulAction R M'] +variable {R S N'} variable [AddMonoid N'] [DistribMulAction S N'] variable {σ : R →* S} diff --git a/Mathlib/GroupTheory/NoncommPiCoprod.lean b/Mathlib/GroupTheory/NoncommPiCoprod.lean index 70be3543599dfc..d675c2b73a7f50 100644 --- a/Mathlib/GroupTheory/NoncommPiCoprod.lean +++ b/Mathlib/GroupTheory/NoncommPiCoprod.lean @@ -90,9 +90,6 @@ variable (ϕ : ∀ i : ι, N i →* M) -- We assume that the elements of different morphism commute variable (hcomm : Pairwise fun i j => ∀ x y, Commute (ϕ i x) (ϕ j y)) --- We use `f` and `g` to denote elements of `Π (i : ι), N i` -variable (f g : ∀ i : ι, N i) - namespace MonoidHom /-- The canonical homomorphism from a family of monoids. -/ @@ -168,9 +165,6 @@ variable {ι : Type*} variable {H : ι → Type*} [∀ i, Group (H i)] variable (ϕ : ∀ i : ι, H i →* G) --- We use `f` and `g` to denote elements of `Π (i : ι), H i` -variable (f g : ∀ i : ι, H i) - namespace MonoidHom -- The subgroup version of `MonoidHom.noncommPiCoprod_mrange` @[to_additive] @@ -251,9 +245,6 @@ namespace Subgroup variable {G : Type*} [Group G] variable {ι : Type*} {H : ι → Subgroup G} --- Elements of `Π (i : ι), H i` are called `f` and `g` here -variable (f g : ∀ i : ι, H i) - section CommutingSubgroups -- We assume that the elements of different subgroups commute diff --git a/Mathlib/GroupTheory/Sylow.lean b/Mathlib/GroupTheory/Sylow.lean index 7792a01f89afb3..6609de9811ac4d 100644 --- a/Mathlib/GroupTheory/Sylow.lean +++ b/Mathlib/GroupTheory/Sylow.lean @@ -414,9 +414,9 @@ end InfiniteSylow open Equiv Equiv.Perm Finset Function List QuotientGroup -universe u v w +universe u -variable {G : Type u} {α : Type v} {β : Type w} [Group G] +variable {G : Type u} [Group G] theorem QuotientGroup.card_preimage_mk (s : Subgroup G) (t : Set (G ⧸ s)) : Nat.card (QuotientGroup.mk ⁻¹' t) = Nat.card s * Nat.card t := by diff --git a/Mathlib/LinearAlgebra/Basis/Basic.lean b/Mathlib/LinearAlgebra/Basis/Basic.lean index 46ed8282bcd9a3..3e294300107a09 100644 --- a/Mathlib/LinearAlgebra/Basis/Basic.lean +++ b/Mathlib/LinearAlgebra/Basis/Basic.lean @@ -24,18 +24,15 @@ universe u open Function Set Submodule Finsupp -variable {ι : Type*} {ι' : Type*} {R : Type*} {R₂ : Type*} {K : Type*} -variable {M : Type*} {M' M'' : Type*} {V : Type u} {V' : Type*} +variable {ι : Type*} {ι' : Type*} {R : Type*} {R₂ : Type*} {M : Type*} {M' : Type*} section Module -variable [Semiring R] -variable [AddCommMonoid M] [Module R M] [AddCommMonoid M'] [Module R M'] - +variable [Semiring R] [AddCommMonoid M] [Module R M] [AddCommMonoid M'] [Module R M'] namespace Basis -variable (b b₁ : Basis ι R M) (i : ι) (c : R) (x : M) +variable (b : Basis ι R M) section Coord @@ -187,9 +184,9 @@ section Module open LinearMap variable {v : ι → M} -variable [Ring R] [CommRing R₂] [AddCommGroup M] [AddCommGroup M'] [AddCommGroup M''] -variable [Module R M] [Module R₂ M] [Module R M'] [Module R M''] -variable {c d : R} {x y : M} +variable [Ring R] [CommRing R₂] [AddCommGroup M] +variable [Module R M] [Module R₂ M] +variable {x y : M} variable (b : Basis ι R M) namespace Basis diff --git a/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean b/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean index 14b5f34c2a2b3b..172f5f1c0d87af 100644 --- a/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean +++ b/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean @@ -162,8 +162,7 @@ end FiniteDimensional namespace Module variable (K V) -variable [DivisionRing K] [AddCommGroup V] [Module K V] {V₂ : Type v'} [AddCommGroup V₂] - [Module K V₂] +variable [DivisionRing K] [AddCommGroup V] [Module K V] /-- In a finite-dimensional space, its dimension (seen as a cardinal) coincides with its `finrank`. This is a copy of `finrank_eq_rank _ _` which creates easier typeclass searches. -/ @@ -426,9 +425,6 @@ protected theorem finiteDimensional (f : V ≃ₗ[K] V₂) [FiniteDimensional K FiniteDimensional K V₂ := Module.Finite.equiv f -variable {R M M₂ : Type*} [Ring R] [AddCommGroup M] [AddCommGroup M₂] -variable [Module R M] [Module R M₂] - end LinearEquiv section @@ -442,8 +438,7 @@ instance finiteDimensional_finsupp {ι : Type*} [Finite ι] [FiniteDimensional K end namespace Submodule -variable [DivisionRing K] [AddCommGroup V] [Module K V] {V₂ : Type v'} [AddCommGroup V₂] - [Module K V₂] +variable [DivisionRing K] [AddCommGroup V] [Module K V] /-- If a submodule is contained in a finite-dimensional submodule with the same or smaller dimension, they are equal. -/ diff --git a/Mathlib/MeasureTheory/Integral/Bochner.lean b/Mathlib/MeasureTheory/Integral/Bochner.lean index 411b231ffbadc2..b4eab8d959db67 100644 --- a/Mathlib/MeasureTheory/Integral/Bochner.lean +++ b/Mathlib/MeasureTheory/Integral/Bochner.lean @@ -279,9 +279,8 @@ and prove basic property of this integral. open Finset -variable [NormedAddCommGroup E] [NormedAddCommGroup F] [NormedSpace ℝ F] {p : ℝ≥0∞} {G F' : Type*} - [NormedAddCommGroup G] [NormedAddCommGroup F'] [NormedSpace ℝ F'] {m : MeasurableSpace α} - {μ : Measure α} +variable [NormedAddCommGroup E] [NormedAddCommGroup F] [NormedSpace ℝ F] + {m : MeasurableSpace α} {μ : Measure α} /-- Bochner integral of simple functions whose codomain is a real `NormedSpace`. This is equal to `∑ x ∈ f.range, (μ (f ⁻¹' {x})).toReal • x` (see `integral_eq`). -/ @@ -423,7 +422,7 @@ namespace L1 open AEEqFun Lp.simpleFunc Lp -variable [NormedAddCommGroup E] [NormedAddCommGroup F] {m : MeasurableSpace α} {μ : Measure α} +variable [NormedAddCommGroup E] {m : MeasurableSpace α} {μ : Measure α} namespace SimpleFunc @@ -464,8 +463,7 @@ Define the Bochner integral on `α →₁ₛ[μ] E` by extension from the simple and prove basic properties of this integral. -/ -variable [NormedField 𝕜] [NormedSpace 𝕜 E] [NormedSpace ℝ E] [SMulCommClass ℝ 𝕜 E] {F' : Type*} - [NormedAddCommGroup F'] [NormedSpace ℝ F'] +variable [NormedField 𝕜] [NormedSpace 𝕜 E] [NormedSpace ℝ E] [SMulCommClass ℝ 𝕜 E] attribute [local instance] simpleFunc.normedSpace @@ -495,7 +493,6 @@ theorem norm_integral_le_norm (f : α →₁ₛ[μ] E) : ‖integral f‖ ≤ rw [integral, norm_eq_integral] exact (toSimpleFunc f).norm_integral_le_integral_norm (SimpleFunc.integrable f) -variable {E' : Type*} [NormedAddCommGroup E'] [NormedSpace ℝ E'] [NormedSpace 𝕜 E'] variable (α E μ 𝕜) /-- The Bochner integral over simple functions in L1 space as a continuous linear map. -/ @@ -575,7 +572,7 @@ open SimpleFunc local notation "Integral" => @integralCLM α E _ _ _ _ _ μ _ variable [NormedSpace ℝ E] [NontriviallyNormedField 𝕜] [NormedSpace 𝕜 E] [SMulCommClass ℝ 𝕜 E] - [NormedSpace ℝ F] [CompleteSpace E] + [CompleteSpace E] section IntegrationInL1 @@ -700,7 +697,7 @@ functions, and 0 otherwise; prove its basic properties. -/ variable [NormedAddCommGroup E] [hE : CompleteSpace E] [NontriviallyNormedField 𝕜] - [NormedSpace 𝕜 E] [NormedAddCommGroup F] [NormedSpace ℝ F] [CompleteSpace F] + [NormedAddCommGroup F] [NormedSpace ℝ F] [CompleteSpace F] {G : Type*} [NormedAddCommGroup G] [NormedSpace ℝ G] open Classical in @@ -730,8 +727,8 @@ section Properties open ContinuousLinearMap MeasureTheory.SimpleFunc -variable [NormedSpace ℝ E] [SMulCommClass ℝ 𝕜 E] -variable {f g : α → E} {m : MeasurableSpace α} {μ : Measure α} +variable [NormedSpace ℝ E] +variable {f : α → E} {m : MeasurableSpace α} {μ : Measure α} theorem integral_eq (f : α → E) (hf : Integrable f μ) : ∫ a, f a ∂μ = L1.integral (hf.toL1 f) := by simp [integral, hE, hf] @@ -1788,7 +1785,7 @@ end Properties section IntegralTrim -variable {H β γ : Type*} [NormedAddCommGroup H] {m m0 : MeasurableSpace β} {μ : Measure β} +variable {β γ : Type*} {m m0 : MeasurableSpace β} {μ : Measure β} /-- Simple function seen as simple function of a larger `MeasurableSpace`. -/ def SimpleFunc.toLargerSpace (hm : m ≤ m0) (f : @SimpleFunc β m γ) : SimpleFunc β γ := diff --git a/Mathlib/Order/Bounds/Basic.lean b/Mathlib/Order/Bounds/Basic.lean index eaee5e41d13306..fb6e31a954dffe 100644 --- a/Mathlib/Order/Bounds/Basic.lean +++ b/Mathlib/Order/Bounds/Basic.lean @@ -26,7 +26,7 @@ variable {α : Type u} {β : Type v} {γ : Type w} {ι : Sort x} section -variable [Preorder α] [Preorder β] {s t : Set α} {a b : α} +variable [Preorder α] {s t : Set α} {a b : α} theorem mem_upperBounds : a ∈ upperBounds s ↔ ∀ x ∈ s, x ≤ a := Iff.rfl diff --git a/Mathlib/Order/CompleteLattice.lean b/Mathlib/Order/CompleteLattice.lean index dc192f4a528ec2..2d47e7b97ad074 100644 --- a/Mathlib/Order/CompleteLattice.lean +++ b/Mathlib/Order/CompleteLattice.lean @@ -45,7 +45,7 @@ In lemma names, open Function OrderDual Set -variable {α β β₂ γ : Type*} {ι ι' : Sort*} {κ : ι → Sort*} {κ' : ι' → Sort*} +variable {α β γ : Type*} {ι ι' : Sort*} {κ : ι → Sort*} {κ' : ι' → Sort*} @[simp] lemma iSup_ulift {ι : Type*} [SupSet α] (f : ULift ι → α) : ⨆ i : ULift ι, f i = ⨆ i, f (.up i) := by simp [iSup]; congr with x; simp diff --git a/Mathlib/Order/GaloisConnection.lean b/Mathlib/Order/GaloisConnection.lean index d4ea55c673a62a..7420bcaf290d10 100644 --- a/Mathlib/Order/GaloisConnection.lean +++ b/Mathlib/Order/GaloisConnection.lean @@ -50,8 +50,8 @@ open Function OrderDual Set universe u v w x -variable {α : Type u} {β : Type v} {γ : Type w} {ι : Sort x} {κ : ι → Sort*} {a a₁ a₂ : α} - {b b₁ b₂ : β} +variable {α : Type u} {β : Type v} {γ : Type w} {ι : Sort x} {κ : ι → Sort*} {a₁ a₂ : α} + {b₁ b₂ : β} /-- A Galois connection is a pair of functions `l` and `u` satisfying `l a ≤ b ↔ a ≤ u b`. They are special cases of adjoint functors in category theory, @@ -337,7 +337,7 @@ theorem gc_Ici_sInf [CompleteSemilatticeInf α] : GaloisConnection (toDual ∘ Ici : α → (Set α)ᵒᵈ) (sInf ∘ ofDual : (Set α)ᵒᵈ → α) := fun _ _ ↦ le_sInf_iff.symm -variable [CompleteLattice α] [CompleteLattice β] [CompleteLattice γ] {f : α → β → γ} {s : Set α} +variable [CompleteLattice α] [CompleteLattice β] [CompleteLattice γ] {s : Set α} {t : Set β} {l u : α → β → γ} {l₁ u₁ : β → γ → α} {l₂ u₂ : α → γ → β} theorem sSup_image2_eq_sSup_sSup (h₁ : ∀ b, GaloisConnection (swap l b) (u₁ b)) diff --git a/Mathlib/Order/PiLex.lean b/Mathlib/Order/PiLex.lean index bcad74a66ca1db..4fd435168435ef 100644 --- a/Mathlib/Order/PiLex.lean +++ b/Mathlib/Order/PiLex.lean @@ -101,7 +101,7 @@ noncomputable instance [LinearOrder ι] [IsWellOrder ι (· < ·)] [∀ a, Linea section PartialOrder -variable [LinearOrder ι] [IsWellOrder ι (· < ·)] [∀ i, PartialOrder (β i)] {x y : ∀ i, β i} {i : ι} +variable [LinearOrder ι] [IsWellOrder ι (· < ·)] [∀ i, PartialOrder (β i)] {x : ∀ i, β i} {i : ι} {a : β i} open Function diff --git a/Mathlib/RingTheory/Localization/Submodule.lean b/Mathlib/RingTheory/Localization/Submodule.lean index 64d723f0fd50de..1e3d73e6d705b3 100644 --- a/Mathlib/RingTheory/Localization/Submodule.lean +++ b/Mathlib/RingTheory/Localization/Submodule.lean @@ -21,7 +21,7 @@ commutative ring, field of fractions variable {R : Type*} [CommRing R] (M : Submonoid R) (S : Type*) [CommRing S] -variable [Algebra R S] {P : Type*} [CommRing P] +variable [Algebra R S] namespace IsLocalization @@ -72,9 +72,6 @@ theorem coeSubmodule_span_singleton (x : R) : coeSubmodule S (Ideal.span {x}) = Submodule.span R {(algebraMap R S) x} := by rw [coeSubmodule_span, Set.image_singleton] -variable {g : R →+* P} -variable {T : Submonoid P} (hy : M ≤ T.comap g) {Q : Type*} [CommRing Q] -variable [Algebra P Q] [IsLocalization T Q] variable [IsLocalization M S] include M in @@ -159,11 +156,11 @@ namespace IsFractionRing open IsLocalization -variable {A K : Type*} [CommRing A] +variable {K : Type*} section CommRing -variable [CommRing K] [Algebra R K] [IsFractionRing R K] [Algebra A K] [IsFractionRing A K] +variable [CommRing K] [Algebra R K] [IsFractionRing R K] @[simp, mono] theorem coeSubmodule_le_coeSubmodule {I J : Ideal R} : diff --git a/Mathlib/Topology/Algebra/Module/Basic.lean b/Mathlib/Topology/Algebra/Module/Basic.lean index df022af8914107..637ef9b981a96d 100644 --- a/Mathlib/Topology/Algebra/Module/Basic.lean +++ b/Mathlib/Topology/Algebra/Module/Basic.lean @@ -130,9 +130,8 @@ end Submodule section closure -variable {R R' : Type u} {M M' : Type v} [Semiring R] [Ring R'] - [TopologicalSpace M] [AddCommMonoid M] [TopologicalSpace M'] [AddCommGroup M'] [Module R M] - [ContinuousConstSMul R M] [Module R' M'] [ContinuousConstSMul R' M'] +variable {R : Type u} {M : Type v} [Semiring R] [TopologicalSpace M] [AddCommMonoid M] [Module R M] + [ContinuousConstSMul R M] theorem Submodule.mapsTo_smul_closure (s : Submodule R M) (c : R) : Set.MapsTo (c • ·) (closure s : Set M) (closure s) := @@ -1418,7 +1417,7 @@ variable {R R₂ R₃ S S₃ : Type*} [Semiring R] [Semiring R₂] [Semiring R [SMulCommClass R₃ S₃ M₃] [ContinuousConstSMul S₃ M₃] [Module S N₂] [ContinuousConstSMul S N₂] [SMulCommClass R S N₂] [Module S N₃] [SMulCommClass R S N₃] [ContinuousConstSMul S N₃] {σ₁₂ : R →+* R₂} {σ₂₃ : R₂ →+* R₃} {σ₁₃ : R →+* R₃} [RingHomCompTriple σ₁₂ σ₂₃ σ₁₃] (c : S) - (h : M₂ →SL[σ₂₃] M₃) (f g : M →SL[σ₁₂] M₂) (x y z : M) + (h : M₂ →SL[σ₂₃] M₃) (f : M →SL[σ₁₂] M₂) /-- `ContinuousLinearMap.prod` as an `Equiv`. -/ @[simps apply] @@ -1505,7 +1504,7 @@ section CommRing variable {R : Type*} [CommRing R] {M : Type*} [TopologicalSpace M] [AddCommGroup M] {M₂ : Type*} [TopologicalSpace M₂] [AddCommGroup M₂] {M₃ : Type*} [TopologicalSpace M₃] [AddCommGroup M₃] - [Module R M] [Module R M₂] [Module R M₃] [ContinuousConstSMul R M₃] + [Module R M] [Module R M₂] [Module R M₃] variable [TopologicalAddGroup M₂] [ContinuousConstSMul R M₂] @@ -1596,10 +1595,10 @@ variable {R₁ : Type*} {R₂ : Type*} {R₃ : Type*} [Semiring R₁] [Semiring {σ₂₃ : R₂ →+* R₃} {σ₃₂ : R₃ →+* R₂} [RingHomInvPair σ₂₃ σ₃₂] [RingHomInvPair σ₃₂ σ₂₃] {σ₁₃ : R₁ →+* R₃} {σ₃₁ : R₃ →+* R₁} [RingHomInvPair σ₁₃ σ₃₁] [RingHomInvPair σ₃₁ σ₁₃] [RingHomCompTriple σ₁₂ σ₂₃ σ₁₃] [RingHomCompTriple σ₃₂ σ₂₁ σ₃₁] {M₁ : Type*} - [TopologicalSpace M₁] [AddCommMonoid M₁] {M'₁ : Type*} [TopologicalSpace M'₁] [AddCommMonoid M'₁] + [TopologicalSpace M₁] [AddCommMonoid M₁] {M₂ : Type*} [TopologicalSpace M₂] [AddCommMonoid M₂] {M₃ : Type*} [TopologicalSpace M₃] [AddCommMonoid M₃] {M₄ : Type*} [TopologicalSpace M₄] [AddCommMonoid M₄] [Module R₁ M₁] - [Module R₁ M'₁] [Module R₂ M₂] [Module R₃ M₃] + [Module R₂ M₂] [Module R₃ M₃] /-- A continuous linear equivalence induces a continuous linear map. -/ @[coe] @@ -2302,7 +2301,6 @@ end ContinuousLinearMap namespace Submodule variable {R : Type*} [Ring R] {M : Type*} [TopologicalSpace M] [AddCommGroup M] [Module R M] - {M₂ : Type*} [TopologicalSpace M₂] [AddCommGroup M₂] [Module R M₂] open ContinuousLinearMap From c744def559485980adb40b991247176a127345b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Thu, 17 Oct 2024 16:19:09 +0000 Subject: [PATCH 335/425] feat(Algebra/Module/Submodule): lemmas about `domRestrict` (#17806) From PFR --- Mathlib/Algebra/Module/Submodule/Ker.lean | 10 +++++++--- Mathlib/Algebra/Module/Submodule/Map.lean | 5 ++++- Mathlib/Algebra/Module/Submodule/Range.lean | 3 +++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Module/Submodule/Ker.lean b/Mathlib/Algebra/Module/Submodule/Ker.lean index 23ce2537e64cc8..b291dd847675d0 100644 --- a/Mathlib/Algebra/Module/Submodule/Ker.lean +++ b/Mathlib/Algebra/Module/Submodule/Ker.lean @@ -109,10 +109,13 @@ theorem le_ker_iff_map [RingHomSurjective τ₁₂] {f : F} {p : Submodule R M} theorem ker_codRestrict {τ₂₁ : R₂ →+* R} (p : Submodule R M) (f : M₂ →ₛₗ[τ₂₁] M) (hf) : ker (codRestrict p f hf) = ker f := by rw [ker, comap_codRestrict, Submodule.map_bot]; rfl +lemma ker_domRestrict [AddCommMonoid M₁] [Module R M₁] (p : Submodule R M) (f : M →ₗ[R] M₁) : + ker (domRestrict f p) = (ker f).comap p.subtype := ker_comp .. + theorem ker_restrict [AddCommMonoid M₁] [Module R M₁] {p : Submodule R M} {q : Submodule R M₁} {f : M →ₗ[R] M₁} (hf : ∀ x : M, x ∈ p → f x ∈ q) : - ker (f.restrict hf) = LinearMap.ker (f.domRestrict p) := by - rw [restrict_eq_codRestrict_domRestrict, ker_codRestrict] + ker (f.restrict hf) = (ker f).comap p.subtype := by + rw [restrict_eq_codRestrict_domRestrict, ker_codRestrict, ker_domRestrict] @[simp] theorem ker_zero : ker (0 : M →ₛₗ[τ₁₂] M₂) = ⊤ := @@ -198,7 +201,8 @@ theorem ker_eq_bot {f : M →ₛₗ[τ₁₂] M₂} : ker f = ⊥ ↔ Injective @[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_eq_bot, injective_domRestrict_iff, disjoint_iff] + rw [← ker_eq_bot, ker_restrict hf, ← ker_domRestrict, ker_eq_bot, injective_domRestrict_iff, + disjoint_iff] end Ring diff --git a/Mathlib/Algebra/Module/Submodule/Map.lean b/Mathlib/Algebra/Module/Submodule/Map.lean index 8e6b50ba4e4654..84ea00362c6d2f 100644 --- a/Mathlib/Algebra/Module/Submodule/Map.lean +++ b/Mathlib/Algebra/Module/Submodule/Map.lean @@ -290,9 +290,12 @@ theorem map_iInf_comap_of_surjective {ι : Sort*} (S : ι → Submodule R₂ M (⨅ i, (S i).comap f).map f = iInf S := (giMapComap hf).l_iInf_u _ -theorem comap_le_comap_iff_of_surjective (p q : Submodule R₂ M₂) : p.comap f ≤ q.comap f ↔ p ≤ q := +theorem comap_le_comap_iff_of_surjective {p q : Submodule R₂ M₂} : p.comap f ≤ q.comap f ↔ p ≤ q := (giMapComap hf).u_le_u_iff +lemma comap_lt_comap_iff_of_surjective {p q : Submodule R₂ M₂} : p.comap f < q.comap f ↔ p < q := by + apply lt_iff_lt_of_le_iff_le' <;> exact comap_le_comap_iff_of_surjective hf + theorem comap_strictMono_of_surjective : StrictMono (comap f) := (giMapComap hf).strictMono_u diff --git a/Mathlib/Algebra/Module/Submodule/Range.lean b/Mathlib/Algebra/Module/Submodule/Range.lean index 933cc427c94e9f..1053c1cf8c54c8 100644 --- a/Mathlib/Algebra/Module/Submodule/Range.lean +++ b/Mathlib/Algebra/Module/Submodule/Range.lean @@ -100,6 +100,9 @@ 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₂) : + range (domRestrict f K) = K.map f := by ext; simp + lemma range_domRestrict_le_range [RingHomSurjective τ₁₂] (f : M →ₛₗ[τ₁₂] M₂) (S : Submodule R M) : LinearMap.range (f.domRestrict S) ≤ LinearMap.range f := by rintro x ⟨⟨y, hy⟩, rfl⟩ From 9d883e2896b1b16d8e646c336c647da4fc1cacd5 Mon Sep 17 00:00:00 2001 From: FMLJohn <417963616@qq.com> Date: Thu, 17 Oct 2024 17:56:40 +0000 Subject: [PATCH 336/425] feat(RingTheory/PowerSeries/WellKnown): changed `PowerSeries.invOneSubPow` (#17360) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The definition of `PowerSeries.invOneSubPow` has been changed into the following: Given a commutative ring `S` and a number `d : ℕ`, `PowerSeries.invOneSubPow S d` is the multiplicative inverse of `(1 - X) ^ d` in `S⟦X⟧ˣ`. When `d` is `0`, `PowerSeries.invOneSubPow S d` will just be `1`. When `d` is positive, `PowerSeries.invOneSubPow S d` will be `∑ n, Nat.choose (d - 1 + n) (d - 1)`. Co-authored-by: FMLJohn <128468682+FMLJohn@users.noreply.github.com> --- Mathlib/RingTheory/PowerSeries/WellKnown.lean | 82 +++++++++++++------ 1 file changed, 56 insertions(+), 26 deletions(-) diff --git a/Mathlib/RingTheory/PowerSeries/WellKnown.lean b/Mathlib/RingTheory/PowerSeries/WellKnown.lean index 8b3ce3c34a0cee..292659bb8862fb 100644 --- a/Mathlib/RingTheory/PowerSeries/WellKnown.lean +++ b/Mathlib/RingTheory/PowerSeries/WellKnown.lean @@ -18,8 +18,9 @@ In this file we define the following power series: It is given by `∑ n, x ^ n /ₚ u ^ (n + 1)`. * `PowerSeries.invOneSubPow`: given a commutative ring `S` and a number `d : ℕ`, - `PowerSeries.invOneSubPow d : S⟦X⟧ˣ` is the power series `∑ n, Nat.choose (d + n) d` - whose multiplicative inverse is `(1 - X) ^ (d + 1)`. + `PowerSeries.invOneSubPow S d` is the multiplicative inverse of `(1 - X) ^ d` in `S⟦X⟧ˣ`. + When `d` is `0`, `PowerSeries.invOneSubPow S d` will just be `1`. When `d` is positive, + `PowerSeries.invOneSubPow S d` will be `∑ n, Nat.choose (d - 1 + n) (d - 1)`. * `PowerSeries.sin`, `PowerSeries.cos`, `PowerSeries.exp` : power series for sin, cosine, and exponential functions. @@ -64,7 +65,7 @@ end Ring section invOneSubPow -variable {S : Type*} [CommRing S] (d : ℕ) +variable (S : Type*) [CommRing S] (d : ℕ) /-- (1 + X + X^2 + ...) * (1 - X) = 1. @@ -97,39 +98,68 @@ theorem mk_one_pow_eq_mk_choose_add : add_right_comm] /-- -The power series `mk fun n => Nat.choose (d + n) d`, whose multiplicative inverse is -`(1 - X) ^ (d + 1)`. +Given a natural number `d : ℕ` and a commutative ring `S`, `PowerSeries.invOneSubPow S d` is the +multiplicative inverse of `(1 - X) ^ d` in `S⟦X⟧ˣ`. When `d` is `0`, `PowerSeries.invOneSubPow S d` +will just be `1`. When `d` is positive, `PowerSeries.invOneSubPow S d` will be the power series +`mk fun n => Nat.choose (d - 1 + n) (d - 1)`. -/ -noncomputable def invOneSubPow : S⟦X⟧ˣ where - val := mk fun n => Nat.choose (d + n) d - inv := (1 - X) ^ (d + 1) - val_inv := by - rw [← mk_one_pow_eq_mk_choose_add, ← mul_pow, mk_one_mul_one_sub_eq_one, one_pow] - inv_val := by - rw [← mk_one_pow_eq_mk_choose_add, ← mul_pow, mul_comm, mk_one_mul_one_sub_eq_one, one_pow] - -theorem invOneSubPow_val_eq_mk_choose_add : - (invOneSubPow d).val = (mk fun n => Nat.choose (d + n) d : S⟦X⟧) := rfl - -theorem invOneSubPow_val_zero_eq_invUnitSub_one : - (invOneSubPow 0).val = invUnitsSub (1 : Sˣ) := by +noncomputable def invOneSubPow : ℕ → S⟦X⟧ˣ + | 0 => 1 + | d + 1 => { + val := mk fun n => Nat.choose (d + n) d + inv := (1 - X) ^ (d + 1) + val_inv := by + rw [← mk_one_pow_eq_mk_choose_add, ← mul_pow, mk_one_mul_one_sub_eq_one, one_pow] + inv_val := by + rw [← mk_one_pow_eq_mk_choose_add, ← mul_pow, mul_comm, mk_one_mul_one_sub_eq_one, one_pow] + } + +theorem invOneSubPow_zero : invOneSubPow S 0 = 1 := by + delta invOneSubPow + simp only [Units.val_one] + +theorem invOneSubPow_val_eq_mk_sub_one_add_choose_of_pos (h : 0 < d) : + (invOneSubPow S d).val = (mk fun n => Nat.choose (d - 1 + n) (d - 1) : S⟦X⟧) := by + rw [← Nat.sub_one_add_one_eq_of_pos h, invOneSubPow, add_tsub_cancel_right] + +theorem invOneSubPow_val_succ_eq_mk_add_choose : + (invOneSubPow S (d + 1)).val = (mk fun n => Nat.choose (d + n) d : S⟦X⟧) := rfl + +theorem invOneSubPow_val_one_eq_invUnitSub_one : + (invOneSubPow S 1).val = invUnitsSub (1 : Sˣ) := by simp [invOneSubPow, invUnitsSub] /-- The theorem `PowerSeries.mk_one_mul_one_sub_eq_one` implies that `1 - X` is a unit in `S⟦X⟧` whose inverse is the power series `1 + X + X^2 + ...`. This theorem states that for any `d : ℕ`, -`PowerSeries.invOneSubPow d` is equal to `(1 - X)⁻¹ ^ (d + 1)`. +`PowerSeries.invOneSubPow S d` is equal to `(1 - X)⁻¹ ^ d`. -/ theorem invOneSubPow_eq_inv_one_sub_pow : - invOneSubPow d = (Units.mkOfMulEqOne (1 - X) (mk 1 : S⟦X⟧) - <| Eq.trans (mul_comm _ _) mk_one_mul_one_sub_eq_one)⁻¹ ^ (d + 1) := by - rw [inv_pow] - exact (DivisionMonoid.inv_eq_of_mul _ (invOneSubPow d) <| by - rw [← Units.val_eq_one, Units.val_mul, Units.val_pow_eq_pow_val] - exact (invOneSubPow d).inv_val).symm + invOneSubPow S d = + (Units.mkOfMulEqOne (1 - X) (mk 1 : S⟦X⟧) <| + Eq.trans (mul_comm _ _) (mk_one_mul_one_sub_eq_one S))⁻¹ ^ d := by + induction d with + | zero => exact Eq.symm <| pow_zero _ + | succ d _ => + rw [inv_pow] + exact (DivisionMonoid.inv_eq_of_mul _ (invOneSubPow S (d + 1)) <| by + rw [← Units.val_eq_one, Units.val_mul, Units.val_pow_eq_pow_val] + exact (invOneSubPow S (d + 1)).inv_val).symm theorem invOneSubPow_inv_eq_one_sub_pow : - (invOneSubPow d).inv = (1 - X : S⟦X⟧) ^ (d + 1) := rfl + (invOneSubPow S d).inv = (1 - X : S⟦X⟧) ^ d := by + induction d with + | zero => exact Eq.symm <| pow_zero _ + | succ d => rfl + +theorem invOneSubPow_inv_eq_one_of_eq_zero (h : d = 0) : + (invOneSubPow S d).inv = 1 := by + delta invOneSubPow + simp only [h, Units.inv_eq_val_inv, inv_one, Units.val_one] + +theorem mk_add_choose_mul_one_sub_pow_eq_one : + (mk fun n ↦ Nat.choose (d + n) d : S⟦X⟧) * ((1 - X) ^ (d + 1)) = 1 := + (invOneSubPow S (d + 1)).val_inv end invOneSubPow From e759b3b1e909c1ebe13a364745f063152a61a3aa Mon Sep 17 00:00:00 2001 From: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com> Date: Thu, 17 Oct 2024 19:04:09 +0000 Subject: [PATCH 337/425] feat: UniqueFactorizationMonoid.factors_rel_of_associated (#17260) --- Mathlib/RingTheory/Radical.lean | 12 ++++++---- .../RingTheory/UniqueFactorizationDomain.lean | 23 ++++++++++++++----- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Mathlib/RingTheory/Radical.lean b/Mathlib/RingTheory/Radical.lean index c86cee4872a468..0c28c161cdf4f4 100644 --- a/Mathlib/RingTheory/Radical.lean +++ b/Mathlib/RingTheory/Radical.lean @@ -46,6 +46,12 @@ variable {M : Type*} [CancelCommMonoidWithZero M] [NormalizationMonoid M] def primeFactors (a : M) : Finset M := (normalizedFactors a).toFinset +theorem _root_.Associated.primeFactors_eq {a b : M} (h : Associated a b) : + primeFactors a = primeFactors b := by + unfold primeFactors + rw [h.normalizedFactors_eq] + + /-- Radical of an element `a` in a unique factorization monoid is the product of the prime factors of `a`. @@ -62,10 +68,8 @@ theorem radical_one_eq : radical (1 : M) = 1 := by rw [radical, primeFactors, normalizedFactors_one, Multiset.toFinset_zero, Finset.prod_empty] theorem radical_eq_of_associated {a b : M} (h : Associated a b) : radical a = radical b := by - rcases iff_iff_and_or_not_and_not.mp h.eq_zero_iff with (⟨rfl, rfl⟩ | ⟨ha, hb⟩) - · rfl - · simp_rw [radical, primeFactors] - rw [(associated_iff_normalizedFactors_eq_normalizedFactors ha hb).mp h] + unfold radical + rw [h.primeFactors_eq] theorem radical_unit_eq_one {a : M} (h : IsUnit a) : radical a = 1 := (radical_eq_of_associated (associated_one_iff_isUnit.mpr h)).trans radical_one_eq diff --git a/Mathlib/RingTheory/UniqueFactorizationDomain.lean b/Mathlib/RingTheory/UniqueFactorizationDomain.lean index e144f86f1433b6..dde98af42a0080 100644 --- a/Mathlib/RingTheory/UniqueFactorizationDomain.lean +++ b/Mathlib/RingTheory/UniqueFactorizationDomain.lean @@ -554,6 +554,13 @@ theorem factors_pow_count_prod [DecidableEq α] {x : α} (hx : x ≠ 0) : _ = prod (factors x) := by rw [toFinset_sum_count_nsmul_eq (factors x)] _ ~ᵤ x := factors_prod hx +theorem factors_rel_of_associated {a b : α} (h : Associated a b) : + Multiset.Rel Associated (factors a) (factors b) := by + rcases iff_iff_and_or_not_and_not.mp h.eq_zero_iff with (⟨rfl, rfl⟩ | ⟨ha, hb⟩) + · simp + · refine factors_unique irreducible_of_factor irreducible_of_factor ?_ + exact ((factors_prod ha).trans h).trans (factors_prod hb).symm + end UniqueFactorizationMonoid namespace UniqueFactorizationMonoid @@ -721,13 +728,17 @@ theorem dvd_iff_normalizedFactors_le_normalizedFactors {x y : α} (hx : x ≠ 0) (normalizedFactors_prod hy).dvd_iff_dvd_right] apply Multiset.prod_dvd_prod_of_le +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 + rw [h', ← Multiset.map_map, ← Multiset.map_map, + Associates.rel_associated_iff_map_eq_map.mp (factors_rel_of_associated h)] + theorem associated_iff_normalizedFactors_eq_normalizedFactors {x y : α} (hx : x ≠ 0) (hy : y ≠ 0) : - x ~ᵤ y ↔ normalizedFactors x = normalizedFactors y := by - refine - ⟨fun h => ?_, fun h => - (normalizedFactors_prod hx).symm.trans (_root_.trans (by rw [h]) (normalizedFactors_prod hy))⟩ - apply le_antisymm <;> rw [← dvd_iff_normalizedFactors_le_normalizedFactors] - all_goals simp [*, h.dvd, h.symm.dvd] + x ~ᵤ y ↔ normalizedFactors x = normalizedFactors y := + ⟨Associated.normalizedFactors_eq, fun h => + (normalizedFactors_prod hx).symm.trans (_root_.trans (by rw [h]) (normalizedFactors_prod hy))⟩ theorem normalizedFactors_of_irreducible_pow {p : α} (hp : Irreducible p) (k : ℕ) : normalizedFactors (p ^ k) = Multiset.replicate k (normalize p) := by From 4092287b49c452c0efcf2dee7d9d5e5db095768d Mon Sep 17 00:00:00 2001 From: Etienne Date: Thu, 17 Oct 2024 19:04:10 +0000 Subject: [PATCH 338/425] feat: sufficient condition for a set of linear forms to span the dual space (#17548) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consider a reflexive module and a set `s` of linear forms. If for any `z ≠ 0` there exists `f ∈ s` such that `f z ≠ 0`, then `s` spans the whole dual space. --- Mathlib/LinearAlgebra/Dual.lean | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Mathlib/LinearAlgebra/Dual.lean b/Mathlib/LinearAlgebra/Dual.lean index 0dfa5a4d643f0c..23b6f1f84347ad 100644 --- a/Mathlib/LinearAlgebra/Dual.lean +++ b/Mathlib/LinearAlgebra/Dual.lean @@ -690,6 +690,20 @@ theorem exists_dual_map_eq_bot_of_lt_top (hp : p < ⊤) (hp' : Free R (M ⧸ p)) obtain ⟨f, hf, hf'⟩ := p.exists_dual_map_eq_bot_of_nmem hx hp' exact ⟨f, by aesop, hf'⟩ +/-- Consider a reflexive module and a set `s` of linear forms. If for any `z ≠ 0` there exists +`f ∈ s` such that `f z ≠ 0`, then `s` spans the whole dual space. -/ +theorem span_eq_top_of_ne_zero [IsReflexive R M] + {s : Set (M →ₗ[R] R)} [Free R ((M →ₗ[R] R) ⧸ (span R s))] + (h : ∀ z ≠ 0, ∃ f ∈ s, f z ≠ 0) : span R s = ⊤ := by + by_contra! hn + obtain ⟨φ, φne, hφ⟩ := exists_dual_map_eq_bot_of_lt_top hn.lt_top inferInstance + let φs := (evalEquiv R M).symm φ + have this f (hf : f ∈ s) : f φs = 0 := by + rw [← mem_bot R, ← hφ, mem_map] + exact ⟨f, subset_span hf, (apply_evalEquiv_symm_apply R M f φ).symm⟩ + obtain ⟨x, xs, hx⟩ := h φs (by simp [φne, φs]) + exact hx <| this x xs + variable {ι 𝕜 E : Type*} [Field 𝕜] [AddCommGroup E] [Module 𝕜 E] open LinearMap Set FiniteDimensional From b2dddd4c7b46f8feff35592d99c9e4ce57a3832f Mon Sep 17 00:00:00 2001 From: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com> Date: Thu, 17 Oct 2024 19:56:26 +0000 Subject: [PATCH 339/425] feat: sum of iterated derivatives (#16886) This introduces `Polynomial.sumIDeriv`, the sum of the iterated derivatives of a polynomial, to be used in particular in the proof of the Lindemann-Weierstrass theorem (see #6718). Included are: * `Polynomial.sumIDeriv_apply`, `Polynomial.sumIDeriv_apply_of_lt`, `Polynomial.sumIDeriv_apply_of_le`: `Polynomial.sumIDeriv` expressed as a sum * `Polynomial.sumIDeriv_C`, `Polynomial.sumIDeriv_X`: `Polynomial.sumIDeriv` applied to simple polynomials * `Polynomial.sumIDeriv_map`: `Polynomial.sumIDeriv` commutes with `Polynomial.map` * `Polynomial.sumIDeriv_derivative`: `Polynomial.sumIDeriv` commutes with `Polynomial.derivative` * `Polynomial.sumIDeriv_eq_self_add`: `sumIDeriv p = p + sumIDeriv (derivative p)` * `Polynomial.exists_iterate_derivative_eq_factorial_smul`: the `k`'th iterated derivative of a polynomial has a common factor `k!` * `Polynomial.aeval_iterate_derivative_of_lt`, `Polynomial.aeval_iterate_derivative_self`, `Polynomial.aeval_iterate_derivative_of_ge`: applying `Polynomial.aeval` to iterated derivatives * `Polynomial.aeval_sumIDeriv`, `Polynomial.aeval_sumIDeriv_of_pos`: applying `Polynomial.aeval` to `Polynomial.sumIDeriv` Co-authored-by: FR-vdash-bot Co-authored-by: FR --- Mathlib.lean | 1 + Mathlib/Algebra/Polynomial/Derivative.lean | 64 +++++ .../Polynomial/SumIteratedDerivative.lean | 245 ++++++++++++++++++ 3 files changed, 310 insertions(+) create mode 100644 Mathlib/Algebra/Polynomial/SumIteratedDerivative.lean diff --git a/Mathlib.lean b/Mathlib.lean index b43069a00a0540..91da140ade63cb 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -744,6 +744,7 @@ import Mathlib.Algebra.Polynomial.Roots import Mathlib.Algebra.Polynomial.Smeval import Mathlib.Algebra.Polynomial.SpecificDegree import Mathlib.Algebra.Polynomial.Splits +import Mathlib.Algebra.Polynomial.SumIteratedDerivative import Mathlib.Algebra.Polynomial.Taylor import Mathlib.Algebra.Polynomial.UnitTrinomial import Mathlib.Algebra.QuadraticDiscriminant diff --git a/Mathlib/Algebra/Polynomial/Derivative.lean b/Mathlib/Algebra/Polynomial/Derivative.lean index 9f22f0fa03689b..9108354da435ca 100644 --- a/Mathlib/Algebra/Polynomial/Derivative.lean +++ b/Mathlib/Algebra/Polynomial/Derivative.lean @@ -12,6 +12,7 @@ import Mathlib.GroupTheory.GroupAction.Ring ## Main definitions * `Polynomial.derivative`: The formal derivative of polynomials, expressed as a linear map. + * `Polynomial.derivativeFinsupp`: Iterated derivatives as a finite support function. -/ @@ -22,6 +23,8 @@ open Finset open Polynomial +open scoped Nat + namespace Polynomial universe u v w y z @@ -330,6 +333,21 @@ theorem coeff_iterate_derivative {k} (p : R[X]) (m : ℕ) : _ = Nat.descFactorial (m + k.succ) k.succ • p.coeff (m + k.succ) := by rw [Nat.succ_add_eq_add_succ] +theorem iterate_derivative_eq_sum (p : R[X]) (k : ℕ) : + derivative^[k] p = + ∑ x ∈ (derivative^[k] p).support, C ((x + k).descFactorial k • p.coeff (x + k)) * X ^ x := by + conv_lhs => rw [(derivative^[k] p).as_sum_support_C_mul_X_pow] + refine sum_congr rfl fun i _ ↦ ?_ + rw [coeff_iterate_derivative, Nat.descFactorial_eq_factorial_mul_choose] + +theorem iterate_derivative_eq_factorial_smul_sum (p : R[X]) (k : ℕ) : + derivative^[k] p = k ! • + ∑ x ∈ (derivative^[k] p).support, C ((x + k).choose k • p.coeff (x + k)) * X ^ x := by + conv_lhs => rw [iterate_derivative_eq_sum] + rw [smul_sum] + refine sum_congr rfl fun i _ ↦ ?_ + rw [← smul_mul_assoc, smul_C, smul_smul, Nat.descFactorial_eq_factorial_mul_choose] + theorem iterate_derivative_mul {n} (p q : R[X]) : derivative^[n] (p * q) = ∑ k ∈ range n.succ, (n.choose k • (derivative^[n - k] p * derivative^[k] q)) := by @@ -374,6 +392,52 @@ theorem iterate_derivative_mul {n} (p q : R[X]) : omega · rw [Nat.choose_zero_right, tsub_zero] +/-- +Iterated derivatives as a finite support function. +-/ +@[simps! apply_toFun] +noncomputable def derivativeFinsupp : R[X] →ₗ[R] ℕ →₀ R[X] where + toFun p := .onFinset (range (p.natDegree + 1)) (derivative^[·] p) fun i ↦ by + contrapose; simp_all [iterate_derivative_eq_zero, Nat.succ_le] + map_add' _ _ := by ext; simp + map_smul' _ _ := by ext; simp + +@[simp] +theorem support_derivativeFinsupp_subset_range {p : R[X]} {n : ℕ} (h : p.natDegree < n) : + (derivativeFinsupp p).support ⊆ range n := by + dsimp [derivativeFinsupp] + exact Finsupp.support_onFinset_subset.trans (Finset.range_subset.mpr h) + +@[simp] +theorem derivativeFinsupp_C (r : R) : derivativeFinsupp (C r : R[X]) = .single 0 (C r) := by + ext i : 1 + match i with + | 0 => simp + | i + 1 => simp + +@[simp] +theorem derivativeFinsupp_one : derivativeFinsupp (1 : R[X]) = .single 0 1 := by + simpa using derivativeFinsupp_C (1 : R) + +@[simp] +theorem derivativeFinsupp_X : derivativeFinsupp (X : R[X]) = .single 0 X + .single 1 1 := by + ext i : 1 + match i with + | 0 => simp + | 1 => simp + | (n + 2) => simp + +theorem derivativeFinsupp_map [Semiring S] (p : R[X]) (f : R →+* S) : + derivativeFinsupp (p.map f) = (derivativeFinsupp p).mapRange (·.map f) (by simp) := by + ext i : 1 + simp + +theorem derivativeFinsupp_derivative (p : R[X]) : + derivativeFinsupp (derivative p) = + (derivativeFinsupp p).comapDomain Nat.succ Nat.succ_injective.injOn := by + ext i : 1 + simp + end Semiring section CommSemiring diff --git a/Mathlib/Algebra/Polynomial/SumIteratedDerivative.lean b/Mathlib/Algebra/Polynomial/SumIteratedDerivative.lean new file mode 100644 index 00000000000000..b8b64c16ec9bfd --- /dev/null +++ b/Mathlib/Algebra/Polynomial/SumIteratedDerivative.lean @@ -0,0 +1,245 @@ +/- +Copyright (c) 2022 Yuyang Zhao. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Yuyang Zhao +-/ +import Mathlib.Algebra.Polynomial.AlgebraMap +import Mathlib.Algebra.Polynomial.BigOperators +import Mathlib.Algebra.Polynomial.Degree.Lemmas +import Mathlib.Algebra.Polynomial.Derivative +import Mathlib.Algebra.Polynomial.RingDivision + +/-! +# Sum of iterated derivatives + +This file introduces `Polynomial.sumIDeriv`, the sum of the iterated derivatives of a polynomial, +as a linear map. This is used in particular in the proof of the Lindemann-Weierstrass theorem +(see #6718). + +## Main results + +* `Polynomial.sumIDeriv`: Sum of iterated derivatives of a polynomial, as a linear map +* `Polynomial.sumIDeriv_apply`, `Polynomial.sumIDeriv_apply_of_lt`, + `Polynomial.sumIDeriv_apply_of_le`: `Polynomial.sumIDeriv` expressed as a sum +* `Polynomial.sumIDeriv_C`, `Polynomial.sumIDeriv_X`: `Polynomial.sumIDeriv` applied to simple + polynomials +* `Polynomial.sumIDeriv_map`: `Polynomial.sumIDeriv` commutes with `Polynomial.map` +* `Polynomial.sumIDeriv_derivative`: `Polynomial.sumIDeriv` commutes with `Polynomial.derivative` +* `Polynomial.sumIDeriv_eq_self_add`: `sumIDeriv p = p + sumIDeriv (derivative p)` +* `Polynomial.exists_iterate_derivative_eq_factorial_smul`: the `k`'th iterated derivative of a + polynomial has a common factor `k!` +* `Polynomial.aeval_iterate_derivative_of_lt`, `Polynomial.aeval_iterate_derivative_self`, + `Polynomial.aeval_iterate_derivative_of_ge`: applying `Polynomial.aeval` to iterated derivatives +* `Polynomial.aeval_sumIDeriv`, `Polynomial.aeval_sumIDeriv_of_pos`: applying `Polynomial.aeval` to + `Polynomial.sumIDeriv` + +-/ + +open Finset +open scoped Nat + +namespace Polynomial + +variable {R S : Type*} + +section Semiring + +variable [Semiring R] [Semiring S] + +/-- +Sum of iterated derivatives of a polynomial, as a linear map + +This definition does not allow different weights for the derivatives. It is likely that it could be +extended to allow them, but this was not needed for the initial use case (the integration by part +of the integral $I_i$ in the +[Lindemann-Weierstrass](https://en.wikipedia.org/wiki/Lindemann%E2%80%93Weierstrass_theorem) +theorem). +-/ +noncomputable def sumIDeriv : R[X] →ₗ[R] R[X] := + Finsupp.lsum ℕ (fun _ ↦ LinearMap.id) ∘ₗ derivativeFinsupp + +theorem sumIDeriv_apply (p : R[X]) : + sumIDeriv p = ∑ i ∈ range (p.natDegree + 1), derivative^[i] p := by + dsimp [sumIDeriv] + exact Finsupp.sum_of_support_subset _ (by simp) _ (by simp) + +theorem sumIDeriv_apply_of_lt {p : R[X]} {n : ℕ} (hn : p.natDegree < n) : + sumIDeriv p = ∑ i ∈ range n, derivative^[i] p := by + dsimp [sumIDeriv] + exact Finsupp.sum_of_support_subset _ (by simp [hn]) _ (by simp) + +theorem sumIDeriv_apply_of_le {p : R[X]} {n : ℕ} (hn : p.natDegree ≤ n) : + sumIDeriv p = ∑ i ∈ range (n + 1), derivative^[i] p := by + dsimp [sumIDeriv] + exact Finsupp.sum_of_support_subset _ (by simp [Nat.lt_succ, hn]) _ (by simp) + +@[simp] +theorem sumIDeriv_C (a : R) : sumIDeriv (C a) = C a := by + rw [sumIDeriv_apply, natDegree_C, zero_add, sum_range_one, Function.iterate_zero_apply] + +@[simp] +theorem sumIDeriv_X : sumIDeriv X = X + C 1 := by + rw [sumIDeriv_apply, natDegree_X, sum_range_succ, sum_range_one, Function.iterate_zero_apply, + Function.iterate_one, derivative_X, eq_natCast, Nat.cast_one] + +@[simp] +theorem sumIDeriv_map (p : R[X]) (f : R →+* S) : + sumIDeriv (p.map f) = (sumIDeriv p).map f := by + let n := max (p.map f).natDegree p.natDegree + rw [sumIDeriv_apply_of_le (le_max_left _ _ : _ ≤ n)] + rw [sumIDeriv_apply_of_le (le_max_right _ _ : _ ≤ n)] + simp_rw [Polynomial.map_sum, iterate_derivative_map p f] + +theorem sumIDeriv_derivative (p : R[X]) : sumIDeriv (derivative p) = derivative (sumIDeriv p) := by + rw [sumIDeriv_apply_of_le ((natDegree_derivative_le p).trans tsub_le_self), sumIDeriv_apply, + derivative_sum] + simp_rw [← Function.iterate_succ_apply, Function.iterate_succ_apply'] + +theorem sumIDeriv_eq_self_add (p : R[X]) : sumIDeriv p = p + sumIDeriv (derivative p) := by + rw [sumIDeriv_derivative, sumIDeriv_apply, derivative_sum, sum_range_succ', sum_range_succ, + add_comm, ← add_zero (Finset.sum _ _)] + simp_rw [← Function.iterate_succ_apply' derivative, Nat.succ_eq_add_one, + Function.iterate_zero_apply, iterate_derivative_eq_zero (Nat.lt_succ_self _)] + +theorem exists_iterate_derivative_eq_factorial_smul (p : R[X]) (k : ℕ) : + ∃ gp : R[X], gp.natDegree ≤ p.natDegree - k ∧ derivative^[k] p = k ! • gp := by + refine ⟨_, (natDegree_sum_le _ _).trans ?_, iterate_derivative_eq_factorial_smul_sum p k⟩ + rw [fold_max_le] + refine ⟨Nat.zero_le _, fun i hi => ?_⟩ + dsimp only [Function.comp] + exact (natDegree_C_mul_le _ _).trans <| (natDegree_X_pow_le _).trans <| + (le_natDegree_of_mem_supp _ hi).trans <| natDegree_iterate_derivative _ _ + +end Semiring + +section CommSemiring + +variable [CommSemiring R] {A : Type*} [CommRing A] [Algebra R A] + +theorem aeval_iterate_derivative_of_lt (p : R[X]) (q : ℕ) (r : A) {p' : A[X]} + (hp : p.map (algebraMap R A) = (X - C r) ^ q * p') {k : ℕ} (hk : k < q) : + aeval r (derivative^[k] p) = 0 := by + have h (x) : (X - C r) ^ (q - (k - x)) = (X - C r) ^ 1 * (X - C r) ^ (q - (k - x) - 1) := by + rw [← pow_add, add_tsub_cancel_of_le] + rw [Nat.lt_iff_add_one_le] at hk + exact (le_tsub_of_add_le_left hk).trans (tsub_le_tsub_left (tsub_le_self : _ ≤ k) _) + rw [aeval_def, eval₂_eq_eval_map, ← iterate_derivative_map] + simp_rw [hp, iterate_derivative_mul, iterate_derivative_X_sub_pow, ← smul_mul_assoc, smul_smul, + h, ← mul_smul_comm, mul_assoc, ← mul_sum, eval_mul, pow_one, eval_sub, eval_X, eval_C, sub_self, + zero_mul] + +theorem aeval_iterate_derivative_self (p : R[X]) (q : ℕ) (r : A) {p' : A[X]} + (hp : p.map (algebraMap R A) = (X - C r) ^ q * p') : + aeval r (derivative^[q] p) = q ! • p'.eval r := by + have h (x) (h : 1 ≤ x) (h' : x ≤ q) : + (X - C r) ^ (q - (q - x)) = (X - C r) ^ 1 * (X - C r) ^ (q - (q - x) - 1) := by + rw [← pow_add, add_tsub_cancel_of_le] + rwa [tsub_tsub_cancel_of_le h'] + rw [aeval_def, eval₂_eq_eval_map, ← iterate_derivative_map] + simp_rw [hp, iterate_derivative_mul, iterate_derivative_X_sub_pow, ← smul_mul_assoc, smul_smul] + rw [sum_range_succ', Nat.choose_zero_right, one_mul, tsub_zero, Nat.descFactorial_self, tsub_self, + pow_zero, smul_mul_assoc, one_mul, Function.iterate_zero_apply, eval_add, eval_smul] + convert zero_add _ + rw [eval_finset_sum] + apply sum_eq_zero + intro x hx + rw [h (x + 1) le_add_self (Nat.add_one_le_iff.mpr (mem_range.mp hx)), pow_one, + eval_mul, eval_smul, eval_mul, eval_sub, eval_X, eval_C, sub_self, zero_mul, + smul_zero, zero_mul] + +variable (A) + +theorem aeval_iterate_derivative_of_ge (p : R[X]) (q : ℕ) {k : ℕ} (hk : q ≤ k) : + ∃ gp : R[X], gp.natDegree ≤ p.natDegree - k ∧ + ∀ r : A, aeval r (derivative^[k] p) = q ! • aeval r gp := by + obtain ⟨p', p'_le, hp'⟩ := exists_iterate_derivative_eq_factorial_smul p k + obtain ⟨k, rfl⟩ := Nat.exists_eq_add_of_le hk + refine ⟨((q + k).descFactorial k : R[X]) * p', (natDegree_C_mul_le _ _).trans p'_le, fun r => ?_⟩ + simp_rw [hp', nsmul_eq_mul, map_mul, map_natCast, ← mul_assoc, ← Nat.cast_mul, + Nat.add_descFactorial_eq_ascFactorial, Nat.factorial_mul_ascFactorial] + +theorem aeval_sumIDeriv (p : R[X]) (q : ℕ) : + ∃ gp : R[X], gp.natDegree ≤ p.natDegree - q ∧ + ∀ (r : A) {p' : A[X]}, p.map (algebraMap R A) = (X - C r) ^ q * p' → + aeval r (sumIDeriv p) = q ! • aeval r gp := by + have h (k) : + ∃ gp : R[X], gp.natDegree ≤ p.natDegree - q ∧ + ∀ (r : A) {p' : A[X]}, p.map (algebraMap R A) = (X - C r) ^ q * p' → + aeval r (derivative^[k] p) = q ! • aeval r gp := by + cases lt_or_ge k q with + | inl hk => + use 0 + rw [natDegree_zero] + use Nat.zero_le _ + intro r p' hp + rw [map_zero, smul_zero, aeval_iterate_derivative_of_lt p q r hp hk] + | inr hk => + obtain ⟨gp, gp_le, h⟩ := aeval_iterate_derivative_of_ge A p q hk + exact ⟨gp, gp_le.trans (tsub_le_tsub_left hk _), fun r p' _ => h r⟩ + choose c h using h + choose c_le hc using h + refine ⟨(range (p.natDegree + 1)).sum c, ?_, ?_⟩ + · refine (natDegree_sum_le _ _).trans ?_ + rw [fold_max_le] + exact ⟨Nat.zero_le _, fun i _ => c_le i⟩ + intro r p' hp + rw [sumIDeriv_apply, map_sum]; simp_rw [hc _ r hp, map_sum, smul_sum] + +theorem aeval_sumIDeriv_of_pos [Nontrivial A] [NoZeroDivisors A] (p : R[X]) {q : ℕ} (hq : 0 < q) : + ∃ gp : R[X], gp.natDegree ≤ p.natDegree - q ∧ + ∀ (inj_amap : Function.Injective (algebraMap R A)) (r : A) {p' : A[X]}, + p.map (algebraMap R A) = (X - C r) ^ (q - 1) * p' → + aeval r (sumIDeriv p) = (q - 1)! • p'.eval r + q ! • aeval r gp := by + rcases eq_or_ne p 0 with (rfl | p0) + · use 0 + rw [natDegree_zero] + use Nat.zero_le _ + intro _ r p' hp + rw [map_zero, map_zero, smul_zero, add_zero] + rw [Polynomial.map_zero] at hp + replace hp := (mul_eq_zero.mp hp.symm).resolve_left ?_ + rw [hp, eval_zero, smul_zero] + exact fun h => X_sub_C_ne_zero r (pow_eq_zero h) + let c k := if hk : q ≤ k then (aeval_iterate_derivative_of_ge A p q hk).choose else 0 + have c_le (k) : (c k).natDegree ≤ p.natDegree - k := by + dsimp only [c] + split_ifs with h + · 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] + 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 ?_ + rw [fold_max_le] + exact ⟨Nat.zero_le _, fun i hi => (c_le i).trans (tsub_le_tsub_left (mem_Ico.mp hi).1 _)⟩ + intro inj_amap r p' hp + have : range (p.natDegree + 1) = range q ∪ Ico q (p.natDegree + 1) := by + rw [range_eq_Ico, Ico_union_Ico_eq_Ico hq.le] + have h := natDegree_map_le (algebraMap R A) p + rw [congr_arg natDegree hp, natDegree_mul, natDegree_pow, natDegree_X_sub_C, mul_one, + ← Nat.sub_add_comm (Nat.one_le_of_lt hq), tsub_le_iff_right] at h + exact le_of_add_le_left h + · exact pow_ne_zero _ (X_sub_C_ne_zero r) + · rintro rfl + rw [mul_zero, Polynomial.map_eq_zero_iff inj_amap] at hp + exact p0 hp + rw [← zero_add ((q - 1)! • p'.eval r)] + rw [sumIDeriv_apply, map_sum, map_sum, this] + have : range q = range (q - 1 + 1) := by rw [tsub_add_cancel_of_le (Nat.one_le_of_lt hq)] + rw [sum_union, this, sum_range_succ] + congr 2 + · apply sum_eq_zero + exact fun x hx => aeval_iterate_derivative_of_lt p _ r hp (mem_range.mp hx) + · rw [← aeval_iterate_derivative_self _ _ _ hp] + · rw [smul_sum, sum_congr rfl] + intro k hk + exact hc k (mem_Ico.mp hk).1 r + · rw [range_eq_Ico, disjoint_iff_inter_eq_empty, eq_empty_iff_forall_not_mem] + intro x hx + rw [mem_inter, mem_Ico, mem_Ico] at hx + exact hx.1.2.not_le hx.2.1 + +end CommSemiring + +end Polynomial From bdecdcb60f733cb48871ea7bf782a46027f518d7 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Thu, 17 Oct 2024 19:56:27 +0000 Subject: [PATCH 340/425] chore: fix outdated `ext` porting notes (#17810) I went through all porting notes mentioning `ext` and fixed / removed those that no longer apply. --- Mathlib/Algebra/Polynomial/Monomial.lean | 9 +++------ Mathlib/AlgebraicGeometry/Limits.lean | 1 - Mathlib/CategoryTheory/EpiMono.lean | 2 -- Mathlib/Data/Set/Image.lean | 2 +- Mathlib/LinearAlgebra/Finsupp.lean | 6 ++---- Mathlib/LinearAlgebra/Matrix/Adjugate.lean | 3 +-- Mathlib/LinearAlgebra/Matrix/Charpoly/LinearMap.lean | 3 +-- Mathlib/NumberTheory/Zsqrtd/Basic.lean | 3 +-- Mathlib/RepresentationTheory/Invariants.lean | 2 +- 9 files changed, 10 insertions(+), 21 deletions(-) diff --git a/Mathlib/Algebra/Polynomial/Monomial.lean b/Mathlib/Algebra/Polynomial/Monomial.lean index 29b15cda6f45e1..535103330d899a 100644 --- a/Mathlib/Algebra/Polynomial/Monomial.lean +++ b/Mathlib/Algebra/Polynomial/Monomial.lean @@ -56,12 +56,9 @@ theorem ringHom_ext {S} [Semiring S] {f g : R[X] →+* S} (h₁ : ∀ a, f (C a) set f' := f.comp (toFinsuppIso R).symm.toRingHom with hf' set g' := g.comp (toFinsuppIso R).symm.toRingHom with hg' have A : f' = g' := by - -- Porting note: Was `ext; simp [..]; simpa [..] using h₂`. - ext : 1 - · ext - simp [f', g', h₁, RingEquiv.toRingHom_eq_coe] - · refine MonoidHom.ext_mnat ?_ - simpa [RingEquiv.toRingHom_eq_coe] using h₂ + ext + simp [f', g', h₁, RingEquiv.toRingHom_eq_coe] + simpa using h₂ have B : f = f'.comp (toFinsuppIso R) := by rw [hf', RingHom.comp_assoc] ext x diff --git a/Mathlib/AlgebraicGeometry/Limits.lean b/Mathlib/AlgebraicGeometry/Limits.lean index d5614273639d98..0622355eef4476 100644 --- a/Mathlib/AlgebraicGeometry/Limits.lean +++ b/Mathlib/AlgebraicGeometry/Limits.lean @@ -57,7 +57,6 @@ def Scheme.emptyTo (X : Scheme.{u}) : ∅ ⟶ X := @[ext] theorem Scheme.empty_ext {X : Scheme.{u}} (f g : ∅ ⟶ X) : f = g := - -- Porting note (#11041): `ext` regression Scheme.Hom.ext' (Subsingleton.elim (α := ∅ ⟶ _) _ _) theorem Scheme.eq_emptyTo {X : Scheme.{u}} (f : ∅ ⟶ X) : f = Scheme.emptyTo X := diff --git a/Mathlib/CategoryTheory/EpiMono.lean b/Mathlib/CategoryTheory/EpiMono.lean index 13cfd3e4ad1b30..8c8f738cc3b9f5 100644 --- a/Mathlib/CategoryTheory/EpiMono.lean +++ b/Mathlib/CategoryTheory/EpiMono.lean @@ -38,7 +38,6 @@ such that `f ≫ retraction f = 𝟙 X`. Every split monomorphism is a monomorphism. -/ /- Porting note(#5171): removed @[nolint has_nonempty_instance] -/ -/- Porting note: `@[ext]` used to accept lemmas like this. Now we add an aesop rule -/ @[ext, aesop apply safe (rule_sets := [CategoryTheory])] structure SplitMono {X Y : C} (f : X ⟶ Y) where /-- The map splitting `f` -/ @@ -64,7 +63,6 @@ such that `section_ f ≫ f = 𝟙 Y`. Every split epimorphism is an epimorphism. -/ /- Porting note(#5171): removed @[nolint has_nonempty_instance] -/ -/- Porting note: `@[ext]` used to accept lemmas like this. Now we add an aesop rule -/ @[ext, aesop apply safe (rule_sets := [CategoryTheory])] structure SplitEpi {X Y : C} (f : X ⟶ Y) where /-- The map splitting `f` -/ diff --git a/Mathlib/Data/Set/Image.lean b/Mathlib/Data/Set/Image.lean index 071d9c15c3f6c4..00387c99f22021 100644 --- a/Mathlib/Data/Set/Image.lean +++ b/Mathlib/Data/Set/Image.lean @@ -950,7 +950,7 @@ theorem range_inclusion (h : s ⊆ t) : range (inclusion h) = { x : t | (x : α) -- When `f` is injective, see also `Equiv.ofInjective`. theorem leftInverse_rangeSplitting (f : α → β) : LeftInverse (rangeFactorization f) (rangeSplitting f) := fun x => by - apply Subtype.ext -- Porting note: why doesn't `ext` find this lemma? + ext simp only [rangeFactorization_coe] apply apply_rangeSplitting diff --git a/Mathlib/LinearAlgebra/Finsupp.lean b/Mathlib/LinearAlgebra/Finsupp.lean index 91e9feb4155da7..5371c450912256 100644 --- a/Mathlib/LinearAlgebra/Finsupp.lean +++ b/Mathlib/LinearAlgebra/Finsupp.lean @@ -1331,8 +1331,7 @@ def splittingOfFinsuppSurjective (f : M →ₗ[R] α →₀ R) (s : Surjective f theorem splittingOfFinsuppSurjective_splits (f : M →ₗ[R] α →₀ R) (s : Surjective f) : f.comp (splittingOfFinsuppSurjective f s) = LinearMap.id := by - -- Porting note: `ext` can't find appropriate theorems. - refine lhom_ext' fun x => ext_ring <| Finsupp.ext fun y => ?_ + ext x dsimp [splittingOfFinsuppSurjective] congr rw [sum_single_index, one_smul] @@ -1357,8 +1356,7 @@ def splittingOfFunOnFintypeSurjective [Finite α] (f : M →ₗ[R] α → R) (s theorem splittingOfFunOnFintypeSurjective_splits [Finite α] (f : M →ₗ[R] α → R) (s : Surjective f) : f.comp (splittingOfFunOnFintypeSurjective f s) = LinearMap.id := by classical - -- Porting note: `ext` can't find appropriate theorems. - refine pi_ext' fun x => ext_ring <| funext fun y => ?_ + ext x y dsimp [splittingOfFunOnFintypeSurjective] rw [linearEquivFunOnFinite_symm_single, Finsupp.sum_single_index, one_smul, (s (Finsupp.single x 1)).choose_spec, Finsupp.single_eq_pi_single] diff --git a/Mathlib/LinearAlgebra/Matrix/Adjugate.lean b/Mathlib/LinearAlgebra/Matrix/Adjugate.lean index ef3a1b2ec68239..516ba73963c505 100644 --- a/Mathlib/LinearAlgebra/Matrix/Adjugate.lean +++ b/Mathlib/LinearAlgebra/Matrix/Adjugate.lean @@ -114,8 +114,7 @@ theorem cramer_row_self (i : n) (h : ∀ j, b j = A j i) : A.cramer b = Pi.singl @[simp] theorem cramer_one : cramer (1 : Matrix n n α) = 1 := by - -- Porting note: was `ext i j` - refine LinearMap.pi_ext' (fun (i : n) => LinearMap.ext_ring (funext (fun (j : n) => ?_))) + ext i j convert congr_fun (cramer_row_self (1 : Matrix n n α) (Pi.single i 1) i _) j · simp · intro j diff --git a/Mathlib/LinearAlgebra/Matrix/Charpoly/LinearMap.lean b/Mathlib/LinearAlgebra/Matrix/Charpoly/LinearMap.lean index e7d285c6ad0d2d..a6138962526ff3 100644 --- a/Mathlib/LinearAlgebra/Matrix/Charpoly/LinearMap.lean +++ b/Mathlib/LinearAlgebra/Matrix/Charpoly/LinearMap.lean @@ -93,8 +93,7 @@ theorem Matrix.represents_iff' {A : Matrix ι ι R} {f : Module.End R M} : have := LinearMap.congr_fun h (Pi.single i 1) rwa [PiToModule.fromEnd_apply_single_one, PiToModule.fromMatrix_apply_single_one] at this · intro h - -- Porting note: was `ext` - refine LinearMap.pi_ext' (fun i => LinearMap.ext_ring ?_) + ext simp_rw [LinearMap.comp_apply, LinearMap.coe_single, PiToModule.fromEnd_apply_single_one, PiToModule.fromMatrix_apply_single_one] apply h diff --git a/Mathlib/NumberTheory/Zsqrtd/Basic.lean b/Mathlib/NumberTheory/Zsqrtd/Basic.lean index 58b19978fb5b9c..914914db4f6cbb 100644 --- a/Mathlib/NumberTheory/Zsqrtd/Basic.lean +++ b/Mathlib/NumberTheory/Zsqrtd/Basic.lean @@ -931,8 +931,7 @@ def lift {d : ℤ} : { r : R // r * r = ↑d } ≃ (ℤ√d →+* R) where ext simp right_inv f := by - -- Porting note: was `ext` - refine hom_ext _ _ ?_ + ext simp /-- `lift r` is injective if `d` is non-square, and R has characteristic zero (that is, the map from diff --git a/Mathlib/RepresentationTheory/Invariants.lean b/Mathlib/RepresentationTheory/Invariants.lean index fa62df0a439487..898d8d34275134 100644 --- a/Mathlib/RepresentationTheory/Invariants.lean +++ b/Mathlib/RepresentationTheory/Invariants.lean @@ -134,7 +134,7 @@ def invariantsEquivRepHom (X Y : Rep k G) : (linHom X.ρ Y.ρ).invariants ≃ₗ map_add' _ _ := rfl map_smul' _ _ := rfl invFun f := ⟨f.hom, fun g => (mem_invariants_iff_comm _ g).2 (f.comm g)⟩ - left_inv _ := by apply Subtype.ext; ext; rfl -- Porting note: Added `apply Subtype.ext` + left_inv _ := by ext; rfl right_inv _ := by ext; rfl end Rep From e355e86a77c6deb2205be0bc9a4983e13b25eed4 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Thu, 17 Oct 2024 19:56:28 +0000 Subject: [PATCH 341/425] chore: fix "proof was" porting notes (#17836) Go through all porting notes that contain the string "proof was" and try to fix them. The following steps were used: * Golf the new proof. * If the current proof is nicer, delete the note. * Try to restore the old proof. * Classify some of the old failing proofs. --- .../Algebra/Category/ModuleCat/Subobject.lean | 4 +-- Mathlib/Algebra/Order/Group/Units.lean | 6 +--- Mathlib/Algebra/Order/Interval/Basic.lean | 7 ++--- Mathlib/Algebra/Star/Subalgebra.lean | 10 +++--- .../Analysis/Calculus/FDeriv/Measurable.lean | 1 - Mathlib/Data/List/OfFn.lean | 10 ++---- Mathlib/Data/Tree/Basic.lean | 4 +-- .../IsAlgClosed/AlgebraicClosure.lean | 31 +++++++------------ Mathlib/Geometry/Manifold/ChartedSpace.lean | 3 +- .../LinearAlgebra/CliffordAlgebra/Equivs.lean | 3 +- .../CliffordAlgebra/EvenEquiv.lean | 9 ++---- Mathlib/LinearAlgebra/LinearIndependent.lean | 4 +-- Mathlib/LinearAlgebra/SymplecticGroup.lean | 1 - Mathlib/MeasureTheory/Measure/Hausdorff.lean | 14 ++------- Mathlib/Order/Hom/Lattice.lean | 6 ---- Mathlib/RepresentationTheory/Rep.lean | 6 +--- Mathlib/RingTheory/AdjoinRoot.lean | 3 -- Mathlib/RingTheory/WittVector/IsPoly.lean | 4 --- Mathlib/Topology/Algebra/Monoid.lean | 2 -- Mathlib/Topology/Constructions.lean | 2 -- .../Topology/FiberBundle/Constructions.lean | 7 ++--- 21 files changed, 33 insertions(+), 104 deletions(-) diff --git a/Mathlib/Algebra/Category/ModuleCat/Subobject.lean b/Mathlib/Algebra/Category/ModuleCat/Subobject.lean index 134f3702fde184..a1508f23b2e542 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Subobject.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Subobject.lean @@ -82,7 +82,7 @@ noncomputable def toKernelSubobject {M N : ModuleCat.{v} R} {f : M ⟶ N} : @[simp] theorem toKernelSubobject_arrow {M N : ModuleCat R} {f : M ⟶ N} (x : LinearMap.ker f) : (kernelSubobject f).arrow (toKernelSubobject x) = x.1 := by - -- Porting note: The whole proof was just `simp [toKernelSubobject]`. + -- Porting note (#10959): the whole proof was just `simp [toKernelSubobject]`. suffices ((arrow ((kernelSubobject f))) ∘ (kernelSubobjectIso f ≪≫ kernelIsoKer f).inv) x = x by convert this rw [Iso.trans_inv, ← coe_comp, Category.assoc] @@ -105,7 +105,7 @@ theorem cokernel_π_imageSubobject_ext {L M N : ModuleCat.{v} R} (f : L ⟶ M) [ (g : (imageSubobject f : ModuleCat.{v} R) ⟶ N) [HasCokernel g] {x y : N} (l : L) (w : x = y + g (factorThruImageSubobject f l)) : cokernel.π g x = cokernel.π g y := by subst w - -- Porting note: The proof from here used to just be `simp`. + -- Porting note (#10959): The proof from here used to just be `simp`. simp only [map_add, add_right_eq_self] change ((cokernel.π g) ∘ (g) ∘ (factorThruImageSubobject f)) l = 0 rw [← coe_comp, ← coe_comp, Category.assoc] diff --git a/Mathlib/Algebra/Order/Group/Units.lean b/Mathlib/Algebra/Order/Group/Units.lean index af674406ea62af..c32449fad0ca7e 100644 --- a/Mathlib/Algebra/Order/Group/Units.lean +++ b/Mathlib/Algebra/Order/Group/Units.lean @@ -20,11 +20,7 @@ variable {α : Type*} additive group."] instance Units.orderedCommGroup [OrderedCommMonoid α] : OrderedCommGroup αˣ := { Units.instPartialOrderUnits, Units.instCommGroupUnits with - mul_le_mul_left := fun _ _ h _ => (@mul_le_mul_left' α _ _ _ _ _ h _) } - --- Porting note: the mathlib3 proof was --- mul_le_mul_left := fun a b h c => (mul_le_mul_left' (h : (a : α) ≤ b) _ : (c : α) * a ≤ c * b) } --- see https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/elaboration.20failure.20in.20algebra.2Eorder.2Egroup.2Eunits + mul_le_mul_left := fun _ _ h _ => (mul_le_mul_left' (α := α) h _) } /-- The units of a linearly ordered commutative monoid form a linearly ordered commutative group. -/ @[to_additive "The units of a linearly ordered commutative additive monoid form a diff --git a/Mathlib/Algebra/Order/Interval/Basic.lean b/Mathlib/Algebra/Order/Interval/Basic.lean index dcd8a5d261e097..5fc5f067acadf1 100644 --- a/Mathlib/Algebra/Order/Interval/Basic.lean +++ b/Mathlib/Algebra/Order/Interval/Basic.lean @@ -611,11 +611,8 @@ theorem length_sub_le : (s - t).length ≤ s.length + t.length := by simpa [sub_eq_add_neg] using length_add_le s (-t) theorem length_sum_le (f : ι → Interval α) (s : Finset ι) : - (∑ i ∈ s, f i).length ≤ ∑ i ∈ s, (f i).length := by - -- Porting note: Old proof was `:= Finset.le_sum_of_subadditive _ length_zero length_add_le _ _` - apply Finset.le_sum_of_subadditive - · exact length_zero - · exact length_add_le + (∑ i ∈ s, f i).length ≤ ∑ i ∈ s, (f i).length := + Finset.le_sum_of_subadditive _ length_zero length_add_le _ _ end Interval diff --git a/Mathlib/Algebra/Star/Subalgebra.lean b/Mathlib/Algebra/Star/Subalgebra.lean index 24e84fa477d779..a88d2390accc9d 100644 --- a/Mathlib/Algebra/Star/Subalgebra.lean +++ b/Mathlib/Algebra/Star/Subalgebra.lean @@ -107,8 +107,7 @@ theorem toSubalgebra_le_iff {S₁ S₂ : StarSubalgebra R A} : equalities. -/ protected def copy (S : StarSubalgebra R A) (s : Set A) (hs : s = ↑S) : StarSubalgebra R A where toSubalgebra := Subalgebra.copy S.toSubalgebra s hs - star_mem' := @fun a ha => hs ▸ (S.star_mem' (by simpa [hs] using ha) : star a ∈ (S : Set A)) - -- Porting note: the old proof kept crashing Lean + star_mem' {a} ha := hs ▸ S.star_mem' (by simpa [hs] using ha) @[simp] theorem coe_copy (S : StarSubalgebra R A) (s : Set A) (hs : s = ↑S) : (S.copy s hs : Set A) = s := @@ -700,10 +699,9 @@ theorem ext_adjoin_singleton {a : A} [FunLike F (adjoin R ({a} : Set A)) B] variable [FunLike F A B] [AlgHomClass F R A B] [StarHomClass F A B] (f g : F) /-- The equalizer of two star `R`-algebra homomorphisms. -/ -def equalizer : StarSubalgebra R A := - { toSubalgebra := AlgHom.equalizer (f : A →ₐ[R] B) g - star_mem' := @fun a (ha : f a = g a) => by simpa only [← map_star] using congrArg star ha } --- Porting note: much like `StarSubalgebra.copy` the old proof was broken and hard to fix +def equalizer : StarSubalgebra R A where + toSubalgebra := AlgHom.equalizer (f : A →ₐ[R] B) g + star_mem' {a} (ha : f a = g a) := by simpa only [← map_star] using congrArg star ha @[simp] theorem mem_equalizer (x : A) : x ∈ StarAlgHom.equalizer f g ↔ f x = g x := diff --git a/Mathlib/Analysis/Calculus/FDeriv/Measurable.lean b/Mathlib/Analysis/Calculus/FDeriv/Measurable.lean index 28e1539f0e516e..5801ab5775fa7c 100644 --- a/Mathlib/Analysis/Calculus/FDeriv/Measurable.lean +++ b/Mathlib/Analysis/Calculus/FDeriv/Measurable.lean @@ -592,7 +592,6 @@ theorem D_subset_differentiable_set {K : Set F} (hK : IsComplete K) : _ ≤ ‖L e p q - L e p r‖ + ‖L e p r - L e' p' r‖ + ‖L e' p' r - L e' p' q'‖ := (le_trans (norm_add_le _ _) (add_le_add_right (norm_add_le _ _) _)) _ ≤ 4 * (1 / 2) ^ e + 4 * (1 / 2) ^ e + 4 * (1 / 2) ^ e := by gcongr - -- Porting note: proof was `by apply_rules [add_le_add]` _ = 12 * (1 / 2) ^ e := by ring /- For definiteness, use `L0 e = L e (n e) (n e)`, to have a single sequence. We claim that this diff --git a/Mathlib/Data/List/OfFn.lean b/Mathlib/Data/List/OfFn.lean index 9aa74790b948bd..a3271be86ffd8e 100644 --- a/Mathlib/Data/List/OfFn.lean +++ b/Mathlib/Data/List/OfFn.lean @@ -200,14 +200,8 @@ def ofFnRec {C : List α → Sort*} (h : ∀ (n) (f : Fin n → α), C (List.ofF @[simp] theorem ofFnRec_ofFn {C : List α → Sort*} (h : ∀ (n) (f : Fin n → α), C (List.ofFn f)) {n : ℕ} - (f : Fin n → α) : @ofFnRec _ C h (List.ofFn f) = h _ f := by - -- Porting note: Old proof was - -- equivSigmaTuple.rightInverse_symm.cast_eq (fun s => h s.1 s.2) ⟨n, f⟩ - have := (@equivSigmaTuple α).rightInverse_symm - dsimp [equivSigmaTuple] at this - have := this.cast_eq (fun s => h s.1 s.2) ⟨n, f⟩ - dsimp only at this - rw [ofFnRec, ← this] + (f : Fin n → α) : @ofFnRec _ C h (List.ofFn f) = h _ f := + equivSigmaTuple.rightInverse_symm.cast_eq (fun s => h s.1 s.2) ⟨n, f⟩ theorem exists_iff_exists_tuple {P : List α → Prop} : (∃ l : List α, P l) ↔ ∃ (n : _) (f : Fin n → α), P (List.ofFn f) := diff --git a/Mathlib/Data/Tree/Basic.lean b/Mathlib/Data/Tree/Basic.lean index 95ebf3246593cf..df733700e6e4a1 100644 --- a/Mathlib/Data/Tree/Basic.lean +++ b/Mathlib/Data/Tree/Basic.lean @@ -103,9 +103,7 @@ compile_inductive% Tree @[elab_as_elim] def unitRecOn {motive : Tree Unit → Sort*} (t : Tree Unit) (base : motive nil) (ind : ∀ x y, motive x → motive y → motive (x △ y)) : motive t := - -- Porting note: Old proof was `t.recOn base fun u => u.recOn ind` but - -- structure eta makes it unnecessary (https://github.com/leanprover/lean4/issues/777). - t.recOn base fun _u => ind + t.recOn base fun _u ↦ ind theorem left_node_right_eq_self : ∀ {x : Tree Unit} (_hx : x ≠ nil), x.left △ x.right = x | nil, h => by trivial diff --git a/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean b/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean index a00d2cba8705ef..ea7fe25e09f587 100644 --- a/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean +++ b/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean @@ -164,12 +164,8 @@ instance Step.algebraSucc (n) : Algebra (Step k n) (Step k (n + 1)) := (toStepSucc k n).toAlgebra theorem toStepSucc.exists_root {n} {f : Polynomial (Step k n)} (hfm : f.Monic) - (hfi : Irreducible f) : ∃ x : Step k (n + 1), f.eval₂ (toStepSucc k n) x = 0 := by --- Porting note: original proof was `@AdjoinMonic.exists_root _ (Step.field k n) _ hfm hfi`, --- but it timeouts. - obtain ⟨x, hx⟩ := @AdjoinMonic.exists_root _ (Step.field k n) _ hfm hfi --- Porting note: using `hx` instead of `by apply hx` timeouts. - exact ⟨x, by apply hx⟩ + (hfi : Irreducible f) : ∃ x : Step k (n + 1), f.eval₂ (toStepSucc k n) x = 0 := + @AdjoinMonic.exists_root _ (Step.field k n) _ hfm hfi -- Porting note: the following two declarations were added during the port to be used in the -- definition of toStepOfLE @@ -186,29 +182,24 @@ private theorem toStepOfLE'.succ (m n : ℕ) (h : m ≤ n) : def toStepOfLE (m n : ℕ) (h : m ≤ n) : Step k m →+* Step k n where toFun := toStepOfLE' k m n h map_one' := by --- Porting note: original proof was `induction' h with n h ih; · exact Nat.leRecOn_self 1` --- `rw [Nat.leRecOn_succ h, ih, RingHom.map_one]` induction' h with a h ih · exact Nat.leRecOn_self 1 - · rw [toStepOfLE'.succ k m a h]; simp [ih] + · simp [toStepOfLE'.succ k m a h, ih] map_mul' x y := by --- Porting note: original proof was `induction' h with n h ih; · simp_rw [Nat.leRecOn_self]` --- `simp_rw [Nat.leRecOn_succ h, ih, RingHom.map_mul]` + simp only induction' h with a h ih - · dsimp [toStepOfLE']; simp_rw [Nat.leRecOn_self] - · simp_rw [toStepOfLE'.succ k m a h]; simp only at ih; simp [ih] --- Porting note: original proof was `induction' h with n h ih; · exact Nat.leRecOn_self 0` --- `rw [Nat.leRecOn_succ h, ih, RingHom.map_zero]` + · simp_rw [toStepOfLE', Nat.leRecOn_self] + · simp [toStepOfLE'.succ k m a h, ih] map_zero' := by + simp only induction' h with a h ih · exact Nat.leRecOn_self 0 - · simp_rw [toStepOfLE'.succ k m a h]; simp only at ih; simp [ih] + · simp [toStepOfLE'.succ k m a h, ih] map_add' x y := by --- Porting note: original proof was `induction' h with n h ih; · simp_rw [Nat.leRecOn_self]` --- `simp_rw [Nat.leRecOn_succ h, ih, RingHom.map_add]` + simp only induction' h with a h ih - · dsimp [toStepOfLE']; simp_rw [Nat.leRecOn_self] - · simp_rw [toStepOfLE'.succ k m a h]; simp only at ih; simp [ih] + · simp_rw [toStepOfLE', Nat.leRecOn_self] + · simp [toStepOfLE'.succ k m a h, ih] @[simp] theorem coe_toStepOfLE (m n : ℕ) (h : m ≤ n) : diff --git a/Mathlib/Geometry/Manifold/ChartedSpace.lean b/Mathlib/Geometry/Manifold/ChartedSpace.lean index 6a69ac58da981f..5acd6a8cea119a 100644 --- a/Mathlib/Geometry/Manifold/ChartedSpace.lean +++ b/Mathlib/Geometry/Manifold/ChartedSpace.lean @@ -758,9 +758,8 @@ section variable {ι : Type*} {Hi : ι → Type*} --- Porting note: Old proof was `Pi.inhabited _`. instance modelPiInhabited [∀ i, Inhabited (Hi i)] : Inhabited (ModelPi Hi) := - ⟨fun _ ↦ default⟩ + Pi.instInhabited instance [∀ i, TopologicalSpace (Hi i)] : TopologicalSpace (ModelPi Hi) := Pi.topologicalSpace diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean index 156e71925668fc..2285548a3e107e 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/Equivs.lean @@ -392,7 +392,6 @@ theorem equiv_ι (r : R) : CliffordAlgebraDualNumber.equiv (ι (R := R) _ r) = r @[simp] theorem equiv_symm_eps : CliffordAlgebraDualNumber.equiv.symm (eps : R[ε]) = ι (0 : QuadraticForm R R) 1 := - -- Porting note: Original proof was `DualNumber.lift_apply_eps _` - DualNumber.lift_apply_eps (R := R) (B := CliffordAlgebra (0 : QuadraticForm R R)) _ + DualNumber.lift_apply_eps _ end CliffordAlgebraDualNumber diff --git a/Mathlib/LinearAlgebra/CliffordAlgebra/EvenEquiv.lean b/Mathlib/LinearAlgebra/CliffordAlgebra/EvenEquiv.lean index 119f96a21ae0df..e9ab3a38b78953 100644 --- a/Mathlib/LinearAlgebra/CliffordAlgebra/EvenEquiv.lean +++ b/Mathlib/LinearAlgebra/CliffordAlgebra/EvenEquiv.lean @@ -152,13 +152,8 @@ def ofEven : CliffordAlgebra.even (Q' Q) →ₐ[R] CliffordAlgebra Q := by theorem ofEven_ι (x y : M × R) : ofEven Q ((even.ι (Q' Q)).bilin x y) = - (ι Q x.1 + algebraMap R _ x.2) * (ι Q y.1 - algebraMap R _ y.2) := by - -- Porting note: entire proof was the term-mode `even.lift_ι (Q' Q) _ x y` - unfold ofEven - lift_lets - intro f - -- TODO: replacing `?_` with `_` takes way longer? - exact @even.lift_ι R (M × R) _ _ _ (Q' Q) _ _ _ ⟨f, ?_, ?_⟩ x y + (ι Q x.1 + algebraMap R _ x.2) * (ι Q y.1 - algebraMap R _ y.2) := + even.lift_ι (Q' Q) _ x y theorem toEven_comp_ofEven : (toEven Q).comp (ofEven Q) = AlgHom.id R _ := even.algHom_ext (Q' Q) <| diff --git a/Mathlib/LinearAlgebra/LinearIndependent.lean b/Mathlib/LinearAlgebra/LinearIndependent.lean index ccd018f0d3ddf5..3f46f76b260abd 100644 --- a/Mathlib/LinearAlgebra/LinearIndependent.lean +++ b/Mathlib/LinearAlgebra/LinearIndependent.lean @@ -931,9 +931,7 @@ theorem LinearIndependent.independent_span_singleton (hv : LinearIndependent R v obtain ⟨⟨r, rfl⟩, hm⟩ := hm suffices r = 0 by simp [this] apply linearIndependent_iff_not_smul_mem_span.mp hv i - -- Porting note: The original proof was using `convert hm`. - suffices v '' (univ \ {i}) = range fun j : { j // j ≠ i } => v j by - rwa [this] + convert hm ext simp diff --git a/Mathlib/LinearAlgebra/SymplecticGroup.lean b/Mathlib/LinearAlgebra/SymplecticGroup.lean index c638f98ae8bd95..55b9036e4c5a47 100644 --- a/Mathlib/LinearAlgebra/SymplecticGroup.lean +++ b/Mathlib/LinearAlgebra/SymplecticGroup.lean @@ -86,7 +86,6 @@ open Matrix theorem mem_iff {A : Matrix (l ⊕ l) (l ⊕ l) R} : A ∈ symplecticGroup l R ↔ A * J l R * Aᵀ = J l R := by simp [symplecticGroup] --- Porting note: Previous proof was `by infer_instance` instance coeMatrix : Coe (symplecticGroup l R) (Matrix (l ⊕ l) (l ⊕ l) R) := ⟨Subtype.val⟩ diff --git a/Mathlib/MeasureTheory/Measure/Hausdorff.lean b/Mathlib/MeasureTheory/Measure/Hausdorff.lean index d4023bb58018d7..ce69db687e782b 100644 --- a/Mathlib/MeasureTheory/Measure/Hausdorff.lean +++ b/Mathlib/MeasureTheory/Measure/Hausdorff.lean @@ -1026,18 +1026,8 @@ theorem hausdorffMeasure_smul_right_image [NormedAddCommGroup E] [NormedSpace -- break lineMap into pieces suffices μH[1] ((‖v‖ • ·) '' (LinearMap.toSpanSingleton ℝ E (‖v‖⁻¹ • v) '' s)) = ‖v‖₊ • μH[1] s by - -- Porting note: proof was shorter, could need some golf - simp only [hausdorffMeasure_real, nnreal_smul_coe_apply] - convert this - · simp only [image_smul, LinearMap.toSpanSingleton_apply, Set.image_image] - ext e - simp only [mem_image] - refine ⟨fun ⟨x, h⟩ => ⟨x, ?_⟩, fun ⟨x, h⟩ => ⟨x, ?_⟩⟩ - · rw [smul_comm (norm _), smul_comm (norm _), inv_smul_smul₀ hn] - exact h - · rw [smul_comm (norm _), smul_comm (norm _), inv_smul_smul₀ hn] at h - exact h - · exact hausdorffMeasure_real.symm + simpa only [Set.image_image, smul_comm (norm _), inv_smul_smul₀ hn, + LinearMap.toSpanSingleton_apply] using this have iso_smul : Isometry (LinearMap.toSpanSingleton ℝ E (‖v‖⁻¹ • v)) := by refine AddMonoidHomClass.isometry_of_norm _ fun x => (norm_smul _ _).trans ?_ rw [norm_smul, norm_inv, norm_norm, inv_mul_cancel₀ hn, mul_one, LinearMap.id_apply] diff --git a/Mathlib/Order/Hom/Lattice.lean b/Mathlib/Order/Hom/Lattice.lean index 94af3f75665044..4179afdc3722b6 100644 --- a/Mathlib/Order/Hom/Lattice.lean +++ b/Mathlib/Order/Hom/Lattice.lean @@ -1567,7 +1567,6 @@ theorem withTop_id : (SupHom.id α).withTop = SupHom.id _ := DFunLike.coe_inject @[simp] theorem withTop_comp (f : SupHom β γ) (g : SupHom α β) : (f.comp g).withTop = f.withTop.comp g.withTop := --- Porting note: Proof was `DFunLike.coe_injective (Option.map_comp_map _ _).symm` DFunLike.coe_injective <| Eq.symm <| Option.map_comp_map _ _ /-- Adjoins a `⊥` to the domain and codomain of a `SupHom`. -/ @@ -1588,7 +1587,6 @@ theorem withBot_id : (SupHom.id α).withBot = SupBotHom.id _ := DFunLike.coe_inj @[simp] theorem withBot_comp (f : SupHom β γ) (g : SupHom α β) : (f.comp g).withBot = f.withBot.comp g.withBot := --- Porting note: Proof was `DFunLike.coe_injective (Option.map_comp_map _ _).symm` DFunLike.coe_injective <| Eq.symm <| Option.map_comp_map _ _ /-- Adjoins a `⊤` to the codomain of a `SupHom`. -/ @@ -1638,7 +1636,6 @@ theorem withTop_id : (InfHom.id α).withTop = InfTopHom.id _ := DFunLike.coe_inj @[simp] theorem withTop_comp (f : InfHom β γ) (g : InfHom α β) : (f.comp g).withTop = f.withTop.comp g.withTop := --- Porting note: Proof was `DFunLike.coe_injective (Option.map_comp_map _ _).symm` DFunLike.coe_injective <| Eq.symm <| Option.map_comp_map _ _ /-- Adjoins a `⊥` to the domain and codomain of an `InfHom`. -/ @@ -1658,7 +1655,6 @@ theorem withBot_id : (InfHom.id α).withBot = InfHom.id _ := DFunLike.coe_inject @[simp] theorem withBot_comp (f : InfHom β γ) (g : InfHom α β) : (f.comp g).withBot = f.withBot.comp g.withBot := --- Porting note: Proof was `DFunLike.coe_injective (Option.map_comp_map _ _).symm` DFunLike.coe_injective <| Eq.symm <| Option.map_comp_map _ _ /-- Adjoins a `⊤` to the codomain of an `InfHom`. -/ @@ -1708,7 +1704,6 @@ theorem withTop_id : (LatticeHom.id α).withTop = LatticeHom.id _ := @[simp] theorem withTop_comp (f : LatticeHom β γ) (g : LatticeHom α β) : (f.comp g).withTop = f.withTop.comp g.withTop := --- Porting note: Proof was `DFunLike.coe_injective (Option.map_comp_map _ _).symm` DFunLike.coe_injective <| Eq.symm <| Option.map_comp_map _ _ /-- Adjoins a `⊥` to the domain and codomain of a `LatticeHom`. -/ @@ -1729,7 +1724,6 @@ theorem withBot_id : (LatticeHom.id α).withBot = LatticeHom.id _ := @[simp] theorem withBot_comp (f : LatticeHom β γ) (g : LatticeHom α β) : (f.comp g).withBot = f.withBot.comp g.withBot := --- Porting note: Proof was `DFunLike.coe_injective (Option.map_comp_map _ _).symm` DFunLike.coe_injective <| Eq.symm <| Option.map_comp_map _ _ /-- Adjoins a `⊤` and `⊥` to the domain and codomain of a `LatticeHom`. -/ diff --git a/Mathlib/RepresentationTheory/Rep.lean b/Mathlib/RepresentationTheory/Rep.lean index 8ebf69973568b4..e6d2b8e5cd51e2 100644 --- a/Mathlib/RepresentationTheory/Rep.lean +++ b/Mathlib/RepresentationTheory/Rep.lean @@ -183,13 +183,9 @@ theorem linearization_μ_hom (X Y : Action (Type u) (MonCat.of G)) : @[simp] theorem linearization_μ_inv_hom (X Y : Action (Type u) (MonCat.of G)) : (inv ((linearization k G).μ X Y)).hom = (finsuppTensorFinsupp' k X.V Y.V).symm.toLinearMap := by --- Porting note (#11039): broken proof was -/- simp_rw [← Action.forget_map, Functor.map_inv, Action.forget_map, linearization_μ_hom] - apply IsIso.inv_eq_of_hom_inv_id _ - exact LinearMap.ext fun x => LinearEquiv.symm_apply_apply _ _-/ rw [← Action.forget_map, Functor.map_inv] apply IsIso.inv_eq_of_hom_inv_id - exact LinearMap.ext fun x => LinearEquiv.symm_apply_apply (finsuppTensorFinsupp' k X.V Y.V) x + exact LinearMap.ext fun x ↦ LinearEquiv.symm_apply_apply _ _ @[simp] theorem linearization_ε_hom : (linearization k G).ε.hom = Finsupp.lsingle PUnit.unit := diff --git a/Mathlib/RingTheory/AdjoinRoot.lean b/Mathlib/RingTheory/AdjoinRoot.lean index bba7f1e3e74579..eed173fefa7a81 100644 --- a/Mathlib/RingTheory/AdjoinRoot.lean +++ b/Mathlib/RingTheory/AdjoinRoot.lean @@ -205,7 +205,6 @@ theorem aeval_eq (p : R[X]) : aeval (root f) p = mk f p := rw [_root_.map_mul, aeval_C, map_pow, aeval_X, RingHom.map_mul, mk_C, RingHom.map_pow, mk_X] rfl --- Porting note: the following proof was partly in term-mode, but I was not able to fix it. theorem adjoinRoot_eq_top : Algebra.adjoin R ({root f} : Set (AdjoinRoot f)) = ⊤ := by refine Algebra.eq_top_iff.2 fun x => ?_ induction x using AdjoinRoot.induction_on with @@ -402,7 +401,6 @@ def modByMonicHom (hg : g.Monic) : AdjoinRoot g →ₗ[R] R[X] := theorem modByMonicHom_mk (hg : g.Monic) (f : R[X]) : modByMonicHom hg (mk g f) = f %ₘ g := rfl --- Porting note: the following proof was partly in term-mode, but I was not able to fix it. theorem mk_leftInverse (hg : g.Monic) : Function.LeftInverse (mk g) (modByMonicHom hg) := by intro f induction f using AdjoinRoot.induction_on @@ -716,7 +714,6 @@ def quotAdjoinRootEquivQuotPolynomialQuot : ((Ideal.quotEquivOfEq (by rw [map_span, Set.image_singleton])).trans (Polynomial.quotQuotEquivComm I f).symm)) --- Porting note: mathlib3 proof was a long `rw` that timeouts. @[simp] theorem quotAdjoinRootEquivQuotPolynomialQuot_mk_of (p : R[X]) : quotAdjoinRootEquivQuotPolynomialQuot I f (Ideal.Quotient.mk (I.map (of f)) (mk f p)) = diff --git a/Mathlib/RingTheory/WittVector/IsPoly.lean b/Mathlib/RingTheory/WittVector/IsPoly.lean index 69617badd66945..87bd44d9849c47 100644 --- a/Mathlib/RingTheory/WittVector/IsPoly.lean +++ b/Mathlib/RingTheory/WittVector/IsPoly.lean @@ -311,15 +311,11 @@ end ZeroOne /-- Addition of Witt vectors is a polynomial function. -/ -- Porting note: replaced `@[is_poly]` with `instance`. instance addIsPoly₂ [Fact p.Prime] : IsPoly₂ p fun _ _ => (· + ·) := - -- porting note: the proof was - -- `⟨⟨wittAdd p, by intros; dsimp only [WittVector.hasAdd]; simp [eval]⟩⟩` ⟨⟨wittAdd p, by intros; ext; exact add_coeff _ _ _⟩⟩ /-- Multiplication of Witt vectors is a polynomial function. -/ -- Porting note: replaced `@[is_poly]` with `instance`. instance mulIsPoly₂ [Fact p.Prime] : IsPoly₂ p fun _ _ => (· * ·) := - -- porting note: the proof was - -- `⟨⟨wittMul p, by intros; dsimp only [WittVector.hasMul]; simp [eval]⟩⟩` ⟨⟨wittMul p, by intros; ext; exact mul_coeff _ _ _⟩⟩ -- unfortunately this is not universe polymorphic, merely because `f` isn't diff --git a/Mathlib/Topology/Algebra/Monoid.lean b/Mathlib/Topology/Algebra/Monoid.lean index 126c6636dd3132..a9380677274964 100644 --- a/Mathlib/Topology/Algebra/Monoid.lean +++ b/Mathlib/Topology/Algebra/Monoid.lean @@ -302,8 +302,6 @@ theorem isClosed_setOf_map_mul [Mul M₁] [Mul M₂] [ContinuousMul M₂] : isClosed_iInter fun x => isClosed_iInter fun y => isClosed_eq (continuous_apply _) - -- Porting note: proof was: - -- `((continuous_apply _).mul (continuous_apply _))` (by continuity) -- Porting note: split variables command over two lines, can't change explicitness at the same time diff --git a/Mathlib/Topology/Constructions.lean b/Mathlib/Topology/Constructions.lean index 646dbbbcf8c5ac..e0bb583947c37a 100644 --- a/Mathlib/Topology/Constructions.lean +++ b/Mathlib/Topology/Constructions.lean @@ -880,11 +880,9 @@ theorem continuous_isRight : Continuous (isRight : X ⊕ Y → Bool) := continuous_sum_dom.2 ⟨continuous_const, continuous_const⟩ @[continuity, fun_prop] --- Porting note: the proof was `continuous_sup_rng_left continuous_coinduced_rng` theorem continuous_inl : Continuous (@inl X Y) := ⟨fun _ => And.left⟩ @[continuity, fun_prop] --- Porting note: the proof was `continuous_sup_rng_right continuous_coinduced_rng` theorem continuous_inr : Continuous (@inr X Y) := ⟨fun _ => And.right⟩ @[fun_prop, continuity] diff --git a/Mathlib/Topology/FiberBundle/Constructions.lean b/Mathlib/Topology/FiberBundle/Constructions.lean index a9ac5e6eb5149d..5ecf7487e24904 100644 --- a/Mathlib/Topology/FiberBundle/Constructions.lean +++ b/Mathlib/Topology/FiberBundle/Constructions.lean @@ -250,11 +250,8 @@ universe u v w₁ w₂ U variable {B : Type u} (F : Type v) (E : B → Type w₁) {B' : Type w₂} (f : B' → B) -instance [∀ x : B, TopologicalSpace (E x)] : ∀ x : B', TopologicalSpace ((f *ᵖ E) x) := by - -- Porting note: Original proof was `delta_instance Bundle.Pullback` - intro x - rw [Bundle.Pullback] - infer_instance +instance [∀ x : B, TopologicalSpace (E x)] : ∀ x : B', TopologicalSpace ((f *ᵖ E) x) := + inferInstanceAs (∀ x, TopologicalSpace (E (f x))) variable [TopologicalSpace B'] [TopologicalSpace (TotalSpace F E)] From a4d283b5f2f1bfb9f5c6d8c8c441d5e9d3b3373b Mon Sep 17 00:00:00 2001 From: Peter Nelson <71660771+apnelson1@users.noreply.github.com> Date: Thu, 17 Oct 2024 19:56:29 +0000 Subject: [PATCH 342/425] feat(Order/BooleanAlgebra, Data/Set/Basic): diff_le_diff_iff (#17876) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds a lemma stating that, for `x, y ≤ z` in a boolean algebra, we have `z \ x ≤ z \ y` iff `y ≤ x`. We also add the same lemma for sets/finsets. --- Mathlib/Data/Finset/Basic.lean | 4 ++++ Mathlib/Data/Set/Basic.lean | 4 ++++ Mathlib/Order/BooleanAlgebra.lean | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/Mathlib/Data/Finset/Basic.lean b/Mathlib/Data/Finset/Basic.lean index d8f077efcc2ea0..f226586bced604 100644 --- a/Mathlib/Data/Finset/Basic.lean +++ b/Mathlib/Data/Finset/Basic.lean @@ -1828,6 +1828,10 @@ theorem sdiff_empty : s \ ∅ = s := theorem sdiff_subset_sdiff (hst : s ⊆ t) (hvu : v ⊆ u) : s \ u ⊆ t \ v := sdiff_le_sdiff hst hvu +theorem sdiff_subset_sdiff_iff_subset {r : Finset α} (hs : s ⊆ r) (ht : t ⊆ r) : + r \ s ⊆ r \ t ↔ t ⊆ s := + sdiff_le_sdiff_iff_le hs ht + @[simp, norm_cast] theorem coe_sdiff (s₁ s₂ : Finset α) : ↑(s₁ \ s₂) = (s₁ \ s₂ : Set α) := Set.ext fun _ => mem_sdiff diff --git a/Mathlib/Data/Set/Basic.lean b/Mathlib/Data/Set/Basic.lean index 2cc7a256bcfdfb..63e22e76e74a89 100644 --- a/Mathlib/Data/Set/Basic.lean +++ b/Mathlib/Data/Set/Basic.lean @@ -1497,6 +1497,10 @@ theorem diff_subset_diff_left {s₁ s₂ t : Set α} (h : s₁ ⊆ s₂) : s₁ theorem diff_subset_diff_right {s t u : Set α} (h : t ⊆ u) : s \ u ⊆ s \ t := sdiff_le_sdiff_left ‹t ≤ u› +theorem diff_subset_diff_iff_subset {r : Set α} (hs : s ⊆ r) (ht : t ⊆ r) : + r \ s ⊆ r \ t ↔ t ⊆ s := + sdiff_le_sdiff_iff_le hs ht + theorem compl_eq_univ_diff (s : Set α) : sᶜ = univ \ s := top_sdiff.symm diff --git a/Mathlib/Order/BooleanAlgebra.lean b/Mathlib/Order/BooleanAlgebra.lean index 60726797718c40..ba0cb4558f27bc 100644 --- a/Mathlib/Order/BooleanAlgebra.lean +++ b/Mathlib/Order/BooleanAlgebra.lean @@ -359,6 +359,11 @@ theorem sdiff_eq_comm (hy : y ≤ x) (hz : z ≤ x) : x \ y = z ↔ x \ z = y := theorem eq_of_sdiff_eq_sdiff (hxz : x ≤ z) (hyz : y ≤ z) (h : z \ x = z \ y) : x = y := by rw [← sdiff_sdiff_eq_self hxz, h, sdiff_sdiff_eq_self hyz] +theorem sdiff_le_sdiff_iff_le (hx : x ≤ z) (hy : y ≤ z) : z \ x ≤ z \ y ↔ y ≤ x := by + refine ⟨fun h ↦ ?_, sdiff_le_sdiff_left⟩ + rw [← sdiff_sdiff_eq_self hx, ← sdiff_sdiff_eq_self hy] + exact sdiff_le_sdiff_left h + theorem sdiff_sdiff_left' : (x \ y) \ z = x \ y ⊓ x \ z := by rw [sdiff_sdiff_left, sdiff_sup] theorem sdiff_sdiff_sup_sdiff : z \ (x \ y ⊔ y \ x) = z ⊓ (z \ x ⊔ y) ⊓ (z \ y ⊔ x) := From 78d236b37033084670ab8e8b7b0514f719bc6696 Mon Sep 17 00:00:00 2001 From: Antoine Chambert-Loir Date: Thu, 17 Oct 2024 20:34:59 +0000 Subject: [PATCH 343/425] feat(GroupTheory/GroupAction/Blocks): lemmas to handle blocks on finite sets (#14029) This PR proves specific properties of blocks when the action is on a finite set Co-authored-by: Thomas Browning --- Mathlib/GroupTheory/GroupAction/Blocks.lean | 138 ++++++++++++++++++-- Mathlib/GroupTheory/Index.lean | 20 ++- 2 files changed, 147 insertions(+), 11 deletions(-) diff --git a/Mathlib/GroupTheory/GroupAction/Blocks.lean b/Mathlib/GroupTheory/GroupAction/Blocks.lean index dddd660c93991f..e88c5972e23aa6 100644 --- a/Mathlib/GroupTheory/GroupAction/Blocks.lean +++ b/Mathlib/GroupTheory/GroupAction/Blocks.lean @@ -4,11 +4,14 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Antoine Chambert-Loir -/ +import Mathlib.Algebra.Group.Subgroup.Actions +import Mathlib.Data.Set.Card import Mathlib.Data.Setoid.Partition import Mathlib.GroupTheory.GroupAction.Basic import Mathlib.GroupTheory.GroupAction.Pointwise import Mathlib.GroupTheory.GroupAction.SubMulAction -import Mathlib.Algebra.Group.Subgroup.Actions +import Mathlib.GroupTheory.Index +import Mathlib.Tactic.IntervalCases /-! # Blocks @@ -22,9 +25,21 @@ Given `SMul G X`, an action of a type `G` on a type `X`, we define The non-existence of nontrivial blocks is the definition of primitive actions. +## Results for actions on finite sets + +- `IsBlock.ncard_block_mul_ncard_orbit_eq` : The cardinality of a block +multiplied by the number of its translates is the cardinal of the ambient type + +- `IsBlock.is_univ_of_large_block` : a too large block is equal to `Set.univ` + +- `IsBlock.is_subsingleton` : a too small block is a subsingleton + +- `IsBlock.of_subset` : the intersections of the translates of a finite subset +that contain a given point is a block + ## References -We follow [wieland1964]. +We follow [wielandt1964]. -/ @@ -200,12 +215,13 @@ theorem isBlock_orbit (a : X) : IsBlock G (orbit G a) := variable (X) /-- The full set is a (trivial) block -/ -theorem isFixedBlock_top : IsFixedBlock G (⊤ : Set X) := - fun _ ↦ by simp only [Set.top_eq_univ, Set.smul_set_univ] +theorem isFixedBlock_univ : IsFixedBlock G (Set.univ : Set X) := + fun _ ↦ by simp only [Set.smul_set_univ] +@[deprecated (since := "2024-09-14")] alias isFixedBlock_top := isFixedBlock_univ /-- The full set is a (trivial) block -/ -theorem isBlock_top : IsBlock G (⊤ : Set X) := - (isFixedBlock_top _).isBlock +theorem isBlock_univ : IsBlock G (Set.univ : Set X) := + (isFixedBlock_univ _).isBlock variable {X} @@ -282,9 +298,9 @@ theorem IsBlock.inter {B₁ B₂ : Set X} (h₁ : IsBlock G B₁) (h₂ : IsBloc theorem IsBlock.iInter {ι : Type*} {B : ι → Set X} (hB : ∀ i : ι, IsBlock G (B i)) : IsBlock G (⋂ i, B i) := by by_cases hι : (IsEmpty ι) - · -- ι = ∅, block = ⊤ - suffices (⋂ i : ι, B i) = Set.univ by simpa only [this] using isBlock_top X - simpa only [Set.top_eq_univ, Set.iInter_eq_univ] using (hι.elim' ·) + · -- ι = ∅, block = univ + suffices (⋂ i : ι, B i) = Set.univ by simpa only [this] using isBlock_univ X + simpa only [Set.iInter_eq_univ] using (hι.elim' ·) rw [IsBlock.def_one] intro g rw [Set.smul_set_iInter] @@ -470,6 +486,110 @@ def block_stabilizerOrderIso [htGX : IsPretransitive G X] (a : X) : end Stabilizer +section Finite + +namespace IsBlock + +variable [IsPretransitive G X] {B : Set X} + +theorem ncard_block_eq_relindex (hB : IsBlock G B) {x : X} (hx : x ∈ B) : + B.ncard = (stabilizer G x).relindex (stabilizer G B) := by + have key : (stabilizer G x).subgroupOf (stabilizer G B) = stabilizer (stabilizer G B) x := by + ext; rfl + rw [Subgroup.relindex, key, index_stabilizer, hB.orbit_stabilizer_eq hx] + +/-- The cardinality of the ambient space is the product of the cardinality of a block + by the cardinality of the set of translates of that block -/ +theorem ncard_block_mul_ncard_orbit_eq (hB : IsBlock G B) (hB_ne : B.Nonempty) : + Set.ncard B * Set.ncard (orbit G B) = Nat.card X := by + obtain ⟨x, hx⟩ := hB_ne + rw [ncard_block_eq_relindex hB hx, ← index_stabilizer, + Subgroup.relindex_mul_index (hB.stabilizer_le hx), index_stabilizer_of_transitive] + +/-- The cardinality of a block divides the cardinality of the ambient type -/ +theorem ncard_dvd_card (hB : IsBlock G B) (hB_ne : B.Nonempty) : + Set.ncard B ∣ Nat.card X := + Dvd.intro _ (hB.ncard_block_mul_ncard_orbit_eq hB_ne) + +/-- A too large block is equal to `univ` -/ +theorem eq_univ_card_lt [hX : Finite X] (hB : IsBlock G B) (hB' : Nat.card X < Set.ncard B * 2) : + B = Set.univ := by + rcases Set.eq_empty_or_nonempty B with rfl | hB_ne + · simp only [Set.ncard_empty, zero_mul, not_lt_zero'] at hB' + have key := hB.ncard_block_mul_ncard_orbit_eq hB_ne + rw [← key, mul_lt_mul_iff_of_pos_left (by rwa [Set.ncard_pos])] at hB' + interval_cases (orbit G B).ncard + · rw [mul_zero, eq_comm, Nat.card_eq_zero, or_iff_left hX.not_infinite] at key + exact (IsEmpty.exists_iff.mp hB_ne).elim + · rw [mul_one, ← Set.ncard_univ] at key + rw [Set.eq_of_subset_of_ncard_le (Set.subset_univ B) key.ge] + +/-- If a block has too many translates, then it is a (sub)singleton -/ +theorem subsingleton_of_card_lt [Finite X] (hB : IsBlock G B) + (hB' : Nat.card X < 2 * Set.ncard (orbit G B)) : + B.Subsingleton := by + suffices Set.ncard B < 2 by + rw [Nat.lt_succ_iff, Set.ncard_le_one_iff_eq] at this + cases this with + | inl h => rw [h]; exact Set.subsingleton_empty + | inr h => + obtain ⟨a, ha⟩ := h; rw [ha]; exact Set.subsingleton_singleton + cases Set.eq_empty_or_nonempty B with + | inl h => rw [h, Set.ncard_empty]; norm_num + | inr h => + rw [← hB.ncard_block_mul_ncard_orbit_eq h, lt_iff_not_ge] at hB' + rw [← not_le] + exact fun hb ↦ hB' (Nat.mul_le_mul_right _ hb) + +/- The assumption `B.Finite` is necessary : + For G = ℤ acting on itself, a = 0 and B = ℕ, the translates `k • B` of the statement + are just `k + ℕ`, for `k ≤ 0`, and the corresponding intersection is `ℕ`, which is not a block. + (Remark by Thomas Browning) -/ +-- Note : add {B} because otherwise Lean includes `hB : IsBlock G B` +/-- The intersection of the translates of a *finite* subset which contain a given point +is a block (Wielandt, th. 7.3 )-/ +theorem of_subset {B : Set X} (a : X) (hfB : B.Finite) : + IsBlock G (⋂ (k : G) (_ : a ∈ k • B), k • B) := by + let B' := ⋂ (k : G) (_ : a ∈ k • B), k • B + cases' Set.eq_empty_or_nonempty B with hfB_e hfB_ne + · simp [hfB_e, isBlock_univ] + have hB'₀ : ∀ (k : G) (_ : a ∈ k • B), B' ≤ k • B := by + intro k hk + exact Set.biInter_subset_of_mem hk + have hfB' : B'.Finite := by + obtain ⟨b, hb : b ∈ B⟩ := hfB_ne + obtain ⟨k, hk : k • b = a⟩ := exists_smul_eq G b a + apply Set.Finite.subset (Set.Finite.map _ hfB) (hB'₀ k ⟨b, hb, hk⟩) + have hag : ∀ g : G, a ∈ g • B' → B' ≤ g • B' := by + intro g hg x hx + -- a = g • b; b ∈ B'; a ∈ k • B → b ∈ k • B + simp only [B', Set.mem_iInter, Set.mem_smul_set_iff_inv_smul_mem, + smul_smul, ← mul_inv_rev] at hg hx ⊢ + exact fun _ ↦ hx _ ∘ hg _ + have hag' (g : G) (hg : a ∈ g • B') : B' = g • B' := by + rw [eq_comm, ← mem_stabilizer_iff, mem_stabilizer_of_finite_iff_le_smul _ hfB'] + exact hag g hg + rw [mk_notempty_one] + intro g hg + rw [← Set.nonempty_iff_ne_empty] at hg + obtain ⟨b : X, hb' : b ∈ g • B', hb : b ∈ B'⟩ := Set.nonempty_def.mp hg + obtain ⟨k : G, hk : k • a = b⟩ := exists_smul_eq G a b + have hak : a ∈ k⁻¹ • B' := by + refine ⟨b, hb, ?_⟩ + simp only [← hk, inv_smul_smul] + have hagk : a ∈ (k⁻¹ * g) • B' := by + rw [mul_smul, Set.mem_smul_set_iff_inv_smul_mem, inv_inv, hk] + exact hb' + have hkB' : B' = k⁻¹ • B' := hag' k⁻¹ hak + have hgkB' : B' = (k⁻¹ * g) • B' := hag' (k⁻¹ * g) hagk + rw [mul_smul] at hgkB' + rw [← smul_eq_iff_eq_inv_smul] at hkB' hgkB' + rw [← hgkB', hkB'] + +end IsBlock + +end Finite + end Group end MulAction diff --git a/Mathlib/GroupTheory/Index.lean b/Mathlib/GroupTheory/Index.lean index 99284c35f6952b..977fdac89d1775 100644 --- a/Mathlib/GroupTheory/Index.lean +++ b/Mathlib/GroupTheory/Index.lean @@ -3,8 +3,9 @@ Copyright (c) 2021 Thomas Browning. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Thomas Browning -/ -import Mathlib.Data.Finite.Card import Mathlib.Algebra.BigOperators.GroupWithZero.Finset +import Mathlib.Data.Finite.Card +import Mathlib.Data.Set.Card import Mathlib.GroupTheory.Coset.Card import Mathlib.GroupTheory.Finiteness import Mathlib.GroupTheory.GroupAction.Quotient @@ -30,7 +31,7 @@ Several theorems proved in this file are known as Lagrange's theorem. - `relindex_mul_index` : If `H ≤ K`, then `H.relindex K * K.index = H.index` - `index_dvd_of_le` : If `H ≤ K`, then `K.index ∣ H.index` - `relindex_mul_relindex` : `relindex` is multiplicative in towers - +- `MulAction.index_stabilizer`: the index of the stabilizer is the cardinality of the orbit -/ @@ -558,6 +559,21 @@ end FiniteIndex end Subgroup +namespace MulAction + +variable (G : Type*) {X : Type*} [Group G] [MulAction G X] (x : X) + +theorem index_stabilizer : + (stabilizer G x).index = (orbit G x).ncard := + (Nat.card_congr (MulAction.orbitEquivQuotientStabilizer G x)).symm.trans + (Set.Nat.card_coe_set_eq (orbit G x)) + +theorem index_stabilizer_of_transitive [IsPretransitive G X] : + (stabilizer G x).index = Nat.card X := by + rw [index_stabilizer, orbit_eq_univ, Set.ncard_univ] + +end MulAction + namespace MonoidHom open Finset From 34de7267074d0f2532903e3e72770b04bfa15ae5 Mon Sep 17 00:00:00 2001 From: jouglasheen Date: Thu, 17 Oct 2024 20:35:01 +0000 Subject: [PATCH 344/425] feat: a nonarchimedean group is totally disconnected (#16687) Prove that a nonarchimedean group is a totally disconnected topological space. Co-authored-by: Kevin Buzzard Co-authored-by: jouglasheen <159258007+jouglasheen@users.noreply.github.com> --- Mathlib.lean | 1 + .../Nonarchimedean/TotallyDisconnected.lean | 60 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 Mathlib/Topology/Algebra/Nonarchimedean/TotallyDisconnected.lean diff --git a/Mathlib.lean b/Mathlib.lean index 91da140ade63cb..d7f45c26073284 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4555,6 +4555,7 @@ import Mathlib.Topology.Algebra.Nonarchimedean.AdicTopology import Mathlib.Topology.Algebra.Nonarchimedean.Bases import Mathlib.Topology.Algebra.Nonarchimedean.Basic import Mathlib.Topology.Algebra.Nonarchimedean.Completion +import Mathlib.Topology.Algebra.Nonarchimedean.TotallyDisconnected import Mathlib.Topology.Algebra.OpenSubgroup import Mathlib.Topology.Algebra.Order.Archimedean import Mathlib.Topology.Algebra.Order.Compact diff --git a/Mathlib/Topology/Algebra/Nonarchimedean/TotallyDisconnected.lean b/Mathlib/Topology/Algebra/Nonarchimedean/TotallyDisconnected.lean new file mode 100644 index 00000000000000..fd36afa2ef8c68 --- /dev/null +++ b/Mathlib/Topology/Algebra/Nonarchimedean/TotallyDisconnected.lean @@ -0,0 +1,60 @@ +/- +Copyright (c) 2024 Jou Glasheen. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jou Glasheen, Kevin Buzzard, David Loeffler, Yongle Hu, Johan Commelin +-/ + +import Mathlib.Topology.Algebra.Nonarchimedean.Basic + +/-! +# Total separatedness of nonarchimedean groups + +In this file, we prove that a nonarchimedean group is a totally separated topological space. +The fact that a nonarchimedean group is a totally disconnected topological space +is implied by the fact that a nonarchimedean group is totally separated. + +## Main results + +- `NonarchimedeanGroup.instTotallySeparated`: + A nonarchimedean group is a totally separated topological space. + +## Notation + + - `G` : Is a nonarchimedean group. + - `V` : Is an open subgroup which is a neighbourhood of the identity in `G`. + +## References + +See Proposition 2.3.9 and Problem 63 in [F. Q. Gouvêa, *p-adic numbers*][gouvea1997]. +-/ + +open Pointwise TopologicalSpace + +variable {G : Type*} [TopologicalSpace G] [Group G] [NonarchimedeanGroup G] [T2Space G] + +namespace NonarchimedeanGroup + +@[to_additive] +lemma exists_openSubgroup_separating {a b : G} (h : a ≠ b) : + ∃ (V : OpenSubgroup G), Disjoint (a • (V : Set G)) (b • V) := by + 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] + intros x mem_aV mem_bV + by_contra! con + obtain ⟨s, hs⟩ := con + have hsa : s ∈ a • (V : Set G) := mem_aV hs + have hsb : s ∈ b • (V : Set G) := mem_bV hs + rw [mem_leftCoset_iff] at hsa hsb + refine dis.subset_compl_right mem_u (hV ?_) + simpa [mul_assoc] using mul_mem hsa (inv_mem hsb) + +@[to_additive] +instance (priority := 100) instTotallySeparated : TotallySeparatedSpace G where + isTotallySeparated_univ x _ y _ hxy := by + obtain ⟨V, dxy⟩ := exists_openSubgroup_separating hxy + exact ⟨_, _, V.isOpen.smul x, (V.isClosed.smul x).isOpen_compl, mem_own_leftCoset .., + dxy.subset_compl_left <| mem_own_leftCoset .., by simp, disjoint_compl_right⟩ + +end NonarchimedeanGroup From 389e09795accaebbea904dccedfed6322feb5b86 Mon Sep 17 00:00:00 2001 From: Matthew Robert Ballard Date: Thu, 17 Oct 2024 20:59:58 +0000 Subject: [PATCH 345/425] chore(Algebra.Order.Monoid.TypeTags): split into unbundled and bundled ordered algebra (#16047) We move the unbundled ordered algebra results out of `Algebra.Order.Monoid.TypeTags` into `Algebra.Order.Monoid.Unbundled.TypeTags` to avoid importing bundled ordered algebra results unless necessary. --- Mathlib.lean | 1 + Mathlib/Algebra/Order/Monoid/ToMulBot.lean | 2 +- Mathlib/Algebra/Order/Monoid/TypeTags.lean | 104 +--------------- .../Order/Monoid/Unbundled/TypeTags.lean | 111 ++++++++++++++++++ Mathlib/Algebra/Order/SuccPred/TypeTags.lean | 2 +- 5 files changed, 116 insertions(+), 104 deletions(-) create mode 100644 Mathlib/Algebra/Order/Monoid/Unbundled/TypeTags.lean diff --git a/Mathlib.lean b/Mathlib.lean index d7f45c26073284..721ac852ea637d 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -653,6 +653,7 @@ import Mathlib.Algebra.Order.Monoid.Unbundled.ExistsOfLE import Mathlib.Algebra.Order.Monoid.Unbundled.MinMax import Mathlib.Algebra.Order.Monoid.Unbundled.OrderDual import Mathlib.Algebra.Order.Monoid.Unbundled.Pow +import Mathlib.Algebra.Order.Monoid.Unbundled.TypeTags import Mathlib.Algebra.Order.Monoid.Unbundled.WithTop import Mathlib.Algebra.Order.Monoid.Units import Mathlib.Algebra.Order.Monoid.WithTop diff --git a/Mathlib/Algebra/Order/Monoid/ToMulBot.lean b/Mathlib/Algebra/Order/Monoid/ToMulBot.lean index 96f8542fa024c2..ab578ee5f849e1 100644 --- a/Mathlib/Algebra/Order/Monoid/ToMulBot.lean +++ b/Mathlib/Algebra/Order/Monoid/ToMulBot.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Jeremy Avigad, Leonardo de Moura, Mario Carneiro, Johannes Hölzl -/ import Mathlib.Algebra.Order.GroupWithZero.Canonical -import Mathlib.Algebra.Order.Monoid.TypeTags +import Mathlib.Algebra.Order.Monoid.Unbundled.TypeTags import Mathlib.Algebra.Group.Equiv.Basic import Mathlib.Algebra.Order.Monoid.Unbundled.WithTop diff --git a/Mathlib/Algebra/Order/Monoid/TypeTags.lean b/Mathlib/Algebra/Order/Monoid/TypeTags.lean index c8a194531eb5bb..31b5a417097b5f 100644 --- a/Mathlib/Algebra/Order/Monoid/TypeTags.lean +++ b/Mathlib/Algebra/Order/Monoid/TypeTags.lean @@ -3,62 +3,13 @@ Copyright (c) 2016 Jeremy Avigad. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Jeremy Avigad, Leonardo de Moura, Mario Carneiro, Johannes Hölzl -/ -import Mathlib.Algebra.Group.TypeTags -import Mathlib.Algebra.Order.Monoid.Defs +import Mathlib.Algebra.Order.Monoid.Unbundled.TypeTags import Mathlib.Algebra.Order.Monoid.Canonical.Defs -/-! # Ordered monoid structures on `Multiplicative α` and `Additive α`. -/ +/-! # Bundled ordered monoid structures on `Multiplicative α` and `Additive α`. -/ variable {α : Type*} -instance : ∀ [LE α], LE (Multiplicative α) := - fun {inst} => inst - -instance : ∀ [LE α], LE (Additive α) := - fun {inst} => inst - -instance : ∀ [LT α], LT (Multiplicative α) := - fun {inst} => inst - -instance : ∀ [LT α], LT (Additive α) := - fun {inst} => inst - -instance Multiplicative.preorder : ∀ [Preorder α], Preorder (Multiplicative α) := - fun {inst} => inst - -instance Additive.preorder : ∀ [Preorder α], Preorder (Additive α) := - fun {inst} => inst - -instance Multiplicative.partialOrder : ∀ [PartialOrder α], PartialOrder (Multiplicative α) := - fun {inst} => inst - -instance Additive.partialOrder : ∀ [PartialOrder α], PartialOrder (Additive α) := - fun {inst} => inst - -instance Multiplicative.linearOrder : ∀ [LinearOrder α], LinearOrder (Multiplicative α) := - fun {inst} => inst - -instance Additive.linearOrder : ∀ [LinearOrder α], LinearOrder (Additive α) := - fun {inst} => inst - -instance Multiplicative.orderBot [LE α] : ∀ [OrderBot α], OrderBot (Multiplicative α) := - fun {inst} => inst - -instance Additive.orderBot [LE α] : ∀ [OrderBot α], OrderBot (Additive α) := - fun {inst} => inst - -instance Multiplicative.orderTop [LE α] : ∀ [OrderTop α], OrderTop (Multiplicative α) := - fun {inst} => inst - -instance Additive.orderTop [LE α] : ∀ [OrderTop α], OrderTop (Additive α) := - fun {inst} => inst - -instance Multiplicative.boundedOrder [LE α] : ∀ [BoundedOrder α], BoundedOrder (Multiplicative α) := - fun {inst} => inst - -instance Additive.boundedOrder [LE α] : ∀ [BoundedOrder α], BoundedOrder (Additive α) := - fun {inst} => inst - instance Multiplicative.orderedCommMonoid [OrderedAddCommMonoid α] : OrderedCommMonoid (Multiplicative α) := { Multiplicative.partialOrder, Multiplicative.commMonoid with @@ -87,13 +38,6 @@ instance Additive.linearOrderedAddCommMonoid [LinearOrderedCommMonoid α] : LinearOrderedAddCommMonoid (Additive α) := { Additive.linearOrder, Additive.orderedAddCommMonoid with } -instance Multiplicative.existsMulOfLe [Add α] [LE α] [ExistsAddOfLE α] : - ExistsMulOfLE (Multiplicative α) := - ⟨@exists_add_of_le α _ _ _⟩ - -instance Additive.existsAddOfLe [Mul α] [LE α] [ExistsMulOfLE α] : ExistsAddOfLE (Additive α) := - ⟨@exists_mul_of_le α _ _ _⟩ - instance Multiplicative.canonicallyOrderedCommMonoid [CanonicallyOrderedAddCommMonoid α] : CanonicallyOrderedCommMonoid (Multiplicative α) := { Multiplicative.orderedCommMonoid, Multiplicative.orderBot, @@ -112,47 +56,3 @@ instance Multiplicative.canonicallyLinearOrderedCommMonoid instance [CanonicallyLinearOrderedCommMonoid α] : CanonicallyLinearOrderedAddCommMonoid (Additive α) := { Additive.canonicallyOrderedAddCommMonoid, Additive.linearOrder with } - -namespace Additive - -variable [Preorder α] - -@[simp] -theorem ofMul_le {a b : α} : ofMul a ≤ ofMul b ↔ a ≤ b := - Iff.rfl - -@[simp] -theorem ofMul_lt {a b : α} : ofMul a < ofMul b ↔ a < b := - Iff.rfl - -@[simp] -theorem toMul_le {a b : Additive α} : toMul a ≤ toMul b ↔ a ≤ b := - Iff.rfl - -@[simp] -theorem toMul_lt {a b : Additive α} : toMul a < toMul b ↔ a < b := - Iff.rfl - -end Additive - -namespace Multiplicative - -variable [Preorder α] - -@[simp] -theorem ofAdd_le {a b : α} : ofAdd a ≤ ofAdd b ↔ a ≤ b := - Iff.rfl - -@[simp] -theorem ofAdd_lt {a b : α} : ofAdd a < ofAdd b ↔ a < b := - Iff.rfl - -@[simp] -theorem toAdd_le {a b : Multiplicative α} : toAdd a ≤ toAdd b ↔ a ≤ b := - Iff.rfl - -@[simp] -theorem toAdd_lt {a b : Multiplicative α} : toAdd a < toAdd b ↔ a < b := - Iff.rfl - -end Multiplicative diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/TypeTags.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/TypeTags.lean new file mode 100644 index 00000000000000..1647d43c6a4342 --- /dev/null +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/TypeTags.lean @@ -0,0 +1,111 @@ +/- +Copyright (c) 2016 Jeremy Avigad. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jeremy Avigad, Leonardo de Moura, Mario Carneiro, Johannes Hölzl +-/ +import Mathlib.Algebra.Group.TypeTags +import Mathlib.Algebra.Order.Monoid.Unbundled.ExistsOfLE +import Mathlib.Order.BoundedOrder + +/-! # Ordered monoid structures on `Multiplicative α` and `Additive α`. -/ + +variable {α : Type*} + +instance : ∀ [LE α], LE (Multiplicative α) := + fun {inst} => inst + +instance : ∀ [LE α], LE (Additive α) := + fun {inst} => inst + +instance : ∀ [LT α], LT (Multiplicative α) := + fun {inst} => inst + +instance : ∀ [LT α], LT (Additive α) := + fun {inst} => inst + +instance Multiplicative.preorder : ∀ [Preorder α], Preorder (Multiplicative α) := + fun {inst} => inst + +instance Additive.preorder : ∀ [Preorder α], Preorder (Additive α) := + fun {inst} => inst + +instance Multiplicative.partialOrder : ∀ [PartialOrder α], PartialOrder (Multiplicative α) := + fun {inst} => inst + +instance Additive.partialOrder : ∀ [PartialOrder α], PartialOrder (Additive α) := + fun {inst} => inst + +instance Multiplicative.linearOrder : ∀ [LinearOrder α], LinearOrder (Multiplicative α) := + fun {inst} => inst + +instance Additive.linearOrder : ∀ [LinearOrder α], LinearOrder (Additive α) := + fun {inst} => inst + +instance Multiplicative.orderBot [LE α] : ∀ [OrderBot α], OrderBot (Multiplicative α) := + fun {inst} => inst + +instance Additive.orderBot [LE α] : ∀ [OrderBot α], OrderBot (Additive α) := + fun {inst} => inst + +instance Multiplicative.orderTop [LE α] : ∀ [OrderTop α], OrderTop (Multiplicative α) := + fun {inst} => inst + +instance Additive.orderTop [LE α] : ∀ [OrderTop α], OrderTop (Additive α) := + fun {inst} => inst + +instance Multiplicative.boundedOrder [LE α] : ∀ [BoundedOrder α], BoundedOrder (Multiplicative α) := + fun {inst} => inst + +instance Additive.boundedOrder [LE α] : ∀ [BoundedOrder α], BoundedOrder (Additive α) := + fun {inst} => inst + +instance Multiplicative.existsMulOfLe [Add α] [LE α] [ExistsAddOfLE α] : + ExistsMulOfLE (Multiplicative α) := + ⟨@exists_add_of_le α _ _ _⟩ + +instance Additive.existsAddOfLe [Mul α] [LE α] [ExistsMulOfLE α] : ExistsAddOfLE (Additive α) := + ⟨@exists_mul_of_le α _ _ _⟩ + +namespace Additive + +variable [Preorder α] + +@[simp] +theorem ofMul_le {a b : α} : ofMul a ≤ ofMul b ↔ a ≤ b := + Iff.rfl + +@[simp] +theorem ofMul_lt {a b : α} : ofMul a < ofMul b ↔ a < b := + Iff.rfl + +@[simp] +theorem toMul_le {a b : Additive α} : toMul a ≤ toMul b ↔ a ≤ b := + Iff.rfl + +@[simp] +theorem toMul_lt {a b : Additive α} : toMul a < toMul b ↔ a < b := + Iff.rfl + +end Additive + +namespace Multiplicative + +variable [Preorder α] + +@[simp] +theorem ofAdd_le {a b : α} : ofAdd a ≤ ofAdd b ↔ a ≤ b := + Iff.rfl + +@[simp] +theorem ofAdd_lt {a b : α} : ofAdd a < ofAdd b ↔ a < b := + Iff.rfl + +@[simp] +theorem toAdd_le {a b : Multiplicative α} : toAdd a ≤ toAdd b ↔ a ≤ b := + Iff.rfl + +@[simp] +theorem toAdd_lt {a b : Multiplicative α} : toAdd a < toAdd b ↔ a < b := + Iff.rfl + +end Multiplicative diff --git a/Mathlib/Algebra/Order/SuccPred/TypeTags.lean b/Mathlib/Algebra/Order/SuccPred/TypeTags.lean index 4293cd851694ae..7c69e6dc40162b 100644 --- a/Mathlib/Algebra/Order/SuccPred/TypeTags.lean +++ b/Mathlib/Algebra/Order/SuccPred/TypeTags.lean @@ -3,8 +3,8 @@ Copyright (c) 2024 Yakov Pechersky. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Yakov Pechersky -/ -import Mathlib.Algebra.Order.Monoid.TypeTags import Mathlib.Order.SuccPred.Archimedean +import Mathlib.Algebra.Order.Monoid.Unbundled.TypeTags /-! # Successor and predecessor on type tags From 23a1a4bd2117e0e4a6391122bcf08d7c2edf6008 Mon Sep 17 00:00:00 2001 From: Christian Merten Date: Thu, 17 Oct 2024 22:32:03 +0000 Subject: [PATCH 346/425] feat(AlgebraicGeometry): proper morphisms of schemes (#17863) We define proper morphisms of schemes and show standard stability properties. Partly from the valuative criterion project. Co-authored by: Andrew Yang --- Mathlib.lean | 1 + .../Morphisms/ClosedImmersion.lean | 14 ++++ .../Morphisms/FiniteType.lean | 3 + .../AlgebraicGeometry/Morphisms/Proper.lean | 69 +++++++++++++++++++ .../Morphisms/UniversallyClosed.lean | 12 +++- 5 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 Mathlib/AlgebraicGeometry/Morphisms/Proper.lean diff --git a/Mathlib.lean b/Mathlib.lean index 721ac852ea637d..6871945d645ea7 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -868,6 +868,7 @@ import Mathlib.AlgebraicGeometry.Morphisms.FiniteType import Mathlib.AlgebraicGeometry.Morphisms.IsIso import Mathlib.AlgebraicGeometry.Morphisms.OpenImmersion import Mathlib.AlgebraicGeometry.Morphisms.Preimmersion +import Mathlib.AlgebraicGeometry.Morphisms.Proper import Mathlib.AlgebraicGeometry.Morphisms.QuasiCompact import Mathlib.AlgebraicGeometry.Morphisms.QuasiSeparated import Mathlib.AlgebraicGeometry.Morphisms.RingHomProperties diff --git a/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean b/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean index c78e3b86d608da..932325058e4265 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean @@ -6,6 +6,7 @@ Authors: Amelia Livingston, Christian Merten, Jonas van der Schaaf import Mathlib.AlgebraicGeometry.Morphisms.Preimmersion import Mathlib.AlgebraicGeometry.Morphisms.QuasiSeparated import Mathlib.AlgebraicGeometry.Morphisms.RingHomProperties +import Mathlib.AlgebraicGeometry.Morphisms.FiniteType import Mathlib.AlgebraicGeometry.ResidueField import Mathlib.RingTheory.RingHom.Surjective @@ -269,4 +270,17 @@ lemma IsClosedImmersion.stableUnderBaseChange : exact ⟨inferInstance, RingHom.surjective_stableUnderBaseChange.pullback_fst_app_top _ RingHom.surjective_respectsIso f _ hsurj⟩ +/-- Closed immersions are locally of finite type. -/ +instance (priority := 900) {X Y : Scheme.{u}} (f : X ⟶ Y) [h : IsClosedImmersion f] : + LocallyOfFiniteType f := by + wlog hY : IsAffine Y + · rw [IsLocalAtTarget.iff_of_iSup_eq_top (P := @LocallyOfFiniteType) _ + (iSup_affineOpens_eq_top Y)] + intro U + have H : IsClosedImmersion (f ∣_ U) := IsLocalAtTarget.restrict h U + exact this _ U.2 + obtain ⟨_, hf⟩ := h.isAffine_surjective_of_isAffine + rw [HasRingHomProperty.iff_of_isAffine (P := @LocallyOfFiniteType)] + exact RingHom.FiniteType.of_surjective (Scheme.Hom.app f ⊤) hf + end AlgebraicGeometry diff --git a/Mathlib/AlgebraicGeometry/Morphisms/FiniteType.lean b/Mathlib/AlgebraicGeometry/Morphisms/FiniteType.lean index def22435c69c04..a5bbcc0abb5f23 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/FiniteType.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/FiniteType.lean @@ -59,6 +59,9 @@ theorem locallyOfFiniteType_of_comp {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) [LocallyOfFiniteType (f ≫ g)] : LocallyOfFiniteType f := HasRingHomProperty.of_comp (fun _ _ ↦ RingHom.FiniteType.of_comp_finiteType) ‹_› +instance : MorphismProperty.IsMultiplicative @LocallyOfFiniteType where + id_mem _ := inferInstance + open scoped TensorProduct in lemma locallyOfFiniteType_stableUnderBaseChange : MorphismProperty.StableUnderBaseChange @LocallyOfFiniteType := diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Proper.lean b/Mathlib/AlgebraicGeometry/Morphisms/Proper.lean new file mode 100644 index 00000000000000..b54565bfb3af81 --- /dev/null +++ b/Mathlib/AlgebraicGeometry/Morphisms/Proper.lean @@ -0,0 +1,69 @@ +/- +Copyright (c) 2024 Christian Merten, Andrew Yang. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Christian Merten, Andrew Yang +-/ +import Mathlib.AlgebraicGeometry.Morphisms.Separated +import Mathlib.AlgebraicGeometry.Morphisms.UniversallyClosed +import Mathlib.AlgebraicGeometry.Morphisms.FiniteType + +/-! + +# Proper morphisms + +A morphism of schemes is proper if it is separated, universally closed and (locally) of finite type. +Note that we don't require quasi-compact, since this is implied by universally closed (TODO). + +-/ + + +noncomputable section + +open CategoryTheory + +universe u + +namespace AlgebraicGeometry + +variable {X Y : Scheme.{u}} (f : X ⟶ Y) + +/-- A morphism is proper if it is separated, universally closed and locally of finite type. -/ +@[mk_iff] +class IsProper extends IsSeparated f, UniversallyClosed f, LocallyOfFiniteType f : Prop where + +lemma isProper_eq : @IsProper = + (@IsSeparated ⊓ @UniversallyClosed : MorphismProperty Scheme) ⊓ @LocallyOfFiniteType := by + ext X Y f + rw [isProper_iff, ← and_assoc] + rfl + +namespace IsProper + +instance : MorphismProperty.RespectsIso @IsProper := by + rw [isProper_eq] + infer_instance + +instance stableUnderComposition : MorphismProperty.IsStableUnderComposition @IsProper := by + rw [isProper_eq] + infer_instance + +instance : MorphismProperty.IsMultiplicative @IsProper := by + rw [isProper_eq] + infer_instance + +instance (priority := 900) [IsClosedImmersion f] : IsProper f where + +lemma stableUnderBaseChange : MorphismProperty.StableUnderBaseChange @IsProper := by + rw [isProper_eq] + exact MorphismProperty.StableUnderBaseChange.inf + (MorphismProperty.StableUnderBaseChange.inf + IsSeparated.stableUnderBaseChange universallyClosed_stableUnderBaseChange) + locallyOfFiniteType_stableUnderBaseChange + +instance : IsLocalAtTarget @IsProper := by + rw [isProper_eq] + infer_instance + +end IsProper + +end AlgebraicGeometry diff --git a/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean b/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean index 6a5489d9924768..166651638bcaa9 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/UniversallyClosed.lean @@ -3,7 +3,7 @@ Copyright (c) 2022 Andrew Yang. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Andrew Yang -/ -import Mathlib.AlgebraicGeometry.Morphisms.Constructors +import Mathlib.AlgebraicGeometry.Morphisms.ClosedImmersion import Mathlib.Topology.LocalAtTarget /-! @@ -40,6 +40,13 @@ class UniversallyClosed (f : X ⟶ Y) : Prop where theorem universallyClosed_eq : @UniversallyClosed = universally (topologically @IsClosedMap) := by ext X Y f; rw [universallyClosed_iff] +instance (priority := 900) [IsClosedImmersion f] : UniversallyClosed f := by + rw [universallyClosed_eq] + intro X' Y' i₁ i₂ f' hf + have hf' : IsClosedImmersion f' := + IsClosedImmersion.stableUnderBaseChange hf.flip inferInstance + exact hf'.base_closed.isClosedMap + theorem universallyClosed_respectsIso : RespectsIso @UniversallyClosed := universallyClosed_eq.symm ▸ universally_respectsIso (topologically @IsClosedMap) @@ -59,6 +66,9 @@ instance universallyClosedTypeComp {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) [hf : UniversallyClosed f] [hg : UniversallyClosed g] : UniversallyClosed (f ≫ g) := comp_mem _ _ _ hf hg +instance : MorphismProperty.IsMultiplicative @UniversallyClosed where + id_mem _ := inferInstance + instance universallyClosed_fst {X Y Z : Scheme} (f : X ⟶ Z) (g : Y ⟶ Z) [hg : UniversallyClosed g] : UniversallyClosed (pullback.fst f g) := universallyClosed_stableUnderBaseChange.fst f g hg From f1ebf24bc990d6d810d4780353eb74d9ecb39803 Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Fri, 18 Oct 2024 00:49:50 +0000 Subject: [PATCH 347/425] refactor: add `compactSpace_spectrum` and `spectrum_nonempty` fields to the `ContinuousFunctionalCalculus` (#17801) --- Mathlib/Algebra/Algebra/Quasispectrum.lean | 3 +++ .../Instances.lean | 1 + .../NonUnital.lean | 21 +++++++++++++------ .../ContinuousFunctionalCalculus/Order.lean | 12 +++++------ .../Restrict.lean | 10 +++++++++ .../ContinuousFunctionalCalculus/Unital.lean | 7 +++++++ .../ContinuousFunctionalCalculus/Rpow.lean | 8 ++++--- .../Matrix/HermitianFunctionalCalculus.lean | 5 +++++ 8 files changed, 51 insertions(+), 16 deletions(-) diff --git a/Mathlib/Algebra/Algebra/Quasispectrum.lean b/Mathlib/Algebra/Algebra/Quasispectrum.lean index 33a5807e877b82..e94372dc43fdc8 100644 --- a/Mathlib/Algebra/Algebra/Quasispectrum.lean +++ b/Mathlib/Algebra/Algebra/Quasispectrum.lean @@ -254,6 +254,9 @@ lemma quasispectrum.not_isUnit_mem (a : A) {r : R} (hr : ¬ IsUnit r) : r ∈ qu lemma quasispectrum.zero_mem [Nontrivial R] (a : A) : 0 ∈ quasispectrum R a := quasispectrum.not_isUnit_mem a <| by simp +theorem quasispectrum.nonempty [Nontrivial R] (a : A) : (quasispectrum R a).Nonempty := + Set.nonempty_of_mem <| quasispectrum.zero_mem R a + instance quasispectrum.instZero [Nontrivial R] (a : A) : Zero (quasispectrum R a) where zero := ⟨0, quasispectrum.zero_mem R a⟩ diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Instances.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Instances.lean index 50abcebd079d70..ea67a1f84c9708 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Instances.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Instances.lean @@ -155,6 +155,7 @@ instance IsStarNormal.instContinuousFunctionalCalculus {A : Type*} [NormedRing A [CStarRing A] [CompleteSpace A] [NormedAlgebra ℂ A] [StarModule ℂ A] : ContinuousFunctionalCalculus ℂ (IsStarNormal : A → Prop) where predicate_zero := isStarNormal_zero + spectrum_nonempty a _ := spectrum.nonempty a exists_cfc_of_predicate a ha := by refine ⟨(elementalStarAlgebra ℂ a).subtype.comp <| continuousFunctionalCalculus a, ?hom_closedEmbedding, ?hom_id, ?hom_map_spectrum, ?predicate_hom⟩ diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean index 361cdc8aefebc4..d4a2d892c661ea 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/NonUnital.lean @@ -73,11 +73,16 @@ class NonUnitalContinuousFunctionalCalculus (R : Type*) {A : Type*} (p : outPara [ContinuousStar R] [NonUnitalRing A] [StarRing A] [TopologicalSpace A] [Module R A] [IsScalarTower R A A] [SMulCommClass R A A] : Prop where predicate_zero : p 0 + [compactSpace_quasispectrum : ∀ a : A, CompactSpace (σₙ R a)] exists_cfc_of_predicate : ∀ a, p a → ∃ φ : C(σₙ R a, R)₀ →⋆ₙₐ[R] A, ClosedEmbedding φ ∧ φ ⟨(ContinuousMap.id R).restrict <| σₙ R a, rfl⟩ = a ∧ (∀ f, σₙ R (φ f) = Set.range f) ∧ ∀ f, p (φ f) --- TODO: try to unify with the unital version. The `ℝ≥0` case makes it tricky. +-- this instance should not be activated everywhere but it is useful when developing generic API +-- for the continuous functional calculus +scoped[NonUnitalContinuousFunctionalCalculus] +attribute [instance] NonUnitalContinuousFunctionalCalculus.compactSpace_quasispectrum + /-- A class guaranteeing that the non-unital continuous functional calculus is uniquely determined by the properties that it is a continuous non-unital star algebra homomorphism mapping the (restriction of) the identity to `a`. This is the necessary tool used to establish `cfcₙHom_comp` @@ -685,7 +690,10 @@ lemma cfcₙHom_of_cfcHom_map_quasispectrum {a : A} (ha : p a) : simp only [Set.mem_singleton_iff] at hx ⊢ rw [show x = 0 from Subtype.val_injective hx, map_zero] -variable [CompleteSpace R] [h_cpct : ∀ a : A, CompactSpace (spectrum R a)] +variable [CompleteSpace R] + +-- gives access to the `ContinuousFunctionalCalculus.compactSpace_spectrum` instance +open scoped ContinuousFunctionalCalculus lemma closedEmbedding_cfcₙHom_of_cfcHom {a : A} (ha : p a) : ClosedEmbedding (cfcₙHom_of_cfcHom R ha) := by @@ -709,6 +717,10 @@ lemma closedEmbedding_cfcₙHom_of_cfcHom {a : A} (ha : p a) : instance ContinuousFunctionalCalculus.toNonUnital : NonUnitalContinuousFunctionalCalculus R p where predicate_zero := cfc_predicate_zero R + compactSpace_quasispectrum a := by + have h_cpct : CompactSpace (spectrum R a) := inferInstance + simp only [← isCompact_iff_compactSpace, quasispectrum_eq_spectrum_union_zero] at h_cpct ⊢ + exact h_cpct |>.union isCompact_singleton exists_cfc_of_predicate _ ha := ⟨cfcₙHom_of_cfcHom R ha, closedEmbedding_cfcₙHom_of_cfcHom ha, @@ -716,12 +728,9 @@ instance ContinuousFunctionalCalculus.toNonUnital : NonUnitalContinuousFunctiona cfcₙHom_of_cfcHom_map_quasispectrum ha, fun _ ↦ cfcHom_predicate ha _⟩ +open scoped NonUnitalContinuousFunctionalCalculus in lemma cfcₙHom_eq_cfcₙHom_of_cfcHom [UniqueNonUnitalContinuousFunctionalCalculus R A] {a : A} (ha : p a) : cfcₙHom (R := R) ha = cfcₙHom_of_cfcHom R ha := by - have h_cpct' : CompactSpace (σₙ R a) := by - specialize h_cpct a - simp_rw [← isCompact_iff_compactSpace, quasispectrum_eq_spectrum_union_zero] at h_cpct ⊢ - exact h_cpct.union isCompact_singleton refine UniqueNonUnitalContinuousFunctionalCalculus.eq_of_continuous_of_map_id (σₙ R a) ?_ _ _ ?_ ?_ ?_ · simp diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Order.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Order.lean index 8536353d9475b4..10e0978f35a5c0 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Order.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Order.lean @@ -85,20 +85,20 @@ lemma cfc_nnreal_le_iff {A : Type*} [TopologicalSpace A] [Ring A] [StarRing A] [ rw [cfc_nnreal_eq_real, cfc_nnreal_eq_real, cfc_le_iff ..] simp [NNReal.coe_le_coe, ← ha_spec.image] +open ContinuousFunctionalCalculus in /-- In a unital `ℝ`-algebra `A` with a continuous functional calculus, an element `a : A` is larger than some `algebraMap ℝ A r` if and only if every element of the `ℝ`-spectrum is nonnegative. -/ lemma CFC.exists_pos_algebraMap_le_iff {A : Type*} [TopologicalSpace A] [Ring A] [StarRing A] - [PartialOrder A] [StarOrderedRing A] [Algebra ℝ A] [NonnegSpectrumClass ℝ A] + [PartialOrder A] [StarOrderedRing A] [Algebra ℝ A] [NonnegSpectrumClass ℝ A] [Nontrivial A] [ContinuousFunctionalCalculus ℝ (IsSelfAdjoint : A → Prop)] - {a : A} [CompactSpace (spectrum ℝ a)] - (h_non : (spectrum ℝ a).Nonempty) (ha : IsSelfAdjoint a := by cfc_tac) : + {a : A} (ha : IsSelfAdjoint a := by cfc_tac) : (∃ r > 0, algebraMap ℝ A r ≤ a) ↔ (∀ x ∈ spectrum ℝ a, 0 < x) := by have h_cpct : IsCompact (spectrum ℝ a) := isCompact_iff_compactSpace.mpr inferInstance simp_rw [algebraMap_le_iff_le_spectrum (a := a)] refine ⟨?_, fun h ↦ ?_⟩ · rintro ⟨r, hr, hr_le⟩ exact (hr.trans_le <| hr_le · ·) - · obtain ⟨r, hr, hr_min⟩ := h_cpct.exists_isMinOn h_non continuousOn_id + · obtain ⟨r, hr, hr_min⟩ := h_cpct.exists_isMinOn (spectrum_nonempty ℝ a ha) continuousOn_id exact ⟨r, h _ hr, hr_min⟩ section CStar_unital @@ -218,10 +218,8 @@ lemma CStarAlgebra.isUnit_of_le {a b : A} (h₀ : IsUnit a) (ha : 0 ≤ a := by rw [← spectrum.zero_not_mem_iff ℝ≥0] at h₀ ⊢ nontriviality A have hb := (show 0 ≤ a from ha).trans hab - have ha' := IsSelfAdjoint.of_nonneg ha |>.spectrum_nonempty - have hb' := IsSelfAdjoint.of_nonneg hb |>.spectrum_nonempty rw [zero_not_mem_iff, SpectrumRestricts.nnreal_lt_iff (.nnreal_of_nonneg ‹_›), - NNReal.coe_zero, ← CFC.exists_pos_algebraMap_le_iff ‹_›] at h₀ ⊢ + NNReal.coe_zero, ← CFC.exists_pos_algebraMap_le_iff] at h₀ ⊢ peel h₀ with r hr _ exact this.trans hab diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Restrict.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Restrict.lean index cf36028a7922ef..bb43228df3fdf2 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Restrict.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Restrict.lean @@ -98,6 +98,12 @@ protected theorem cfc (f : C(S, R)) (halg : IsUniformEmbedding (algebraMap R S)) (h : ∀ a, p a ↔ q a ∧ SpectrumRestricts a f) : ContinuousFunctionalCalculus R p where predicate_zero := h0 + spectrum_nonempty a ha := ((h a).mp ha).2.image ▸ + (ContinuousFunctionalCalculus.spectrum_nonempty a ((h a).mp ha).1 |>.image f) + compactSpace_spectrum a := by + have := ContinuousFunctionalCalculus.compactSpace_spectrum (R := S) a + rw [← isCompact_iff_compactSpace] at this ⊢ + simpa using halg.toClosedEmbedding.isCompact_preimage this exists_cfc_of_predicate a ha := by refine ⟨((h a).mp ha).2.starAlgHom (cfcHom ((h a).mp ha).1 (R := S)), ?hom_closedEmbedding, ?hom_id, ?hom_map_spectrum, ?predicate_hom⟩ @@ -235,6 +241,10 @@ protected theorem cfc (f : C(S, R)) (halg : IsUniformEmbedding (algebraMap R S)) (h : ∀ a, p a ↔ q a ∧ QuasispectrumRestricts a f) : NonUnitalContinuousFunctionalCalculus R p where predicate_zero := h0 + compactSpace_quasispectrum a := by + have := NonUnitalContinuousFunctionalCalculus.compactSpace_quasispectrum (R := S) a + rw [← isCompact_iff_compactSpace] at this ⊢ + simpa using halg.toClosedEmbedding.isCompact_preimage this exists_cfc_of_predicate a ha := by refine ⟨((h a).mp ha).2.nonUnitalStarAlgHom (cfcₙHom ((h a).mp ha).1 (R := S)), ?hom_closedEmbedding, ?hom_id, ?hom_map_spectrum, ?predicate_hom⟩ diff --git a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unital.lean b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unital.lean index 8b6473cba0de3e..29fa35441c9460 100644 --- a/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unital.lean +++ b/Mathlib/Analysis/CStarAlgebra/ContinuousFunctionalCalculus/Unital.lean @@ -162,10 +162,17 @@ class ContinuousFunctionalCalculus (R : Type*) {A : Type*} (p : outParam (A → [CommSemiring R] [StarRing R] [MetricSpace R] [TopologicalSemiring R] [ContinuousStar R] [Ring A] [StarRing A] [TopologicalSpace A] [Algebra R A] : Prop where predicate_zero : p 0 + [compactSpace_spectrum (a : A) : CompactSpace (spectrum R a)] + spectrum_nonempty [Nontrivial A] (a : A) (ha : p a) : (spectrum R a).Nonempty exists_cfc_of_predicate : ∀ a, p a → ∃ φ : C(spectrum R a, R) →⋆ₐ[R] A, ClosedEmbedding φ ∧ φ ((ContinuousMap.id R).restrict <| spectrum R a) = a ∧ (∀ f, spectrum R (φ f) = Set.range f) ∧ ∀ f, p (φ f) +-- this instance should not be activated everywhere but it is useful when developing generic API +-- for the continuous functional calculus +scoped[ContinuousFunctionalCalculus] +attribute [instance] ContinuousFunctionalCalculus.compactSpace_spectrum + /-- A class guaranteeing that the continuous functional calculus is uniquely determined by the properties that it is a continuous star algebra homomorphism mapping the (restriction of) the identity to `a`. This is the necessary tool used to establish `cfcHom_comp` and the more common diff --git a/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/Rpow.lean b/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/Rpow.lean index 9fcf8e77c60a6b..fda3885c78a009 100644 --- a/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/Rpow.lean +++ b/Mathlib/Analysis/SpecialFunctions/ContinuousFunctionalCalculus/Rpow.lean @@ -5,8 +5,8 @@ Authors: Frédéric Dupuis -/ import Mathlib.Analysis.SpecialFunctions.Pow.Real -import Mathlib.Analysis.Normed.Algebra.Spectrum import Mathlib.Analysis.CStarAlgebra.ContinuousFunctionalCalculus.NonUnital +import Mathlib.Analysis.SpecialFunctions.Pow.Continuity /-! # Real powers defined via the continuous functional calculus @@ -306,8 +306,10 @@ lemma rpow_intCast (a : Aˣ) (n : ℤ) (ha : (0 : A) ≤ a := by cfc_tac) : section unital_vs_nonunital -variable [∀ (a : A), CompactSpace (spectrum ℝ a)] - [UniqueNonUnitalContinuousFunctionalCalculus ℝ≥0 A] +variable [UniqueNonUnitalContinuousFunctionalCalculus ℝ≥0 A] + +-- provides instance `ContinuousFunctionalCalculus.compactSpace_spectrum` +open scoped ContinuousFunctionalCalculus lemma nnrpow_eq_rpow {a : A} {x : ℝ≥0} (hx : 0 < x) : a ^ x = a ^ (x : ℝ) := by rw [nnrpow_def (A := A), rpow_def, cfcₙ_eq_cfc] diff --git a/Mathlib/LinearAlgebra/Matrix/HermitianFunctionalCalculus.lean b/Mathlib/LinearAlgebra/Matrix/HermitianFunctionalCalculus.lean index ff884d2e289adb..5c9c8e57575415 100644 --- a/Mathlib/LinearAlgebra/Matrix/HermitianFunctionalCalculus.lean +++ b/Mathlib/LinearAlgebra/Matrix/HermitianFunctionalCalculus.lean @@ -135,6 +135,11 @@ instance instContinuousFunctionalCalculus : rw [star_eq_conjTranspose, diagonal_conjTranspose] congr! simp [Pi.star_def, Function.comp_def] + spectrum_nonempty a ha := by + obtain (h | h) := isEmpty_or_nonempty n + · obtain ⟨x, y, hxy⟩ := exists_pair_ne (Matrix n n 𝕜) + exact False.elim <| Matrix.of.symm.injective.ne hxy <| Subsingleton.elim _ _ + · exact eigenvalues_eq_spectrum_real ha ▸ Set.range_nonempty _ predicate_zero := .zero _ instance instUniqueContinuousFunctionalCalculus : From 99ae512ef571b5534a1e977e6763cab017a5355c Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Fri, 18 Oct 2024 12:13:10 +1100 Subject: [PATCH 348/425] cleanup imports --- Mathlib/Tactic/Says.lean | 1 - Mathlib/Tactic/Simps/Basic.lean | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Mathlib/Tactic/Says.lean b/Mathlib/Tactic/Says.lean index e2d5e9007ad3f9..ef529b606b0b6f 100644 --- a/Mathlib/Tactic/Says.lean +++ b/Mathlib/Tactic/Says.lean @@ -6,7 +6,6 @@ Authors: Kim Morrison import Mathlib.Init import Lean.Meta.Tactic.TryThis import Batteries.Linter.UnreachableTactic -import Batteries.Data.String.Basic import Qq.Match /-! diff --git a/Mathlib/Tactic/Simps/Basic.lean b/Mathlib/Tactic/Simps/Basic.lean index e247fa6ee04ce4..cd847797c5d2ec 100644 --- a/Mathlib/Tactic/Simps/Basic.lean +++ b/Mathlib/Tactic/Simps/Basic.lean @@ -5,7 +5,6 @@ Authors: Floris van Doorn -/ import Lean.Elab.Tactic.Simp import Lean.Elab.App -import Batteries.Data.String.Basic import Mathlib.Tactic.Simps.NotationClass import Mathlib.Lean.Expr.Basic @@ -487,8 +486,8 @@ This is checked by inspecting whether the first character of the remaining part We use this variant because the latter is often a different field with an auto-generated name. -/ -private def dropPrefixIfNotNumber? (s : String) (pre : Substring) : Option Substring := do - let ret ← Substring.dropPrefix? s pre +private def dropPrefixIfNotNumber? (s : String) (pre : String) : Option Substring := do + let ret ← s.dropPrefix? pre -- flag is true when the remaining part is nonempty and starts with a digit. let flag := ret.toString.data.head?.elim false Char.isDigit if flag then none else some ret From 3f9cdcd1db12e4b662c93305015ce28d909918d8 Mon Sep 17 00:00:00 2001 From: Moritz Firsching Date: Fri, 18 Oct 2024 01:51:14 +0000 Subject: [PATCH 349/425] feat(Tactic/Linter/Lint): improve `dupNamespace` linter (#17631) Refactor the the way the ids are extracted for the `dupNamespace` linter. We also extract this to a new file in anticipation of re-using that function in another linter. The new version finds auto-generated names, such as `to_additive` names, but ignores "internal" names. Like the previous linter, it also supports `export` and `alias`. Co-authored-by: adomani Co-authored-by: damiano Co-authored-by: Moritz Firsching --- Mathlib.lean | 1 + Mathlib/Tactic.lean | 1 + Mathlib/Tactic/DeclarationNames.lean | 45 ++++++++++++++++++++++++++++ Mathlib/Tactic/Linter/Lint.lean | 32 ++++++++------------ test/Lint.lean | 28 +++++++++++++++-- 5 files changed, 85 insertions(+), 22 deletions(-) create mode 100644 Mathlib/Tactic/DeclarationNames.lean diff --git a/Mathlib.lean b/Mathlib.lean index 6871945d645ea7..8963ee37e6ec3d 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4298,6 +4298,7 @@ import Mathlib.Tactic.Contrapose import Mathlib.Tactic.Conv import Mathlib.Tactic.Convert import Mathlib.Tactic.Core +import Mathlib.Tactic.DeclarationNames import Mathlib.Tactic.DefEqTransformations import Mathlib.Tactic.DeprecateMe import Mathlib.Tactic.DeriveFintype diff --git a/Mathlib/Tactic.lean b/Mathlib/Tactic.lean index c8d7b7ae274942..cd494193a67b40 100644 --- a/Mathlib/Tactic.lean +++ b/Mathlib/Tactic.lean @@ -62,6 +62,7 @@ import Mathlib.Tactic.Contrapose import Mathlib.Tactic.Conv import Mathlib.Tactic.Convert import Mathlib.Tactic.Core +import Mathlib.Tactic.DeclarationNames import Mathlib.Tactic.DefEqTransformations import Mathlib.Tactic.DeprecateMe import Mathlib.Tactic.DeriveFintype diff --git a/Mathlib/Tactic/DeclarationNames.lean b/Mathlib/Tactic/DeclarationNames.lean new file mode 100644 index 00000000000000..3003bab4db21d1 --- /dev/null +++ b/Mathlib/Tactic/DeclarationNames.lean @@ -0,0 +1,45 @@ +/- +Copyright (c) 2024 Moritz Firsching. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Damiano Testa, Moritz Firsching +-/ + +import Lean.DeclarationRange +import Lean.ResolveName + +/-! +This file contains functions that are used by multiple linters. +-/ + +open Lean Parser Elab Command Meta +namespace Mathlib.Linter + +/-- +If `pos` is a `String.Pos`, then `getNamesFrom pos` returns the array of identifiers +for the names of the declarations whose syntax begins in position at least `pos`. +-/ +def getNamesFrom {m} [Monad m] [MonadEnv m] [MonadFileMap m] (pos : String.Pos) : + m (Array Syntax) := do + let drs := declRangeExt.getState (← getEnv) + let fm ← getFileMap + let mut nms := #[] + for (nm, rgs) in drs do + if pos ≤ fm.ofPosition rgs.range.pos then + let ofPos1 := fm.ofPosition rgs.selectionRange.pos + let ofPos2 := fm.ofPosition rgs.selectionRange.endPos + nms := nms.push (mkIdentFrom (.ofRange ⟨ofPos1, ofPos2⟩) nm) + return nms + +/-- +If `stx` is a syntax node for an `export` statement, then `getAliasSyntax stx` returns the array of +identifiers with the "exported" names. +-/ +def getAliasSyntax {m} [Monad m] [MonadResolveName m] (stx : Syntax) : m (Array Syntax) := do + let mut aliases := #[] + if let `(export $_ ($ids*)) := stx then + let currNamespace ← getCurrNamespace + for idStx in ids do + let id := idStx.getId + aliases := aliases.push + (mkIdentFrom (.ofRange (idStx.raw.getRange?.getD default)) (currNamespace ++ id)) + return aliases diff --git a/Mathlib/Tactic/Linter/Lint.lean b/Mathlib/Tactic/Linter/Lint.lean index 4c0a8fb5df9a44..8641d3a70bb7d4 100644 --- a/Mathlib/Tactic/Linter/Lint.lean +++ b/Mathlib/Tactic/Linter/Lint.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Floris van Doorn -/ import Batteries.Tactic.Lint +import Mathlib.Tactic.DeclarationNames /-! # Linters for Mathlib @@ -77,29 +78,20 @@ namespace DupNamespaceLinter open Lean Parser Elab Command Meta -/-- `getIds stx` extracts the `declId` nodes from the `Syntax` `stx`. -If `stx` is an `alias` or an `export`, then it extracts an `ident`, instead of a `declId`. -/ -partial -def getIds : Syntax → Array Syntax - | .node _ `Batteries.Tactic.Alias.alias args => args[2:3] - | .node _ ``Lean.Parser.Command.export args => (args[3:4] : Array Syntax).map (·[0]) - | stx@(.node _ _ args) => - ((args.attach.map fun ⟨a, _⟩ ↦ getIds a).foldl (· ++ ·) #[stx]).filter (·.getKind == ``declId) - | _ => default - @[inherit_doc linter.dupNamespace] def dupNamespace : Linter where run := withSetOptionIn fun stx ↦ do if Linter.getLinterValue linter.dupNamespace (← getOptions) then - match getIds stx with - | #[id] => - let ns := (← getScope).currNamespace - let declName := ns ++ (if id.getKind == ``declId then id[0].getId else id.getId) - let nm := declName.components - let some (dup, _) := nm.zip (nm.tailD []) |>.find? fun (x, y) ↦ x == y - | return - Linter.logLint linter.dupNamespace id - m!"The namespace '{dup}' is duplicated in the declaration '{declName}'" - | _ => return + let mut aliases := #[] + if let some exp := stx.find? (·.isOfKind `Lean.Parser.Command.export) then + aliases ← getAliasSyntax exp + for id in (← getNamesFrom (stx.getPos?.getD default)) ++ aliases do + let declName := id.getId + if declName.hasMacroScopes 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}'" initialize addLinter dupNamespace diff --git a/test/Lint.lean b/test/Lint.lean index 25bf9c9147d13b..7f6b2c917ddfbf 100644 --- a/test/Lint.lean +++ b/test/Lint.lean @@ -7,6 +7,23 @@ import Mathlib.Order.SetNotation set_option linter.dupNamespace false +namespace termG +-- this creates a hygienic declaration starting with `termG.termG.«_@».test.Lint...` +-- and the linter ignores it +set_option linter.dupNamespace true in +local notation "G" => Unit + +/-- info: [termG, termG] -/ +#guard_msgs in +open Lean in +run_meta + let env ← getEnv + let consts := env.constants.toList.find? (·.1.getRoot == `termG) + let reps := (consts.map (·.1.components.take 2)).getD default + logInfo m!"{reps}" + guard (reps[0]! == reps[1]!) +end termG + /-- warning: The namespace 'add' is duplicated in the declaration 'add.add' note: this linter can be disabled with `set_option linter.dupNamespace false` @@ -25,8 +42,12 @@ note: this linter can be disabled with `set_option linter.dupNamespace false` set_option linter.dupNamespace true in def Foo.foo := True --- the `dupNamespace` linter does not notice that `to_additive` created `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` +-/ #guard_msgs in +set_option linter.dupNamespace true in @[to_additive] theorem add.mul : True := .intro -- However, the declaration `Foo.add.add` is present in the environment. @@ -52,10 +73,13 @@ namespace 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' +note: this linter can be disabled with `set_option linter.dupNamespace false` -/ #guard_msgs in set_option linter.dupNamespace true in -export Nat (add) +export Nat (add add_comm add) end add From 1814dc4dcc7a88545743b89f61260b1db6d9fd02 Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Fri, 18 Oct 2024 02:46:57 +0000 Subject: [PATCH 350/425] refactor(Equiv/Set): use `Disjoint` (#17880) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... instead of `s ∩ t ⊆ ∅` in `Equiv.Set.union`. Also add `simps` to `Equiv.Set.univ`. --- Mathlib/Data/Finset/Basic.lean | 2 +- Mathlib/Data/Set/Card.lean | 3 +-- Mathlib/GroupTheory/Perm/Finite.lean | 8 +++---- Mathlib/Logic/Equiv/Set.lean | 32 ++++++++++++--------------- Mathlib/SetTheory/Cardinal/Basic.lean | 2 +- 5 files changed, 21 insertions(+), 26 deletions(-) diff --git a/Mathlib/Data/Finset/Basic.lean b/Mathlib/Data/Finset/Basic.lean index f226586bced604..a94497b850efa5 100644 --- a/Mathlib/Data/Finset/Basic.lean +++ b/Mathlib/Data/Finset/Basic.lean @@ -3019,7 +3019,7 @@ open Finset /-- The disjoint union of finsets is a sum -/ def Finset.union (s t : Finset α) (h : Disjoint s t) : s ⊕ t ≃ (s ∪ t : Finset α) := - Equiv.Set.ofEq (coe_union _ _) |>.trans (Equiv.Set.union (disjoint_coe.mpr h).le_bot) |>.symm + Equiv.Set.ofEq (coe_union _ _) |>.trans (Equiv.Set.union (disjoint_coe.mpr h)) |>.symm @[simp] theorem Finset.union_symm_inl (h : Disjoint s t) (x : s) : diff --git a/Mathlib/Data/Set/Card.lean b/Mathlib/Data/Set/Card.lean index 57aba3430a7619..fa03f476c8309b 100644 --- a/Mathlib/Data/Set/Card.lean +++ b/Mathlib/Data/Set/Card.lean @@ -109,8 +109,7 @@ theorem encard_ne_zero : s.encard ≠ 0 ↔ s.Nonempty := by theorem encard_union_eq (h : Disjoint s t) : (s ∪ t).encard = s.encard + t.encard := by classical - have e := (Equiv.Set.union (by rwa [subset_empty_iff, ← disjoint_iff_inter_eq_empty])).symm - simp [encard, ← PartENat.card_congr e, PartENat.card_sum, PartENat.withTopEquiv] + simp [encard, PartENat.card_congr (Equiv.Set.union h), PartENat.card_sum, PartENat.withTopEquiv] theorem encard_insert_of_not_mem {a : α} (has : a ∉ s) : (insert a s).encard = s.encard + 1 := by rw [← union_singleton, encard_union_eq (by simpa), encard_singleton] diff --git a/Mathlib/GroupTheory/Perm/Finite.lean b/Mathlib/GroupTheory/Perm/Finite.lean index e7ead8ca2a46cd..8c9cb242cb255f 100644 --- a/Mathlib/GroupTheory/Perm/Finite.lean +++ b/Mathlib/GroupTheory/Perm/Finite.lean @@ -184,9 +184,9 @@ theorem Disjoint.isConj_mul [Finite α] {σ τ π ρ : Perm α} (hc1 : IsConj σ have hd2'' := disjoint_coe.2 (disjoint_iff_disjoint_support.1 hd2) refine isConj_of_support_equiv ?_ ?_ · refine - ((Equiv.Set.ofEq hd1').trans (Equiv.Set.union hd1''.le_bot)).trans + ((Equiv.Set.ofEq hd1').trans (Equiv.Set.union hd1'')).trans ((Equiv.sumCongr (subtypeEquiv f fun a => ?_) (subtypeEquiv g fun a => ?_)).trans - ((Equiv.Set.ofEq hd2').trans (Equiv.Set.union hd2''.le_bot)).symm) <;> + ((Equiv.Set.ofEq hd2').trans (Equiv.Set.union hd2'')).symm) <;> · simp only [Set.mem_image, toEmbedding_apply, exists_eq_right, support_conj, coe_map, apply_eq_iff_eq] · intro x hx @@ -195,7 +195,7 @@ theorem Disjoint.isConj_mul [Finite α] {σ τ π ρ : Perm α} (hc1 : IsConj σ rw [hd1', Set.mem_union] at hx cases' hx with hxσ hxτ · rw [mem_coe, mem_support] at hxσ - rw [Set.union_apply_left hd1''.le_bot _, Set.union_apply_left hd1''.le_bot _] + rw [Set.union_apply_left, Set.union_apply_left] · simp only [subtypeEquiv_apply, Perm.coe_mul, Sum.map_inl, comp_apply, Set.union_symm_apply_left, Subtype.coe_mk, apply_eq_iff_eq] have h := (hd2 (f x)).resolve_left ?_ @@ -206,7 +206,7 @@ theorem Disjoint.isConj_mul [Finite α] {σ τ π ρ : Perm α} (hc1 : IsConj σ · rwa [Subtype.coe_mk, Perm.mul_apply, (hd1 x).resolve_left hxσ, mem_coe, apply_mem_support, mem_support] · rw [mem_coe, ← apply_mem_support, mem_support] at hxτ - rw [Set.union_apply_right hd1''.le_bot _, Set.union_apply_right hd1''.le_bot _] + rw [Set.union_apply_right, Set.union_apply_right] · simp only [subtypeEquiv_apply, Perm.coe_mul, Sum.map_inr, comp_apply, Set.union_symm_apply_right, Subtype.coe_mk, apply_eq_iff_eq] have h := (hd2 (g (τ x))).resolve_right ?_ diff --git a/Mathlib/Logic/Equiv/Set.lean b/Mathlib/Logic/Equiv/Set.lean index fb24c904db0686..a734cb9993db06 100644 --- a/Mathlib/Logic/Equiv/Set.lean +++ b/Mathlib/Logic/Equiv/Set.lean @@ -174,8 +174,8 @@ def image {α β : Type*} (e : α ≃ β) (s : Set α) : namespace Set --- Porting note: Removed attribute @[simps apply symm_apply] /-- `univ α` is equivalent to `α`. -/ +@[simps apply symm_apply] protected def univ (α) : @univ α ≃ α := ⟨Subtype.val, fun a => ⟨a, trivial⟩, fun ⟨_, _⟩ => rfl, fun _ => rfl⟩ @@ -203,25 +203,25 @@ protected def union' {α} {s t : Set α} (p : α → Prop) [DecidablePred p] (hs rcases o with (⟨x, h⟩ | ⟨x, h⟩) <;> [simp [hs _ h]; simp [ht _ h]] /-- If sets `s` and `t` are disjoint, then `s ∪ t` is equivalent to `s ⊕ t`. -/ -protected def union {α} {s t : Set α} [DecidablePred fun x => x ∈ s] (H : s ∩ t ⊆ ∅) : +protected def union {α} {s t : Set α} [DecidablePred fun x => x ∈ s] (H : Disjoint s t) : (s ∪ t : Set α) ≃ s ⊕ t := - Set.union' (fun x => x ∈ s) (fun _ => id) fun _ xt xs => H ⟨xs, xt⟩ + Set.union' (fun x => x ∈ s) (fun _ => id) fun _ xt xs => Set.disjoint_left.mp H xs xt -theorem union_apply_left {α} {s t : Set α} [DecidablePred fun x => x ∈ s] (H : s ∩ t ⊆ ∅) +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 -theorem union_apply_right {α} {s t : Set α} [DecidablePred fun x => x ∈ s] (H : s ∩ t ⊆ ∅) +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 => H ⟨h, ha⟩ + dif_neg fun h => Set.disjoint_left.mp H h ha @[simp] -theorem union_symm_apply_left {α} {s t : Set α} [DecidablePred fun x => x ∈ s] (H : s ∩ t ⊆ ∅) +theorem union_symm_apply_left {α} {s t : Set α} [DecidablePred fun x => x ∈ s] (H : Disjoint s t) (a : s) : (Equiv.Set.union H).symm (Sum.inl a) = ⟨a, by simp⟩ := rfl @[simp] -theorem union_symm_apply_right {α} {s t : Set α} [DecidablePred fun x => x ∈ s] (H : s ∩ t ⊆ ∅) +theorem union_symm_apply_right {α} {s t : Set α} [DecidablePred fun x => x ∈ s] (H : Disjoint s t) (a : t) : (Equiv.Set.union H).symm (Sum.inr a) = ⟨a, by simp⟩ := rfl @@ -247,7 +247,7 @@ protected def insert {α} {s : Set.{u} α} [DecidablePred (· ∈ s)] {a : α} ( (insert a s : Set α) ≃ s ⊕ PUnit.{u + 1} := calc (insert a s : Set α) ≃ ↥(s ∪ {a}) := Equiv.Set.ofEq (by simp) - _ ≃ s ⊕ ({a} : Set α) := Equiv.Set.union fun x ⟨hx, _⟩ => by simp_all + _ ≃ s ⊕ ({a} : Set α) := Equiv.Set.union <| by simpa _ ≃ s ⊕ PUnit.{u + 1} := sumCongr (Equiv.refl _) (Equiv.Set.singleton _) @[simp] @@ -273,7 +273,7 @@ theorem insert_apply_right {α} {s : Set.{u} α} [DecidablePred (· ∈ s)] {a : /-- If `s : Set α` is a set with decidable membership, then `s ⊕ sᶜ` is equivalent to `α`. -/ protected def sumCompl {α} (s : Set α) [DecidablePred (· ∈ s)] : s ⊕ (sᶜ : Set α) ≃ α := calc - s ⊕ (sᶜ : Set α) ≃ ↥(s ∪ sᶜ) := (Equiv.Set.union (by simp [Set.ext_iff])).symm + s ⊕ (sᶜ : Set α) ≃ ↥(s ∪ sᶜ) := (Equiv.Set.union disjoint_compl_right).symm _ ≃ @univ α := Equiv.Set.ofEq (by simp) _ ≃ α := Equiv.Set.univ _ @@ -289,15 +289,11 @@ theorem sumCompl_apply_inr {α : Type u} (s : Set α) [DecidablePred (· ∈ s)] theorem sumCompl_symm_apply_of_mem {α : Type u} {s : Set α} [DecidablePred (· ∈ s)] {x : α} (hx : x ∈ s) : (Equiv.Set.sumCompl s).symm x = Sum.inl ⟨x, hx⟩ := by - have : ((⟨x, Or.inl hx⟩ : (s ∪ sᶜ : Set α)) : α) ∈ s := hx - rw [Equiv.Set.sumCompl] - simpa using Set.union_apply_left (by simp) this + simp [Equiv.Set.sumCompl, Equiv.Set.univ, union_apply_left, hx] theorem sumCompl_symm_apply_of_not_mem {α : Type u} {s : Set α} [DecidablePred (· ∈ s)] {x : α} (hx : x ∉ s) : (Equiv.Set.sumCompl s).symm x = Sum.inr ⟨x, hx⟩ := by - have : ((⟨x, Or.inr hx⟩ : (s ∪ sᶜ : Set α)) : α) ∈ sᶜ := hx - rw [Equiv.Set.sumCompl] - simpa using Set.union_apply_right (by simp) this + simp [Equiv.Set.sumCompl, Equiv.Set.univ, union_apply_right, hx] @[simp] theorem sumCompl_symm_apply {α : Type*} {s : Set α} [DecidablePred (· ∈ s)] {x : s} : @@ -315,7 +311,7 @@ protected def sumDiffSubset {α} {s t : Set α} (h : s ⊆ t) [DecidablePred (· s ⊕ (t \ s : Set α) ≃ t := calc s ⊕ (t \ s : Set α) ≃ (s ∪ t \ s : Set α) := - (Equiv.Set.union (by simp [inter_diff_self])).symm + (Equiv.Set.union disjoint_sdiff_self_right).symm _ ≃ t := Equiv.Set.ofEq (by simp [union_diff_self, union_eq_self_of_subset_left h]) @[simp] @@ -346,7 +342,7 @@ protected def unionSumInter {α : Type u} (s t : Set α) [DecidablePred (· ∈ (s ∪ t : Set α) ⊕ (s ∩ t : Set α) ≃ (s ∪ t \ s : Set α) ⊕ (s ∩ t : Set α) := by rw [union_diff_self] _ ≃ (s ⊕ (t \ s : Set α)) ⊕ (s ∩ t : Set α) := - sumCongr (Set.union <| subset_empty_iff.2 (inter_diff_self _ _)) (Equiv.refl _) + sumCongr (Set.union disjoint_sdiff_self_right) (Equiv.refl _) _ ≃ s ⊕ ((t \ s : Set α) ⊕ (s ∩ t : Set α)) := sumAssoc _ _ _ _ ≃ s ⊕ (t \ s ∪ s ∩ t : Set α) := sumCongr (Equiv.refl _) diff --git a/Mathlib/SetTheory/Cardinal/Basic.lean b/Mathlib/SetTheory/Cardinal/Basic.lean index 8c37e772ce499d..22ec5d425d8c17 100644 --- a/Mathlib/SetTheory/Cardinal/Basic.lean +++ b/Mathlib/SetTheory/Cardinal/Basic.lean @@ -1954,7 +1954,7 @@ theorem mk_union_le {α : Type u} (S T : Set α) : #(S ∪ T : Set α) ≤ #S + theorem mk_union_of_disjoint {α : Type u} {S T : Set α} (H : Disjoint S T) : #(S ∪ T : Set α) = #S + #T := by classical - exact Quot.sound ⟨Equiv.Set.union H.le_bot⟩ + exact Quot.sound ⟨Equiv.Set.union H⟩ theorem mk_insert {α : Type u} {s : Set α} {a : α} (h : a ∉ s) : #(insert a s : Set α) = #s + 1 := by From fb09b71265c60a58ebf2c1d4fd6b9477d4506d14 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Fri, 18 Oct 2024 03:51:31 +0000 Subject: [PATCH 351/425] chore: cleanup of pairwise imports (#17888) --- Mathlib/Data/Fin/Basic.lean | 3 +++ Mathlib/Data/List/OfFn.lean | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Mathlib/Data/Fin/Basic.lean b/Mathlib/Data/Fin/Basic.lean index 715342aa569631..5dbafff567583e 100644 --- a/Mathlib/Data/Fin/Basic.lean +++ b/Mathlib/Data/Fin/Basic.lean @@ -626,6 +626,9 @@ theorem leftInverse_cast (eq : n = m) : LeftInverse (cast eq.symm) (cast eq) := theorem rightInverse_cast (eq : n = m) : RightInverse (cast eq.symm) (cast eq) := fun _ => rfl +theorem cast_lt_cast (eq : n = m) {a b : Fin n} : cast eq a < cast eq b ↔ a < b := + Iff.rfl + theorem cast_le_cast (eq : n = m) {a b : Fin n} : cast eq a ≤ cast eq b ↔ a ≤ b := Iff.rfl diff --git a/Mathlib/Data/List/OfFn.lean b/Mathlib/Data/List/OfFn.lean index a3271be86ffd8e..27001ba3ea4b09 100644 --- a/Mathlib/Data/List/OfFn.lean +++ b/Mathlib/Data/List/OfFn.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Mario Carneiro -/ import Batteries.Data.List.OfFn -import Batteries.Data.List.Pairwise import Mathlib.Data.Fin.Tuple.Basic /-! @@ -178,8 +177,9 @@ theorem ofFn_fin_repeat {m} (a : Fin m → α) (n : ℕ) : @[simp] theorem pairwise_ofFn {R : α → α → Prop} {n} {f : Fin n → α} : (ofFn f).Pairwise R ↔ ∀ ⦃i j⦄, i < j → R (f i) (f j) := by - simp only [pairwise_iff_get, (Fin.rightInverse_cast (length_ofFn f)).surjective.forall, get_ofFn, - ← Fin.not_le, Fin.cast_le_cast] + simp only [pairwise_iff_getElem, length_ofFn, List.getElem_ofFn, + (Fin.rightInverse_cast (length_ofFn f)).surjective.forall, Fin.forall_iff, Fin.cast_mk, + Fin.mk_lt_mk, forall_comm (α := (_ : Prop)) (β := ℕ)] /-- Lists are equivalent to the sigma type of tuples of a given length. -/ @[simps] From 077e0efd658ccaa95474fb130feeded70c602f6a Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Fri, 18 Oct 2024 04:24:40 +0000 Subject: [PATCH 352/425] chore: move deprecated file Mathlib/Data/ByteArray into Mathlib/Deprecated (#17884) --- Mathlib.lean | 2 +- Mathlib/{Data => Deprecated}/ByteArray.lean | 0 scripts/noshake.json | 3 ++- 3 files changed, 3 insertions(+), 2 deletions(-) rename Mathlib/{Data => Deprecated}/ByteArray.lean (100%) diff --git a/Mathlib.lean b/Mathlib.lean index 8963ee37e6ec3d..9a66b6063fc594 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2145,7 +2145,6 @@ import Mathlib.Data.Bool.Count import Mathlib.Data.Bool.Set import Mathlib.Data.Bracket import Mathlib.Data.Bundle -import Mathlib.Data.ByteArray import Mathlib.Data.Char import Mathlib.Data.Complex.Abs import Mathlib.Data.Complex.Basic @@ -2670,6 +2669,7 @@ import Mathlib.Data.ZMod.Quotient import Mathlib.Data.ZMod.Units import Mathlib.Deprecated.AlgebraClasses import Mathlib.Deprecated.Aliases +import Mathlib.Deprecated.ByteArray import Mathlib.Deprecated.Combinator import Mathlib.Deprecated.Equiv import Mathlib.Deprecated.Group diff --git a/Mathlib/Data/ByteArray.lean b/Mathlib/Deprecated/ByteArray.lean similarity index 100% rename from Mathlib/Data/ByteArray.lean rename to Mathlib/Deprecated/ByteArray.lean diff --git a/scripts/noshake.json b/scripts/noshake.json index 681e7f87ee2b5b..3e93d378ca0e2f 100644 --- a/scripts/noshake.json +++ b/scripts/noshake.json @@ -344,14 +344,15 @@ "Mathlib.Lean.Meta": ["Batteries.Logic"], "Mathlib.Lean.Expr.ExtraRecognizers": ["Mathlib.Data.Set.Operations"], "Mathlib.Lean.Expr.Basic": ["Batteries.Logic"], - "Mathlib.Deprecated.NatLemmas": ["Batteries.Data.Nat.Lemmas", "Batteries.WF"], "Mathlib.GroupTheory.MonoidLocalization.Basic": ["Mathlib.Init.Data.Prod"], "Mathlib.Geometry.Manifold.Sheaf.Smooth": ["Mathlib.CategoryTheory.Sites.Whiskering"], "Mathlib.Geometry.Manifold.PoincareConjecture": ["Mathlib.AlgebraicTopology.FundamentalGroupoid.SimplyConnected", "Mathlib.Util.Superscript"], + "Mathlib.Deprecated.NatLemmas": ["Batteries.Data.Nat.Lemmas", "Batteries.WF"], "Mathlib.Deprecated.MinMax": ["Mathlib.Order.MinMax"], + "Mathlib.Deprecated.ByteArray": ["Batteries.Data.ByteSubarray"], "Mathlib.Data.Vector.Basic": ["Mathlib.Control.Applicative"], "Mathlib.Data.Set.Image": ["Batteries.Tactic.Congr"], "Mathlib.Data.Seq.Parallel": ["Mathlib.Init.Data.Prod"], From 1b9ced20cbaf344811df3cbe11b727d3989bf2e2 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Fri, 18 Oct 2024 04:24:41 +0000 Subject: [PATCH 353/425] chore: cleanup of imports involving List.count (#17885) --- Archive/MiuLanguage/DecisionNec.lean | 2 -- Mathlib/Combinatorics/Enumerative/DyckWord.lean | 1 - Mathlib/Data/List/Count.lean | 3 +-- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Archive/MiuLanguage/DecisionNec.lean b/Archive/MiuLanguage/DecisionNec.lean index 694b599ac899d5..3bd06ca5463c65 100644 --- a/Archive/MiuLanguage/DecisionNec.lean +++ b/Archive/MiuLanguage/DecisionNec.lean @@ -5,9 +5,7 @@ Authors: Gihan Marasingha -/ import Archive.MiuLanguage.Basic import Mathlib.Data.List.Basic -import Mathlib.Data.List.Count import Mathlib.Data.Nat.ModEq -import Mathlib.Tactic.Ring /-! # Decision procedure: necessary condition diff --git a/Mathlib/Combinatorics/Enumerative/DyckWord.lean b/Mathlib/Combinatorics/Enumerative/DyckWord.lean index cd58430af7c763..5924d03e54bd15 100644 --- a/Mathlib/Combinatorics/Enumerative/DyckWord.lean +++ b/Mathlib/Combinatorics/Enumerative/DyckWord.lean @@ -3,7 +3,6 @@ Copyright (c) 2024 Jeremy Tan. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Jeremy Tan -/ -import Batteries.Data.List.Count import Mathlib.Combinatorics.Enumerative.Catalan import Mathlib.Tactic.Positivity diff --git a/Mathlib/Data/List/Count.lean b/Mathlib/Data/List/Count.lean index 89475cec9fe1e4..13c127b563b2a9 100644 --- a/Mathlib/Data/List/Count.lean +++ b/Mathlib/Data/List/Count.lean @@ -10,8 +10,7 @@ import Mathlib.Tactic.Common # Counting in lists This file proves basic properties of `List.countP` and `List.count`, which count the number of -elements of a list satisfying a predicate and equal to a given element respectively. Their -definitions can be found in `Batteries.Data.List.Basic`. +elements of a list satisfying a predicate and equal to a given element respectively. -/ assert_not_exists Set.range From 4358f93967f3a6a35e2e299ff9de9e7007336549 Mon Sep 17 00:00:00 2001 From: Moritz Firsching Date: Fri, 18 Oct 2024 05:30:33 +0000 Subject: [PATCH 354/425] feat(NumberTheory/FermatNumber): fermatNumber n + 2 (#17659) We provide a simple non-linear recurrence relation for the Fermat numbers. Since this involves subtraction, both Nat and Int versions are given. Co-authored-by: Moritz Firsching --- Mathlib/NumberTheory/Fermat.lean | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/Mathlib/NumberTheory/Fermat.lean b/Mathlib/NumberTheory/Fermat.lean index 5fe9b6b32bc736..848dc49be4810f 100644 --- a/Mathlib/NumberTheory/Fermat.lean +++ b/Mathlib/NumberTheory/Fermat.lean @@ -8,6 +8,8 @@ import Mathlib.Algebra.Order.Ring.Basic import Mathlib.Algebra.Order.Star.Basic import Mathlib.Data.Nat.Prime.Defs import Mathlib.Tactic.Ring.RingNF +import Mathlib.Tactic.Linarith + /-! # Fermat numbers @@ -62,6 +64,32 @@ theorem fermatNumber_succ (n : ℕ) : fermatNumber (n + 1) = (fermatNumber n - 1 rw [fermatNumber, pow_succ, mul_comm, Nat.pow_mul'] rfl +theorem two_mul_fermatNumber_sub_one_sq_le_fermatNumber_sq (n : ℕ) : + 2 * (fermatNumber n - 1) ^ 2 ≤ (fermatNumber (n + 1)) ^ 2 := by + simp only [fermatNumber, add_tsub_cancel_right] + have : 0 ≤ 1 + 2 ^ (2 ^ n * 4) := le_add_left 0 (Nat.add 1 _) + ring_nf + linarith + +theorem fermatNumber_eq_fermatNumber_sq_sub_two_mul_fermatNumber_sub_one_sq (n : ℕ) : + fermatNumber (n + 2) = (fermatNumber (n + 1)) ^ 2 - 2 * (fermatNumber n - 1) ^ 2 := by + simp only [fermatNumber, add_sub_self_right] + rw [← add_sub_self_right (2 ^ 2 ^ (n + 2) + 1) <| 2 * 2 ^ 2 ^ (n + 1)] + ring_nf + +end Nat + +open Nat + +theorem Int.fermatNumber_eq_fermatNumber_sq_sub_two_mul_fermatNumber_sub_one_sq (n : ℕ) : + (fermatNumber (n + 2) : ℤ) = (fermatNumber (n + 1)) ^ 2 - 2 * (fermatNumber n - 1) ^ 2 := by + rw [Nat.fermatNumber_eq_fermatNumber_sq_sub_two_mul_fermatNumber_sub_one_sq, + Nat.cast_sub <| two_mul_fermatNumber_sub_one_sq_le_fermatNumber_sq n] + simp only [fermatNumber, push_cast, add_tsub_cancel_right] + +namespace Nat + +open Finset /-- **Goldbach's theorem** : no two distinct Fermat numbers share a common factor greater than one. @@ -78,4 +106,4 @@ theorem coprime_fermatNumber_fermatNumber {k n : ℕ} (h : k ≠ n) : refine ((dvd_prime prime_two).mp h_m).elim id (fun h_two ↦ ?_) exact ((odd_fermatNumber _).not_two_dvd_nat (h_two ▸ h_n)).elim - end Nat +end Nat From 7472f1890db5b5b49e613e429661187cdea7e662 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Fri, 18 Oct 2024 16:51:48 +1100 Subject: [PATCH 355/425] fix test --- test/Lint.lean | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/Lint.lean b/test/Lint.lean index a19190e5ec9d84..e851cbc66986b2 100644 --- a/test/Lint.lean +++ b/test/Lint.lean @@ -48,9 +48,6 @@ namespace 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' -note: this linter can be disabled with `set_option linter.dupNamespace false` -/ #guard_msgs in export Nat (add) From 5d0c5274420fa8a2989d403a5058acb316ab06e4 Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Fri, 18 Oct 2024 05:56:05 +0000 Subject: [PATCH 356/425] feat(PathConnected): review API, add missing lemmas (#17855) --- .../Complex/UpperHalfPlane/Topology.lean | 3 +- Mathlib/Analysis/Convex/Normed.lean | 2 +- Mathlib/Topology/Connected/PathConnected.lean | 204 +++++++++--------- 3 files changed, 103 insertions(+), 106 deletions(-) diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Topology.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Topology.lean index 3c32e2e099f233..caecc196aeb8d7 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Topology.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Topology.lean @@ -55,8 +55,7 @@ instance : T4Space ℍ := inferInstance instance : ContractibleSpace ℍ := (convex_halfspace_im_gt 0).contractibleSpace ⟨I, one_pos.trans_eq I_im.symm⟩ -instance : LocPathConnectedSpace ℍ := - locPathConnected_of_isOpen <| isOpen_lt continuous_const Complex.continuous_im +instance : LocPathConnectedSpace ℍ := openEmbedding_coe.locPathConnectedSpace instance : NoncompactSpace ℍ := by refine ⟨fun h => ?_⟩ diff --git a/Mathlib/Analysis/Convex/Normed.lean b/Mathlib/Analysis/Convex/Normed.lean index 235a27716dee47..fae3e58b55f18f 100644 --- a/Mathlib/Analysis/Convex/Normed.lean +++ b/Mathlib/Analysis/Convex/Normed.lean @@ -112,7 +112,7 @@ instance (priority := 100) NormedSpace.instPathConnectedSpace : PathConnectedSpa TopologicalAddGroup.pathConnectedSpace instance (priority := 100) NormedSpace.instLocPathConnectedSpace : LocPathConnectedSpace E := - locPathConnected_of_bases (fun _ => Metric.nhds_basis_ball) fun x r r_pos => + .of_bases (fun _ => Metric.nhds_basis_ball) fun x r r_pos => (convex_ball x r).isPathConnected <| by simp [r_pos] theorem Wbtw.dist_add_dist {x y z : P} (h : Wbtw ℝ x y z) : diff --git a/Mathlib/Topology/Connected/PathConnected.lean b/Mathlib/Topology/Connected/PathConnected.lean index 644fcb694b3a8d..e5798309d30d41 100644 --- a/Mathlib/Topology/Connected/PathConnected.lean +++ b/Mathlib/Topology/Connected/PathConnected.lean @@ -785,13 +785,35 @@ theorem Specializes.joinedIn (h : x ⤳ y) (hx : x ∈ F) (hy : y ∈ F) : Joine theorem Inseparable.joinedIn (h : Inseparable x y) (hx : x ∈ F) (hy : y ∈ F) : JoinedIn F x y := h.specializes.joinedIn hx hy -/-! ### Path component -/ +theorem JoinedIn.map_continuousOn (h : JoinedIn F x y) {f : X → Y} (hf : ContinuousOn f F) : + JoinedIn (f '' F) (f x) (f y) := + let ⟨γ, hγ⟩ := h + ⟨γ.map' <| hf.mono (range_subset_iff.mpr hγ), fun t ↦ mem_image_of_mem _ (hγ t)⟩ + +theorem JoinedIn.map (h : JoinedIn F x y) {f : X → Y} (hf : Continuous f) : + JoinedIn (f '' F) (f x) (f y) := + h.map_continuousOn hf.continuousOn + +theorem Inducing.joinedIn_image {f : X → Y} (hf : Inducing f) (hx : x ∈ F) (hy : y ∈ F) : + JoinedIn (f '' F) (f x) (f y) ↔ JoinedIn F x y := by + refine ⟨?_, (.map · hf.continuous)⟩ + rintro ⟨γ, hγ⟩ + choose γ' hγ'F hγ' using hγ + have h₀ : x ⤳ γ' 0 := by rw [← hf.specializes_iff, hγ', γ.source] + have h₁ : γ' 1 ⤳ y := by rw [← hf.specializes_iff, hγ', γ.target] + have h : JoinedIn F (γ' 0) (γ' 1) := by + refine ⟨⟨⟨γ', ?_⟩, rfl, rfl⟩, hγ'F⟩ + simpa only [hf.continuous_iff, comp_def, hγ'] using map_continuous γ + exact (h₀.joinedIn hx (hγ'F _)).trans <| h.trans <| h₁.joinedIn (hγ'F _) hy +/-! ### Path component -/ /-- The path component of `x` is the set of points that can be joined to `x`. -/ def pathComponent (x : X) := { y | Joined x y } +theorem mem_pathComponent_iff : x ∈ pathComponent y ↔ Joined y x := .rfl + @[simp] theorem mem_pathComponent_self (x : X) : x ∈ pathComponent x := Joined.refl x @@ -867,24 +889,16 @@ theorem IsPathConnected.image' (hF : IsPathConnected F) exact hf.mono (range_subset_iff.2 (hx y_in).somePath_mem) /-- If `f` is continuous and `F` is path-connected, so is `f(F)`. -/ -theorem IsPathConnected.image (hF : IsPathConnected F) {f : X → Y} - (hf : Continuous f) : IsPathConnected (f '' F) := hF.image' hf.continuousOn +theorem IsPathConnected.image (hF : IsPathConnected F) {f : X → Y} (hf : Continuous f) : + IsPathConnected (f '' F) := + hF.image' hf.continuousOn /-- If `f : X → Y` is a `Inducing`, `f(F)` is path-connected iff `F` is. -/ nonrec theorem Inducing.isPathConnected_iff {f : X → Y} (hf : Inducing f) : IsPathConnected F ↔ IsPathConnected (f '' F) := by - refine ⟨fun hF ↦ hF.image hf.continuous, fun hF ↦ ?_⟩ - simp? [isPathConnected_iff] at hF ⊢ says - simp only [isPathConnected_iff, image_nonempty, mem_image, forall_exists_index, - and_imp, forall_apply_eq_imp_iff₂] at hF ⊢ - refine ⟨hF.1, fun x hx y hy ↦ ?_⟩ - rcases hF.2 x hx y hy with ⟨γ, hγ⟩ - choose γ' hγ' hγγ' using hγ - have key₁ : Inseparable x (γ' 0) := by rw [← hf.inseparable_iff, hγγ' 0, γ.source] - have key₂ : Inseparable (γ' 1) y := by rw [← hf.inseparable_iff, hγγ' 1, γ.target] - refine key₁.joinedIn hx (hγ' 0) |>.trans ⟨⟨⟨γ', ?_⟩, rfl, rfl⟩, hγ'⟩ |>.trans - (key₂.joinedIn (hγ' 1) hy) - simpa [hf.continuous_iff] using γ.continuous.congr fun t ↦ (hγγ' t).symm + simp only [IsPathConnected, forall_mem_image, exists_mem_image] + refine exists_congr fun x ↦ and_congr_right fun hx ↦ forall₂_congr fun y hy ↦ ?_ + rw [hf.joinedIn_image hx hy] /-- If `h : X → Y` is a homeomorphism, `h(s)` is path-connected iff `s` is. -/ @[simp] @@ -922,10 +936,7 @@ theorem IsPathConnected.union {U V : Set X} (hU : IsPathConnected U) (hV : IsPat ambient type `U` (when `U` contains `W`). -/ theorem IsPathConnected.preimage_coe {U W : Set X} (hW : IsPathConnected W) (hWU : W ⊆ U) : IsPathConnected (((↑) : U → X) ⁻¹' W) := by - rcases hW with ⟨x, x_in, hx⟩ - use ⟨x, hWU x_in⟩, by simp [x_in] - rintro ⟨y, hyU⟩ hyW - exact ⟨(hx hyW).joined_subtype.somePath.map (continuous_inclusion hWU), by simp⟩ + rwa [inducing_subtype_val.isPathConnected_iff, Subtype.image_preimage_val, inter_eq_right.2 hWU] theorem IsPathConnected.exists_path_through_family {n : ℕ} {s : Set X} (h : IsPathConnected s) (p : Fin (n + 1) → X) (hp : ∀ i, p i ∈ s) : @@ -997,6 +1008,7 @@ theorem IsPathConnected.exists_path_through_family' {n : ℕ} /-- A topological space is path-connected if it is non-empty and every two points can be joined by a continuous path. -/ +@[mk_iff] class PathConnectedSpace (X : Type*) [TopologicalSpace X] : Prop where /-- A path-connected space must be nonempty. -/ nonempty : Nonempty X @@ -1025,31 +1037,12 @@ def somePath (x y : X) : Path x y := end PathConnectedSpace -theorem isPathConnected_iff_pathConnectedSpace : IsPathConnected F ↔ PathConnectedSpace F := by - rw [isPathConnected_iff] - constructor - · rintro ⟨⟨x, x_in⟩, h⟩ - refine ⟨⟨⟨x, x_in⟩⟩, ?_⟩ - rintro ⟨y, y_in⟩ ⟨z, z_in⟩ - have H := h y y_in z z_in - rwa [joinedIn_iff_joined y_in z_in] at H - · rintro ⟨⟨x, x_in⟩, H⟩ - refine ⟨⟨x, x_in⟩, fun y y_in z z_in => ?_⟩ - rw [joinedIn_iff_joined y_in z_in] - apply H - theorem pathConnectedSpace_iff_univ : PathConnectedSpace X ↔ IsPathConnected (univ : Set X) := by - constructor - · intro h - haveI := @PathConnectedSpace.nonempty X _ _ - inhabit X - refine ⟨default, mem_univ _, ?_⟩ - intros y _hy - simpa using PathConnectedSpace.joined default y - · intro h - have h' := h.joinedIn - cases' h with x h - exact ⟨⟨x⟩, by simpa using h'⟩ + simp [pathConnectedSpace_iff, isPathConnected_iff, nonempty_iff_univ_nonempty] + +theorem isPathConnected_iff_pathConnectedSpace : IsPathConnected F ↔ PathConnectedSpace F := by + rw [pathConnectedSpace_iff_univ, inducing_subtype_val.isPathConnected_iff, image_univ, + Subtype.range_val_subtype, setOf_mem_eq] theorem isPathConnected_univ [PathConnectedSpace X] : IsPathConnected (univ : Set X) := pathConnectedSpace_iff_univ.mp inferInstance @@ -1111,6 +1104,7 @@ end PathConnectedSpace /-! ### Locally path connected spaces -/ +section LocPathConnectedSpace /-- A topological space is locally path connected, at every point, path connected neighborhoods form a neighborhood basis. -/ @@ -1120,66 +1114,70 @@ class LocPathConnectedSpace (X : Type*) [TopologicalSpace X] : Prop where export LocPathConnectedSpace (path_connected_basis) -theorem locPathConnected_of_bases {p : ι → Prop} {s : X → ι → Set X} - (h : ∀ x, (𝓝 x).HasBasis p (s x)) (h' : ∀ x i, p i → IsPathConnected (s x i)) : - LocPathConnectedSpace X := by - constructor - intro x - apply (h x).to_hasBasis - · intro i pi - exact ⟨s x i, ⟨(h x).mem_of_mem pi, h' x i pi⟩, by rfl⟩ - · rintro U ⟨U_in, _hU⟩ - rcases (h x).mem_iff.mp U_in with ⟨i, pi, hi⟩ - tauto - -theorem pathConnectedSpace_iff_connectedSpace [LocPathConnectedSpace X] : - PathConnectedSpace X ↔ ConnectedSpace X := by - constructor - · intro h - infer_instance - · intro hX - rw [pathConnectedSpace_iff_eq] - use Classical.arbitrary X - refine IsClopen.eq_univ ⟨?_, ?_⟩ (by simp) - · rw [isClosed_iff_nhds] - intro y H - rcases (path_connected_basis y).ex_mem with ⟨U, ⟨U_in, hU⟩⟩ - rcases H U U_in with ⟨z, hz, hz'⟩ - exact (hU.joinedIn z hz y <| mem_of_mem_nhds U_in).joined.mem_pathComponent hz' - · rw [isOpen_iff_mem_nhds] - intro y y_in - rcases (path_connected_basis y).ex_mem with ⟨U, ⟨U_in, hU⟩⟩ - apply mem_of_superset U_in - rw [← pathComponent_congr y_in] - exact hU.subset_pathComponent (mem_of_mem_nhds U_in) - -theorem pathConnected_subset_basis [LocPathConnectedSpace X] {U : Set X} (h : IsOpen U) - (hx : x ∈ U) : (𝓝 x).HasBasis (fun s : Set X => s ∈ 𝓝 x ∧ IsPathConnected s ∧ s ⊆ U) id := +theorem LocPathConnectedSpace.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 + 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⟩ + +@[deprecated (since := "2024-10-16")] +alias locPathConnected_of_bases := LocPathConnectedSpace.of_bases + +variable [LocPathConnectedSpace X] + +/-- In a locally path connected space, each path component is an open set. -/ +protected theorem IsOpen.pathComponent (x : X) : IsOpen (pathComponent x) := by + rw [isOpen_iff_mem_nhds] + intro y hxy + rcases (path_connected_basis y).ex_mem with ⟨V, hVy, hVc⟩ + filter_upwards [hVy] with z hz + exact hxy.out.trans (hVc.joinedIn _ (mem_of_mem_nhds hVy) _ hz).joined + +/-- In a locally path connected space, each path component is a closed set. -/ +protected theorem IsClosed.pathComponent (x : X) : IsClosed (pathComponent x) := by + rw [← isOpen_compl_iff, isOpen_iff_mem_nhds] + intro y hxy + rcases (path_connected_basis y).ex_mem with ⟨V, hVy, hVc⟩ + filter_upwards [hVy] with z hz hxz + exact hxy <| hxz.trans (hVc.joinedIn _ hz _ (mem_of_mem_nhds hVy)).joined + +/-- In a locally path connected space, each path component is a clopen set. -/ +protected theorem IsClopen.pathComponent (x : X) : IsClopen (pathComponent x) := + ⟨.pathComponent x, .pathComponent x⟩ + +theorem pathConnectedSpace_iff_connectedSpace : PathConnectedSpace X ↔ ConnectedSpace X := by + refine ⟨fun _ ↦ inferInstance, fun h ↦ ⟨inferInstance, fun x y ↦ ?_⟩⟩ + rw [← mem_pathComponent_iff, (IsClopen.pathComponent _).eq_univ] <;> simp + +theorem pathComponent_eq_connectedComponent (x : X) : pathComponent x = connectedComponent x := + (pathComponent_subset_component x).antisymm <| + (IsClopen.pathComponent x).connectedComponent_subset (mem_pathComponent_self _) + +theorem pathConnected_subset_basis {U : Set X} (h : IsOpen U) (hx : x ∈ U) : + (𝓝 x).HasBasis (fun s : Set X => s ∈ 𝓝 x ∧ IsPathConnected s ∧ s ⊆ U) id := (path_connected_basis x).hasBasis_self_subset (IsOpen.mem_nhds h hx) -theorem locPathConnected_of_isOpen [LocPathConnectedSpace X] {U : Set X} (h : IsOpen U) : - LocPathConnectedSpace U := - ⟨by - rintro ⟨x, x_in⟩ - rw [nhds_subtype_eq_comap] - constructor - intro V - rw [(HasBasis.comap ((↑) : U → X) (pathConnected_subset_basis h x_in)).mem_iff] - constructor - · rintro ⟨W, ⟨W_in, hW, hWU⟩, hWV⟩ - exact ⟨Subtype.val ⁻¹' W, ⟨⟨preimage_mem_comap W_in, hW.preimage_coe hWU⟩, hWV⟩⟩ - · rintro ⟨W, ⟨W_in, hW⟩, hWV⟩ - refine - ⟨(↑) '' W, - ⟨Filter.image_coe_mem_of_mem_comap (IsOpen.mem_nhds h x_in) W_in, - hW.image continuous_subtype_val, Subtype.coe_image_subset U W⟩, - ?_⟩ - rintro x ⟨y, ⟨y_in, hy⟩⟩ - rw [← Subtype.coe_injective hy] - tauto⟩ - -theorem IsOpen.isConnected_iff_isPathConnected [LocPathConnectedSpace X] {U : Set X} - (U_op : IsOpen U) : IsPathConnected U ↔ IsConnected U := by +theorem OpenEmbedding.locPathConnectedSpace {e : Y → X} (he : OpenEmbedding e) : + LocPathConnectedSpace 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 := + (openEmbedding_subtype_val h).locPathConnectedSpace + +@[deprecated (since := "2024-10-17")] +alias locPathConnected_of_isOpen := IsOpen.locPathConnectedSpace + +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 := locPathConnected_of_isOpen U_op - exact pathConnectedSpace_iff_connectedSpace + haveI := U_op.locPathConnectedSpace + exact pathConnectedSpace_iff_connectedSpace.symm + +end LocPathConnectedSpace From 319d7a37f0e813c9603b8df05901330e49aaf0eb Mon Sep 17 00:00:00 2001 From: FR Date: Fri, 18 Oct 2024 06:38:39 +0000 Subject: [PATCH 357/425] chore: move `NNRat` APIs earlier (#17269) No need to import bundled ordered algebraic typeclasses in `ring` tactic now. --- Archive/Imo/Imo1998Q2.lean | 2 +- Archive/Imo/Imo2013Q1.lean | 7 ++- .../ContinuedFractions/ConvergentsEquiv.lean | 1 + Mathlib/Algebra/Field/Rat.lean | 52 +++++++++++++++++-- Mathlib/Algebra/Order/Field/Rat.lean | 22 -------- Mathlib/Algebra/Order/Module/Rat.lean | 1 + Mathlib/Algebra/Order/Star/Basic.lean | 4 +- Mathlib/Data/FP/Basic.lean | 2 +- Mathlib/Data/Finset/Density.lean | 1 + Mathlib/Data/NNRat/BigOperators.lean | 1 + Mathlib/Data/NNRat/Defs.lean | 11 +++- Mathlib/Data/NNRat/Lemmas.lean | 7 --- Mathlib/Data/Nat/BitIndices.lean | 6 +-- Mathlib/Data/Rat/Cast/Defs.lean | 7 +-- Mathlib/Data/Rat/Cast/Lemmas.lean | 2 +- Mathlib/Data/Rat/Cast/Order.lean | 2 +- Mathlib/Data/Rat/Star.lean | 4 +- Mathlib/Data/Real/Basic.lean | 1 + Mathlib/NumberTheory/Fermat.lean | 1 + Mathlib/Tactic/Polyrith.lean | 1 - Mathlib/Tactic/Ring/Basic.lean | 3 +- test/cancel_denoms.lean | 1 + test/linear_combination'.lean | 1 + test/linear_combination.lean | 1 + test/module.lean | 1 + test/ring.lean | 1 + 26 files changed, 88 insertions(+), 55 deletions(-) diff --git a/Archive/Imo/Imo1998Q2.lean b/Archive/Imo/Imo1998Q2.lean index 367aec35fd5fc4..db7ae353454968 100644 --- a/Archive/Imo/Imo1998Q2.lean +++ b/Archive/Imo/Imo1998Q2.lean @@ -5,7 +5,7 @@ Authors: Oliver Nash -/ import Mathlib.Algebra.Order.BigOperators.Group.Finset import Mathlib.Algebra.Order.Field.Basic -import Mathlib.Algebra.Ring.Int +import Mathlib.Algebra.Order.Field.Rat import Mathlib.GroupTheory.GroupAction.Ring import Mathlib.Tactic.NoncommRing import Mathlib.Tactic.Ring diff --git a/Archive/Imo/Imo2013Q1.lean b/Archive/Imo/Imo2013Q1.lean index 42b43f937926ce..295886d7e18ea2 100644 --- a/Archive/Imo/Imo2013Q1.lean +++ b/Archive/Imo/Imo2013Q1.lean @@ -3,12 +3,11 @@ Copyright (c) 2021 David Renshaw. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: David Renshaw -/ -import Mathlib.Algebra.BigOperators.Pi -import Mathlib.Algebra.Order.Ring.Abs -import Mathlib.Data.PNat.Basic -import Mathlib.Tactic.Ring +import Mathlib.Algebra.BigOperators.Group.Finset +import Mathlib.Algebra.Order.Field.Rat import Mathlib.Tactic.FieldSimp import Mathlib.Tactic.Positivity.Basic +import Mathlib.Tactic.Ring /-! # IMO 2013 Q1 diff --git a/Mathlib/Algebra/ContinuedFractions/ConvergentsEquiv.lean b/Mathlib/Algebra/ContinuedFractions/ConvergentsEquiv.lean index 99e76fa64a5f58..fa5e59f20d0ad2 100644 --- a/Mathlib/Algebra/ContinuedFractions/ConvergentsEquiv.lean +++ b/Mathlib/Algebra/ContinuedFractions/ConvergentsEquiv.lean @@ -3,6 +3,7 @@ Copyright (c) 2020 Kevin Kappelmann. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Kevin Kappelmann -/ +import Mathlib.Algebra.Order.Field.Defs import Mathlib.Algebra.ContinuedFractions.ContinuantsRecurrence import Mathlib.Algebra.ContinuedFractions.TerminatedStable import Mathlib.Tactic.FieldSimp diff --git a/Mathlib/Algebra/Field/Rat.lean b/Mathlib/Algebra/Field/Rat.lean index ee2d2e48680d13..ad60ac2ab4bb07 100644 --- a/Mathlib/Algebra/Field/Rat.lean +++ b/Mathlib/Algebra/Field/Rat.lean @@ -13,11 +13,6 @@ This file contains the field instance on the rational numbers. See note [foundational algebra order theory]. -## TODO - -Move the `Semifield ℚ≥0` instance here. This will involve proving it by hand rather than relying on -the `Nonneg` machinery. - ## Tags rat, rationals, field, ℚ, numerator, denominator, num, denom @@ -44,4 +39,51 @@ These also prevent non-computable instances being used to construct these instan instance instDivisionRing : DivisionRing ℚ := inferInstance +protected lemma inv_nonneg {a : ℚ} (ha : 0 ≤ a) : 0 ≤ a⁻¹ := by + rw [inv_def'] + exact divInt_nonneg (Int.ofNat_nonneg a.den) (num_nonneg.mpr ha) + +protected lemma div_nonneg {a b : ℚ} (ha : 0 ≤ a) (hb : 0 ≤ b) : 0 ≤ a / b := + mul_nonneg ha (Rat.inv_nonneg hb) + end Rat + +namespace NNRat + +instance instInv : Inv ℚ≥0 where + inv x := ⟨x⁻¹, Rat.inv_nonneg x.2⟩ + +instance instDiv : Div ℚ≥0 where + div x y := ⟨x / y, Rat.div_nonneg x.2 y.2⟩ + +@[simp, norm_cast] lemma coe_inv (q : ℚ≥0) : ((q⁻¹ : ℚ≥0) : ℚ) = (q : ℚ)⁻¹ := rfl +@[simp, norm_cast] lemma coe_div (p q : ℚ≥0) : ((p / q : ℚ≥0) : ℚ) = p / q := rfl + +lemma inv_def (q : ℚ≥0) : q⁻¹ = divNat q.den q.num := by ext; simp [Rat.inv_def', num_coe, den_coe] +lemma div_def (p q : ℚ≥0) : p / q = divNat (p.num * q.den) (p.den * q.num) := by + ext; simp [Rat.div_def', num_coe, den_coe] + +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_ofNat] + simpa using q.coprime_num_den.symm + +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 + +@[simp] +lemma num_div_den (q : ℚ≥0) : (q.num : ℚ≥0) / q.den = q := by + ext1 + rw [coe_div, coe_natCast, coe_natCast, num, ← Int.cast_natCast] + exact (cast_def _).symm + +instance instSemifield : Semifield ℚ≥0 where + __ := instNNRatCommSemiring + inv_zero := by ext; simp + mul_inv_cancel q h := by ext; simp [h] + nnratCast_def q := q.num_div_den.symm + nnqsmul q a := q * a + nnqsmul_def q a := rfl + +end NNRat diff --git a/Mathlib/Algebra/Order/Field/Rat.lean b/Mathlib/Algebra/Order/Field/Rat.lean index 228df54d19272a..7b6ba3bfd819a1 100644 --- a/Mathlib/Algebra/Order/Field/Rat.lean +++ b/Mathlib/Algebra/Order/Field/Rat.lean @@ -32,25 +32,3 @@ end Rat -- instances for performance deriving instance CanonicallyLinearOrderedSemifield, LinearOrderedSemifield, LinearOrderedCommGroupWithZero for NNRat - -/-! ### Miscellaneous lemmas -/ - -namespace NNRat - -@[simp, norm_cast] lemma coe_inv (q : ℚ≥0) : ((q⁻¹ : ℚ≥0) : ℚ) = (q : ℚ)⁻¹ := rfl -@[simp, norm_cast] lemma coe_div (p q : ℚ≥0) : ((p / q : ℚ≥0) : ℚ) = p / q := rfl - -lemma inv_def (q : ℚ≥0) : q⁻¹ = divNat q.den q.num := by ext; simp [Rat.inv_def', num_coe, den_coe] -lemma div_def (p q : ℚ≥0) : p / q = divNat (p.num * q.den) (p.den * q.num) := by - ext; simp [Rat.div_def', num_coe, den_coe] - -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_ofNat] - simpa using q.coprime_num_den.symm - -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 - -end NNRat diff --git a/Mathlib/Algebra/Order/Module/Rat.lean b/Mathlib/Algebra/Order/Module/Rat.lean index 288226c0069632..21b376b2c7771d 100644 --- a/Mathlib/Algebra/Order/Module/Rat.lean +++ b/Mathlib/Algebra/Order/Module/Rat.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Yaël Dillies -/ import Mathlib.Algebra.Order.Module.Defs +import Mathlib.Data.NNRat.Lemmas import Mathlib.Data.Rat.Cast.Order /-! diff --git a/Mathlib/Algebra/Order/Star/Basic.lean b/Mathlib/Algebra/Order/Star/Basic.lean index bcda0ea6851ab9..6370c2c91944e5 100644 --- a/Mathlib/Algebra/Order/Star/Basic.lean +++ b/Mathlib/Algebra/Order/Star/Basic.lean @@ -3,10 +3,10 @@ Copyright (c) 2023 Kim Morrison. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Kim Morrison -/ -import Mathlib.Algebra.Group.Submonoid.Operations +import Mathlib.Algebra.Order.Group.Defs +import Mathlib.Algebra.Order.Group.Nat import Mathlib.Algebra.Star.SelfAdjoint import Mathlib.Algebra.Star.StarRingHom -import Mathlib.Algebra.Regular.Basic import Mathlib.Tactic.ContinuousFunctionalCalculus /-! # Star ordered rings diff --git a/Mathlib/Data/FP/Basic.lean b/Mathlib/Data/FP/Basic.lean index c854edb12daef3..703af9e82aadb2 100644 --- a/Mathlib/Data/FP/Basic.lean +++ b/Mathlib/Data/FP/Basic.lean @@ -85,7 +85,7 @@ theorem Float.Zero.valid : ValidFinite emin 0 := ring_nf rw [mul_comm] assumption - le_trans C.precMax (Nat.le_mul_of_pos_left _ two_pos), + le_trans C.precMax (Nat.le_mul_of_pos_left _ Nat.zero_lt_two), by (rw [max_eq_right]; simp [sub_eq_add_neg, Int.ofNat_zero_le])⟩ @[nolint docBlame] diff --git a/Mathlib/Data/Finset/Density.lean b/Mathlib/Data/Finset/Density.lean index 002513c40e808f..08b5292155a45b 100644 --- a/Mathlib/Data/Finset/Density.lean +++ b/Mathlib/Data/Finset/Density.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Yaël Dillies -/ import Mathlib.Algebra.Order.Field.Basic +import Mathlib.Algebra.Order.Field.Rat import Mathlib.Data.Fintype.Card import Mathlib.Data.NNRat.Order import Mathlib.Data.Rat.Cast.CharZero diff --git a/Mathlib/Data/NNRat/BigOperators.lean b/Mathlib/Data/NNRat/BigOperators.lean index e49a23c8a08e61..755e9be98bc811 100644 --- a/Mathlib/Data/NNRat/BigOperators.lean +++ b/Mathlib/Data/NNRat/BigOperators.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Yaël Dillies, Bhavik Mehta -/ import Mathlib.Algebra.Order.BigOperators.Ring.Finset +import Mathlib.Algebra.Order.Ring.Rat import Mathlib.Data.NNRat.Defs /-! # Casting lemmas for non-negative rational numbers involving sums and products diff --git a/Mathlib/Data/NNRat/Defs.lean b/Mathlib/Data/NNRat/Defs.lean index 5bda9ba5b38260..3f411698b84cd9 100644 --- a/Mathlib/Data/NNRat/Defs.lean +++ b/Mathlib/Data/NNRat/Defs.lean @@ -14,7 +14,8 @@ import Mathlib.Algebra.Ring.Rat This file defines the nonnegative rationals as a subtype of `Rat` and provides its basic algebraic order structure. -Note that `NNRat` is not declared as a `Field` here. See `Data.NNRat.Lemmas` for that instance. +Note that `NNRat` is not declared as a `Semifield` here. See `Mathlib.Algebra.Field.Rat` for that +instance. We also define an instance `CanLift ℚ ℚ≥0`. This instance can be used by the `lift` tactic to replace `x : ℚ` and `hx : 0 ≤ x` in the proof context with `x : ℚ≥0` while replacing all occurrences @@ -63,8 +64,16 @@ namespace NNRat variable {p q : ℚ≥0} +instance instNontrivial : Nontrivial ℚ≥0 where exists_pair_ne := ⟨1, 0, by decide⟩ +instance instOrderBot : OrderBot ℚ≥0 where + bot := 0 + bot_le q := q.2 + @[simp] lemma val_eq_cast (q : ℚ≥0) : q.1 = q := rfl +instance instCharZero : CharZero ℚ≥0 where + cast_injective a b hab := by simpa using congr_arg num hab + instance canLift : CanLift ℚ ℚ≥0 (↑) fun q ↦ 0 ≤ q where prf q hq := ⟨⟨q, hq⟩, rfl⟩ diff --git a/Mathlib/Data/NNRat/Lemmas.lean b/Mathlib/Data/NNRat/Lemmas.lean index 4e1ee467939ebc..91aadd51015c42 100644 --- a/Mathlib/Data/NNRat/Lemmas.lean +++ b/Mathlib/Data/NNRat/Lemmas.lean @@ -61,13 +61,6 @@ namespace NNRat variable {p q : ℚ≥0} -@[simp] -lemma num_div_den (q : ℚ≥0) : (q.num : ℚ≥0) / q.den = q := by - ext : 1 - rw [coe_div, coe_natCast, coe_natCast, num, ← Int.cast_natCast, - Int.natAbs_of_nonneg (Rat.num_nonneg.2 q.cast_nonneg)] - exact Rat.num_div_den q - /-- A recursor for nonnegative rationals in terms of numerators and denominators. -/ protected def rec {α : ℚ≥0 → Sort*} (h : ∀ m n : ℕ, α (m / n)) (q : ℚ≥0) : α q := by rw [← num_div_den q]; apply h diff --git a/Mathlib/Data/Nat/BitIndices.lean b/Mathlib/Data/Nat/BitIndices.lean index 79bd2eb583ef4c..bd77462f100320 100644 --- a/Mathlib/Data/Nat/BitIndices.lean +++ b/Mathlib/Data/Nat/BitIndices.lean @@ -3,12 +3,12 @@ Copyright (c) 2024 Peter Nelson. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Peter Nelson -/ -import Mathlib.Data.List.Sort -import Mathlib.Data.Nat.Bitwise import Mathlib.Algebra.BigOperators.Ring.List import Mathlib.Algebra.Order.BigOperators.Group.List import Mathlib.Algebra.Order.Star.Basic -import Mathlib.Algebra.Order.Sub.Defs +import Mathlib.Algebra.Order.Sub.Basic +import Mathlib.Data.List.Sort +import Mathlib.Data.Nat.Bitwise /-! # Bit Indices diff --git a/Mathlib/Data/Rat/Cast/Defs.lean b/Mathlib/Data/Rat/Cast/Defs.lean index 739dbc17cb0ce9..5458a333b24685 100644 --- a/Mathlib/Data/Rat/Cast/Defs.lean +++ b/Mathlib/Data/Rat/Cast/Defs.lean @@ -3,13 +3,12 @@ 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 -/ +import Mathlib.Algebra.Field.Basic import Mathlib.Algebra.Field.Rat import Mathlib.Algebra.Group.Commute.Basic -import Mathlib.Algebra.GroupWithZero.Units.Lemmas -import Mathlib.Algebra.Order.Field.Rat import Mathlib.Data.Int.Cast.Lemmas -import Mathlib.Data.NNRat.Lemmas import Mathlib.Data.Rat.Lemmas +import Mathlib.Order.Nat /-! # Casts for Rational Numbers @@ -24,6 +23,8 @@ casting lemmas showing the well-behavedness of this injection. rat, rationals, field, ℚ, numerator, denominator, num, denom, cast, coercion, casting -/ +assert_not_exists OrderedAddCommMonoid + variable {F ι α β : Type*} namespace NNRat diff --git a/Mathlib/Data/Rat/Cast/Lemmas.lean b/Mathlib/Data/Rat/Cast/Lemmas.lean index 4089d6b56d2e41..f61ef4b4568241 100644 --- a/Mathlib/Data/Rat/Cast/Lemmas.lean +++ b/Mathlib/Data/Rat/Cast/Lemmas.lean @@ -3,7 +3,7 @@ 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 -/ -import Mathlib.Algebra.Field.Basic +import Mathlib.Algebra.Order.Nonneg.Field import Mathlib.Data.Rat.Cast.Defs import Mathlib.Tactic.Positivity.Basic diff --git a/Mathlib/Data/Rat/Cast/Order.lean b/Mathlib/Data/Rat/Cast/Order.lean index 2a1d627e9d6b0f..c85aa1ca681f0a 100644 --- a/Mathlib/Data/Rat/Cast/Order.lean +++ b/Mathlib/Data/Rat/Cast/Order.lean @@ -3,7 +3,7 @@ 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 -/ -import Mathlib.Algebra.Order.Ring.Rat +import Mathlib.Algebra.Order.Field.Rat import Mathlib.Data.Rat.Cast.CharZero import Mathlib.Tactic.Positivity.Core import Mathlib.Algebra.Order.Field.Basic diff --git a/Mathlib/Data/Rat/Star.lean b/Mathlib/Data/Rat/Star.lean index 8f4b38afcab0ef..1e69ef6c771368 100644 --- a/Mathlib/Data/Rat/Star.lean +++ b/Mathlib/Data/Rat/Star.lean @@ -4,10 +4,10 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Jireh Loreaux, Yaël Dillies -/ import Mathlib.Algebra.GroupWithZero.Commute +import Mathlib.Algebra.Order.Field.Rat +import Mathlib.Algebra.Order.Monoid.Submonoid import Mathlib.Algebra.Order.Ring.Abs import Mathlib.Algebra.Order.Star.Basic -import Mathlib.Data.NNRat.Lemmas -import Mathlib.Algebra.Order.Monoid.Submonoid import Mathlib.Tactic.FieldSimp /-! diff --git a/Mathlib/Data/Real/Basic.lean b/Mathlib/Data/Real/Basic.lean index 9efe0fb5d9ae33..3465de02f2a9ad 100644 --- a/Mathlib/Data/Real/Basic.lean +++ b/Mathlib/Data/Real/Basic.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Mario Carneiro, Floris van Doorn -/ import Mathlib.Algebra.Order.CauSeq.Completion +import Mathlib.Algebra.Order.Field.Rat /-! # Real numbers from Cauchy sequences diff --git a/Mathlib/NumberTheory/Fermat.lean b/Mathlib/NumberTheory/Fermat.lean index 848dc49be4810f..c90f62582cae85 100644 --- a/Mathlib/NumberTheory/Fermat.lean +++ b/Mathlib/NumberTheory/Fermat.lean @@ -5,6 +5,7 @@ Authors: Moritz Firsching -/ import Mathlib.Algebra.BigOperators.Group.Finset import Mathlib.Algebra.Order.Ring.Basic +import Mathlib.Algebra.Order.Ring.Nat import Mathlib.Algebra.Order.Star.Basic import Mathlib.Data.Nat.Prime.Defs import Mathlib.Tactic.Ring.RingNF diff --git a/Mathlib/Tactic/Polyrith.lean b/Mathlib/Tactic/Polyrith.lean index 1b3ef56ab08c83..b6da0ce70e38b3 100644 --- a/Mathlib/Tactic/Polyrith.lean +++ b/Mathlib/Tactic/Polyrith.lean @@ -3,7 +3,6 @@ Copyright (c) 2022 Dhruv Bhatia. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Dhruv Bhatia, Eric Wieser, Mario Carneiro -/ -import Mathlib.Algebra.Order.Field.Rat import Mathlib.Tactic.LinearCombination /-! diff --git a/Mathlib/Tactic/Ring/Basic.lean b/Mathlib/Tactic/Ring/Basic.lean index c5ac7fd426cd86..b25109521ba025 100644 --- a/Mathlib/Tactic/Ring/Basic.lean +++ b/Mathlib/Tactic/Ring/Basic.lean @@ -3,7 +3,6 @@ Copyright (c) 2018 Mario Carneiro. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Mario Carneiro, Aurélien Saue, Anne Baanen -/ -import Mathlib.Algebra.Order.Ring.Rat import Mathlib.Tactic.NormNum.Inv import Mathlib.Tactic.NormNum.Pow import Mathlib.Util.AtomM @@ -75,6 +74,8 @@ This feature wasn't needed yet, so it's not implemented yet. ring, semiring, exponent, power -/ +assert_not_exists OrderedAddCommMonoid + namespace Mathlib.Tactic namespace Ring diff --git a/test/cancel_denoms.lean b/test/cancel_denoms.lean index b717b67f56ee2a..4d1001ecbcd6e9 100644 --- a/test/cancel_denoms.lean +++ b/test/cancel_denoms.lean @@ -1,3 +1,4 @@ +import Mathlib.Algebra.Order.Field.Rat import Mathlib.Tactic.CancelDenoms import Mathlib.Tactic.Ring diff --git a/test/linear_combination'.lean b/test/linear_combination'.lean index 14516504da879a..36056748d622d1 100644 --- a/test/linear_combination'.lean +++ b/test/linear_combination'.lean @@ -1,3 +1,4 @@ +import Mathlib.Algebra.Order.Field.Defs import Mathlib.Tactic.LinearCombination' import Mathlib.Tactic.Linarith diff --git a/test/linear_combination.lean b/test/linear_combination.lean index 9f652a8186a635..6e8b23a79630f5 100644 --- a/test/linear_combination.lean +++ b/test/linear_combination.lean @@ -1,3 +1,4 @@ +import Mathlib.Algebra.Order.Field.Defs import Mathlib.Tactic.LinearCombination import Mathlib.Tactic.Linarith diff --git a/test/module.lean b/test/module.lean index ee59dd02d0d9fa..b3ec8f57b57893 100644 --- a/test/module.lean +++ b/test/module.lean @@ -3,6 +3,7 @@ Copyright (c) 2024 Heather Macbeth. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Heather Macbeth -/ +import Mathlib.Algebra.Order.Field.Defs import Mathlib.Tactic.FieldSimp import Mathlib.Tactic.LinearCombination import Mathlib.Tactic.Module diff --git a/test/ring.lean b/test/ring.lean index 5abd490bfa5003..ffdfe755e4decb 100644 --- a/test/ring.lean +++ b/test/ring.lean @@ -1,3 +1,4 @@ +import Mathlib.Algebra.Order.Field.Defs import Mathlib.Tactic.FieldSimp import Mathlib.Tactic.Ring From 9b16c5d7fb54a2f624ce50e9b4f9de1e2a26b963 Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Fri, 18 Oct 2024 07:23:26 +0000 Subject: [PATCH 358/425] chore(Topology/Algebra/Order): move 2 files (#17879) These two files don't deal with algebra (groups, monoids etc); move them to `Topology/Order` instead. --- Mathlib.lean | 4 ++-- Mathlib/Analysis/Calculus/LocalExtr/Rolle.lean | 2 +- Mathlib/Topology/MetricSpace/Bounded.lean | 2 +- Mathlib/Topology/MetricSpace/ProperSpace/Lemmas.lean | 2 +- Mathlib/Topology/{Algebra => }/Order/Compact.lean | 0 Mathlib/Topology/{Algebra => }/Order/Rolle.lean | 2 +- test/LibrarySearch/IsCompact.lean | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) rename Mathlib/Topology/{Algebra => }/Order/Compact.lean (100%) rename Mathlib/Topology/{Algebra => }/Order/Rolle.lean (98%) diff --git a/Mathlib.lean b/Mathlib.lean index 9a66b6063fc594..6b0d74489e5e71 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4561,12 +4561,10 @@ import Mathlib.Topology.Algebra.Nonarchimedean.Completion import Mathlib.Topology.Algebra.Nonarchimedean.TotallyDisconnected import Mathlib.Topology.Algebra.OpenSubgroup import Mathlib.Topology.Algebra.Order.Archimedean -import Mathlib.Topology.Algebra.Order.Compact import Mathlib.Topology.Algebra.Order.Field import Mathlib.Topology.Algebra.Order.Floor import Mathlib.Topology.Algebra.Order.Group import Mathlib.Topology.Algebra.Order.LiminfLimsup -import Mathlib.Topology.Algebra.Order.Rolle import Mathlib.Topology.Algebra.Order.UpperLower import Mathlib.Topology.Algebra.Polynomial import Mathlib.Topology.Algebra.PontryaginDual @@ -4823,6 +4821,7 @@ import Mathlib.Topology.Order.Bornology import Mathlib.Topology.Order.Bounded import Mathlib.Topology.Order.Category.AlexDisc import Mathlib.Topology.Order.Category.FrameAdjunction +import Mathlib.Topology.Order.Compact import Mathlib.Topology.Order.DenselyOrdered import Mathlib.Topology.Order.ExtendFrom import Mathlib.Topology.Order.ExtrClosure @@ -4846,6 +4845,7 @@ import Mathlib.Topology.Order.OrderClosed import Mathlib.Topology.Order.PartialSups import Mathlib.Topology.Order.Priestley import Mathlib.Topology.Order.ProjIcc +import Mathlib.Topology.Order.Rolle import Mathlib.Topology.Order.ScottTopology import Mathlib.Topology.Order.T5 import Mathlib.Topology.Order.UpperLowerSetTopology diff --git a/Mathlib/Analysis/Calculus/LocalExtr/Rolle.lean b/Mathlib/Analysis/Calculus/LocalExtr/Rolle.lean index bd4dace2f80942..ef3e8f191d3804 100644 --- a/Mathlib/Analysis/Calculus/LocalExtr/Rolle.lean +++ b/Mathlib/Analysis/Calculus/LocalExtr/Rolle.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Yury Kudryashov, Anatole Dedecker -/ import Mathlib.Analysis.Calculus.LocalExtr.Basic -import Mathlib.Topology.Algebra.Order.Rolle +import Mathlib.Topology.Order.Rolle /-! # Rolle's Theorem diff --git a/Mathlib/Topology/MetricSpace/Bounded.lean b/Mathlib/Topology/MetricSpace/Bounded.lean index 5ce1a3fd60a5eb..7bd2d18acad754 100644 --- a/Mathlib/Topology/MetricSpace/Bounded.lean +++ b/Mathlib/Topology/MetricSpace/Bounded.lean @@ -3,7 +3,7 @@ Copyright (c) 2015, 2017 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 -/ -import Mathlib.Topology.Algebra.Order.Compact +import Mathlib.Topology.Order.Compact import Mathlib.Topology.MetricSpace.ProperSpace import Mathlib.Topology.MetricSpace.Cauchy import Mathlib.Topology.EMetricSpace.Diam diff --git a/Mathlib/Topology/MetricSpace/ProperSpace/Lemmas.lean b/Mathlib/Topology/MetricSpace/ProperSpace/Lemmas.lean index d582d83e1a6e6b..f75b63205c5b66 100644 --- a/Mathlib/Topology/MetricSpace/ProperSpace/Lemmas.lean +++ b/Mathlib/Topology/MetricSpace/ProperSpace/Lemmas.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Sébastien Gouëzel -/ -import Mathlib.Topology.Algebra.Order.Compact +import Mathlib.Topology.Order.Compact import Mathlib.Topology.MetricSpace.ProperSpace import Mathlib.Topology.Order.IntermediateValue import Mathlib.Topology.Order.LocalExtr diff --git a/Mathlib/Topology/Algebra/Order/Compact.lean b/Mathlib/Topology/Order/Compact.lean similarity index 100% rename from Mathlib/Topology/Algebra/Order/Compact.lean rename to Mathlib/Topology/Order/Compact.lean diff --git a/Mathlib/Topology/Algebra/Order/Rolle.lean b/Mathlib/Topology/Order/Rolle.lean similarity index 98% rename from Mathlib/Topology/Algebra/Order/Rolle.lean rename to Mathlib/Topology/Order/Rolle.lean index 57a3118c4e740f..31fa140f80c8ac 100644 --- a/Mathlib/Topology/Algebra/Order/Rolle.lean +++ b/Mathlib/Topology/Order/Rolle.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Yury Kudryashov -/ import Mathlib.Topology.Order.ExtendFrom -import Mathlib.Topology.Algebra.Order.Compact +import Mathlib.Topology.Order.Compact import Mathlib.Topology.Order.LocalExtr import Mathlib.Topology.Order.T5 diff --git a/test/LibrarySearch/IsCompact.lean b/test/LibrarySearch/IsCompact.lean index 0428a0cc91ba1c..0ac0af98ca6a4c 100644 --- a/test/LibrarySearch/IsCompact.lean +++ b/test/LibrarySearch/IsCompact.lean @@ -1,5 +1,5 @@ import Mathlib.Topology.Instances.Real -import Mathlib.Topology.Algebra.Order.Compact +import Mathlib.Topology.Order.Compact -- TODO: uses sorry, but is hidden behind the `apply?` /-- warning: declaration uses 'sorry' -/ From 672f75b15914a0b4f9b9f6aa3108cb0950e1cf65 Mon Sep 17 00:00:00 2001 From: Jiang Jiedong Date: Fri, 18 Oct 2024 07:51:31 +0000 Subject: [PATCH 359/425] refactor: rename `IsLocalRingHom` to `IsLocalHom` (#17403) Replace the `IsLocalRingHom` with `IsLocalHom`. Add instances for `IsLocalHom` in `CommRingCat` to resolve the problem caused by #6045. For a more detailed explanation of the problem, see https://github.com/leanprover-community/mathlib4/pull/17403#issuecomment-2418322525. Further golf some proof related to `IsLocalHom` instance search. Co-authored-by: Jiang Jiedong <107380768+jjdishere@users.noreply.github.com> --- Mathlib/Algebra/Associated/Basic.lean | 2 +- .../Algebra/Category/Ring/Constructions.lean | 14 +++-- Mathlib/Algebra/Category/Ring/Instances.lean | 52 +++++++++++++--- Mathlib/Algebra/Group/Units/Equiv.lean | 8 ++- Mathlib/Algebra/Group/Units/Hom.lean | 59 ++++++++++++------- .../Algebra/GroupWithZero/Units/Lemmas.lean | 11 ++-- Mathlib/Algebra/Polynomial/Expand.lean | 7 ++- Mathlib/AlgebraicGeometry/AffineScheme.lean | 1 - .../GammaSpecAdjunction.lean | 2 - .../PrimeSpectrum/Basic.lean | 11 ++-- .../ProjectiveSpectrum/Scheme.lean | 2 +- Mathlib/AlgebraicGeometry/ResidueField.lean | 9 --- Mathlib/AlgebraicGeometry/Scheme.lean | 5 +- Mathlib/AlgebraicGeometry/Spec.lean | 6 +- Mathlib/AlgebraicGeometry/Stalk.lean | 14 ++--- Mathlib/AlgebraicGeometry/StructureSheaf.lean | 8 +-- Mathlib/FieldTheory/Separable.lean | 2 +- .../RingedSpace/LocallyRingedSpace.lean | 26 ++++---- .../LocallyRingedSpace/HasColimits.lean | 40 +++++++------ .../LocallyRingedSpace/ResidueField.lean | 11 ---- .../Geometry/RingedSpace/OpenImmersion.lean | 7 +-- .../LinearAlgebra/ExteriorAlgebra/Basic.lean | 8 ++- Mathlib/RingTheory/Henselian.lean | 9 ++- Mathlib/RingTheory/Ideal/Basic.lean | 2 +- .../LocalRing/ResidueField/Basic.lean | 27 +++++---- .../RingTheory/LocalRing/RingHom/Basic.lean | 47 ++++++++++----- Mathlib/RingTheory/Localization/AtPrime.lean | 10 +++- Mathlib/RingTheory/MvPowerSeries/Inverse.lean | 10 +++- Mathlib/RingTheory/PowerSeries/Inverse.lean | 10 +++- Mathlib/RingTheory/SurjectiveOnStalks.lean | 5 +- .../RingTheory/Valuation/ValExtension.lean | 10 +++- .../Valuation/ValuationSubring.lean | 2 +- 32 files changed, 269 insertions(+), 168 deletions(-) diff --git a/Mathlib/Algebra/Associated/Basic.lean b/Mathlib/Algebra/Associated/Basic.lean index a5cad90ce7c77e..503074287a0cc5 100644 --- a/Mathlib/Algebra/Associated/Basic.lean +++ b/Mathlib/Algebra/Associated/Basic.lean @@ -249,7 +249,7 @@ theorem Irreducible.dvd_comm [Monoid M] {p q : M} (hp : Irreducible p) (hq : Irr ⟨hp.dvd_symm hq, hq.dvd_symm hp⟩ theorem Irreducible.of_map {F : Type*} [Monoid M] [Monoid N] [FunLike F M N] [MonoidHomClass F M N] - {f : F} [IsLocalRingHom f] {x} (hfx : Irreducible (f x)) : Irreducible x := + {f : F} [IsLocalHom f] {x} (hfx : Irreducible (f x)) : Irreducible x := ⟨fun hu ↦ hfx.not_unit <| hu.map f, by rintro p q rfl exact (hfx.isUnit_or_isUnit <| map_mul f p q).imp (.of_map f _) (.of_map f _)⟩ diff --git a/Mathlib/Algebra/Category/Ring/Constructions.lean b/Mathlib/Algebra/Category/Ring/Constructions.lean index c2cc69f71a187a..d9bb67a3267cd2 100644 --- a/Mathlib/Algebra/Category/Ring/Constructions.lean +++ b/Mathlib/Algebra/Category/Ring/Constructions.lean @@ -224,7 +224,7 @@ def equalizerForkIsLimit : IsLimit (equalizerFork f g) := by · intro m hm exact RingHom.ext fun x => Subtype.ext <| ConcreteCategory.congr_hom hm x -instance : IsLocalRingHom (equalizerFork f g).ι := by +instance : IsLocalHom (equalizerFork f g).ι := by constructor rintro ⟨a, h₁ : _ = _⟩ (⟨⟨x, y, h₃, h₄⟩, rfl : x = _⟩ : IsUnit a) have : y ∈ RingHom.eqLocus f g := by @@ -234,8 +234,9 @@ instance : IsLocalRingHom (equalizerFork f g).ι := by rw [isUnit_iff_exists_inv] exact ⟨⟨y, this⟩, Subtype.eq h₃⟩ -instance equalizer_ι_isLocalRingHom (F : WalkingParallelPair ⥤ CommRingCat.{u}) : - IsLocalRingHom (limit.π F WalkingParallelPair.zero) := by +@[instance] +theorem equalizer_ι_isLocalHom (F : WalkingParallelPair ⥤ CommRingCat.{u}) : + IsLocalHom (limit.π F WalkingParallelPair.zero) := by have := limMap_π (diagramIsoParallelPair F).hom WalkingParallelPair.zero rw [← IsIso.comp_inv_eq] at this rw [← this] @@ -244,15 +245,18 @@ instance equalizer_ι_isLocalRingHom (F : WalkingParallelPair ⥤ CommRingCat.{u equalizerForkIsLimit (F.map WalkingParallelPairHom.left) (F.map WalkingParallelPairHom.right)⟩ WalkingParallelPair.zero] - change IsLocalRingHom ((lim.map _ ≫ _ ≫ (equalizerFork _ _).ι) ≫ _) + change IsLocalHom ((lim.map _ ≫ _ ≫ (equalizerFork _ _).ι) ≫ _) infer_instance +@[deprecated (since := "2024-10-10")] +alias equalizer_ι_isLocalRingHom := equalizer_ι_isLocalHom + open CategoryTheory.Limits.WalkingParallelPair Opposite open CategoryTheory.Limits.WalkingParallelPairHom instance equalizer_ι_is_local_ring_hom' (F : WalkingParallelPairᵒᵖ ⥤ CommRingCat.{u}) : - IsLocalRingHom (limit.π F (Opposite.op WalkingParallelPair.one)) := by + IsLocalHom (limit.π F (Opposite.op WalkingParallelPair.one)) := by have : _ = limit.π F (walkingParallelPairOpEquiv.functor.obj _) := (limit.isoLimitCone_inv_π ⟨_, IsLimit.whiskerEquivalence (limit.isLimit F) walkingParallelPairOpEquiv⟩ diff --git a/Mathlib/Algebra/Category/Ring/Instances.lean b/Mathlib/Algebra/Category/Ring/Instances.lean index fc588d27c82481..def5d4f5edf11c 100644 --- a/Mathlib/Algebra/Category/Ring/Instances.lean +++ b/Mathlib/Algebra/Category/Ring/Instances.lean @@ -11,6 +11,7 @@ import Mathlib.RingTheory.LocalRing.RingHom.Basic # Ring-theoretic results in terms of categorical languages -/ +universe u open CategoryTheory @@ -36,16 +37,53 @@ instance Localization.epi' {R : CommRingCat} (M : Submonoid R) : rcases R with ⟨α, str⟩ exact IsLocalization.epi M _ -instance CommRingCat.isLocalRingHom_comp {R S T : CommRingCat} (f : R ⟶ S) (g : S ⟶ T) - [IsLocalRingHom g] [IsLocalRingHom f] : IsLocalRingHom (f ≫ g) := - RingHom.isLocalRingHom_comp _ _ +/- +These three instances solve the issue where the `FunLike` instances provided by +`CommRingCat.instFunLike'`, `CommRingCat.instFunLike''`, and `CommRingCat.instFunLike'''` +are not syntactically equal to `CommRingCat.instFunLike` when applied to +objects of the form `CommRingCat.of R`. +To prevent infinite loops, the priority of these three instances must be set lower +than that of other instances. +-/ +instance (priority := 50) {R : Type*} [CommRing R] {S : CommRingCat} (f : CommRingCat.of R ⟶ S) + [IsLocalHom (R := CommRingCat.of R) f] : IsLocalHom f := + inferInstance + +instance (priority := 50) {R : CommRingCat} {S : Type*} [CommRing S] (f : R ⟶ CommRingCat.of S) + [IsLocalHom (S := CommRingCat.of S) f] : IsLocalHom f := + inferInstance + +instance (priority := 50) {R S : Type u} [CommRing R] [CommRing S] + (f : CommRingCat.of R ⟶ CommRingCat.of S) + [IsLocalHom (R := CommRingCat.of R) (S := CommRingCat.of S) f] : IsLocalHom f := + inferInstance + +-- This instance handles the coercion of a morphism into a real `RingHom`. +instance {R S : CommRingCat} (f : R ⟶ S) [IsLocalHom f] : + IsLocalHom (F := R →+* S) f := + inferInstance -theorem isLocalRingHom_of_iso {R S : CommRingCat} (f : R ≅ S) : IsLocalRingHom f.hom := +@[instance] +theorem CommRingCat.isLocalHom_comp {R S T : CommRingCat} (f : R ⟶ S) (g : S ⟶ T) + [IsLocalHom g] [IsLocalHom f] : IsLocalHom (f ≫ g) := + RingHom.isLocalHom_comp _ _ + +@[deprecated (since := "2024-10-10")] +alias CommRingCat.isLocalRingHom_comp := CommRingCat.isLocalHom_comp + +theorem isLocalHom_of_iso {R S : CommRingCat} (f : R ≅ S) : IsLocalHom f.hom := { map_nonunit := fun a ha => by convert f.inv.isUnit_map ha exact (RingHom.congr_fun f.hom_inv_id _).symm } +@[deprecated (since := "2024-10-10")] +alias isLocalRingHom_of_iso := isLocalHom_of_iso + -- see Note [lower instance priority] -instance (priority := 100) isLocalRingHom_of_isIso {R S : CommRingCat} (f : R ⟶ S) [IsIso f] : - IsLocalRingHom f := - isLocalRingHom_of_iso (asIso f) +@[instance 100] +theorem isLocalHom_of_isIso {R S : CommRingCat} (f : R ⟶ S) [IsIso f] : + IsLocalHom f := + isLocalHom_of_iso (asIso f) + +@[deprecated (since := "2024-10-10")] +alias isLocalRingHom_of_isIso := isLocalHom_of_isIso diff --git a/Mathlib/Algebra/Group/Units/Equiv.lean b/Mathlib/Algebra/Group/Units/Equiv.lean index 12d6fb5b2285c2..27f2a366dd06d7 100644 --- a/Mathlib/Algebra/Group/Units/Equiv.lean +++ b/Mathlib/Algebra/Group/Units/Equiv.lean @@ -193,9 +193,13 @@ theorem MulEquiv.inv_symm (G : Type*) [DivisionCommMonoid G] : (MulEquiv.inv G).symm = MulEquiv.inv G := rfl -instance isLocalRingHom_equiv [Monoid M] [Monoid N] [EquivLike F M N] - [MulEquivClass F M N] (f : F) : IsLocalRingHom f where +@[instance] +theorem isLocalHom_equiv [Monoid M] [Monoid N] [EquivLike F M N] + [MulEquivClass F M N] (f : F) : IsLocalHom f where map_nonunit a ha := by convert ha.map (f : M ≃* N).symm rw [MulEquiv.eq_symm_apply] rfl -- note to reviewers: ugly `rfl` + +@[deprecated (since := "2024-10-10")] +alias isLocalRingHom_equiv := isLocalHom_equiv diff --git a/Mathlib/Algebra/Group/Units/Hom.lean b/Mathlib/Algebra/Group/Units/Hom.lean index 844235b25ef68e..5a210213562a4d 100644 --- a/Mathlib/Algebra/Group/Units/Hom.lean +++ b/Mathlib/Algebra/Group/Units/Hom.lean @@ -17,7 +17,7 @@ also contains unrelated results about `Units` that depend on `MonoidHom`. * `Units.map`: Turn a homomorphism from `α` to `β` monoids into a homomorphism from `αˣ` to `βˣ`. * `MonoidHom.toHomUnits`: Turn a homomorphism from a group `α` to `β` into a homomorphism from `α` to `βˣ`. -* `IsLocalRingHom`: A predicate on monoid maps, requiring that it maps nonunits +* `IsLocalHom`: A predicate on monoid maps, requiring that it maps nonunits to nonunits. For local rings, this means that the image of the unique maximal ideal is again contained in the unique maximal ideal. This is developed earlier, and in the generality of monoids, as it allows its use in non-local-ring related contexts, but it does have the @@ -28,7 +28,7 @@ also contains unrelated results about `Units` that depend on `MonoidHom`. The results that don't mention homomorphisms should be proved (earlier?) in a different file and be used to golf the basic `Group` lemmas. -Add a `@[to_additive]` version of `IsLocalRingHom`. +Add a `@[to_additive]` version of `IsLocalHom`. -/ assert_not_exists MonoidWithZero @@ -179,7 +179,7 @@ theorem of_leftInverse [MonoidHomClass G N M] {f : F} {x : M} (g : G) (hfg : Function.LeftInverse g f) (h : IsUnit (f x)) : IsUnit x := by simpa only [hfg x] using h.map g -/-- Prefer `IsLocalRingHom.of_leftInverse`, but we can't get rid of this because of `ToAdditive`. -/ +/-- Prefer `IsLocalHom.of_leftInverse`, but we can't get rid of this because of `ToAdditive`. -/ @[to_additive] theorem _root_.isUnit_map_of_leftInverse [MonoidHomClass F M N] [MonoidHomClass G N M] {f : F} {x : M} (g : G) (hfg : Function.LeftInverse g f) : @@ -208,7 +208,7 @@ theorem liftRight_inv_mul (f : M →* N) (h : ∀ x, IsUnit (f x)) (x) : end Monoid end IsUnit -section IsLocalRingHom +section IsLocalHom variable {G R S T F : Type*} @@ -218,13 +218,16 @@ variable [Monoid R] [Monoid S] [Monoid T] [FunLike F R S] is a unit if `f a` is a unit for any `a`. See `LocalRing.local_hom_TFAE` for other equivalent definitions in the local ring case - from where this concept originates, but it is useful in other contexts, so we allow this generalisation in mathlib. -/ -class IsLocalRingHom (f : F) : Prop where - /-- A local ring homomorphism `f : R ⟶ S` will send nonunits of `R` to nonunits of `S`. -/ +class IsLocalHom (f : F) : Prop where + /-- A local homomorphism `f : R ⟶ S` will send nonunits of `R` to nonunits of `S`. -/ map_nonunit : ∀ a, IsUnit (f a) → IsUnit a +@[deprecated (since := "2024-10-10")] +alias IsLocalRingHom := IsLocalHom + @[simp] -theorem IsUnit.of_map (f : F) [IsLocalRingHom f] (a : R) (h : IsUnit (f a)) : IsUnit a := - IsLocalRingHom.map_nonunit a h +theorem IsUnit.of_map (f : F) [IsLocalHom f] (a : R) (h : IsUnit (f a)) : IsUnit a := + IsLocalHom.map_nonunit a h -- TODO : remove alias, change the parenthesis of `f` and `a` alias isUnit_of_map_unit := IsUnit.of_map @@ -232,24 +235,38 @@ alias isUnit_of_map_unit := IsUnit.of_map variable [MonoidHomClass F R S] @[simp] -theorem isUnit_map_iff (f : F) [IsLocalRingHom f] (a : R) : IsUnit (f a) ↔ IsUnit a := - ⟨IsLocalRingHom.map_nonunit a, IsUnit.map f⟩ +theorem isUnit_map_iff (f : F) [IsLocalHom f] (a : R) : IsUnit (f a) ↔ IsUnit a := + ⟨IsLocalHom.map_nonunit a, IsUnit.map f⟩ -theorem isLocalRingHom_of_leftInverse [FunLike G S R] [MonoidHomClass G S R] - {f : F} (g : G) (hfg : Function.LeftInverse g f) : IsLocalRingHom f where +theorem isLocalHom_of_leftInverse [FunLike G S R] [MonoidHomClass G S R] + {f : F} (g : G) (hfg : Function.LeftInverse g f) : IsLocalHom f where map_nonunit a ha := by rwa [isUnit_map_of_leftInverse g hfg] at ha -instance MonoidHom.isLocalRingHom_comp (g : S →* T) (f : R →* S) [IsLocalRingHom g] - [IsLocalRingHom f] : IsLocalRingHom (g.comp f) where - map_nonunit a := IsLocalRingHom.map_nonunit a ∘ IsLocalRingHom.map_nonunit (f := g) (f a) +@[deprecated (since := "2024-10-10")] +alias isLocalRingHom_of_leftInverse := isLocalHom_of_leftInverse + +@[instance] +theorem MonoidHom.isLocalHom_comp (g : S →* T) (f : R →* S) [IsLocalHom g] + [IsLocalHom f] : IsLocalHom (g.comp f) where + map_nonunit a := IsLocalHom.map_nonunit a ∘ IsLocalHom.map_nonunit (f := g) (f a) + +@[deprecated (since := "2024-10-10")] +alias MonoidHom.isLocalRingHom_comp := MonoidHom.isLocalHom_comp -- see note [lower instance priority] -instance (priority := 100) isLocalRingHom_toMonoidHom (f : F) [IsLocalRingHom f] : - IsLocalRingHom (f : R →* S) := - ⟨IsLocalRingHom.map_nonunit (f := f)⟩ +@[instance 100] +theorem isLocalHom_toMonoidHom (f : F) [IsLocalHom f] : + IsLocalHom (f : R →* S) := + ⟨IsLocalHom.map_nonunit (f := f)⟩ -theorem MonoidHom.isLocalRingHom_of_comp (f : R →* S) (g : S →* T) [IsLocalRingHom (g.comp f)] : - IsLocalRingHom f := +@[deprecated (since := "2024-10-10")] +alias isLocalRingHom_toMonoidHom := isLocalHom_toMonoidHom + +theorem MonoidHom.isLocalHom_of_comp (f : R →* S) (g : S →* T) [IsLocalHom (g.comp f)] : + IsLocalHom f := ⟨fun _ ha => (isUnit_map_iff (g.comp f) _).mp (ha.map g)⟩ -end IsLocalRingHom +@[deprecated (since := "2024-10-10")] +alias MonoidHom.isLocalRingHom_of_comp := MonoidHom.isLocalHom_of_comp + +end IsLocalHom diff --git a/Mathlib/Algebra/GroupWithZero/Units/Lemmas.lean b/Mathlib/Algebra/GroupWithZero/Units/Lemmas.lean index 407a0fb1b6c75b..2d5790637992e0 100644 --- a/Mathlib/Algebra/GroupWithZero/Units/Lemmas.lean +++ b/Mathlib/Algebra/GroupWithZero/Units/Lemmas.lean @@ -22,8 +22,8 @@ section Monoid variable [Monoid M] [GroupWithZero G₀] -lemma isLocalRingHom_of_exists_map_ne_one [FunLike F G₀ M] [MonoidHomClass F G₀ M] {f : F} - (hf : ∃ x : G₀, f x ≠ 1) : IsLocalRingHom f where +lemma isLocalHom_of_exists_map_ne_one [FunLike F G₀ M] [MonoidHomClass F G₀ M] {f : F} + (hf : ∃ x : G₀, f x ≠ 1) : IsLocalHom f where map_nonunit a h := by rcases eq_or_ne a 0 with (rfl | h) · obtain ⟨t, ht⟩ := hf @@ -33,9 +33,12 @@ lemma isLocalRingHom_of_exists_map_ne_one [FunLike F G₀ M] [MonoidHomClass F G exact (h.mul_right_cancel this).symm · exact ⟨⟨a, a⁻¹, mul_inv_cancel₀ h, inv_mul_cancel₀ h⟩, rfl⟩ +@[deprecated (since := "2024-10-10")] +alias isLocalRingHom_of_exists_map_ne_one := isLocalHom_of_exists_map_ne_one + instance [GroupWithZero G₀] [FunLike F G₀ M₀] [MonoidWithZeroHomClass F G₀ M₀] [Nontrivial M₀] - (f : F) : IsLocalRingHom f := - isLocalRingHom_of_exists_map_ne_one ⟨0, by simp⟩ + (f : F) : IsLocalHom f := + isLocalHom_of_exists_map_ne_one ⟨0, by simp⟩ end Monoid diff --git a/Mathlib/Algebra/Polynomial/Expand.lean b/Mathlib/Algebra/Polynomial/Expand.lean index ae212d4a084966..33ed390954f877 100644 --- a/Mathlib/Algebra/Polynomial/Expand.lean +++ b/Mathlib/Algebra/Polynomial/Expand.lean @@ -268,17 +268,20 @@ section IsDomain variable (R : Type u) [CommRing R] [IsDomain R] -theorem isLocalRingHom_expand {p : ℕ} (hp : 0 < p) : IsLocalRingHom (expand R p) := by +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 [hf2, isUnit_C] at hf1; rw [expand_eq_C hp] at hf2; rwa [hf2, isUnit_C] +@[deprecated (since := "2024-10-10")] +alias isLocalRingHom_expand := isLocalHom_expand + variable {R} theorem of_irreducible_expand {p : ℕ} (hp : p ≠ 0) {f : R[X]} (hf : Irreducible (expand R p f)) : Irreducible f := - let _ := isLocalRingHom_expand R hp.bot_lt + let _ := isLocalHom_expand R hp.bot_lt hf.of_map theorem of_irreducible_expand_pow {p : ℕ} (hp : p ≠ 0) {f : R[X]} {n : ℕ} : diff --git a/Mathlib/AlgebraicGeometry/AffineScheme.lean b/Mathlib/AlgebraicGeometry/AffineScheme.lean index 0859e4051faef8..74ea6759b202f6 100644 --- a/Mathlib/AlgebraicGeometry/AffineScheme.lean +++ b/Mathlib/AlgebraicGeometry/AffineScheme.lean @@ -288,7 +288,6 @@ lemma isoSpec_hom_base_apply (x : U) : (Iso.eq_comp_inv _).mpr (Scheme.Opens.germ_stalkIso_hom U (V := ⊤) x trivial), X.presheaf.germ_res_assoc, Spec.map_comp, Scheme.comp_base_apply] congr 1 - have := isLocalRingHom_of_isIso (U.stalkIso x).inv exact LocalRing.comap_closedPoint (U.stalkIso x).inv lemma isoSpec_inv_app_top : diff --git a/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean b/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean index bd775fd8d0f992..577af21ca59d10 100644 --- a/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean +++ b/Mathlib/AlgebraicGeometry/GammaSpecAdjunction.lean @@ -271,8 +271,6 @@ def identityToΓSpec : 𝟭 LocallyRingedSpace.{u} ⟶ Γ.rightOp ⋙ Spec.toLoc dsimp show PrimeSpectrum.comap (f.c.app (op ⊤)) (X.toΓSpecFun x) = Y.toΓSpecFun (f.base x) dsimp [toΓSpecFun] - -- TODO: this instance was found automatically before #6045 - have := @AlgebraicGeometry.LocallyRingedSpace.isLocalRingHomStalkMap X Y rw [← LocalRing.comap_closedPoint (f.stalkMap x), ← PrimeSpectrum.comap_comp_apply, ← PrimeSpectrum.comap_comp_apply] congr 2 diff --git a/Mathlib/AlgebraicGeometry/PrimeSpectrum/Basic.lean b/Mathlib/AlgebraicGeometry/PrimeSpectrum/Basic.lean index 26c8303a688160..05c884eb52c603 100644 --- a/Mathlib/AlgebraicGeometry/PrimeSpectrum/Basic.lean +++ b/Mathlib/AlgebraicGeometry/PrimeSpectrum/Basic.lean @@ -624,17 +624,20 @@ def closedPoint : PrimeSpectrum R := variable {R} -theorem isLocalRingHom_iff_comap_closedPoint {S : Type v} [CommSemiring S] [LocalRing S] - (f : R →+* S) : IsLocalRingHom f ↔ PrimeSpectrum.comap f (closedPoint S) = closedPoint R := by +theorem isLocalHom_iff_comap_closedPoint {S : Type v} [CommSemiring S] [LocalRing S] + (f : R →+* S) : IsLocalHom f ↔ PrimeSpectrum.comap f (closedPoint S) = closedPoint R := by -- Porting note: inline `this` does **not** work have := (local_hom_TFAE f).out 0 4 rw [this, PrimeSpectrum.ext_iff] rfl +@[deprecated (since := "2024-10-10")] +alias isLocalRingHom_iff_comap_closedPoint := isLocalHom_iff_comap_closedPoint + @[simp] theorem comap_closedPoint {S : Type v} [CommSemiring S] [LocalRing S] (f : R →+* S) - [IsLocalRingHom f] : PrimeSpectrum.comap f (closedPoint S) = closedPoint R := - (isLocalRingHom_iff_comap_closedPoint f).mp inferInstance + [IsLocalHom f] : PrimeSpectrum.comap f (closedPoint S) = closedPoint R := + (isLocalHom_iff_comap_closedPoint f).mp inferInstance theorem specializes_closedPoint (x : PrimeSpectrum R) : x ⤳ closedPoint R := (PrimeSpectrum.le_iff_specializes _ _).mp (LocalRing.le_maximalIdeal x.2.1) diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean index 106326628a9e44..77da59dbcba244 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean @@ -642,7 +642,7 @@ lemma toSpec_base_apply_eq_comap {f} (x : Proj| pbo f) : rw [awayToΓ_ΓToStalk, CommRingCat.comp_eq_ring_hom_comp, PrimeSpectrum.comap_comp] exact congr(PrimeSpectrum.comap _ $(@LocalRing.comap_closedPoint (HomogeneousLocalization.AtPrime 𝒜 x.1.asHomogeneousIdeal.toIdeal) _ _ - ((Proj| pbo f).presheaf.stalk x) _ _ _ (isLocalRingHom_of_isIso _))) + ((Proj| pbo f).presheaf.stalk x) _ _ _ (isLocalHom_of_isIso _))) lemma toSpec_base_apply_eq {f} (x : Proj| pbo f) : (toSpec 𝒜 f).base x = ProjIsoSpecTopComponent.toSpec 𝒜 f x := diff --git a/Mathlib/AlgebraicGeometry/ResidueField.lean b/Mathlib/AlgebraicGeometry/ResidueField.lean index a429de3ad31746..ac1d5d1e8dcc24 100644 --- a/Mathlib/AlgebraicGeometry/ResidueField.lean +++ b/Mathlib/AlgebraicGeometry/ResidueField.lean @@ -83,15 +83,6 @@ lemma basicOpen_eq_bot_iff_forall_evaluation_eq_zero (f : X.presheaf.obj (op U)) variable {X Y : Scheme.{u}} (f : X ⟶ Y) - --- TODO: This instance is found before #6045. --- We need this strange instance for `residueFieldMap`, the type of `F` must be fixed --- like this. The instance `IsLocalRingHom (f.stalkMap x)` already exists, but does not work for --- `residueFieldMap`. -instance (x): IsLocalRingHom (F := Y.presheaf.stalk (f.base x) →+* X.presheaf.stalk x) - (f.stalkMap x) := - f.1.2 x - /-- If `X ⟶ Y` is a morphism of locally ringed spaces and `x` a point of `X`, we obtain a morphism of residue fields in the other direction. -/ def Hom.residueFieldMap (f : X.Hom Y) (x : X) : diff --git a/Mathlib/AlgebraicGeometry/Scheme.lean b/Mathlib/AlgebraicGeometry/Scheme.lean index b958a149bf9ecc..d77a37bef9383a 100644 --- a/Mathlib/AlgebraicGeometry/Scheme.lean +++ b/Mathlib/AlgebraicGeometry/Scheme.lean @@ -640,6 +640,9 @@ namespace Scheme variable {X Y : Scheme.{u}} (f : X ⟶ Y) +instance (x) : IsLocalHom (f.stalkMap x) := + f.prop x + @[simp] lemma stalkMap_id (X : Scheme.{u}) (x : X) : (𝟙 X : X ⟶ X).stalkMap x = 𝟙 (X.presheaf.stalk x) := @@ -723,7 +726,7 @@ open LocalRing @[simp] lemma Spec_closedPoint {R S : CommRingCat} [LocalRing R] [LocalRing S] - {f : R ⟶ S} [IsLocalRingHom f] : (Spec.map f).base (closedPoint S) = closedPoint R := + {f : R ⟶ S} [IsLocalHom f] : (Spec.map f).base (closedPoint S) = closedPoint R := LocalRing.comap_closedPoint f end LocalRing diff --git a/Mathlib/AlgebraicGeometry/Spec.lean b/Mathlib/AlgebraicGeometry/Spec.lean index 25719eb7d693ff..4d4595fade0bde 100644 --- a/Mathlib/AlgebraicGeometry/Spec.lean +++ b/Mathlib/AlgebraicGeometry/Spec.lean @@ -230,7 +230,7 @@ The induced map of a ring homomorphism on the prime spectra, as a morphism of lo def Spec.locallyRingedSpaceMap {R S : CommRingCat.{u}} (f : R ⟶ S) : Spec.locallyRingedSpaceObj S ⟶ Spec.locallyRingedSpaceObj R := LocallyRingedSpace.Hom.mk (Spec.sheafedSpaceMap f) fun p => - IsLocalRingHom.mk fun a ha => by + IsLocalHom.mk fun a ha => by -- Here, we are showing that the map on prime spectra induced by `f` is really a morphism of -- *locally* ringed spaces, i.e. that the induced map on the stalks is a local ring -- homomorphism. @@ -238,11 +238,9 @@ def Spec.locallyRingedSpaceMap {R S : CommRingCat.{u}} (f : R ⟶ S) : #adaptation_note /-- nightly-2024-04-01 It's this `erw` that is blowing up. The implicit arguments differ significantly. -/ erw [← localRingHom_comp_stalkIso_apply] at ha - -- TODO: this instance was found automatically before #6045 - haveI : IsLocalRingHom (stalkIso (↑S) p).inv := isLocalRingHom_of_isIso _ replace ha := (isUnit_map_iff (stalkIso S p).inv _).mp ha -- Porting note: `f` had to be made explicit - replace ha := IsLocalRingHom.map_nonunit + replace ha := IsLocalHom.map_nonunit (f := (Localization.localRingHom (PrimeSpectrum.comap f p).asIdeal p.asIdeal f _)) _ ha convert RingHom.isUnit_map (stalkIso R (PrimeSpectrum.comap f p)).inv ha erw [← comp_apply, show stalkToFiberRingHom R _ = (stalkIso _ _).hom from rfl, diff --git a/Mathlib/AlgebraicGeometry/Stalk.lean b/Mathlib/AlgebraicGeometry/Stalk.lean index c5d01c49065527..251d379d23a14f 100644 --- a/Mathlib/AlgebraicGeometry/Stalk.lean +++ b/Mathlib/AlgebraicGeometry/Stalk.lean @@ -198,11 +198,9 @@ def stalkClosedPointTo : X.presheaf.stalk (f.base (closedPoint R)) ⟶ R := f.stalkMap (closedPoint R) ≫ (stalkClosedPointIso R).hom -instance isLocalRingHom_stalkClosedPointTo : - IsLocalRingHom (stalkClosedPointTo f) := by - apply (config := { allowSynthFailures := true }) RingHom.isLocalRingHom_comp - · apply isLocalRingHom_of_iso - · apply f.prop +instance isLocalHom_stalkClosedPointTo : + IsLocalHom (stalkClosedPointTo f) := + inferInstanceAs <| IsLocalHom (f.stalkMap (closedPoint R) ≫ (stalkClosedPointIso R).hom) lemma preimage_eq_top_of_closedPoint_mem {U : Opens X} (hU : f.base (closedPoint R) ∈ U) : f ⁻¹ᵁ U = ⊤ := @@ -234,7 +232,7 @@ lemma germ_stalkClosedPointTo (U : Opens X) (hU : f.base (closedPoint R) ∈ U) @[reassoc] lemma germ_stalkClosedPointTo_Spec_fromSpecStalk - {x : X} (f : X.presheaf.stalk x ⟶ R) [IsLocalRingHom f] (U : Opens X) (hU) : + {x : X} (f : X.presheaf.stalk x ⟶ R) [IsLocalHom f] (U : Opens X) (hU) : X.presheaf.germ U _ hU ≫ stalkClosedPointTo (Spec.map f ≫ X.fromSpecStalk x) = X.presheaf.germ U x (by simpa using hU) ≫ f := by have : (Spec.map f ≫ X.fromSpecStalk x).base (closedPoint R) = x := by @@ -278,7 +276,7 @@ variable {R} omit [LocalRing R] in /-- useful lemma for applications of `SpecToEquivOfLocalRing` -/ lemma SpecToEquivOfLocalRing_eq_iff - {f₁ f₂ : Σ x, { f : X.presheaf.stalk x ⟶ R // IsLocalRingHom f }} : + {f₁ f₂ : Σ x, { f : X.presheaf.stalk x ⟶ R // IsLocalHom f }} : f₁ = f₂ ↔ ∃ h₁ : f₁.1 = f₂.1, f₁.2.1 = (X.presheaf.stalkCongr (by rw [h₁]; rfl)).hom ≫ f₂.2.1 := by constructor @@ -297,7 +295,7 @@ Given a local ring `R` and scheme `X`, morphisms `Spec R ⟶ X` corresponds to p @[simps] noncomputable def SpecToEquivOfLocalRing : - (Spec R ⟶ X) ≃ Σ x, { f : X.presheaf.stalk x ⟶ R // IsLocalRingHom f } where + (Spec R ⟶ X) ≃ Σ x, { f : X.presheaf.stalk x ⟶ R // IsLocalHom f } where toFun f := ⟨f.base (closedPoint R), Scheme.stalkClosedPointTo f, inferInstance⟩ invFun xf := Spec.map xf.2.1 ≫ X.fromSpecStalk xf.1 left_inv := Scheme.Spec_stalkClosedPointTo_fromSpecStalk diff --git a/Mathlib/AlgebraicGeometry/StructureSheaf.lean b/Mathlib/AlgebraicGeometry/StructureSheaf.lean index 7541f38a34b7c0..6d0abf3ae594a6 100644 --- a/Mathlib/AlgebraicGeometry/StructureSheaf.lean +++ b/Mathlib/AlgebraicGeometry/StructureSheaf.lean @@ -542,14 +542,14 @@ def stalkIso (x : PrimeSpectrum.Top R) : instance (x : PrimeSpectrum R) : IsIso (stalkToFiberRingHom R x) := (stalkIso R x).isIso_hom -instance (x : PrimeSpectrum R) : IsLocalRingHom (stalkToFiberRingHom R x) := - isLocalRingHom_of_isIso _ +instance (x : PrimeSpectrum R) : IsLocalHom (stalkToFiberRingHom R x) := + isLocalHom_of_isIso _ instance (x : PrimeSpectrum R) : IsIso (localizationToStalk R x) := (stalkIso R x).isIso_inv -instance (x : PrimeSpectrum R) : IsLocalRingHom (localizationToStalk R x) := - isLocalRingHom_of_isIso _ +instance (x : PrimeSpectrum R) : IsLocalHom (localizationToStalk R x) := + isLocalHom_of_isIso _ @[simp, reassoc] theorem stalkToFiberRingHom_localizationToStalk (x : PrimeSpectrum.Top R) : diff --git a/Mathlib/FieldTheory/Separable.lean b/Mathlib/FieldTheory/Separable.lean index 63d3ad68e42f22..b8cfde792d4393 100644 --- a/Mathlib/FieldTheory/Separable.lean +++ b/Mathlib/FieldTheory/Separable.lean @@ -350,7 +350,7 @@ theorem separable_or {f : F[X]} (hf : Irreducible f) : have := natDegree_eq_zero_of_derivative_eq_zero H have := (natDegree_pos_iff_degree_pos.mpr <| degree_pos_of_irreducible hf).ne' contradiction - haveI := isLocalRingHom_expand F hp + haveI := isLocalHom_expand F hp exact Or.inr ⟨by rw [separable_iff_derivative_ne_zero hf, Classical.not_not, H], contract p f, diff --git a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean index 72d5eb095aa969..f0aedb017be003 100644 --- a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean +++ b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean @@ -11,7 +11,7 @@ import Mathlib.Geometry.RingedSpace.Stalks We define (bundled) locally ringed spaces (as `SheafedSpace CommRing` along with the fact that the stalks are local rings), and morphisms between these (morphisms in `SheafedSpace` with -`IsLocalRingHom` on the stalk maps). +`IsLocalHom` on the stalk maps). -/ -- Explicit universe annotations were used in this file to improve performance #12737 @@ -73,7 +73,7 @@ def 𝒪 : Sheaf CommRingCat X.toTopCat := structure Hom (X Y : LocallyRingedSpace.{u}) extends X.toPresheafedSpace.Hom Y.toPresheafedSpace : Type _ where /-- the underlying morphism induces a local ring homomorphism on stalks -/ - prop : ∀ x, IsLocalRingHom (toHom.stalkMap x) + prop : ∀ x, IsLocalHom (toHom.stalkMap x) /-- A morphism of locally ringed spaces as a morphism of sheafed spaces. -/ abbrev Hom.toShHom {X Y : LocallyRingedSpace.{u}} (f : X.Hom Y) : @@ -104,18 +104,23 @@ noncomputable def Hom.stalkMap {X Y : LocallyRingedSpace.{u}} (f : Hom X Y) (x : Y.presheaf.stalk (f.1.1 x) ⟶ X.presheaf.stalk x := f.toShHom.stalkMap x -instance isLocalRingHomStalkMap {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) (x : X) : - IsLocalRingHom (f.stalkMap x) := +@[instance] +theorem isLocalHomStalkMap {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) (x : X) : + IsLocalHom (f.stalkMap x) := f.2 x -instance isLocalRingHomValStalkMap {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) (x : X) : - IsLocalRingHom (f.toShHom.stalkMap x) := +@[instance] +theorem isLocalHomValStalkMap {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) (x : X) : + IsLocalHom (f.toShHom.stalkMap x) := f.2 x +@[deprecated (since := "2024-10-10")] +alias isLocalRingHomValStalkMap := isLocalHomValStalkMap + /-- The identity morphism on a locally ringed space. -/ @[simps! toShHom] def id (X : LocallyRingedSpace.{u}) : Hom X X := - ⟨𝟙 X.toSheafedSpace, fun x => by erw [PresheafedSpace.stalkMap.id]; apply isLocalRingHom_id⟩ + ⟨𝟙 X.toSheafedSpace, fun x => by erw [PresheafedSpace.stalkMap.id]; infer_instance⟩ instance (X : LocallyRingedSpace.{u}) : Inhabited (Hom X X) := ⟨id X⟩ @@ -124,7 +129,7 @@ instance (X : LocallyRingedSpace.{u}) : Inhabited (Hom X X) := def comp {X Y Z : LocallyRingedSpace.{u}} (f : Hom X Y) (g : Hom Y Z) : Hom X Z := ⟨f.toShHom ≫ g.toShHom, fun x => by erw [PresheafedSpace.stalkMap.comp] - exact @RingHom.isLocalRingHom_comp _ _ _ _ _ _ _ _ (f.2 _) (g.2 _)⟩ + infer_instance⟩ /-- The category of locally ringed spaces. -/ instance : Category LocallyRingedSpace.{u} where @@ -180,12 +185,11 @@ See also `isoOfSheafedSpaceIso`. @[simps! toShHom] def homOfSheafedSpaceHomOfIsIso {X Y : LocallyRingedSpace.{u}} (f : X.toSheafedSpace ⟶ Y.toSheafedSpace) [IsIso f] : X ⟶ Y := - Hom.mk f fun x => + Hom.mk f fun _ => -- Here we need to see that the stalk maps are really local ring homomorphisms. -- This can be solved by type class inference, because stalk maps of isomorphisms -- are isomorphisms and isomorphisms are local ring homomorphisms. - show IsLocalRingHom ((SheafedSpace.forgetToPresheafedSpace.map f).stalkMap x) by - infer_instance + inferInstance /-- Given two locally ringed spaces `X` and `Y`, an isomorphism between `X` and `Y` as _sheafed_ spaces can be lifted to an isomorphism `X ⟶ Y` as locally ringed spaces. diff --git a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean index a45f070a1bf4f5..01ff44c393aaa0 100644 --- a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean +++ b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/HasColimits.lean @@ -102,7 +102,7 @@ noncomputable def coproductCofanIsColimit : IsColimit (coproductCofan F) where (colimit.ι_desc (C := SheafedSpace.{u+1, u, u} CommRingCatMax.{u, u}) (forgetToSheafedSpace.mapCocone s) i : _)] haveI : - IsLocalRingHom + IsLocalHom (((forgetToSheafedSpace.mapCocone s).ι.app i).stalkMap y) := (s.ι.app i).2 y infer_instance⟩ @@ -131,9 +131,10 @@ variable {X Y : LocallyRingedSpace.{v}} (f g : X ⟶ Y) namespace HasCoequalizer -instance coequalizer_π_app_isLocalRingHom +@[instance] +theorem coequalizer_π_app_isLocalHom (U : TopologicalSpace.Opens (coequalizer f.toShHom g.toShHom).carrier) : - IsLocalRingHom ((coequalizer.π f.toShHom g.toShHom : _).c.app (op U)) := by + IsLocalHom ((coequalizer.π f.toShHom g.toShHom : _).c.app (op U)) := by have := ι_comp_coequalizerComparison f.toShHom g.toShHom SheafedSpace.forgetToPresheafedSpace rw [← PreservesCoequalizer.iso_hom] at this erw [SheafedSpace.congr_app this.symm (op U)] @@ -144,6 +145,9 @@ instance coequalizer_π_app_isLocalRingHom PresheafedSpace.c_isIso_of_iso _ infer_instance +@[deprecated (since := "2024-10-10")] +alias coequalizer_π_app_isLocalRingHom := coequalizer_π_app_isLocalHom + /-! We roughly follow the construction given in [MR0302656]. Given a pair `f, g : X ⟶ Y` of morphisms of locally ringed spaces, we want to show that the stalk map of @@ -210,8 +214,9 @@ theorem imageBasicOpen_image_open : erw [imageBasicOpen_image_preimage] exact (imageBasicOpen f g U s).2 -instance coequalizer_π_stalk_isLocalRingHom (x : Y) : - IsLocalRingHom ((coequalizer.π f.toShHom g.toShHom : _).stalkMap x) := by +@[instance] +theorem coequalizer_π_stalk_isLocalHom (x : Y) : + IsLocalHom ((coequalizer.π f.toShHom g.toShHom : _).stalkMap x) := by constructor rintro a ha rcases TopCat.Presheaf.germ_exist _ _ a with ⟨U, hU, s, rfl⟩ @@ -240,6 +245,9 @@ instance coequalizer_π_stalk_isLocalRingHom (x : Y) : convert @RingedSpace.isUnit_res_basicOpen Y.toRingedSpace (unop _) (((coequalizer.π f.toShHom g.toShHom).c.app (op U)) s) +@[deprecated (since := "2024-10-10")] +alias coequalizer_π_stalk_isLocalRingHom := coequalizer_π_stalk_isLocalHom + end HasCoequalizer /-- The coequalizer of two locally ringed space in the category of sheafed spaces is a locally @@ -249,20 +257,18 @@ noncomputable def coequalizer : LocallyRingedSpace where localRing x := by obtain ⟨y, rfl⟩ := (TopCat.epi_iff_surjective (coequalizer.π f.toShHom g.toShHom).base).mp inferInstance x - -- TODO: this instance was found automatically before #6045 - have _ : IsLocalRingHom ((coequalizer.π f.toShHom g.toShHom).stalkMap y) := inferInstance exact ((coequalizer.π f.toShHom g.toShHom : _).stalkMap y).domain_localRing /-- The explicit coequalizer cofork of locally ringed spaces. -/ noncomputable def coequalizerCofork : Cofork f g := @Cofork.ofπ _ _ _ _ f g (coequalizer f g) ⟨coequalizer.π f.toShHom g.toShHom, -- Porting note: this used to be automatic - HasCoequalizer.coequalizer_π_stalk_isLocalRingHom _ _⟩ + HasCoequalizer.coequalizer_π_stalk_isLocalHom _ _⟩ (LocallyRingedSpace.Hom.ext' (coequalizer.condition f.toShHom g.toShHom)) -theorem isLocalRingHom_stalkMap_congr {X Y : RingedSpace} (f g : X ⟶ Y) (H : f = g) (x) - (h : IsLocalRingHom (f.stalkMap x)) : - IsLocalRingHom (g.stalkMap x) := by +theorem isLocalHom_stalkMap_congr {X Y : RingedSpace} (f g : X ⟶ Y) (H : f = g) (x) + (h : IsLocalHom (f.stalkMap x)) : + IsLocalHom (g.stalkMap x) := by rw [PresheafedSpace.stalkMap.congr_hom _ _ H.symm x]; infer_instance /-- The cofork constructed in `coequalizer_cofork` is indeed a colimit cocone. -/ @@ -274,19 +280,19 @@ noncomputable def coequalizerCoforkIsColimit : IsColimit (coequalizerCofork f g) · intro x rcases (TopCat.epi_iff_surjective (coequalizer.π f.toShHom g.toShHom).base).mp inferInstance x with ⟨y, rfl⟩ - -- Porting note: was `apply isLocalRingHom_of_comp _ (PresheafedSpace.stalkMap ...)`, this + -- Porting note: was `apply isLocalHom_of_comp _ (PresheafedSpace.stalkMap ...)`, this -- used to allow you to provide the proof that `... ≫ ...` is a local ring homomorphism later, -- but this is no longer possible set h := _ - change IsLocalRingHom h - suffices _ : IsLocalRingHom (((coequalizerCofork f g).π.1.stalkMap _).comp h) by - apply isLocalRingHom_of_comp _ ((coequalizerCofork f g).π.1.stalkMap _) + change IsLocalHom h + suffices _ : IsLocalHom (((coequalizerCofork f g).π.1.stalkMap _).comp h) by + apply isLocalHom_of_comp _ ((coequalizerCofork f g).π.1.stalkMap _) -- note to reviewers: this `change` is now more brittle because it now has to fully resolve -- the type to be able to search for `MonoidHomClass`, even though of course all homs in -- `CommRingCat` are clearly such - change IsLocalRingHom (h ≫ (coequalizerCofork f g).π.toShHom.stalkMap y) + change IsLocalHom (h ≫ (coequalizerCofork f g).π.toShHom.stalkMap y) erw [← PresheafedSpace.stalkMap.comp] - apply isLocalRingHom_stalkMap_congr _ _ (coequalizer.π_desc s.π.toShHom e).symm y + apply isLocalHom_stalkMap_congr _ _ (coequalizer.π_desc s.π.toShHom e).symm y infer_instance constructor · exact LocallyRingedSpace.Hom.ext' (coequalizer.π_desc _ _) diff --git a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean index 89243a71df33e9..3a60a5f355de1e 100644 --- a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean +++ b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace/ResidueField.lean @@ -85,14 +85,6 @@ lemma Γevaluation_ne_zero_iff_mem_basicOpen (x : X) (f : X.presheaf.obj (op ⊤ variable {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) (x : X) --- TODO: This instance is found before #6045. --- We need this strange instance for `residueFieldMap`, the type of `F` must be fixed --- like this. The instance `IsLocalRingHom (f.stalkMap x)` already exists, but does not work for --- `residueFieldMap`. -instance : IsLocalRingHom (F := Y.presheaf.stalk (f.base x) →+* X.presheaf.stalk x) - (f.stalkMap x) := - f.2 x - /-- If `X ⟶ Y` is a morphism of locally ringed spaces and `x` a point of `X`, we obtain a morphism of residue fields in the other direction. -/ def residueFieldMap (x : X) : Y.residueField (f.base x) ⟶ X.residueField x := @@ -114,9 +106,6 @@ lemma residueFieldMap_comp {Z : LocallyRingedSpace.{u}} (g : Y ⟶ Z) (x : X) : residueFieldMap (f ≫ g) x = residueFieldMap g (f.base x) ≫ residueFieldMap f x := by simp only [comp_toShHom, SheafedSpace.comp_base, Function.comp_apply, residueFieldMap] simp_rw [stalkMap_comp] - haveI : IsLocalRingHom (g.stalkMap (f.base x)) := inferInstance - -- TODO: This instance is found before #6045. - haveI : IsLocalRingHom (f.stalkMap x) := inferInstance apply LocalRing.ResidueField.map_comp @[reassoc] diff --git a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean index a29fd4205a61ae..959214c2572955 100644 --- a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean +++ b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean @@ -947,7 +947,7 @@ instance : SheafedSpace.IsOpenImmersion (LocallyRingedSpace.forgetToSheafedSpace H -- note to reviewers: is there a `count_heartbeats` for this? -set_option synthInstance.maxHeartbeats 30000 in +set_option synthInstance.maxHeartbeats 40000 in /-- An explicit pullback cone over `cospan f g` if `f` is an open immersion. -/ def pullbackConeOfLeft : PullbackCone f g := by refine PullbackCone.mk ?_ @@ -966,7 +966,7 @@ def pullbackConeOfLeft : PullbackCone f g := by instance : LocallyRingedSpace.IsOpenImmersion (pullbackConeOfLeft f g).snd := show PresheafedSpace.IsOpenImmersion (Y.toPresheafedSpace.ofRestrict _) by infer_instance -set_option synthInstance.maxHeartbeats 80000 in +set_option synthInstance.maxHeartbeats 40000 in /-- The constructed `pullbackConeOfLeft` is indeed limiting. -/ def pullbackConeOfLeftIsLimit : IsLimit (pullbackConeOfLeft f g) := PullbackCone.isLimitAux' _ fun s => by @@ -986,8 +986,7 @@ def pullbackConeOfLeftIsLimit : IsLimit (pullbackConeOfLeft f g) := change _ = _ ≫ s.snd.1.stalkMap x at this rw [PresheafedSpace.stalkMap.comp, ← IsIso.eq_inv_comp] at this rw [this] - -- TODO: This instance is found by `infer_instance` before #6045. - apply CommRingCat.isLocalRingHom_comp + infer_instance · intro m _ h₂ rw [← cancel_mono (pullbackConeOfLeft f g).snd] exact h₂.trans <| LocallyRingedSpace.Hom.ext' diff --git a/Mathlib/LinearAlgebra/ExteriorAlgebra/Basic.lean b/Mathlib/LinearAlgebra/ExteriorAlgebra/Basic.lean index cd48d0d7611d47..258bd811ae3b5e 100644 --- a/Mathlib/LinearAlgebra/ExteriorAlgebra/Basic.lean +++ b/Mathlib/LinearAlgebra/ExteriorAlgebra/Basic.lean @@ -164,8 +164,12 @@ theorem algebraMap_eq_zero_iff (x : R) : algebraMap R (ExteriorAlgebra R M) x = theorem algebraMap_eq_one_iff (x : R) : algebraMap R (ExteriorAlgebra R M) x = 1 ↔ x = 1 := map_eq_one_iff (algebraMap _ _) (algebraMap_leftInverse _).injective -instance isLocalRingHom_algebraMap : IsLocalRingHom (algebraMap R (ExteriorAlgebra R M)) := - isLocalRingHom_of_leftInverse _ (algebraMap_leftInverse M) +@[instance] +theorem isLocalHom_algebraMap : IsLocalHom (algebraMap R (ExteriorAlgebra R M)) := + isLocalHom_of_leftInverse _ (algebraMap_leftInverse M) + +@[deprecated (since := "2024-10-10")] +alias isLocalRingHom_algebraMap := isLocalHom_algebraMap theorem isUnit_algebraMap (r : R) : IsUnit (algebraMap R (ExteriorAlgebra R M) r) ↔ IsUnit r := isUnit_map_of_leftInverse _ (algebraMap_leftInverse M) diff --git a/Mathlib/RingTheory/Henselian.lean b/Mathlib/RingTheory/Henselian.lean index b1762c379f8243..42918161d3de05 100644 --- a/Mathlib/RingTheory/Henselian.lean +++ b/Mathlib/RingTheory/Henselian.lean @@ -60,8 +60,8 @@ universe u v open Polynomial LocalRing Polynomial Function List -theorem isLocalRingHom_of_le_jacobson_bot {R : Type*} [CommRing R] (I : Ideal R) - (h : I ≤ Ideal.jacobson ⊥) : IsLocalRingHom (Ideal.Quotient.mk I) := by +theorem isLocalHom_of_le_jacobson_bot {R : Type*} [CommRing R] (I : Ideal R) + (h : I ≤ Ideal.jacobson ⊥) : IsLocalHom (Ideal.Quotient.mk I) := by constructor intro a h have : IsUnit (Ideal.Quotient.mk (Ideal.jacobson ⊥) a) := by @@ -79,6 +79,9 @@ theorem isLocalRingHom_of_le_jacobson_bot {R : Type*} [CommRing R] (I : Ideal R) simp? at h1 says simp only [mul_one, sub_add_cancel, IsUnit.mul_iff] at h1 exact h1.1 +@[deprecated (since := "2024-10-10")] +alias isLocalRingHom_of_le_jacobson_bot := isLocalHom_of_le_jacobson_bot + /-- A ring `R` is *Henselian* at an ideal `I` if the following condition holds: for every polynomial `f` over `R`, with a *simple* root `a₀` over the quotient ring `R/I`, there exists a lift `a : R` of `a₀` that is a root of `f`. @@ -193,7 +196,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 := isLocalRingHom_of_le_jacobson_bot I (IsAdicComplete.le_jacobson_bot I) + haveI := 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/Basic.lean b/Mathlib/RingTheory/Ideal/Basic.lean index 69a42212b475e8..1db54f75b9e6ee 100644 --- a/Mathlib/RingTheory/Ideal/Basic.lean +++ b/Mathlib/RingTheory/Ideal/Basic.lean @@ -808,7 +808,7 @@ theorem one_not_mem_nonunits [Monoid α] : (1 : α) ∉ nonunits α := -- Porting note : as this can be proved by other `simp` lemmas, this is marked as high priority. @[simp (high)] theorem map_mem_nonunits_iff [Monoid α] [Monoid β] [FunLike F α β] [MonoidHomClass F α β] (f : F) - [IsLocalRingHom f] (a) : f a ∈ nonunits β ↔ a ∈ nonunits α := + [IsLocalHom f] (a) : f a ∈ nonunits β ↔ a ∈ nonunits α := ⟨fun h ha => h <| ha.map f, fun h ha => h <| ha.of_map⟩ theorem coe_subset_nonunits [Semiring α] {I : Ideal α} (h : I ≠ ⊤) : (I : Set α) ⊆ nonunits α := diff --git a/Mathlib/RingTheory/LocalRing/ResidueField/Basic.lean b/Mathlib/RingTheory/LocalRing/ResidueField/Basic.lean index ca824388493096..5dc19df864940b 100644 --- a/Mathlib/RingTheory/LocalRing/ResidueField/Basic.lean +++ b/Mathlib/RingTheory/LocalRing/ResidueField/Basic.lean @@ -41,7 +41,7 @@ instance ResidueField.algebra : Algebra R (ResidueField R) := theorem ResidueField.algebraMap_eq : algebraMap R (ResidueField R) = residue R := rfl -instance : IsLocalRingHom (LocalRing.residue R) := +instance : IsLocalHom (LocalRing.residue R) := ⟨fun _ ha => Classical.not_not.mp (Ideal.Quotient.eq_zero_iff_mem.not.mp (isUnit_iff_ne_zero.mp ha))⟩ @@ -50,22 +50,22 @@ variable {R} namespace ResidueField /-- A local ring homomorphism into a field can be descended onto the residue field. -/ -def lift {R S : Type*} [CommRing R] [LocalRing R] [Field S] (f : R →+* S) [IsLocalRingHom f] : +def lift {R S : Type*} [CommRing R] [LocalRing R] [Field S] (f : R →+* S) [IsLocalHom f] : LocalRing.ResidueField R →+* S := Ideal.Quotient.lift _ f fun a ha => by_contradiction fun h => ha (isUnit_of_map_unit f a (isUnit_iff_ne_zero.mpr h)) theorem lift_comp_residue {R S : Type*} [CommRing R] [LocalRing R] [Field S] (f : R →+* S) - [IsLocalRingHom f] : (lift f).comp (residue R) = f := + [IsLocalHom f] : (lift f).comp (residue R) = f := RingHom.ext fun _ => rfl @[simp] theorem lift_residue_apply {R S : Type*} [CommRing R] [LocalRing R] [Field S] (f : R →+* S) - [IsLocalRingHom f] (x) : lift f (residue R x) = f x := + [IsLocalHom f] (x) : lift f (residue R x) = f x := rfl /-- The map on residue fields induced by a local homomorphism between local rings -/ -def map (f : R →+* S) [IsLocalRingHom f] : ResidueField R →+* ResidueField S := +def map (f : R →+* S) [IsLocalHom f] : ResidueField R →+* ResidueField S := Ideal.Quotient.lift (maximalIdeal R) ((Ideal.Quotient.mk _).comp f) fun a ha => by erw [Ideal.Quotient.eq_zero_iff_mem] exact map_nonunit f a ha @@ -79,16 +79,16 @@ theorem map_id : /-- The composite of two `LocalRing.ResidueField.map`s is the `LocalRing.ResidueField.map` of the composite. -/ -theorem map_comp (f : T →+* R) (g : R →+* S) [IsLocalRingHom f] [IsLocalRingHom g] : +theorem map_comp (f : T →+* R) (g : R →+* S) [IsLocalHom f] [IsLocalHom g] : LocalRing.ResidueField.map (g.comp f) = (LocalRing.ResidueField.map g).comp (LocalRing.ResidueField.map f) := Ideal.Quotient.ringHom_ext <| RingHom.ext fun _ => rfl -theorem map_comp_residue (f : R →+* S) [IsLocalRingHom f] : +theorem map_comp_residue (f : R →+* S) [IsLocalHom f] : (ResidueField.map f).comp (residue R) = (residue S).comp f := rfl -theorem map_residue (f : R →+* S) [IsLocalRingHom f] (r : R) : +theorem map_residue (f : R →+* S) [IsLocalHom f] (r : R) : ResidueField.map f (residue R r) = residue S (f r) := rfl @@ -96,8 +96,8 @@ theorem map_id_apply (x : ResidueField R) : map (RingHom.id R) x = x := DFunLike.congr_fun map_id x @[simp] -theorem map_map (f : R →+* S) (g : S →+* T) (x : ResidueField R) [IsLocalRingHom f] - [IsLocalRingHom g] : map g (map f x) = map (g.comp f) x := +theorem map_map (f : R →+* S) (g : S →+* T) (x : ResidueField R) [IsLocalHom f] + [IsLocalHom g] : map g (map f x) = map (g.comp f) x := DFunLike.congr_fun (map_comp f g).symm x /-- A ring isomorphism defines an isomorphism of residue fields. -/ @@ -147,7 +147,7 @@ end MulSemiringAction section FiniteDimensional -variable [Algebra R S] [IsLocalRingHom (algebraMap R S)] +variable [Algebra R S] [IsLocalHom (algebraMap R S)] noncomputable instance : Algebra (ResidueField R) (ResidueField S) := (ResidueField.map (algebraMap R S)).toAlgebra @@ -175,13 +175,16 @@ end FiniteDimensional end ResidueField -theorem isLocalRingHom_residue : IsLocalRingHom (LocalRing.residue R) := by +theorem isLocalHom_residue : IsLocalHom (LocalRing.residue R) := by constructor intro a ha by_contra h erw [Ideal.Quotient.eq_zero_iff_mem.mpr ((LocalRing.mem_maximalIdeal _).mpr h)] at ha exact ha.ne_zero rfl +@[deprecated (since := "2024-10-10")] +alias isLocalRingHom_residue := isLocalHom_residue + end end LocalRing diff --git a/Mathlib/RingTheory/LocalRing/RingHom/Basic.lean b/Mathlib/RingTheory/LocalRing/RingHom/Basic.lean index 4b44e62f3ee66d..f14d328b4582a5 100644 --- a/Mathlib/RingTheory/LocalRing/RingHom/Basic.lean +++ b/Mathlib/RingTheory/LocalRing/RingHom/Basic.lean @@ -21,25 +21,40 @@ section variable [Semiring R] [Semiring S] [Semiring T] -instance isLocalRingHom_id (R : Type*) [Semiring R] : IsLocalRingHom (RingHom.id R) where +@[instance] +theorem isLocalHom_id (R : Type*) [Semiring R] : IsLocalHom (RingHom.id R) where map_nonunit _ := id +@[deprecated (since := "2024-10-10")] +alias isLocalRingHom_id := isLocalHom_id + -- see note [lower instance priority] -instance (priority := 100) isLocalRingHom_toRingHom {F : Type*} [FunLike F R S] - [RingHomClass F R S] (f : F) [IsLocalRingHom f] : IsLocalRingHom (f : R →+* S) := - ⟨IsLocalRingHom.map_nonunit (f := f)⟩ +@[instance 100] +theorem isLocalHom_toRingHom {F : Type*} [FunLike F R S] + [RingHomClass F R S] (f : F) [IsLocalHom f] : IsLocalHom (f : R →+* S) := + ⟨IsLocalHom.map_nonunit (f := f)⟩ + +@[deprecated (since := "2024-10-10")] +alias isLocalRingHom_toRingHom := isLocalHom_toRingHom -instance RingHom.isLocalRingHom_comp (g : S →+* T) (f : R →+* S) [IsLocalRingHom g] - [IsLocalRingHom f] : IsLocalRingHom (g.comp f) where - map_nonunit a := IsLocalRingHom.map_nonunit a ∘ IsLocalRingHom.map_nonunit (f := g) (f a) +@[instance] +theorem RingHom.isLocalHom_comp (g : S →+* T) (f : R →+* S) [IsLocalHom g] + [IsLocalHom f] : IsLocalHom (g.comp f) where + map_nonunit a := IsLocalHom.map_nonunit a ∘ IsLocalHom.map_nonunit (f := g) (f a) -theorem isLocalRingHom_of_comp (f : R →+* S) (g : S →+* T) [IsLocalRingHom (g.comp f)] : - IsLocalRingHom f := +@[deprecated (since := "2024-10-10")] +alias RingHom.isLocalRingHom_comp := RingHom.isLocalHom_comp + +theorem isLocalHom_of_comp (f : R →+* S) (g : S →+* T) [IsLocalHom (g.comp f)] : + IsLocalHom f := ⟨fun _ ha => (isUnit_map_iff (g.comp f) _).mp (g.isUnit_map ha)⟩ +@[deprecated (since := "2024-10-10")] +alias isLocalRingHom_of_comp := isLocalHom_of_comp + /-- If `f : R →+* S` is a local ring hom, then `R` is a local ring if `S` is. -/ theorem RingHom.domain_localRing {R S : Type*} [CommSemiring R] [CommSemiring S] [H : LocalRing S] - (f : R →+* S) [IsLocalRingHom f] : LocalRing R := by + (f : R →+* S) [IsLocalHom f] : LocalRing R := by haveI : Nontrivial R := pullback_nonzero f f.map_zero f.map_one apply LocalRing.of_nonunits_add intro a b @@ -57,7 +72,7 @@ variable [CommSemiring R] [LocalRing R] [CommSemiring S] [LocalRing S] /-- The image of the maximal ideal of the source is contained within the maximal ideal of the target. -/ -theorem map_nonunit (f : R →+* S) [IsLocalRingHom f] (a : R) (h : a ∈ maximalIdeal R) : +theorem map_nonunit (f : R →+* S) [IsLocalHom f] (a : R) (h : a ∈ maximalIdeal R) : f a ∈ maximalIdeal S := fun H => h <| isUnit_of_map_unit f a H end @@ -73,7 +88,7 @@ i.e. any preimage of a unit is still a unit. https://stacks.math.columbia.edu/ta -/ theorem local_hom_TFAE (f : R →+* S) : List.TFAE - [IsLocalRingHom f, f '' (maximalIdeal R).1 ⊆ maximalIdeal S, + [IsLocalHom f, f '' (maximalIdeal R).1 ⊆ maximalIdeal S, (maximalIdeal R).map f ≤ maximalIdeal S, maximalIdeal R ≤ (maximalIdeal S).comap f, (maximalIdeal S).comap f = maximalIdeal R] := by tfae_have 1 → 2 @@ -89,19 +104,19 @@ theorem local_hom_TFAE (f : R →+* S) : end theorem of_surjective [CommSemiring R] [LocalRing R] [CommSemiring S] [Nontrivial S] (f : R →+* S) - [IsLocalRingHom f] (hf : Function.Surjective f) : LocalRing S := + [IsLocalHom f] (hf : Function.Surjective f) : LocalRing S := of_isUnit_or_isUnit_of_isUnit_add (by intro a b hab obtain ⟨a, rfl⟩ := hf a obtain ⟨b, rfl⟩ := hf b rw [← map_add] at hab exact - (isUnit_or_isUnit_of_isUnit_add <| IsLocalRingHom.map_nonunit _ hab).imp f.isUnit_map + (isUnit_or_isUnit_of_isUnit_add <| IsLocalHom.map_nonunit _ hab).imp f.isUnit_map f.isUnit_map) /-- If `f : R →+* S` is a surjective local ring hom, then the induced units map is surjective. -/ theorem surjective_units_map_of_local_ringHom [CommRing R] [CommRing S] (f : R →+* S) - (hf : Function.Surjective f) (h : IsLocalRingHom f) : + (hf : Function.Surjective f) (h : IsLocalHom f) : Function.Surjective (Units.map <| f.toMonoidHom) := by intro a obtain ⟨b, hb⟩ := hf (a : S) @@ -113,7 +128,7 @@ theorem surjective_units_map_of_local_ringHom [CommRing R] [CommRing S] (f : R /-- Every ring hom `f : K →+* R` from a division ring `K` to a nontrivial ring `R` is a local ring hom. -/ instance (priority := 100) {K R} [DivisionRing K] [CommRing R] [Nontrivial R] - (f : K →+* R) : IsLocalRingHom f where + (f : K →+* R) : IsLocalHom f where map_nonunit r hr := by simpa only [isUnit_iff_ne_zero, ne_eq, map_eq_zero] using hr.ne_zero end LocalRing diff --git a/Mathlib/RingTheory/Localization/AtPrime.lean b/Mathlib/RingTheory/Localization/AtPrime.lean index cec0198c34a92a..90a63bac869907 100644 --- a/Mathlib/RingTheory/Localization/AtPrime.lean +++ b/Mathlib/RingTheory/Localization/AtPrime.lean @@ -218,14 +218,18 @@ theorem localRingHom_mk' (J : Ideal P) [J.IsPrime] (f : R →+* P) (hIJ : I = J. (⟨f y, le_comap_primeCompl_iff.mpr (ge_of_eq hIJ) y.2⟩ : J.primeCompl) := map_mk' _ _ _ -instance isLocalRingHom_localRingHom (J : Ideal P) [hJ : J.IsPrime] (f : R →+* P) - (hIJ : I = J.comap f) : IsLocalRingHom (localRingHom I J f hIJ) := - IsLocalRingHom.mk fun x hx => by +@[instance] +theorem isLocalHom_localRingHom (J : Ideal P) [hJ : J.IsPrime] (f : R →+* P) + (hIJ : I = J.comap f) : IsLocalHom (localRingHom I J f hIJ) := + IsLocalHom.mk fun x hx => by rcases IsLocalization.mk'_surjective I.primeCompl x with ⟨r, s, rfl⟩ rw [localRingHom_mk'] at hx rw [AtPrime.isUnit_mk'_iff] at hx ⊢ exact fun hr => hx ((SetLike.ext_iff.mp hIJ r).mp hr) +@[deprecated (since := "2024-10-10")] +alias isLocalRingHom_localRingHom := isLocalHom_localRingHom + theorem localRingHom_unique (J : Ideal P) [J.IsPrime] (f : R →+* P) (hIJ : I = J.comap f) {j : Localization.AtPrime I →+* Localization.AtPrime J} (hj : ∀ x : R, j (algebraMap _ _ x) = algebraMap _ _ (f x)) : localRingHom I J f hIJ = j := diff --git a/Mathlib/RingTheory/MvPowerSeries/Inverse.lean b/Mathlib/RingTheory/MvPowerSeries/Inverse.lean index d5160e80675891..ce619c30ce0998 100644 --- a/Mathlib/RingTheory/MvPowerSeries/Inverse.lean +++ b/Mathlib/RingTheory/MvPowerSeries/Inverse.lean @@ -31,7 +31,7 @@ Instances are defined: * Formal power series over a local ring form a local ring. * The morphism `MvPowerSeries.map σ f : MvPowerSeries σ A →* MvPowerSeries σ B` - induced by a local morphism `f : A →+* B` (`IsLocalRingHom f`) + induced by a local morphism `f : A →+* B` (`IsLocalHom f`) of commutative rings is a *local* morphism. -/ @@ -167,13 +167,14 @@ end CommRing section LocalRing -variable {S : Type*} [CommRing R] [CommRing S] (f : R →+* S) [IsLocalRingHom f] +variable {S : Type*} [CommRing R] [CommRing S] (f : R →+* S) [IsLocalHom f] -- Thanks to the linter for informing us that this instance does -- not actually need R and S to be local rings! /-- The map between multivariate formal power series over the same indexing set induced by a local ring hom `A → B` is local -/ -instance map.isLocalRingHom : IsLocalRingHom (map σ f) := +@[instance] +theorem map.isLocalHom : IsLocalHom (map σ f) := ⟨by rintro φ ⟨ψ, h⟩ replace h := congr_arg (constantCoeff σ S) h @@ -183,6 +184,9 @@ instance map.isLocalRingHom : IsLocalRingHom (map σ f) := rcases isUnit_of_map_unit f _ this with ⟨c, hc⟩ exact isUnit_of_mul_eq_one φ (invOfUnit φ c) (mul_invOfUnit φ c hc.symm)⟩ +@[deprecated (since := "2024-10-10")] +alias map.isLocalRingHom := map.isLocalHom + end LocalRing section Field diff --git a/Mathlib/RingTheory/PowerSeries/Inverse.lean b/Mathlib/RingTheory/PowerSeries/Inverse.lean index aec805253fd3db..4a9202d3df4a70 100644 --- a/Mathlib/RingTheory/PowerSeries/Inverse.lean +++ b/Mathlib/RingTheory/PowerSeries/Inverse.lean @@ -266,10 +266,14 @@ end Field section LocalRing -variable {S : Type*} [CommRing R] [CommRing S] (f : R →+* S) [IsLocalRingHom f] +variable {S : Type*} [CommRing R] [CommRing S] (f : R →+* S) [IsLocalHom f] -instance map.isLocalRingHom : IsLocalRingHom (map f) := - MvPowerSeries.map.isLocalRingHom f +@[instance] +theorem map.isLocalHom : IsLocalHom (map f) := + MvPowerSeries.map.isLocalHom f + +@[deprecated (since := "2024-10-10")] +alias map.isLocalRingHom := map.isLocalHom variable [LocalRing R] [LocalRing S] diff --git a/Mathlib/RingTheory/SurjectiveOnStalks.lean b/Mathlib/RingTheory/SurjectiveOnStalks.lean index 94c5443047b713..c8c8f65ad3cbae 100644 --- a/Mathlib/RingTheory/SurjectiveOnStalks.lean +++ b/Mathlib/RingTheory/SurjectiveOnStalks.lean @@ -174,7 +174,7 @@ lemma SurjectiveOnStalks.baseChange one_mul, mul_one, id_apply, ← e] rw [Algebra.algebraMap_eq_smul_one, ← smul_tmul', smul_mul_assoc] -lemma surjectiveOnStalks_iff_of_isLocalRingHom [LocalRing S] [IsLocalRingHom f] : +lemma surjectiveOnStalks_iff_of_isLocalHom [LocalRing S] [IsLocalHom f] : f.SurjectiveOnStalks ↔ Function.Surjective f := by refine ⟨fun H x ↦ ?_, fun h ↦ surjectiveOnStalks_of_surjective h⟩ obtain ⟨y, r, c, hc, hr, e⟩ := @@ -185,4 +185,7 @@ lemma surjectiveOnStalks_iff_of_isLocalRingHom [LocalRing S] [IsLocalRingHom f] apply hc.mul_right_injective simp only [← _root_.map_mul, ← mul_assoc, IsUnit.mul_val_inv, one_mul, e] +@[deprecated (since := "2024-10-10")] +alias surjectiveOnStalks_iff_of_isLocalRingHom := surjectiveOnStalks_iff_of_isLocalHom + end RingHom diff --git a/Mathlib/RingTheory/Valuation/ValExtension.lean b/Mathlib/RingTheory/Valuation/ValExtension.lean index 566aa0f741a772..11ee048743d9ce 100644 --- a/Mathlib/RingTheory/Valuation/ValExtension.lean +++ b/Mathlib/RingTheory/Valuation/ValExtension.lean @@ -143,16 +143,20 @@ theorem algebraMap_injective [IsValExtension vK vA] [Nontrivial A] : ext apply RingHom.injective (algebraMap K A) h -instance instIsLocalRingHomValuationInteger {S ΓS: Type*} [CommRing S] +@[instance] +theorem instIsLocalHomValuationInteger {S ΓS: Type*} [CommRing S] [LinearOrderedCommGroupWithZero ΓS] - [Algebra R S] [IsLocalRingHom (algebraMap R S)] {vS : Valuation S ΓS} - [IsValExtension vR vS] : IsLocalRingHom (algebraMap vR.integer vS.integer) where + [Algebra R S] [IsLocalHom (algebraMap R S)] {vS : Valuation S ΓS} + [IsValExtension vR vS] : IsLocalHom (algebraMap vR.integer vS.integer) where map_nonunit r hr := by apply (Valuation.integer.integers (v := vR)).isUnit_of_one · exact (isUnit_map_iff (algebraMap R S) _).mp (hr.map (algebraMap _ S)) · apply (Valuation.integer.integers (v := vS)).one_of_isUnit at hr exact (val_map_eq_one_iff vR vS _).mp hr +@[deprecated (since := "2024-10-10")] +alias instIsLocalRingHomValuationInteger := instIsLocalHomValuationInteger + end integer end IsValExtension diff --git a/Mathlib/RingTheory/Valuation/ValuationSubring.lean b/Mathlib/RingTheory/Valuation/ValuationSubring.lean index 48d6df21160fae..d6d738435853cb 100644 --- a/Mathlib/RingTheory/Valuation/ValuationSubring.lean +++ b/Mathlib/RingTheory/Valuation/ValuationSubring.lean @@ -646,7 +646,7 @@ theorem ker_unitGroupToResidueFieldUnits : theorem surjective_unitGroupToResidueFieldUnits : Function.Surjective A.unitGroupToResidueFieldUnits := (LocalRing.surjective_units_map_of_local_ringHom _ Ideal.Quotient.mk_surjective - LocalRing.isLocalRingHom_residue).comp + LocalRing.isLocalHom_residue).comp (MulEquiv.surjective _) /-- The quotient of the unit group of `A` by the principal unit group of `A` agrees with From ab615cabc502be94a00ef0f58e1b2e83136bd645 Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Fri, 18 Oct 2024 08:24:02 +0000 Subject: [PATCH 360/425] chore: bump to nightly-2024-10-18 --- lean-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lean-toolchain b/lean-toolchain index 22d46f9584c417..4c427a2de2a633 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-17 +leanprover/lean4:nightly-2024-10-18 From 1f26636368232f82cf41fc3ab1793f6d61a9edc2 Mon Sep 17 00:00:00 2001 From: Moritz Firsching Date: Fri, 18 Oct 2024 08:51:11 +0000 Subject: [PATCH 361/425] chore(Algebra/Module/Equiv/Defs): remove `FunLike` instance (#17477) Co-authored-by: Moritz Firsching --- Mathlib/Algebra/Module/Equiv/Defs.lean | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Mathlib/Algebra/Module/Equiv/Defs.lean b/Mathlib/Algebra/Module/Equiv/Defs.lean index 7d08836e2d79fd..430a86911a3e03 100644 --- a/Mathlib/Algebra/Module/Equiv/Defs.lean +++ b/Mathlib/Algebra/Module/Equiv/Defs.lean @@ -168,15 +168,6 @@ instance : EquivLike (M ≃ₛₗ[σ] M₂) M M₂ where left_inv := LinearEquiv.left_inv right_inv := LinearEquiv.right_inv -/-- Helper instance for when inference gets stuck on following the normal chain -`EquivLike → FunLike`. - -TODO: this instance doesn't appear to be necessary: remove it (after benchmarking?) --/ -instance : FunLike (M ≃ₛₗ[σ] M₂) M M₂ where - coe := DFunLike.coe - coe_injective' := DFunLike.coe_injective - instance : SemilinearEquivClass (M ≃ₛₗ[σ] M₂) σ M M₂ where map_add := (·.map_add') --map_add' Porting note (#11215): TODO why did I need to change this? map_smulₛₗ := (·.map_smul') --map_smul' Porting note (#11215): TODO why did I need to change this? From 6dca5634f0e8d885d4dae292bfa910bb62a9e524 Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Fri, 18 Oct 2024 08:51:13 +0000 Subject: [PATCH 362/425] chore(MeasureTheory): use `Disjoint` (#17890) --- .../ConditionalExpectation/CondexpL1.lean | 8 ++++---- Mathlib/MeasureTheory/Function/LpSpace.lean | 4 ++-- Mathlib/MeasureTheory/Integral/Bochner.lean | 9 ++++----- Mathlib/MeasureTheory/Integral/SetToL1.lean | 16 ++++++++-------- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL1.lean b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL1.lean index 633ff287c5581b..45d4dfd32c71c6 100644 --- a/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL1.lean +++ b/Mathlib/MeasureTheory/Function/ConditionalExpectation/CondexpL1.lean @@ -135,7 +135,7 @@ theorem norm_condexpIndL1Fin_le (hs : MeasurableSet s) (hμs : μ s ≠ ∞) (x exact lintegral_nnnorm_condexpIndSMul_le hm hs hμs x theorem condexpIndL1Fin_disjoint_union (hs : MeasurableSet s) (ht : MeasurableSet t) (hμs : μ s ≠ ∞) - (hμt : μ t ≠ ∞) (hst : s ∩ t = ∅) (x : G) : + (hμt : μ t ≠ ∞) (hst : Disjoint s t) (x : G) : condexpIndL1Fin hm (hs.union ht) ((measure_union_le s t).trans_lt (lt_top_iff_ne_top.mpr (ENNReal.add_ne_top.mpr ⟨hμs, hμt⟩))).ne x = condexpIndL1Fin hm hs hμs x + condexpIndL1Fin hm ht hμt x := by @@ -224,7 +224,7 @@ theorem continuous_condexpIndL1 : Continuous fun x : G => condexpIndL1 hm μ s x continuous_of_linear_of_bound condexpIndL1_add condexpIndL1_smul norm_condexpIndL1_le theorem condexpIndL1_disjoint_union (hs : MeasurableSet s) (ht : MeasurableSet t) (hμs : μ s ≠ ∞) - (hμt : μ t ≠ ∞) (hst : s ∩ t = ∅) (x : G) : + (hμt : μ t ≠ ∞) (hst : Disjoint s t) (x : G) : condexpIndL1 hm μ (s ∪ t) x = condexpIndL1 hm μ s x + condexpIndL1 hm μ t x := by have hμst : μ (s ∪ t) ≠ ∞ := ((measure_union_le s t).trans_lt (lt_top_iff_ne_top.mpr (ENNReal.add_ne_top.mpr ⟨hμs, hμt⟩))).ne @@ -283,12 +283,12 @@ theorem norm_condexpInd_le : ‖(condexpInd G hm μ s : G →L[ℝ] α →₁[μ ContinuousLinearMap.opNorm_le_bound _ ENNReal.toReal_nonneg norm_condexpInd_apply_le theorem condexpInd_disjoint_union_apply (hs : MeasurableSet s) (ht : MeasurableSet t) - (hμs : μ s ≠ ∞) (hμt : μ t ≠ ∞) (hst : s ∩ t = ∅) (x : G) : + (hμs : μ s ≠ ∞) (hμt : μ t ≠ ∞) (hst : Disjoint s t) (x : G) : condexpInd G hm μ (s ∪ t) x = condexpInd G hm μ s x + condexpInd G hm μ t x := condexpIndL1_disjoint_union hs ht hμs hμt hst x theorem condexpInd_disjoint_union (hs : MeasurableSet s) (ht : MeasurableSet t) (hμs : μ s ≠ ∞) - (hμt : μ t ≠ ∞) (hst : s ∩ t = ∅) : (condexpInd G hm μ (s ∪ t) : G →L[ℝ] α →₁[μ] G) = + (hμt : μ t ≠ ∞) (hst : Disjoint s t) : (condexpInd G hm μ (s ∪ t) : G →L[ℝ] α →₁[μ] G) = condexpInd G hm μ s + condexpInd G hm μ t := by ext1 x; push_cast; exact condexpInd_disjoint_union_apply hs ht hμs hμt hst x diff --git a/Mathlib/MeasureTheory/Function/LpSpace.lean b/Mathlib/MeasureTheory/Function/LpSpace.lean index a20a1c45824a73..7e5941d3645180 100644 --- a/Mathlib/MeasureTheory/Function/LpSpace.lean +++ b/Mathlib/MeasureTheory/Function/LpSpace.lean @@ -857,7 +857,7 @@ theorem memℒp_add_of_disjoint {f g : α → E} (h : Disjoint (support f) (supp /-- The indicator of a disjoint union of two sets is the sum of the indicators of the sets. -/ theorem indicatorConstLp_disjoint_union {s t : Set α} (hs : MeasurableSet s) (ht : MeasurableSet t) - (hμs : μ s ≠ ∞) (hμt : μ t ≠ ∞) (hst : s ∩ t = ∅) (c : E) : + (hμs : μ s ≠ ∞) (hμt : μ t ≠ ∞) (hst : Disjoint s t) (c : E) : indicatorConstLp p (hs.union ht) (measure_union_ne_top hμs hμt) c = indicatorConstLp p hs hμs c + indicatorConstLp p ht hμt c := by ext1 @@ -865,7 +865,7 @@ theorem indicatorConstLp_disjoint_union {s t : Set α} (hs : MeasurableSet s) (h refine EventuallyEq.trans ?_ (EventuallyEq.add indicatorConstLp_coeFn.symm indicatorConstLp_coeFn.symm) - rw [Set.indicator_union_of_disjoint (Set.disjoint_iff_inter_eq_empty.mpr hst) _] + rw [Set.indicator_union_of_disjoint hst] end IndicatorConstLp diff --git a/Mathlib/MeasureTheory/Integral/Bochner.lean b/Mathlib/MeasureTheory/Integral/Bochner.lean index b4eab8d959db67..b497a13fc272b3 100644 --- a/Mathlib/MeasureTheory/Integral/Bochner.lean +++ b/Mathlib/MeasureTheory/Integral/Bochner.lean @@ -201,18 +201,17 @@ theorem weightedSMul_null {s : Set α} (h_zero : μ s = 0) : (weightedSMul μ s ext1 x; rw [weightedSMul_apply, h_zero]; simp theorem weightedSMul_union' (s t : Set α) (ht : MeasurableSet t) (hs_finite : μ s ≠ ∞) - (ht_finite : μ t ≠ ∞) (h_inter : s ∩ t = ∅) : + (ht_finite : μ t ≠ ∞) (hdisj : Disjoint s t) : (weightedSMul μ (s ∪ t) : F →L[ℝ] F) = weightedSMul μ s + weightedSMul μ t := by ext1 x - simp_rw [add_apply, weightedSMul_apply, - measure_union (Set.disjoint_iff_inter_eq_empty.mpr h_inter) ht, + simp_rw [add_apply, weightedSMul_apply, measure_union hdisj ht, ENNReal.toReal_add hs_finite ht_finite, add_smul] @[nolint unusedArguments] theorem weightedSMul_union (s t : Set α) (_hs : MeasurableSet s) (ht : MeasurableSet t) - (hs_finite : μ s ≠ ∞) (ht_finite : μ t ≠ ∞) (h_inter : s ∩ t = ∅) : + (hs_finite : μ s ≠ ∞) (ht_finite : μ t ≠ ∞) (hdisj : Disjoint s t) : (weightedSMul μ (s ∪ t) : F →L[ℝ] F) = weightedSMul μ s + weightedSMul μ t := - weightedSMul_union' s t ht hs_finite ht_finite h_inter + weightedSMul_union' s t ht hs_finite ht_finite hdisj theorem weightedSMul_smul [NormedField 𝕜] [NormedSpace 𝕜 F] [SMulCommClass ℝ 𝕜 F] (c : 𝕜) (s : Set α) (x : F) : weightedSMul μ s (c • x) = c • weightedSMul μ s x := by diff --git a/Mathlib/MeasureTheory/Integral/SetToL1.lean b/Mathlib/MeasureTheory/Integral/SetToL1.lean index e4fe8a61b787a9..3d16c95fed2c12 100644 --- a/Mathlib/MeasureTheory/Integral/SetToL1.lean +++ b/Mathlib/MeasureTheory/Integral/SetToL1.lean @@ -9,7 +9,7 @@ import Mathlib.MeasureTheory.Function.SimpleFuncDenseLp # Extension of a linear function from indicators to L1 Let `T : Set α → E →L[ℝ] F` be additive for measurable sets with finite measure, in the sense that -for `s, t` two such sets, `s ∩ t = ∅ → T (s ∪ t) = T s + T t`. `T` is akin to a bilinear map on +for `s, t` two such sets, `Disjoint s t → T (s ∪ t) = T s + T t`. `T` is akin to a bilinear map on `Set α × E`, or a linear map on indicator functions. This file constructs an extension of `T` to integrable simple functions, which are finite sums of @@ -23,7 +23,7 @@ expectation of an integrable function in `MeasureTheory.Function.ConditionalExpe ## Main Definitions - `FinMeasAdditive μ T`: the property that `T` is additive on measurable sets with finite measure. - For two such sets, `s ∩ t = ∅ → T (s ∪ t) = T s + T t`. + For two such sets, `Disjoint s t → T (s ∪ t) = T s + T t`. - `DominatedFinMeasAdditive μ T C`: `FinMeasAdditive μ T ∧ ∀ s, ‖T s‖ ≤ C * (μ s).toReal`. This is the property needed to perform the extension from indicators to L1. - `setToL1 (hT : DominatedFinMeasAdditive μ T C) : (α →₁[μ] E) →L[ℝ] F`: the extension of `T` @@ -90,7 +90,8 @@ section FinMeasAdditive sets with finite measure is the sum of its values on each set. -/ def FinMeasAdditive {β} [AddMonoid β] {_ : MeasurableSpace α} (μ : Measure α) (T : Set α → β) : Prop := - ∀ s t, MeasurableSet s → MeasurableSet t → μ s ≠ ∞ → μ t ≠ ∞ → s ∩ t = ∅ → T (s ∪ t) = T s + T t + ∀ s t, MeasurableSet s → MeasurableSet t → μ s ≠ ∞ → μ t ≠ ∞ → Disjoint s t → + T (s ∪ t) = T s + T t namespace FinMeasAdditive @@ -133,7 +134,7 @@ theorem smul_measure_iff (c : ℝ≥0∞) (hc_ne_zero : c ≠ 0) (hc_ne_top : c theorem map_empty_eq_zero {β} [AddCancelMonoid β] {T : Set α → β} (hT : FinMeasAdditive μ T) : T ∅ = 0 := by have h_empty : μ ∅ ≠ ∞ := (measure_empty.le.trans_lt ENNReal.coe_lt_top).ne - specialize hT ∅ ∅ MeasurableSet.empty MeasurableSet.empty h_empty h_empty (Set.inter_empty ∅) + specialize hT ∅ ∅ MeasurableSet.empty MeasurableSet.empty h_empty h_empty (disjoint_empty _) rw [Set.union_empty] at hT nth_rw 1 [← add_zero (T ∅)] at hT exact (add_left_cancel hT).symm @@ -160,10 +161,9 @@ theorem map_iUnion_fin_meas_set_eq_sum (T : Set α → β) (T_empty : T ∅ = 0) · congr; convert Finset.iSup_insert a s S · exact (measure_biUnion_lt_top s.finite_toSet fun i hi ↦ (hps i <| Finset.mem_insert_of_mem hi).lt_top).ne - · simp_rw [Set.inter_iUnion] - refine iUnion_eq_empty.mpr fun i => iUnion_eq_empty.mpr fun hi => ?_ - rw [← Set.disjoint_iff_inter_eq_empty] - refine h_disj a (Finset.mem_insert_self a s) i (Finset.mem_insert_of_mem hi) fun hai => ?_ + · simp_rw [Set.disjoint_iUnion_right] + intro i hi + refine h_disj a (Finset.mem_insert_self a s) i (Finset.mem_insert_of_mem hi) fun hai ↦ ?_ rw [← hai] at hi exact has hi From 484ebdb314975169309726cd7395071b5663fb74 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Fri, 18 Oct 2024 20:13:24 +1100 Subject: [PATCH 363/425] bump deps --- lake-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lake-manifest.json b/lake-manifest.json index f8cd3cf6d0da72..96a345843c8886 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "fbc501009ac92d25302279d9716cfdc405fabe8d", + "rev": "2ddb1c16a016c14f5dd344faec974c03b17255a7", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "nightly-testing", From ec349bacca2d1e67eae5142d16b30a202510578d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 18 Oct 2024 09:18:36 +0000 Subject: [PATCH 364/425] chore(PosPart): Make more lemmas simp (#17053) --- Mathlib/Algebra/Order/Group/PosPart.lean | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Order/Group/PosPart.lean b/Mathlib/Algebra/Order/Group/PosPart.lean index 085e56c1b0be23..eb8835fa801345 100644 --- a/Mathlib/Algebra/Order/Group/PosPart.lean +++ b/Mathlib/Algebra/Order/Group/PosPart.lean @@ -65,7 +65,7 @@ instance instLeOnePart : LeOnePart α where @[to_additive] lemma oneLePart_mono : Monotone (·⁺ᵐ : α → α) := fun _a _b hab ↦ sup_le_sup_right hab _ -@[to_additive (attr := simp)] lemma oneLePart_one : (1 : α)⁺ᵐ = 1 := sup_idem _ +@[to_additive (attr := simp high)] lemma oneLePart_one : (1 : α)⁺ᵐ = 1 := sup_idem _ @[to_additive (attr := simp)] lemma leOnePart_one : (1 : α)⁻ᵐ = 1 := by simp [leOnePart] @@ -79,8 +79,10 @@ instance instLeOnePart : LeOnePart α where @[to_additive] lemma inv_le_leOnePart (a : α) : a⁻¹ ≤ a⁻ᵐ := le_sup_left @[to_additive (attr := simp)] lemma oneLePart_eq_self : a⁺ᵐ = a ↔ 1 ≤ a := sup_eq_left +@[to_additive (attr := simp)] lemma oneLePart_eq_one : a⁺ᵐ = 1 ↔ a ≤ 1 := sup_eq_right -@[to_additive] lemma oneLePart_eq_one : a⁺ᵐ = 1 ↔ a ≤ 1 := sup_eq_right +@[to_additive (attr := simp)] alias ⟨_, oneLePart_of_one_le⟩ := oneLePart_eq_self +@[to_additive (attr := simp)] alias ⟨_, oneLePart_of_le_one⟩ := oneLePart_eq_one /-- See also `leOnePart_eq_inv`. -/ @[to_additive "See also `negPart_eq_neg`."] @@ -114,6 +116,9 @@ variable [CovariantClass α α (· * ·) (· ≤ ·)] @[to_additive (attr := simp)] lemma leOnePart_eq_one : a⁻ᵐ = 1 ↔ 1 ≤ a := by simp [leOnePart_eq_one'] +@[to_additive (attr := simp)] alias ⟨_, leOnePart_of_le_one⟩ := leOnePart_eq_inv +@[to_additive (attr := simp)] alias ⟨_, leOnePart_of_one_le⟩ := leOnePart_eq_one + @[to_additive (attr := simp) negPart_pos] lemma one_lt_ltOnePart (ha : a < 1) : 1 < a⁻ᵐ := by rwa [leOnePart_eq_inv.2 ha.le, one_lt_inv'] From 3b5cedb7b2da9faae67402d7a66a75e5f44b666e Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Fri, 18 Oct 2024 09:18:37 +0000 Subject: [PATCH 365/425] feat(Topology): define `ContinuousEval{,Const}` classes (#17319) --- Mathlib.lean | 2 + .../NormedSpace/Multilinear/Basic.lean | 27 +++--- Mathlib/Analysis/ODE/PicardLindelof.lean | 4 +- .../Topology/Algebra/ContinuousMonoidHom.lean | 15 +++- .../Algebra/Module/Alternating/Topology.lean | 26 +++--- .../Algebra/Module/Multilinear/Topology.lean | 27 +++--- .../Algebra/Module/StrongTopology.lean | 30 ++++--- Mathlib/Topology/CompactOpen.lean | 41 +++++---- Mathlib/Topology/Connected/PathConnected.lean | 14 +-- Mathlib/Topology/ContinuousMap/Algebra.lean | 40 +++++---- .../ContinuousMap/ContinuousMapZero.lean | 12 ++- Mathlib/Topology/Hom/ContinuousEval.lean | 69 ++++++++++++++ Mathlib/Topology/Hom/ContinuousEvalConst.lean | 89 +++++++++++++++++++ Mathlib/Topology/Homotopy/HSpaces.lean | 2 +- Mathlib/Topology/Homotopy/HomotopyGroup.lean | 8 +- Mathlib/Topology/Homotopy/Path.lean | 10 +-- 16 files changed, 307 insertions(+), 109 deletions(-) create mode 100644 Mathlib/Topology/Hom/ContinuousEval.lean create mode 100644 Mathlib/Topology/Hom/ContinuousEvalConst.lean diff --git a/Mathlib.lean b/Mathlib.lean index 6b0d74489e5e71..1e5548b290acc8 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4716,6 +4716,8 @@ import Mathlib.Topology.Filter import Mathlib.Topology.GDelta import Mathlib.Topology.Germ import Mathlib.Topology.Gluing +import Mathlib.Topology.Hom.ContinuousEval +import Mathlib.Topology.Hom.ContinuousEvalConst import Mathlib.Topology.Hom.Open import Mathlib.Topology.Homeomorph import Mathlib.Topology.Homotopy.Basic diff --git a/Mathlib/Analysis/NormedSpace/Multilinear/Basic.lean b/Mathlib/Analysis/NormedSpace/Multilinear/Basic.lean index ceb978b4e25e75..7f88338734d621 100644 --- a/Mathlib/Analysis/NormedSpace/Multilinear/Basic.lean +++ b/Mathlib/Analysis/NormedSpace/Multilinear/Basic.lean @@ -80,16 +80,19 @@ variable {𝕜 ι : Type*} {E : ι → Type*} {F : Type*} [NormedField 𝕜] [Finite ι] [∀ i, SeminormedAddCommGroup (E i)] [∀ i, NormedSpace 𝕜 (E i)] [TopologicalSpace F] [AddCommGroup F] [TopologicalAddGroup F] [Module 𝕜 F] -/-- Applying a multilinear map to a vector is continuous in both coordinates. -/ -theorem ContinuousMultilinearMap.continuous_eval : - Continuous fun p : ContinuousMultilinearMap 𝕜 E F × ∀ i, E i => p.1 p.2 := by - cases nonempty_fintype ι - let _ := TopologicalAddGroup.toUniformSpace F - have := comm_topologicalAddGroup_is_uniform (G := F) - refine (UniformOnFun.continuousOn_eval₂ fun m ↦ ?_).comp_continuous - (embedding_toUniformOnFun.continuous.prodMap continuous_id) fun (f, x) ↦ f.cont.continuousAt - exact ⟨ball m 1, NormedSpace.isVonNBounded_of_isBounded _ isBounded_ball, - ball_mem_nhds _ one_pos⟩ +instance ContinuousMultilinearMap.instContinuousEval : + ContinuousEval (ContinuousMultilinearMap 𝕜 E F) (Π i, E i) F where + continuous_eval := by + cases nonempty_fintype ι + let _ := TopologicalAddGroup.toUniformSpace F + have := comm_topologicalAddGroup_is_uniform (G := F) + refine (UniformOnFun.continuousOn_eval₂ fun m ↦ ?_).comp_continuous + (embedding_toUniformOnFun.continuous.prodMap continuous_id) fun (f, x) ↦ f.cont.continuousAt + exact ⟨ball m 1, NormedSpace.isVonNBounded_of_isBounded _ isBounded_ball, + ball_mem_nhds _ one_pos⟩ + +@[deprecated (since := "2024-10-05")] +protected alias ContinuousMultilinearMap.continuous_eval := continuous_eval namespace ContinuousLinearMap @@ -97,8 +100,8 @@ variable {G : Type*} [AddCommGroup G] [TopologicalSpace G] [Module 𝕜 G] [Cont (f : G →L[𝕜] ContinuousMultilinearMap 𝕜 E F) lemma continuous_uncurry_of_multilinear : - Continuous (fun (p : G × (Π i, E i)) ↦ f p.1 p.2) := - ContinuousMultilinearMap.continuous_eval.comp <| .prodMap (map_continuous f) continuous_id + Continuous (fun (p : G × (Π i, E i)) ↦ f p.1 p.2) := by + fun_prop lemma continuousOn_uncurry_of_multilinear {s} : ContinuousOn (fun (p : G × (Π i, E i)) ↦ f p.1 p.2) s := diff --git a/Mathlib/Analysis/ODE/PicardLindelof.lean b/Mathlib/Analysis/ODE/PicardLindelof.lean index 1f6996fcbf20ef..bf6d91625d9e7a 100644 --- a/Mathlib/Analysis/ODE/PicardLindelof.lean +++ b/Mathlib/Analysis/ODE/PicardLindelof.lean @@ -223,10 +223,10 @@ instance [CompleteSpace E] : CompleteSpace v.FunSpace := by refine (completeSpace_iff_isComplete_range isUniformInducing_toContinuousMap).2 (IsClosed.isComplete ?_) rw [range_toContinuousMap, setOf_and] - refine (isClosed_eq (ContinuousMap.continuous_eval_const _) continuous_const).inter ?_ + refine (isClosed_eq (continuous_eval_const _) continuous_const).inter ?_ have : IsClosed {f : Icc v.tMin v.tMax → E | LipschitzWith v.C f} := isClosed_setOf_lipschitzWith v.C - exact this.preimage ContinuousMap.continuous_coe + exact this.preimage continuous_coeFun theorem intervalIntegrable_vComp (t₁ t₂ : ℝ) : IntervalIntegrable f.vComp volume t₁ t₂ := f.continuous_vComp.intervalIntegrable _ _ diff --git a/Mathlib/Topology/Algebra/ContinuousMonoidHom.lean b/Mathlib/Topology/Algebra/ContinuousMonoidHom.lean index 4e852f064519b4..a41b781ceaadc5 100644 --- a/Mathlib/Topology/Algebra/ContinuousMonoidHom.lean +++ b/Mathlib/Topology/Algebra/ContinuousMonoidHom.lean @@ -240,6 +240,15 @@ theorem embedding_toContinuousMap : Embedding (toContinuousMap : ContinuousMonoidHom A B → C(A, B)) := ⟨inducing_toContinuousMap A B, toContinuousMap_injective⟩ +@[to_additive] +instance instContinuousEvalConst : ContinuousEvalConst (ContinuousMonoidHom A B) A B := + .of_continuous_forget (inducing_toContinuousMap A B).continuous + +@[to_additive] +instance instContinuousEval [LocallyCompactPair A B] : + ContinuousEval (ContinuousMonoidHom A B) A B := + .of_continuous_forget (inducing_toContinuousMap A B).continuous + @[to_additive] lemma range_toContinuousMap : Set.range (toContinuousMap : ContinuousMonoidHom A B → C(A, B)) = @@ -254,10 +263,10 @@ theorem closedEmbedding_toContinuousMap [ContinuousMul B] [T2Space B] : toEmbedding := embedding_toContinuousMap A B isClosed_range := by simp only [range_toContinuousMap, Set.setOf_and, Set.setOf_forall] - refine .inter (isClosed_singleton.preimage (ContinuousMap.continuous_eval_const 1)) <| + refine .inter (isClosed_singleton.preimage (continuous_eval_const 1)) <| isClosed_iInter fun x ↦ isClosed_iInter fun y ↦ ?_ - exact isClosed_eq (ContinuousMap.continuous_eval_const (x * y)) <| - .mul (ContinuousMap.continuous_eval_const x) (ContinuousMap.continuous_eval_const y) + exact isClosed_eq (continuous_eval_const (x * y)) <| + .mul (continuous_eval_const x) (continuous_eval_const y) variable {A B C D E} diff --git a/Mathlib/Topology/Algebra/Module/Alternating/Topology.lean b/Mathlib/Topology/Algebra/Module/Alternating/Topology.lean index 32efbbd5a39c7e..52bcb32bef151f 100644 --- a/Mathlib/Topology/Algebra/Module/Alternating/Topology.lean +++ b/Mathlib/Topology/Algebra/Module/Alternating/Topology.lean @@ -36,7 +36,7 @@ lemma isClosed_range_toContinuousMultilinearMap [ContinuousSMul 𝕜 E] [T2Space ContinuousMultilinearMap 𝕜 (fun _ : ι ↦ E) F)) := by simp only [range_toContinuousMultilinearMap, setOf_forall] repeat refine isClosed_iInter fun _ ↦ ?_ - exact isClosed_singleton.preimage (ContinuousMultilinearMap.continuous_eval_const _) + exact isClosed_singleton.preimage (continuous_eval_const _) end IsClosedRange @@ -125,6 +125,10 @@ lemma embedding_toContinuousMultilinearMap : haveI := comm_topologicalAddGroup_is_uniform (G := F) isUniformEmbedding_toContinuousMultilinearMap.embedding +instance instTopologicalAddGroup : TopologicalAddGroup (E [⋀^ι]→L[𝕜] F) := + embedding_toContinuousMultilinearMap.topologicalAddGroup + (toContinuousMultilinearMapLinear (R := ℕ)) + @[continuity, fun_prop] lemma continuous_toContinuousMultilinearMap : Continuous (toContinuousMultilinearMap : (E [⋀^ι]→L[𝕜] F → _)) := @@ -159,21 +163,19 @@ lemma closedEmbedding_toContinuousMultilinearMap [T2Space F] : (E [⋀^ι]→L[𝕜] F) → ContinuousMultilinearMap 𝕜 (fun _ : ι ↦ E) F) := ⟨embedding_toContinuousMultilinearMap, isClosed_range_toContinuousMultilinearMap⟩ -@[continuity, fun_prop] -theorem continuous_eval_const (x : ι → E) : - Continuous fun p : E [⋀^ι]→L[𝕜] F ↦ p x := - (ContinuousMultilinearMap.continuous_eval_const x).comp continuous_toContinuousMultilinearMap +instance instContinuousEvalConst : ContinuousEvalConst (E [⋀^ι]→L[𝕜] F) (ι → E) F := + .of_continuous_forget continuous_toContinuousMultilinearMap -theorem continuous_coe_fun : - Continuous (DFunLike.coe : E [⋀^ι]→L[𝕜] F → (ι → E) → F) := - continuous_pi continuous_eval_const +@[deprecated (since := "2024-10-05")] +protected alias continuous_eval_const := continuous_eval_const + +@[deprecated (since := "2024-10-05")] +protected alias continuous_coe_fun := continuous_coeFun instance instT2Space [T2Space F] : T2Space (E [⋀^ι]→L[𝕜] F) := - .of_injective_continuous DFunLike.coe_injective continuous_coe_fun + .of_injective_continuous DFunLike.coe_injective continuous_coeFun -instance instT3Space [T2Space F] : T2Space (E [⋀^ι]→L[𝕜] F) := - letI : UniformSpace F := TopologicalAddGroup.toUniformSpace F - haveI : UniformAddGroup F := comm_topologicalAddGroup_is_uniform +instance instT3Space [T2Space F] : T3Space (E [⋀^ι]→L[𝕜] F) := inferInstance section RestrictScalars diff --git a/Mathlib/Topology/Algebra/Module/Multilinear/Topology.lean b/Mathlib/Topology/Algebra/Module/Multilinear/Topology.lean index baf4b78201f9af..19af25db016c5e 100644 --- a/Mathlib/Topology/Algebra/Module/Multilinear/Topology.lean +++ b/Mathlib/Topology/Algebra/Module/Multilinear/Topology.lean @@ -5,6 +5,7 @@ Authors: Yury Kudryashov -/ import Mathlib.Topology.Algebra.Module.Multilinear.Bounded import Mathlib.Topology.Algebra.Module.UniformConvergence +import Mathlib.Topology.Hom.ContinuousEvalConst /-! # Topology on continuous multilinear maps @@ -152,6 +153,11 @@ end UniformAddGroup variable [TopologicalSpace F] [TopologicalAddGroup F] +instance instTopologicalAddGroup : TopologicalAddGroup (ContinuousMultilinearMap 𝕜 E F) := + letI := TopologicalAddGroup.toUniformSpace F + haveI := comm_topologicalAddGroup_is_uniform (G := F) + inferInstance + instance instContinuousConstSMul {M : Type*} [Monoid M] [DistribMulAction M F] [SMulCommClass 𝕜 M F] [ContinuousConstSMul M F] : ContinuousConstSMul M (ContinuousMultilinearMap 𝕜 E F) := by @@ -188,20 +194,21 @@ theorem hasBasis_nhds_zero : variable [∀ i, ContinuousSMul 𝕜 (E i)] -theorem continuous_eval_const (x : Π i, E i) : - Continuous fun p : ContinuousMultilinearMap 𝕜 E F ↦ p x := by - letI := TopologicalAddGroup.toUniformSpace F - haveI := comm_topologicalAddGroup_is_uniform (G := F) - exact (uniformContinuous_eval_const x).continuous +instance : ContinuousEvalConst (ContinuousMultilinearMap 𝕜 E F) (Π i, E i) F where + continuous_eval_const x := + let _ := TopologicalAddGroup.toUniformSpace F + have _ := comm_topologicalAddGroup_is_uniform (G := F) + (uniformContinuous_eval_const x).continuous +@[deprecated (since := "2024-10-05")] protected alias continuous_eval_const := continuous_eval_const @[deprecated (since := "2024-04-10")] alias continuous_eval_left := continuous_eval_const - -theorem continuous_coe_fun : - Continuous (DFunLike.coe : ContinuousMultilinearMap 𝕜 E F → (Π i, E i) → F) := - continuous_pi continuous_eval_const +@[deprecated (since := "2024-10-05")] protected alias continuous_coe_fun := continuous_coeFun instance instT2Space [T2Space F] : T2Space (ContinuousMultilinearMap 𝕜 E F) := - .of_injective_continuous DFunLike.coe_injective continuous_coe_fun + .of_injective_continuous DFunLike.coe_injective continuous_coeFun + +instance instT3Space [T2Space F] : T3Space (ContinuousMultilinearMap 𝕜 E F) := + inferInstance section RestrictScalars diff --git a/Mathlib/Topology/Algebra/Module/StrongTopology.lean b/Mathlib/Topology/Algebra/Module/StrongTopology.lean index 8e988265fd7450..3132c5f3d16b8e 100644 --- a/Mathlib/Topology/Algebra/Module/StrongTopology.lean +++ b/Mathlib/Topology/Algebra/Module/StrongTopology.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Anatole Dedecker -/ import Mathlib.Topology.Algebra.Module.UniformConvergence +import Mathlib.Topology.Hom.ContinuousEvalConst /-! # Strong topologies on the space of continuous linear maps @@ -151,12 +152,19 @@ instance instTopologicalAddGroup [TopologicalSpace F] [TopologicalAddGroup F] haveI : UniformAddGroup F := comm_topologicalAddGroup_is_uniform infer_instance +theorem continuousEvalConst [TopologicalSpace F] [TopologicalAddGroup F] + (𝔖 : Set (Set E)) (h𝔖 : ⋃₀ 𝔖 = Set.univ) : + ContinuousEvalConst (UniformConvergenceCLM σ F 𝔖) E F where + continuous_eval_const x := by + letI : UniformSpace F := TopologicalAddGroup.toUniformSpace F + haveI : UniformAddGroup F := comm_topologicalAddGroup_is_uniform + exact (UniformOnFun.uniformContinuous_eval h𝔖 x).continuous.comp + (embedding_coeFn σ F 𝔖).continuous + theorem t2Space [TopologicalSpace F] [TopologicalAddGroup F] [T2Space F] - (𝔖 : Set (Set E)) (h𝔖 : ⋃₀ 𝔖 = univ) : T2Space (UniformConvergenceCLM σ F 𝔖) := by - letI : UniformSpace F := TopologicalAddGroup.toUniformSpace F - haveI : UniformAddGroup F := comm_topologicalAddGroup_is_uniform - haveI : T2Space (E →ᵤ[𝔖] F) := UniformOnFun.t2Space_of_covering h𝔖 - exact (embedding_coeFn σ F 𝔖).t2Space + (𝔖 : Set (Set E)) (h𝔖 : ⋃₀ 𝔖 = univ) : T2Space (UniformConvergenceCLM σ F 𝔖) := + have := continuousEvalConst σ F 𝔖 h𝔖 + .of_injective_continuous DFunLike.coe_injective continuous_coeFun instance instDistribMulAction (M : Type*) [Monoid M] [DistribMulAction M F] [SMulCommClass 𝕜₂ M F] [TopologicalSpace F] [TopologicalAddGroup F] [ContinuousConstSMul M F] (𝔖 : Set (Set E)) : @@ -321,11 +329,13 @@ instance uniformSpace [UniformSpace F] [UniformAddGroup F] : UniformSpace (E → instance uniformAddGroup [UniformSpace F] [UniformAddGroup F] : UniformAddGroup (E →SL[σ] F) := UniformConvergenceCLM.instUniformAddGroup σ F _ -instance [TopologicalSpace F] [TopologicalAddGroup F] [ContinuousSMul 𝕜₁ E] [T2Space F] : - T2Space (E →SL[σ] F) := - UniformConvergenceCLM.t2Space σ F _ - (Set.eq_univ_of_forall fun x => - Set.mem_sUnion_of_mem (Set.mem_singleton x) (isVonNBounded_singleton x)) +instance instContinuousEvalConst [TopologicalSpace F] [TopologicalAddGroup F] + [ContinuousSMul 𝕜₁ E] : ContinuousEvalConst (E →SL[σ] F) E F := + UniformConvergenceCLM.continuousEvalConst σ F _ Bornology.isVonNBounded_covers + +instance instT2Space [TopologicalSpace F] [TopologicalAddGroup F] [ContinuousSMul 𝕜₁ E] + [T2Space F] : T2Space (E →SL[σ] F) := + UniformConvergenceCLM.t2Space σ F _ Bornology.isVonNBounded_covers protected theorem hasBasis_nhds_zero_of_basis [TopologicalSpace F] [TopologicalAddGroup F] {ι : Type*} {p : ι → Prop} {b : ι → Set F} (h : (𝓝 0 : Filter F).HasBasis p b) : diff --git a/Mathlib/Topology/CompactOpen.lean b/Mathlib/Topology/CompactOpen.lean index c4e0af021885c1..9c199df740de26 100644 --- a/Mathlib/Topology/CompactOpen.lean +++ b/Mathlib/Topology/CompactOpen.lean @@ -3,6 +3,7 @@ Copyright (c) 2018 Reid Barton. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Reid Barton -/ +import Mathlib.Topology.Hom.ContinuousEval import Mathlib.Topology.ContinuousMap.Basic /-! @@ -160,27 +161,24 @@ section Ev /-- The evaluation map `C(X, Y) × X → Y` is continuous if `X, Y` is a locally compact pair of spaces. -/ -@[continuity] -theorem continuous_eval [LocallyCompactPair X Y] : Continuous fun p : C(X, Y) × X => p.1 p.2 := by - simp_rw [continuous_iff_continuousAt, ContinuousAt, (nhds_basis_opens _).tendsto_right_iff] - rintro ⟨f, x⟩ U ⟨hx : f x ∈ U, hU : IsOpen U⟩ - rcases exists_mem_nhds_isCompact_mapsTo f.continuous (hU.mem_nhds hx) with ⟨K, hxK, hK, hKU⟩ - filter_upwards [prod_mem_nhds (eventually_mapsTo hK hU hKU) hxK] using fun _ h ↦ h.1 h.2 +instance [LocallyCompactPair X Y] : ContinuousEval C(X, Y) X Y where + continuous_eval := by + simp_rw [continuous_iff_continuousAt, ContinuousAt, (nhds_basis_opens _).tendsto_right_iff] + rintro ⟨f, x⟩ U ⟨hx : f x ∈ U, hU : IsOpen U⟩ + rcases exists_mem_nhds_isCompact_mapsTo f.continuous (hU.mem_nhds hx) with ⟨K, hxK, hK, hKU⟩ + filter_upwards [prod_mem_nhds (eventually_mapsTo hK hU hKU) hxK] using fun _ h ↦ h.1 h.2 -/-- Evaluation of a continuous map `f` at a point `x` is continuous in `f`. +@[deprecated (since := "2024-10-01")] protected alias continuous_eval := continuous_eval -Porting note: merged `continuous_eval_const` with `continuous_eval_const'` removing unneeded -assumptions. -/ -@[continuity] -theorem continuous_eval_const (a : X) : Continuous fun f : C(X, Y) => f a := - continuous_def.2 fun U hU ↦ by simpa using isOpen_setOf_mapsTo (isCompact_singleton (x := a)) hU +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 -/-- Coercion from `C(X, Y)` with compact-open topology to `X → Y` with pointwise convergence -topology is a continuous map. +@[deprecated (since := "2024-10-01")] protected alias continuous_eval_const := continuous_eval_const -Porting note: merged `continuous_coe` with `continuous_coe'` removing unneeded assumptions. -/ +@[deprecated continuous_coeFun (since := "2024-10-01")] theorem continuous_coe : Continuous ((⇑) : C(X, Y) → (X → Y)) := - continuous_pi continuous_eval_const + continuous_coeFun lemma isClosed_setOf_mapsTo {t : Set Y} (ht : IsClosed t) (s : Set X) : IsClosed {f : C(X, Y) | MapsTo f s t} := @@ -192,7 +190,7 @@ lemma isClopen_setOf_mapsTo (hK : IsCompact K) (hU : IsClopen U) : @[norm_cast] lemma specializes_coe {f g : C(X, Y)} : ⇑f ⤳ ⇑g ↔ f ⤳ g := by - refine ⟨fun h ↦ ?_, fun h ↦ h.map continuous_coe⟩ + refine ⟨fun h ↦ ?_, fun h ↦ h.map continuous_coeFun⟩ suffices ∀ K, IsCompact K → ∀ U, IsOpen U → MapsTo g K U → MapsTo f K U by simpa [specializes_iff_pure, nhds_compactOpen] exact fun K _ U hU hg x hx ↦ (h.map (continuous_apply x)).mem_open hU (hg hx) @@ -202,7 +200,7 @@ lemma inseparable_coe {f g : C(X, Y)} : Inseparable (f : X → Y) g ↔ Insepara simp only [inseparable_iff_specializes_and, specializes_coe] instance [T0Space Y] : T0Space C(X, Y) := - t0Space_of_injective_of_continuous DFunLike.coe_injective continuous_coe + t0Space_of_injective_of_continuous DFunLike.coe_injective continuous_coeFun instance [R0Space Y] : R0Space C(X, Y) where specializes_symmetric f g h := by @@ -210,10 +208,10 @@ instance [R0Space Y] : R0Space C(X, Y) where exact h.symm instance [T1Space Y] : T1Space C(X, Y) := - t1Space_of_injective_of_continuous DFunLike.coe_injective continuous_coe + t1Space_of_injective_of_continuous DFunLike.coe_injective continuous_coeFun instance [R1Space Y] : R1Space C(X, Y) := - .of_continuous_specializes_imp continuous_coe fun _ _ ↦ specializes_coe.1 + .of_continuous_specializes_imp continuous_coeFun fun _ _ ↦ specializes_coe.1 instance [T2Space Y] : T2Space C(X, Y) := inferInstance @@ -388,7 +386,8 @@ theorem continuous_uncurry [LocallyCompactSpace X] [LocallyCompactSpace Y] : Continuous (uncurry : C(X, C(Y, Z)) → C(X × Y, Z)) := by apply continuous_of_continuous_uncurry rw [← (Homeomorph.prodAssoc _ _ _).comp_continuous_iff'] - apply continuous_eval.comp (continuous_eval.prodMap continuous_id) + dsimp [Function.comp_def] + exact (continuous_fst.fst.eval continuous_fst.snd).eval continuous_snd /-- The family of constant maps: `Y → C(X, Y)` as a continuous map. -/ def const' : C(Y, C(X, Y)) := diff --git a/Mathlib/Topology/Connected/PathConnected.lean b/Mathlib/Topology/Connected/PathConnected.lean index e5798309d30d41..4cc61d6513e73a 100644 --- a/Mathlib/Topology/Connected/PathConnected.lean +++ b/Mathlib/Topology/Connected/PathConnected.lean @@ -198,14 +198,14 @@ compact-open topology on the space `C(I,X)` of continuous maps from `I` to `X`. instance topologicalSpace : TopologicalSpace (Path x y) := TopologicalSpace.induced ((↑) : _ → C(I, X)) ContinuousMap.compactOpen -theorem continuous_eval : Continuous fun p : Path x y × I => p.1 p.2 := - ContinuousMap.continuous_eval.comp <| - (continuous_induced_dom (α := Path x y)).prodMap continuous_id +instance : ContinuousEval (Path x y) I X := .of_continuous_forget continuous_induced_dom -@[continuity] +@[deprecated (since := "2024-10-04")] protected alias continuous_eval := continuous_eval + +@[deprecated Continuous.eval (since := "2024-10-04")] theorem _root_.Continuous.path_eval {Y} [TopologicalSpace Y] {f : Y → Path x y} {g : Y → I} - (hf : Continuous f) (hg : Continuous g) : Continuous fun y => f y (g y) := - Continuous.comp continuous_eval (hf.prod_mk hg) + (hf : Continuous f) (hg : Continuous g) : Continuous fun y => f y (g y) := by + continuity theorem continuous_uncurry_iff {Y} [TopologicalSpace Y] {g : Y → Path x y} : Continuous ↿g ↔ Continuous g := @@ -427,7 +427,7 @@ theorem symm_continuous_family {ι : Type*} [TopologicalSpace ι] @[continuity] theorem continuous_symm : Continuous (symm : Path x y → Path y x) := - continuous_uncurry_iff.mp <| symm_continuous_family _ (continuous_fst.path_eval continuous_snd) + continuous_uncurry_iff.mp <| symm_continuous_family _ (continuous_fst.eval continuous_snd) @[continuity] theorem continuous_uncurry_extend_of_continuous_family {ι : Type*} [TopologicalSpace ι] diff --git a/Mathlib/Topology/ContinuousMap/Algebra.lean b/Mathlib/Topology/ContinuousMap/Algebra.lean index 4e62f17e049be0..b6ff6659b48783 100644 --- a/Mathlib/Topology/ContinuousMap/Algebra.lean +++ b/Mathlib/Topology/ContinuousMap/Algebra.lean @@ -372,25 +372,27 @@ instance [CommGroup β] [TopologicalGroup β] : TopologicalGroup C(α, β) where uniformContinuous_inv.comp_tendstoUniformlyOn (tendsto_iff_forall_compact_tendstoUniformlyOn.mp Filter.tendsto_id K hK) --- TODO: rewrite the next three lemmas for products and deduce sum case via `to_additive`, once --- definition of `tprod` is in place -/-- If `α` is locally compact, and an infinite sum of functions in `C(α, β)` -converges to `g` (for the compact-open topology), then the pointwise sum converges to `g x` for -all `x ∈ α`. -/ -theorem hasSum_apply {γ : Type*} [AddCommMonoid β] [ContinuousAdd β] - {f : γ → C(α, β)} {g : C(α, β)} (hf : HasSum f g) (x : α) : - HasSum (fun i : γ => f i x) (g x) := by - let ev : C(α, β) →+ β := (Pi.evalAddMonoidHom _ x).comp coeFnAddMonoidHom - exact hf.map ev (ContinuousMap.continuous_eval_const x) - -theorem summable_apply [AddCommMonoid β] [ContinuousAdd β] {γ : Type*} {f : γ → C(α, β)} - (hf : Summable f) (x : α) : Summable fun i : γ => f i x := - (hasSum_apply hf.hasSum x).summable - -theorem tsum_apply [T2Space β] [AddCommMonoid β] [ContinuousAdd β] {γ : Type*} {f : γ → C(α, β)} - (hf : Summable f) (x : α) : - ∑' i : γ, f i x = (∑' i : γ, f i) x := - (hasSum_apply hf.hasSum x).tsum_eq +/-- If an infinite product of functions in `C(α, β)` converges to `g` +(for the compact-open topology), then the pointwise product converges to `g x` for all `x ∈ α`. -/ +@[to_additive + "If an infinite sum of functions in `C(α, β)` converges to `g` (for the compact-open topology), +then the pointwise sum converges to `g x` for all `x ∈ α`."] +theorem hasProd_apply {γ : Type*} [CommMonoid β] [ContinuousMul β] + {f : γ → C(α, β)} {g : C(α, β)} (hf : HasProd f g) (x : α) : + HasProd (fun i : γ => f i x) (g x) := by + let ev : C(α, β) →* β := (Pi.evalMonoidHom _ x).comp coeFnMonoidHom + exact hf.map ev (continuous_eval_const x) + +@[to_additive] +theorem multipliable_apply [CommMonoid β] [ContinuousMul β] {γ : Type*} {f : γ → C(α, β)} + (hf : Multipliable f) (x : α) : Multipliable fun i : γ => f i x := + (hasProd_apply hf.hasProd x).multipliable + +@[to_additive] +theorem tprod_apply [T2Space β] [CommMonoid β] [ContinuousMul β] {γ : Type*} {f : γ → C(α, β)} + (hf : Multipliable f) (x : α) : + ∏' i : γ, f i x = (∏' i : γ, f i) x := + (hasProd_apply hf.hasProd x).tprod_eq end ContinuousMap diff --git a/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean b/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean index 5fa65e8b7c342f..575b4e26ad07c1 100644 --- a/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean +++ b/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean @@ -85,15 +85,25 @@ lemma embedding_toContinuousMap : Embedding ((↑) : C(X, R)₀ → C(X, R)) whe inj _ _ h := ext fun x ↦ congr($(h) x) instance [T0Space R] : T0Space C(X, R)₀ := embedding_toContinuousMap.t0Space +instance [R0Space R] : R0Space C(X, R)₀ := embedding_toContinuousMap.r0Space instance [T1Space R] : T1Space C(X, R)₀ := embedding_toContinuousMap.t1Space +instance [R1Space R] : R1Space C(X, R)₀ := embedding_toContinuousMap.r1Space instance [T2Space R] : T2Space C(X, R)₀ := embedding_toContinuousMap.t2Space +instance [RegularSpace R] : RegularSpace C(X, R)₀ := embedding_toContinuousMap.regularSpace +instance [T3Space R] : T3Space C(X, R)₀ := embedding_toContinuousMap.t3Space + +instance instContinuousEvalConst : ContinuousEvalConst C(X, R)₀ X R := + .of_continuous_forget embedding_toContinuousMap.continuous + +instance instContinuousEval [LocallyCompactPair X R] : ContinuousEval C(X, R)₀ X R := + .of_continuous_forget embedding_toContinuousMap.continuous lemma closedEmbedding_toContinuousMap [T1Space R] : ClosedEmbedding ((↑) : C(X, R)₀ → C(X, R)) where toEmbedding := embedding_toContinuousMap isClosed_range := by rw [range_toContinuousMap] - exact isClosed_singleton.preimage <| ContinuousMap.continuous_eval_const 0 + exact isClosed_singleton.preimage <| continuous_eval_const 0 @[fun_prop] lemma continuous_comp_left {X Y Z : Type*} [TopologicalSpace X] diff --git a/Mathlib/Topology/Hom/ContinuousEval.lean b/Mathlib/Topology/Hom/ContinuousEval.lean new file mode 100644 index 00000000000000..7667c58b0d186a --- /dev/null +++ b/Mathlib/Topology/Hom/ContinuousEval.lean @@ -0,0 +1,69 @@ +/- +Copyright (c) 2024 Yury Kudryashov. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Yury Kudryashov +-/ +import Mathlib.Topology.Hom.ContinuousEvalConst +import Mathlib.Topology.ContinuousMap.Defs + +/-! +# Bundled maps with evaluation continuous in both variables + +In this file we define a class `ContinuousEval F X Y` +saying that `F` is a bundled morphism class (in the sense of `FunLike`) +with a topology such that `fun (f, x) : F × X ↦ f x` is a continuous function. +-/ + +open scoped Topology +open Filter + +/-- A typeclass saying that `F` is a bundled morphism class (in the sense of `FunLike`) +with a topology such that `fun (f, x) : F × X ↦ f x` is a continuous function. -/ +class ContinuousEval (F : Type*) (X Y : outParam Type*) [FunLike F X Y] + [TopologicalSpace F] [TopologicalSpace X] [TopologicalSpace Y] : Prop where + /-- Evaluation of a bundled morphism at a point is continuous in both variables. -/ + continuous_eval : Continuous fun fx : F × X ↦ fx.1 fx.2 + +export ContinuousEval (continuous_eval) + +variable {F X Y Z : Type*} [FunLike F X Y] + [TopologicalSpace F] [TopologicalSpace X] [TopologicalSpace Y] [ContinuousEval F X Y] + [TopologicalSpace Z] {f : Z → F} {g : Z → X} {s : Set Z} {z : Z} + +@[continuity, fun_prop] +protected theorem Continuous.eval (hf : Continuous f) (hg : Continuous g) : + Continuous fun z ↦ f z (g z) := + continuous_eval.comp (hf.prod_mk hg) + +/-- If a type `F'` of bundled morphisms admits a continuous projection +to a type satisfying `ContinuousEval`, +then `F'` satisfies this predicate too. + +The word "forget" in the name is motivated by the term "forgetful functor". -/ +theorem ContinuousEval.of_continuous_forget {F' : Type*} [FunLike F' X Y] [TopologicalSpace F'] + {f : F' → F} (hc : Continuous f) (hf : ∀ g, ⇑(f g) = g := by intro; rfl) : + ContinuousEval F' X Y where + continuous_eval := by simpa only [← hf] using hc.fst'.eval continuous_snd + +instance (priority := 100) ContinuousEval.toContinuousMapClass : ContinuousMapClass F X Y where + map_continuous _ := continuous_const.eval continuous_id + +instance (priority := 100) ContinuousEval.toContinuousEvalConst : ContinuousEvalConst F X Y where + continuous_eval_const _ := continuous_id.eval continuous_const + +protected theorem Filter.Tendsto.eval {α : Type*} {l : Filter α} {f : α → F} {f₀ : F} + {g : α → X} {x₀ : X} (hf : Tendsto f l (𝓝 f₀)) (hg : Tendsto g l (𝓝 x₀)) : + Tendsto (fun a ↦ f a (g a)) l (𝓝 (f₀ x₀)) := + (ContinuousEval.continuous_eval.tendsto _).comp (hf.prod_mk_nhds hg) + +protected nonrec theorem ContinuousAt.eval (hf : ContinuousAt f z) (hg : ContinuousAt g z) : + ContinuousAt (fun z ↦ f z (g z)) z := + hf.eval hg + +protected nonrec theorem ContinuousWithinAt.eval (hf : ContinuousWithinAt f s z) + (hg : ContinuousWithinAt g s z) : ContinuousWithinAt (fun z ↦ f z (g z)) s z := + hf.eval hg + +protected theorem ContinuousOn.eval (hf : ContinuousOn f s) (hg : ContinuousOn g s) : + ContinuousOn (fun z ↦ f z (g z)) s := + fun z hz ↦ (hf z hz).eval (hg z hz) diff --git a/Mathlib/Topology/Hom/ContinuousEvalConst.lean b/Mathlib/Topology/Hom/ContinuousEvalConst.lean new file mode 100644 index 00000000000000..6793028a59d887 --- /dev/null +++ b/Mathlib/Topology/Hom/ContinuousEvalConst.lean @@ -0,0 +1,89 @@ +/- +Copyright (c) 2024 Yury Kudryashov. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Yury Kudryashov +-/ +import Mathlib.Topology.Constructions + +/-! +# Bundled morphisms with continuous evaluation at a point + +In this file we define a typeclass +saying that `F` is a type of bundled morphisms (in the sense of `DFunLike`) +with a topology on `F` such that evaluation at a point is continuous in `f : F`. + +## Implementation Notes + +For now, we define the typeclass for non-dependent bundled functions only. +Whenever we add a type of bundled dependent functions with a topology having this property, +we may decide to generalize from `FunLike` to `DFunLike`. +-/ + +open scoped Topology +open Filter + +/-- A typeclass saying that `F` is a type of bundled morphisms (in the sense of `DFunLike`) +with a topology on `F` such that evaluation at a point is continuous in `f : F`. -/ +class ContinuousEvalConst (F : Type*) (α X : outParam Type*) [FunLike F α X] + [TopologicalSpace F] [TopologicalSpace X] : Prop where + continuous_eval_const (x : α) : Continuous fun f : F ↦ f x + +export ContinuousEvalConst (continuous_eval_const) + +section ContinuousEvalConst + +variable {F α X Z : Type*} [FunLike F α X] [TopologicalSpace F] [TopologicalSpace X] + [ContinuousEvalConst F α X] [TopologicalSpace Z] {f : Z → F} {s : Set Z} {z : Z} + +/-- If a type `F'` of bundled morphisms admits a continuous projection +to a type satisfying `ContinuousEvalConst`, +then `F'` satisfies this predicate too. + +The word "forget" in the name is motivated by the term "forgetful functor". -/ +theorem ContinuousEvalConst.of_continuous_forget {F' : Type*} [FunLike F' α X] [TopologicalSpace F'] + {f : F' → F} (hc : Continuous f) (hf : ∀ g, ⇑(f g) = g := by intro; rfl) : + ContinuousEvalConst F' α X where + continuous_eval_const x := by simpa only [← hf] using (continuous_eval_const x).comp hc + +@[continuity, fun_prop] +protected theorem Continuous.eval_const (hf : Continuous f) (x : α) : Continuous (f · x) := + (continuous_eval_const x).comp hf + +theorem continuous_coeFun : Continuous (DFunLike.coe : F → α → X) := + continuous_pi continuous_eval_const + +protected theorem Continuous.coeFun (hf : Continuous f) : Continuous fun z ↦ ⇑(f z) := + continuous_pi hf.eval_const + +protected theorem Filter.Tendsto.eval_const {ι : Type*} {l : Filter ι} {f : ι → F} {g : F} + (hf : Tendsto f l (𝓝 g)) (a : α) : Tendsto (f · a) l (𝓝 (g a)) := + ((continuous_id.eval_const a).tendsto _).comp hf + +protected theorem Filter.Tendsto.coeFun {ι : Type*} {l : Filter ι} {f : ι → F} {g : F} + (hf : Tendsto f l (𝓝 g)) : Tendsto (fun i ↦ ⇑(f i)) l (𝓝 ⇑g) := + (continuous_id.coeFun.tendsto _).comp hf + +protected nonrec theorem ContinuousAt.eval_const (hf : ContinuousAt f z) (x : α) : + ContinuousAt (f · x) z := + hf.eval_const x + +protected nonrec theorem ContinuousAt.coeFun (hf : ContinuousAt f z) : + ContinuousAt (fun z ↦ ⇑(f z)) z := + hf.coeFun + +protected nonrec theorem ContinuousWithinAt.eval_const (hf : ContinuousWithinAt f s z) (x : α) : + ContinuousWithinAt (f · x) s z := + hf.eval_const x + +protected nonrec theorem ContinuousWithinAt.coeFun (hf : ContinuousWithinAt f s z) : + ContinuousWithinAt (fun z ↦ ⇑(f z)) s z := + hf.coeFun + +protected theorem ContinuousOn.eval_const (hf : ContinuousOn f s) (x : α) : + ContinuousOn (f · x) s := + fun z hz ↦ (hf z hz).eval_const x + +protected theorem ContinuousOn.coeFun (hf : ContinuousOn f s) (x : α) : ContinuousOn (f · x) s := + fun z hz ↦ (hf z hz).eval_const x + +end ContinuousEvalConst diff --git a/Mathlib/Topology/Homotopy/HSpaces.lean b/Mathlib/Topology/Homotopy/HSpaces.lean index cf728834e55ae6..fba0212ad88f5e 100644 --- a/Mathlib/Topology/Homotopy/HSpaces.lean +++ b/Mathlib/Topology/Homotopy/HSpaces.lean @@ -212,7 +212,7 @@ def delayReflRight (θ : I) (γ : Path x y) : Path x y where theorem continuous_delayReflRight : Continuous fun p : I × Path x y => delayReflRight p.1 p.2 := continuous_uncurry_iff.mp <| - (continuous_snd.comp continuous_fst).path_eval <| + (continuous_snd.comp continuous_fst).eval <| continuous_qRight.comp <| continuous_snd.prod_mk <| continuous_fst.comp continuous_fst theorem delayReflRight_zero (γ : Path x y) : delayReflRight 0 γ = γ.trans (Path.refl y) := by diff --git a/Mathlib/Topology/Homotopy/HomotopyGroup.lean b/Mathlib/Topology/Homotopy/HomotopyGroup.lean index fac80ea72c6068..a9ec3d6dc3be4d 100644 --- a/Mathlib/Topology/Homotopy/HomotopyGroup.lean +++ b/Mathlib/Topology/Homotopy/HomotopyGroup.lean @@ -111,6 +111,11 @@ theorem ext (f g : Ω^ N X x) (H : ∀ y, f y = g y) : f = g := theorem mk_apply (f : C(I^N, X)) (H y) : (⟨f, H⟩ : Ω^ N X x) y = f y := rfl +instance instContinuousEval : ContinuousEval (Ω^ N X x) (I^N) X := + .of_continuous_forget continuous_subtype_val + +instance instContinuousEvalConst : ContinuousEvalConst (Ω^ N X x) (I^N) X := inferInstance + /-- Copy of a `GenLoop` with a new map from the unit cube equal to the old one. Useful to fix definitional equalities. -/ def copy (f : Ω^ N X x) (g : (I^N) → X) (h : g = f) : Ω^ N X x := @@ -184,7 +189,7 @@ def toLoop (i : N) (p : Ω^ N X x) : Ω (Ω^ { j // j ≠ i } X x) const where theorem continuous_toLoop (i : N) : Continuous (@toLoop N X _ x _ i) := Path.continuous_uncurry_iff.1 <| Continuous.subtype_mk - (ContinuousMap.continuous_eval.comp <| + (continuous_eval.comp <| Continuous.prodMap (ContinuousMap.continuous_curry.comp <| (ContinuousMap.continuous_comp_left _).comp continuous_subtype_val) @@ -372,7 +377,6 @@ def genLoopHomeoOfIsEmpty (N x) [IsEmpty N] : Ω^ N X x ≃ₜ X where invFun y := ⟨ContinuousMap.const _ y, fun _ ⟨i, _⟩ => isEmptyElim i⟩ left_inv f := by ext; exact congr_arg f (Subsingleton.elim _ _) right_inv _ := rfl - continuous_toFun := (ContinuousMap.continuous_eval_const (0 : N → I)).comp continuous_induced_dom continuous_invFun := ContinuousMap.const'.2.subtype_mk _ /-- The homotopy "group" indexed by an empty type is in bijection with diff --git a/Mathlib/Topology/Homotopy/Path.lean b/Mathlib/Topology/Homotopy/Path.lean index 254ed2b7f70dca..a5ad060e6071e5 100644 --- a/Mathlib/Topology/Homotopy/Path.lean +++ b/Mathlib/Topology/Homotopy/Path.lean @@ -188,15 +188,7 @@ def reparam (p : Path x₀ x₁) (f : I → I) (hf : Continuous f) (hf₀ : f 0 · rw [Set.mem_singleton_iff] at hx rw [hx] simp [hf₁] - continuous_toFun := by - -- Porting note: was `continuity` in auto-param - refine continuous_const.path_eval ?_ - apply Continuous.subtype_mk - apply Continuous.add <;> apply Continuous.mul - · exact continuous_induced_dom.comp (unitInterval.continuous_symm.comp continuous_fst) - · continuity - · continuity - · continuity + continuous_toFun := by fun_prop /-- Suppose `F : Homotopy p q`. Then we have a `Homotopy p.symm q.symm` by reversing the second argument. From 8e0ebee297fc69a4ac143794e1e26ad52d25a587 Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Fri, 18 Oct 2024 09:18:38 +0000 Subject: [PATCH 366/425] chore(*): fix some TODOs (#17891) Also drop an unneeded assumption in a lemma. --- .../Order/Monoid/Unbundled/ExistsOfLE.lean | 7 ++++--- Mathlib/Analysis/Calculus/ContDiff/Basic.lean | 5 ++--- Mathlib/Analysis/Oscillation.lean | 2 +- Mathlib/Data/Finset/Card.lean | 3 +-- Mathlib/Data/NNReal/Basic.lean | 20 ++++++++----------- .../Integral/RieszMarkovKakutani.lean | 2 +- .../MetricSpace/HausdorffDistance.lean | 2 +- 7 files changed, 18 insertions(+), 23 deletions(-) diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/ExistsOfLE.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/ExistsOfLE.lean index da6e069dc2d224..bfca4ed38d9a97 100644 --- a/Mathlib/Algebra/Order/Monoid/Unbundled/ExistsOfLE.lean +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/ExistsOfLE.lean @@ -65,20 +65,21 @@ end MulOneClass section ExistsMulOfLE variable [LinearOrder α] [DenselyOrdered α] [Monoid α] [ExistsMulOfLE α] - [CovariantClass α α (· * ·) (· < ·)] [ContravariantClass α α (· * ·) (· < ·)] {a b : α} + [ContravariantClass α α (· * ·) (· < ·)] {a b : α} @[to_additive] theorem le_of_forall_one_lt_le_mul (h : ∀ ε : α, 1 < ε → a ≤ b * ε) : a ≤ b := le_of_forall_le_of_dense fun x hxb => by obtain ⟨ε, rfl⟩ := exists_mul_of_le hxb.le - exact h _ ((lt_mul_iff_one_lt_right' b).1 hxb) + exact h _ (one_lt_of_lt_mul_right hxb) @[to_additive] theorem le_of_forall_one_lt_lt_mul' (h : ∀ ε : α, 1 < ε → a < b * ε) : a ≤ b := le_of_forall_one_lt_le_mul fun ε hε => (h ε hε).le @[to_additive] -theorem le_iff_forall_one_lt_lt_mul' : a ≤ b ↔ ∀ ε, 1 < ε → a < b * ε := +theorem le_iff_forall_one_lt_lt_mul' [CovariantClass α α (· * ·) (· < ·)] : + a ≤ b ↔ ∀ ε, 1 < ε → a < b * ε := ⟨fun h _ => lt_mul_of_le_of_one_lt h, le_of_forall_one_lt_lt_mul'⟩ end ExistsMulOfLE diff --git a/Mathlib/Analysis/Calculus/ContDiff/Basic.lean b/Mathlib/Analysis/Calculus/ContDiff/Basic.lean index f4d4b2b3d92ccf..23b46aad1701c6 100644 --- a/Mathlib/Analysis/Calculus/ContDiff/Basic.lean +++ b/Mathlib/Analysis/Calculus/ContDiff/Basic.lean @@ -1562,9 +1562,8 @@ end prodMap section AlgebraInverse -variable (𝕜) {R : Type*} [NormedRing R] --- Porting note: this couldn't be on the same line as the binder type update of `𝕜` -variable [NormedAlgebra 𝕜 R] +variable (𝕜) +variable {R : Type*} [NormedRing R] [NormedAlgebra 𝕜 R] open NormedRing ContinuousLinearMap Ring diff --git a/Mathlib/Analysis/Oscillation.lean b/Mathlib/Analysis/Oscillation.lean index c6327e3b9a0596..cfc6cf9116dd93 100644 --- a/Mathlib/Analysis/Oscillation.lean +++ b/Mathlib/Analysis/Oscillation.lean @@ -52,7 +52,7 @@ namespace ContinuousWithinAt theorem oscillationWithin_eq_zero [TopologicalSpace E] {f : E → F} {D : Set E} {x : E} (hf : ContinuousWithinAt f D x) : oscillationWithin f D x = 0 := by - refine le_antisymm (le_of_forall_pos_le_add fun ε hε _ ↦ ?_) (zero_le _) + refine le_antisymm (_root_.le_of_forall_pos_le_add fun ε hε ↦ ?_) (zero_le _) rw [zero_add] have : ball (f x) (ε / 2) ∈ (𝓝[D] x).map f := hf <| ball_mem_nhds _ (by simp [ne_of_gt hε]) refine (biInf_le diam this).trans (le_of_le_of_eq diam_ball ?_) diff --git a/Mathlib/Data/Finset/Card.lean b/Mathlib/Data/Finset/Card.lean index 376e7fe70747f2..67ac01fae42610 100644 --- a/Mathlib/Data/Finset/Card.lean +++ b/Mathlib/Data/Finset/Card.lean @@ -25,8 +25,7 @@ This defines the cardinality of a `Finset` and provides induction principles for -/ assert_not_exists MonoidWithZero --- TODO: After a lot more work, --- assert_not_exists OrderedCommMonoid +assert_not_exists OrderedCommMonoid open Function Multiset Nat diff --git a/Mathlib/Data/NNReal/Basic.lean b/Mathlib/Data/NNReal/Basic.lean index f0ef943d2ea06b..0db61f23290b13 100644 --- a/Mathlib/Data/NNReal/Basic.lean +++ b/Mathlib/Data/NNReal/Basic.lean @@ -68,8 +68,8 @@ scoped notation "ℝ≥0" => NNReal noncomputable instance : FloorSemiring ℝ≥0 := Nonneg.floorSemiring instance instDenselyOrdered : DenselyOrdered ℝ≥0 := Nonneg.instDenselyOrdered instance : OrderBot ℝ≥0 := inferInstance -instance : Archimedean ℝ≥0 := Nonneg.instArchimedean -instance : MulArchimedean ℝ≥0 := Nonneg.instMulArchimedean +instance instArchimedean : Archimedean ℝ≥0 := Nonneg.instArchimedean +instance instMulArchimedean : MulArchimedean ℝ≥0 := Nonneg.instMulArchimedean noncomputable instance : Sub ℝ≥0 := Nonneg.sub noncomputable instance : OrderedSub ℝ≥0 := Nonneg.orderedSub @@ -493,17 +493,13 @@ theorem le_iInf_add_iInf {ι ι' : Sort*} [Nonempty ι] [Nonempty ι'] {f : ι rw [← NNReal.coe_le_coe, NNReal.coe_add, coe_iInf, coe_iInf] exact le_ciInf_add_ciInf h -example : Archimedean ℝ≥0 := by infer_instance +-- Short-circuit instance search +instance instCovariantClassAddLE : CovariantClass ℝ≥0 ℝ≥0 (· + ·) (· ≤ ·) := inferInstance +instance instContravariantClassAddLT : ContravariantClass ℝ≥0 ℝ≥0 (· + ·) (· < ·) := inferInstance +instance instCovariantClassMulLE : CovariantClass ℝ≥0 ℝ≥0 (· * ·) (· ≤ ·) := inferInstance --- Porting note (#11215): TODO: remove? -instance covariant_add : CovariantClass ℝ≥0 ℝ≥0 (· + ·) (· ≤ ·) := inferInstance - -instance contravariant_add : ContravariantClass ℝ≥0 ℝ≥0 (· + ·) (· < ·) := inferInstance - -instance covariant_mul : CovariantClass ℝ≥0 ℝ≥0 (· * ·) (· ≤ ·) := inferInstance - --- Porting note (#11215): TODO: delete? -nonrec theorem le_of_forall_pos_le_add {a b : ℝ≥0} (h : ∀ ε, 0 < ε → a ≤ b + ε) : a ≤ b := +@[deprecated le_of_forall_pos_le_add (since := "2024-10-17")] +protected theorem le_of_forall_pos_le_add {a b : ℝ≥0} (h : ∀ ε, 0 < ε → a ≤ b + ε) : a ≤ b := le_of_forall_pos_le_add h theorem lt_iff_exists_rat_btwn (a b : ℝ≥0) : diff --git a/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani.lean b/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani.lean index b6a9c18db7857b..da3bb926998298 100644 --- a/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani.lean +++ b/Mathlib/MeasureTheory/Integral/RieszMarkovKakutani.lean @@ -86,7 +86,7 @@ theorem exists_lt_rieszContentAux_add_pos (K : Compacts X) {ε : ℝ≥0} (εpos finitely subadditive: `λ(K₁ ∪ K₂) ≤ λ(K₁) + λ(K₂)` for any compact subsets `K₁, K₂ ⊆ X`. -/ theorem rieszContentAux_sup_le (K1 K2 : Compacts X) : rieszContentAux Λ (K1 ⊔ K2) ≤ rieszContentAux Λ K1 + rieszContentAux Λ K2 := by - apply NNReal.le_of_forall_pos_le_add + apply _root_.le_of_forall_pos_le_add intro ε εpos --get test functions s.t. `λ(Ki) ≤ Λfi ≤ λ(Ki) + ε/2, i=1,2` obtain ⟨f1, f_test_function_K1⟩ := exists_lt_rieszContentAux_add_pos Λ K1 (half_pos εpos) diff --git a/Mathlib/Topology/MetricSpace/HausdorffDistance.lean b/Mathlib/Topology/MetricSpace/HausdorffDistance.lean index b898627b74b4ef..06799e111037e2 100644 --- a/Mathlib/Topology/MetricSpace/HausdorffDistance.lean +++ b/Mathlib/Topology/MetricSpace/HausdorffDistance.lean @@ -451,7 +451,7 @@ 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) --- Porting note (#11215): TODO: make it a `simp` lemma +@[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] From 74a2dd2afb5454cbcc9fb3aa05584b00c628e9f2 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Fri, 18 Oct 2024 20:26:08 +1100 Subject: [PATCH 367/425] fixes --- Mathlib/Data/List/Permutation.lean | 2 ++ Mathlib/Data/List/Range.lean | 1 + 2 files changed, 3 insertions(+) diff --git a/Mathlib/Data/List/Permutation.lean b/Mathlib/Data/List/Permutation.lean index 24e912e10a51b3..91a3959536f1d2 100644 --- a/Mathlib/Data/List/Permutation.lean +++ b/Mathlib/Data/List/Permutation.lean @@ -187,11 +187,13 @@ theorem mem_foldr_permutationsAux2 {t : α} {ts : List α} {r L : List (List α) simp only [mem_permutationsAux2', ← this, or_comm, and_left_comm, mem_append, mem_flatMap, append_assoc, cons_append, exists_prop] +set_option linter.deprecated false in theorem length_foldr_permutationsAux2 (t : α) (ts : List α) (r L : List (List α)) : length (foldr (fun y r => (permutationsAux2 t ts r y id).2) r L) = Nat.sum (map length L) + length r := by simp [foldr_permutationsAux2, Function.comp_def, length_permutationsAux2, length_flatMap'] +set_option linter.deprecated false in theorem length_foldr_permutationsAux2' (t : α) (ts : List α) (r L : List (List α)) (n) (H : ∀ l ∈ L, length l = n) : length (foldr (fun y r => (permutationsAux2 t ts r y id).2) r L) = n * length L + length r := by diff --git a/Mathlib/Data/List/Range.lean b/Mathlib/Data/List/Range.lean index 076367af8be8ee..0b4918b7a6de22 100644 --- a/Mathlib/Data/List/Range.lean +++ b/Mathlib/Data/List/Range.lean @@ -150,6 +150,7 @@ lemma ranges_flatten' : ∀ l : List ℕ, l.ranges.flatten = range (Nat.sum l) @[deprecated (since := "2024-10-15")] alias ranges_join' := ranges_flatten' +set_option linter.deprecated false in /-- Any entry of any member of `l.ranges` is strictly smaller than `Nat.sum l`. See `List.mem_mem_ranges_iff_lt_sum` for the version about `List.sum`. -/ lemma mem_mem_ranges_iff_lt_natSum (l : List ℕ) {n : ℕ} : From d595afe39964612d06746b14c6a85af99d583a2d Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Fri, 18 Oct 2024 20:34:04 +1100 Subject: [PATCH 368/425] unused variable --- Mathlib/Algebra/Polynomial/SumIteratedDerivative.lean | 9 +++++---- Mathlib/AlgebraicGeometry/Properties.lean | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Mathlib/Algebra/Polynomial/SumIteratedDerivative.lean b/Mathlib/Algebra/Polynomial/SumIteratedDerivative.lean index b8b64c16ec9bfd..0ccb87b12b34d9 100644 --- a/Mathlib/Algebra/Polynomial/SumIteratedDerivative.lean +++ b/Mathlib/Algebra/Polynomial/SumIteratedDerivative.lean @@ -185,16 +185,17 @@ theorem aeval_sumIDeriv (p : R[X]) (q : ℕ) : intro r p' hp rw [sumIDeriv_apply, map_sum]; simp_rw [hc _ r hp, map_sum, smul_sum] -theorem aeval_sumIDeriv_of_pos [Nontrivial A] [NoZeroDivisors A] (p : R[X]) {q : ℕ} (hq : 0 < q) : +theorem aeval_sumIDeriv_of_pos [Nontrivial A] [NoZeroDivisors A] (p : R[X]) {q : ℕ} (hq : 0 < q) + (inj_amap : Function.Injective (algebraMap R A)) : ∃ gp : R[X], gp.natDegree ≤ p.natDegree - q ∧ - ∀ (inj_amap : Function.Injective (algebraMap R A)) (r : A) {p' : A[X]}, + ∀ (r : A) {p' : A[X]}, p.map (algebraMap R A) = (X - C r) ^ (q - 1) * p' → aeval r (sumIDeriv p) = (q - 1)! • p'.eval r + q ! • aeval r gp := by rcases eq_or_ne p 0 with (rfl | p0) · use 0 rw [natDegree_zero] use Nat.zero_le _ - intro _ r p' hp + intro r p' hp rw [map_zero, map_zero, smul_zero, add_zero] rw [Polynomial.map_zero] at hp replace hp := (mul_eq_zero.mp hp.symm).resolve_left ?_ @@ -213,7 +214,7 @@ theorem aeval_sumIDeriv_of_pos [Nontrivial A] [NoZeroDivisors A] (p : R[X]) {q : · refine (natDegree_sum_le _ _).trans ?_ rw [fold_max_le] exact ⟨Nat.zero_le _, fun i hi => (c_le i).trans (tsub_le_tsub_left (mem_Ico.mp hi).1 _)⟩ - intro inj_amap r p' hp + intro r p' hp have : range (p.natDegree + 1) = range q ∪ Ico q (p.natDegree + 1) := by rw [range_eq_Ico, Ico_union_Ico_eq_Ico hq.le] have h := natDegree_map_le (algebraMap R A) p diff --git a/Mathlib/AlgebraicGeometry/Properties.lean b/Mathlib/AlgebraicGeometry/Properties.lean index a5bbb08d90c154..cafbcd2bf5a4ac 100644 --- a/Mathlib/AlgebraicGeometry/Properties.lean +++ b/Mathlib/AlgebraicGeometry/Properties.lean @@ -110,7 +110,7 @@ theorem reduce_to_affine_global (P : ∀ {X : Scheme} (_ : X.Opens), Prop) {X : Scheme} (U : X.Opens) (h₁ : ∀ (X : Scheme) (U : X.Opens), (∀ x : U, ∃ (V : _) (_ : x.1 ∈ V) (_ : V ⟶ U), P V) → P U) - (h₂ : ∀ (X Y) (f : X ⟶ Y) [hf : IsOpenImmersion f], + (h₂ : ∀ (X Y) (f : X ⟶ Y) [IsOpenImmersion f], ∃ (U : X.Opens) (V : Y.Opens), U = ⊤ ∧ V = f.opensRange ∧ (P U → P V)) (h₃ : ∀ R : CommRingCat, P (X := Spec R) ⊤) : P U := by apply h₁ From 34f08fb6b3608c4b798f493e995f4eb615a9b01d Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Fri, 18 Oct 2024 09:52:32 +0000 Subject: [PATCH 369/425] feat: generalize results from EuclideanSpace to PiLp (#17663) The EuclideanSpace results are left in place for convenience. This generalizes leanprover-community/mathlib3#15363 Co-authored-by: Eric Wieser --- Mathlib.lean | 2 + .../Analysis/Calculus/ContDiff/WithLp.lean | 41 ++++++++++++++ Mathlib/Analysis/Calculus/FDeriv/WithLp.lean | 56 +++++++++++++++++++ .../Analysis/InnerProductSpace/Calculus.lean | 54 ++++++++---------- Mathlib/Analysis/InnerProductSpace/PiL2.lean | 13 +---- Mathlib/Analysis/Normed/Lp/PiLp.lean | 16 +++++- 6 files changed, 141 insertions(+), 41 deletions(-) create mode 100644 Mathlib/Analysis/Calculus/ContDiff/WithLp.lean create mode 100644 Mathlib/Analysis/Calculus/FDeriv/WithLp.lean diff --git a/Mathlib.lean b/Mathlib.lean index 1e5548b290acc8..3c455bcceb7e97 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1004,6 +1004,7 @@ import Mathlib.Analysis.Calculus.ContDiff.Defs import Mathlib.Analysis.Calculus.ContDiff.FTaylorSeries import Mathlib.Analysis.Calculus.ContDiff.FiniteDimension import Mathlib.Analysis.Calculus.ContDiff.RCLike +import Mathlib.Analysis.Calculus.ContDiff.WithLp import Mathlib.Analysis.Calculus.Darboux import Mathlib.Analysis.Calculus.Deriv.Abs import Mathlib.Analysis.Calculus.Deriv.Add @@ -1041,6 +1042,7 @@ import Mathlib.Analysis.Calculus.FDeriv.Prod import Mathlib.Analysis.Calculus.FDeriv.RestrictScalars import Mathlib.Analysis.Calculus.FDeriv.Star import Mathlib.Analysis.Calculus.FDeriv.Symmetric +import Mathlib.Analysis.Calculus.FDeriv.WithLp import Mathlib.Analysis.Calculus.FormalMultilinearSeries import Mathlib.Analysis.Calculus.Gradient.Basic import Mathlib.Analysis.Calculus.Implicit diff --git a/Mathlib/Analysis/Calculus/ContDiff/WithLp.lean b/Mathlib/Analysis/Calculus/ContDiff/WithLp.lean new file mode 100644 index 00000000000000..4c99b51e455bab --- /dev/null +++ b/Mathlib/Analysis/Calculus/ContDiff/WithLp.lean @@ -0,0 +1,41 @@ +/- +Copyright (c) 2022 Anatole Dedecker. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Anatole Dedecker, Eric Wieser +-/ +import Mathlib.Analysis.Calculus.ContDiff.Basic +import Mathlib.Analysis.Normed.Lp.PiLp + +/-! +# Derivatives on `WithLp` +-/ + +section PiLp + +open ContinuousLinearMap + +variable {𝕜 ι : Type*} {E : ι → Type*} {H : Type*} +variable [NontriviallyNormedField 𝕜] [NormedAddCommGroup H] [∀ i, NormedAddCommGroup (E i)] + [∀ i, NormedSpace 𝕜 (E i)] [NormedSpace 𝕜 H] [Fintype ι] (p) [Fact (1 ≤ p)] + {f : H → PiLp p E} {f' : H →L[𝕜] PiLp p E} {t : Set H} {y : H} + +theorem contDiffWithinAt_piLp {n : ℕ∞} : + ContDiffWithinAt 𝕜 n f t y ↔ ∀ i, ContDiffWithinAt 𝕜 n (fun x => f x i) t y := by + rw [← (PiLp.continuousLinearEquiv p 𝕜 E).comp_contDiffWithinAt_iff, contDiffWithinAt_pi] + rfl + +theorem contDiffAt_piLp {n : ℕ∞} : + ContDiffAt 𝕜 n f y ↔ ∀ i, ContDiffAt 𝕜 n (fun x => f x i) y := by + rw [← (PiLp.continuousLinearEquiv p 𝕜 E).comp_contDiffAt_iff, contDiffAt_pi] + rfl + +theorem contDiffOn_piLp {n : ℕ∞} : + ContDiffOn 𝕜 n f t ↔ ∀ i, ContDiffOn 𝕜 n (fun x => f x i) t := by + rw [← (PiLp.continuousLinearEquiv p 𝕜 E).comp_contDiffOn_iff, contDiffOn_pi] + rfl + +theorem contDiff_piLp {n : ℕ∞} : ContDiff 𝕜 n f ↔ ∀ i, ContDiff 𝕜 n fun x => f x i := by + rw [← (PiLp.continuousLinearEquiv p 𝕜 E).comp_contDiff_iff, contDiff_pi] + rfl + +end PiLp diff --git a/Mathlib/Analysis/Calculus/FDeriv/WithLp.lean b/Mathlib/Analysis/Calculus/FDeriv/WithLp.lean new file mode 100644 index 00000000000000..1953b606870a99 --- /dev/null +++ b/Mathlib/Analysis/Calculus/FDeriv/WithLp.lean @@ -0,0 +1,56 @@ +/- +Copyright (c) 2022 Anatole Dedecker. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Anatole Dedecker, Eric Wieser +-/ +import Mathlib.Analysis.Calculus.FDeriv.Prod +import Mathlib.Analysis.Calculus.FDeriv.Equiv +import Mathlib.Analysis.Normed.Lp.PiLp + + +/-! +# Derivatives on `WithLp` +-/ + +section PiLp + +open ContinuousLinearMap + +variable {𝕜 ι : Type*} {E : ι → Type*} {H : Type*} +variable [NontriviallyNormedField 𝕜] [NormedAddCommGroup H] [∀ i, NormedAddCommGroup (E i)] + [∀ i, NormedSpace 𝕜 (E i)] [NormedSpace 𝕜 H] [Fintype ι] (p) [Fact (1 ≤ p)] + {f : H → PiLp p E} {f' : H →L[𝕜] PiLp p E} {t : Set H} {y : H} + +theorem differentiableWithinAt_piLp : + DifferentiableWithinAt 𝕜 f t y ↔ ∀ i, DifferentiableWithinAt 𝕜 (fun x => f x i) t y := by + rw [← (PiLp.continuousLinearEquiv p 𝕜 E).comp_differentiableWithinAt_iff, + differentiableWithinAt_pi] + rfl + +theorem differentiableAt_piLp : + DifferentiableAt 𝕜 f y ↔ ∀ i, DifferentiableAt 𝕜 (fun x => f x i) y := by + rw [← (PiLp.continuousLinearEquiv p 𝕜 E).comp_differentiableAt_iff, differentiableAt_pi] + rfl + +theorem differentiableOn_piLp : + DifferentiableOn 𝕜 f t ↔ ∀ i, DifferentiableOn 𝕜 (fun x => f x i) t := by + rw [← (PiLp.continuousLinearEquiv p 𝕜 E).comp_differentiableOn_iff, differentiableOn_pi] + rfl + +theorem differentiable_piLp : Differentiable 𝕜 f ↔ ∀ i, Differentiable 𝕜 fun x => f x i := by + rw [← (PiLp.continuousLinearEquiv p 𝕜 E).comp_differentiable_iff, differentiable_pi] + rfl + +theorem hasStrictFDerivAt_piLp : + HasStrictFDerivAt f f' y ↔ + ∀ i, HasStrictFDerivAt (fun x => f x i) (PiLp.proj _ _ i ∘L f') y := by + rw [← (PiLp.continuousLinearEquiv p 𝕜 E).comp_hasStrictFDerivAt_iff, hasStrictFDerivAt_pi'] + rfl + +theorem hasFDerivWithinAt_piLp : + HasFDerivWithinAt f f' t y ↔ + ∀ i, HasFDerivWithinAt (fun x => f x i) (PiLp.proj _ _ i ∘L f') t y := by + rw [← (PiLp.continuousLinearEquiv p 𝕜 E).comp_hasFDerivWithinAt_iff, hasFDerivWithinAt_pi'] + rfl + +end PiLp diff --git a/Mathlib/Analysis/InnerProductSpace/Calculus.lean b/Mathlib/Analysis/InnerProductSpace/Calculus.lean index 44808e4d72423f..018aa26547ec5c 100644 --- a/Mathlib/Analysis/InnerProductSpace/Calculus.lean +++ b/Mathlib/Analysis/InnerProductSpace/Calculus.lean @@ -6,6 +6,8 @@ Authors: Yury Kudryashov import Mathlib.Analysis.InnerProductSpace.PiL2 import Mathlib.Analysis.SpecialFunctions.Sqrt import Mathlib.Analysis.NormedSpace.HomeomorphBall +import Mathlib.Analysis.Calculus.ContDiff.WithLp +import Mathlib.Analysis.Calculus.FDeriv.WithLp /-! # Calculus in inner product spaces @@ -264,60 +266,52 @@ end DerivInner section PiLike +/-! ### Convenience aliases of `PiLp` lemmas for `EuclideanSpace` -/ + open ContinuousLinearMap variable {𝕜 ι H : Type*} [RCLike 𝕜] [NormedAddCommGroup H] [NormedSpace 𝕜 H] [Fintype ι] {f : H → EuclideanSpace 𝕜 ι} {f' : H →L[𝕜] EuclideanSpace 𝕜 ι} {t : Set H} {y : H} theorem differentiableWithinAt_euclidean : - DifferentiableWithinAt 𝕜 f t y ↔ ∀ i, DifferentiableWithinAt 𝕜 (fun x => f x i) t y := by - rw [← (EuclideanSpace.equiv ι 𝕜).comp_differentiableWithinAt_iff, differentiableWithinAt_pi] - rfl + DifferentiableWithinAt 𝕜 f t y ↔ ∀ i, DifferentiableWithinAt 𝕜 (fun x => f x i) t y := + differentiableWithinAt_piLp _ theorem differentiableAt_euclidean : - DifferentiableAt 𝕜 f y ↔ ∀ i, DifferentiableAt 𝕜 (fun x => f x i) y := by - rw [← (EuclideanSpace.equiv ι 𝕜).comp_differentiableAt_iff, differentiableAt_pi] - rfl + DifferentiableAt 𝕜 f y ↔ ∀ i, DifferentiableAt 𝕜 (fun x => f x i) y := + differentiableAt_piLp _ theorem differentiableOn_euclidean : - DifferentiableOn 𝕜 f t ↔ ∀ i, DifferentiableOn 𝕜 (fun x => f x i) t := by - rw [← (EuclideanSpace.equiv ι 𝕜).comp_differentiableOn_iff, differentiableOn_pi] - rfl + DifferentiableOn 𝕜 f t ↔ ∀ i, DifferentiableOn 𝕜 (fun x => f x i) t := + differentiableOn_piLp _ -theorem differentiable_euclidean : Differentiable 𝕜 f ↔ ∀ i, Differentiable 𝕜 fun x => f x i := by - rw [← (EuclideanSpace.equiv ι 𝕜).comp_differentiable_iff, differentiable_pi] - rfl +theorem differentiable_euclidean : Differentiable 𝕜 f ↔ ∀ i, Differentiable 𝕜 fun x => f x i := + differentiable_piLp _ theorem hasStrictFDerivAt_euclidean : HasStrictFDerivAt f f' y ↔ - ∀ i, HasStrictFDerivAt (fun x => f x i) (EuclideanSpace.proj i ∘L f') y := by - rw [← (EuclideanSpace.equiv ι 𝕜).comp_hasStrictFDerivAt_iff, hasStrictFDerivAt_pi'] - rfl + ∀ i, HasStrictFDerivAt (fun x => f x i) (PiLp.proj _ _ i ∘L f') y := + hasStrictFDerivAt_piLp _ theorem hasFDerivWithinAt_euclidean : HasFDerivWithinAt f f' t y ↔ - ∀ i, HasFDerivWithinAt (fun x => f x i) (EuclideanSpace.proj i ∘L f') t y := by - rw [← (EuclideanSpace.equiv ι 𝕜).comp_hasFDerivWithinAt_iff, hasFDerivWithinAt_pi'] - rfl + ∀ i, HasFDerivWithinAt (fun x => f x i) (PiLp.proj _ _ i ∘L f') t y := + hasFDerivWithinAt_piLp _ theorem contDiffWithinAt_euclidean {n : ℕ∞} : - ContDiffWithinAt 𝕜 n f t y ↔ ∀ i, ContDiffWithinAt 𝕜 n (fun x => f x i) t y := by - rw [← (EuclideanSpace.equiv ι 𝕜).comp_contDiffWithinAt_iff, contDiffWithinAt_pi] - rfl + ContDiffWithinAt 𝕜 n f t y ↔ ∀ i, ContDiffWithinAt 𝕜 n (fun x => f x i) t y := + contDiffWithinAt_piLp _ theorem contDiffAt_euclidean {n : ℕ∞} : - ContDiffAt 𝕜 n f y ↔ ∀ i, ContDiffAt 𝕜 n (fun x => f x i) y := by - rw [← (EuclideanSpace.equiv ι 𝕜).comp_contDiffAt_iff, contDiffAt_pi] - rfl + ContDiffAt 𝕜 n f y ↔ ∀ i, ContDiffAt 𝕜 n (fun x => f x i) y := + contDiffAt_piLp _ theorem contDiffOn_euclidean {n : ℕ∞} : - ContDiffOn 𝕜 n f t ↔ ∀ i, ContDiffOn 𝕜 n (fun x => f x i) t := by - rw [← (EuclideanSpace.equiv ι 𝕜).comp_contDiffOn_iff, contDiffOn_pi] - rfl + ContDiffOn 𝕜 n f t ↔ ∀ i, ContDiffOn 𝕜 n (fun x => f x i) t := + contDiffOn_piLp _ -theorem contDiff_euclidean {n : ℕ∞} : ContDiff 𝕜 n f ↔ ∀ i, ContDiff 𝕜 n fun x => f x i := by - rw [← (EuclideanSpace.equiv ι 𝕜).comp_contDiff_iff, contDiff_pi] - rfl +theorem contDiff_euclidean {n : ℕ∞} : ContDiff 𝕜 n f ↔ ∀ i, ContDiff 𝕜 n fun x => f x i := + contDiff_piLp _ end PiLike diff --git a/Mathlib/Analysis/InnerProductSpace/PiL2.lean b/Mathlib/Analysis/InnerProductSpace/PiL2.lean index 2c14b91ede9f15..3a77d1f7c5328e 100644 --- a/Mathlib/Analysis/InnerProductSpace/PiL2.lean +++ b/Mathlib/Analysis/InnerProductSpace/PiL2.lean @@ -200,18 +200,11 @@ abbrev EuclideanSpace.equiv : EuclideanSpace 𝕜 ι ≃L[𝕜] ι → 𝕜 := variable {ι 𝕜} --- TODO : This should be generalized to `PiLp`. /-- The projection on the `i`-th coordinate of `EuclideanSpace 𝕜 ι`, as a linear map. -/ -@[simps!] -def EuclideanSpace.projₗ (i : ι) : EuclideanSpace 𝕜 ι →ₗ[𝕜] 𝕜 := - (LinearMap.proj i).comp (WithLp.linearEquiv 2 𝕜 (ι → 𝕜) : EuclideanSpace 𝕜 ι →ₗ[𝕜] ι → 𝕜) +abbrev EuclideanSpace.projₗ (i : ι) : EuclideanSpace 𝕜 ι →ₗ[𝕜] 𝕜 := PiLp.projₗ _ _ i --- TODO : This should be generalized to `PiLp`. -/-- The projection on the `i`-th coordinate of `EuclideanSpace 𝕜 ι`, -as a continuous linear map. -/ -@[simps! apply coe] -def EuclideanSpace.proj (i : ι) : EuclideanSpace 𝕜 ι →L[𝕜] 𝕜 := - ⟨EuclideanSpace.projₗ i, continuous_apply i⟩ +/-- The projection on the `i`-th coordinate of `EuclideanSpace 𝕜 ι`, as a continuous linear map. -/ +abbrev EuclideanSpace.proj (i : ι) : EuclideanSpace 𝕜 ι →L[𝕜] 𝕜 := PiLp.proj _ _ i section DecEq diff --git a/Mathlib/Analysis/Normed/Lp/PiLp.lean b/Mathlib/Analysis/Normed/Lp/PiLp.lean index 3902519c5b489f..3b9cc58963b915 100644 --- a/Mathlib/Analysis/Normed/Lp/PiLp.lean +++ b/Mathlib/Analysis/Normed/Lp/PiLp.lean @@ -91,7 +91,7 @@ section /- Register simplification lemmas for the applications of `PiLp` elements, as the usual lemmas for Pi types will not trigger. -/ variable {𝕜 p α} -variable [SeminormedRing 𝕜] [∀ i, SeminormedAddCommGroup (β i)] +variable [Semiring 𝕜] [∀ i, SeminormedAddCommGroup (β i)] variable [∀ i, Module 𝕜 (β i)] (c : 𝕜) variable (x y : PiLp p β) (i : ι) @@ -121,6 +121,13 @@ theorem smul_apply : (c • x) i = c • x i := @[simp] theorem neg_apply : (-x) i = -x i := rfl + +variable (p) in +/-- The projection on the `i`-th coordinate of `WithLp p (∀ i, α i)`, as a linear map. -/ +@[simps!] +def projₗ (i : ι) : PiLp p β →ₗ[𝕜] β i := + (LinearMap.proj i : (∀ i, β i) →ₗ[𝕜] β i) ∘ₗ (WithLp.linearEquiv p 𝕜 (∀ i, β i)).toLinearMap + end /-! Note that the unapplied versions of these lemmas are deliberately omitted, as they break @@ -891,6 +898,13 @@ protected def continuousLinearEquiv : PiLp p β ≃L[𝕜] ∀ i, β i where continuous_toFun := continuous_equiv _ _ continuous_invFun := continuous_equiv_symm _ _ +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 := continuous_apply i + end Fintype section Basis From 6338c7313383353c208346451dbdf0cc037ac8a2 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Fri, 18 Oct 2024 09:52:33 +0000 Subject: [PATCH 370/425] fix: improve line-wrapping of (D)Finsupp reprs (#17882) These were previously wrapping very poorly. Also update tests to use `#guard_msgs` more effectively, and fix a typo in the delaborators for DFinsupp. --- Mathlib/Data/DFinsupp/Notation.lean | 10 +++---- Mathlib/Data/Finsupp/Notation.lean | 6 ++-- test/dfinsupp_notation.lean | 41 ++++++++++++++++++++------- test/finsupp_notation.lean | 44 +++++++++++++++++++++++++---- 4 files changed, 78 insertions(+), 23 deletions(-) diff --git a/Mathlib/Data/DFinsupp/Notation.lean b/Mathlib/Data/DFinsupp/Notation.lean index f4782385250a8b..bdb9cdad1a53ff 100644 --- a/Mathlib/Data/DFinsupp/Notation.lean +++ b/Mathlib/Data/DFinsupp/Notation.lean @@ -44,13 +44,13 @@ def elabUpdate₀ : Elab.Term.TermElab | _ => fun _ => Elab.throwUnsupportedSyntax /-- Unexpander for the `fun₀ | i => x` notation. -/ -@[app_unexpander Finsupp.single] +@[app_unexpander DFinsupp.single] def singleUnexpander : Lean.PrettyPrinter.Unexpander | `($_ $pat $val) => `(fun₀ | $pat => $val) | _ => throw () /-- Unexpander for the `fun₀ | i => x` notation. -/ -@[app_unexpander Finsupp.update] +@[app_unexpander DFinsupp.update] def updateUnexpander : Lean.PrettyPrinter.Unexpander | `($_ $f $pat $val) => match f with | `(fun₀ $xs:matchAlt*) => `(fun₀ $xs:matchAlt* | $pat => $val) @@ -68,9 +68,9 @@ unsafe instance {α : Type*} {β : α → Type*} [Repr α] [∀ i, Repr (β i)] if vals.length = 0 then "0" else - let ret := "fun₀" ++ - Std.Format.join (vals_dedup.map <| - fun a => f!" | " ++ a.1 ++ f!" => " ++ a.2) + let ret : Std.Format := f!"fun₀" ++ .nest 2 ( + .group (.join <| vals_dedup.map fun a => + .line ++ .group (f!"| {a.1} =>" ++ .line ++ a.2))) if p ≥ leadPrec then Format.paren ret else ret end DFinsupp diff --git a/Mathlib/Data/Finsupp/Notation.lean b/Mathlib/Data/Finsupp/Notation.lean index 2091f9b3cb8d19..12c11f9e628e50 100644 --- a/Mathlib/Data/Finsupp/Notation.lean +++ b/Mathlib/Data/Finsupp/Notation.lean @@ -83,9 +83,9 @@ unsafe instance instRepr {α β} [Repr α] [Repr β] [Zero β] : Repr (α →₀ if f.support.card = 0 then "0" else - let ret := "fun₀" ++ - Std.Format.join (f.support.val.unquot.map <| - fun a => " | " ++ repr a ++ " => " ++ repr (f a)) + let ret : Std.Format := f!"fun₀" ++ .nest 2 ( + .group (.join <| f.support.val.unquot.map fun a => + .line ++ .group (f!"| {repr a} =>" ++ .line ++ repr (f a)))) if p ≥ leadPrec then Format.paren ret else ret -- This cannot be put in `Mathlib.Data.DFinsupp.Notation` where it belongs, since doc-strings diff --git a/test/dfinsupp_notation.lean b/test/dfinsupp_notation.lean index ed6511532b5f91..ea4d3815079ae8 100644 --- a/test/dfinsupp_notation.lean +++ b/test/dfinsupp_notation.lean @@ -7,20 +7,41 @@ example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4 : Π₀ i, Fin (i + 10)) 1 = 3 := by example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4 : Π₀ i, Fin (i + 10)) 2 = 3 := by simp example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4 : Π₀ i, Fin (i + 10)) 3 = 4 := by simp +section Repr + +/-- info: fun₀ | 1 => 3 | 2 => 3 : Π₀ (i : ℕ), Fin (i + 10) -/ +#guard_msgs in +#check (fun₀ | 1 => 3 | 2 => 3 : Π₀ i, Fin (i + 10)) + +/-- info: fun₀ | 2 => 7 -/ +#guard_msgs in +#eval ((fun₀ | 1 => 3 | 2 => 3) + (fun₀ | 1 => -3 | 2 => 4) : Π₀ _, ℤ) + /-- -info: +info: fun₀ + | ["there are five words here", "and five more words here"] => 5 + | ["there are seven words but only here"] => 7 + | ["just two"] => 2 -/ #guard_msgs in -#eval show Lean.MetaM Unit from - guard <| - reprStr (fun₀ | 1 => 3 | 2 => 3 : Π₀ i, Fin (i + 10)) - = "fun₀ | 1 => 3 | 2 => 3" +#eval (fun₀ + | ["there are five words here", "and five more words here"] => 5 + | ["there are seven words but only here"] => 7 + | ["just two"] => 2 : Π₀ _ : List String, ℕ) + +end Repr +section PrettyPrinter /-- -info: +info: fun₀ + | ["there are five words here", "and five more words here"] => 5 + | ["there are seven words but only here"] => 7 + | ["just two"] => 2 : Π₀ (i : List String), ℕ -/ #guard_msgs in -#eval show Lean.MetaM Unit from - guard <| - reprStr ((fun₀ | 1 => 3 | 2 => 3) + (fun₀ | 1 => -3 | 2 => 4) : Π₀ _, ℤ) - = "fun₀ | 2 => 7" +#check (fun₀ + | ["there are five words here", "and five more words here"] => 5 + | ["there are seven words but only here"] => 7 + | ["just two"] => 2 : Π₀ _ : List String, ℕ) + +end PrettyPrinter diff --git a/test/finsupp_notation.lean b/test/finsupp_notation.lean index e042b67a8903f0..08e871dde99cb3 100644 --- a/test/finsupp_notation.lean +++ b/test/finsupp_notation.lean @@ -12,14 +12,48 @@ example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4) 2 = 3 := by example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4) 3 = 4 := by simp +section repr + +/-- info: fun₀ | 1 => 3 | 2 => 3 -/ +#guard_msgs in +#eval (Finsupp.mk {1, 2} (fun | 1 | 2 => 3 | _ => 0) (fun x => by aesop)) + /-- -info: +info: fun₀ + | ["there are five words here", "and five more words here"] => 5 + | ["there are seven words but only here"] => 7 + | ["just two"] => 2 -/ #guard_msgs in -#eval show Lean.MetaM Unit from - guard <| - reprStr (Finsupp.mk {1, 2} (fun | 1 | 2 => 3 | _ => 0) (fun x => by aesop)) - = "fun₀ | 1 => 3 | 2 => 3" +#eval Finsupp.mk + {["there are five words here", "and five more words here"], + ["there are seven words but only here"], + ["just two"]} + (fun + | ["there are five words here", "and five more words here"] => 5 + | ["there are seven words but only here"] => 7 + | ["just two"] => 2 + | _ => 0) + (fun x => by aesop) + +end repr + +section PrettyPrinter + +/-- +info: fun₀ + | ["there are five words here", "and five more words here"] => 5 + | ["there are seven words but only here"] => 7 + | ["just two"] => 2 : List String →₀ ℕ +-/ +#guard_msgs in +#check fun₀ + | ["there are five words here", "and five more words here"] => 5 + | ["there are seven words but only here"] => 7 + | ["just two"] => 2 + +end PrettyPrinter + /-! ## (computable) number theory examples -/ From fd77f31972aa69d64ea2889b8d154417042e4aba Mon Sep 17 00:00:00 2001 From: Jakob von Raumer Date: Fri, 18 Oct 2024 09:52:34 +0000 Subject: [PATCH 371/425] chore(CategoryTheory): Make terminology for final functors consistent (#17895) Removes the remaining mentions of "cofinal functors". --- Mathlib/CategoryTheory/Limits/Final.lean | 32 ++++++++++----------- Mathlib/CategoryTheory/Limits/Presheaf.lean | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Final.lean b/Mathlib/CategoryTheory/Limits/Final.lean index 2341721a15f556..965ee9e0e669e8 100644 --- a/Mathlib/CategoryTheory/Limits/Final.lean +++ b/Mathlib/CategoryTheory/Limits/Final.lean @@ -36,7 +36,7 @@ This readily implies 2., as `comp_hasColimit`, `hasColimit_of_comp`, and `colimi From 2. we can specialize to `G = coyoneda.obj (op d)` to obtain 3., as `colimitCompCoyonedaIso`. -From 3., we prove 1. directly in `cofinal_of_colimit_comp_coyoneda_iso_pUnit`. +From 3., we prove 1. directly in `final_of_colimit_comp_coyoneda_iso_pUnit`. Dually, we prove that if a functor `F : C ⥤ D` is initial, then any functor `G : D ⥤ E` has a limit if and only if `F ⋙ G` does, and these limits are isomorphic via `limit.pre G F`. @@ -170,13 +170,13 @@ instance (d : D) : Nonempty (StructuredArrow d F) := variable {E : Type u₃} [Category.{v₃} E] (G : D ⥤ E) /-- -When `F : C ⥤ D` is cofinal, we denote by `lift F d` an arbitrary choice of object in `C` such that +When `F : C ⥤ D` is final, we denote by `lift F d` an arbitrary choice of object in `C` such that there exists a morphism `d ⟶ F.obj (lift F d)`. -/ def lift (d : D) : C := (Classical.arbitrary (StructuredArrow d F)).right -/-- When `F : C ⥤ D` is cofinal, we denote by `homToLift` an arbitrary choice of morphism +/-- When `F : C ⥤ D` is final, we denote by `homToLift` an arbitrary choice of morphism `d ⟶ F.obj (lift F d)`. -/ def homToLift (d : D) : d ⟶ F.obj (lift F d) := @@ -267,7 +267,7 @@ theorem colimit_cocone_comp_aux (s : Cocone (F ⋙ G)) (j : C) : variable (F G) -/-- If `F` is cofinal, +/-- If `F` is final, the category of cocones on `F ⋙ G` is equivalent to the category of cocones on `G`, for any `G : D ⥤ E`. -/ @@ -280,13 +280,13 @@ def coconesEquiv : Cocone (F ⋙ G) ≌ Cocone G where variable {G} -/-- When `F : C ⥤ D` is cofinal, and `t : Cocone G` for some `G : D ⥤ E`, +/-- When `F : C ⥤ D` is final, and `t : Cocone G` for some `G : D ⥤ E`, `t.whisker F` is a colimit cocone exactly when `t` is. -/ def isColimitWhiskerEquiv (t : Cocone G) : IsColimit (t.whisker F) ≃ IsColimit t := IsColimit.ofCoconeEquiv (coconesEquiv F G).symm -/-- When `F` is cofinal, and `t : Cocone (F ⋙ G)`, +/-- When `F` is final, and `t : Cocone (F ⋙ G)`, `extendCocone.obj t` is a colimit cocone exactly when `t` is. -/ def isColimitExtendCoconeEquiv (t : Cocone (F ⋙ G)) : @@ -312,7 +312,7 @@ section variable (G) -/-- When `F : C ⥤ D` is cofinal, and `G : D ⥤ E` has a colimit, then `F ⋙ G` has a colimit also and +/-- When `F : C ⥤ D` is final, and `G : D ⥤ E` has a colimit, then `F ⋙ G` has a colimit also and `colimit (F ⋙ G) ≅ colimit G` https://stacks.math.columbia.edu/tag/04E7 @@ -328,7 +328,7 @@ def colimitCoconeOfComp (t : ColimitCocone (F ⋙ G)) : ColimitCocone G where cocone := extendCocone.obj t.cocone isColimit := (isColimitExtendCoconeEquiv F _).symm t.isColimit -/-- When `F` is cofinal, and `F ⋙ G` has a colimit, then `G` has a colimit also. +/-- When `F` is final, and `F ⋙ G` has a colimit, then `G` has a colimit also. We can't make this an instance, because `F` is not determined by the goal. (Even if this weren't a problem, it would cause a loop with `comp_hasColimit`.) @@ -345,7 +345,7 @@ section -- Porting note: this instance does not seem to be found automatically --attribute [local instance] hasColimit_of_comp -/-- When `F` is cofinal, and `F ⋙ G` has a colimit, then `G` has a colimit also and +/-- When `F` is final, and `F ⋙ G` has a colimit, then `G` has a colimit also and `colimit (F ⋙ G) ≅ colimit G` https://stacks.math.columbia.edu/tag/04E7 @@ -390,9 +390,9 @@ theorem zigzag_of_eqvGen_quot_rel {F : C ⥤ D} {d : D} {f₁ f₂ : ΣX, d ⟶ end Final -/-- If `colimit (F ⋙ coyoneda.obj (op d)) ≅ PUnit` for all `d : D`, then `F` is cofinal. +/-- If `colimit (F ⋙ coyoneda.obj (op d)) ≅ PUnit` for all `d : D`, then `F` is final. -/ -theorem cofinal_of_colimit_comp_coyoneda_iso_pUnit +theorem final_of_colimit_comp_coyoneda_iso_pUnit (I : ∀ d, colimit (F ⋙ coyoneda.obj (op d)) ≅ PUnit) : Final F := ⟨fun d => by have : Nonempty (StructuredArrow d F) := by @@ -410,18 +410,18 @@ theorem cofinal_of_colimit_comp_coyoneda_iso_pUnit clear e y₁ y₂ exact Final.zigzag_of_eqvGen_quot_rel t⟩ -/-- A variant of `cofinal_of_colimit_comp_coyoneda_iso_pUnit` where we bind the various claims +/-- A variant of `final_of_colimit_comp_coyoneda_iso_pUnit` where we bind the various claims about `colimit (F ⋙ coyoneda.obj (Opposite.op d))` for each `d : D` into a single claim about the presheaf `colimit (F ⋙ yoneda)`. -/ -theorem cofinal_of_isTerminal_colimit_comp_yoneda +theorem final_of_isTerminal_colimit_comp_yoneda (h : IsTerminal (colimit (F ⋙ yoneda))) : Final F := by - refine cofinal_of_colimit_comp_coyoneda_iso_pUnit _ (fun d => ?_) + refine final_of_colimit_comp_coyoneda_iso_pUnit _ (fun d => ?_) refine Types.isTerminalEquivIsoPUnit _ ?_ let b := IsTerminal.isTerminalObj ((evaluation _ _).obj (Opposite.op d)) _ h exact b.ofIso <| preservesColimitIso ((evaluation _ _).obj (Opposite.op d)) (F ⋙ yoneda) /-- If the universal morphism `colimit (F ⋙ coyoneda.obj (op d)) ⟶ colimit (coyoneda.obj (op d))` -is an isomorphism (as it always is when `F` is cofinal), +is an isomorphism (as it always is when `F` is final), then `colimit (F ⋙ coyoneda.obj (op d)) ≅ PUnit` (simply because `colimit (coyoneda.obj (op d)) ≅ PUnit`). -/ @@ -437,7 +437,7 @@ variable {C : Type v} [Category.{v} C] {D : Type v} [Category.{v} D] (F : C ⥤ theorem final_iff_isIso_colimit_pre : Final F ↔ ∀ G : D ⥤ Type v, IsIso (colimit.pre G F) := ⟨fun _ => inferInstance, - fun _ => cofinal_of_colimit_comp_coyoneda_iso_pUnit _ fun _ => Final.colimitCompCoyonedaIso _ _⟩ + fun _ => final_of_colimit_comp_coyoneda_iso_pUnit _ fun _ => Final.colimitCompCoyonedaIso _ _⟩ end SmallCategory diff --git a/Mathlib/CategoryTheory/Limits/Presheaf.lean b/Mathlib/CategoryTheory/Limits/Presheaf.lean index 5dc588dc02b386..79b189b11e50c4 100644 --- a/Mathlib/CategoryTheory/Limits/Presheaf.lean +++ b/Mathlib/CategoryTheory/Limits/Presheaf.lean @@ -559,7 +559,7 @@ variable {I : Type v₁} [SmallCategory I] (F : I ⥤ C) Proposition 2.6.3(ii) in [Kashiwara2006] -/ theorem final_toCostructuredArrow_comp_pre {c : Cocone (F ⋙ yoneda)} (hc : IsColimit c) : Functor.Final (c.toCostructuredArrow ⋙ CostructuredArrow.pre F yoneda c.pt) := by - apply Functor.cofinal_of_isTerminal_colimit_comp_yoneda + apply Functor.final_of_isTerminal_colimit_comp_yoneda suffices IsTerminal (colimit ((c.toCostructuredArrow ⋙ CostructuredArrow.pre F yoneda c.pt) ⋙ CostructuredArrow.toOver yoneda c.pt)) by From 23752ee05683cc476abb6f9eb98b63c0eb5d3da1 Mon Sep 17 00:00:00 2001 From: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com> Date: Fri, 18 Oct 2024 10:20:47 +0000 Subject: [PATCH 372/425] feat: the algebraic closure of an algebraic k-algebra is an algebraic closure of k (#17894) Co-authored-by: FR --- Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean b/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean index ea7fe25e09f587..d58f8dcbc128b9 100644 --- a/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean +++ b/Mathlib/FieldTheory/IsAlgClosed/AlgebraicClosure.lean @@ -403,4 +403,9 @@ instance [CharZero k] : CharZero (AlgebraicClosure k) := instance {p : ℕ} [CharP k p] : CharP (AlgebraicClosure k) p := charP_of_injective_algebraMap (RingHom.injective (algebraMap k (AlgebraicClosure k))) p +instance {L : Type*} [Field k] [Field L] [Algebra k L] [Algebra.IsAlgebraic k L] : + IsAlgClosure k (AlgebraicClosure L) where + isAlgebraic := .trans (L := L) + isAlgClosed := inferInstance + end AlgebraicClosure From 1cc3f60d578ae8b32e7e308018e9f409a5dbaedc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Fri, 18 Oct 2024 10:35:29 +0000 Subject: [PATCH 373/425] chore(Order/RelIso/Set): golf `wellFounded_iff_wellFounded_subrel` (#17606) We also move it out of the initial segment file - it doesn't need that machinery to be proven. --- Mathlib/Order/InitialSeg.lean | 14 -------------- Mathlib/Order/RelIso/Set.lean | 11 +++++++++++ 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/Mathlib/Order/InitialSeg.lean b/Mathlib/Order/InitialSeg.lean index 513501c25072e6..e53d78efa02774 100644 --- a/Mathlib/Order/InitialSeg.lean +++ b/Mathlib/Order/InitialSeg.lean @@ -461,20 +461,6 @@ protected theorem acc [IsTrans β s] (f : r ≺i s) (a : α) : Acc r a ↔ Acc s end PrincipalSeg -/-- A relation is well-founded iff every principal segment of it is well-founded. - -In this lemma we use `Subrel` to indicate its principal segments because it's usually more -convenient to use. --/ -theorem wellFounded_iff_wellFounded_subrel {β : Type*} {s : β → β → Prop} [IsTrans β s] : - WellFounded s ↔ ∀ b, WellFounded (Subrel s { b' | s b' b }) := by - refine - ⟨fun wf b => ⟨fun b' => ((PrincipalSeg.ofElement _ b).acc b').mpr (wf.apply b')⟩, fun wf => - ⟨fun b => Acc.intro _ fun b' hb' => ?_⟩⟩ - let f := PrincipalSeg.ofElement s b - obtain ⟨b', rfl⟩ := f.mem_range_of_rel_top ((PrincipalSeg.ofElement_top s b).symm ▸ hb') - exact (f.acc b').mp ((wf b).apply b') - theorem wellFounded_iff_principalSeg.{u} {β : Type u} {s : β → β → Prop} [IsTrans β s] : WellFounded s ↔ ∀ (α : Type u) (r : α → α → Prop) (_ : r ≺i s), WellFounded r := ⟨fun wf _ _ f => RelHomClass.wellFounded f.toRelEmbedding wf, fun h => diff --git a/Mathlib/Order/RelIso/Set.lean b/Mathlib/Order/RelIso/Set.lean index 961b9773f59123..ec7b62b18b16f3 100644 --- a/Mathlib/Order/RelIso/Set.lean +++ b/Mathlib/Order/RelIso/Set.lean @@ -98,3 +98,14 @@ theorem RelIso.preimage_eq_image_symm (e : r ≃r s) (t : Set β) : e ⁻¹' t = rw [e.symm.image_eq_preimage_symm]; rfl end image + +theorem Acc.of_subrel {r : α → α → Prop} [IsTrans α r] {b : α} (a : { a // r a b }) + (h : Acc (Subrel r { a | r a b }) a) : Acc r a.1 := + h.recOn fun a _ IH ↦ ⟨_, fun _ hb ↦ IH ⟨_, _root_.trans hb a.2⟩ hb⟩ + +/-- A relation `r` is well-founded iff every downward-interval `{ a | r a b }` of it is +well-founded. -/ +theorem wellFounded_iff_wellFounded_subrel {r : α → α → Prop} [IsTrans α r] : + WellFounded r ↔ ∀ b, WellFounded (Subrel r { a | r a b }) where + mp h _ := InvImage.wf Subtype.val h + mpr h := ⟨fun a ↦ ⟨_, fun b hr ↦ ((h a).apply _).of_subrel ⟨b, hr⟩⟩⟩ From cbaeaf5ebf33c9f777f35f6cf3a44029e7d35c0e Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Fri, 18 Oct 2024 10:35:30 +0000 Subject: [PATCH 374/425] chore(Topology): deprecate `Homeomorph.toContinuousMap` (#17714) Use `_root_.toContinuousMap` instead. --- Mathlib/MeasureTheory/Measure/Content.lean | 6 +++--- Mathlib/Topology/Category/TopCat/Basic.lean | 4 ++-- Mathlib/Topology/ContinuousMap/Algebra.lean | 4 ++-- Mathlib/Topology/ContinuousMap/Basic.lean | 16 ++++++---------- Mathlib/Topology/ContinuousMap/Compact.lean | 4 ++-- .../ContinuousMap/ContinuousMapZero.lean | 8 ++++---- Mathlib/Topology/ContinuousMap/Defs.lean | 4 ++++ .../Topology/ContinuousMap/Polynomial.lean | 2 +- .../Topology/ContinuousMap/Weierstrass.lean | 2 +- Mathlib/Topology/Homotopy/HomotopyGroup.lean | 19 +++++++++---------- Mathlib/Topology/Sets/Opens.lean | 8 ++++---- 11 files changed, 38 insertions(+), 39 deletions(-) diff --git a/Mathlib/MeasureTheory/Measure/Content.lean b/Mathlib/MeasureTheory/Measure/Content.lean index b07a09b9ad57e5..77169173b08ad4 100644 --- a/Mathlib/MeasureTheory/Measure/Content.lean +++ b/Mathlib/MeasureTheory/Measure/Content.lean @@ -190,7 +190,7 @@ theorem innerContent_iUnion_nat [R1Space G] ⦃U : ℕ → Set G⦄ rwa [Opens.iSup_def] at this theorem innerContent_comap (f : G ≃ₜ G) (h : ∀ ⦃K : Compacts G⦄, μ (K.map f f.continuous) = μ K) - (U : Opens G) : μ.innerContent (Opens.comap f.toContinuousMap U) = μ.innerContent U := by + (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, Subtype.mk_eq_mk, Compacts.equiv] @@ -200,7 +200,7 @@ theorem innerContent_comap (f : G ≃ₜ G) (h : ∀ ⦃K : Compacts G⦄, μ (K theorem is_mul_left_invariant_innerContent [Group G] [TopologicalGroup G] (h : ∀ (g : G) {K : Compacts G}, μ (K.map _ <| continuous_mul_left g) = μ K) (g : G) (U : Opens G) : - μ.innerContent (Opens.comap (Homeomorph.mulLeft g).toContinuousMap U) = μ.innerContent U := by + μ.innerContent (Opens.comap (Homeomorph.mulLeft g) U) = μ.innerContent U := by convert μ.innerContent_comap (Homeomorph.mulLeft g) (fun K => h g) U @[to_additive] @@ -211,7 +211,7 @@ theorem innerContent_pos_of_is_mul_left_invariant [Group G] [TopologicalGroup G] rcases compact_covered_by_mul_left_translates K.2 this with ⟨s, hs⟩ suffices μ K ≤ s.card * μ.innerContent U by exact (ENNReal.mul_pos_iff.mp <| hK.bot_lt.trans_le this).2 - have : (K : Set G) ⊆ ↑(⨆ g ∈ s, Opens.comap (Homeomorph.mulLeft g).toContinuousMap U) := by + have : (K : Set G) ⊆ ↑(⨆ g ∈ s, Opens.comap (Homeomorph.mulLeft g : C(G, G)) U) := by simpa only [Opens.iSup_def, Opens.coe_comap, Subtype.coe_mk] refine (μ.le_innerContent _ _ this).trans ?_ refine diff --git a/Mathlib/Topology/Category/TopCat/Basic.lean b/Mathlib/Topology/Category/TopCat/Basic.lean index 8cf13a2f355f49..f1a2371e9013c8 100644 --- a/Mathlib/Topology/Category/TopCat/Basic.lean +++ b/Mathlib/Topology/Category/TopCat/Basic.lean @@ -126,8 +126,8 @@ def trivial : Type u ⥤ TopCat.{u} where @[simps] def isoOfHomeo {X Y : TopCat.{u}} (f : X ≃ₜ Y) : X ≅ Y where -- Porting note: previously ⟨f⟩ for hom (inv) and tidy closed proofs - hom := f.toContinuousMap - inv := f.symm.toContinuousMap + hom := (f : C(X, Y)) + inv := (f.symm : C(Y, X)) hom_inv_id := by ext; exact f.symm_apply_apply _ inv_hom_id := by ext; exact f.apply_symm_apply _ diff --git a/Mathlib/Topology/ContinuousMap/Algebra.lean b/Mathlib/Topology/ContinuousMap/Algebra.lean index b6ff6659b48783..59525a680230d5 100644 --- a/Mathlib/Topology/ContinuousMap/Algebra.lean +++ b/Mathlib/Topology/ContinuousMap/Algebra.lean @@ -1010,7 +1010,7 @@ variable [ContinuousStar A] [Algebra 𝕜 A] actually a homeomorphism. -/ @[simps] def compStarAlgEquiv' (f : X ≃ₜ Y) : C(Y, A) ≃⋆ₐ[𝕜] C(X, A) := - { f.toContinuousMap.compStarAlgHom' 𝕜 A with + { (f : C(X, Y)).compStarAlgHom' 𝕜 A with toFun := (f : C(X, Y)).compStarAlgHom' 𝕜 A invFun := (f.symm : C(Y, X)).compStarAlgHom' 𝕜 A left_inv := fun g => by @@ -1019,7 +1019,7 @@ def compStarAlgEquiv' (f : X ≃ₜ Y) : C(Y, A) ≃⋆ₐ[𝕜] C(X, A) := right_inv := fun g => by simp only [ContinuousMap.compStarAlgHom'_apply, ContinuousMap.comp_assoc, symm_comp_toContinuousMap, ContinuousMap.comp_id] - map_smul' := fun k a => map_smul (f.toContinuousMap.compStarAlgHom' 𝕜 A) k a } + map_smul' := fun k a => map_smul ((f : C(X, Y)).compStarAlgHom' 𝕜 A) k a } end Homeomorph diff --git a/Mathlib/Topology/ContinuousMap/Basic.lean b/Mathlib/Topology/ContinuousMap/Basic.lean index bd8aca0de948b3..69e4f1e0ee255f 100644 --- a/Mathlib/Topology/ContinuousMap/Basic.lean +++ b/Mathlib/Topology/ContinuousMap/Basic.lean @@ -429,19 +429,15 @@ namespace Homeomorph variable {α β γ : Type*} [TopologicalSpace α] [TopologicalSpace β] [TopologicalSpace γ] variable (f : α ≃ₜ β) (g : β ≃ₜ γ) +instance instContinuousMapClass : ContinuousMapClass (α ≃ₜ β) α β where + map_continuous f := f.continuous_toFun + /-- The forward direction of a homeomorphism, as a bundled continuous map. -/ -@[simps] -def toContinuousMap (e : α ≃ₜ β) : C(α, β) := +@[simps, deprecated _root_.toContinuousMap (since := "2024-10-12")] +protected def toContinuousMap (e : α ≃ₜ β) : C(α, β) := ⟨e, e.continuous_toFun⟩ -/-- `Homeomorph.toContinuousMap` as a coercion. -/ -instance : Coe (α ≃ₜ β) C(α, β) := - ⟨Homeomorph.toContinuousMap⟩ - --- Porting note: Syntactic tautology -/- theorem toContinuousMap_as_coe : f.toContinuousMap = f := - rfl --/ +attribute [deprecated ContinuousMap.coe_apply (since := "2024-10-12")] toContinuousMap_apply @[simp] theorem coe_refl : (Homeomorph.refl α : C(α, α)) = ContinuousMap.id α := diff --git a/Mathlib/Topology/ContinuousMap/Compact.lean b/Mathlib/Topology/ContinuousMap/Compact.lean index 552c3e592bff1c..e5b573631c8382 100644 --- a/Mathlib/Topology/ContinuousMap/Compact.lean +++ b/Mathlib/Topology/ContinuousMap/Compact.lean @@ -455,8 +455,8 @@ theorem compRightContinuousMap_apply {X Y : Type*} (T : Type*) [TopologicalSpace def compRightHomeomorph {X Y : Type*} (T : Type*) [TopologicalSpace X] [CompactSpace X] [TopologicalSpace Y] [CompactSpace Y] [PseudoMetricSpace T] (f : X ≃ₜ Y) : C(Y, T) ≃ₜ C(X, T) where - toFun := compRightContinuousMap T f.toContinuousMap - invFun := compRightContinuousMap T f.symm.toContinuousMap + toFun := compRightContinuousMap T f + invFun := compRightContinuousMap T f.symm left_inv g := ext fun _ => congr_arg g (f.apply_symm_apply _) right_inv g := ext fun _ => congr_arg g (f.symm_apply_apply _) diff --git a/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean b/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean index 575b4e26ad07c1..6d699f5ba30429 100644 --- a/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean +++ b/Mathlib/Topology/ContinuousMap/ContinuousMapZero.lean @@ -303,15 +303,15 @@ alias uniformEmbedding_comp := isUniformEmbedding_comp 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.toContinuousMap, (f.toEquiv.apply_eq_iff_eq_symm_apply.eq ▸ hf).symm⟩ - invFun g := g.comp ⟨f.toContinuousMap, hf⟩ + toFun g := g.comp ⟨f.symm, (f.toEquiv.apply_eq_iff_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 _ uniformContinuous_toFun := isUniformEmbedding_toContinuousMap.uniformContinuous_iff.mpr <| - ContinuousMap.uniformContinuous_comp_left f.symm.toContinuousMap |>.comp + ContinuousMap.uniformContinuous_comp_left (f.symm : C(Y, X)) |>.comp isUniformEmbedding_toContinuousMap.uniformContinuous uniformContinuous_invFun := isUniformEmbedding_toContinuousMap.uniformContinuous_iff.mpr <| - ContinuousMap.uniformContinuous_comp_left f.toContinuousMap |>.comp + ContinuousMap.uniformContinuous_comp_left (f : C(X, Y)) |>.comp isUniformEmbedding_toContinuousMap.uniformContinuous end UniformSpace diff --git a/Mathlib/Topology/ContinuousMap/Defs.lean b/Mathlib/Topology/ContinuousMap/Defs.lean index f576214a277582..e1ee866070f685 100644 --- a/Mathlib/Topology/ContinuousMap/Defs.lean +++ b/Mathlib/Topology/ContinuousMap/Defs.lean @@ -93,6 +93,10 @@ protected theorem coe_coe {F : Type*} [FunLike F X Y] [ContinuousMapClass F X Y] ⇑(f : C(X, Y)) = f := rfl +protected theorem coe_apply {F : Type*} [FunLike F X Y] [ContinuousMapClass F X Y] (f : F) (x : X) : + (f : C(X, Y)) x = f x := + rfl + @[ext] theorem ext {f g : C(X, Y)} (h : ∀ a, f a = g a) : f = g := DFunLike.ext _ _ h diff --git a/Mathlib/Topology/ContinuousMap/Polynomial.lean b/Mathlib/Topology/ContinuousMap/Polynomial.lean index 83a3dd5e6a0ed4..237d38cd410f8e 100644 --- a/Mathlib/Topology/ContinuousMap/Polynomial.lean +++ b/Mathlib/Topology/ContinuousMap/Polynomial.lean @@ -164,7 +164,7 @@ open ContinuousMap /-- The preimage of polynomials on `[0,1]` under the pullback map by `x ↦ (b-a) * x + a` is the polynomials on `[a,b]`. -/ theorem polynomialFunctions.comap_compRightAlgHom_iccHomeoI (a b : ℝ) (h : a < b) : - (polynomialFunctions I).comap (compRightAlgHom ℝ ℝ (iccHomeoI a b h).symm.toContinuousMap) = + (polynomialFunctions I).comap (compRightAlgHom ℝ ℝ (iccHomeoI a b h).symm) = polynomialFunctions (Set.Icc a b) := by ext f fconstructor diff --git a/Mathlib/Topology/ContinuousMap/Weierstrass.lean b/Mathlib/Topology/ContinuousMap/Weierstrass.lean index fbfdd66fb20238..8e903e39101e16 100644 --- a/Mathlib/Topology/ContinuousMap/Weierstrass.lean +++ b/Mathlib/Topology/ContinuousMap/Weierstrass.lean @@ -55,7 +55,7 @@ theorem polynomialFunctions_closure_eq_top (a b : ℝ) : · -- We can pullback continuous functions on `[a,b]` to continuous functions on `[0,1]`, -- by precomposing with an affine map. let W : C(Set.Icc a b, ℝ) →ₐ[ℝ] C(I, ℝ) := - compRightAlgHom ℝ ℝ (iccHomeoI a b h).symm.toContinuousMap + compRightAlgHom ℝ ℝ (iccHomeoI a b h).symm -- This operation is itself a homeomorphism -- (with respect to the norm topologies on continuous functions). let W' : C(Set.Icc a b, ℝ) ≃ₜ C(I, ℝ) := compRightHomeomorph ℝ (iccHomeoI a b h).symm diff --git a/Mathlib/Topology/Homotopy/HomotopyGroup.lean b/Mathlib/Topology/Homotopy/HomotopyGroup.lean index a9ec3d6dc3be4d..21ad316e363399 100644 --- a/Mathlib/Topology/Homotopy/HomotopyGroup.lean +++ b/Mathlib/Topology/Homotopy/HomotopyGroup.lean @@ -180,7 +180,7 @@ variable [DecidableEq N] @[simps] def toLoop (i : N) (p : Ω^ N X x) : Ω (Ω^ { j // j ≠ i } X x) const where toFun t := - ⟨(p.val.comp (Cube.insertAt i).toContinuousMap).curry t, fun y yH => + ⟨(p.val.comp (Cube.insertAt i)).curry t, fun y yH => p.property (Cube.insertAt i (t, y)) (Cube.insertAt_boundary i <| Or.inr yH)⟩ source' := by ext t; refine p.property (Cube.insertAt i (0, t)) ⟨i, Or.inl ?_⟩; simp target' := by ext t; refine p.property (Cube.insertAt i (1, t)) ⟨i, Or.inr ?_⟩; simp @@ -200,10 +200,10 @@ theorem continuous_toLoop (i : N) : Continuous (@toLoop N X _ x _ i) := @[simps] def fromLoop (i : N) (p : Ω (Ω^ { j // j ≠ i } X x) const) : Ω^ N X x := ⟨(ContinuousMap.comp ⟨Subtype.val, by fun_prop⟩ p.toContinuousMap).uncurry.comp - (Cube.splitAt i).toContinuousMap, + (Cube.splitAt i), by rintro y ⟨j, Hj⟩ - simp only [ContinuousMap.comp_apply, toContinuousMap_apply, + simp only [ContinuousMap.comp_apply, ContinuousMap.coe_coe, funSplitAt_apply, ContinuousMap.uncurry_apply, ContinuousMap.coe_mk, Function.uncurry_apply_pair] obtain rfl | Hne := eq_or_ne j i @@ -243,8 +243,8 @@ theorem fromLoop_apply (i : N) {p : Ω (Ω^ { j // j ≠ i } X x) const} {t : I^ /-- Composition with `Cube.insertAt` as a continuous map. -/ abbrev cCompInsert (i : N) : C(C(I^N, X), C(I × I^{ j // j ≠ i }, X)) := - ⟨fun f => f.comp (Cube.insertAt i).toContinuousMap, - (Cube.insertAt i).toContinuousMap.continuous_comp_left⟩ + ⟨fun f => f.comp (Cube.insertAt i), + (toContinuousMap <| Cube.insertAt i).continuous_comp_left⟩ /-- A homotopy between `n+1`-dimensional loops `p` and `q` constant on the boundary seen as a homotopy between two paths in the space of `n`-dimensional paths. -/ @@ -280,7 +280,7 @@ theorem homotopicTo (i : N) {p q : Ω^ N X x} : C(I × I^N, X) := (ContinuousMap.comp ⟨_, ContinuousMap.continuous_uncurry⟩ (ContinuousMap.comp ⟨Subtype.val, by continuity⟩ H.toContinuousMap).curry).uncurry.comp <| - (ContinuousMap.id I).prodMap (Cube.splitAt i).toContinuousMap + (ContinuousMap.id I).prodMap (Cube.splitAt i) theorem homotopicFrom (i : N) {p q : Ω^ N X x} : (toLoop i p).Homotopic (toLoop i q) → Homotopic p q := by @@ -289,15 +289,14 @@ theorem homotopicFrom (i : N) {p q : Ω^ N X x} : · rintro t y ⟨j, jH⟩ erw [homotopyFrom_apply] obtain rfl | h := eq_or_ne j i - · simp only [Prod.map_apply, id_eq, toContinuousMap_apply, funSplitAt_apply, - Function.uncurry_apply_pair] + · simp only [Prod.map_apply, id_eq, funSplitAt_apply, Function.uncurry_apply_pair] rw [H.eq_fst] exacts [congr_arg p ((Cube.splitAt j).left_inv _), jH] · rw [p.2 _ ⟨j, jH⟩]; apply boundary; exact ⟨⟨j, h⟩, jH⟩ all_goals intro apply (homotopyFrom_apply _ _ _).trans - simp only [Prod.map_apply, id_eq, toContinuousMap_apply, funSplitAt_apply, + simp only [Prod.map_apply, id_eq, funSplitAt_apply, Function.uncurry_apply_pair, ContinuousMap.HomotopyWith.apply_zero, ContinuousMap.HomotopyWith.apply_one, ne_eq, Path.coe_toContinuousMap, toLoop_apply_coe, ContinuousMap.curry_apply, ContinuousMap.comp_apply] @@ -315,7 +314,7 @@ def transAt (i : N) (f g : Ω^ N X x) : Ω^ N X x := (by ext1; symm dsimp only [Path.trans, fromLoop, Path.coe_mk_mk, Function.comp_apply, mk_apply, - ContinuousMap.comp_apply, toContinuousMap_apply, funSplitAt_apply, + ContinuousMap.comp_apply, ContinuousMap.coe_coe, funSplitAt_apply, ContinuousMap.uncurry_apply, ContinuousMap.coe_mk, Function.uncurry_apply_pair] split_ifs · show f _ = _; congr 1 diff --git a/Mathlib/Topology/Sets/Opens.lean b/Mathlib/Topology/Sets/Opens.lean index 1b2ffd4204a29e..bd142710c09905 100644 --- a/Mathlib/Topology/Sets/Opens.lean +++ b/Mathlib/Topology/Sets/Opens.lean @@ -379,10 +379,10 @@ theorem comap_injective [T0Space β] : Injective (comap : C(α, β) → FrameHom /-- A homeomorphism induces an order-preserving equivalence on open sets, by taking comaps. -/ @[simps (config := .asFn) apply] def _root_.Homeomorph.opensCongr (f : α ≃ₜ β) : Opens α ≃o Opens β where - toFun := Opens.comap f.symm.toContinuousMap - invFun := Opens.comap f.toContinuousMap - left_inv := fun _ => ext <| f.toEquiv.preimage_symm_preimage _ - right_inv := fun _ => ext <| f.toEquiv.symm_preimage_preimage _ + toFun := Opens.comap (f.symm : C(β, α)) + invFun := Opens.comap (f : C(α, β)) + left_inv _ := ext <| f.toEquiv.preimage_symm_preimage _ + right_inv _ := ext <| f.toEquiv.symm_preimage_preimage _ map_rel_iff' := by simp only [← SetLike.coe_subset_coe]; exact f.symm.surjective.preimage_subset_preimage_iff From 1ee5cd92a144780e03f1cdb6addc2c9564fad89d Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Fri, 18 Oct 2024 21:44:05 +1100 Subject: [PATCH 375/425] unused variable --- Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean b/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean index 932325058e4265..e02b816afa9d2e 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean @@ -256,7 +256,7 @@ instance IsClosedImmersion.isLocalAtTarget : IsLocalAtTarget @IsClosedImmersion /-- 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 - (fun X Y f ↦ IsAffine X ∧ Function.Surjective (f.app ⊤)) := by + (fun X _ f ↦ IsAffine X ∧ Function.Surjective (f.app ⊤)) := by convert HasAffineProperty.of_isLocalAtTarget @IsClosedImmersion refine ⟨fun ⟨h₁, h₂⟩ ↦ of_surjective_of_isAffine _ h₂, by apply isAffine_surjective_of_isAffine⟩ From a6bc4c5ee86f2ccb63f6d63406cd3db02d3de29a Mon Sep 17 00:00:00 2001 From: sgouezel Date: Fri, 18 Oct 2024 11:08:02 +0000 Subject: [PATCH 376/425] chore: reorganize the `ContinuousOn` file (#17901) Before adding some API for `ContinuousWithinAt` to have it match the one for `DifferentiableWithinAt`, and `ContDiffWithinAt`, and manifold versions, I'd rather start from a clean file. The file was a mess of random things added at random places, I tried to make it coherent. Nothing has been added or removed, no name has been changed, pure shuffling around. --- Mathlib/Topology/Constructions.lean | 7 + Mathlib/Topology/ContinuousOn.lean | 732 +++++++++++++++------------- 2 files changed, 398 insertions(+), 341 deletions(-) diff --git a/Mathlib/Topology/Constructions.lean b/Mathlib/Topology/Constructions.lean index e0bb583947c37a..82bce23e4c0c90 100644 --- a/Mathlib/Topology/Constructions.lean +++ b/Mathlib/Topology/Constructions.lean @@ -1134,6 +1134,13 @@ lemma isClosed_preimage_val {s t : Set X} : IsClosed (s ↓∩ t) ↔ s ∩ clos Subtype.image_preimage_coe, subset_antisymm_iff, and_iff_left, Set.subset_inter_iff, and_iff_right] exacts [Set.inter_subset_left, Set.subset_inter Set.inter_subset_left subset_closure] + +theorem frontier_inter_open_inter {s t : Set X} (ht : IsOpen t) : + frontier (s ∩ t) ∩ t = frontier s ∩ t := by + simp only [Set.inter_comm _ t, ← Subtype.preimage_coe_eq_preimage_coe_iff, + ht.isOpenMap_subtype_val.preimage_frontier_eq_frontier_preimage continuous_subtype_val, + Subtype.preimage_coe_self_inter] + end Subtype section Quotient diff --git a/Mathlib/Topology/ContinuousOn.lean b/Mathlib/Topology/ContinuousOn.lean index a09c8362c391f9..d69f7aec791234 100644 --- a/Mathlib/Topology/ContinuousOn.lean +++ b/Mathlib/Topology/ContinuousOn.lean @@ -9,13 +9,14 @@ import Mathlib.Topology.Constructions /-! # Neighborhoods and continuity relative to a subset -This file defines relative versions +This file develops API on the relative versions * `nhdsWithin` of `nhds` * `ContinuousOn` of `Continuous` * `ContinuousWithinAt` of `ContinuousAt` -and proves their basic properties, including the relationships between +related to continuity, which are defined in previous definition files. +Their basic properties studied in this file include the relationships between these restricted notions and the corresponding notions for the subtype equipped with the subspace topology. @@ -32,6 +33,10 @@ open Set Filter Function Topology Filter variable {α : Type*} {β : Type*} {γ : Type*} {δ : Type*} variable [TopologicalSpace α] +/-! +## Properties of the neighborhood-within filter +-/ + @[simp] theorem nhds_bind_nhdsWithin {a : α} {s : Set α} : ((𝓝 a).bind fun x => 𝓝[s] x) = 𝓝[s] a := bind_inf_principal.trans <| congr_arg₂ _ nhds_bind_nhds rfl @@ -299,6 +304,8 @@ instance Pi.instNeBotNhdsWithinIoi [Nonempty ι] [∀ i, Preorder (π i)] {x : [∀ i, (𝓝[>] x i).NeBot] : (𝓝[>] x).NeBot := Pi.instNeBotNhdsWithinIio (π := fun i ↦ (π i)ᵒᵈ) (x := fun i ↦ OrderDual.toDual (x i)) +end Pi + theorem Filter.Tendsto.piecewise_nhdsWithin {f g : α → β} {t : Set α} [∀ x, Decidable (x ∈ t)] {a : α} {s : Set α} {l : Filter β} (h₀ : Tendsto f (𝓝[s ∩ t] a) l) (h₁ : Tendsto g (𝓝[s ∩ tᶜ] a) l) : Tendsto (piecewise t f g) (𝓝[s] a) l := by @@ -438,8 +445,16 @@ theorem tendsto_nhdsWithin_iff_subtype {s : Set α} {a : α} (h : a ∈ s) (f : Tendsto f (𝓝[s] a) l ↔ Tendsto (s.restrict f) (𝓝 ⟨a, h⟩) l := by rw [nhdsWithin_eq_map_subtype_coe h, tendsto_map'_iff]; rfl +/-! +## Local continuity properties of functions +-/ + variable [TopologicalSpace β] [TopologicalSpace γ] [TopologicalSpace δ] +/-! +### `ContinuousWithinAt` +-/ + /-- If a function is continuous within `s` at `x`, then it tends to `f x` within `s` by definition. We register this fact for use with the dot notation, especially to use `Filter.Tendsto.comp` as `ContinuousWithinAt.comp` will have a different meaning. -/ @@ -447,10 +462,6 @@ theorem ContinuousWithinAt.tendsto {f : α → β} {s : Set α} {x : α} (h : Co Tendsto f (𝓝[s] x) (𝓝 (f x)) := h -theorem ContinuousOn.continuousWithinAt {f : α → β} {s : Set α} {x : α} (hf : ContinuousOn f s) - (hx : x ∈ s) : ContinuousWithinAt f s x := - hf x hx - theorem continuousWithinAt_univ (f : α → β) (x : α) : ContinuousWithinAt f Set.univ x ↔ ContinuousAt f x := by rw [ContinuousAt, ContinuousWithinAt, nhdsWithin_univ] @@ -471,93 +482,44 @@ theorem ContinuousWithinAt.tendsto_nhdsWithin_image {f : α → β} {x : α} {s (h : ContinuousWithinAt f s x) : Tendsto f (𝓝[s] x) (𝓝[f '' s] f x) := h.tendsto_nhdsWithin (mapsTo_image _ _) -theorem ContinuousWithinAt.prod_map {f : α → γ} {g : β → δ} {s : Set α} {t : Set β} {x : α} {y : β} - (hf : ContinuousWithinAt f s x) (hg : ContinuousWithinAt g t y) : - ContinuousWithinAt (Prod.map f g) (s ×ˢ t) (x, y) := by - unfold ContinuousWithinAt at * - rw [nhdsWithin_prod_eq, Prod.map, nhds_prod_eq] - exact hf.prod_map hg - -theorem continuousWithinAt_prod_of_discrete_left [DiscreteTopology α] - {f : α × β → γ} {s : Set (α × β)} {x : α × β} : - ContinuousWithinAt f s x ↔ ContinuousWithinAt (f ⟨x.1, ·⟩) {b | (x.1, b) ∈ s} x.2 := by - rw [← x.eta]; simp_rw [ContinuousWithinAt, nhdsWithin, nhds_prod_eq, nhds_discrete, pure_prod, - ← map_inf_principal_preimage]; rfl - -theorem continuousWithinAt_prod_of_discrete_right [DiscreteTopology β] - {f : α × β → γ} {s : Set (α × β)} {x : α × β} : - ContinuousWithinAt f s x ↔ ContinuousWithinAt (f ⟨·, x.2⟩) {a | (a, x.2) ∈ s} x.1 := by - rw [← x.eta]; simp_rw [ContinuousWithinAt, nhdsWithin, nhds_prod_eq, nhds_discrete, prod_pure, - ← map_inf_principal_preimage]; rfl - -theorem continuousAt_prod_of_discrete_left [DiscreteTopology α] {f : α × β → γ} {x : α × β} : - ContinuousAt f x ↔ ContinuousAt (f ⟨x.1, ·⟩) x.2 := by - simp_rw [← continuousWithinAt_univ]; exact continuousWithinAt_prod_of_discrete_left - -theorem continuousAt_prod_of_discrete_right [DiscreteTopology β] {f : α × β → γ} {x : α × β} : - ContinuousAt f x ↔ ContinuousAt (f ⟨·, x.2⟩) x.1 := by - simp_rw [← continuousWithinAt_univ]; exact continuousWithinAt_prod_of_discrete_right - -theorem continuousOn_prod_of_discrete_left [DiscreteTopology α] {f : α × β → γ} {s : Set (α × β)} : - ContinuousOn f s ↔ ∀ a, ContinuousOn (f ⟨a, ·⟩) {b | (a, b) ∈ s} := by - simp_rw [ContinuousOn, Prod.forall, continuousWithinAt_prod_of_discrete_left]; rfl - -theorem continuousOn_prod_of_discrete_right [DiscreteTopology β] {f : α × β → γ} {s : Set (α × β)} : - ContinuousOn f s ↔ ∀ b, ContinuousOn (f ⟨·, b⟩) {a | (a, b) ∈ s} := by - simp_rw [ContinuousOn, Prod.forall, continuousWithinAt_prod_of_discrete_right]; apply forall_swap - -/-- If a function `f a b` is such that `y ↦ f a b` is continuous for all `a`, and `a` lives in a -discrete space, then `f` is continuous, and vice versa. -/ -theorem continuous_prod_of_discrete_left [DiscreteTopology α] {f : α × β → γ} : - Continuous f ↔ ∀ a, Continuous (f ⟨a, ·⟩) := by - simp_rw [continuous_iff_continuousOn_univ]; exact continuousOn_prod_of_discrete_left - -theorem continuous_prod_of_discrete_right [DiscreteTopology β] {f : α × β → γ} : - Continuous f ↔ ∀ b, Continuous (f ⟨·, b⟩) := by - simp_rw [continuous_iff_continuousOn_univ]; exact continuousOn_prod_of_discrete_right - -theorem isOpenMap_prod_of_discrete_left [DiscreteTopology α] {f : α × β → γ} : - IsOpenMap f ↔ ∀ a, IsOpenMap (f ⟨a, ·⟩) := by - simp_rw [isOpenMap_iff_nhds_le, Prod.forall, nhds_prod_eq, nhds_discrete, pure_prod, map_map] - rfl - -theorem isOpenMap_prod_of_discrete_right [DiscreteTopology β] {f : α × β → γ} : - IsOpenMap f ↔ ∀ b, IsOpenMap (f ⟨·, b⟩) := by - simp_rw [isOpenMap_iff_nhds_le, Prod.forall, forall_swap (α := α) (β := β), nhds_prod_eq, - nhds_discrete, prod_pure, map_map]; rfl +theorem nhdsWithin_le_comap {x : α} {s : Set α} {f : α → β} (ctsf : ContinuousWithinAt f s x) : + 𝓝[s] x ≤ comap f (𝓝[f '' s] f x) := + ctsf.tendsto_nhdsWithin_image.le_comap -theorem continuousWithinAt_pi {ι : Type*} {π : ι → Type*} [∀ i, TopologicalSpace (π i)] - {f : α → ∀ i, π i} {s : Set α} {x : α} : - ContinuousWithinAt f s x ↔ ∀ i, ContinuousWithinAt (fun y => f y i) s x := - tendsto_pi_nhds +theorem ContinuousWithinAt.preimage_mem_nhdsWithin {f : α → β} {x : α} {s : Set α} {t : Set β} + (h : ContinuousWithinAt f s x) (ht : t ∈ 𝓝 (f x)) : f ⁻¹' t ∈ 𝓝[s] x := + h ht -theorem continuousOn_pi {ι : Type*} {π : ι → Type*} [∀ i, TopologicalSpace (π i)] - {f : α → ∀ i, π i} {s : Set α} : ContinuousOn f s ↔ ∀ i, ContinuousOn (fun y => f y i) s := - ⟨fun h i x hx => tendsto_pi_nhds.1 (h x hx) i, fun h x hx => tendsto_pi_nhds.2 fun i => h i x hx⟩ +theorem ContinuousWithinAt.preimage_mem_nhdsWithin' {f : α → β} {x : α} {s : Set α} {t : Set β} + (h : ContinuousWithinAt f s x) (ht : t ∈ 𝓝[f '' s] f x) : f ⁻¹' t ∈ 𝓝[s] x := + h.tendsto_nhdsWithin (mapsTo_image _ _) ht -@[fun_prop] -theorem continuousOn_pi' {ι : Type*} {π : ι → Type*} [∀ i, TopologicalSpace (π i)] - {f : α → ∀ i, π i} {s : Set α} (hf : ∀ i, ContinuousOn (fun y => f y i) s) : - ContinuousOn f s := - continuousOn_pi.2 hf +theorem ContinuousWithinAt.preimage_mem_nhdsWithin'' + {f : α → β} {x : α} {y : β} {s t : Set β} + (h : ContinuousWithinAt f (f ⁻¹' s) x) (ht : t ∈ 𝓝[s] y) (hxy : y = f x) : + f ⁻¹' t ∈ 𝓝[f ⁻¹' s] x := by + rw [hxy] at ht + exact h.preimage_mem_nhdsWithin' (nhdsWithin_mono _ (image_preimage_subset f s) ht) -theorem ContinuousWithinAt.fin_insertNth {n} {π : Fin (n + 1) → Type*} - [∀ i, TopologicalSpace (π i)] (i : Fin (n + 1)) {f : α → π i} {a : α} {s : Set α} - (hf : ContinuousWithinAt f s a) {g : α → ∀ j : Fin n, π (i.succAbove j)} - (hg : ContinuousWithinAt g s a) : ContinuousWithinAt (fun a => i.insertNth (f a) (g a)) s a := - hf.tendsto.fin_insertNth i hg +theorem continuousWithinAt_of_not_mem_closure {f : α → β} {s : Set α} {x : α} (hx : x ∉ closure s) : + ContinuousWithinAt f s x := by + rw [mem_closure_iff_nhdsWithin_neBot, not_neBot] at hx + rw [ContinuousWithinAt, hx] + exact tendsto_bot -nonrec theorem ContinuousOn.fin_insertNth {n} {π : Fin (n + 1) → Type*} - [∀ i, TopologicalSpace (π i)] (i : Fin (n + 1)) {f : α → π i} {s : Set α} - (hf : ContinuousOn f s) {g : α → ∀ j : Fin n, π (i.succAbove j)} (hg : ContinuousOn g s) : - ContinuousOn (fun a => i.insertNth (f a) (g a)) s := fun a ha => - (hf a ha).fin_insertNth i (hg a ha) +/-! +### `ContinuousOn` +-/ theorem continuousOn_iff {f : α → β} {s : Set α} : ContinuousOn f s ↔ ∀ x ∈ s, ∀ t : Set β, IsOpen t → f x ∈ t → ∃ u, IsOpen u ∧ x ∈ u ∧ u ∩ s ⊆ f ⁻¹' t := by simp only [ContinuousOn, ContinuousWithinAt, tendsto_nhds, mem_nhdsWithin] +theorem ContinuousOn.continuousWithinAt {f : α → β} {s : Set α} {x : α} (hf : ContinuousOn f s) + (hx : x ∈ s) : ContinuousWithinAt f s x := + hf x hx + theorem continuousOn_iff_continuous_restrict {f : α → β} {s : Set α} : ContinuousOn f s ↔ Continuous (s.restrict f) := by rw [ContinuousOn, continuous_iff_continuousAt]; constructor @@ -606,10 +568,6 @@ theorem continuousOn_iff_isClosed {f : α → β} {s : Set α} : 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] -theorem ContinuousOn.prod_map {f : α → γ} {g : β → δ} {s : Set α} {t : Set β} - (hf : ContinuousOn f s) (hg : ContinuousOn g t) : ContinuousOn (Prod.map f g) (s ×ˢ t) := - fun ⟨x, y⟩ ⟨hx, hy⟩ => ContinuousWithinAt.prod_map (hf x hx) (hg y hy) - theorem continuous_of_cover_nhds {ι : Sort*} {f : α → β} {s : ι → Set α} (hs : ∀ x : α, ∃ i, s i ∈ 𝓝 x) (hf : ∀ i, ContinuousOn f (s i)) : Continuous f := @@ -629,9 +587,66 @@ theorem Set.Subsingleton.continuousOn {s : Set α} (hs : s.Subsingleton) (f : α ContinuousOn f s := hs.induction_on (continuousOn_empty f) (continuousOn_singleton f) -theorem nhdsWithin_le_comap {x : α} {s : Set α} {f : α → β} (ctsf : ContinuousWithinAt f s x) : - 𝓝[s] x ≤ comap f (𝓝[f '' s] f x) := - ctsf.tendsto_nhdsWithin_image.le_comap +theorem continuousOn_open_iff {f : α → β} {s : Set α} (hs : IsOpen s) : + ContinuousOn f s ↔ ∀ t, IsOpen t → IsOpen (s ∩ f ⁻¹' t) := by + rw [continuousOn_iff'] + constructor + · intro h t ht + rcases h t ht with ⟨u, u_open, hu⟩ + rw [inter_comm, hu] + apply IsOpen.inter u_open hs + · intro h t ht + refine ⟨s ∩ f ⁻¹' t, h t ht, ?_⟩ + rw [@inter_comm _ s (f ⁻¹' t), inter_assoc, inter_self] + +theorem ContinuousOn.isOpen_inter_preimage {f : α → β} {s : Set α} {t : Set β} + (hf : ContinuousOn f s) (hs : IsOpen s) (ht : IsOpen t) : IsOpen (s ∩ f ⁻¹' t) := + (continuousOn_open_iff hs).1 hf t ht + +theorem ContinuousOn.isOpen_preimage {f : α → β} {s : Set α} {t : Set β} (h : ContinuousOn f s) + (hs : IsOpen s) (hp : f ⁻¹' t ⊆ s) (ht : IsOpen t) : IsOpen (f ⁻¹' t) := by + convert (continuousOn_open_iff hs).mp h t ht + rw [inter_comm, inter_eq_self_of_subset_left hp] + +theorem ContinuousOn.preimage_isClosed_of_isClosed {f : α → β} {s : Set α} {t : Set β} + (hf : ContinuousOn f s) (hs : IsClosed s) (ht : IsClosed t) : IsClosed (s ∩ f ⁻¹' t) := by + rcases continuousOn_iff_isClosed.1 hf t ht with ⟨u, hu⟩ + rw [inter_comm, hu.2] + apply IsClosed.inter hu.1 hs + +theorem ContinuousOn.preimage_interior_subset_interior_preimage {f : α → β} {s : Set α} {t : Set β} + (hf : ContinuousOn f s) (hs : IsOpen s) : s ∩ f ⁻¹' interior t ⊆ s ∩ interior (f ⁻¹' t) := + calc + s ∩ f ⁻¹' interior t ⊆ interior (s ∩ f ⁻¹' t) := + interior_maximal (inter_subset_inter (Subset.refl _) (preimage_mono interior_subset)) + (hf.isOpen_inter_preimage hs isOpen_interior) + _ = s ∩ interior (f ⁻¹' t) := by rw [interior_inter, hs.interior_eq] + +theorem continuousOn_of_locally_continuousOn {f : α → β} {s : Set α} + (h : ∀ x ∈ s, ∃ t, IsOpen t ∧ x ∈ t ∧ ContinuousOn f (s ∩ t)) : ContinuousOn f s := by + intro x xs + rcases h x xs with ⟨t, open_t, xt, ct⟩ + have := ct x ⟨xs, xt⟩ + rwa [ContinuousWithinAt, ← nhdsWithin_restrict _ xt open_t] at this + +theorem continuousOn_to_generateFrom_iff {β} {s : Set α} {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, + and_imp] + exact forall_congr' fun t => forall_swap + +-- Porting note: dropped an unneeded assumption +theorem continuousOn_isOpen_of_generateFrom {β : Type*} {s : Set α} {T : Set (Set β)} {f : α → β} + (h : ∀ t ∈ T, IsOpen (s ∩ f ⁻¹' t)) : + @ContinuousOn α β _ (.generateFrom T) f s := + continuousOn_to_generateFrom_iff.2 fun _x hx t ht hxt => mem_nhdsWithin.2 + ⟨_, h t ht, ⟨hx, hxt⟩, fun _y hy => hy.1.2⟩ + +/-! +### Congruence and monotonicity properties with respect to sets +-/ theorem ContinuousWithinAt.mono {f : α → β} {s t : Set α} {x : α} (h : ContinuousWithinAt f t x) (hs : s ⊆ t) : ContinuousWithinAt f s x := @@ -661,31 +676,6 @@ theorem ContinuousWithinAt.union {f : α → β} {s t : Set α} {x : α} (hs : C (ht : ContinuousWithinAt f t x) : ContinuousWithinAt f (s ∪ t) x := continuousWithinAt_union.2 ⟨hs, ht⟩ -theorem ContinuousWithinAt.mem_closure_image {f : α → β} {s : Set α} {x : α} - (h : ContinuousWithinAt f s x) (hx : x ∈ closure s) : f x ∈ closure (f '' s) := - haveI := mem_closure_iff_nhdsWithin_neBot.1 hx - mem_closure_of_tendsto h <| mem_of_superset self_mem_nhdsWithin (subset_preimage_image f s) - -theorem ContinuousWithinAt.mem_closure {f : α → β} {s : Set α} {x : α} {A : Set β} - (h : ContinuousWithinAt f s x) (hx : x ∈ closure s) (hA : MapsTo f s A) : f x ∈ closure A := - closure_mono (image_subset_iff.2 hA) (h.mem_closure_image hx) - -theorem Set.MapsTo.closure_of_continuousWithinAt {f : α → β} {s : Set α} {t : Set β} - (h : MapsTo f s t) (hc : ∀ x ∈ closure s, ContinuousWithinAt f s x) : - MapsTo f (closure s) (closure t) := fun x hx => (hc x hx).mem_closure hx h - -theorem Set.MapsTo.closure_of_continuousOn {f : α → β} {s : Set α} {t : Set β} (h : MapsTo f s t) - (hc : ContinuousOn f (closure s)) : MapsTo f (closure s) (closure t) := - h.closure_of_continuousWithinAt fun x hx => (hc x hx).mono subset_closure - -theorem ContinuousWithinAt.image_closure {f : α → β} {s : Set α} - (hf : ∀ x ∈ closure s, ContinuousWithinAt f s x) : f '' closure s ⊆ closure (f '' s) := - ((mapsTo_image f s).closure_of_continuousWithinAt hf).image_subset - -theorem ContinuousOn.image_closure {f : α → β} {s : Set α} (hf : ContinuousOn f (closure s)) : - f '' closure s ⊆ closure (f '' s) := - ContinuousWithinAt.image_closure fun x hx => (hf x hx).mono subset_closure - @[simp] theorem continuousWithinAt_singleton {f : α → β} {x : α} : ContinuousWithinAt f {x} x := by simp only [ContinuousWithinAt, nhdsWithin_singleton, tendsto_pure_nhds] @@ -712,50 +702,16 @@ theorem continuousWithinAt_compl_self {f : α → β} {a : α} : ContinuousWithinAt f {a}ᶜ a ↔ ContinuousAt f a := by rw [compl_eq_univ_diff, continuousWithinAt_diff_self, continuousWithinAt_univ] -@[simp] -theorem continuousWithinAt_update_same [DecidableEq α] {f : α → β} {s : Set α} {x : α} {y : β} : - ContinuousWithinAt (update f x y) s x ↔ Tendsto f (𝓝[s \ {x}] x) (𝓝 y) := - calc - ContinuousWithinAt (update f x y) s x ↔ Tendsto (update f x y) (𝓝[s \ {x}] x) (𝓝 y) := by - { rw [← continuousWithinAt_diff_self, ContinuousWithinAt, update_same] } - _ ↔ Tendsto f (𝓝[s \ {x}] x) (𝓝 y) := - tendsto_congr' <| eventually_nhdsWithin_iff.2 <| Eventually.of_forall - fun _ hz => update_noteq hz.2 _ _ - -@[simp] -theorem continuousAt_update_same [DecidableEq α] {f : α → β} {x : α} {y : β} : - ContinuousAt (Function.update f x y) x ↔ Tendsto f (𝓝[≠] x) (𝓝 y) := by - rw [← continuousWithinAt_univ, continuousWithinAt_update_same, compl_eq_univ_diff] - -theorem IsOpenMap.continuousOn_image_of_leftInvOn {f : α → β} {s : Set α} - (h : IsOpenMap (s.restrict 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] - exact h _ (ht.preimage continuous_subtype_val) - · rw [inter_eq_self_of_subset_left (image_subset f 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 +theorem ContinuousOn.mono {f : α → β} {s t : Set α} (hf : ContinuousOn f s) (h : t ⊆ s) : + ContinuousOn f t := fun x hx => (hf x (h hx)).mono_left (nhdsWithin_mono _ h) -theorem ContinuousOn.congr_mono {f g : α → β} {s s₁ : Set α} (h : ContinuousOn f s) - (h' : EqOn g f s₁) (h₁ : s₁ ⊆ s) : ContinuousOn g s₁ := by - intro x hx - unfold ContinuousWithinAt - have A := (h x (h₁ hx)).mono h₁ - unfold ContinuousWithinAt at A - rw [← h' hx] at A - exact A.congr' h'.eventuallyEq_nhdsWithin.symm +theorem antitone_continuousOn {f : α → β} : Antitone (ContinuousOn f) := fun _s _t hst hf => + hf.mono hst -theorem ContinuousOn.congr {f g : α → β} {s : Set α} (h : ContinuousOn f s) (h' : EqOn g f s) : - ContinuousOn g s := - h.congr_mono h' (Subset.refl _) -theorem continuousOn_congr {f g : α → β} {s : Set α} (h' : EqOn g f s) : - ContinuousOn g s ↔ ContinuousOn f s := - ⟨fun h => ContinuousOn.congr h h'.symm, fun h => h.congr h'⟩ +/-! +### Relation between `ContinuousAt` and `ContinuousWithinAt` +-/ theorem ContinuousAt.continuousWithinAt {f : α → β} {s : Set α} {x : α} (h : ContinuousAt f x) : ContinuousWithinAt f s x := @@ -780,7 +736,61 @@ theorem ContinuousOn.continuousAt {f : α → β} {s : Set α} {x : α} (h : Con theorem ContinuousAt.continuousOn {f : α → β} {s : Set α} (hcont : ∀ x ∈ s, ContinuousAt f x) : ContinuousOn f s := fun x hx => (hcont x hx).continuousWithinAt -theorem ContinuousWithinAt.comp {g : β → γ} {f : α → β} {s : Set α} {t : Set β} {x : α} +@[fun_prop] +theorem Continuous.continuousOn {f : α → β} {s : Set α} (h : Continuous f) : ContinuousOn f s := by + rw [continuous_iff_continuousOn_univ] at h + exact h.mono (subset_univ _) + +theorem Continuous.continuousWithinAt {f : α → β} {s : Set α} {x : α} (h : Continuous f) : + ContinuousWithinAt f s x := + h.continuousAt.continuousWithinAt + + +/-! +### Congruence properties with respect to functions +-/ + +theorem ContinuousOn.congr_mono {f g : α → β} {s s₁ : Set α} (h : ContinuousOn f s) + (h' : EqOn g f s₁) (h₁ : s₁ ⊆ s) : ContinuousOn g s₁ := by + intro x hx + unfold ContinuousWithinAt + have A := (h x (h₁ hx)).mono h₁ + unfold ContinuousWithinAt at A + rw [← h' hx] at A + exact A.congr' h'.eventuallyEq_nhdsWithin.symm + +theorem ContinuousOn.congr {f g : α → β} {s : Set α} (h : ContinuousOn f s) (h' : EqOn g f s) : + ContinuousOn g s := + h.congr_mono h' (Subset.refl _) + +theorem continuousOn_congr {f g : α → β} {s : Set α} (h' : EqOn g f s) : + ContinuousOn g s ↔ ContinuousOn f s := + ⟨fun h => ContinuousOn.congr h h'.symm, fun h => h.congr h'⟩ + +theorem Filter.EventuallyEq.congr_continuousWithinAt {f g : α → β} {s : Set α} {x : α} + (h : f =ᶠ[𝓝[s] x] g) (hx : f x = g x) : + ContinuousWithinAt f s x ↔ ContinuousWithinAt g s x := by + rw [ContinuousWithinAt, hx, tendsto_congr' h, ContinuousWithinAt] + +theorem ContinuousWithinAt.congr_of_eventuallyEq {f f₁ : α → β} {s : Set α} {x : α} + (h : ContinuousWithinAt f s x) (h₁ : f₁ =ᶠ[𝓝[s] x] f) (hx : f₁ x = f x) : + ContinuousWithinAt f₁ s x := + (h₁.congr_continuousWithinAt hx).2 h + +theorem ContinuousWithinAt.congr {f f₁ : α → β} {s : Set α} {x : α} (h : ContinuousWithinAt f s x) + (h₁ : ∀ y ∈ s, f₁ y = f y) (hx : f₁ x = f x) : ContinuousWithinAt f₁ s x := + h.congr_of_eventuallyEq (mem_of_superset self_mem_nhdsWithin h₁) hx + +theorem ContinuousWithinAt.congr_mono {f g : α → β} {s s₁ : Set α} {x : α} + (h : ContinuousWithinAt f s x) (h' : EqOn g f s₁) (h₁ : s₁ ⊆ s) (hx : g x = f x) : + ContinuousWithinAt g s₁ x := + (h.mono h₁).congr h' hx + +/-! +### Composition +-/ + +theorem ContinuousWithinAt.comp {g : β → γ} {f : α → β} {s : Set α} {t : Set β} {x : α} (hg : ContinuousWithinAt g t (f x)) (hf : ContinuousWithinAt f s x) (h : MapsTo f s t) : ContinuousWithinAt (g ∘ f) s x := hg.tendsto.comp (hf.tendsto_nhdsWithin h) @@ -803,26 +813,11 @@ theorem ContinuousOn.comp'' {g : β → γ} {f : α → β} {s : Set α} {t : Se (hf : ContinuousOn f s) (h : Set.MapsTo f s t) : ContinuousOn (fun x => g (f x)) s := ContinuousOn.comp hg hf h -theorem ContinuousOn.mono {f : α → β} {s t : Set α} (hf : ContinuousOn f s) (h : t ⊆ s) : - ContinuousOn f t := fun x hx => (hf x (h hx)).mono_left (nhdsWithin_mono _ h) - -theorem antitone_continuousOn {f : α → β} : Antitone (ContinuousOn f) := fun _s _t hst hf => - hf.mono hst - @[fun_prop] theorem ContinuousOn.comp' {g : β → γ} {f : α → β} {s : Set α} {t : Set β} (hg : ContinuousOn g t) (hf : ContinuousOn f s) : ContinuousOn (g ∘ f) (s ∩ f ⁻¹' t) := hg.comp (hf.mono inter_subset_left) inter_subset_right -@[fun_prop] -theorem Continuous.continuousOn {f : α → β} {s : Set α} (h : Continuous f) : ContinuousOn f s := by - rw [continuous_iff_continuousOn_univ] at h - exact h.mono (subset_univ _) - -theorem Continuous.continuousWithinAt {f : α → β} {s : Set α} {x : α} (h : Continuous f) : - ContinuousWithinAt f s x := - h.continuousAt.continuousWithinAt - theorem Continuous.comp_continuousOn {g : β → γ} {f : α → β} {s : Set α} (hg : Continuous g) (hf : ContinuousOn f s) : ContinuousOn (g ∘ f) s := hg.continuousOn.comp hf (mapsTo_univ _ _) @@ -839,60 +834,185 @@ theorem ContinuousOn.comp_continuous {g : β → γ} {f : α → β} {s : Set β rw [continuous_iff_continuousOn_univ] at * exact hg.comp hf fun x _ => hs x +theorem ContinuousAt.comp₂_continuousWithinAt {f : β × γ → δ} {g : α → β} {h : α → γ} {x : α} + {s : Set α} (hf : ContinuousAt f (g x, h x)) (hg : ContinuousWithinAt g s x) + (hh : ContinuousWithinAt h s x) : + ContinuousWithinAt (fun x ↦ f (g x, h x)) s x := + ContinuousAt.comp_continuousWithinAt hf (hg.prod_mk_nhds hh) + +theorem ContinuousAt.comp₂_continuousWithinAt_of_eq {f : β × γ → δ} {g : α → β} + {h : α → γ} {x : α} {s : Set α} {y : β × γ} (hf : ContinuousAt f y) + (hg : ContinuousWithinAt g s x) (hh : ContinuousWithinAt h s x) (e : (g x, h x) = y) : + ContinuousWithinAt (fun x ↦ f (g x, h x)) s x := by + rw [← e] at hf + exact hf.comp₂_continuousWithinAt hg hh + + +/-! +### Image +-/ + +theorem ContinuousWithinAt.mem_closure_image {f : α → β} {s : Set α} {x : α} + (h : ContinuousWithinAt f s x) (hx : x ∈ closure s) : f x ∈ closure (f '' s) := + haveI := mem_closure_iff_nhdsWithin_neBot.1 hx + mem_closure_of_tendsto h <| mem_of_superset self_mem_nhdsWithin (subset_preimage_image f s) + +theorem ContinuousWithinAt.mem_closure {f : α → β} {s : Set α} {x : α} {A : Set β} + (h : ContinuousWithinAt f s x) (hx : x ∈ closure s) (hA : MapsTo f s A) : f x ∈ closure A := + closure_mono (image_subset_iff.2 hA) (h.mem_closure_image hx) + +theorem Set.MapsTo.closure_of_continuousWithinAt {f : α → β} {s : Set α} {t : Set β} + (h : MapsTo f s t) (hc : ∀ x ∈ closure s, ContinuousWithinAt f s x) : + MapsTo f (closure s) (closure t) := fun x hx => (hc x hx).mem_closure hx h + +theorem Set.MapsTo.closure_of_continuousOn {f : α → β} {s : Set α} {t : Set β} (h : MapsTo f s t) + (hc : ContinuousOn f (closure s)) : MapsTo f (closure s) (closure t) := + h.closure_of_continuousWithinAt fun x hx => (hc x hx).mono subset_closure + +theorem ContinuousWithinAt.image_closure {f : α → β} {s : Set α} + (hf : ∀ x ∈ closure s, ContinuousWithinAt f s x) : f '' closure s ⊆ closure (f '' s) := + ((mapsTo_image f s).closure_of_continuousWithinAt hf).image_subset + +theorem ContinuousOn.image_closure {f : α → β} {s : Set α} (hf : ContinuousOn f (closure s)) : + f '' closure s ⊆ closure (f '' s) := + ContinuousWithinAt.image_closure fun x hx => (hf x hx).mono subset_closure + +/-! +### Product +-/ + +theorem ContinuousWithinAt.prod_map {f : α → γ} {g : β → δ} {s : Set α} {t : Set β} {x : α} {y : β} + (hf : ContinuousWithinAt f s x) (hg : ContinuousWithinAt g t y) : + ContinuousWithinAt (Prod.map f g) (s ×ˢ t) (x, y) := by + unfold ContinuousWithinAt at * + rw [nhdsWithin_prod_eq, Prod.map, nhds_prod_eq] + exact hf.prod_map hg + +theorem continuousWithinAt_prod_of_discrete_left [DiscreteTopology α] + {f : α × β → γ} {s : Set (α × β)} {x : α × β} : + ContinuousWithinAt f s x ↔ ContinuousWithinAt (f ⟨x.1, ·⟩) {b | (x.1, b) ∈ s} x.2 := by + rw [← x.eta]; simp_rw [ContinuousWithinAt, nhdsWithin, nhds_prod_eq, nhds_discrete, pure_prod, + ← map_inf_principal_preimage]; rfl + +theorem continuousWithinAt_prod_of_discrete_right [DiscreteTopology β] + {f : α × β → γ} {s : Set (α × β)} {x : α × β} : + ContinuousWithinAt f s x ↔ ContinuousWithinAt (f ⟨·, x.2⟩) {a | (a, x.2) ∈ s} x.1 := by + rw [← x.eta]; simp_rw [ContinuousWithinAt, nhdsWithin, nhds_prod_eq, nhds_discrete, prod_pure, + ← map_inf_principal_preimage]; rfl + +theorem continuousAt_prod_of_discrete_left [DiscreteTopology α] {f : α × β → γ} {x : α × β} : + ContinuousAt f x ↔ ContinuousAt (f ⟨x.1, ·⟩) x.2 := by + simp_rw [← continuousWithinAt_univ]; exact continuousWithinAt_prod_of_discrete_left + +theorem continuousAt_prod_of_discrete_right [DiscreteTopology β] {f : α × β → γ} {x : α × β} : + ContinuousAt f x ↔ ContinuousAt (f ⟨·, x.2⟩) x.1 := by + simp_rw [← continuousWithinAt_univ]; exact continuousWithinAt_prod_of_discrete_right + +theorem continuousOn_prod_of_discrete_left [DiscreteTopology α] {f : α × β → γ} {s : Set (α × β)} : + ContinuousOn f s ↔ ∀ a, ContinuousOn (f ⟨a, ·⟩) {b | (a, b) ∈ s} := by + simp_rw [ContinuousOn, Prod.forall, continuousWithinAt_prod_of_discrete_left]; rfl + +theorem continuousOn_prod_of_discrete_right [DiscreteTopology β] {f : α × β → γ} {s : Set (α × β)} : + ContinuousOn f s ↔ ∀ b, ContinuousOn (f ⟨·, b⟩) {a | (a, b) ∈ s} := by + simp_rw [ContinuousOn, Prod.forall, continuousWithinAt_prod_of_discrete_right]; apply forall_swap + +/-- If a function `f a b` is such that `y ↦ f a b` is continuous for all `a`, and `a` lives in a +discrete space, then `f` is continuous, and vice versa. -/ +theorem continuous_prod_of_discrete_left [DiscreteTopology α] {f : α × β → γ} : + Continuous f ↔ ∀ a, Continuous (f ⟨a, ·⟩) := by + simp_rw [continuous_iff_continuousOn_univ]; exact continuousOn_prod_of_discrete_left + +theorem continuous_prod_of_discrete_right [DiscreteTopology β] {f : α × β → γ} : + Continuous f ↔ ∀ b, Continuous (f ⟨·, b⟩) := by + simp_rw [continuous_iff_continuousOn_univ]; exact continuousOn_prod_of_discrete_right + +theorem isOpenMap_prod_of_discrete_left [DiscreteTopology α] {f : α × β → γ} : + IsOpenMap f ↔ ∀ a, IsOpenMap (f ⟨a, ·⟩) := by + simp_rw [isOpenMap_iff_nhds_le, Prod.forall, nhds_prod_eq, nhds_discrete, pure_prod, map_map] + rfl + +theorem isOpenMap_prod_of_discrete_right [DiscreteTopology β] {f : α × β → γ} : + IsOpenMap f ↔ ∀ b, IsOpenMap (f ⟨·, b⟩) := by + simp_rw [isOpenMap_iff_nhds_le, Prod.forall, forall_swap (α := α) (β := β), nhds_prod_eq, + nhds_discrete, prod_pure, map_map]; rfl + +theorem ContinuousOn.prod_map {f : α → γ} {g : β → δ} {s : Set α} {t : Set β} + (hf : ContinuousOn f s) (hg : ContinuousOn g t) : ContinuousOn (Prod.map f g) (s ×ˢ t) := + fun ⟨x, y⟩ ⟨hx, hy⟩ => ContinuousWithinAt.prod_map (hf x hx) (hg y hy) + +theorem ContinuousWithinAt.prod {f : α → β} {g : α → γ} {s : Set α} {x : α} + (hf : ContinuousWithinAt f s x) (hg : ContinuousWithinAt g s x) : + ContinuousWithinAt (fun x => (f x, g x)) s x := + hf.prod_mk_nhds hg + @[fun_prop] -theorem continuousOn_apply {ι : Type*} {π : ι → Type*} [∀ i, TopologicalSpace (π i)] - (i : ι) (s) : ContinuousOn (fun p : ∀ i, π i => p i) s := - Continuous.continuousOn (continuous_apply i) +theorem ContinuousOn.prod {f : α → β} {g : α → γ} {s : Set α} (hf : ContinuousOn f s) + (hg : ContinuousOn g s) : ContinuousOn (fun x => (f x, g x)) s := fun x hx => + ContinuousWithinAt.prod (hf x hx) (hg x hx) -theorem ContinuousWithinAt.preimage_mem_nhdsWithin {f : α → β} {x : α} {s : Set α} {t : Set β} - (h : ContinuousWithinAt f s x) (ht : t ∈ 𝓝 (f x)) : f ⁻¹' t ∈ 𝓝[s] x := - h ht +theorem continuousOn_fst {s : Set (α × β)} : ContinuousOn Prod.fst s := + continuous_fst.continuousOn -theorem Set.LeftInvOn.map_nhdsWithin_eq {f : α → β} {g : β → α} {x : β} {s : Set β} - (h : LeftInvOn f g s) (hx : f (g x) = x) (hf : ContinuousWithinAt f (g '' s) (g x)) - (hg : ContinuousWithinAt g s x) : map g (𝓝[s] x) = 𝓝[g '' s] g x := by - apply le_antisymm - · exact hg.tendsto_nhdsWithin (mapsTo_image _ _) - · have A : g ∘ f =ᶠ[𝓝[g '' s] g x] id := - h.rightInvOn_image.eqOn.eventuallyEq_of_mem self_mem_nhdsWithin - refine le_map_of_right_inverse A ?_ - simpa only [hx] using hf.tendsto_nhdsWithin (h.mapsTo (surjOn_image _ _)) +theorem continuousWithinAt_fst {s : Set (α × β)} {p : α × β} : ContinuousWithinAt Prod.fst s p := + continuous_fst.continuousWithinAt -theorem Function.LeftInverse.map_nhds_eq {f : α → β} {g : β → α} {x : β} - (h : Function.LeftInverse f g) (hf : ContinuousWithinAt f (range g) (g x)) - (hg : ContinuousAt g x) : map g (𝓝 x) = 𝓝[range g] g x := by - simpa only [nhdsWithin_univ, image_univ] using - (h.leftInvOn univ).map_nhdsWithin_eq (h x) (by rwa [image_univ]) hg.continuousWithinAt +@[fun_prop] +theorem ContinuousOn.fst {f : α → β × γ} {s : Set α} (hf : ContinuousOn f s) : + ContinuousOn (fun x => (f x).1) s := + continuous_fst.comp_continuousOn hf -theorem ContinuousWithinAt.preimage_mem_nhdsWithin' {f : α → β} {x : α} {s : Set α} {t : Set β} - (h : ContinuousWithinAt f s x) (ht : t ∈ 𝓝[f '' s] f x) : f ⁻¹' t ∈ 𝓝[s] x := - h.tendsto_nhdsWithin (mapsTo_image _ _) ht +theorem ContinuousWithinAt.fst {f : α → β × γ} {s : Set α} {a : α} (h : ContinuousWithinAt f s a) : + ContinuousWithinAt (fun x => (f x).fst) s a := + continuousAt_fst.comp_continuousWithinAt h -theorem ContinuousWithinAt.preimage_mem_nhdsWithin'' - {f : α → β} {x : α} {y : β} {s t : Set β} - (h : ContinuousWithinAt f (f ⁻¹' s) x) (ht : t ∈ 𝓝[s] y) (hxy : y = f x) : - f ⁻¹' t ∈ 𝓝[f ⁻¹' s] x := by - rw [hxy] at ht - exact h.preimage_mem_nhdsWithin' (nhdsWithin_mono _ (image_preimage_subset f s) ht) +theorem continuousOn_snd {s : Set (α × β)} : ContinuousOn Prod.snd s := + continuous_snd.continuousOn -theorem Filter.EventuallyEq.congr_continuousWithinAt {f g : α → β} {s : Set α} {x : α} - (h : f =ᶠ[𝓝[s] x] g) (hx : f x = g x) : - ContinuousWithinAt f s x ↔ ContinuousWithinAt g s x := by - rw [ContinuousWithinAt, hx, tendsto_congr' h, ContinuousWithinAt] +theorem continuousWithinAt_snd {s : Set (α × β)} {p : α × β} : ContinuousWithinAt Prod.snd s p := + continuous_snd.continuousWithinAt -theorem ContinuousWithinAt.congr_of_eventuallyEq {f f₁ : α → β} {s : Set α} {x : α} - (h : ContinuousWithinAt f s x) (h₁ : f₁ =ᶠ[𝓝[s] x] f) (hx : f₁ x = f x) : - ContinuousWithinAt f₁ s x := - (h₁.congr_continuousWithinAt hx).2 h +@[fun_prop] +theorem ContinuousOn.snd {f : α → β × γ} {s : Set α} (hf : ContinuousOn f s) : + ContinuousOn (fun x => (f x).2) s := + continuous_snd.comp_continuousOn hf -theorem ContinuousWithinAt.congr {f f₁ : α → β} {s : Set α} {x : α} (h : ContinuousWithinAt f s x) - (h₁ : ∀ y ∈ s, f₁ y = f y) (hx : f₁ x = f x) : ContinuousWithinAt f₁ s x := - h.congr_of_eventuallyEq (mem_of_superset self_mem_nhdsWithin h₁) hx +theorem ContinuousWithinAt.snd {f : α → β × γ} {s : Set α} {a : α} (h : ContinuousWithinAt f s a) : + ContinuousWithinAt (fun x => (f x).snd) s a := + continuousAt_snd.comp_continuousWithinAt h -theorem ContinuousWithinAt.congr_mono {f g : α → β} {s s₁ : Set α} {x : α} - (h : ContinuousWithinAt f s x) (h' : EqOn g f s₁) (h₁ : s₁ ⊆ s) (hx : g x = f x) : - ContinuousWithinAt g s₁ x := - (h.mono h₁).congr h' hx +theorem continuousWithinAt_prod_iff {f : α → β × γ} {s : Set α} {x : α} : + ContinuousWithinAt f s x ↔ + ContinuousWithinAt (Prod.fst ∘ f) s x ∧ ContinuousWithinAt (Prod.snd ∘ f) s x := + ⟨fun h => ⟨h.fst, h.snd⟩, fun ⟨h1, h2⟩ => h1.prod h2⟩ + +/-! +### Pi +-/ + +theorem continuousWithinAt_pi {ι : Type*} {π : ι → Type*} [∀ i, TopologicalSpace (π i)] + {f : α → ∀ i, π i} {s : Set α} {x : α} : + ContinuousWithinAt f s x ↔ ∀ i, ContinuousWithinAt (fun y => f y i) s x := + tendsto_pi_nhds + +theorem continuousOn_pi {ι : Type*} {π : ι → Type*} [∀ i, TopologicalSpace (π i)] + {f : α → ∀ i, π i} {s : Set α} : ContinuousOn f s ↔ ∀ i, ContinuousOn (fun y => f y i) s := + ⟨fun h i x hx => tendsto_pi_nhds.1 (h x hx) i, fun h x hx => tendsto_pi_nhds.2 fun i => h i x hx⟩ + +@[fun_prop] +theorem continuousOn_pi' {ι : Type*} {π : ι → Type*} [∀ i, TopologicalSpace (π i)] + {f : α → ∀ i, π i} {s : Set α} (hf : ∀ i, ContinuousOn (fun y => f y i) s) : + ContinuousOn f s := + continuousOn_pi.2 hf + +@[fun_prop] +theorem continuousOn_apply {ι : Type*} {π : ι → Type*} [∀ i, TopologicalSpace (π i)] + (i : ι) (s) : ContinuousOn (fun p : ∀ i, π i => p i) s := + Continuous.continuousOn (continuous_apply i) + + +/-! +### Specific functions +-/ @[fun_prop] theorem continuousOn_const {s : Set α} {c : β} : ContinuousOn (fun _ => c) s := @@ -916,85 +1036,33 @@ protected theorem ContinuousOn.iterate {f : α → α} {s : Set α} (hcont : Con | 0 => continuousOn_id | (n + 1) => (hcont.iterate hmaps n).comp hcont hmaps -theorem continuousOn_open_iff {f : α → β} {s : Set α} (hs : IsOpen s) : - ContinuousOn f s ↔ ∀ t, IsOpen t → IsOpen (s ∩ f ⁻¹' t) := by - rw [continuousOn_iff'] - constructor - · intro h t ht - rcases h t ht with ⟨u, u_open, hu⟩ - rw [inter_comm, hu] - apply IsOpen.inter u_open hs - · intro h t ht - refine ⟨s ∩ f ⁻¹' t, h t ht, ?_⟩ - rw [@inter_comm _ s (f ⁻¹' t), inter_assoc, inter_self] - -theorem ContinuousOn.isOpen_inter_preimage {f : α → β} {s : Set α} {t : Set β} - (hf : ContinuousOn f s) (hs : IsOpen s) (ht : IsOpen t) : IsOpen (s ∩ f ⁻¹' t) := - (continuousOn_open_iff hs).1 hf t ht - -theorem ContinuousOn.isOpen_preimage {f : α → β} {s : Set α} {t : Set β} (h : ContinuousOn f s) - (hs : IsOpen s) (hp : f ⁻¹' t ⊆ s) (ht : IsOpen t) : IsOpen (f ⁻¹' t) := by - convert (continuousOn_open_iff hs).mp h t ht - rw [inter_comm, inter_eq_self_of_subset_left hp] - -theorem ContinuousOn.preimage_isClosed_of_isClosed {f : α → β} {s : Set α} {t : Set β} - (hf : ContinuousOn f s) (hs : IsClosed s) (ht : IsClosed t) : IsClosed (s ∩ f ⁻¹' t) := by - rcases continuousOn_iff_isClosed.1 hf t ht with ⟨u, hu⟩ - rw [inter_comm, hu.2] - apply IsClosed.inter hu.1 hs - -theorem ContinuousOn.preimage_interior_subset_interior_preimage {f : α → β} {s : Set α} {t : Set β} - (hf : ContinuousOn f s) (hs : IsOpen s) : s ∩ f ⁻¹' interior t ⊆ s ∩ interior (f ⁻¹' t) := - calc - s ∩ f ⁻¹' interior t ⊆ interior (s ∩ f ⁻¹' t) := - interior_maximal (inter_subset_inter (Subset.refl _) (preimage_mono interior_subset)) - (hf.isOpen_inter_preimage hs isOpen_interior) - _ = s ∩ interior (f ⁻¹' t) := by rw [interior_inter, hs.interior_eq] - -theorem continuousOn_of_locally_continuousOn {f : α → β} {s : Set α} - (h : ∀ x ∈ s, ∃ t, IsOpen t ∧ x ∈ t ∧ ContinuousOn f (s ∩ t)) : ContinuousOn f s := by - intro x xs - rcases h x xs with ⟨t, open_t, xt, ct⟩ - have := ct x ⟨xs, xt⟩ - rwa [ContinuousWithinAt, ← nhdsWithin_restrict _ xt open_t] at this - -theorem continuousOn_to_generateFrom_iff {β} {s : Set α} {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, - and_imp] - exact forall_congr' fun t => forall_swap - --- Porting note: dropped an unneeded assumption -theorem continuousOn_isOpen_of_generateFrom {β : Type*} {s : Set α} {T : Set (Set β)} {f : α → β} - (h : ∀ t ∈ T, IsOpen (s ∩ f ⁻¹' t)) : - @ContinuousOn α β _ (.generateFrom T) f s := - continuousOn_to_generateFrom_iff.2 fun _x hx t ht hxt => mem_nhdsWithin.2 - ⟨_, h t ht, ⟨hx, hxt⟩, fun _y hy => hy.1.2⟩ - -theorem ContinuousWithinAt.prod {f : α → β} {g : α → γ} {s : Set α} {x : α} - (hf : ContinuousWithinAt f s x) (hg : ContinuousWithinAt g s x) : - ContinuousWithinAt (fun x => (f x, g x)) s x := - hf.prod_mk_nhds hg +theorem ContinuousWithinAt.fin_insertNth {n} {π : Fin (n + 1) → Type*} + [∀ i, TopologicalSpace (π i)] (i : Fin (n + 1)) {f : α → π i} {a : α} {s : Set α} + (hf : ContinuousWithinAt f s a) {g : α → ∀ j : Fin n, π (i.succAbove j)} + (hg : ContinuousWithinAt g s a) : ContinuousWithinAt (fun a => i.insertNth (f a) (g a)) s a := + hf.tendsto.fin_insertNth i hg -@[fun_prop] -theorem ContinuousOn.prod {f : α → β} {g : α → γ} {s : Set α} (hf : ContinuousOn f s) - (hg : ContinuousOn g s) : ContinuousOn (fun x => (f x, g x)) s := fun x hx => - ContinuousWithinAt.prod (hf x hx) (hg x hx) +nonrec theorem ContinuousOn.fin_insertNth {n} {π : Fin (n + 1) → Type*} + [∀ i, TopologicalSpace (π i)] (i : Fin (n + 1)) {f : α → π i} {s : Set α} + (hf : ContinuousOn f s) {g : α → ∀ j : Fin n, π (i.succAbove j)} (hg : ContinuousOn g s) : + ContinuousOn (fun a => i.insertNth (f a) (g a)) s := fun a ha => + (hf a ha).fin_insertNth i (hg a ha) -theorem ContinuousAt.comp₂_continuousWithinAt {f : β × γ → δ} {g : α → β} {h : α → γ} {x : α} - {s : Set α} (hf : ContinuousAt f (g x, h x)) (hg : ContinuousWithinAt g s x) - (hh : ContinuousWithinAt h s x) : - ContinuousWithinAt (fun x ↦ f (g x, h x)) s x := - ContinuousAt.comp_continuousWithinAt hf (hg.prod hh) +theorem Set.LeftInvOn.map_nhdsWithin_eq {f : α → β} {g : β → α} {x : β} {s : Set β} + (h : LeftInvOn f g s) (hx : f (g x) = x) (hf : ContinuousWithinAt f (g '' s) (g x)) + (hg : ContinuousWithinAt g s x) : map g (𝓝[s] x) = 𝓝[g '' s] g x := by + apply le_antisymm + · exact hg.tendsto_nhdsWithin (mapsTo_image _ _) + · have A : g ∘ f =ᶠ[𝓝[g '' s] g x] id := + h.rightInvOn_image.eqOn.eventuallyEq_of_mem self_mem_nhdsWithin + refine le_map_of_right_inverse A ?_ + simpa only [hx] using hf.tendsto_nhdsWithin (h.mapsTo (surjOn_image _ _)) -theorem ContinuousAt.comp₂_continuousWithinAt_of_eq {f : β × γ → δ} {g : α → β} - {h : α → γ} {x : α} {s : Set α} {y : β × γ} (hf : ContinuousAt f y) - (hg : ContinuousWithinAt g s x) (hh : ContinuousWithinAt h s x) (e : (g x, h x) = y) : - ContinuousWithinAt (fun x ↦ f (g x, h x)) s x := by - rw [← e] at hf - exact hf.comp₂_continuousWithinAt hg hh +theorem Function.LeftInverse.map_nhds_eq {f : α → β} {g : β → α} {x : β} + (h : Function.LeftInverse f g) (hf : ContinuousWithinAt f (range g) (g x)) + (hg : ContinuousAt g x) : map g (𝓝 x) = 𝓝[range g] g x := by + simpa only [nhdsWithin_univ, image_univ] using + (h.leftInvOn univ).map_nhdsWithin_eq (h x) (by rwa [image_univ]) hg.continuousWithinAt theorem Inducing.continuousWithinAt_iff {f : α → β} {g : β → γ} (hg : Inducing g) {s : Set α} {x : α} : ContinuousWithinAt f s x ↔ ContinuousWithinAt (g ∘ f) s x := by @@ -1024,11 +1092,37 @@ theorem QuotientMap.continuousOn_isOpen_iff {f : α → β} {g : β → γ} (h : simp only [continuousOn_iff_continuous_restrict, (h.restrictPreimage_isOpen hs).continuous_iff] rfl -theorem continuousWithinAt_of_not_mem_closure {f : α → β} {s : Set α} {x : α} (hx : x ∉ closure s) : - ContinuousWithinAt f s x := by - rw [mem_closure_iff_nhdsWithin_neBot, not_neBot] at hx - rw [ContinuousWithinAt, hx] - exact tendsto_bot +theorem IsOpenMap.continuousOn_image_of_leftInvOn {f : α → β} {s : Set α} + (h : IsOpenMap (s.restrict 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] + exact h _ (ht.preimage continuous_subtype_val) + · rw [inter_eq_self_of_subset_left (image_subset f 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 + +/-! +### Continuity of piecewise defined functions +-/ + +@[simp] +theorem continuousWithinAt_update_same [DecidableEq α] {f : α → β} {s : Set α} {x : α} {y : β} : + ContinuousWithinAt (update f x y) s x ↔ Tendsto f (𝓝[s \ {x}] x) (𝓝 y) := + calc + ContinuousWithinAt (update f x y) s x ↔ Tendsto (update f x y) (𝓝[s \ {x}] x) (𝓝 y) := by + { rw [← continuousWithinAt_diff_self, ContinuousWithinAt, update_same] } + _ ↔ Tendsto f (𝓝[s \ {x}] x) (𝓝 y) := + tendsto_congr' <| eventually_nhdsWithin_iff.2 <| Eventually.of_forall + fun _ hz => update_noteq hz.2 _ _ + +@[simp] +theorem continuousAt_update_same [DecidableEq α] {f : α → β} {x : α} {y : β} : + ContinuousAt (Function.update f x y) x ↔ Tendsto f (𝓝[≠] x) (𝓝 y) := by + rw [← continuousWithinAt_univ, continuousWithinAt_update_same, compl_eq_univ_diff] theorem ContinuousOn.if' {s : Set α} {p : α → Prop} {f g : α → β} [∀ a, Decidable (p a)] (hpf : ∀ a ∈ s ∩ frontier { a | p a }, @@ -1177,48 +1271,4 @@ theorem continuousOn_piecewise_ite' {s s' t : Set α} {f f' : α → β} [∀ x, theorem continuousOn_piecewise_ite {s s' t : Set α} {f f' : α → β} [∀ x, Decidable (x ∈ t)] (h : ContinuousOn f s) (h' : ContinuousOn f' s') (H : s ∩ frontier t = s' ∩ frontier t) (Heq : EqOn f f' (s ∩ frontier t)) : ContinuousOn (t.piecewise f f') (t.ite s s') := - continuousOn_piecewise_ite' (h.mono inter_subset_left) (h'.mono inter_subset_left) H - Heq - -theorem frontier_inter_open_inter {s t : Set α} (ht : IsOpen t) : - frontier (s ∩ t) ∩ t = frontier s ∩ t := by - simp only [Set.inter_comm _ t, ← Subtype.preimage_coe_eq_preimage_coe_iff, - ht.isOpenMap_subtype_val.preimage_frontier_eq_frontier_preimage continuous_subtype_val, - Subtype.preimage_coe_self_inter] - -theorem continuousOn_fst {s : Set (α × β)} : ContinuousOn Prod.fst s := - continuous_fst.continuousOn - -theorem continuousWithinAt_fst {s : Set (α × β)} {p : α × β} : ContinuousWithinAt Prod.fst s p := - continuous_fst.continuousWithinAt - -@[fun_prop] -theorem ContinuousOn.fst {f : α → β × γ} {s : Set α} (hf : ContinuousOn f s) : - ContinuousOn (fun x => (f x).1) s := - continuous_fst.comp_continuousOn hf - -theorem ContinuousWithinAt.fst {f : α → β × γ} {s : Set α} {a : α} (h : ContinuousWithinAt f s a) : - ContinuousWithinAt (fun x => (f x).fst) s a := - continuousAt_fst.comp_continuousWithinAt h - -theorem continuousOn_snd {s : Set (α × β)} : ContinuousOn Prod.snd s := - continuous_snd.continuousOn - -theorem continuousWithinAt_snd {s : Set (α × β)} {p : α × β} : ContinuousWithinAt Prod.snd s p := - continuous_snd.continuousWithinAt - -@[fun_prop] -theorem ContinuousOn.snd {f : α → β × γ} {s : Set α} (hf : ContinuousOn f s) : - ContinuousOn (fun x => (f x).2) s := - continuous_snd.comp_continuousOn hf - -theorem ContinuousWithinAt.snd {f : α → β × γ} {s : Set α} {a : α} (h : ContinuousWithinAt f s a) : - ContinuousWithinAt (fun x => (f x).snd) s a := - continuousAt_snd.comp_continuousWithinAt h - -theorem continuousWithinAt_prod_iff {f : α → β × γ} {s : Set α} {x : α} : - ContinuousWithinAt f s x ↔ - ContinuousWithinAt (Prod.fst ∘ f) s x ∧ ContinuousWithinAt (Prod.snd ∘ f) s x := - ⟨fun h => ⟨h.fst, h.snd⟩, fun ⟨h1, h2⟩ => h1.prod h2⟩ - -end Pi + continuousOn_piecewise_ite' (h.mono inter_subset_left) (h'.mono inter_subset_left) H Heq From 6c837c78f211be4560cf2b63adb5347e9854b808 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Fri, 18 Oct 2024 12:42:54 +0000 Subject: [PATCH 377/425] chore: delete >1year old deprecations (#17903) --- Mathlib/Algebra/BigOperators/Group/List.lean | 1 - Mathlib/Topology/Algebra/Module/Basic.lean | 5 ----- Mathlib/Topology/Separation.lean | 5 ----- Mathlib/Topology/UniformSpace/CompactConvergence.lean | 5 ----- 4 files changed, 16 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Group/List.lean b/Mathlib/Algebra/BigOperators/Group/List.lean index 42ca241b7d835a..c61a25c867599e 100644 --- a/Mathlib/Algebra/BigOperators/Group/List.lean +++ b/Mathlib/Algebra/BigOperators/Group/List.lean @@ -626,7 +626,6 @@ namespace MonoidHom protected theorem map_list_prod (f : M →* N) (l : List M) : f l.prod = (l.map f).prod := map_list_prod f l -attribute [deprecated map_list_prod (since := "2023-01-10")] MonoidHom.map_list_prod attribute [deprecated map_list_sum (since := "2024-05-02")] AddMonoidHom.map_list_sum end MonoidHom diff --git a/Mathlib/Topology/Algebra/Module/Basic.lean b/Mathlib/Topology/Algebra/Module/Basic.lean index 637ef9b981a96d..4296c9b9179992 100644 --- a/Mathlib/Topology/Algebra/Module/Basic.lean +++ b/Mathlib/Topology/Algebra/Module/Basic.lean @@ -450,11 +450,6 @@ theorem map_smul_of_tower {R S : Type*} [Semiring S] [SMul R M₁] [Module S M f (c • x) = c • f x := LinearMap.CompatibleSMul.map_smul (f : M₁ →ₗ[S] M₂) c x -@[deprecated _root_.map_sum (since := "2023-09-16")] -protected theorem map_sum {ι : Type*} (f : M₁ →SL[σ₁₂] M₂) (s : Finset ι) (g : ι → M₁) : - f (∑ i ∈ s, g i) = ∑ i ∈ s, f (g i) := - map_sum .. - @[simp, norm_cast] theorem coe_coe (f : M₁ →SL[σ₁₂] M₂) : ⇑(f : M₁ →ₛₗ[σ₁₂] M₂) = f := rfl diff --git a/Mathlib/Topology/Separation.lean b/Mathlib/Topology/Separation.lean index 4d39f3cd21001c..792e2e67b25444 100644 --- a/Mathlib/Topology/Separation.lean +++ b/Mathlib/Topology/Separation.lean @@ -2122,11 +2122,6 @@ theorem exists_open_between_and_isCompact_closure [LocallyCompactSpace X] [Regul refine ⟨interior L, isOpen_interior, KL, A.trans LU, ?_⟩ exact L_compact.closure_of_subset interior_subset -@[deprecated WeaklyLocallyCompactSpace.locallyCompactSpace (since := "2023-09-03")] -theorem locally_compact_of_compact [T2Space X] [CompactSpace X] : - LocallyCompactSpace X := - inferInstance - end LocallyCompactRegularSpace section T25 diff --git a/Mathlib/Topology/UniformSpace/CompactConvergence.lean b/Mathlib/Topology/UniformSpace/CompactConvergence.lean index f13aaeff613afa..c70587a4d11373 100644 --- a/Mathlib/Topology/UniformSpace/CompactConvergence.lean +++ b/Mathlib/Topology/UniformSpace/CompactConvergence.lean @@ -252,11 +252,6 @@ theorem tendsto_iff_tendstoLocallyUniformly [WeaklyLocallyCompactSpace α] : obtain ⟨n, hn₁, hn₂⟩ := exists_compact_mem_nhds x exact ⟨n, hn₂, h n hn₁ V hV⟩ -@[deprecated tendsto_iff_tendstoLocallyUniformly (since := "2023-09-03")] -theorem tendstoLocallyUniformly_of_tendsto [WeaklyLocallyCompactSpace α] (h : Tendsto F p (𝓝 f)) : - TendstoLocallyUniformly (fun i a => F i a) f p := - tendsto_iff_tendstoLocallyUniformly.1 h - section Functorial variable {γ δ : Type*} [TopologicalSpace γ] [UniformSpace δ] From 8f520637f08a283ae0e192c0a218a1b4e67ec8ea Mon Sep 17 00:00:00 2001 From: FR Date: Fri, 18 Oct 2024 13:37:51 +0000 Subject: [PATCH 378/425] chore: redefine `Nat.bitCasesOn` `Nat.binaryRec` (#15571) The new definitions of `Nat.bitCasesOn` and `Nat.binaryRec*` have better runtime performance. Also they have lighter weight dependencies now and may be upstreamed to `Batteries` later. --- Mathlib/Data/Nat/Bits.lean | 133 +++++++++++++++++++--------------- Mathlib/Data/Nat/Bitwise.lean | 10 ++- Mathlib/Data/Nat/Size.lean | 1 - 3 files changed, 79 insertions(+), 65 deletions(-) diff --git a/Mathlib/Data/Nat/Bits.lean b/Mathlib/Data/Nat/Bits.lean index c6e41071fc2140..e580011668c94b 100644 --- a/Mathlib/Data/Nat/Bits.lean +++ b/Mathlib/Data/Nat/Bits.lean @@ -123,10 +123,24 @@ lemma bit_val (b n) : bit b n = 2 * n + cond b 1 0 := by lemma bit_decomp (n : Nat) : bit (bodd n) (div2 n) = n := (bit_val _ _).trans <| (Nat.add_comm _ _).trans <| bodd_add_div2 _ -/-- For a predicate `C : Nat → Sort*`, if instances can be +theorem shiftRight_one (n) : n >>> 1 = n / 2 := rfl + +@[simp] +theorem bit_decide_mod_two_eq_one_shiftRight_one (n : Nat) : bit (n % 2 = 1) (n >>> 1) = n := by + simp only [bit, shiftRight_one] + cases mod_two_eq_zero_or_one n with | _ h => simpa [h] using Nat.div_add_mod n 2 + +theorem bit_testBit_zero_shiftRight_one (n : Nat) : bit (n.testBit 0) (n >>> 1) = n := by + simp + +/-- For a predicate `motive : Nat → Sort*`, if instances can be constructed for natural numbers of the form `bit b n`, they can be constructed for any given natural number. -/ -def bitCasesOn {C : Nat → Sort u} (n) (h : ∀ b n, C (bit b n)) : C n := bit_decomp n ▸ h _ _ +def bitCasesOn {motive : Nat → Sort u} (n) (h : ∀ b n, motive (bit b n)) : motive n := + -- `1 &&& n != 0` is faster than `n.testBit 0`. This may change when we have faster `testBit`. + let x := h (1 &&& n != 0) (n >>> 1) + -- `congrArg motive _ ▸ x` is defeq to `x` in non-dependent case + congrArg motive n.bit_testBit_zero_shiftRight_one ▸ x lemma bit_zero : bit false 0 = 0 := rfl @@ -158,21 +172,16 @@ lemma binaryRec_decreasing (h : n ≠ 0) : div2 n < n := by rwa [Nat.mul_one] at this /-- A recursion principle for `bit` representations of natural numbers. - For a predicate `C : Nat → Sort*`, if instances can be + For a predicate `motive : Nat → Sort*`, if instances can be constructed for natural numbers of the form `bit b n`, they can be constructed for all natural numbers. -/ -def binaryRec {C : Nat → Sort u} (z : C 0) (f : ∀ b n, C n → C (bit b n)) : ∀ n, C n := - fun n => - if n0 : n = 0 then by - simp only [n0] - exact z - else by - let n' := div2 n - have _x : bit (bodd n) n' = n := by - apply bit_decomp n - rw [← _x] - exact f (bodd n) n' (binaryRec z f n') - decreasing_by exact binaryRec_decreasing n0 +def binaryRec {motive : Nat → Sort u} (z : motive 0) (f : ∀ b n, motive n → motive (bit b n)) + (n : Nat) : motive n := + if n0 : n = 0 then congrArg motive n0 ▸ z + else + let x := f (1 &&& n != 0) (n >>> 1) (binaryRec z f (n >>> 1)) + congrArg motive n.bit_testBit_zero_shiftRight_one ▸ x +decreasing_by exact bitwise_rec_lemma n0 /-- `size n` : Returns the size of a natural number in bits i.e. the length of its binary representation -/ @@ -191,7 +200,8 @@ def ldiff : ℕ → ℕ → ℕ := bitwise fun a b => a && not b @[simp] -lemma binaryRec_zero {C : Nat → Sort u} (z : C 0) (f : ∀ b n, C n → C (bit b n)) : +lemma binaryRec_zero {motive : Nat → Sort u} + (z : motive 0) (f : ∀ b n, motive n → motive (bit b n)) : binaryRec z f 0 = z := by rw [binaryRec] rfl @@ -200,7 +210,8 @@ lemma binaryRec_zero {C : Nat → Sort u} (z : C 0) (f : ∀ b n, C n → C (bit lemma binaryRec_one {C : Nat → Sort u} (z : C 0) (f : ∀ b n, C n → C (bit b n)) : binaryRec z f 1 = f true 0 z := by rw [binaryRec] - simp + simp only [succ_ne_self, ↓reduceDIte, reduceShiftRight, binaryRec_zero] + rfl /-! bitwise ops -/ @@ -249,25 +260,6 @@ lemma testBit_bit_succ (m b n) : testBit (bit b n) (succ m) = testBit n m := by simp only [bodd_eq_one_and_ne_zero] at this exact this -lemma binaryRec_eq {C : Nat → Sort u} {z : C 0} {f : ∀ b n, C n → C (bit b n)} - (h : f false 0 z = z) (b n) : binaryRec z f (bit b n) = f b n (binaryRec z f n) := by - rw [binaryRec] - split_ifs with h' - · generalize binaryRec z f (bit b n) = e - revert e - have bf := bodd_bit b n - have n0 := div2_bit b n - rw [h'] at bf n0 - simp only [bodd_zero, div2_zero] at bf n0 - subst bf n0 - rw [binaryRec_zero] - intros - rw [h, eq_mpr_eq_cast, cast_eq] - · simp only; generalize_proofs h - revert h - rw [bodd_bit, div2_bit] - intros; simp only [eq_mpr_eq_cast, cast_eq] - /-! ### `boddDiv2_eq` and `bodd` -/ @@ -296,28 +288,41 @@ theorem bit_ne_zero (b) {n} (h : n ≠ 0) : bit b n ≠ 0 := by cases b <;> dsimp [bit] <;> omega @[simp] -theorem bitCasesOn_bit {C : ℕ → Sort u} (H : ∀ b n, C (bit b n)) (b : Bool) (n : ℕ) : - bitCasesOn (bit b n) H = H b n := - eq_of_heq <| (eqRec_heq _ _).trans <| by rw [bodd_bit, div2_bit] +theorem bit_div_two (b n) : bit b n / 2 = n := by + rw [bit_val, Nat.add_comm, add_mul_div_left, div_eq_of_lt, Nat.zero_add] + · cases b <;> decide + · decide + +@[simp] +theorem bit_shiftRight_one (b n) : bit b n >>> 1 = n := + bit_div_two b n @[simp] -theorem bitCasesOn_bit0 {C : ℕ → Sort u} (H : ∀ b n, C (bit b n)) (n : ℕ) : +theorem bitCasesOn_bit {motive : ℕ → Sort u} (h : ∀ b n, motive (bit b n)) (b : Bool) (n : ℕ) : + bitCasesOn (bit b n) h = h b n := by + change congrArg motive (bit b n).bit_testBit_zero_shiftRight_one ▸ h _ _ = h b n + generalize congrArg motive (bit b n).bit_testBit_zero_shiftRight_one = e; revert e + rw [testBit_bit_zero, bit_shiftRight_one] + intros; rfl + +@[simp] +theorem bitCasesOn_bit0 {motive : ℕ → Sort u} (H : ∀ b n, motive (bit b n)) (n : ℕ) : bitCasesOn (2 * n) H = H false n := bitCasesOn_bit H false n @[simp] -theorem bitCasesOn_bit1 {C : ℕ → Sort u} (H : ∀ b n, C (bit b n)) (n : ℕ) : +theorem bitCasesOn_bit1 {motive : ℕ → Sort u} (H : ∀ b n, motive (bit b n)) (n : ℕ) : bitCasesOn (2 * n + 1) H = H true n := bitCasesOn_bit H true n -theorem bit_cases_on_injective {C : ℕ → Sort u} : - Function.Injective fun H : ∀ b n, C (bit b n) => fun n => bitCasesOn n H := by +theorem bit_cases_on_injective {motive : ℕ → Sort u} : + Function.Injective fun H : ∀ b n, motive (bit b n) => fun n => bitCasesOn n H := by intro H₁ H₂ h ext b n simpa only [bitCasesOn_bit] using congr_fun h (bit b n) @[simp] -theorem bit_cases_on_inj {C : ℕ → Sort u} (H₁ H₂ : ∀ b n, C (bit b n)) : +theorem bit_cases_on_inj {motive : ℕ → Sort u} (H₁ H₂ : ∀ b n, motive (bit b n)) : ((fun n => bitCasesOn n H₁) = fun n => bitCasesOn n H₂) ↔ H₁ = H₂ := bit_cases_on_injective.eq_iff @@ -340,27 +345,34 @@ The same as `binaryRec_eq`, but that one unfortunately requires `f` to be the identity when appending `false` to `0`. Here, we allow you to explicitly say that that case is not happening, i.e. supplying `n = 0 → b = true`. -/ -theorem binaryRec_eq' {C : ℕ → Sort*} {z : C 0} {f : ∀ b n, C n → C (bit b n)} (b n) - (h : f false 0 z = z ∨ (n = 0 → b = true)) : +theorem binaryRec_eq' {motive : ℕ → Sort*} {z : motive 0} {f : ∀ b n, motive n → motive (bit b n)} + (b n) (h : f false 0 z = z ∨ (n = 0 → b = true)) : binaryRec z f (bit b n) = f b n (binaryRec z f n) := by - rw [binaryRec] - split_ifs with h' - · rcases bit_eq_zero_iff.mp h' with ⟨rfl, rfl⟩ - rw [binaryRec_zero] + by_cases h' : bit b n = 0 + case pos => + obtain ⟨rfl, rfl⟩ := bit_eq_zero_iff.mp h' simp only [imp_false, or_false, eq_self_iff_true, not_true, reduceCtorEq] at h + unfold binaryRec exact h.symm - · dsimp only [] - generalize_proofs e - revert e - rw [bodd_bit, div2_bit] - intros - rfl + case neg => + rw [binaryRec, dif_neg h'] + change congrArg motive (bit b n).bit_testBit_zero_shiftRight_one ▸ f _ _ _ = _ + generalize congrArg motive (bit b n).bit_testBit_zero_shiftRight_one = e; revert e + rw [testBit_bit_zero, bit_shiftRight_one] + intros; rfl + +theorem binaryRec_eq {motive : Nat → Sort u} {z : motive 0} + {f : ∀ b n, motive n → motive (bit b n)} + (h : f false 0 z = z) (b n) : + binaryRec z f (bit b n) = f b n (binaryRec z f n) := + binaryRec_eq' b n (.inl h) /-- The same as `binaryRec`, but the induction step can assume that if `n=0`, the bit being appended is `true`-/ @[elab_as_elim] -def binaryRec' {C : ℕ → Sort*} (z : C 0) (f : ∀ b n, (n = 0 → b = true) → C n → C (bit b n)) : - ∀ n, C n := +def binaryRec' {motive : ℕ → Sort*} (z : motive 0) + (f : ∀ b n, (n = 0 → b = true) → motive n → motive (bit b n)) : + ∀ n, motive n := binaryRec z fun b n ih => if h : n = 0 → b = true then f b n h ih else by @@ -370,8 +382,9 @@ def binaryRec' {C : ℕ → Sort*} (z : C 0) (f : ∀ b n, (n = 0 → b = true) /-- The same as `binaryRec`, but special casing both 0 and 1 as base cases -/ @[elab_as_elim] -def binaryRecFromOne {C : ℕ → Sort*} (z₀ : C 0) (z₁ : C 1) (f : ∀ b n, n ≠ 0 → C n → C (bit b n)) : - ∀ n, C n := +def binaryRecFromOne {motive : ℕ → Sort*} (z₀ : motive 0) (z₁ : motive 1) + (f : ∀ b n, n ≠ 0 → motive n → motive (bit b n)) : + ∀ n, motive n := binaryRec' z₀ fun b n h ih => if h' : n = 0 then by rw [h', h h'] diff --git a/Mathlib/Data/Nat/Bitwise.lean b/Mathlib/Data/Nat/Bitwise.lean index 98bc466c54c8db..2a45dc564a4b8d 100644 --- a/Mathlib/Data/Nat/Bitwise.lean +++ b/Mathlib/Data/Nat/Bitwise.lean @@ -69,10 +69,12 @@ 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 = bit_decomp n ▸ f (bodd n) (div2 n) (binaryRec z f (div2 n)) := by - rw [Eq.rec_eq_cast] - rw [binaryRec] - dsimp only - rw [dif_neg h, eq_mpr_eq_cast] + cases n using bitCasesOn with + | h b n => + rw [binaryRec_eq' _ _ (by right; simpa [bit_eq_zero_iff] using h)] + generalize_proofs h; revert h + rw [bodd_bit, div2_bit] + simp @[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/Size.lean b/Mathlib/Data/Nat/Size.lean index f3f51b3aa4f029..5c7eb08714c3c1 100644 --- a/Mathlib/Data/Nat/Size.lean +++ b/Mathlib/Data/Nat/Size.lean @@ -44,7 +44,6 @@ theorem size_bit {b n} (h : bit b n ≠ 0) : size (bit b n) = succ (size n) := b lhs rw [binaryRec] simp [h] - rw [div2_bit] section From e84469bdcf9629d3ca28d01dd2889a5ee3fb5742 Mon Sep 17 00:00:00 2001 From: FR Date: Fri, 18 Oct 2024 13:37:52 +0000 Subject: [PATCH 379/425] =?UTF-8?q?chore:=20do=20not=20use=20`=C2=B7=20?= =?UTF-8?q?=E2=89=88=20=C2=B7`=20in=20`Quotient.eq`=20(#17594)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When `Setoid` is not an instance, we obviously want to avoid using `· ≈ ·`. Currently mathlib replicates the API around `Quotient.mk` for `Quotient.mk''`, but this is not needed because `Quotient.mk` doesn't use instance parameters now. After adjusting the API we can stop using `Quotient.mk''`. --- Mathlib/Algebra/BigOperators/Group/Finset.lean | 2 +- Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian.lean | 4 ++-- Mathlib/Data/Multiset/Basic.lean | 2 +- Mathlib/Data/Quot.lean | 5 ++++- Mathlib/Data/Setoid/Basic.lean | 7 +++++-- Mathlib/ModelTheory/DirectLimit.lean | 2 +- 6 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Group/Finset.lean b/Mathlib/Algebra/BigOperators/Group/Finset.lean index cda549919c99cb..ed79af0319d287 100644 --- a/Mathlib/Algebra/BigOperators/Group/Finset.lean +++ b/Mathlib/Algebra/BigOperators/Group/Finset.lean @@ -1618,7 +1618,7 @@ theorem prod_partition (R : Setoid α) [DecidableRel R.r] : /-- If we can partition a product into subsets that cancel out, then the whole product cancels. -/ @[to_additive "If we can partition a sum into subsets that cancel out, then the whole sum cancels."] theorem prod_cancels_of_partition_cancels (R : Setoid α) [DecidableRel R.r] - (h : ∀ x ∈ s, ∏ a ∈ s.filter fun y => y ≈ x, f a = 1) : ∏ x ∈ s, f x = 1 := by + (h : ∀ x ∈ s, ∏ a ∈ s.filter fun y => R y x, f a = 1) : ∏ x ∈ s, f x = 1 := by rw [prod_partition R, ← Finset.prod_eq_one] intro xbar xbar_in_s obtain ⟨x, x_in_s, rfl⟩ := mem_image.mp xbar_in_s diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian.lean index d0976e216dd812..e4838de2f5dd08 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian.lean @@ -1169,7 +1169,7 @@ lemma add_of_equiv {P Q : Fin 3 → R} (h : P ≈ Q) : W'.add P Q = W'.dblXYZ P 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 have smul : P ≈ Q ↔ u • P ≈ v • Q := by - erw [← Quotient.eq, ← Quotient.eq, smul_eq P hu, smul_eq Q hv] + erw [← Quotient.eq_iff_equiv, ← Quotient.eq_iff_equiv, smul_eq P hu, smul_eq Q hv] rfl rw [add_of_equiv <| smul.mp h, dblXYZ_smul, add_of_equiv h] @@ -1185,7 +1185,7 @@ lemma add_of_not_equiv {P Q : Fin 3 → R} (h : ¬P ≈ Q) : W'.add P Q = W'.add 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 have smul : P ≈ Q ↔ u • P ≈ v • Q := by - erw [← Quotient.eq, ← Quotient.eq, smul_eq P hu, smul_eq Q hv] + erw [← Quotient.eq_iff_equiv, ← Quotient.eq_iff_equiv, smul_eq P hu, smul_eq Q hv] rfl rw [add_of_not_equiv <| h.comp smul.mpr, addXYZ_smul, add_of_not_equiv h] diff --git a/Mathlib/Data/Multiset/Basic.lean b/Mathlib/Data/Multiset/Basic.lean index 8f15a338625d13..e04ef7fa7a1dc6 100644 --- a/Mathlib/Data/Multiset/Basic.lean +++ b/Mathlib/Data/Multiset/Basic.lean @@ -69,7 +69,7 @@ instance [DecidableEq α] (l₁ l₂ : List α) : Decidable (l₁ ≈ l₂) := -- Porting note: `Quotient.recOnSubsingleton₂ s₁ s₂` was in parens which broke elaboration instance decidableEq [DecidableEq α] : DecidableEq (Multiset α) - | s₁, s₂ => Quotient.recOnSubsingleton₂ s₁ s₂ fun _ _ => decidable_of_iff' _ Quotient.eq + | s₁, s₂ => Quotient.recOnSubsingleton₂ s₁ s₂ fun _ _ => decidable_of_iff' _ Quotient.eq_iff_equiv /-- defines a size for a multiset by referring to the size of the underlying list -/ protected diff --git a/Mathlib/Data/Quot.lean b/Mathlib/Data/Quot.lean index 8f524efb7730bb..a11fa73582072b 100644 --- a/Mathlib/Data/Quot.lean +++ b/Mathlib/Data/Quot.lean @@ -274,9 +274,12 @@ theorem Quot.eq {α : Type*} {r : α → α → Prop} {x y : α} : ⟨Quot.eqvGen_exact, Quot.eqvGen_sound⟩ @[simp] -theorem Quotient.eq {r : Setoid α} {x y : α} : Quotient.mk r x = ⟦y⟧ ↔ x ≈ y := +theorem Quotient.eq {r : Setoid α} {x y : α} : Quotient.mk r x = ⟦y⟧ ↔ r x y := ⟨Quotient.exact, Quotient.sound⟩ +theorem Quotient.eq_iff_equiv {r : Setoid α} {x y : α} : Quotient.mk r x = ⟦y⟧ ↔ x ≈ y := + Quotient.eq + theorem Quotient.forall {α : Sort*} {s : Setoid α} {p : Quotient s → Prop} : (∀ a, p a) ↔ ∀ a : α, p ⟦a⟧ := ⟨fun h _ ↦ h _, fun h a ↦ a.ind h⟩ diff --git a/Mathlib/Data/Setoid/Basic.lean b/Mathlib/Data/Setoid/Basic.lean index 63241cbb3689de..c34439b36e1e10 100644 --- a/Mathlib/Data/Setoid/Basic.lean +++ b/Mathlib/Data/Setoid/Basic.lean @@ -221,9 +221,12 @@ lemma sInf_equiv {S : Set (Setoid α)} {x y : α} : letI := sInf S x ≈ y ↔ ∀ s ∈ S, s.Rel x y := Iff.rfl +lemma sInf_iff {S : Set (Setoid α)} {x y : α} : + sInf S x y ↔ ∀ s ∈ S, s x y := Iff.rfl + lemma quotient_mk_sInf_eq {S : Set (Setoid α)} {x y : α} : - Quotient.mk (sInf S) x = Quotient.mk (sInf S) y ↔ ∀ s ∈ S, s.Rel x y := by - simp [sInf_equiv] + Quotient.mk (sInf S) x = Quotient.mk (sInf S) y ↔ ∀ s ∈ S, s x y := by + simp [sInf_iff] /-- The map induced between quotients by a setoid inequality. -/ def map_of_le {s t : Setoid α} (h : s ≤ t) : Quotient s → Quotient t := diff --git a/Mathlib/ModelTheory/DirectLimit.lean b/Mathlib/ModelTheory/DirectLimit.lean index 295d49fb6ebf96..bc5cfde3f62f1a 100644 --- a/Mathlib/ModelTheory/DirectLimit.lean +++ b/Mathlib/ModelTheory/DirectLimit.lean @@ -349,7 +349,7 @@ def lift (g : ∀ i, G i ↪[L] P) (Hg : ∀ i j hij x, g j (f i j hij x) = g i rw [← Quotient.out_eq x, ← Quotient.out_eq y, Quotient.lift_mk, Quotient.lift_mk] at xy obtain ⟨i, hx, hy⟩ := directed_of (· ≤ ·) x.out.1 y.out.1 rw [← Hg x.out.1 i hx, ← Hg y.out.1 i hy] at xy - rw [← Quotient.out_eq x, ← Quotient.out_eq y, Quotient.eq, equiv_iff G f hx hy] + rw [← Quotient.out_eq x, ← Quotient.out_eq y, Quotient.eq_iff_equiv, equiv_iff G f hx hy] exact (g i).injective xy map_fun' F x := by obtain ⟨i, y, rfl⟩ := exists_quotient_mk'_sigma_mk'_eq G f x From 344c0bb0e582a25235a93bb531130cb0433c6392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 18 Oct 2024 14:18:26 +0000 Subject: [PATCH 380/425] feat: a subgroup is `1` iff it's trivial (#17906) From LeanCamCombi --- Mathlib/Algebra/Group/Subgroup/Pointwise.lean | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mathlib/Algebra/Group/Subgroup/Pointwise.lean b/Mathlib/Algebra/Group/Subgroup/Pointwise.lean index 95c62df222f42b..f42601fa4cc090 100644 --- a/Mathlib/Algebra/Group/Subgroup/Pointwise.lean +++ b/Mathlib/Algebra/Group/Subgroup/Pointwise.lean @@ -41,6 +41,10 @@ lemma smul_coe_set [Group G] [SetLike S G] [SubgroupClass S G] {s : S} {a : G} ( a • (s : Set G) = s := by ext; simp [Set.mem_smul_set_iff_inv_smul_mem, mul_mem_cancel_left, ha] +@[norm_cast, to_additive] +lemma coe_set_eq_one [Group G] {s : Subgroup G} : (s : Set G) = 1 ↔ s = ⊥ := + (SetLike.ext'_iff.trans (by rfl)).symm + @[to_additive (attr := simp)] lemma op_smul_coe_set [Group G] [SetLike S G] [SubgroupClass S G] {s : S} {a : G} (ha : a ∈ s) : MulOpposite.op a • (s : Set G) = s := by From 2a3ae36b046fab48ee07482c6b66d7d5f1e6eff3 Mon Sep 17 00:00:00 2001 From: Scott Carnahan <128885296+ScottCarnahan@users.noreply.github.com> Date: Fri, 18 Oct 2024 14:51:42 +0000 Subject: [PATCH 381/425] feat (RingTheory/HahnSeries/Summable) : transport summable families along Equiv (#16872) This PR defines a new summable family given a summable family of Hahn series and an equivalence of parametrizing types. We show that the new family has the same formal sum as the old one. --- Mathlib/RingTheory/HahnSeries/Summable.lean | 25 ++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/Mathlib/RingTheory/HahnSeries/Summable.lean b/Mathlib/RingTheory/HahnSeries/Summable.lean index 4405c005d34e1e..45a21761c48c32 100644 --- a/Mathlib/RingTheory/HahnSeries/Summable.lean +++ b/Mathlib/RingTheory/HahnSeries/Summable.lean @@ -42,7 +42,7 @@ open Pointwise noncomputable section -variable {Γ : Type*} {R : Type*} +variable {Γ Γ' R V α β : Type*} namespace HahnSeries @@ -61,13 +61,11 @@ theorem isPWO_iUnion_support_powers [LinearOrderedCancelAddCommMonoid Γ] [Ring section -variable (Γ) (R) [PartialOrder Γ] [AddCommMonoid R] - /-- A family of Hahn series whose formal coefficient-wise sum is a Hahn series. For each coefficient of the sum to be well-defined, we require that only finitely many series are nonzero at any given coefficient. For the formal sum to be a Hahn series, we require that the union of the supports of the constituent series is partially well-ordered. -/ -structure SummableFamily (α : Type*) where +structure SummableFamily (Γ) (R) [PartialOrder Γ] [AddCommMonoid R] (α : Type*) where /-- A parametrized family of Hahn series. -/ toFun : α → HahnSeries Γ R isPWO_iUnion_support' : Set.IsPWO (⋃ a : α, (toFun a).support) @@ -79,7 +77,7 @@ namespace SummableFamily section AddCommMonoid -variable [PartialOrder Γ] [AddCommMonoid R] {α : Type*} +variable [PartialOrder Γ] [AddCommMonoid R] instance : FunLike (SummableFamily Γ R α) α (HahnSeries Γ R) where coe := toFun @@ -180,6 +178,23 @@ theorem hsum_add {s t : SummableFamily Γ R α} : (s + t).hsum = s.hsum + t.hsum simp only [hsum_coeff, add_coeff, add_apply] exact finsum_add_distrib (s.finite_co_support _) (t.finite_co_support _) +/-- A summable family induced by an equivalence of the parametrizing type. -/ +@[simps] +def Equiv (e : α ≃ β) (s : SummableFamily Γ R α) : SummableFamily Γ R β where + toFun b := s (e.symm b) + isPWO_iUnion_support' := by + refine Set.IsPWO.mono s.isPWO_iUnion_support fun g => ?_ + simp only [Set.mem_iUnion, mem_support, ne_eq, forall_exists_index] + exact fun b hg => Exists.intro (e.symm b) hg + finite_co_support' g := + (Equiv.set_finite_iff e.subtypeEquivOfSubtype').mp <| s.finite_co_support' g + +@[simp] +theorem hsum_equiv (e : α ≃ β) (s : SummableFamily Γ R α) : (Equiv e s).hsum = s.hsum := by + ext g + simp only [hsum_coeff, Equiv_toFun] + exact finsum_eq_of_bijective e.symm (Equiv.bijective e.symm) fun x => rfl + end AddCommMonoid section AddCommGroup From c289ac29f16b5d6733857a95139dc57fa8ebc646 Mon Sep 17 00:00:00 2001 From: Jz Pan Date: Fri, 18 Oct 2024 14:51:43 +0000 Subject: [PATCH 382/425] feat(RingTheory/Algebraic): add some results on `Transcendental` (#17867) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `transcendental_iff`, `transcendental_iff_ker_eq_bot`: similar to the API of `AlgebraicIndependent` - `IsAlgebraic.of_aeval`, `Transcendental.aeval`: behavior of transcendental over `aeval` - `Polynomial.transcendental`, `Polynomial.transcendental_X`: some specific polynomials are transcendental over its base ring - `Transcendental.linearIndependent_sub_inv`: if `E / F` is a field extension, `x` is an element of `E` transcendental over `F`, then `{(x - a)⁻¹ | a : F}` is linearly independent over `F` - `transcendental_algebraMap_iff`: negation of `isAlgebraic_algebraMap_iff` --- Mathlib/RingTheory/Algebraic.lean | 69 +++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/Mathlib/RingTheory/Algebraic.lean b/Mathlib/RingTheory/Algebraic.lean index 86852795792387..9942e6c3473710 100644 --- a/Mathlib/RingTheory/Algebraic.lean +++ b/Mathlib/RingTheory/Algebraic.lean @@ -40,6 +40,63 @@ theorem is_transcendental_of_subsingleton [Subsingleton R] (x : A) : Transcenden variable {R} +/-- An element `x` is transcendental over `R` if and only if for any polynomial `p`, +`Polynomial.aeval x p = 0` implies `p = 0`. This is similar to `algebraicIndependent_iff`. -/ +theorem transcendental_iff {x : A} : + Transcendental R x ↔ ∀ p : R[X], aeval x p = 0 → p = 0 := by + rw [Transcendental, IsAlgebraic, not_exists] + congr! 1; tauto + +variable (R) in +theorem Polynomial.transcendental_X : Transcendental R (X (R := R)) := by + simp [transcendental_iff] + +theorem IsAlgebraic.of_aeval {r : A} (f : R[X]) (hf : f.natDegree ≠ 0) + (hf' : f.leadingCoeff ∈ nonZeroDivisors R) (H : IsAlgebraic R (aeval r f)) : + IsAlgebraic R r := by + obtain ⟨p, h1, h2⟩ := H + have : (p.comp f).coeff (p.natDegree * f.natDegree) ≠ 0 := fun h ↦ h1 <| by + rwa [coeff_comp_degree_mul_degree hf, + mul_right_mem_nonZeroDivisors_eq_zero_iff (pow_mem hf' _), + leadingCoeff_eq_zero] at h + exact ⟨p.comp f, fun h ↦ this (by simp [h]), by rwa [aeval_comp]⟩ + +theorem Transcendental.aeval {r : A} (H : Transcendental R r) (f : R[X]) (hf : f.natDegree ≠ 0) + (hf' : f.leadingCoeff ∈ nonZeroDivisors R) : + Transcendental R (aeval r f) := fun h ↦ H (h.of_aeval f hf hf') + +theorem Polynomial.transcendental (f : R[X]) (hf : f.natDegree ≠ 0) + (hf' : f.leadingCoeff ∈ nonZeroDivisors R) : + Transcendental R f := by + simpa using (transcendental_X R).aeval f hf hf' + +/-- If `E / F` is a field extension, `x` is an element of `E` transcendental over `F`, +then `{(x - a)⁻¹ | a : F}` is linearly independent over `F`. -/ +theorem Transcendental.linearIndependent_sub_inv + {F E : Type*} [Field F] [Field E] [Algebra F E] {x : E} (H : Transcendental F x) : + LinearIndependent F fun a ↦ (x - algebraMap F E a)⁻¹ := by + rw [transcendental_iff] at H + refine linearIndependent_iff'.2 fun s m hm i hi ↦ ?_ + have hnz (a : F) : x - algebraMap F E a ≠ 0 := fun h ↦ + X_sub_C_ne_zero a <| H (.X - .C a) (by simp [h]) + let b := s.prod fun j ↦ x - algebraMap F E j + have h1 : ∀ i ∈ s, m i • (b * (x - algebraMap F E i)⁻¹) = + m i • (s.erase i).prod fun j ↦ x - algebraMap F E j := fun i hi ↦ by + simp_rw [b, ← s.prod_erase_mul _ hi, mul_inv_cancel_right₀ (hnz i)] + replace hm := congr(b * $(hm)) + simp_rw [mul_zero, Finset.mul_sum, mul_smul_comm, Finset.sum_congr rfl h1] at hm + let p : Polynomial F := s.sum fun i ↦ .C (m i) * (s.erase i).prod fun j ↦ .X - .C j + replace hm := congr(Polynomial.aeval i $(H p (by simp_rw [← hm, p, map_sum, map_mul, map_prod, + map_sub, aeval_X, aeval_C, Algebra.smul_def]))) + have h2 : ∀ j ∈ s.erase i, m j * ((s.erase j).prod fun x ↦ i - x) = 0 := fun j hj ↦ by + have := Finset.mem_erase_of_ne_of_mem (Finset.ne_of_mem_erase hj).symm hi + simp_rw [← (s.erase j).prod_erase_mul _ this, sub_self, mul_zero] + simp_rw [map_zero, p, map_sum, map_mul, map_prod, map_sub, aeval_X, + aeval_C, Algebra.id.map_eq_self, ← s.sum_erase_add _ hi, + Finset.sum_eq_zero h2, zero_add] at hm + exact eq_zero_of_ne_zero_of_mul_right_eq_zero (Finset.prod_ne_zero_iff.2 fun j hj ↦ + sub_ne_zero.2 (Finset.ne_of_mem_erase hj).symm) hm + /-- A subalgebra is algebraic if all its elements are algebraic. -/ nonrec def Subalgebra.IsAlgebraic (S : Subalgebra R A) : Prop := @@ -86,10 +143,18 @@ theorem isAlgebraic_iff_not_injective {x : A} : IsAlgebraic R x ↔ ¬Function.Injective (Polynomial.aeval x : R[X] →ₐ[R] A) := by simp only [IsAlgebraic, injective_iff_map_eq_zero, not_forall, and_comm, exists_prop] +/-- An element `x` is transcendental over `R` if and only if the map `Polynomial.aeval x` +is injective. This is similar to `algebraicIndependent_iff_injective_aeval`. -/ theorem transcendental_iff_injective {x : A} : Transcendental R x ↔ Function.Injective (Polynomial.aeval x : R[X] →ₐ[R] A) := isAlgebraic_iff_not_injective.not_left +/-- An element `x` is transcendental over `R` if and only if the kernel of the ring homomorphism +`Polynomial.aeval x` is the zero ideal. This is similar to `algebraicIndependent_iff_ker_eq_bot`. -/ +theorem transcendental_iff_ker_eq_bot {x : A} : + Transcendental R x ↔ RingHom.ker (aeval (R := R) x) = ⊥ := by + rw [transcendental_iff_injective, RingHom.injective_iff_ker_eq_bot] + end section zero_ne_one @@ -174,6 +239,10 @@ theorem isAlgebraic_algebraMap_iff {a : S} (h : Function.Injective (algebraMap S IsAlgebraic R (algebraMap S A a) ↔ IsAlgebraic R a := isAlgebraic_algHom_iff (IsScalarTower.toAlgHom R S A) h +theorem transcendental_algebraMap_iff {a : S} (h : Function.Injective (algebraMap S A)) : + Transcendental R (algebraMap S A a) ↔ Transcendental R a := by + simp_rw [Transcendental, isAlgebraic_algebraMap_iff h] + theorem IsAlgebraic.of_pow {r : A} {n : ℕ} (hn : 0 < n) (ht : IsAlgebraic R (r ^ n)) : IsAlgebraic R r := by obtain ⟨p, p_nonzero, hp⟩ := ht From 66fe0b7279d0edf044d905b5a4068aa929b78e7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 18 Oct 2024 14:51:44 +0000 Subject: [PATCH 383/425] doc(Simps): deduplicate clause (#17916) Both clauses were different before #8296 --- Mathlib/Tactic/Simps/Basic.lean | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mathlib/Tactic/Simps/Basic.lean b/Mathlib/Tactic/Simps/Basic.lean index 1caba0e4825aba..3b28a506c4d612 100644 --- a/Mathlib/Tactic/Simps/Basic.lean +++ b/Mathlib/Tactic/Simps/Basic.lean @@ -317,8 +317,7 @@ Some common uses: This will generate `foo_apply` lemmas for each declaration `foo`. * If you prefer `coe_foo` lemmas that state equalities between functions, use `initialize_simps_projections MulHom (toFun → coe, as_prefix coe)` - In this case you have to use `@[simps (config := .asFn)]` or equivalently - `@[simps (config := .asFn)]` whenever you call `@[simps]`. + In this case you have to use `@[simps (config := .asFn)]` whenever you call `@[simps]`. * You can also initialize to use both, in which case you have to choose which one to use by default, by using either of the following ``` From 9e3fa1e4f5106b00d9b078c99479dae53c6adbb7 Mon Sep 17 00:00:00 2001 From: Jz Pan Date: Fri, 18 Oct 2024 15:39:36 +0000 Subject: [PATCH 384/425] feat(FieldTheory/Adjoin): add some results of `extendScalars` (#15238) - `extendScalars_{self|top|inf|sup}` for intermediate fields and subfields - also add `restrictScalars_{inf|sup}` and `bot_toSubfield` - add a missing helper lemma `toSubfield_injective` --- Mathlib/FieldTheory/Adjoin.lean | 82 ++++++++++++++++++- .../FieldTheory/IntermediateField/Basic.lean | 15 ++-- 2 files changed, 89 insertions(+), 8 deletions(-) diff --git a/Mathlib/FieldTheory/Adjoin.lean b/Mathlib/FieldTheory/Adjoin.lean index aa48dc241889b9..f5504ce4341215 100644 --- a/Mathlib/FieldTheory/Adjoin.lean +++ b/Mathlib/FieldTheory/Adjoin.lean @@ -114,6 +114,9 @@ theorem mem_bot {x : E} : x ∈ (⊥ : IntermediateField F E) ↔ x ∈ Set.rang @[simp] theorem bot_toSubalgebra : (⊥ : IntermediateField F E).toSubalgebra = ⊥ := rfl +theorem bot_toSubfield : (⊥ : IntermediateField F E).toSubfield = (algebraMap F E).fieldRange := + rfl + @[simp] theorem coe_top : ↑(⊤ : IntermediateField F E) = (Set.univ : Set E) := rfl @@ -267,16 +270,31 @@ def topEquiv : (⊤ : IntermediateField F E) ≃ₐ[F] E := -- Porting note: this theorem is now generated by the `@[simps!]` above. +section RestrictScalars + @[simp] theorem restrictScalars_bot_eq_self (K : IntermediateField F E) : (⊥ : IntermediateField K E).restrictScalars _ = K := SetLike.coe_injective Subtype.range_coe +variable {K : Type*} [Field K] [Algebra K E] [Algebra K F] [IsScalarTower K F E] + @[simp] -theorem restrictScalars_top {K : Type*} [Field K] [Algebra K E] [Algebra K F] - [IsScalarTower K F E] : (⊤ : IntermediateField F E).restrictScalars K = ⊤ := +theorem restrictScalars_top : (⊤ : IntermediateField F E).restrictScalars K = ⊤ := rfl +variable (K) +variable (L L' : IntermediateField F E) + +theorem restrictScalars_sup : + L.restrictScalars K ⊔ L'.restrictScalars K = (L ⊔ L').restrictScalars K := + toSubfield_injective (by simp) + +theorem restrictScalars_inf : + L.restrictScalars K ⊓ L'.restrictScalars K = (L ⊓ L').restrictScalars K := rfl + +end RestrictScalars + variable {K : Type*} [Field K] [Algebra F K] @[simp] @@ -1466,3 +1484,63 @@ theorem comap_map (f : L →ₐ[K] L') (S : IntermediateField K L) : (S.map f).c SetLike.coe_injective (Set.preimage_image_eq _ f.injective) end IntermediateField + +section ExtendScalars + +variable {K : Type*} [Field K] {L : Type*} [Field L] [Algebra K L] + +namespace Subfield + +variable (F : Subfield L) + +@[simp] +theorem extendScalars_self : extendScalars (le_refl F) = ⊥ := by + ext x + rw [mem_extendScalars, IntermediateField.mem_bot] + refine ⟨fun h ↦ ⟨⟨x, h⟩, rfl⟩, ?_⟩ + rintro ⟨y, rfl⟩ + exact y.2 + +@[simp] +theorem extendScalars_top : extendScalars (le_top : F ≤ ⊤) = ⊤ := + IntermediateField.toSubfield_injective (by simp) + +variable {F} +variable {E E' : Subfield L} (h : F ≤ E) (h' : F ≤ E') + +theorem extendScalars_sup : + extendScalars h ⊔ extendScalars h' = extendScalars (le_sup_of_le_left h : F ≤ E ⊔ E') := + ((extendScalars.orderIso F).map_sup ⟨_, h⟩ ⟨_, h'⟩).symm + +theorem extendScalars_inf : extendScalars h ⊓ extendScalars h' = extendScalars (le_inf h h') := + ((extendScalars.orderIso F).map_inf ⟨_, h⟩ ⟨_, h'⟩).symm + +end Subfield + +namespace IntermediateField + +variable (F : IntermediateField K L) + +@[simp] +theorem extendScalars_self : extendScalars (le_refl F) = ⊥ := + restrictScalars_injective K (by simp) + +@[simp] +theorem extendScalars_top : extendScalars (le_top : F ≤ ⊤) = ⊤ := + restrictScalars_injective K (by simp) + +variable {F} +variable {E E' : IntermediateField K L} (h : F ≤ E) (h' : F ≤ E') + +theorem extendScalars_sup : + extendScalars h ⊔ extendScalars h' = extendScalars (le_sup_of_le_left h : F ≤ E ⊔ E') := + ((extendScalars.orderIso F).map_sup ⟨_, h⟩ ⟨_, h'⟩).symm + +theorem extendScalars_inf : extendScalars h ⊓ extendScalars h' = extendScalars (le_inf h h') := + ((extendScalars.orderIso F).map_inf ⟨_, h⟩ ⟨_, h'⟩).symm + +end IntermediateField + +end ExtendScalars + +set_option linter.style.longFile 1700 diff --git a/Mathlib/FieldTheory/IntermediateField/Basic.lean b/Mathlib/FieldTheory/IntermediateField/Basic.lean index 1c807c53644734..54dbf4d6b374da 100644 --- a/Mathlib/FieldTheory/IntermediateField/Basic.lean +++ b/Mathlib/FieldTheory/IntermediateField/Basic.lean @@ -494,14 +494,17 @@ theorem coe_inclusion {E F : IntermediateField K L} (hEF : E ≤ F) (e : E) : variable {S} -theorem toSubalgebra_injective : - Function.Injective (IntermediateField.toSubalgebra : IntermediateField K L → _) := by - intro S S' h +theorem toSubalgebra_injective : Function.Injective (toSubalgebra : IntermediateField K L → _) := by + intro _ _ h + ext + simp_rw [← mem_toSubalgebra, h] + +theorem toSubfield_injective : Function.Injective (toSubfield : IntermediateField K L → _) := by + intro _ _ h ext - rw [← mem_toSubalgebra, ← mem_toSubalgebra, h] + simp_rw [← mem_toSubfield, h] -theorem map_injective (f : L →ₐ[K] L') : - Function.Injective (map f) := by +theorem map_injective (f : L →ₐ[K] L') : Function.Injective (map f) := by intro _ _ h rwa [← toSubalgebra_injective.eq_iff, toSubalgebra_map, toSubalgebra_map, (Subalgebra.map_injective f.injective).eq_iff, toSubalgebra_injective.eq_iff] at h From c5b97e2f7eecede13acd99994d4be2239dbd2ea3 Mon Sep 17 00:00:00 2001 From: Yongle Hu Date: Fri, 18 Oct 2024 15:39:37 +0000 Subject: [PATCH 385/425] feat(NumberTheory/NumberField/Basic): lemmas for extension of ring of integers (#17784) Add some lemmas and `instance`s for extension of number fields or ring of integers. Co-authored-by: Yongle Hu @mbkybky Co-authored-by: Jiedong Jiang @jjdishere Co-authored-by: Hu Yongle <2065545849@qq.com> --- Mathlib/NumberTheory/NumberField/Basic.lean | 64 ++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/Mathlib/NumberTheory/NumberField/Basic.lean b/Mathlib/NumberTheory/NumberField/Basic.lean index cd142c881c370e..64c8f95606e20f 100644 --- a/Mathlib/NumberTheory/NumberField/Basic.lean +++ b/Mathlib/NumberTheory/NumberField/Basic.lean @@ -59,6 +59,23 @@ protected theorem isAlgebraic [NumberField K] : Algebra.IsAlgebraic ℚ K := instance [NumberField K] [NumberField L] [Algebra K L] : FiniteDimensional K L := Module.Finite.of_restrictScalars_finite ℚ K L +/-- A finite extension of a number field is a number field. -/ +theorem of_module_finite [NumberField K] [Algebra K L] [Module.Finite K L] : NumberField L where + to_charZero := charZero_of_injective_algebraMap (algebraMap K L).injective + to_finiteDimensional := + letI := charZero_of_injective_algebraMap (algebraMap K L).injective + Module.Finite.trans K L + +variable {K} {L} in +instance of_intermediateField [NumberField K] [NumberField L] [Algebra K L] + (E : IntermediateField K L) : NumberField E := + of_module_finite K E + +theorem of_tower [NumberField K] [NumberField L] [Algebra K L] (E : Type*) [Field E] + [Algebra K E] [Algebra E L] [IsScalarTower K E L] : NumberField E := + letI := Module.Finite.left K E L + of_module_finite K E + /-- The ring of integers (or number ring) corresponding to a number field is the integral closure of ℤ in the number field. @@ -89,7 +106,7 @@ instance : Nontrivial (𝓞 K) := inferInstanceAs (Nontrivial (integralClosure _ _)) instance {L : Type*} [Ring L] [Algebra K L] : Algebra (𝓞 K) L := inferInstanceAs (Algebra (integralClosure _ _) L) -instance {L : Type*} [Ring L] [Algebra K L] : IsScalarTower (𝓞 K) K L := +instance {L : Type*} [Ring L] [Algebra K L] : IsScalarTower (𝓞 K) K L := inferInstanceAs (IsScalarTower (integralClosure _ _) K L) variable {K} @@ -222,6 +239,9 @@ instance [NumberField K] : IsFractionRing (𝓞 K) K := instance : IsIntegralClosure (𝓞 K) ℤ K := integralClosure.isIntegralClosure _ _ +instance : Algebra.IsIntegral ℤ (𝓞 K) := + IsIntegralClosure.isIntegral_algebra ℤ K + instance [NumberField K] : IsIntegrallyClosed (𝓞 K) := integralClosure.isIntegrallyClosedOfFiniteExtension ℚ @@ -283,6 +303,48 @@ def restrict_monoidHom [MulOneClass M] (f : M →* K) (h : ∀ x, IsIntegral ℤ map_one' := by simp only [restrict, map_one, mk_one] map_mul' x y := by simp only [restrict, map_mul, mk_mul_mk _] +section extension + +variable (K L : Type*) [Field K] [Field L] [Algebra K L] + +instance : IsScalarTower (𝓞 K) (𝓞 L) L := + IsScalarTower.of_algebraMap_eq' rfl + +instance : IsIntegralClosure (𝓞 L) (𝓞 K) L := + IsIntegralClosure.tower_top (R := ℤ) + +/-- The ring of integers of `L` is isomorphic to any integral closure of `𝓞 K` in `L` -/ +protected noncomputable def algEquiv (R : Type*) [CommRing R] [Algebra (𝓞 K) R] [Algebra R L] + [IsScalarTower (𝓞 K) R L] [IsIntegralClosure R (𝓞 K) L] : 𝓞 L ≃ₐ[𝓞 K] R := + (IsIntegralClosure.equiv (𝓞 K) R L _).symm + +/-- Any extension between ring of integers is integral. -/ +instance extension_algebra_isIntegral : Algebra.IsIntegral (𝓞 K) (𝓞 L) := + IsIntegralClosure.isIntegral_algebra (𝓞 K) L + +/-- Any extension between ring of integers of number fields is noetherian. -/ +instance extension_isNoetherian [NumberField K] [NumberField L] : IsNoetherian (𝓞 K) (𝓞 L) := + IsIntegralClosure.isNoetherian (𝓞 K) K L (𝓞 L) + +/-- The kernel of the algebraMap between ring of integers is `⊥`. -/ +theorem ker_algebraMap_eq_bot : RingHom.ker (algebraMap (𝓞 K) (𝓞 L)) = ⊥ := + (RingHom.ker_eq_bot_iff_eq_zero (algebraMap (𝓞 K) (𝓞 L))).mpr <| fun x hx => by + have h : (algebraMap K L) x = (algebraMap (𝓞 K) (𝓞 L)) x := rfl + simp only [hx, map_zero, map_eq_zero, RingOfIntegers.coe_eq_zero_iff] at h + exact h + +/-- The algebraMap between ring of integers is injective. -/ +theorem algebraMap.injective : Function.Injective (algebraMap (𝓞 K) (𝓞 L)) := + (RingHom.injective_iff_ker_eq_bot (algebraMap (𝓞 K) (𝓞 L))).mpr (ker_algebraMap_eq_bot K L) + +instance : NoZeroSMulDivisors (𝓞 K) (𝓞 L) := + NoZeroSMulDivisors.of_algebraMap_injective (algebraMap.injective K L) + +instance : NoZeroSMulDivisors (𝓞 K) L := + NoZeroSMulDivisors.trans (𝓞 K) (𝓞 L) L + +end extension + end RingOfIntegers variable [NumberField K] From 8b31f1fbde480a5c530264eeea00d051d4c586c5 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 18 Oct 2024 15:48:17 +0000 Subject: [PATCH 386/425] feat(GroupTheory/ArchimedeanDensely): discrete iff not densely ordered (#16618) Stronger statements than previously proven `Or`s --- Mathlib/GroupTheory/ArchimedeanDensely.lean | 108 ++++++++++++++++---- 1 file changed, 86 insertions(+), 22 deletions(-) diff --git a/Mathlib/GroupTheory/ArchimedeanDensely.lean b/Mathlib/GroupTheory/ArchimedeanDensely.lean index 8b00a52cd33def..cf344500028b4a 100644 --- a/Mathlib/GroupTheory/ArchimedeanDensely.lean +++ b/Mathlib/GroupTheory/ArchimedeanDensely.lean @@ -191,6 +191,21 @@ lemma LinearOrderedAddCommGroup.discrete_or_denselyOrdered (G : Type*) · simp [hz.left] · simpa [lt_sub_iff_add_lt'] using hz.right +/-- Any linearly ordered archimedean additive group is either isomorphic (and order-isomorphic) +to the integers, or is densely ordered, exclusively. -/ +lemma LinearOrderedAddCommGroup.discrete_iff_not_denselyOrdered (G : Type*) + [LinearOrderedAddCommGroup G] [Archimedean G] : + Nonempty (G ≃+o ℤ) ↔ ¬ DenselyOrdered G := by + suffices ∀ (_ : G ≃+o ℤ), ¬ DenselyOrdered G by + rcases LinearOrderedAddCommGroup.discrete_or_denselyOrdered G with ⟨⟨h⟩⟩|h + · simpa [this h] using ⟨h⟩ + · simp only [h, not_true_eq_false, iff_false, not_nonempty_iff] + exact ⟨fun H ↦ (this H) h⟩ + intro e H + rw [denselyOrdered_iff_of_orderIsoClass e] at H + obtain ⟨_, _⟩ := exists_between (one_pos (α := ℤ)) + linarith + variable (G) in /-- Any linearly ordered mul-archimedean group is either isomorphic (and order-isomorphic) to the multiplicative integers, or is densely ordered. -/ @@ -201,31 +216,28 @@ lemma LinearOrderedCommGroup.discrete_or_denselyOrdered : rintro ⟨f, hf⟩ exact ⟨AddEquiv.toMultiplicative' f, hf⟩ -/-- 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. -/ -lemma LinearOrderedCommGroupWithZero.discrete_or_denselyOrdered (G : Type*) - [LinearOrderedCommGroupWithZero G] [Nontrivial Gˣ] [MulArchimedean G] : - Nonempty (G ≃*o ℤₘ₀) ∨ DenselyOrdered G := by - classical - refine (LinearOrderedCommGroup.discrete_or_denselyOrdered Gˣ).imp ?_ ?_ - · intro ⟨f⟩ - refine ⟨OrderMonoidIso.trans - ⟨WithZero.withZeroUnitsEquiv.symm, ?_⟩ ⟨f.withZero, ?_⟩⟩ - · intro - simp only [WithZero.withZeroUnitsEquiv, MulEquiv.symm_mk, - MulEquiv.toEquiv_eq_coe, Equiv.toFun_as_coe, EquivLike.coe_coe, MulEquiv.coe_mk, - Equiv.coe_fn_symm_mk ] - split_ifs <;> - simp_all [← Units.val_le_val] - · intro a b - induction a <;> induction b <;> - simp [MulEquiv.withZero] +variable (G) in +/-- Any linearly ordered mul-archimedean group is either isomorphic (and order-isomorphic) +to the multiplicative integers, or is densely ordered, exclusively. -/ +@[to_additive existing] +lemma LinearOrderedCommGroup.discrete_iff_not_denselyOrdered : + Nonempty (G ≃*o Multiplicative ℤ) ↔ ¬ DenselyOrdered G := by + let e : G ≃o Additive G := OrderIso.refl G + rw [denselyOrdered_iff_of_orderIsoClass e, + ← LinearOrderedAddCommGroup.discrete_iff_not_denselyOrdered (Additive G)] + refine Nonempty.congr ?_ ?_ <;> intro f + · exact ⟨MulEquiv.toAdditive' f, by simp⟩ + · exact ⟨MulEquiv.toAdditive'.symm f, by simp⟩ + +lemma denselyOrdered_units_iff {G₀ : Type*} [LinearOrderedCommGroupWithZero G₀] [Nontrivial G₀ˣ] : + DenselyOrdered G₀ˣ ↔ DenselyOrdered G₀ := by + constructor · intro H refine ⟨fun x y h ↦ ?_⟩ rcases (zero_le' (a := x)).eq_or_lt with rfl|hx - · lift y to Gˣ using h.ne'.isUnit - obtain ⟨z, hz⟩ := exists_ne (1 : Gˣ) - refine ⟨(y * |z|ₘ⁻¹ : Gˣ), ?_, ?_⟩ + · lift y to G₀ˣ using h.ne'.isUnit + obtain ⟨z, hz⟩ := exists_ne (1 : G₀ˣ) + refine ⟨(y * |z|ₘ⁻¹ : G₀ˣ), ?_, ?_⟩ · simp [zero_lt_iff] · rw [Units.val_lt_val] simp [hz] @@ -233,3 +245,55 @@ lemma LinearOrderedCommGroupWithZero.discrete_or_denselyOrdered (G : Type*) (by simp [← Units.val_lt_val, h]) refine ⟨z, ?_, ?_⟩ <;> simpa [← Units.val_lt_val] + · intro H + refine ⟨fun x y h ↦ ?_⟩ + obtain ⟨z, hz⟩ := exists_between (Units.val_lt_val.mpr h) + rcases (zero_le' (a := z)).eq_or_lt with rfl|hz' + · simp at hz + refine ⟨Units.mk0 z hz'.ne', ?_⟩ + simp [← Units.val_lt_val, hz] + +/-- 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. -/ +lemma LinearOrderedCommGroupWithZero.discrete_or_denselyOrdered (G : Type*) + [LinearOrderedCommGroupWithZero G] [Nontrivial Gˣ] [MulArchimedean G] : + Nonempty (G ≃*o WithZero (Multiplicative ℤ)) ∨ DenselyOrdered G := by + classical + rw [← denselyOrdered_units_iff] + refine (LinearOrderedCommGroup.discrete_or_denselyOrdered Gˣ).imp_left ?_ + intro ⟨f⟩ + refine ⟨OrderMonoidIso.trans + ⟨WithZero.withZeroUnitsEquiv.symm, ?_⟩ ⟨f.withZero, ?_⟩⟩ + · intro + simp only [WithZero.withZeroUnitsEquiv, MulEquiv.symm_mk, + MulEquiv.toEquiv_eq_coe, Equiv.toFun_as_coe, EquivLike.coe_coe, MulEquiv.coe_mk, + Equiv.coe_fn_symm_mk ] + split_ifs <;> + simp_all [← Units.val_le_val] + · intro a b + induction a <;> induction b <;> + simp [MulEquiv.withZero] + +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 -/ +lemma LinearOrderedCommGroupWithZero.discrete_iff_not_denselyOrdered (G : Type*) + [LinearOrderedCommGroupWithZero G] [Nontrivial Gˣ] [MulArchimedean G] : + Nonempty (G ≃*o WithZero (Multiplicative ℤ)) ↔ ¬ DenselyOrdered G := by + rw [← denselyOrdered_units_iff, + ← LinearOrderedCommGroup.discrete_iff_not_denselyOrdered] + refine Nonempty.congr ?_ ?_ <;> intro f + · refine ⟨MulEquiv.unzero (withZeroUnitsEquiv.trans f), ?_⟩ + intros + simp only [MulEquiv.unzero, withZeroUnitsEquiv, MulEquiv.trans_apply, + MulEquiv.coe_mk, Equiv.coe_fn_mk, recZeroCoe_coe, OrderMonoidIso.coe_mulEquiv, + MulEquiv.symm_trans_apply, MulEquiv.symm_mk, Equiv.coe_fn_symm_mk, map_eq_zero, coe_ne_zero, + ↓reduceDIte, unzero_coe, MulEquiv.toEquiv_eq_coe, Equiv.toFun_as_coe, EquivLike.coe_coe] + rw [← Units.val_le_val, ← map_le_map_iff f, ← coe_le_coe, coe_unzero, coe_unzero] + · refine ⟨withZeroUnitsEquiv.symm.trans (MulEquiv.withZero f), ?_⟩ + intros + simp only [withZeroUnitsEquiv, MulEquiv.symm_mk, MulEquiv.withZero, + MulEquiv.toMonoidHom_eq_coe, MulEquiv.toEquiv_eq_coe, Equiv.toFun_as_coe, EquivLike.coe_coe, + MulEquiv.trans_apply, MulEquiv.coe_mk, Equiv.coe_fn_symm_mk, Equiv.coe_fn_mk] + split_ifs <;> + simp_all [← Units.val_le_val] From 94bb3a8e89c75b20472ec5a37df0f225cb08e003 Mon Sep 17 00:00:00 2001 From: Yuma Mizuno Date: Fri, 18 Oct 2024 15:58:51 +0000 Subject: [PATCH 387/425] feat(CategoryTheory/Monoidal): add `Mon_Class` type class (#17185) [Zulip discussion](https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/Algebras.20in.20monoidal.20categories.2C.20bundled.20or.20semi-bundled.3F) --- Mathlib/CategoryTheory/Monoidal/Bimon_.lean | 41 +++++++++++- Mathlib/CategoryTheory/Monoidal/Comon_.lean | 67 ++++++++++++++++++- Mathlib/CategoryTheory/Monoidal/Hopf_.lean | 35 +++++++++- Mathlib/CategoryTheory/Monoidal/Mon_.lean | 72 ++++++++++++++++++++- 4 files changed, 208 insertions(+), 7 deletions(-) diff --git a/Mathlib/CategoryTheory/Monoidal/Bimon_.lean b/Mathlib/CategoryTheory/Monoidal/Bimon_.lean index 109f528c801239..e195b655047045 100644 --- a/Mathlib/CategoryTheory/Monoidal/Bimon_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Bimon_.lean @@ -29,7 +29,46 @@ universe v₁ v₂ u₁ u₂ u open CategoryTheory MonoidalCategory -variable (C : Type u₁) [Category.{v₁} C] [MonoidalCategory.{v₁} C] [BraidedCategory C] +variable {C : Type u₁} [Category.{v₁} C] [MonoidalCategory.{v₁} C] [BraidedCategory C] + +open scoped Mon_Class Comon_Class + +/-- +A bimonoid object in a braided category `C` is a object that is simultaneously monoid and comonoid +objects, and structure morphisms of them satisfy appropriate consistency conditions. +-/ +class Bimon_Class (M : C) extends Mon_Class M, Comon_Class M where + /- For the names of the conditions below, the unprimed names are reserved for the version where + the argument `M` is explicit. -/ + mul_comul' : μ[M] ≫ Δ[M] = (Δ[M] ⊗ Δ[M]) ≫ tensor_μ M M M M ≫ (μ[M] ⊗ μ[M]) := by aesop_cat + one_comul' : η[M] ≫ Δ[M] = η[M ⊗ M] := by aesop_cat + mul_counit' : μ[M] ≫ ε[M] = ε[M ⊗ M] := by aesop_cat + one_counit' : η[M] ≫ ε[M] = 𝟙 (𝟙_ C) := by aesop_cat + +namespace Bimon_Class + +/- The simp attribute is reserved for the unprimed versions. -/ +attribute [reassoc] mul_comul' one_comul' mul_counit' one_counit' + +variable (M : C) [Bimon_Class M] + +@[reassoc (attr := simp)] +theorem mul_comul (M : C) [Bimon_Class M] : + μ[M] ≫ Δ[M] = (Δ[M] ⊗ Δ[M]) ≫ tensor_μ M M M M ≫ (μ[M] ⊗ μ[M]) := + mul_comul' + +@[reassoc (attr := simp)] +theorem one_comul (M : C) [Bimon_Class M] : η[M] ≫ Δ[M] = η[M ⊗ M] := one_comul' + +@[reassoc (attr := simp)] +theorem mul_counit (M : C) [Bimon_Class M] : μ[M] ≫ ε[M] = ε[M ⊗ M] := mul_counit' + +@[reassoc (attr := simp)] +theorem one_counit (M : C) [Bimon_Class M] : η[M] ≫ ε[M] = 𝟙 (𝟙_ C) := one_counit' + +end Bimon_Class + +variable (C) /-- A bimonoid object in a braided category `C` is a comonoid object in the (monoidal) diff --git a/Mathlib/CategoryTheory/Monoidal/Comon_.lean b/Mathlib/CategoryTheory/Monoidal/Comon_.lean index 498a20b561c799..ff63ce4bbb0eb0 100644 --- a/Mathlib/CategoryTheory/Monoidal/Comon_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Comon_.lean @@ -29,7 +29,49 @@ universe v₁ v₂ u₁ u₂ u open CategoryTheory MonoidalCategory -variable (C : Type u₁) [Category.{v₁} C] [MonoidalCategory.{v₁} C] +variable {C : Type u₁} [Category.{v₁} C] [MonoidalCategory.{v₁} C] + +/-- A comonoid object internal to a monoidal category. + +When the monoidal category is preadditive, this is also sometimes called a "coalgebra object". +-/ +class Comon_Class (X : C) where + /-- The counit morphism of a comonoid object. -/ + counit : X ⟶ 𝟙_ C + /-- The comultiplication morphism of a comonoid object. -/ + comul : X ⟶ X ⊗ X + /- For the names of the conditions below, the unprimed names are reserved for the version where + the argument `X` is explicit. -/ + counit_comul' : comul ≫ counit ▷ X = (λ_ X).inv := by aesop_cat + comul_counit' : comul ≫ X ◁ counit = (ρ_ X).inv := by aesop_cat + comul_assoc' : comul ≫ X ◁ comul = comul ≫ (comul ▷ X) ≫ (α_ X X X).hom := by aesop_cat + +namespace Comon_Class + +@[inherit_doc] scoped notation "Δ" => Comon_Class.comul +@[inherit_doc] scoped notation "Δ["M"]" => Comon_Class.comul (X := M) +@[inherit_doc] scoped notation "ε" => Comon_Class.counit +@[inherit_doc] scoped notation "ε["M"]" => Comon_Class.counit (X := M) + +/- The simp attribute is reserved for the unprimed versions. -/ +attribute [reassoc] counit_comul' comul_counit' comul_assoc' + +@[reassoc (attr := simp)] +theorem counit_comul (X : C) [Comon_Class X] : Δ ≫ ε ▷ X = (λ_ X).inv := counit_comul' + +@[reassoc (attr := simp)] +theorem comul_counit (X : C) [Comon_Class X] : Δ ≫ X ◁ ε = (ρ_ X).inv := comul_counit' + +@[reassoc (attr := simp)] +theorem comul_assoc (X : C) [Comon_Class X] : + Δ ≫ X ◁ Δ = Δ ≫ Δ ▷ X ≫ (α_ X X X).hom := + comul_assoc' + +end Comon_Class + +open scoped Comon_Class + +variable (C) /-- A comonoid object internal to a monoidal category. @@ -52,6 +94,24 @@ attribute [reassoc (attr := simp)] Comon_.comul_assoc namespace Comon_ +variable {C} + +/-- Construct an object of `Comon_ C` from an object `X : C` and `Comon_Class X` instance. -/ +@[simps] +def mk' (X : C) [Comon_Class X] : Comon_ C where + X := X + counit := ε + comul := Δ + +instance {M : Comon_ C} : Comon_Class M.X where + counit := M.counit + comul := M.comul + counit_comul' := M.counit_comul + comul_counit' := M.comul_counit + comul_assoc' := M.comul_assoc + +variable (C) + /-- The trivial comonoid object. We later show this is terminal in `Comon_ C`. -/ @[simps] @@ -251,6 +311,9 @@ variable [BraidedCategory C] theorem tensorObj_X (A B : Comon_ C) : (A ⊗ B).X = A.X ⊗ B.X := rfl +instance (A B : C) [Comon_Class A] [Comon_Class B] : Comon_Class (A ⊗ B) := + inferInstanceAs <| Comon_Class (Comon_.mk' A ⊗ Comon_.mk' B).X + theorem tensorObj_counit (A B : Comon_ C) : (A ⊗ B).counit = (A.counit ⊗ B.counit) ≫ (λ_ _).hom := rfl @@ -281,7 +344,7 @@ theorem tensorObj_comul (A B : Comon_ C) : /-- The forgetful functor from `Comon_ C` to `C` is monoidal when `C` is braided monoidal. -/ def forgetMonoidal : MonoidalFunctor (Comon_ C) C := { forget C with - ε := 𝟙 _ + «ε» := 𝟙 _ μ := fun _ _ => 𝟙 _ } @[simp] theorem forgetMonoidal_toFunctor : (forgetMonoidal C).toFunctor = forget C := rfl diff --git a/Mathlib/CategoryTheory/Monoidal/Hopf_.lean b/Mathlib/CategoryTheory/Monoidal/Hopf_.lean index 4bf50784e7cc78..e9e5220ef1ddcc 100644 --- a/Mathlib/CategoryTheory/Monoidal/Hopf_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Hopf_.lean @@ -22,7 +22,40 @@ universe v₁ v₂ u₁ u₂ u open CategoryTheory MonoidalCategory -variable (C : Type u₁) [Category.{v₁} C] [MonoidalCategory.{v₁} C] [BraidedCategory C] +variable {C : Type u₁} [Category.{v₁} C] [MonoidalCategory.{v₁} C] [BraidedCategory C] + +open scoped Mon_Class Comon_Class + +/-- +A Hopf monoid in a braided category `C` is a bimonoid object in `C` equipped with an antipode. +-/ +class Hopf_Class (X : C) extends Bimon_Class X where + /-- The antipode is an endomorphism of the underlying object of the Hopf monoid. -/ + antipode : X ⟶ X + /- For the names of the conditions below, the unprimed names are reserved for the version where + the argument `X` is explicit. -/ + antipode_left' : Δ ≫ antipode ▷ X ≫ μ = ε ≫ η := by aesop_cat + antipode_right' : Δ ≫ X ◁ antipode ≫ μ = ε ≫ η := by aesop_cat + +namespace Hopf_Class + +@[inherit_doc] scoped notation "𝒮" => Hopf_Class.antipode +@[inherit_doc] scoped notation "𝒮["X"]" => Hopf_Class.antipode (X := X) + +/- The simp attribute is reserved for the unprimed versions. -/ +attribute [reassoc] antipode_left' antipode_right' + +/-- The object is provided as an explicit argument. -/ +@[reassoc (attr := simp)] +theorem antipode_left (X : C) [Hopf_Class X] : Δ ≫ 𝒮 ▷ X ≫ μ = ε ≫ η := antipode_left' + +/-- The object is provided as an explicit argument. -/ +@[reassoc (attr := simp)] +theorem antipode_right (X : C) [Hopf_Class X] : Δ ≫ X ◁ 𝒮 ≫ μ = ε ≫ η := antipode_right' + +end Hopf_Class + +variable (C) /-- A Hopf monoid in a braided category `C` is a bimonoid object in `C` equipped with an antipode. diff --git a/Mathlib/CategoryTheory/Monoidal/Mon_.lean b/Mathlib/CategoryTheory/Monoidal/Mon_.lean index fc0cec7c2faf79..c04c4f4d55c076 100644 --- a/Mathlib/CategoryTheory/Monoidal/Mon_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Mon_.lean @@ -23,7 +23,51 @@ universe v₁ v₂ u₁ u₂ u open CategoryTheory MonoidalCategory -variable (C : Type u₁) [Category.{v₁} C] [MonoidalCategory.{v₁} C] +variable {C : Type u₁} [Category.{v₁} C] [MonoidalCategory.{v₁} C] + +/-- A monoid object internal to a monoidal category. + +When the monoidal category is preadditive, this is also sometimes called an "algebra object". +-/ +class Mon_Class (X : C) where + /-- The unit morphism of a monoid object. -/ + one : 𝟙_ C ⟶ X + /-- The multiplication morphism of a monoid object. -/ + mul : X ⊗ X ⟶ X + /- For the names of the conditions below, the unprimed names are reserved for the version where + the argument `X` is explicit. -/ + one_mul' : one ▷ X ≫ mul = (λ_ X).hom := by aesop_cat + mul_one' : X ◁ one ≫ mul = (ρ_ X).hom := by aesop_cat + -- Obviously there is some flexibility stating this axiom. + -- This one has left- and right-hand sides matching the statement of `Monoid.mul_assoc`, + -- and chooses to place the associator on the right-hand side. + -- The heuristic is that unitors and associators "don't have much weight". + mul_assoc' : (mul ▷ X) ≫ mul = (α_ X X X).hom ≫ (X ◁ mul) ≫ mul := by aesop_cat + +namespace Mon_Class + +@[inherit_doc] scoped notation "μ" => Mon_Class.mul +@[inherit_doc] scoped notation "μ["M"]" => Mon_Class.mul (X := M) +@[inherit_doc] scoped notation "η" => Mon_Class.one +@[inherit_doc] scoped notation "η["M"]" => Mon_Class.one (X := M) + +/- The simp attribute is reserved for the unprimed versions. -/ +attribute [reassoc] one_mul' mul_one' mul_assoc' + +@[reassoc (attr := simp)] +theorem one_mul (X : C) [Mon_Class X] : η ▷ X ≫ μ = (λ_ X).hom := one_mul' + +@[reassoc (attr := simp)] +theorem mul_one (X : C) [Mon_Class X] : X ◁ η ≫ μ = (ρ_ X).hom := mul_one' + +@[reassoc (attr := simp)] +theorem mul_assoc (X : C) [Mon_Class X] : μ ▷ X ≫ μ = (α_ X X X).hom ≫ X ◁ μ ≫ μ := mul_assoc' + +end Mon_Class + +open scoped Mon_Class + +variable (C) /-- A monoid object internal to a monoidal category. @@ -50,6 +94,24 @@ attribute [reassoc (attr := simp)] Mon_.mul_assoc namespace Mon_ +variable {C} + +/-- Construct an object of `Mon_ C` from an object `X : C` and `Mon_Class X` instance. -/ +@[simps] +def mk' (X : C) [Mon_Class X] : Mon_ C where + X := X + one := η + mul := μ + +instance {M : Mon_ C} : Mon_Class M.X where + one := M.one + mul := M.mul + one_mul' := M.one_mul + mul_one' := M.mul_one + mul_assoc' := M.mul_assoc + +variable (C) + /-- The trivial monoid object. We later show this is initial in `Mon_ C`. -/ @[simps] @@ -235,7 +297,7 @@ def monToLaxMonoidal : Mon_ C ⥤ LaxMonoidalFunctor (Discrete PUnit.{u + 1}) C { obj := fun _ => A.X map := fun _ => 𝟙 _ ε := A.one - μ := fun _ _ => A.mul } + «μ» := fun _ _ => A.mul } map f := { app := fun _ => f.hom } @@ -496,13 +558,17 @@ theorem tensor_mul (M N : Mon_ C) : (M ⊗ N).mul = instance monMonoidal : MonoidalCategory (Mon_ C) where tensorHom_def := by intros; ext; simp [tensorHom_def] +@[simps!] +instance {M N : C} [Mon_Class M] [Mon_Class N] : Mon_Class (M ⊗ N) := + inferInstanceAs <| Mon_Class (Mon_.mk' M ⊗ Mon_.mk' N).X + variable (C) /-- The forgetful functor from `Mon_ C` to `C` is monoidal when `C` is braided monoidal. -/ def forgetMonoidal : MonoidalFunctor (Mon_ C) C := { forget C with ε := 𝟙 _ - μ := fun _ _ => 𝟙 _ } + «μ» := fun _ _ => 𝟙 _ } @[simp] theorem forgetMonoidal_toFunctor : (forgetMonoidal C).toFunctor = forget C := rfl @[simp] theorem forgetMonoidal_ε : (forgetMonoidal C).ε = 𝟙 (𝟙_ C) := rfl From c6a02ffa70f93156c098b09f6b8d612ed1eb8a52 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Fri, 18 Oct 2024 16:20:05 +0000 Subject: [PATCH 388/425] chore: more `erw`s that can become `rw`s (#17923) Automatically found by the `erw` linter from #17638. --- Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean | 2 +- Mathlib/CategoryTheory/Shift/Basic.lean | 2 +- Mathlib/Condensed/Discrete/Colimit.lean | 4 ++-- Mathlib/Geometry/RingedSpace/OpenImmersion.lean | 4 ++-- Mathlib/Topology/Order/ScottTopology.lean | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean b/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean index cb15f1505053c7..abcc9d116cda02 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Reflexive.lean @@ -514,7 +514,7 @@ lemma mk_π {X : C} (π : F.obj zero ⟶ X) (h : F.map left ≫ π = F.map right (mk π h).π = π := rfl lemma condition (G : ReflexiveCofork F) : F.map left ≫ G.π = F.map right ≫ G.π := by - erw [Cocone.w G left, Cocone.w G right] + rw [Cocone.w G left, Cocone.w G right] @[simp] lemma app_one_eq_π (G : ReflexiveCofork F) : G.ι.app zero = G.π := rfl diff --git a/Mathlib/CategoryTheory/Shift/Basic.lean b/Mathlib/CategoryTheory/Shift/Basic.lean index 7acb86cbee29dc..889c3bf069f826 100644 --- a/Mathlib/CategoryTheory/Shift/Basic.lean +++ b/Mathlib/CategoryTheory/Shift/Basic.lean @@ -519,7 +519,7 @@ lemma shiftFunctorCompIsoId_add'_inv_app : dsimp [shiftFunctorCompIsoId] simp only [Functor.map_comp, Category.assoc] congr 1 - erw [← NatTrans.naturality] + rw [← NatTrans.naturality] dsimp rw [← cancel_mono ((shiftFunctorAdd' C p' p 0 hp).inv.app X), Iso.hom_inv_id_app, Category.assoc, Category.assoc, Category.assoc, Category.assoc, diff --git a/Mathlib/Condensed/Discrete/Colimit.lean b/Mathlib/Condensed/Discrete/Colimit.lean index 75f3c6ee7dfebd..9e6930f3aa8498 100644 --- a/Mathlib/Condensed/Discrete/Colimit.lean +++ b/Mathlib/Condensed/Discrete/Colimit.lean @@ -276,7 +276,7 @@ lemma isoLocallyConstantOfIsColimit_inv (X : Profinite.{u}ᵒᵖ ⥤ Type (u+1)) simp only [types_comp_apply, isoFinYoneda_inv_app, counitApp_app] apply presheaf_ext.{u, u+1} (X := X) (Y := X) (f := f) intro x - erw [incl_of_counitAppApp] + rw [incl_of_counitAppApp] simp only [counitAppAppImage, CompHausLike.coe_of] letI : Fintype (fiber.{u, u+1} f x) := Fintype.ofInjective (sigmaIncl.{u, u+1} f x).1 Subtype.val_injective @@ -551,7 +551,7 @@ lemma isoLocallyConstantOfIsColimit_inv (X : LightProfinite.{u}ᵒᵖ ⥤ Type u simp only [types_comp_apply, isoFinYoneda_inv_app, counitApp_app] apply presheaf_ext.{u, u} (X := X) (Y := X) (f := f) intro x - erw [incl_of_counitAppApp] + rw [incl_of_counitAppApp] simp only [counitAppAppImage, CompHausLike.coe_of] letI : Fintype (fiber.{u, u} f x) := Fintype.ofInjective (sigmaIncl.{u, u} f x).1 Subtype.val_injective diff --git a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean index 959214c2572955..11dbae9b63d30f 100644 --- a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean +++ b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean @@ -1120,8 +1120,8 @@ theorem lift_range (H' : Set.range g.base ⊆ Set.range f.base) : have : _ = (pullback.fst f g).base := PreservesPullback.iso_hom_fst (LocallyRingedSpace.forgetToSheafedSpace ⋙ SheafedSpace.forget _) f g - rw [LocallyRingedSpace.comp_base, ← this, ← Category.assoc, coe_comp] - rw [Set.range_comp, Set.range_iff_surjective.mpr, Set.image_univ] + rw [LocallyRingedSpace.comp_base, ← this, ← Category.assoc, coe_comp, Set.range_comp, + Set.range_iff_surjective.mpr, Set.image_univ] -- Porting note (#11224): change `rw` to `erw` on this lemma · erw [TopCat.pullback_fst_range] ext diff --git a/Mathlib/Topology/Order/ScottTopology.lean b/Mathlib/Topology/Order/ScottTopology.lean index 0a203e27ad7898..2a58f0caeeb475 100644 --- a/Mathlib/Topology/Order/ScottTopology.lean +++ b/Mathlib/Topology/Order/ScottTopology.lean @@ -177,7 +177,7 @@ variable {α D} lemma isOpen_iff [IsScottHausdorff α D] : IsOpen s ↔ ∀ ⦃d : Set α⦄, d ∈ D → d.Nonempty → DirectedOn (· ≤ ·) d → ∀ ⦃a : α⦄, IsLUB d a → - a ∈ s → ∃ b ∈ d, Ici b ∩ d ⊆ s := by erw [topology_eq_scottHausdorff (α := α) (D := D)]; rfl + a ∈ s → ∃ b ∈ d, Ici b ∩ d ⊆ s := by rw [topology_eq_scottHausdorff (α := α) (D := D)]; rfl lemma dirSupInaccOn_of_isOpen [IsScottHausdorff α D] (h : IsOpen s) : DirSupInaccOn D s := fun d hd₀ hd₁ hd₂ a hda hd₃ ↦ by @@ -241,7 +241,7 @@ lemma topology_eq [IsScott α D] : ‹_› = scott α D := topology_eq_scott variable {α} {D} {s : Set α} {a : α} lemma isOpen_iff_isUpperSet_and_scottHausdorff_open [IsScott α D] : - IsOpen s ↔ IsUpperSet s ∧ IsOpen[scottHausdorff α D] s := by erw [topology_eq α D]; rfl + IsOpen s ↔ IsUpperSet s ∧ IsOpen[scottHausdorff α D] s := by rw [topology_eq α D]; rfl lemma isOpen_iff_isUpperSet_and_dirSupInaccOn [IsScott α D] : IsOpen s ↔ IsUpperSet s ∧ DirSupInaccOn D s := by From 7b3afdd0e7374470ac2af311f49a06197ede6db1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 18 Oct 2024 16:28:16 +0000 Subject: [PATCH 389/425] feat: more lemmas about the size of pointwise sets (#17231) Complete the API and follow the convention that `Cardinal.mk` is called `card` and `Nat.card` is called `natCard` in lemma names. From LeanCamCombi --- Mathlib.lean | 1 + Mathlib/Algebra/Group/Pointwise/Set/Card.lean | 82 ++++++++++++------- .../GroupWithZero/Pointwise/Set/Card.lean | 27 ++++++ Mathlib/SetTheory/Cardinal/Basic.lean | 8 ++ 4 files changed, 89 insertions(+), 29 deletions(-) create mode 100644 Mathlib/Algebra/GroupWithZero/Pointwise/Set/Card.lean diff --git a/Mathlib.lean b/Mathlib.lean index 3c455bcceb7e97..b0b4fbb4d3724d 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -330,6 +330,7 @@ import Mathlib.Algebra.GroupWithZero.NonZeroDivisors import Mathlib.Algebra.GroupWithZero.Opposite import Mathlib.Algebra.GroupWithZero.Pi import Mathlib.Algebra.GroupWithZero.Pointwise.Set.Basic +import Mathlib.Algebra.GroupWithZero.Pointwise.Set.Card import Mathlib.Algebra.GroupWithZero.Prod import Mathlib.Algebra.GroupWithZero.Semiconj import Mathlib.Algebra.GroupWithZero.ULift diff --git a/Mathlib/Algebra/Group/Pointwise/Set/Card.lean b/Mathlib/Algebra/Group/Pointwise/Set/Card.lean index 341ed441df9323..80a073b792385c 100644 --- a/Mathlib/Algebra/Group/Pointwise/Set/Card.lean +++ b/Mathlib/Algebra/Group/Pointwise/Set/Card.lean @@ -3,60 +3,84 @@ 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 -/ -import Mathlib.Algebra.Group.Pointwise.Finset.Basic +import Mathlib.Data.Set.Pointwise.Finite import Mathlib.SetTheory.Cardinal.Finite /-! -# Cardinalities of pointwise operations on sets. +# Cardinalities of pointwise operations on sets -/ -namespace Set - -open Pointwise - -variable {α β : Type*} +open scoped Cardinal Pointwise -section MulAction -variable [Group α] [MulAction α β] +namespace Set +variable {G M α : Type*} -@[to_additive (attr := simp)] -lemma card_smul_set (a : α) (s : Set β) : Nat.card ↥(a • s) = Nat.card s := - Nat.card_image_of_injective (MulAction.injective a) _ +section Mul +variable [Mul M] {s t : Set M} -end MulAction +@[to_additive] +lemma _root_.Cardinal.mk_mul_le : #(s * t) ≤ #s * #t := by + rw [← image2_mul]; exact Cardinal.mk_image2_le -section IsCancelMul -variable [Mul α] [IsCancelMul α] {s t : Set α} +variable [IsCancelMul M] @[to_additive] -lemma card_mul_le : Nat.card (s * t) ≤ Nat.card s * Nat.card t := by - classical +lemma natCard_mul_le : Nat.card (s * t) ≤ Nat.card s * Nat.card t := by obtain h | h := (s * t).infinite_or_finite · simp [Set.Infinite.card_eq_zero h] - obtain ⟨hs, ht⟩ | rfl | rfl := finite_mul.1 h - · lift s to Finset α using hs - lift t to Finset α using ht - rw [← Finset.coe_mul] - simpa [-Finset.coe_mul] using Finset.card_mul_le - all_goals simp + simp only [Nat.card, ← Cardinal.toNat_mul] + refine Cardinal.toNat_le_toNat Cardinal.mk_mul_le ?_ + aesop (add simp [Cardinal.mul_lt_aleph0_iff, finite_mul]) + +@[to_additive (attr := deprecated (since := "2024-09-30"))] alias card_mul_le := natCard_mul_le -end IsCancelMul +end Mul section InvolutiveInv -variable [InvolutiveInv α] {s t : Set α} +variable [InvolutiveInv G] {s t : Set G} + +@[to_additive (attr := simp)] +lemma _root_.Cardinal.mk_inv (s : Set G) : #↥(s⁻¹) = #s := by + rw [← image_inv, Cardinal.mk_image_eq_of_injOn _ _ inv_injective.injOn] @[to_additive (attr := simp)] -lemma card_inv (s : Set α) : Nat.card ↥(s⁻¹) = Nat.card s := by +lemma natCard_inv (s : Set G) : Nat.card ↥(s⁻¹) = Nat.card s := by rw [← image_inv, Nat.card_image_of_injective inv_injective] +@[to_additive (attr := deprecated (since := "2024-09-30"))] alias card_inv := natCard_inv + end InvolutiveInv +section DivInvMonoid +variable [DivInvMonoid M] {s t : Set M} + +@[to_additive] +lemma _root_.Cardinal.mk_div_le : #(s / t) ≤ #s * #t := by + rw [← image2_div]; exact Cardinal.mk_image2_le + +end DivInvMonoid + section Group -variable [Group α] {s t : Set α} +variable [Group G] {s t : Set G} @[to_additive] -lemma card_div_le : Nat.card (s / t) ≤ Nat.card s * Nat.card t := by - rw [div_eq_mul_inv, ← card_inv t]; exact card_mul_le +lemma natCard_div_le : Nat.card (s / t) ≤ Nat.card s * Nat.card t := by + rw [div_eq_mul_inv, ← natCard_inv t]; exact natCard_mul_le + +@[to_additive (attr := deprecated (since := "2024-09-30"))] alias card_div_le := natCard_div_le + +variable [MulAction G α] + +@[to_additive (attr := simp)] +lemma _root_.Cardinal.mk_smul_set (a : G) (s : Set α) : #↥(a • s) = #s := + Cardinal.mk_image_eq_of_injOn _ _ (MulAction.injective a).injOn + +@[to_additive (attr := simp)] +lemma natCard_smul_set (a : G) (s : Set α) : Nat.card ↥(a • s) = Nat.card s := + Nat.card_image_of_injective (MulAction.injective a) _ + +@[to_additive (attr := deprecated (since := "2024-09-30"))] +alias card_smul_set := Cardinal.mk_smul_set end Group end Set diff --git a/Mathlib/Algebra/GroupWithZero/Pointwise/Set/Card.lean b/Mathlib/Algebra/GroupWithZero/Pointwise/Set/Card.lean new file mode 100644 index 00000000000000..8466c8876f1c1c --- /dev/null +++ b/Mathlib/Algebra/GroupWithZero/Pointwise/Set/Card.lean @@ -0,0 +1,27 @@ +/- +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 +-/ +import Mathlib.Algebra.Group.Pointwise.Set.Basic +import Mathlib.Algebra.GroupWithZero.Action.Basic +import Mathlib.SetTheory.Cardinal.Finite + +/-! +# Cardinality of sets under pointwise group with zero operations +-/ + +open scoped Cardinal Pointwise + +variable {G G₀ M M₀ : Type*} + +namespace Set +variable [GroupWithZero G₀] [Zero M₀] [MulActionWithZero G₀ M₀] {a : G₀} + +lemma _root_.Cardinal.mk_smul_set₀ (ha : a ≠ 0) (s : Set M₀) : #↥(a • s) = #s := + Cardinal.mk_image_eq_of_injOn _ _ (MulAction.injective₀ ha).injOn + +lemma natCard_smul_set₀ (ha : a ≠ 0) (s : Set M₀) : Nat.card ↥(a • s) = Nat.card s := + Nat.card_image_of_injective (MulAction.injective₀ ha) _ + +end Set diff --git a/Mathlib/SetTheory/Cardinal/Basic.lean b/Mathlib/SetTheory/Cardinal/Basic.lean index 22ec5d425d8c17..fcc9e9174c5c2b 100644 --- a/Mathlib/SetTheory/Cardinal/Basic.lean +++ b/Mathlib/SetTheory/Cardinal/Basic.lean @@ -1820,9 +1820,17 @@ theorem mk_emptyCollection_iff {α : Type u} {s : Set α} : #s = 0 ↔ s = ∅ : theorem mk_univ {α : Type u} : #(@univ α) = #α := mk_congr (Equiv.Set.univ α) +@[simp] lemma mk_setProd {α β : Type u} (s : Set α) (t : Set β) : #(s ×ˢ t) = #s * #t := by + rw [mul_def, mk_congr (Equiv.Set.prod ..)] + theorem mk_image_le {α β : Type u} {f : α → β} {s : Set α} : #(f '' s) ≤ #s := mk_le_of_surjective surjective_onto_image +lemma mk_image2_le {α β γ : Type u} {f : α → β → γ} {s : Set α} {t : Set β} : + #(image2 f s t) ≤ #s * #t := by + rw [← image_uncurry_prod, ← mk_setProd] + exact mk_image_le + theorem mk_image_le_lift {α : Type u} {β : Type v} {f : α → β} {s : Set α} : lift.{u} #(f '' s) ≤ lift.{v} #s := lift_mk_le.{0}.mpr ⟨Embedding.ofSurjective _ surjective_onto_image⟩ From 7e96f0c587bdf06977946b7227123bfd4ae81dc4 Mon Sep 17 00:00:00 2001 From: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:28:18 +0000 Subject: [PATCH 390/425] chore: remove unused open statements (#17899) --- Mathlib/Algebra/Group/EvenFunction.lean | 2 -- Mathlib/Algebra/Polynomial/Module/Basic.lean | 2 +- Mathlib/Analysis/Calculus/LogDeriv.lean | 2 +- Mathlib/Analysis/Normed/Group/Ultra.lean | 2 -- .../Analysis/SpecialFunctions/Trigonometric/Cotangent.lean | 4 ++-- Mathlib/Combinatorics/Additive/ErdosGinzburgZiv.lean | 1 - Mathlib/Combinatorics/SetFamily/KruskalKatona.lean | 2 +- Mathlib/Data/Nat/Choose/Lucas.lean | 2 +- Mathlib/GroupTheory/CosetCover.lean | 2 +- Mathlib/GroupTheory/GroupAction/Blocks.lean | 2 +- Mathlib/MeasureTheory/Measure/SeparableMeasure.lean | 2 +- Mathlib/ModelTheory/Algebra/Field/IsAlgClosed.lean | 2 +- Mathlib/NumberTheory/Fermat.lean | 1 - Mathlib/NumberTheory/JacobiSum/Basic.lean | 2 +- Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean | 2 +- Mathlib/NumberTheory/NumberField/Units/Regulator.lean | 2 +- Mathlib/Order/LiminfLimsup.lean | 2 +- Mathlib/Probability/Martingale/BorelCantelli.lean | 2 +- Mathlib/RingTheory/RootsOfUnity/Lemmas.lean | 2 +- 19 files changed, 16 insertions(+), 22 deletions(-) diff --git a/Mathlib/Algebra/Group/EvenFunction.lean b/Mathlib/Algebra/Group/EvenFunction.lean index 3896969ce67959..4713a0549c61fa 100644 --- a/Mathlib/Algebra/Group/EvenFunction.lean +++ b/Mathlib/Algebra/Group/EvenFunction.lean @@ -18,8 +18,6 @@ conflicting with the root-level definitions `Even` and `Odd` (which, for functio function takes even resp. odd _values_, a wholly different concept). -/ -open scoped BigOperators - namespace Function variable {α β : Type*} [Neg α] diff --git a/Mathlib/Algebra/Polynomial/Module/Basic.lean b/Mathlib/Algebra/Polynomial/Module/Basic.lean index 9a18a3951bc2ea..c22c4aea59f64a 100644 --- a/Mathlib/Algebra/Polynomial/Module/Basic.lean +++ b/Mathlib/Algebra/Polynomial/Module/Basic.lean @@ -14,7 +14,7 @@ This is defined as a type alias `PolynomialModule R M := ℕ →₀ M`, since th module structures on `ℕ →₀ M` of interest. See the docstring of `PolynomialModule` for details. -/ universe u v -open Polynomial BigOperators +open Polynomial /-- The `R[X]`-module `M[X]` for an `R`-module `M`. This is isomorphic (as an `R`-module) to `M[X]` when `M` is a ring. diff --git a/Mathlib/Analysis/Calculus/LogDeriv.lean b/Mathlib/Analysis/Calculus/LogDeriv.lean index 495f3de5c2775b..7b8a8970a06f36 100644 --- a/Mathlib/Analysis/Calculus/LogDeriv.lean +++ b/Mathlib/Analysis/Calculus/LogDeriv.lean @@ -17,7 +17,7 @@ noncomputable section open Filter Function -open scoped Topology BigOperators Classical +open scoped Topology Classical variable {𝕜 𝕜': Type*} [NontriviallyNormedField 𝕜] [NontriviallyNormedField 𝕜'] [NormedAlgebra 𝕜 𝕜'] diff --git a/Mathlib/Analysis/Normed/Group/Ultra.lean b/Mathlib/Analysis/Normed/Group/Ultra.lean index 2b8c5f341691f3..8881f035276fbd 100644 --- a/Mathlib/Analysis/Normed/Group/Ultra.lean +++ b/Mathlib/Analysis/Normed/Group/Ultra.lean @@ -33,8 +33,6 @@ ultrametric, nonarchimedean -/ open Metric NNReal -open scoped BigOperators - namespace IsUltrametricDist section Group diff --git a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean index d9d5e56fb97ef7..1db8bfb1259ff5 100644 --- a/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean +++ b/Mathlib/Analysis/SpecialFunctions/Trigonometric/Cotangent.lean @@ -11,9 +11,9 @@ import Mathlib.Analysis.Complex.UpperHalfPlane.Exp This file contains lemmas about the cotangent function, including useful series expansions. -/ -open Real Complex BigOperators Filter +open Real Complex -open scoped UpperHalfPlane Topology +open scoped UpperHalfPlane lemma Complex.cot_eq_exp_ratio (z : ℂ) : cot z = (Complex.exp (2 * I * z) + 1) / (I * (1 - Complex.exp (2 * I * z))) := by diff --git a/Mathlib/Combinatorics/Additive/ErdosGinzburgZiv.lean b/Mathlib/Combinatorics/Additive/ErdosGinzburgZiv.lean index a3bad041f207ed..164ae582fd7595 100644 --- a/Mathlib/Combinatorics/Additive/ErdosGinzburgZiv.lean +++ b/Mathlib/Combinatorics/Additive/ErdosGinzburgZiv.lean @@ -22,7 +22,6 @@ elements of sum zero. -/ open Finset MvPolynomial -open scoped BigOperators variable {ι : Type*} diff --git a/Mathlib/Combinatorics/SetFamily/KruskalKatona.lean b/Mathlib/Combinatorics/SetFamily/KruskalKatona.lean index 8b5ce0135fec7a..23daec75ae3d27 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 Finset Colex Nat UV -open scoped BigOperators FinsetFamily +open scoped FinsetFamily variable {α : Type*} [LinearOrder α] {s U V : Finset α} {n : ℕ} diff --git a/Mathlib/Data/Nat/Choose/Lucas.lean b/Mathlib/Data/Nat/Choose/Lucas.lean index 94e97c1f452af2..0df7d593456f8d 100644 --- a/Mathlib/Data/Nat/Choose/Lucas.lean +++ b/Mathlib/Data/Nat/Choose/Lucas.lean @@ -22,7 +22,7 @@ k_i` modulo `p`, where `n_i` and `k_i` are the base-`p` digits of `n` and `k`, r open Finset hiding choose -open Nat BigOperators Polynomial +open Nat Polynomial namespace Choose diff --git a/Mathlib/GroupTheory/CosetCover.lean b/Mathlib/GroupTheory/CosetCover.lean index a8ba591868ffa5..155e9fd467601a 100644 --- a/Mathlib/GroupTheory/CosetCover.lean +++ b/Mathlib/GroupTheory/CosetCover.lean @@ -42,7 +42,7 @@ set of all minimal polynomials (not proved here). -/ -open scoped Pointwise BigOperators +open scoped Pointwise namespace Subgroup diff --git a/Mathlib/GroupTheory/GroupAction/Blocks.lean b/Mathlib/GroupTheory/GroupAction/Blocks.lean index e88c5972e23aa6..cc63c90b25d163 100644 --- a/Mathlib/GroupTheory/GroupAction/Blocks.lean +++ b/Mathlib/GroupTheory/GroupAction/Blocks.lean @@ -43,7 +43,7 @@ We follow [wielandt1964]. -/ -open scoped BigOperators Pointwise +open scoped Pointwise namespace MulAction diff --git a/Mathlib/MeasureTheory/Measure/SeparableMeasure.lean b/Mathlib/MeasureTheory/Measure/SeparableMeasure.lean index 167c0d5bdfb539..cb0e5e2a0c352c 100644 --- a/Mathlib/MeasureTheory/Measure/SeparableMeasure.lean +++ b/Mathlib/MeasureTheory/Measure/SeparableMeasure.lean @@ -63,7 +63,7 @@ written `≠ ∞` rather than `< ∞`. See `Ne.lt_top` and `ne_of_lt` to switch separable measure, measure-dense, Lp space, second-countable -/ -open MeasurableSpace Set ENNReal TopologicalSpace BigOperators symmDiff Filter Real +open MeasurableSpace Set ENNReal TopologicalSpace symmDiff Real namespace MeasureTheory diff --git a/Mathlib/ModelTheory/Algebra/Field/IsAlgClosed.lean b/Mathlib/ModelTheory/Algebra/Field/IsAlgClosed.lean index 2d7efbda8ea354..54708abe18b61c 100644 --- a/Mathlib/ModelTheory/Algebra/Field/IsAlgClosed.lean +++ b/Mathlib/ModelTheory/Algebra/Field/IsAlgClosed.lean @@ -49,7 +49,7 @@ namespace FirstOrder namespace Field -open Ring FreeCommRing BigOperators Polynomial Language +open 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 diff --git a/Mathlib/NumberTheory/Fermat.lean b/Mathlib/NumberTheory/Fermat.lean index c90f62582cae85..0e3ab436b24145 100644 --- a/Mathlib/NumberTheory/Fermat.lean +++ b/Mathlib/NumberTheory/Fermat.lean @@ -26,7 +26,6 @@ for all natural numbers `n`. namespace Nat open Finset -open scoped BigOperators /-- Fermat numbers: the `n`-th Fermat number is defined as `2^(2^n) + 1`. -/ def fermatNumber (n : ℕ) : ℕ := 2 ^ (2 ^ n) + 1 diff --git a/Mathlib/NumberTheory/JacobiSum/Basic.lean b/Mathlib/NumberTheory/JacobiSum/Basic.lean index a936f799462cac..7e6fd3e597e49f 100644 --- a/Mathlib/NumberTheory/JacobiSum/Basic.lean +++ b/Mathlib/NumberTheory/JacobiSum/Basic.lean @@ -28,7 +28,7 @@ but generalize where appropriate. This is based on Lean code written as part of the bachelor's thesis of Alexander Spahl. -/ -open BigOperators Finset +open Finset /-! ### Jacobi sums: definition and first properties diff --git a/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean b/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean index 4970ba0001a5ad..cc34b948b40e0a 100644 --- a/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean +++ b/Mathlib/NumberTheory/NumberField/Units/DirichletTheorem.lean @@ -40,7 +40,7 @@ open scoped NumberField noncomputable section -open NumberField NumberField.InfinitePlace NumberField.Units BigOperators +open NumberField NumberField.InfinitePlace NumberField.Units variable (K : Type*) [Field K] diff --git a/Mathlib/NumberTheory/NumberField/Units/Regulator.lean b/Mathlib/NumberTheory/NumberField/Units/Regulator.lean index 34d7ce23394912..cd7cb76b5bf075 100644 --- a/Mathlib/NumberTheory/NumberField/Units/Regulator.lean +++ b/Mathlib/NumberTheory/NumberField/Units/Regulator.lean @@ -32,7 +32,7 @@ namespace NumberField.Units variable (K : Type*) [Field K] -open MeasureTheory Classical BigOperators NumberField.InfinitePlace +open MeasureTheory Classical NumberField.InfinitePlace NumberField NumberField.Units.dirichletUnitTheorem variable [NumberField K] diff --git a/Mathlib/Order/LiminfLimsup.lean b/Mathlib/Order/LiminfLimsup.lean index 0d6faea4d46f66..300e1d0160937d 100644 --- a/Mathlib/Order/LiminfLimsup.lean +++ b/Mathlib/Order/LiminfLimsup.lean @@ -285,7 +285,7 @@ end Relation section add_and_sum -open Filter BigOperators Set +open Filter Set variable {α : Type*} {f : Filter α} variable {R : Type*} diff --git a/Mathlib/Probability/Martingale/BorelCantelli.lean b/Mathlib/Probability/Martingale/BorelCantelli.lean index 4897ac3d82a8ea..0f483a8596a0b7 100644 --- a/Mathlib/Probability/Martingale/BorelCantelli.lean +++ b/Mathlib/Probability/Martingale/BorelCantelli.lean @@ -34,7 +34,7 @@ and `ProbabilityTheory.measure_limsup_eq_one` for the second (which does). open Filter -open scoped NNReal ENNReal MeasureTheory ProbabilityTheory BigOperators Topology +open scoped NNReal ENNReal MeasureTheory ProbabilityTheory Topology namespace MeasureTheory diff --git a/Mathlib/RingTheory/RootsOfUnity/Lemmas.lean b/Mathlib/RingTheory/RootsOfUnity/Lemmas.lean index e6fded4815f544..33d3afe29785af 100644 --- a/Mathlib/RingTheory/RootsOfUnity/Lemmas.lean +++ b/Mathlib/RingTheory/RootsOfUnity/Lemmas.lean @@ -23,7 +23,7 @@ variable {R : Type*} [CommRing R] [IsDomain R] namespace IsPrimitiveRoot -open Finset Polynomial BigOperators +open Finset Polynomial /-- If `μ` is a primitive `n`th root of unity in `R`, then `∏(1≤k Date: Fri, 18 Oct 2024 16:28:19 +0000 Subject: [PATCH 391/425] chore: remove `CoeFun` instances where `FunLike` is available (#17900) During the port we found that `FunLike` is robust enough not to need an extra `CoeFun` shortcut. Let's see if that rule can be consistently applied to the whole of the library. There is still duplication between `FunLike` and `CoeFun` for `Grp`, `Mon`, `CommGrp` and `CommMon`, which will need a more thorough fix. See also #17866. This is the second half of #17870, and doesn't affect the benchmarks. --- Mathlib/Algebra/Algebra/Hom.lean | 2 -- Mathlib/Algebra/Algebra/NonUnitalHom.lean | 5 ----- Mathlib/Algebra/MonoidAlgebra/Defs.lean | 4 ++-- Mathlib/Algebra/Polynomial/Module/Basic.lean | 2 +- Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean | 3 --- Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean | 5 ----- Mathlib/LinearAlgebra/QuadraticForm/Basic.lean | 5 ----- Mathlib/MeasureTheory/OuterMeasure/Defs.lean | 3 --- Mathlib/ModelTheory/Basic.lean | 6 ------ Mathlib/ModelTheory/ElementaryMaps.lean | 3 --- Mathlib/Order/OmegaCompletePartialOrder.lean | 1 - Mathlib/Topology/Algebra/Module/Multilinear/Basic.lean | 3 --- Mathlib/Topology/Algebra/Module/WeakDual.lean | 5 ----- Mathlib/Topology/Connected/PathConnected.lean | 6 ------ Mathlib/Topology/Homeomorph.lean | 2 -- Mathlib/Topology/MetricSpace/Dilation.lean | 3 --- Mathlib/Topology/MetricSpace/DilationEquiv.lean | 3 --- 17 files changed, 3 insertions(+), 58 deletions(-) diff --git a/Mathlib/Algebra/Algebra/Hom.lean b/Mathlib/Algebra/Algebra/Hom.lean index 55dcdc81a91cb8..5c5eac38616b58 100644 --- a/Mathlib/Algebra/Algebra/Hom.lean +++ b/Mathlib/Algebra/Algebra/Hom.lean @@ -85,8 +85,6 @@ section Semiring variable [CommSemiring R] [Semiring A] [Semiring B] [Semiring C] [Semiring D] variable [Algebra R A] [Algebra R B] [Algebra R C] [Algebra R D] --- Porting note: we don't port specialized `CoeFun` instances if there is `DFunLike` instead - instance funLike : FunLike (A →ₐ[R] B) A B where coe f := f.toFun coe_injective' f g h := by diff --git a/Mathlib/Algebra/Algebra/NonUnitalHom.lean b/Mathlib/Algebra/Algebra/NonUnitalHom.lean index 34a5518dc4de3d..7eb27b49ee74a2 100644 --- a/Mathlib/Algebra/Algebra/NonUnitalHom.lean +++ b/Mathlib/Algebra/Algebra/NonUnitalHom.lean @@ -156,11 +156,6 @@ variable [NonUnitalNonAssocSemiring A] [DistribMulAction R A] variable [NonUnitalNonAssocSemiring B] [DistribMulAction S B] variable [NonUnitalNonAssocSemiring C] [DistribMulAction T C] --- Porting note: Replaced with DFunLike instance --- /-- see Note [function coercion] -/ --- instance : CoeFun (A →ₙₐ[R] B) fun _ => A → B := --- ⟨toFun⟩ - instance : DFunLike (A →ₛₙₐ[φ] B) A fun _ => B where coe f := f.toFun coe_injective' := by rintro ⟨⟨⟨f, _⟩, _⟩, _⟩ ⟨⟨⟨g, _⟩, _⟩, _⟩ h; congr diff --git a/Mathlib/Algebra/MonoidAlgebra/Defs.lean b/Mathlib/Algebra/MonoidAlgebra/Defs.lean index 7125b7d636d97c..767b5198c52d89 100644 --- a/Mathlib/Algebra/MonoidAlgebra/Defs.lean +++ b/Mathlib/Algebra/MonoidAlgebra/Defs.lean @@ -86,7 +86,7 @@ instance MonoidAlgebra.instIsCancelAdd [IsCancelAdd k] : IsCancelAdd (MonoidAlge inferInstanceAs (IsCancelAdd (G →₀ k)) instance MonoidAlgebra.coeFun : CoeFun (MonoidAlgebra k G) fun _ => G → k := - Finsupp.instCoeFun + inferInstanceAs (CoeFun (G →₀ k) _) end @@ -823,7 +823,7 @@ instance instIsCancelAdd [IsCancelAdd k] : IsCancelAdd (AddMonoidAlgebra k G) := inferInstanceAs (IsCancelAdd (G →₀ k)) instance coeFun : CoeFun k[G] fun _ => G → k := - Finsupp.instCoeFun + inferInstanceAs (CoeFun (G →₀ k) _) end AddMonoidAlgebra diff --git a/Mathlib/Algebra/Polynomial/Module/Basic.lean b/Mathlib/Algebra/Polynomial/Module/Basic.lean index c22c4aea59f64a..047d5c7f868646 100644 --- a/Mathlib/Algebra/Polynomial/Module/Basic.lean +++ b/Mathlib/Algebra/Polynomial/Module/Basic.lean @@ -57,7 +57,7 @@ instance instFunLike : FunLike (PolynomialModule R M) ℕ M := Finsupp.instFunLike instance : CoeFun (PolynomialModule R M) fun _ => ℕ → M := - Finsupp.instCoeFun + inferInstanceAs <| CoeFun (_ →₀ _) _ theorem zero_apply (i : ℕ) : (0 : PolynomialModule R M) i = 0 := Finsupp.zero_apply diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean index 0849ae203d5a83..3dcf47e22249d9 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineEquiv.lean @@ -89,9 +89,6 @@ instance equivLike : EquivLike (P₁ ≃ᵃ[k] P₂) P₁ P₂ where right_inv f := f.right_inv coe_injective' _ _ h _ := toAffineMap_injective (DFunLike.coe_injective h) -instance : CoeFun (P₁ ≃ᵃ[k] P₂) fun _ => P₁ → P₂ := - DFunLike.hasCoeToFun - instance : CoeOut (P₁ ≃ᵃ[k] P₂) (P₁ ≃ P₂) := ⟨AffineEquiv.toEquiv⟩ diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean index edeab9e15af306..71f99e5c85dde4 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean @@ -67,11 +67,6 @@ instance AffineMap.instFunLike (k : Type*) {V1 : Type*} (P1 : Type*) {V2 : Type* apply vadd_right_cancel (f p) rw [← f_add, h, ← g_add] -instance AffineMap.hasCoeToFun (k : Type*) {V1 : Type*} (P1 : Type*) {V2 : Type*} (P2 : Type*) - [Ring k] [AddCommGroup V1] [Module k V1] [AffineSpace V1 P1] [AddCommGroup V2] [Module k V2] - [AffineSpace V2 P2] : CoeFun (P1 →ᵃ[k] P2) fun _ => P1 → P2 := - DFunLike.hasCoeToFun - namespace LinearMap variable {k : Type*} {V₁ : Type*} {V₂ : Type*} [Ring k] [AddCommGroup V₁] [Module k V₁] diff --git a/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean b/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean index fe2fe2b66dfe2a..39bc41327d5110 100644 --- a/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean +++ b/Mathlib/LinearAlgebra/QuadraticForm/Basic.lean @@ -161,11 +161,6 @@ instance instFunLike : FunLike (QuadraticMap R M N) M N where coe := toFun coe_injective' x y h := by cases x; cases y; congr -/-- Helper instance for when there's too many metavariables to apply -`DFunLike.hasCoeToFun` directly. -/ -instance : CoeFun (QuadraticMap R M N) fun _ => M → N := - ⟨DFunLike.coe⟩ - variable (Q) /-- The `simp` normal form for a quadratic map is `DFunLike.coe`, not `toFun`. -/ diff --git a/Mathlib/MeasureTheory/OuterMeasure/Defs.lean b/Mathlib/MeasureTheory/OuterMeasure/Defs.lean index e1169e732155e1..a776ff90e2c9cf 100644 --- a/Mathlib/MeasureTheory/OuterMeasure/Defs.lean +++ b/Mathlib/MeasureTheory/OuterMeasure/Defs.lean @@ -62,9 +62,6 @@ instance : FunLike (OuterMeasure α) (Set α) ℝ≥0∞ where coe m := m.measureOf coe_injective' | ⟨_, _, _, _⟩, ⟨_, _, _, _⟩, rfl => rfl -instance instCoeFun : CoeFun (OuterMeasure α) (fun _ => Set α → ℝ≥0∞) := - inferInstance - @[simp] theorem measureOf_eq_coe (m : OuterMeasure α) : m.measureOf = m := rfl instance : OuterMeasureClass (OuterMeasure α) α where diff --git a/Mathlib/ModelTheory/Basic.lean b/Mathlib/ModelTheory/Basic.lean index 6846aee6eb65c7..08419dda7c6f09 100644 --- a/Mathlib/ModelTheory/Basic.lean +++ b/Mathlib/ModelTheory/Basic.lean @@ -296,9 +296,6 @@ instance homClass : HomClass L (M →[L] N) M N where instance [L.IsAlgebraic] : StrongHomClass L (M →[L] N) M N := HomClass.strongHomClassOfIsAlgebraic -instance hasCoeToFun : CoeFun (M →[L] N) fun _ => M → N := - DFunLike.hasCoeToFun - @[simp] theorem toFun_eq_coe {f : M →[L] N} : f.toFun = (f : M → N) := rfl @@ -557,9 +554,6 @@ def symm (f : M ≃[L] N) : N ≃[L] M := refine (f.map_rel' r (f.toEquiv.symm ∘ x)).symm.trans ?_ rw [← Function.comp_assoc, Equiv.toFun_as_coe, Equiv.self_comp_symm, Function.id_comp] } -instance hasCoeToFun : CoeFun (M ≃[L] N) fun _ => M → N := - DFunLike.hasCoeToFun - @[simp] theorem symm_symm (f : M ≃[L] N) : f.symm.symm = f := diff --git a/Mathlib/ModelTheory/ElementaryMaps.lean b/Mathlib/ModelTheory/ElementaryMaps.lean index f774228f18d50d..a8c9fc27167187 100644 --- a/Mathlib/ModelTheory/ElementaryMaps.lean +++ b/Mathlib/ModelTheory/ElementaryMaps.lean @@ -67,9 +67,6 @@ instance instFunLike : FunLike (M ↪ₑ[L] N) M N where ext x exact funext_iff.1 h x -instance : CoeFun (M ↪ₑ[L] N) fun _ => M → N := - DFunLike.hasCoeToFun - @[simp] theorem map_boundedFormula (f : M ↪ₑ[L] N) {α : Type*} {n : ℕ} (φ : L.BoundedFormula α n) (v : α → M) (xs : Fin n → M) : φ.Realize (f ∘ v) (f ∘ xs) ↔ φ.Realize v xs := by diff --git a/Mathlib/Order/OmegaCompletePartialOrder.lean b/Mathlib/Order/OmegaCompletePartialOrder.lean index 0d7b0cf6a38043..179530a5796f41 100644 --- a/Mathlib/Order/OmegaCompletePartialOrder.lean +++ b/Mathlib/Order/OmegaCompletePartialOrder.lean @@ -72,7 +72,6 @@ variable [Preorder α] [Preorder β] [Preorder γ] instance : FunLike (Chain α) ℕ α := inferInstanceAs <| FunLike (ℕ →o α) ℕ α instance : OrderHomClass (Chain α) ℕ α := inferInstanceAs <| OrderHomClass (ℕ →o α) ℕ α -instance : CoeFun (Chain α) fun _ => ℕ → α := ⟨DFunLike.coe⟩ instance [Inhabited α] : Inhabited (Chain α) := ⟨⟨default, fun _ _ _ => le_rfl⟩⟩ diff --git a/Mathlib/Topology/Algebra/Module/Multilinear/Basic.lean b/Mathlib/Topology/Algebra/Module/Multilinear/Basic.lean index ad413d2ba21ae3..1a0a5179e33809 100644 --- a/Mathlib/Topology/Algebra/Module/Multilinear/Basic.lean +++ b/Mathlib/Topology/Algebra/Module/Multilinear/Basic.lean @@ -78,9 +78,6 @@ instance continuousMapClass : ContinuousMapClass (ContinuousMultilinearMap R M₁ M₂) (∀ i, M₁ i) M₂ where map_continuous := ContinuousMultilinearMap.cont -instance : CoeFun (ContinuousMultilinearMap R M₁ M₂) fun _ => (∀ i, M₁ i) → M₂ := - ⟨fun f => f⟩ - /-- 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 (L₁ : ContinuousMultilinearMap R M₁ M₂) (v : ∀ i, M₁ i) : M₂ := diff --git a/Mathlib/Topology/Algebra/Module/WeakDual.lean b/Mathlib/Topology/Algebra/Module/WeakDual.lean index 1a71efa833d83f..45e6b09628962f 100644 --- a/Mathlib/Topology/Algebra/Module/WeakDual.lean +++ b/Mathlib/Topology/Algebra/Module/WeakDual.lean @@ -102,11 +102,6 @@ instance instFunLike : FunLike (WeakDual 𝕜 E) E 𝕜 := instance instContinuousLinearMapClass : ContinuousLinearMapClass (WeakDual 𝕜 E) 𝕜 E 𝕜 := ContinuousLinearMap.continuousSemilinearMapClass -/-- Helper instance for when there's too many metavariables to apply `DFunLike.hasCoeToFun` -directly. -/ -instance : CoeFun (WeakDual 𝕜 E) fun _ => E → 𝕜 := - DFunLike.hasCoeToFun - /-- If a monoid `M` distributively continuously acts on `𝕜` and this action commutes with multiplication on `𝕜`, then it acts on `WeakDual 𝕜 E`. -/ instance instMulAction (M) [Monoid M] [DistribMulAction M 𝕜] [SMulCommClass 𝕜 M 𝕜] diff --git a/Mathlib/Topology/Connected/PathConnected.lean b/Mathlib/Topology/Connected/PathConnected.lean index 4cc61d6513e73a..93ef11a0f5e30c 100644 --- a/Mathlib/Topology/Connected/PathConnected.lean +++ b/Mathlib/Topology/Connected/PathConnected.lean @@ -85,12 +85,6 @@ instance Path.funLike : FunLike (Path x y) I X where instance Path.continuousMapClass : ContinuousMapClass (Path x y) I X where map_continuous γ := show Continuous γ.toContinuousMap by fun_prop --- Porting note: not necessary in light of the instance above -/- -instance : CoeFun (Path x y) fun _ => I → X := - ⟨fun p => p.toFun⟩ --/ - @[ext] protected theorem Path.ext : ∀ {γ₁ γ₂ : Path x y}, (γ₁ : I → X) = γ₂ → γ₁ = γ₂ := by rintro ⟨⟨x, h11⟩, h12, h13⟩ ⟨⟨x, h21⟩, h22, h23⟩ rfl diff --git a/Mathlib/Topology/Homeomorph.lean b/Mathlib/Topology/Homeomorph.lean index 09be530f7a37a9..c406c1e326c583 100644 --- a/Mathlib/Topology/Homeomorph.lean +++ b/Mathlib/Topology/Homeomorph.lean @@ -60,8 +60,6 @@ instance : EquivLike (X ≃ₜ Y) X Y where right_inv h := h.right_inv coe_injective' _ _ H _ := toEquiv_injective <| DFunLike.ext' H -instance : CoeFun (X ≃ₜ Y) fun _ ↦ X → Y := ⟨DFunLike.coe⟩ - @[simp] theorem homeomorph_mk_coe (a : X ≃ Y) (b c) : (Homeomorph.mk a b c : X → Y) = a := rfl diff --git a/Mathlib/Topology/MetricSpace/Dilation.lean b/Mathlib/Topology/MetricSpace/Dilation.lean index 2622d97a69454c..0ece9c35abd155 100644 --- a/Mathlib/Topology/MetricSpace/Dilation.lean +++ b/Mathlib/Topology/MetricSpace/Dilation.lean @@ -87,9 +87,6 @@ instance funLike : FunLike (α →ᵈ β) α β where instance toDilationClass : DilationClass (α →ᵈ β) α β where edist_eq' f := edist_eq' f -instance : CoeFun (α →ᵈ β) fun _ => α → β := - DFunLike.hasCoeToFun - @[simp] theorem toFun_eq_coe {f : α →ᵈ β} : f.toFun = (f : α → β) := rfl diff --git a/Mathlib/Topology/MetricSpace/DilationEquiv.lean b/Mathlib/Topology/MetricSpace/DilationEquiv.lean index d510cd58fb9e79..3fffba7e083051 100644 --- a/Mathlib/Topology/MetricSpace/DilationEquiv.lean +++ b/Mathlib/Topology/MetricSpace/DilationEquiv.lean @@ -60,9 +60,6 @@ instance : EquivLike (X ≃ᵈ Y) X Y where instance : DilationEquivClass (X ≃ᵈ Y) X Y where edist_eq' f := f.edist_eq' -instance : CoeFun (X ≃ᵈ Y) fun _ ↦ (X → Y) where - coe f := f - @[simp] theorem coe_toEquiv (e : X ≃ᵈ Y) : ⇑e.toEquiv = e := rfl @[ext] From 2178cceeb3452f1a474caa729442569a4646056d Mon Sep 17 00:00:00 2001 From: mathlib4-update-dependencies-bot <150093616+mathlib-bors@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:57:13 +0000 Subject: [PATCH 392/425] chore: update Mathlib dependencies 2024-10-18 (#17922) 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 b86cb2dfc481e7..c93ba44db832ee 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -15,7 +15,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "fa3d73a2cf077f4b14c7840352ac7b08aeb6eb41", + "rev": "1357f4f49450abb9dfd4783e38219f4ce84f9785", "name": "Qq", "manifestFile": "lake-manifest.json", "inputRev": "master", From 1ef8dd30084da1bb42462baaf2dbfcafc07701c9 Mon Sep 17 00:00:00 2001 From: Scott Carnahan <128885296+ScottCarnahan@users.noreply.github.com> Date: Fri, 18 Oct 2024 17:35:48 +0000 Subject: [PATCH 393/425] feat (RingTheory/HahnSeries/Summable) : singleton summable family (#16871) This PR defines a summable family made of a single Hahn series, and shows that the formal sum of the family is equal to the original Hahn series. --- Mathlib/RingTheory/HahnSeries/Summable.lean | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Mathlib/RingTheory/HahnSeries/Summable.lean b/Mathlib/RingTheory/HahnSeries/Summable.lean index 45a21761c48c32..a4a57ee6c16245 100644 --- a/Mathlib/RingTheory/HahnSeries/Summable.lean +++ b/Mathlib/RingTheory/HahnSeries/Summable.lean @@ -178,6 +178,19 @@ theorem hsum_add {s t : SummableFamily Γ R α} : (s + t).hsum = s.hsum + t.hsum simp only [hsum_coeff, add_coeff, add_apply] exact finsum_add_distrib (s.finite_co_support _) (t.finite_co_support _) +/-- The summable family made of a single Hahn series. -/ +@[simps] +def single (x : HahnSeries Γ R) : SummableFamily Γ R Unit where + toFun _ := x + isPWO_iUnion_support' := + Eq.mpr (congrArg (fun s ↦ s.IsPWO) (Set.iUnion_const x.support)) x.isPWO_support + finite_co_support' g := Set.toFinite {a | ((fun _ ↦ x) a).coeff g ≠ 0} + +@[simp] +theorem hsum_single (x : HahnSeries Γ R) : (single x).hsum = x := by + ext g + simp only [hsum_coeff, single_toFun, finsum_unique] + /-- A summable family induced by an equivalence of the parametrizing type. -/ @[simps] def Equiv (e : α ≃ β) (s : SummableFamily Γ R α) : SummableFamily Γ R β where From 75204348c7d435ac1d22d07c32f5d2836d9548ed Mon Sep 17 00:00:00 2001 From: Thmoas-Guan <150537269+Thmoas-Guan@users.noreply.github.com> Date: Fri, 18 Oct 2024 17:54:26 +0000 Subject: [PATCH 394/425] feat(FieldTheory/Galois): Finite galois subextensions (#16978) Define the type of finite Galois subextensions and prove basic properties about it. Co-authored-by: Yuyang Zhao Nailin Guan <3571819596@qq.com> Jujian Zhang Moves: - Mathlib.FieldTheory.Galois -> Mathlib.FieldTheory.Galois.Basic --- Mathlib.lean | 1 + Mathlib/FieldTheory/Galois/Infinite.lean | 214 +++++++++++++++++++++++ Mathlib/FieldTheory/KrullTopology.lean | 11 ++ Mathlib/FieldTheory/Normal.lean | 45 +++++ Mathlib/FieldTheory/NormalClosure.lean | 17 ++ 5 files changed, 288 insertions(+) create mode 100644 Mathlib/FieldTheory/Galois/Infinite.lean diff --git a/Mathlib.lean b/Mathlib.lean index b0b4fbb4d3724d..c66a3419a9aeb8 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2724,6 +2724,7 @@ import Mathlib.FieldTheory.Finite.Trace import Mathlib.FieldTheory.Finiteness import Mathlib.FieldTheory.Fixed import Mathlib.FieldTheory.Galois.Basic +import Mathlib.FieldTheory.Galois.Infinite import Mathlib.FieldTheory.IntermediateField.Algebraic import Mathlib.FieldTheory.IntermediateField.Basic import Mathlib.FieldTheory.IsAlgClosed.AlgebraicClosure diff --git a/Mathlib/FieldTheory/Galois/Infinite.lean b/Mathlib/FieldTheory/Galois/Infinite.lean new file mode 100644 index 00000000000000..d3c2345887e0d5 --- /dev/null +++ b/Mathlib/FieldTheory/Galois/Infinite.lean @@ -0,0 +1,214 @@ +/- +Copyright (c) 2024 Nailin Guan. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Nailin Guan, Yuyang Zhao, Jujian Zhang +-/ + +import Mathlib.Algebra.Category.Grp.FiniteGrp +import Mathlib.CategoryTheory.Category.Preorder +import Mathlib.FieldTheory.NormalClosure +import Mathlib.FieldTheory.SeparableClosure + +/-! + +# Main definitions and results + +In a field extension `K/k` + +* `FiniteGaloisIntermediateField` : The type of intermediate fields of `K/k` + that are finite and Galois over `k` + +* `adjoin` : The finite Galois intermediate field obtained from the normal closure of adjoining a + finite `s : Set K` to `k`. + +* `finGaloisGroup L` : The (finite) Galois group `Gal(L/k)` associated to a + `L : FiniteGaloisIntermediateField k K` `L`. + +* `finGaloisGroupMap` : For `FiniteGaloisIntermediateField` s `L₁` and `L₂` with `L₂ ≤ L₁` + giving the restriction of `Gal(L₁/k)` to `Gal(L₂/k)` + +* `finGaloisGroupFunctor` : Mapping `FiniteGaloisIntermediateField` ordered by inverse inclusion to + its corresponding Galois Group as `FiniteGrp`. + +# TODO + +* `FiniteGaloisIntermediateField` should be a `ConditionallyCompleteLattice` but isn't proved yet. + +-/ + +open CategoryTheory Opposite +open scoped IntermediateField + +variable (k K : Type*) [Field k] [Field K] [Algebra k K] + +/-- The type of intermediate fields of `K/k` that are finite and Galois over `k` -/ +structure FiniteGaloisIntermediateField extends IntermediateField k K where + [finiteDimensional : FiniteDimensional k toIntermediateField] + [isGalois : IsGalois k toIntermediateField] + +namespace FiniteGaloisIntermediateField + +instance : Coe (FiniteGaloisIntermediateField k K) (IntermediateField k K) where + coe := toIntermediateField + +instance : CoeSort (FiniteGaloisIntermediateField k K) (Type _) where + coe L := L.toIntermediateField + +instance (L : FiniteGaloisIntermediateField k K) : FiniteDimensional k L := + L.finiteDimensional + +instance (L : FiniteGaloisIntermediateField k K) : IsGalois k L := L.isGalois + +variable {k K} + +lemma val_injective : Function.Injective (toIntermediateField (k := k) (K := K)) := by + rintro ⟨⟩ ⟨⟩ eq + simpa only [mk.injEq] using eq + +/-- Turns the collection of finite Galois IntermediateFields of `K/k` into a lattice. -/ + +instance (L₁ L₂ : IntermediateField k K) [IsGalois k L₁] [IsGalois k L₂] : + IsGalois k ↑(L₁ ⊔ L₂) where + +instance (L₁ L₂ : IntermediateField k K) [FiniteDimensional k L₁] : + FiniteDimensional k ↑(L₁ ⊓ L₂) := + .of_injective (IntermediateField.inclusion inf_le_left).toLinearMap + (IntermediateField.inclusion inf_le_left).injective + +instance (L₁ L₂ : IntermediateField k K) [FiniteDimensional k L₂] : + FiniteDimensional k ↑(L₁ ⊓ L₂) := + .of_injective (IntermediateField.inclusion inf_le_right).toLinearMap + (IntermediateField.inclusion inf_le_right).injective + +instance (L₁ L₂ : IntermediateField k K) [Algebra.IsSeparable k L₁] : + Algebra.IsSeparable k ↑(L₁ ⊓ L₂) := + .of_algHom _ _ (IntermediateField.inclusion inf_le_left) + +instance (L₁ L₂ : IntermediateField k K) [Algebra.IsSeparable k L₂] : + Algebra.IsSeparable k ↑(L₁ ⊓ L₂) := + .of_algHom _ _ (IntermediateField.inclusion inf_le_right) + +instance (L₁ L₂ : IntermediateField k K) [IsGalois k L₁] [IsGalois k L₂] : + IsGalois k ↑(L₁ ⊓ L₂) where + +instance : Sup (FiniteGaloisIntermediateField k K) where + sup L₁ L₂ := .mk <| L₁ ⊔ L₂ + +instance : Inf (FiniteGaloisIntermediateField k K) where + inf L₁ L₂ := .mk <| L₁ ⊓ L₂ + +instance : Lattice (FiniteGaloisIntermediateField k K) := + val_injective.lattice _ (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) + +instance : OrderBot (FiniteGaloisIntermediateField k K) where + bot := .mk ⊥ + bot_le _ := bot_le (α := IntermediateField _ _) + +@[simp] +lemma le_iff (L₁ L₂ : FiniteGaloisIntermediateField k K) : + L₁ ≤ L₂ ↔ L₁.toIntermediateField ≤ L₂.toIntermediateField := + Iff.rfl + +variable (k) in +/-- The minimal (finite) Galois intermediate field containing a finite set `s : Set K` in a +Galois extension `K/k` defined as the the normal closure of the field obtained by adjoining +the set `s : Set K` to `k`. -/ +noncomputable def adjoin [IsGalois k K] (s : Set K) [Finite s] : + FiniteGaloisIntermediateField k K := { + normalClosure k (IntermediateField.adjoin k (s : Set K)) K with + finiteDimensional := + letI : FiniteDimensional k (IntermediateField.adjoin k (s : Set K)) := + IntermediateField.finiteDimensional_adjoin <| fun z _ => + IsAlgebraic.isIntegral (Algebra.IsAlgebraic.isAlgebraic z) + normalClosure.is_finiteDimensional k (IntermediateField.adjoin k (s : Set K)) K + isGalois := IsGalois.normalClosure k (IntermediateField.adjoin k (s : Set K)) K } + +@[simp] +lemma adjoin_val [IsGalois k K] (s : Set K) [Finite s] : + (FiniteGaloisIntermediateField.adjoin k s) = + normalClosure k (IntermediateField.adjoin k s) K := + rfl + +variable (k) in +lemma subset_adjoin [IsGalois k K] (s : Set K) [Finite s] : + s ⊆ (adjoin k s).toIntermediateField := + (IntermediateField.subset_adjoin k s).trans (IntermediateField.le_normalClosure _) + +theorem adjoin_simple_le_iff [IsGalois k K] {x : K} {L : FiniteGaloisIntermediateField k K} : + adjoin k {x} ≤ L ↔ x ∈ L.toIntermediateField := by + simp only [le_iff, adjoin_val, IntermediateField.normalClosure_le_iff_of_normal, + IntermediateField.adjoin_le_iff, Set.le_eq_subset, Set.singleton_subset_iff, SetLike.mem_coe] + +@[simp] +theorem adjoin_map [IsGalois k K] (f : K →ₐ[k] K) (s : Set K) [Finite s] : + adjoin k (f '' s) = adjoin k s := by + apply val_injective; dsimp [adjoin_val] + rw [← IntermediateField.adjoin_map, IntermediateField.normalClosure_map_eq] + +@[simp] +theorem adjoin_simple_map_algHom [IsGalois k K] (f : K →ₐ[k] K) (x : K) : + adjoin k {f x} = adjoin k {x} := by + simpa only [Set.image_singleton] using adjoin_map f { x } + +@[simp] +theorem adjoin_simple_map_algEquiv [IsGalois k K] (f : K ≃ₐ[k] K) (x : K) : + adjoin k {f x} = adjoin k {x} := + adjoin_simple_map_algHom (f : K →ₐ[k] K) x + +end FiniteGaloisIntermediateField + +section Profinite + +variable {k K} + +/-- The (finite) Galois group `Gal(L / k)` associated to a +`L : FiniteGaloisIntermediateField k K` `L`. -/ +def FiniteGaloisIntermediateField.finGaloisGroup (L : FiniteGaloisIntermediateField k K) : + FiniteGrp := + letI := AlgEquiv.fintype k L + FiniteGrp.of <| L ≃ₐ[k] L + +/-- For `FiniteGaloisIntermediateField` s `L₁` and `L₂` with `L₂ ≤ L₁` + the restriction homomorphism from `Gal(L₁/k)` to `Gal(L₂/k)` -/ +noncomputable def finGaloisGroupMap {L₁ L₂ : (FiniteGaloisIntermediateField k K)ᵒᵖ} + (le : L₁ ⟶ L₂) : L₁.unop.finGaloisGroup ⟶ L₂.unop.finGaloisGroup := + haveI : Normal k L₂.unop := IsGalois.to_normal + letI : Algebra L₂.unop L₁.unop := RingHom.toAlgebra (Subsemiring.inclusion <| leOfHom le.1) + haveI : IsScalarTower k L₂.unop L₁.unop := IsScalarTower.of_algebraMap_eq (congrFun rfl) + FiniteGrp.ofHom (AlgEquiv.restrictNormalHom L₂.unop) + +namespace finGaloisGroupMap + +@[simp] +lemma map_id (L : (FiniteGaloisIntermediateField k K)ᵒᵖ) : + (finGaloisGroupMap (𝟙 L)) = 𝟙 L.unop.finGaloisGroup := + AlgEquiv.restrictNormalHom_id _ _ + +@[simp] +lemma map_comp {L₁ L₂ L₃ : (FiniteGaloisIntermediateField k K)ᵒᵖ} (f : L₁ ⟶ L₂) (g : L₂ ⟶ L₃) : + finGaloisGroupMap (f ≫ g) = finGaloisGroupMap f ≫ finGaloisGroupMap g := by + iterate 2 + induction L₁ with | _ L₁ => ?_ + induction L₂ with | _ L₂ => ?_ + induction L₃ with | _ L₃ => ?_ + letI : Algebra L₃ L₂ := RingHom.toAlgebra (Subsemiring.inclusion g.unop.le) + letI : Algebra L₂ L₁ := RingHom.toAlgebra (Subsemiring.inclusion f.unop.le) + letI : Algebra L₃ L₁ := RingHom.toAlgebra (Subsemiring.inclusion (g.unop.le.trans f.unop.le)) + haveI : IsScalarTower k L₂ L₁ := IsScalarTower.of_algebraMap_eq' rfl + haveI : IsScalarTower k L₃ L₁ := IsScalarTower.of_algebraMap_eq' rfl + haveI : IsScalarTower k L₃ L₂ := IsScalarTower.of_algebraMap_eq' rfl + haveI : IsScalarTower L₃ L₂ L₁ := IsScalarTower.of_algebraMap_eq' rfl + apply IsScalarTower.AlgEquiv.restrictNormalHom_comp k L₃ L₂ L₁ + +end finGaloisGroupMap + +variable (k K) in +/-- The functor from `FiniteGaloisIntermediateField` (ordered by reverse inclusion) to `FiniteGrp`, +mapping each intermediate field `K/L/k` to `Gal (L/k)`.-/ +noncomputable def finGaloisGroupFunctor : (FiniteGaloisIntermediateField k K)ᵒᵖ ⥤ FiniteGrp where + obj L := L.unop.finGaloisGroup + map := finGaloisGroupMap + map_id := finGaloisGroupMap.map_id + map_comp := finGaloisGroupMap.map_comp + +end Profinite diff --git a/Mathlib/FieldTheory/KrullTopology.lean b/Mathlib/FieldTheory/KrullTopology.lean index 7f7f53c3109a78..c5751d36c7ff4b 100644 --- a/Mathlib/FieldTheory/KrullTopology.lean +++ b/Mathlib/FieldTheory/KrullTopology.lean @@ -178,6 +178,17 @@ instance krullTopology (K L : Type*) [Field K] [Field L] [Algebra K L] : instance (K L : Type*) [Field K] [Field L] [Algebra K L] : TopologicalGroup (L ≃ₐ[K] L) := GroupFilterBasis.isTopologicalGroup (galGroupBasis K L) +open scoped Topology in +lemma krullTopology_mem_nhds_one (K L : Type*) [Field K] [Field L] [Algebra K L] + (s : Set (L ≃ₐ[K] L)) : s ∈ 𝓝 1 ↔ ∃ E : IntermediateField K L, + FiniteDimensional K E ∧ (E.fixingSubgroup : Set (L ≃ₐ[K] L)) ⊆ s := by + rw [GroupFilterBasis.nhds_one_eq] + constructor + · rintro ⟨-, ⟨-, ⟨E, fin, rfl⟩, rfl⟩, hE⟩ + exact ⟨E, fin, hE⟩ + · rintro ⟨E, fin, hE⟩ + exact ⟨E.fixingSubgroup, ⟨E.fixingSubgroup, ⟨E, fin, rfl⟩, rfl⟩, hE⟩ + section KrullT2 open scoped Topology Filter diff --git a/Mathlib/FieldTheory/Normal.lean b/Mathlib/FieldTheory/Normal.lean index 98ae051a5fd577..242f0ef840a7d7 100644 --- a/Mathlib/FieldTheory/Normal.lean +++ b/Mathlib/FieldTheory/Normal.lean @@ -355,10 +355,55 @@ theorem AlgEquiv.restrict_liftNormal (χ : K₁ ≃ₐ[F] K₁) [Normal F K₁] (algebraMap K₁ E).injective (Eq.trans (AlgEquiv.restrictNormal_commutes _ K₁ x) (χ.liftNormal_commutes E x)) +/-- The group homomorphism given by restricting an algebra isomorphism to a normal subfield +is surjective. -/ theorem AlgEquiv.restrictNormalHom_surjective [Normal F K₁] [Normal F E] : Function.Surjective (AlgEquiv.restrictNormalHom K₁ : (E ≃ₐ[F] E) → K₁ ≃ₐ[F] K₁) := fun χ => ⟨χ.liftNormal E, χ.restrict_liftNormal E⟩ +/-- The group homomorphism given by restricting an algebra isomorphism to itself +is the identity map. -/ +@[simp] +theorem AlgEquiv.restrictNormalHom_id (F K : Type*) + [Field F] [Field K] [Algebra F K] [Normal F K] : + AlgEquiv.restrictNormalHom K = MonoidHom.id (K ≃ₐ[F] K) := by + ext f x + dsimp only [restrictNormalHom, MonoidHom.mk'_apply, MonoidHom.id_apply] + apply (algebraMap K K).injective + rw [AlgEquiv.restrictNormal_commutes] + simp only [Algebra.id.map_eq_id, RingHom.id_apply] + +namespace IsScalarTower + +/-- In a scalar tower `K₃/K₂/K₁/F` with `K₁` and `K₂` are normal over `F`, the group homomorphism +given by the restriction of algebra isomorphisms of `K₃` to `K₁` is equal to the composition of +the group homomorphism given by the restricting an algebra isomorphism of `K₃` to `K₂` and +the group homomorphism given by the restricting an algebra isomorphism of `K₂` to `K₁` -/ +theorem AlgEquiv.restrictNormalHom_comp (F K₁ K₂ K₃ : Type*) + [Field F] [Field K₁] [Field K₂] [Field K₃] + [Algebra F K₁] [Algebra F K₂] [Algebra F K₃] [Algebra K₁ K₂] [Algebra K₁ K₃] [Algebra K₂ K₃] + [IsScalarTower F K₁ K₃] [IsScalarTower F K₁ K₂] [IsScalarTower F K₂ K₃] [IsScalarTower K₁ K₂ K₃] + [Normal F K₁] [Normal F K₂] : + AlgEquiv.restrictNormalHom K₁ = + (AlgEquiv.restrictNormalHom K₁).comp + (AlgEquiv.restrictNormalHom (F := F) (K₁ := K₃) K₂) := by + ext f x + apply (algebraMap K₁ K₃).injective + rw [IsScalarTower.algebraMap_eq K₁ K₂ K₃] + simp only [AlgEquiv.restrictNormalHom, MonoidHom.mk'_apply, RingHom.coe_comp, Function.comp_apply, + ← algebraMap_apply, AlgEquiv.restrictNormal_commutes, MonoidHom.coe_comp] + +theorem AlgEquiv.restrictNormalHom_comp_apply (K₁ K₂ : Type*) {F K₃ : Type*} + [Field F] [Field K₁] [Field K₂] [Field K₃] + [Algebra F K₁] [Algebra F K₂] [Algebra F K₃] [Algebra K₁ K₂] [Algebra K₁ K₃] [Algebra K₂ K₃] + [IsScalarTower F K₁ K₃] [IsScalarTower F K₁ K₂] [IsScalarTower F K₂ K₃] [IsScalarTower K₁ K₂ K₃] + [Normal F K₁] [Normal F K₂] (f : K₃ ≃ₐ[F] K₃) : + AlgEquiv.restrictNormalHom K₁ f = + (AlgEquiv.restrictNormalHom K₁) (AlgEquiv.restrictNormalHom K₂ f) := by + rw [IsScalarTower.AlgEquiv.restrictNormalHom_comp F K₁ K₂ K₃, MonoidHom.comp_apply] + +end IsScalarTower + open IntermediateField in theorem Normal.minpoly_eq_iff_mem_orbit [h : Normal F E] {x y : E} : minpoly F x = minpoly F y ↔ x ∈ MulAction.orbit (E ≃ₐ[F] E) y := by diff --git a/Mathlib/FieldTheory/NormalClosure.lean b/Mathlib/FieldTheory/NormalClosure.lean index 680dc94bf87097..fac28822a66a53 100644 --- a/Mathlib/FieldTheory/NormalClosure.lean +++ b/Mathlib/FieldTheory/NormalClosure.lean @@ -282,4 +282,21 @@ lemma normal_iff_forall_map_eq : Normal F K ↔ ∀ σ : L →ₐ[F] L, K.map σ lemma normal_iff_forall_map_eq' : Normal F K ↔ ∀ σ : L ≃ₐ[F] L, K.map ↑σ = K := ⟨fun h σ ↦ normal_iff_forall_map_eq.1 h σ, fun h ↦ normal_iff_forall_map_le'.2 (fun σ ↦ (h σ).le)⟩ +@[simp] +lemma normalClosure_map_eq (K : IntermediateField F L) (σ : L →ₐ[F] L) : + normalClosure F (K.map σ) L = normalClosure F K L := by + have (σ : L ≃ₐ[F] L) : normalClosure F (K.map (σ : L →ₐ[F] L)) L = normalClosure F K L := by + simp_rw [normalClosure_def'', map_map] + exact (Equiv.mulRight σ).iSup_congr fun _ ↦ rfl + exact this ((Algebra.IsAlgebraic.algEquivEquivAlgHom _ _).symm σ) + +@[simp] +theorem normalClosure_le_iff_of_normal {K₁ K₂ : IntermediateField F L} [Normal F K₂] : + normalClosure F K₁ L ≤ K₂ ↔ K₁ ≤ K₂ := by + refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ + · rw [normalClosure_le_iff] at h + simpa only [fieldRange_val] using h K₁.val + · rw [← normalClosure_of_normal K₂] + exact normalClosure_mono K₁ K₂ h + end IntermediateField From 8610319f04e6b637e3c597905fa5cb405e5549fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Fri, 18 Oct 2024 18:06:40 +0000 Subject: [PATCH 395/425] =?UTF-8?q?doc(SetTheory/Game/PGame):=20expand=20d?= =?UTF-8?q?ocstrings=20for=20`=E2=89=A4`=20and=20`=E2=A7=8F`=20(#16809)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Mathlib/SetTheory/Game/PGame.lean | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Mathlib/SetTheory/Game/PGame.lean b/Mathlib/SetTheory/Game/PGame.lean index afa7e0b2209179..83f9d1f8d25599 100644 --- a/Mathlib/SetTheory/Game/PGame.lean +++ b/Mathlib/SetTheory/Game/PGame.lean @@ -23,6 +23,9 @@ takes two types (thought of as indexing the possible moves for the players Left pair of functions out of these types to `SetTheory.PGame` (thought of as describing the resulting game after making a move). +We may denote a game as $\{L | R\}$, where $L$ and $R$ stand for the collections of left and right +moves. This notation is not currently used in Mathlib. + Combinatorial games themselves, as a quotient of pregames, are constructed in `Game.lean`. ## Conway induction @@ -349,15 +352,17 @@ instance isEmpty_one_rightMoves : IsEmpty (RightMoves 1) := /-- The less or equal relation on pre-games. -If `0 ≤ x`, then Left can win `x` as the second player. -/ +If `0 ≤ x`, then Left can win `x` as the second player. `x ≤ y` means that `0 ≤ y - x`. +See `PGame.le_iff_sub_nonneg`. -/ instance le : LE PGame := ⟨Sym2.GameAdd.fix wf_isOption fun x y le => (∀ i, ¬le y (x.moveLeft i) (Sym2.GameAdd.snd_fst <| IsOption.moveLeft i)) ∧ ∀ j, ¬le (y.moveRight j) x (Sym2.GameAdd.fst_snd <| IsOption.moveRight j)⟩ -/-- The less or fuzzy relation on pre-games. +/-- The less or fuzzy relation on pre-games. `x ⧏ y` is defined as `¬ y ≤ x`. -If `0 ⧏ x`, then Left can win `x` as the first player. -/ +If `0 ⧏ x`, then Left can win `x` as the first player. `x ⧏ y` means that `0 ⧏ y - x`. +See `PGame.lf_iff_sub_zero_lf`. -/ def LF (x y : PGame) : Prop := ¬y ≤ x From df601e35b5257a5c391ee5ca5648201c4f46cc78 Mon Sep 17 00:00:00 2001 From: David Kurniadi Angdinata Date: Fri, 18 Oct 2024 18:31:29 +0000 Subject: [PATCH 396/425] feat(AlgebraicGeometry/EllipticCurve/Projective): implement group operations on point representatives for projective coordinates (#9418) Define the analogous secant-and-tangent negation `neg` and addition `add` on `PointRep` over `F`, and lift them to `PointClass`. Define `Point` as a `PointClass` that is nonsingular. Prove in `neg_equiv` and `add_equiv` that these operations preserve the equivalence. Prove in `nonsingular_neg` and `nonsingular_add` that these operations preserve nonsingularity by reducing it to the affine case, and lift these proofs to `PointClass`. This is the third in a series of four PRs leading to #8485 --- .../EllipticCurve/Projective.lean | 282 +++++++++++++++++- scripts/no_lints_prime_decls.txt | 1 + 2 files changed, 282 insertions(+), 1 deletion(-) diff --git a/Mathlib/AlgebraicGeometry/EllipticCurve/Projective.lean b/Mathlib/AlgebraicGeometry/EllipticCurve/Projective.lean index 3d4ea8337acc9a..00a1a91f99235b 100644 --- a/Mathlib/AlgebraicGeometry/EllipticCurve/Projective.lean +++ b/Mathlib/AlgebraicGeometry/EllipticCurve/Projective.lean @@ -14,7 +14,8 @@ import Mathlib.Tactic.LinearCombination' This file defines the type of points on a Weierstrass curve as a tuple, consisting of an equivalence class of triples up to scaling by a unit, satisfying a Weierstrass equation with a nonsingular -condition. +condition. This file also defines the negation and addition operations of the group law for this +type, and proves that they respect the Weierstrass equation and the nonsingular condition. ## Mathematical background @@ -32,6 +33,7 @@ given by a tuple consisting of $[x:y:z]$ and the nonsingular condition on any re As in `Mathlib.AlgebraicGeometry.EllipticCurve.Affine`, the set of nonsingular rational points forms an abelian group under the same secant-and-tangent process, but the polynomials involved are homogeneous, and any instances of division become multiplication in the $Z$-coordinate. +Note that most computational proofs follow from their analogous proofs for affine coordinates. ## Main definitions @@ -39,10 +41,16 @@ homogeneous, and any instances of division become multiplication in the $Z$-coor * `WeierstrassCurve.Projective.toAffine`: the Weierstrass curve in affine coordinates. * `WeierstrassCurve.Projective.Nonsingular`: the nonsingular condition on a point representative. * `WeierstrassCurve.Projective.NonsingularLift`: the nonsingular condition on a point class. + * `WeierstrassCurve.Projective.neg`: the negation operation on a point representative. + * `WeierstrassCurve.Projective.negMap`: the negation operation on a point class. + * `WeierstrassCurve.Projective.add`: the addition operation on a point representative. + * `WeierstrassCurve.Projective.addMap`: the addition operation on a point class. ## Main statements * `WeierstrassCurve.Projective.polynomial_relation`: Euler's homogeneous function theorem. + * `WeierstrassCurve.Projective.nonsingular_neg`: negation preserves the nonsingular condition. + * `WeierstrassCurve.Projective.nonsingular_add`: addition preserves the nonsingular condition. ## Implementation notes @@ -138,6 +146,11 @@ lemma smul_equiv (P : Fin 3 → R) {u : R} (hu : IsUnit u) : u • P ≈ P := lemma smul_eq (P : Fin 3 → R) {u : R} (hu : IsUnit u) : (⟦u • P⟧ : PointClass R) = ⟦P⟧ := Quotient.eq.mpr <| smul_equiv P hu +lemma smul_equiv_smul (P Q : Fin 3 → R) {u v : R} (hu : IsUnit u) (hv : IsUnit v) : + u • P ≈ v • Q ↔ P ≈ Q := by + erw [← Quotient.eq_iff_equiv, ← Quotient.eq_iff_equiv, smul_eq P hu, smul_eq Q hv] + rfl + variable (W') in /-- The coercion to a Weierstrass curve in affine coordinates. -/ abbrev toAffine : Affine R := @@ -1163,4 +1176,271 @@ lemma addXYZ_of_Z_ne_zero {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equati end Addition +section Negation + +/-! ### Negation on point representatives -/ + +variable (W') in +/-- The negation of a point representative. -/ +def neg (P : Fin 3 → R) : Fin 3 → R := + ![P x, W'.negY P, P z] + +lemma neg_X (P : Fin 3 → R) : W'.neg P x = P x := + rfl + +lemma neg_Y (P : Fin 3 → R) : W'.neg P y = W'.negY P := + rfl + +lemma neg_Z (P : Fin 3 → R) : W'.neg P z = P z := + rfl + +lemma neg_smul (P : Fin 3 → R) (u : R) : W'.neg (u • P) = u • W'.neg P := by + simpa only [neg, negY_smul] using (smul_fin3 (W'.neg P) u).symm + +lemma neg_smul_equiv (P : Fin 3 → R) {u : R} (hu : IsUnit u) : W'.neg (u • P) ≈ W'.neg P := + ⟨hu.unit, (neg_smul ..).symm⟩ + +lemma neg_equiv {P Q : Fin 3 → R} (h : P ≈ Q) : W'.neg P ≈ W'.neg Q := by + rcases h with ⟨u, rfl⟩ + exact neg_smul_equiv Q u.isUnit + +lemma neg_of_Z_eq_zero [NoZeroDivisors R] {P : Fin 3 → R} (hP : W'.Equation P) (hPz : P z = 0) : + W'.neg P = -P y • ![0, 1, 0] := by + erw [neg, X_eq_zero_of_Z_eq_zero hP hPz, negY_of_Z_eq_zero hP hPz, hPz, smul_fin3, mul_zero, + mul_one] + +lemma neg_of_Z_ne_zero {P : Fin 3 → F} (hPz : P z ≠ 0) : + W.neg P = P z • ![P x / P z, W.toAffine.negY (P x / P z) (P y / P z), 1] := by + erw [neg, smul_fin3, mul_div_cancel₀ _ hPz, ← negY_of_Z_ne_zero hPz, mul_div_cancel₀ _ hPz, + mul_one] + +private lemma nonsingular_neg_of_Z_ne_zero {P : Fin 3 → F} (hP : W.Nonsingular P) (hPz : P z ≠ 0) : + W.Nonsingular ![P x / P z, W.toAffine.negY (P x / P z) (P y / P z), 1] := + (nonsingular_some ..).mpr <| Affine.nonsingular_neg <| (nonsingular_of_Z_ne_zero hPz).mp hP + +lemma nonsingular_neg {P : Fin 3 → F} (hP : W.Nonsingular P) : W.Nonsingular <| W.neg P := by + by_cases hPz : P z = 0 + · simp only [neg_of_Z_eq_zero hP.left hPz, nonsingular_smul _ (isUnit_Y_of_Z_eq_zero hP hPz).neg, + nonsingular_zero] + · simp only [neg_of_Z_ne_zero hPz, nonsingular_smul _ <| Ne.isUnit hPz, + nonsingular_neg_of_Z_ne_zero hP hPz] + +lemma addZ_neg (P : Fin 3 → R) : W'.addZ P (W'.neg P) = 0 := by + rw [addZ, neg_X, neg_Y, neg_Z, negY] + ring1 + +lemma addX_neg (P : Fin 3 → R) : W'.addX P (W'.neg P) = 0 := by + rw [addX, neg_X, neg_Y, neg_Z, negY] + ring1 + +lemma negAddY_neg {P : Fin 3 → R} (hP : W'.Equation P) : W'.negAddY P (W'.neg P) = W'.dblZ P := by + linear_combination (norm := (rw [negAddY, neg_X, neg_Y, neg_Z, dblZ, negY]; ring1)) + -3 * (P y - W'.negY P) * (equation_iff _).mp hP + +lemma addY_neg {P : Fin 3 → R} (hP : W'.Equation P) : W'.addY P (W'.neg P) = -W'.dblZ P := by + rw [addY, negY_eq, addX_neg, negAddY_neg hP, addZ_neg, mul_zero, sub_zero, mul_zero, sub_zero] + +lemma addXYZ_neg {P : Fin 3 → R} (hP : W'.Equation P) : + W'.addXYZ P (W'.neg P) = -W'.dblZ P • ![0, 1, 0] := by + erw [addXYZ, addX_neg, addY_neg hP, addZ_neg, smul_fin3, mul_zero, mul_one] + +variable (W') in +/-- The negation of a point class. If `P` is a point representative, +then `W'.negMap ⟦P⟧` is definitionally equivalent to `W'.neg P`. -/ +def negMap (P : PointClass R) : PointClass R := + P.map W'.neg fun _ _ => neg_equiv + +lemma negMap_eq (P : Fin 3 → R) : W'.negMap ⟦P⟧ = ⟦W'.neg P⟧ := + rfl + +lemma negMap_of_Z_eq_zero {P : Fin 3 → F} (hP : W.Nonsingular P) (hPz : P z = 0) : + W.negMap ⟦P⟧ = ⟦![0, 1, 0]⟧ := by + rw [negMap_eq, neg_of_Z_eq_zero hP.left hPz, smul_eq _ (isUnit_Y_of_Z_eq_zero hP hPz).neg] + +lemma negMap_of_Z_ne_zero {P : Fin 3 → F} (hPz : P z ≠ 0) : + W.negMap ⟦P⟧ = ⟦![P x / P z, W.toAffine.negY (P x / P z) (P y / P z), 1]⟧ := by + rw [negMap_eq, neg_of_Z_ne_zero hPz, smul_eq _ <| Ne.isUnit hPz] + +lemma nonsingularLift_negMap {P : PointClass F} (hP : W.NonsingularLift P) : + W.NonsingularLift <| W.negMap P := by + rcases P with ⟨_⟩ + exact nonsingular_neg hP + +end Negation + +section Addition + +/-! ### Addition on point representatives -/ + +open Classical in +variable (W') in +/-- The addition of two point representatives. -/ +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 + +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 + rw [add_of_equiv <| (smul_equiv_smul P Q hu hv).mpr h, dblXYZ_smul, add_of_equiv h] + +lemma add_self (P : Fin 3 → R) : W'.add P P = W'.dblXYZ P := + add_of_equiv <| Setoid.refl _ + +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 + +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 + rw [add_of_not_equiv <| h.comp (smul_equiv_smul P Q hu hv).mp, addXYZ_smul, add_of_not_equiv h] + +lemma add_smul_equiv (P Q : Fin 3 → R) {u v : R} (hu : IsUnit u) (hv : IsUnit v) : + W'.add (u • P) (v • Q) ≈ W'.add P Q := by + by_cases h : P ≈ Q + · exact ⟨hu.unit ^ 4, by convert (add_smul_of_equiv h hu hv).symm⟩ + · exact ⟨(hu.unit * hv.unit) ^ 2, by convert (add_smul_of_not_equiv h hu hv).symm⟩ + +lemma add_equiv {P P' Q Q' : Fin 3 → R} (hP : P ≈ P') (hQ : Q ≈ Q') : + W'.add P Q ≈ W'.add P' Q' := by + rcases hP, hQ with ⟨⟨u, rfl⟩, ⟨v, rfl⟩⟩ + exact add_smul_equiv P' Q' u.isUnit v.isUnit + +lemma add_of_Z_eq_zero {P Q : Fin 3 → F} (hP : W.Nonsingular P) (hQ : W.Nonsingular Q) + (hPz : P z = 0) (hQz : Q z = 0) : W.add P Q = P y ^ 4 • ![0, 1, 0] := by + rw [add, if_pos <| equiv_of_Z_eq_zero hP hQ hPz hQz, dblXYZ_of_Z_eq_zero hP.left hPz] + +lemma add_of_Z_eq_zero_left [NoZeroDivisors R] {P Q : Fin 3 → R} (hP : W'.Equation P) + (hPz : P z = 0) (hQz : Q z ≠ 0) : W'.add P Q = (P y ^ 2 * Q z) • Q := by + rw [add, if_neg <| not_equiv_of_Z_eq_zero_left hPz hQz, addXYZ_of_Z_eq_zero_left hP hPz] + +lemma add_of_Z_eq_zero_right [NoZeroDivisors R] {P Q : Fin 3 → R} (hQ : W'.Equation Q) + (hPz : P z ≠ 0) (hQz : Q z = 0) : W'.add P Q = -(Q y ^ 2 * P z) • P := by + rw [add, if_neg <| not_equiv_of_Z_eq_zero_right hPz hQz, addXYZ_of_Z_eq_zero_right hQ hQz] + +lemma add_of_Y_eq {P Q : Fin 3 → F} (hP : W.Equation P) (hPz : P z ≠ 0) (hQz : Q z ≠ 0) + (hx : P x * Q z = Q x * P z) (hy : P y * Q z = Q y * P z) (hy' : P y * Q z = W.negY Q * P z) : + W.add P Q = W.dblU P • ![0, 1, 0] := by + rw [add, if_pos <| equiv_of_X_eq_of_Y_eq hPz hQz hx hy, dblXYZ_of_Y_eq hP hPz hQz hx hy hy'] + +lemma add_of_Y_ne {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0) + (hQz : Q z ≠ 0) (hx : P x * Q z = Q x * P z) (hy : P y * Q z ≠ Q y * P z) : + W.add P Q = addU P Q • ![0, 1, 0] := by + rw [add, if_neg <| not_equiv_of_Y_ne hy, addXYZ_of_X_eq hP hQ hPz hQz hx] + +lemma add_of_Y_ne' {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0) + (hQz : Q z ≠ 0) (hx : P x * Q z = Q x * P z) (hy : P y * Q z ≠ W.negY Q * P z) : + W.add P Q = W.dblZ P • + ![W.toAffine.addX (P x / P z) (Q x / Q z) + (W.toAffine.slope (P x / P z) (Q x / Q z) (P y / P z) (Q y / Q z)), + W.toAffine.addY (P x / P z) (Q x / Q z) (P y / P z) + (W.toAffine.slope (P x / P z) (Q x / Q z) (P y / P z) (Q y / Q z)), 1] := by + rw [add, if_pos <| equiv_of_X_eq_of_Y_eq hPz hQz hx <| Y_eq_of_Y_ne' hP hQ hPz hQz hx hy, + dblXYZ_of_Z_ne_zero hP hQ hPz hQz hx hy] + +lemma add_of_X_ne {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0) + (hQz : Q z ≠ 0) (hx : P x * Q z ≠ Q x * P z) : W.add P Q = W.addZ P Q • + ![W.toAffine.addX (P x / P z) (Q x / Q z) + (W.toAffine.slope (P x / P z) (Q x / Q z) (P y / P z) (Q y / Q z)), + W.toAffine.addY (P x / P z) (Q x / Q z) (P y / P z) + (W.toAffine.slope (P x / P z) (Q x / Q z) (P y / P z) (Q y / Q z)), 1] := by + rw [add, if_neg <| not_equiv_of_X_ne hx, addXYZ_of_Z_ne_zero hP hQ hPz hQz hx] + +private lemma nonsingular_add_of_Z_ne_zero {P Q : Fin 3 → F} (hP : W.Nonsingular P) + (hQ : W.Nonsingular Q) (hPz : P z ≠ 0) (hQz : Q z ≠ 0) + (hxy : P x * Q z = Q x * P z → P y * Q z ≠ W.negY Q * P z) : W.Nonsingular + ![W.toAffine.addX (P x / P z) (Q x / Q z) + (W.toAffine.slope (P x / P z) (Q x / Q z) (P y / P z) (Q y / Q z)), + W.toAffine.addY (P x / P z) (Q x / Q z) (P y / P z) + (W.toAffine.slope (P x / P z) (Q x / Q z) (P y / P z) (Q y / Q z)), 1] := + (nonsingular_some ..).mpr <| Affine.nonsingular_add ((nonsingular_of_Z_ne_zero hPz).mp hP) + ((nonsingular_of_Z_ne_zero hQz).mp hQ) (by rwa [← X_eq_iff hPz hQz, ne_eq, ← Y_eq_iff' hPz hQz]) + +lemma nonsingular_add {P Q : Fin 3 → F} (hP : W.Nonsingular P) (hQ : W.Nonsingular Q) : + W.Nonsingular <| W.add P Q := by + by_cases hPz : P z = 0 + · by_cases hQz : Q z = 0 + · simp only [add_of_Z_eq_zero hP hQ hPz hQz, + nonsingular_smul _ <| (isUnit_Y_of_Z_eq_zero hP hPz).pow 4, nonsingular_zero] + · simpa only [add_of_Z_eq_zero_left hP.left hPz hQz, + nonsingular_smul _ <| ((isUnit_Y_of_Z_eq_zero hP hPz).pow 2).mul <| Ne.isUnit hQz] + · by_cases hQz : Q z = 0 + · simpa only [add_of_Z_eq_zero_right hQ.left hPz hQz, + nonsingular_smul _ (((isUnit_Y_of_Z_eq_zero hQ hQz).pow 2).mul <| Ne.isUnit hPz).neg] + · by_cases hxy : P x * Q z = Q x * P z → P y * Q z ≠ W.negY Q * P z + · by_cases hx : P x * Q z = Q x * P z + · simp only [add_of_Y_ne' hP.left hQ.left hPz hQz hx <| hxy hx, + nonsingular_smul _ <| isUnit_dblZ_of_Y_ne' hP.left hQ.left hPz hQz hx <| hxy hx, + nonsingular_add_of_Z_ne_zero hP hQ hPz hQz hxy] + · simp only [add_of_X_ne hP.left hQ.left hPz hQz hx, + nonsingular_smul _ <| isUnit_addZ_of_X_ne hP.left hQ.left hx, + nonsingular_add_of_Z_ne_zero hP hQ hPz hQz hxy] + · rw [_root_.not_imp, not_ne_iff] at hxy + by_cases hy : P y * Q z = Q y * P z + · simp only [add_of_Y_eq hP.left hPz hQz hxy.left hy hxy.right, nonsingular_smul _ <| + isUnit_dblU_of_Y_eq hP hPz hQz hxy.left hy hxy.right, nonsingular_zero] + · simp only [add_of_Y_ne hP.left hQ.left hPz hQz hxy.left hy, + nonsingular_smul _ <| isUnit_addU_of_Y_ne hPz hQz hy, nonsingular_zero] + +variable (W') in +/-- The addition of two point classes. If `P` is a point representative, +then `W.addMap ⟦P⟧ ⟦Q⟧` is definitionally equivalent to `W.add P Q`. -/ +noncomputable def addMap (P Q : PointClass R) : PointClass R := + Quotient.map₂ W'.add (fun _ _ hP _ _ hQ => add_equiv hP hQ) P Q + +lemma addMap_eq (P Q : Fin 3 → R) : W'.addMap ⟦P⟧ ⟦Q⟧ = ⟦W'.add P Q⟧ := + rfl + +lemma addMap_of_Z_eq_zero_left {P : Fin 3 → F} {Q : PointClass F} (hP : W.Nonsingular P) + (hQ : W.NonsingularLift Q) (hPz : P z = 0) : W.addMap ⟦P⟧ Q = Q := by + rcases Q with ⟨Q⟩ + by_cases hQz : Q z = 0 + · erw [addMap_eq, add_of_Z_eq_zero hP hQ hPz hQz, + smul_eq _ <| (isUnit_Y_of_Z_eq_zero hP hPz).pow 4, Quotient.eq] + exact Setoid.symm <| equiv_zero_of_Z_eq_zero hQ hQz + · erw [addMap_eq, add_of_Z_eq_zero_left hP.left hPz hQz, + smul_eq _ <| ((isUnit_Y_of_Z_eq_zero hP hPz).pow 2).mul <| Ne.isUnit hQz] + rfl + +lemma addMap_of_Z_eq_zero_right {P : PointClass F} {Q : Fin 3 → F} (hP : W.NonsingularLift P) + (hQ : W.Nonsingular Q) (hQz : Q z = 0) : W.addMap P ⟦Q⟧ = P := by + rcases P with ⟨P⟩ + by_cases hPz : P z = 0 + · erw [addMap_eq, add_of_Z_eq_zero hP hQ hPz hQz, + smul_eq _ <| (isUnit_Y_of_Z_eq_zero hP hPz).pow 4, Quotient.eq] + exact Setoid.symm <| equiv_zero_of_Z_eq_zero hP hPz + · erw [addMap_eq, add_of_Z_eq_zero_right hQ.left hPz hQz, + smul_eq _ (((isUnit_Y_of_Z_eq_zero hQ hQz).pow 2).mul <| Ne.isUnit hPz).neg] + rfl + +lemma addMap_of_Y_eq {P Q : Fin 3 → F} (hP : W.Nonsingular P) (hQ : W.Equation Q) (hPz : P z ≠ 0) + (hQz : Q z ≠ 0) (hx : P x * Q z = Q x * P z) (hy' : P y * Q z = W.negY Q * P z) : + W.addMap ⟦P⟧ ⟦Q⟧ = ⟦![0, 1, 0]⟧ := by + by_cases hy : P y * Q z = Q y * P z + · rw [addMap_eq, add_of_Y_eq hP.left hPz hQz hx hy hy', + smul_eq _ <| isUnit_dblU_of_Y_eq hP hPz hQz hx hy hy'] + · rw [addMap_eq, add_of_Y_ne hP.left hQ hPz hQz hx hy, + smul_eq _ <| isUnit_addU_of_Y_ne hPz hQz hy] + +lemma addMap_of_Z_ne_zero {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0) + (hQz : Q z ≠ 0) (hxy : P x * Q z = Q x * P z → P y * Q z ≠ W.negY Q * P z) : W.addMap ⟦P⟧ ⟦Q⟧ = + ⟦![W.toAffine.addX (P x / P z) (Q x / Q z) + (W.toAffine.slope (P x / P z) (Q x / Q z) (P y / P z) (Q y / Q z)), + W.toAffine.addY (P x / P z) (Q x / Q z) (P y / P z) + (W.toAffine.slope (P x / P z) (Q x / Q z) (P y / P z) (Q y / Q z)), 1]⟧ := by + by_cases hx : P x * Q z = Q x * P z + · rw [addMap_eq, add_of_Y_ne' hP hQ hPz hQz hx <| hxy hx, + smul_eq _ <| isUnit_dblZ_of_Y_ne' hP hQ hPz hQz hx <| hxy hx] + · rw [addMap_eq, add_of_X_ne hP hQ hPz hQz hx, smul_eq _ <| isUnit_addZ_of_X_ne hP hQ hx] + +lemma nonsingularLift_addMap {P Q : PointClass F} (hP : W.NonsingularLift P) + (hQ : W.NonsingularLift Q) : W.NonsingularLift <| W.addMap P Q := by + rcases P; rcases Q + exact nonsingular_add hP hQ + +end Addition + end WeierstrassCurve.Projective diff --git a/scripts/no_lints_prime_decls.txt b/scripts/no_lints_prime_decls.txt index 8affabbf01733e..671479377b629d 100644 --- a/scripts/no_lints_prime_decls.txt +++ b/scripts/no_lints_prime_decls.txt @@ -4796,6 +4796,7 @@ WeierstrassCurve.leadingCoeff_preΨ' WeierstrassCurve.map_preΨ' WeierstrassCurve.natDegree_coeff_preΨ' WeierstrassCurve.natDegree_preΨ' +WeierstrassCurve.Projective.add_of_Y_ne' WeierstrassCurve.Projective.addX_eq' WeierstrassCurve.Projective.addY_of_X_eq' WeierstrassCurve.Projective.addZ_eq' From abad5bb64ad342b9f7f122f073225ba5c551664f Mon Sep 17 00:00:00 2001 From: FR Date: Fri, 18 Oct 2024 18:38:50 +0000 Subject: [PATCH 397/425] chore(Data/Nat/Bits): do not use tactic to make definitions (#17926) --- Mathlib/Data/Nat/Bits.lean | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Mathlib/Data/Nat/Bits.lean b/Mathlib/Data/Nat/Bits.lean index e580011668c94b..63469d742f2128 100644 --- a/Mathlib/Data/Nat/Bits.lean +++ b/Mathlib/Data/Nat/Bits.lean @@ -375,10 +375,11 @@ def binaryRec' {motive : ℕ → Sort*} (z : motive 0) ∀ n, motive n := binaryRec z fun b n ih => if h : n = 0 → b = true then f b n h ih - else by - convert z - rw [bit_eq_zero_iff] - simpa using h + else + have : bit b n = 0 := by + rw [bit_eq_zero_iff] + cases n <;> cases b <;> simp at h ⊢ + congrArg motive this ▸ z /-- The same as `binaryRec`, but special casing both 0 and 1 as base cases -/ @[elab_as_elim] @@ -386,9 +387,10 @@ def binaryRecFromOne {motive : ℕ → Sort*} (z₀ : motive 0) (z₁ : motive 1 (f : ∀ b n, n ≠ 0 → motive n → motive (bit b n)) : ∀ n, motive n := binaryRec' z₀ fun b n h ih => - if h' : n = 0 then by - rw [h', h h'] - exact z₁ + if h' : n = 0 then + have : bit b n = bit true 0 := by + rw [h', h h'] + congrArg motive this ▸ z₁ else f b n h' ih @[simp] From 7d20facb45c8983b0c9e7d2db53146a6642b8ef8 Mon Sep 17 00:00:00 2001 From: FordUniver Date: Fri, 18 Oct 2024 19:09:03 +0000 Subject: [PATCH 398/425] feat: variant of the binary AM-GM inequality (#17877) added variant of binary AM-GM inequality Co-authored-by: FordUniver <61389961+FordUniver@users.noreply.github.com> --- Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean | 17 +++++++++++++++-- Mathlib/Data/Nat/Cast/Defs.lean | 4 ++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean b/Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean index 2aa45b63b34c9f..9c0bbff7ea7738 100644 --- a/Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean +++ b/Mathlib/Algebra/Order/Ring/Unbundled/Basic.lean @@ -751,8 +751,8 @@ lemma max_mul_mul_le_max_mul_max [PosMulMono α] [MulPosMono α] (b c : α) (ha mul_le_mul (le_max_right a c) (le_max_right b d) hd (le_trans ha (le_max_left a c)) max_le (by simpa [mul_comm, max_comm] using ba) (by simpa [mul_comm, max_comm] using cd) -/-- Binary **arithmetic mean-geometric mean inequality** (aka AM-GM inequality) for linearly ordered -commutative semirings. -/ +/-- Binary, squared, and division-free **arithmetic mean-geometric mean inequality** +(aka AM-GM inequality) for linearly ordered commutative semirings. -/ lemma two_mul_le_add_sq [ExistsAddOfLE α] [MulPosStrictMono α] [ContravariantClass α α (· + ·) (· ≤ ·)] [CovariantClass α α (· + ·) (· ≤ ·)] (a b : α) : 2 * a * b ≤ a ^ 2 + b ^ 2 := by @@ -761,6 +761,19 @@ lemma two_mul_le_add_sq [ExistsAddOfLE α] [MulPosStrictMono α] alias two_mul_le_add_pow_two := two_mul_le_add_sq +/-- Binary, squared, and division-free **arithmetic mean-geometric mean inequality** +(aka AM-GM inequality) for linearly ordered commutative semirings. -/ +lemma four_mul_le_sq_add [ExistsAddOfLE α] [MulPosStrictMono α] + [ContravariantClass α α (· + ·) (· ≤ ·)] [CovariantClass α α (· + ·) (· ≤ ·)] + (a b : α) : 4 * a * b ≤ (a + b) ^ 2 := by + calc 4 * a * b + _ = 2 * a * b + 2 * a * b := by rw [mul_assoc, two_add_two_eq_four.symm, add_mul, mul_assoc] + _ ≤ a ^ 2 + b ^ 2 + 2 * a * b := by gcongr; exact two_mul_le_add_sq _ _ + _ = a ^ 2 + 2 * a * b + b ^ 2 := by rw [add_right_comm] + _ = (a + b) ^ 2 := (add_sq a b).symm + +alias four_mul_le_pow_two_add := four_mul_le_sq_add + end LinearOrderedCommSemiring section LinearOrderedRing diff --git a/Mathlib/Data/Nat/Cast/Defs.lean b/Mathlib/Data/Nat/Cast/Defs.lean index 937ea2f0f088c8..eb1e5e16903609 100644 --- a/Mathlib/Data/Nat/Cast/Defs.lean +++ b/Mathlib/Data/Nat/Cast/Defs.lean @@ -199,3 +199,7 @@ theorem three_add_one_eq_four [AddMonoidWithOne R] : 3 + 1 = (4 : R) := by ← Nat.cast_add, ← Nat.cast_add, ← Nat.cast_add] apply congrArg decide + +theorem two_add_two_eq_four [AddMonoidWithOne R] : 2 + 2 = (4 : R) := by + simp [← one_add_one_eq_two, ← Nat.cast_one, ← three_add_one_eq_four, + ← two_add_one_eq_three, add_assoc] From 63c47e1d61626a0e8d3209728b4a86fc90b87cd7 Mon Sep 17 00:00:00 2001 From: FR Date: Fri, 18 Oct 2024 19:09:04 +0000 Subject: [PATCH 399/425] chore(Data/Nat/Bits): attribute `elab_as_elim` `inline` `specialize` (#17897) Add attribute `elab_as_elim` to binary recursors. Also add `inline` and `specialize` for performance. Without `specialize`, the `popcountTR` in the test is not tail-recursive, and so crashes with ``` error: libc++abi: terminating due to uncaught exception of type lean::throwable: deep recursion was detected at 'interpreter' ``` Co-authored-by: Eric Wieser --- Mathlib/Data/Nat/Bits.lean | 10 ++++++---- Mathlib/Data/Nat/Fib/Basic.lean | 8 ++++---- Mathlib/Data/Nat/Size.lean | 14 +++++++------- test/BinaryRec.lean | 8 ++++++++ 4 files changed, 25 insertions(+), 15 deletions(-) create mode 100644 test/BinaryRec.lean diff --git a/Mathlib/Data/Nat/Bits.lean b/Mathlib/Data/Nat/Bits.lean index 63469d742f2128..371661d05995b7 100644 --- a/Mathlib/Data/Nat/Bits.lean +++ b/Mathlib/Data/Nat/Bits.lean @@ -136,6 +136,7 @@ theorem bit_testBit_zero_shiftRight_one (n : Nat) : bit (n.testBit 0) (n >>> 1) /-- For a predicate `motive : Nat → Sort*`, if instances can be constructed for natural numbers of the form `bit b n`, they can be constructed for any given natural number. -/ +@[inline] def bitCasesOn {motive : Nat → Sort u} (n) (h : ∀ b n, motive (bit b n)) : motive n := -- `1 &&& n != 0` is faster than `n.testBit 0`. This may change when we have faster `testBit`. let x := h (1 &&& n != 0) (n >>> 1) @@ -175,6 +176,7 @@ lemma binaryRec_decreasing (h : n ≠ 0) : div2 n < n := by For a predicate `motive : Nat → Sort*`, if instances can be constructed for natural numbers of the form `bit b n`, they can be constructed for all natural numbers. -/ +@[elab_as_elim, specialize] def binaryRec {motive : Nat → Sort u} (z : motive 0) (f : ∀ b n, motive n → motive (bit b n)) (n : Nat) : motive n := if n0 : n = 0 then congrArg motive n0 ▸ z @@ -208,7 +210,7 @@ lemma binaryRec_zero {motive : Nat → Sort u} @[simp] lemma binaryRec_one {C : Nat → Sort u} (z : C 0) (f : ∀ b n, C n → C (bit b n)) : - binaryRec z f 1 = f true 0 z := by + binaryRec (motive := C) z f 1 = f true 0 z := by rw [binaryRec] simp only [succ_ne_self, ↓reduceDIte, reduceShiftRight, binaryRec_zero] rfl @@ -369,7 +371,7 @@ theorem binaryRec_eq {motive : Nat → Sort u} {z : motive 0} /-- The same as `binaryRec`, but the induction step can assume that if `n=0`, the bit being appended is `true`-/ -@[elab_as_elim] +@[elab_as_elim, specialize] def binaryRec' {motive : ℕ → Sort*} (z : motive 0) (f : ∀ b n, (n = 0 → b = true) → motive n → motive (bit b n)) : ∀ n, motive n := @@ -382,7 +384,7 @@ def binaryRec' {motive : ℕ → Sort*} (z : motive 0) congrArg motive this ▸ z /-- The same as `binaryRec`, but special casing both 0 and 1 as base cases -/ -@[elab_as_elim] +@[elab_as_elim, specialize] def binaryRecFromOne {motive : ℕ → Sort*} (z₀ : motive 0) (z₁ : motive 1) (f : ∀ b n, n ≠ 0 → motive n → motive (bit b n)) : ∀ n, motive n := @@ -399,7 +401,7 @@ theorem zero_bits : bits 0 = [] := by simp [Nat.bits] @[simp] theorem bits_append_bit (n : ℕ) (b : Bool) (hn : n = 0 → b = true) : (bit b n).bits = b :: n.bits := by - rw [Nat.bits, binaryRec_eq'] + rw [Nat.bits, Nat.bits, binaryRec_eq'] simpa @[simp] diff --git a/Mathlib/Data/Nat/Fib/Basic.lean b/Mathlib/Data/Nat/Fib/Basic.lean index 4d5698a009a291..587e609b5ab7ba 100644 --- a/Mathlib/Data/Nat/Fib/Basic.lean +++ b/Mathlib/Data/Nat/Fib/Basic.lean @@ -200,12 +200,12 @@ theorem fast_fib_aux_bit_tt (n : ℕ) : · simp theorem fast_fib_aux_eq (n : ℕ) : fastFibAux n = (fib n, fib (n + 1)) := by - apply Nat.binaryRec _ (fun b n' ih => _) n + refine Nat.binaryRec ?_ ?_ n · simp [fastFibAux] · rintro (_|_) n' ih <;> - simp only [fast_fib_aux_bit_ff, fast_fib_aux_bit_tt, congr_arg Prod.fst ih, - congr_arg Prod.snd ih, Prod.mk.inj_iff] <;> - simp [bit, fib_two_mul, fib_two_mul_add_one, fib_two_mul_add_two] + simp only [fast_fib_aux_bit_ff, fast_fib_aux_bit_tt, congr_arg Prod.fst ih, + congr_arg Prod.snd ih, Prod.mk.inj_iff] <;> + simp [bit, fib_two_mul, fib_two_mul_add_one, fib_two_mul_add_two] theorem fast_fib_eq (n : ℕ) : fastFib n = fib n := by rw [fastFib, fast_fib_aux_eq] diff --git a/Mathlib/Data/Nat/Size.lean b/Mathlib/Data/Nat/Size.lean index 5c7eb08714c3c1..1fdafff0b8fd02 100644 --- a/Mathlib/Data/Nat/Size.lean +++ b/Mathlib/Data/Nat/Size.lean @@ -39,7 +39,7 @@ theorem size_zero : size 0 = 0 := by simp [size] @[simp] theorem size_bit {b n} (h : bit b n ≠ 0) : size (bit b n) = succ (size n) := by - rw [size] + unfold size conv => lhs rw [binaryRec] @@ -81,7 +81,7 @@ theorem size_shiftLeft {m} (h : m ≠ 0) (n) : size (m <<< n) = size m + n := by theorem lt_size_self (n : ℕ) : n < 2 ^ size n := by rw [← one_shiftLeft] have : ∀ {n}, n = 0 → n < 1 <<< (size n) := by simp - apply binaryRec _ _ n + refine binaryRec ?_ ?_ n · apply this rfl intro b n IH by_cases h : bit b n = 0 @@ -91,11 +91,11 @@ theorem lt_size_self (n : ℕ) : n < 2 ^ size n := by theorem size_le {m n : ℕ} : size m ≤ n ↔ m < 2 ^ n := ⟨fun h => lt_of_lt_of_le (lt_size_self _) (pow_le_pow_of_le_right (by decide) h), by - rw [← one_shiftLeft]; revert n - apply binaryRec _ _ m - · intro n - simp - · intro b m IH n h + rw [← one_shiftLeft] + induction m using binaryRec generalizing n with + | z => simp + | f b m IH => + intro h by_cases e : bit b m = 0 · simp [e] rw [size_bit e] diff --git a/test/BinaryRec.lean b/test/BinaryRec.lean new file mode 100644 index 00000000000000..1112d600d4af8b --- /dev/null +++ b/test/BinaryRec.lean @@ -0,0 +1,8 @@ +import Mathlib.Data.Nat.Bits + +def Nat.popcountTR (n : Nat) : Nat := + n.binaryRec (·) (fun b _ f x ↦ f (x + b.toNat)) 0 + +/-- info: 1 -/ +#guard_msgs in +#eval Nat.popcountTR (2 ^ 20240) From 547e878793a20c0a59b55ba0cca411f38d0e1bfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 18 Oct 2024 21:00:38 +0000 Subject: [PATCH 400/425] =?UTF-8?q?feat:=20`Disjoint=20(a=20=E2=80=A2=20s)?= =?UTF-8?q?=20t=20=E2=86=94=20Disjoint=20s=20(a=E2=81=BB=C2=B9=20=E2=80=A2?= =?UTF-8?q?=20t)`=20(#17907)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Mathlib/Data/Set/Pointwise/SMul.lean | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Mathlib/Data/Set/Pointwise/SMul.lean b/Mathlib/Data/Set/Pointwise/SMul.lean index 00fe29ebfea631..9e6917fe0172c9 100644 --- a/Mathlib/Data/Set/Pointwise/SMul.lean +++ b/Mathlib/Data/Set/Pointwise/SMul.lean @@ -330,7 +330,7 @@ theorem smul_set_inter : a • (s ∩ t) = a • s ∩ a • t := image_inter <| MulAction.injective a @[to_additive] -theorem smul_set_iInter {ι : Type*} +theorem smul_set_iInter {ι : Sort*} (a : α) (t : ι → Set β) : (a • ⋂ i, t i) = ⋂ i, a • t i := image_iInter (MulAction.bijective a) t @@ -401,8 +401,19 @@ lemma inv_op_smul_set_distrib (a : α) (s : Set α) : (op a • s)⁻¹ = a⁻¹ ext; simp [mem_smul_set_iff_inv_smul_mem] @[to_additive (attr := simp)] -lemma smul_set_disjoint_iff : Disjoint (a • s) (a • t) ↔ Disjoint s t := by - simp [disjoint_iff, ← smul_set_inter] +lemma disjoint_smul_set : Disjoint (a • s) (a • t) ↔ Disjoint s t := + disjoint_image_iff <| MulAction.injective _ + +@[to_additive] +lemma disjoint_smul_set_left : Disjoint (a • s) t ↔ Disjoint s (a⁻¹ • t) := by + simpa using disjoint_smul_set (a := a) (t := a⁻¹ • t) + +@[to_additive] +lemma disjoint_smul_set_right : Disjoint s (a • t) ↔ Disjoint (a⁻¹ • s) t := by + simpa using disjoint_smul_set (a := a) (s := a⁻¹ • s) + +@[to_additive (attr := deprecated (since := "2024-10-18"))] +alias smul_set_disjoint_iff := disjoint_smul_set end Group From 8959a60fa36fe31f229b95fa4bb3612b36b29160 Mon Sep 17 00:00:00 2001 From: Yuma Mizuno Date: Fri, 18 Oct 2024 21:29:10 +0000 Subject: [PATCH 401/425] feat(CategoryTheory/Monoidal): add `IsMon_Hom` type class (#17186) --- Mathlib/CategoryTheory/Monoidal/Bimon_.lean | 4 ++++ Mathlib/CategoryTheory/Monoidal/Comon_.lean | 9 +++++++++ Mathlib/CategoryTheory/Monoidal/Mon_.lean | 9 +++++++++ 3 files changed, 22 insertions(+) diff --git a/Mathlib/CategoryTheory/Monoidal/Bimon_.lean b/Mathlib/CategoryTheory/Monoidal/Bimon_.lean index e195b655047045..d5228377308462 100644 --- a/Mathlib/CategoryTheory/Monoidal/Bimon_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Bimon_.lean @@ -68,6 +68,10 @@ theorem one_counit (M : C) [Bimon_Class M] : η[M] ≫ ε[M] = 𝟙 (𝟙_ C) := end Bimon_Class +/-- The property that a morphism between bimonoid objects is a bimonoid morphism. -/ +class IsBimon_Hom {M N : C} [Bimon_Class M] [Bimon_Class N] (f : M ⟶ N) extends + IsMon_Hom f, IsComon_Hom f : Prop + variable (C) /-- diff --git a/Mathlib/CategoryTheory/Monoidal/Comon_.lean b/Mathlib/CategoryTheory/Monoidal/Comon_.lean index ff63ce4bbb0eb0..ac2283e8e74022 100644 --- a/Mathlib/CategoryTheory/Monoidal/Comon_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Comon_.lean @@ -71,6 +71,15 @@ end Comon_Class open scoped Comon_Class +variable {M N : C} [Comon_Class M] [Comon_Class N] + +/-- The property that a morphism between comonoid objects is a comonoid morphism. -/ +class IsComon_Hom (f : M ⟶ N) : Prop where + hom_counit : f ≫ ε = ε := by aesop_cat + hom_comul : f ≫ Δ = Δ ≫ (f ⊗ f) := by aesop_cat + +attribute [reassoc (attr := simp)] IsComon_Hom.hom_counit IsComon_Hom.hom_comul + variable (C) /-- A comonoid object internal to a monoidal category. diff --git a/Mathlib/CategoryTheory/Monoidal/Mon_.lean b/Mathlib/CategoryTheory/Monoidal/Mon_.lean index c04c4f4d55c076..52b4de6677a397 100644 --- a/Mathlib/CategoryTheory/Monoidal/Mon_.lean +++ b/Mathlib/CategoryTheory/Monoidal/Mon_.lean @@ -67,6 +67,15 @@ end Mon_Class open scoped Mon_Class +variable {M N : C} [Mon_Class M] [Mon_Class N] + +/-- The property that a morphism between monoid objects is a monoid morphism. -/ +class IsMon_Hom (f : M ⟶ N) : Prop where + one_hom : η ≫ f = η := by aesop_cat + mul_hom : μ ≫ f = (f ⊗ f) ≫ μ := by aesop_cat + +attribute [reassoc (attr := simp)] IsMon_Hom.one_hom IsMon_Hom.mul_hom + variable (C) /-- A monoid object internal to a monoidal category. From de5d061f84a1fdff844f983aea367c3bdbf676b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Fri, 18 Oct 2024 21:29:11 +0000 Subject: [PATCH 402/425] chore: Rename `OpenEmbedding` to `IsOpenEmbedding` (#17898) `Function.Embedding` is a type while `Embedding` is a proposition, and there are many other kinds of embeddings than topological embeddings. Hence this PR is a step towards 1. renaming `Embedding` to `IsEmbedding` and similarly for neighborhing declarations (which `OpenEmbedding` is) 2. namespacing it inside `Topology` [Zulip](https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/rename.20.60Inducing.60.20and.20.60Embedding.60.3F). See #15993 for context. --- Mathlib/AlgebraicGeometry/AffineScheme.lean | 14 +- Mathlib/AlgebraicGeometry/Cover/Open.lean | 2 +- Mathlib/AlgebraicGeometry/FunctionField.lean | 4 +- Mathlib/AlgebraicGeometry/Gluing.lean | 9 +- Mathlib/AlgebraicGeometry/Limits.lean | 4 +- .../AlgebraicGeometry/Morphisms/Affine.lean | 2 +- .../AlgebraicGeometry/Morphisms/IsIso.lean | 2 +- .../Morphisms/OpenImmersion.lean | 4 +- .../Morphisms/Preimmersion.lean | 2 +- .../Morphisms/UnderlyingMap.lean | 14 +- Mathlib/AlgebraicGeometry/Noetherian.lean | 4 +- Mathlib/AlgebraicGeometry/OpenImmersion.lean | 25 ++-- .../PrimeSpectrum/Basic.lean | 7 +- .../ProjectiveSpectrum/Scheme.lean | 13 +- Mathlib/AlgebraicGeometry/Properties.lean | 4 +- Mathlib/AlgebraicGeometry/Restrict.lean | 30 ++--- Mathlib/AlgebraicGeometry/Scheme.lean | 2 +- .../Complex/UpperHalfPlane/Manifold.lean | 4 +- .../Complex/UpperHalfPlane/Topology.lean | 15 ++- Mathlib/Analysis/Normed/Ring/Units.lean | 7 +- Mathlib/Analysis/SpecialFunctions/Exp.lean | 11 +- Mathlib/Geometry/Manifold/ChartedSpace.lean | 12 +- .../Geometry/Manifold/ContMDiff/Basic.lean | 27 ++-- .../Instances/UnitsOfNormedAlgebra.lean | 10 +- .../Manifold/LocalInvariantProperties.lean | 4 +- .../Manifold/SmoothManifoldWithCorners.lean | 8 +- .../RingedSpace/LocallyRingedSpace.lean | 10 +- .../Geometry/RingedSpace/OpenImmersion.lean | 53 ++++---- .../Geometry/RingedSpace/PresheafedSpace.lean | 16 +-- .../RingedSpace/PresheafedSpace/Gluing.lean | 19 +-- .../Geometry/RingedSpace/SheafedSpace.lean | 8 +- Mathlib/Geometry/RingedSpace/Stalks.lean | 10 +- .../Constructions/BorelSpace/Basic.lean | 5 +- .../EisensteinSeries/UniformConvergence.lean | 2 +- Mathlib/Topology/Algebra/ConstMulAction.lean | 2 +- .../Algebra/Constructions/DomMulAct.lean | 12 +- .../Algebra/Nonarchimedean/Basic.lean | 2 +- Mathlib/Topology/Bases.lean | 4 +- .../Category/CompHausLike/Limits.lean | 28 ++-- Mathlib/Topology/Category/Stonean/Limits.lean | 4 +- Mathlib/Topology/Category/TopCat/Basic.lean | 38 ++++-- .../Category/TopCat/Limits/Products.lean | 7 +- .../Category/TopCat/Limits/Pullbacks.lean | 48 ++++--- .../Topology/Category/TopCat/OpenNhds.lean | 7 +- Mathlib/Topology/Category/TopCat/Opens.lean | 33 +++-- Mathlib/Topology/Clopen.lean | 2 +- .../Topology/Compactification/OnePoint.lean | 23 ++-- .../Topology/Compactness/LocallyCompact.lean | 7 +- .../Topology/Connected/LocallyConnected.lean | 9 +- Mathlib/Topology/Connected/PathConnected.lean | 7 +- Mathlib/Topology/Constructions.lean | 72 +++++++---- Mathlib/Topology/ContinuousOn.lean | 5 +- Mathlib/Topology/Defs/Induced.lean | 7 +- Mathlib/Topology/Gluing.lean | 24 ++-- Mathlib/Topology/Homeomorph.lean | 16 ++- Mathlib/Topology/Inseparable.lean | 5 +- Mathlib/Topology/Instances/ENNReal.lean | 11 +- Mathlib/Topology/Instances/ENat.lean | 7 +- Mathlib/Topology/Instances/EReal.lean | 9 +- Mathlib/Topology/Irreducible.lean | 2 +- Mathlib/Topology/IsLocalHomeomorph.lean | 54 +++++--- Mathlib/Topology/LocalAtTarget.lean | 30 +++-- Mathlib/Topology/LocallyClosed.lean | 5 +- Mathlib/Topology/Maps/Basic.lean | 121 ++++++++++++------ Mathlib/Topology/PartialHomeomorph.lean | 29 +++-- Mathlib/Topology/QuasiSeparated.lean | 14 +- Mathlib/Topology/SeparatedMap.lean | 11 +- Mathlib/Topology/Separation.lean | 17 ++- Mathlib/Topology/Sets/Opens.lean | 14 +- Mathlib/Topology/Sheaves/LocalPredicate.lean | 4 +- .../Sheaves/SheafCondition/Sites.lean | 19 ++- Mathlib/Topology/Sheaves/Stalks.lean | 7 +- Mathlib/Topology/Sober.lean | 7 +- Mathlib/Topology/Support.lean | 2 +- scripts/no_lints_prime_decls.txt | 8 +- 75 files changed, 677 insertions(+), 419 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AffineScheme.lean b/Mathlib/AlgebraicGeometry/AffineScheme.lean index 74ea6759b202f6..5a69b75178c417 100644 --- a/Mathlib/AlgebraicGeometry/AffineScheme.lean +++ b/Mathlib/AlgebraicGeometry/AffineScheme.lean @@ -278,7 +278,7 @@ def isoSpec : ↑U ≅ Spec Γ(X, U) := haveI : IsAffine U := hU U.toScheme.isoSpec ≪≫ Scheme.Spec.mapIso - (X.presheaf.mapIso (eqToIso U.openEmbedding_obj_top).op).op + (X.presheaf.mapIso (eqToIso U.isOpenEmbedding_obj_top).op).op open LocalRing in lemma isoSpec_hom_base_apply (x : U) : @@ -395,8 +395,8 @@ theorem _root_.AlgebraicGeometry.Scheme.Hom.isAffineOpen_iff_of_isOpenImmersion (f : AlgebraicGeometry.Scheme.Hom X Y) [H : IsOpenImmersion f] {U : X.Opens} : IsAffineOpen (f ''ᵁ U) ↔ IsAffineOpen U := by refine ⟨fun hU => @isAffine_of_isIso _ _ - (IsOpenImmersion.isoOfRangeEq (X.ofRestrict U.openEmbedding ≫ f) (Y.ofRestrict _) ?_).hom ?_ hU, - fun hU => hU.image_of_isOpenImmersion f⟩ + (IsOpenImmersion.isoOfRangeEq (X.ofRestrict U.isOpenEmbedding ≫ f) (Y.ofRestrict _) ?_).hom + ?_ hU, fun hU => hU.image_of_isOpenImmersion f⟩ · rw [Scheme.comp_base, coe_comp, Set.range_comp] dsimp [Opens.coe_inclusion', Scheme.restrict] erw [Subtype.range_coe, Subtype.range_coe] -- now `erw` after #13170 @@ -491,7 +491,7 @@ theorem ι_basicOpen_preimage (r : Γ(X, ⊤)) : IsAffineOpen ((X.basicOpen r).ι ⁻¹ᵁ U) := by apply (X.basicOpen r).ι.isAffineOpen_iff_of_isOpenImmersion.mp dsimp [Scheme.Hom.opensFunctor, LocallyRingedSpace.IsOpenImmersion.opensFunctor] - rw [Opens.functor_obj_map_obj, Opens.openEmbedding_obj_top, inf_comm, + rw [Opens.functor_obj_map_obj, Opens.isOpenEmbedding_obj_top, inf_comm, ← Scheme.basicOpen_res _ _ (homOfLE le_top).op] exact hU.basicOpen _ @@ -504,12 +504,12 @@ theorem exists_basicOpen_le {V : X.Opens} (x : V) (h : ↑x ∈ U) : ((Opens.map U.inclusion').obj V).isOpen have : U.ι ''ᵁ (U.toScheme.basicOpen r) = - X.basicOpen (X.presheaf.map (eqToHom U.openEmbedding_obj_top.symm).op r) := by + X.basicOpen (X.presheaf.map (eqToHom U.isOpenEmbedding_obj_top.symm).op r) := by refine (Scheme.image_basicOpen U.ι r).trans ?_ rw [Scheme.basicOpen_res_eq] simp only [Scheme.Opens.toScheme_presheaf_obj, Scheme.Opens.ι_appIso, Iso.refl_inv, CommRingCat.id_apply] - use X.presheaf.map (eqToHom U.openEmbedding_obj_top.symm).op r + use X.presheaf.map (eqToHom U.isOpenEmbedding_obj_top.symm).op r rw [← this] exact ⟨Set.image_subset_iff.mpr h₂, ⟨_, h⟩, h₁, rfl⟩ @@ -573,7 +573,7 @@ theorem isLocalization_of_eq_basicOpen {V : X.Opens} (i : V ⟶ U) (e : V = X.ba instance _root_.AlgebraicGeometry.Γ_restrict_isLocalization (X : Scheme.{u}) [IsAffine X] (r : Γ(X, ⊤)) : IsLocalization.Away r Γ(X.basicOpen r, ⊤) := - (isAffineOpen_top X).isLocalization_of_eq_basicOpen r _ (Opens.openEmbedding_obj_top _) + (isAffineOpen_top X).isLocalization_of_eq_basicOpen r _ (Opens.isOpenEmbedding_obj_top _) include hU in theorem basicOpen_basicOpen_is_basicOpen (g : Γ(X, X.basicOpen f)) : diff --git a/Mathlib/AlgebraicGeometry/Cover/Open.lean b/Mathlib/AlgebraicGeometry/Cover/Open.lean index 836bfdf366a33f..32b601db856c3c 100644 --- a/Mathlib/AlgebraicGeometry/Cover/Open.lean +++ b/Mathlib/AlgebraicGeometry/Cover/Open.lean @@ -248,7 +248,7 @@ theorem OpenCover.compactSpace {X : Scheme.{u}} (𝒰 : X.OpenCover) [Finite (TopCat.homeoOfIso (asIso (IsOpenImmersion.isoOfRangeEq (𝒰.map i) - (X.ofRestrict (Opens.openEmbedding ⟨_, (𝒰.IsOpen i).base_open.isOpen_range⟩)) + (X.ofRestrict (Opens.isOpenEmbedding ⟨_, (𝒰.IsOpen i).base_open.isOpen_range⟩)) Subtype.range_coe.symm).hom.base)) /-- Given open covers `{ Uᵢ }` and `{ Uⱼ }`, we may form the open cover `{ Uᵢ ∩ Uⱼ }`. -/ diff --git a/Mathlib/AlgebraicGeometry/FunctionField.lean b/Mathlib/AlgebraicGeometry/FunctionField.lean index 242c360e3de84f..6833058adc17ff 100644 --- a/Mathlib/AlgebraicGeometry/FunctionField.lean +++ b/Mathlib/AlgebraicGeometry/FunctionField.lean @@ -135,7 +135,7 @@ theorem IsAffineOpen.primeIdealOf_genericPoint {X : Scheme} [IsIntegral X] {U : delta IsAffineOpen.primeIdealOf convert genericPoint_eq_of_isOpenImmersion - (U.toScheme.isoSpec.hom ≫ Spec.map (X.presheaf.map (eqToHom U.openEmbedding_obj_top).op)) + (U.toScheme.isoSpec.hom ≫ Spec.map (X.presheaf.map (eqToHom U.isOpenEmbedding_obj_top).op)) -- Porting note: this was `ext1` apply Subtype.ext exact (genericPoint_eq_of_isOpenImmersion U.ι).symm @@ -146,7 +146,7 @@ theorem functionField_isFractionRing_of_isAffineOpen [IsIntegral X] (U : X.Opens haveI : IsAffine _ := hU haveI : IsIntegral U := @isIntegral_of_isAffine_of_isDomain _ _ _ - (by rw [Scheme.Opens.toScheme_presheaf_obj, Opens.openEmbedding_obj_top]; infer_instance) + (by rw [Scheme.Opens.toScheme_presheaf_obj, Opens.isOpenEmbedding_obj_top]; infer_instance) delta IsFractionRing Scheme.functionField convert hU.isLocalization_stalk ⟨genericPoint X, (((genericPoint_spec X).mem_open_set_iff U.isOpen).mpr (by simpa using ‹Nonempty U›))⟩ using 1 diff --git a/Mathlib/AlgebraicGeometry/Gluing.lean b/Mathlib/AlgebraicGeometry/Gluing.lean index 9eeee3d9e71e3a..c38450ee481558 100644 --- a/Mathlib/AlgebraicGeometry/Gluing.lean +++ b/Mathlib/AlgebraicGeometry/Gluing.lean @@ -379,10 +379,13 @@ theorem fromGlued_open_map : IsOpenMap 𝒰.fromGlued.base := by exact Set.preimage_image_eq _ 𝒰.fromGlued_injective · exact ⟨hx, 𝒰.covers x⟩ -theorem fromGlued_openEmbedding : OpenEmbedding 𝒰.fromGlued.base := - openEmbedding_of_continuous_injective_open +theorem fromGlued_isOpenEmbedding : IsOpenEmbedding 𝒰.fromGlued.base := + isOpenEmbedding_of_continuous_injective_open (by fun_prop) 𝒰.fromGlued_injective 𝒰.fromGlued_open_map +@[deprecated (since := "2024-10-18")] +alias fromGlued_openEmbedding := fromGlued_isOpenEmbedding + instance : Epi 𝒰.fromGlued.base := by rw [TopCat.epi_iff_surjective] intro x @@ -393,7 +396,7 @@ instance : Epi 𝒰.fromGlued.base := by exact h instance fromGlued_open_immersion : IsOpenImmersion 𝒰.fromGlued := - IsOpenImmersion.of_stalk_iso _ 𝒰.fromGlued_openEmbedding + IsOpenImmersion.of_stalk_iso _ 𝒰.fromGlued_isOpenEmbedding instance : IsIso 𝒰.fromGlued := let F := Scheme.forgetToLocallyRingedSpace ⋙ LocallyRingedSpace.forgetToSheafedSpace ⋙ diff --git a/Mathlib/AlgebraicGeometry/Limits.lean b/Mathlib/AlgebraicGeometry/Limits.lean index 0622355eef4476..1480c9d5d315fa 100644 --- a/Mathlib/AlgebraicGeometry/Limits.lean +++ b/Mathlib/AlgebraicGeometry/Limits.lean @@ -250,7 +250,7 @@ lemma sigmaι_eq_iff (i j : ι) (x y) : by_cases h : i = j · subst h simp only [Sigma.mk.inj_iff, heq_eq_eq, true_and] - exact ((disjointGlueData f).ι i).openEmbedding.inj H + exact ((disjointGlueData f).ι i).isOpenEmbedding.inj H · obtain (e | ⟨z, _⟩) := (Scheme.GlueData.ι_eq_iff _ _ _ _ _).mp H · exact (h (Sigma.mk.inj_iff.mp e).1).elim · simp only [disjointGlueData_J, disjointGlueData_V, h, ↓reduceIte] at z @@ -269,7 +269,7 @@ lemma disjoint_opensRange_sigmaι (i j : ι) (h : i ≠ j) : lemma exists_sigmaι_eq (x : (∐ f : _)) : ∃ i y, (Sigma.ι f i).base y = x := by obtain ⟨i, y, e⟩ := (disjointGlueData f).ι_jointly_surjective ((sigmaIsoGlued f).hom.base x) - refine ⟨i, y, (sigmaIsoGlued f).hom.openEmbedding.inj ?_⟩ + refine ⟨i, y, (sigmaIsoGlued f).hom.isOpenEmbedding.inj ?_⟩ rwa [← Scheme.comp_base_apply, ι_sigmaIsoGlued_hom] lemma iSup_opensRange_sigmaι : ⨆ i, (Sigma.ι f i).opensRange = ⊤ := diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean b/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean index ecd431a4735b48..bcb0509ca655d0 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Affine.lean @@ -129,7 +129,7 @@ lemma isAffine_of_isAffineOpen_basicOpen (s : Set Γ(X, ⊤)) refine IsIso.comp_isIso' ?_ inferInstance convert isIso_ΓSpec_adjunction_unit_app_basicOpen i.1 using 0 refine congr(IsIso ((ΓSpec.adjunction.unit.app X).app $(?_))) - rw [Opens.openEmbedding_obj_top] + rw [Opens.isOpenEmbedding_obj_top] /-- If `s` is a spanning set of `Γ(X, U)`, such that each `X.basicOpen i` is affine, then `U` is also diff --git a/Mathlib/AlgebraicGeometry/Morphisms/IsIso.lean b/Mathlib/AlgebraicGeometry/Morphisms/IsIso.lean index 384f3493f9a1eb..41f31c85bebb9a 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/IsIso.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/IsIso.lean @@ -31,7 +31,7 @@ lemma isomorphisms_eq_stalkwise : ext X Y f exact ⟨fun H ↦ inferInstanceAs (IsIso (TopCat.isoOfHomeo (H.1.1.toHomeomeomorph_of_surjective H.2)).hom), fun (_ : IsIso f.base) ↦ - let e := (TopCat.homeoOfIso <| asIso f.base); ⟨e.openEmbedding, e.surjective⟩⟩ + let e := (TopCat.homeoOfIso <| asIso f.base); ⟨e.isOpenEmbedding, e.surjective⟩⟩ instance : IsLocalAtTarget (isomorphisms Scheme) := isomorphisms_eq_isOpenImmersion_inf_surjective ▸ inferInstance diff --git a/Mathlib/AlgebraicGeometry/Morphisms/OpenImmersion.lean b/Mathlib/AlgebraicGeometry/Morphisms/OpenImmersion.lean index 43a94b8d2d1a0e..1a4868bc3510b3 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/OpenImmersion.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/OpenImmersion.lean @@ -29,13 +29,13 @@ namespace AlgebraicGeometry variable {X Y Z : Scheme.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) theorem isOpenImmersion_iff_stalk {f : X ⟶ Y} : IsOpenImmersion f ↔ - OpenEmbedding f.base ∧ ∀ x, IsIso (f.stalkMap x) := by + IsOpenEmbedding f.base ∧ ∀ x, IsIso (f.stalkMap x) := by constructor · intro h; exact ⟨h.1, inferInstance⟩ · rintro ⟨h₁, h₂⟩; exact IsOpenImmersion.of_stalk_iso f h₁ theorem isOpenImmersion_eq_inf : - @IsOpenImmersion = (topologically OpenEmbedding) ⊓ + @IsOpenImmersion = (topologically IsOpenEmbedding) ⊓ stalkwise (fun f ↦ Function.Bijective f) := by ext exact isOpenImmersion_iff_stalk.trans diff --git a/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean b/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean index a5fd6903836cb9..9336dbb858cded 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean @@ -60,7 +60,7 @@ instance : IsLocalAtTarget @IsPreimmersion := isPreimmersion_eq_inf ▸ inferInstance instance (priority := 900) {X Y : Scheme} (f : X ⟶ Y) [IsOpenImmersion f] : IsPreimmersion f where - base_embedding := f.openEmbedding.toEmbedding + base_embedding := f.isOpenEmbedding.toEmbedding surj_on_stalks _ := (ConcreteCategory.bijective_of_isIso _).2 instance : MorphismProperty.IsMultiplicative @IsPreimmersion where diff --git a/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean b/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean index ff349f67ab6a8c..00d8b44dc43f00 100644 --- a/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean +++ b/Mathlib/AlgebraicGeometry/Morphisms/UnderlyingMap.lean @@ -18,7 +18,7 @@ of the underlying map of topological spaces, including - `IsOpenMap` - `IsClosedMap` - `Embedding` -- `OpenEmbedding` +- `IsOpenEmbedding` - `ClosedEmbedding` -/ @@ -119,17 +119,17 @@ instance embedding_isLocalAtTarget : IsLocalAtTarget (topologically Embedding) : end Embedding -section OpenEmbedding +section IsOpenEmbedding -instance : (topologically OpenEmbedding).RespectsIso := - topologically_respectsIso _ (fun e ↦ e.openEmbedding) (fun _ _ hf hg ↦ hg.comp hf) +instance : (topologically IsOpenEmbedding).RespectsIso := + topologically_respectsIso _ (fun e ↦ e.isOpenEmbedding) (fun _ _ hf hg ↦ hg.comp hf) -instance openEmbedding_isLocalAtTarget : IsLocalAtTarget (topologically OpenEmbedding) := +instance isOpenEmbedding_isLocalAtTarget : IsLocalAtTarget (topologically IsOpenEmbedding) := topologically_isLocalAtTarget _ (fun _ s hf ↦ hf.restrictPreimage s) - (fun _ _ _ hU hfcont hf ↦ (openEmbedding_iff_openEmbedding_of_iSup_eq_top hU hfcont).mpr hf) + (fun _ _ _ hU hfcont hf ↦ (isOpenEmbedding_iff_isOpenEmbedding_of_iSup_eq_top hU hfcont).mpr hf) -end OpenEmbedding +end IsOpenEmbedding section ClosedEmbedding diff --git a/Mathlib/AlgebraicGeometry/Noetherian.lean b/Mathlib/AlgebraicGeometry/Noetherian.lean index 45c741d3583198..121bca1ca0d2b8 100644 --- a/Mathlib/AlgebraicGeometry/Noetherian.lean +++ b/Mathlib/AlgebraicGeometry/Noetherian.lean @@ -199,7 +199,7 @@ instance (priority := 100) {Z : Scheme} [IsLocallyNoetherian X] apply (quasiCompact_iff_forall_affine f).mpr intro U hU rw [Opens.map_coe, ← Set.preimage_inter_range] - apply f.openEmbedding.toInducing.isCompact_preimage' + apply f.isOpenEmbedding.toInducing.isCompact_preimage' · apply (noetherianSpace_set_iff _).mp · convert noetherianSpace_of_isAffineOpen U hU apply IsLocallyNoetherian.component_noetherian ⟨U, hU⟩ @@ -213,7 +213,7 @@ instance (priority := 100) IsLocallyNoetherian.quasiSeparatedSpace [IsLocallyNoe QuasiSeparatedSpace X := by apply (quasiSeparatedSpace_iff_affine X).mpr intro U V - have hInd := U.2.fromSpec.openEmbedding.toInducing + have hInd := U.2.fromSpec.isOpenEmbedding.toInducing apply (hInd.isCompact_preimage_iff ?_).mp · rw [← Set.preimage_inter_range, IsAffineOpen.range_fromSpec, Set.inter_comm] apply hInd.isCompact_preimage' diff --git a/Mathlib/AlgebraicGeometry/OpenImmersion.lean b/Mathlib/AlgebraicGeometry/OpenImmersion.lean index 7b3769c5084045..bc36b58d339d18 100644 --- a/Mathlib/AlgebraicGeometry/OpenImmersion.lean +++ b/Mathlib/AlgebraicGeometry/OpenImmersion.lean @@ -56,7 +56,7 @@ protected def scheme (X : LocallyRingedSpace.{u}) refine SheafedSpace.forgetToPresheafedSpace.preimageIso ?_ apply PresheafedSpace.IsOpenImmersion.isoOfRangeEq (PresheafedSpace.ofRestrict _ _) f.1 · exact Subtype.range_coe_subtype - · exact Opens.openEmbedding _ -- Porting note (#11187): was `infer_instance` + · exact Opens.isOpenEmbedding _ -- Porting note (#11187): was `infer_instance` end LocallyRingedSpace.IsOpenImmersion @@ -71,13 +71,16 @@ namespace Scheme.Hom variable {X Y : Scheme.{u}} (f : Scheme.Hom X Y) [H : IsOpenImmersion f] -theorem openEmbedding : OpenEmbedding f.base := +theorem isOpenEmbedding : IsOpenEmbedding f.base := H.base_open +@[deprecated (since := "2024-10-18")] +alias openEmbedding := isOpenEmbedding + /-- The image of an open immersion as an open set. -/ @[simps] def opensRange : Y.Opens := - ⟨_, f.openEmbedding.isOpen_range⟩ + ⟨_, f.isOpenEmbedding.isOpen_range⟩ /-- The functor `opens X ⥤ opens Y` associated with an open immersion `f : X ⟶ Y`. -/ abbrev opensFunctor : X.Opens ⥤ Y.Opens := @@ -103,7 +106,7 @@ lemma image_top_eq_opensRange : f ''ᵁ ⊤ = f.opensRange := by @[simp] lemma preimage_image_eq (U : X.Opens) : f ⁻¹ᵁ f ''ᵁ U = U := by apply Opens.ext - simp [Set.preimage_image_eq _ f.openEmbedding.inj] + simp [Set.preimage_image_eq _ f.isOpenEmbedding.inj] lemma image_le_image_iff (f : X ⟶ Y) [IsOpenImmersion f] (U U' : X.Opens) : f ''ᵁ U ≤ f ''ᵁ U' ↔ U ≤ U' := by @@ -194,7 +197,7 @@ def IsOpenImmersion.opensEquiv {X Y : Scheme.{u}} (f : X ⟶ Y) [IsOpenImmersion X.Opens ≃ { U : Y.Opens // U ≤ f.opensRange } where toFun U := ⟨f ''ᵁ U, Set.image_subset_range _ _⟩ invFun U := f ⁻¹ᵁ U - left_inv _ := Opens.ext (Set.preimage_image_eq _ f.openEmbedding.inj) + left_inv _ := Opens.ext (Set.preimage_image_eq _ f.isOpenEmbedding.inj) right_inv U := Subtype.ext (Opens.ext (Set.image_preimage_eq_of_subset U.2)) namespace Scheme @@ -202,7 +205,7 @@ namespace Scheme instance basic_open_isOpenImmersion {R : CommRingCat.{u}} (f : R) : IsOpenImmersion (Spec.map (CommRingCat.ofHom (algebraMap R (Localization.Away f)))) := by apply SheafedSpace.IsOpenImmersion.of_stalk_iso (H := ?_) - · exact (PrimeSpectrum.localization_away_openEmbedding (Localization.Away f) f : _) + · exact (PrimeSpectrum.localization_away_isOpenEmbedding (Localization.Away f) f : _) · intro x exact Spec_map_localization_isIso R (Submonoid.powers f) x @@ -292,7 +295,7 @@ end PresheafedSpace.IsOpenImmersion section Restrict -variable {U : TopCat.{u}} (X : Scheme.{u}) {f : U ⟶ TopCat.of X} (h : OpenEmbedding f) +variable {U : TopCat.{u}} (X : Scheme.{u}) {f : U ⟶ TopCat.of X} (h : IsOpenEmbedding f) /-- The restriction of a Scheme along an open embedding. -/ @[simps! (config := .lemmasOnly) carrier, simps! presheaf_obj] @@ -351,7 +354,7 @@ theorem to_iso {X Y : Scheme.{u}} (f : X ⟶ Y) [h : IsOpenImmersion f] [Epi f.b LocallyRingedSpace.forgetToSheafedSpace ⋙ SheafedSpace.forgetToPresheafedSpace) (@PresheafedSpace.IsOpenImmersion.to_iso _ _ _ _ f.toPshHom h _) _ -theorem of_stalk_iso {X Y : Scheme.{u}} (f : X ⟶ Y) (hf : OpenEmbedding f.base) +theorem of_stalk_iso {X Y : Scheme.{u}} (f : X ⟶ Y) (hf : IsOpenEmbedding f.base) [∀ x, IsIso (f.stalkMap x)] : IsOpenImmersion f := haveI (x : X) : IsIso (f.toShHom.stalkMap x) := inferInstanceAs <| IsIso (f.stalkMap x) SheafedSpace.IsOpenImmersion.of_stalk_iso f.toShHom hf @@ -368,10 +371,10 @@ lemma of_comp {X Y Z : Scheme.{u}} (f : X ⟶ Y) (g : Y ⟶ Z) [IsOpenImmersion infer_instance IsIso.of_isIso_comp_left (f := g.stalkMap (f.base x)) _ IsOpenImmersion.of_stalk_iso _ <| - OpenEmbedding.of_comp _ (Scheme.Hom.openEmbedding g) (Scheme.Hom.openEmbedding (f ≫ g)) + IsOpenEmbedding.of_comp _ (Scheme.Hom.isOpenEmbedding g) (Scheme.Hom.isOpenEmbedding (f ≫ g)) theorem iff_stalk_iso {X Y : Scheme.{u}} (f : X ⟶ Y) : - IsOpenImmersion f ↔ OpenEmbedding f.base ∧ ∀ x, IsIso (f.stalkMap x) := + IsOpenImmersion f ↔ IsOpenEmbedding f.base ∧ ∀ x, IsIso (f.stalkMap x) := ⟨fun H => ⟨H.1, fun x ↦ inferInstanceAs <| IsIso (f.toPshHom.stalkMap x)⟩, fun ⟨h₁, h₂⟩ => @IsOpenImmersion.of_stalk_iso _ _ f h₁ h₂⟩ @@ -391,7 +394,7 @@ theorem _root_.AlgebraicGeometry.isIso_iff_stalk_iso {X Y : Scheme.{u}} (f : X (Equiv.ofBijective _ ⟨h₂.inj, (TopCat.epi_iff_surjective _).mp h₁⟩) h₂.continuous h₂.isOpenMap)).hom infer_instance - · intro H; exact ⟨inferInstance, (TopCat.homeoOfIso (asIso f.base)).openEmbedding⟩ + · intro H; exact ⟨inferInstance, (TopCat.homeoOfIso (asIso f.base)).isOpenEmbedding⟩ /-- An open immersion induces an isomorphism from the domain onto the image -/ def isoRestrict : X ≅ (Z.restrict H.base_open : _) := diff --git a/Mathlib/AlgebraicGeometry/PrimeSpectrum/Basic.lean b/Mathlib/AlgebraicGeometry/PrimeSpectrum/Basic.lean index 05c884eb52c603..f918a39487b28a 100644 --- a/Mathlib/AlgebraicGeometry/PrimeSpectrum/Basic.lean +++ b/Mathlib/AlgebraicGeometry/PrimeSpectrum/Basic.lean @@ -457,13 +457,16 @@ theorem localization_away_comap_range (S : Type v) [CommSemiring S] [Algebra R S · rintro h₁ _ ⟨⟨n, rfl⟩, h₃⟩ exact h₁ (x.2.mem_of_pow_mem _ h₃) -theorem localization_away_openEmbedding (S : Type v) [CommSemiring S] [Algebra R S] (r : R) - [IsLocalization.Away r S] : OpenEmbedding (comap (algebraMap R S)) := +theorem localization_away_isOpenEmbedding (S : Type v) [CommSemiring S] [Algebra R S] (r : R) + [IsLocalization.Away r S] : IsOpenEmbedding (comap (algebraMap R S)) := { toEmbedding := localization_comap_embedding S (Submonoid.powers r) isOpen_range := by rw [localization_away_comap_range S r] exact isOpen_basicOpen } +@[deprecated (since := "2024-10-18")] +alias localization_away_openEmbedding := localization_away_isOpenEmbedding + theorem isCompact_basicOpen (f : R) : IsCompact (basicOpen f : Set (PrimeSpectrum R)) := by rw [← localization_away_comap_range (Localization (Submonoid.powers f))] exact isCompact_range (map_continuous _) diff --git a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean index 77da59dbcba244..dae30030d35070 100644 --- a/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean +++ b/Mathlib/AlgebraicGeometry/ProjectiveSpectrum/Scheme.lean @@ -122,12 +122,13 @@ local notation3 "Proj.T" => PresheafedSpace.carrier <| SheafedSpace.toPresheafed /-- `Proj` restrict to some open set -/ macro "Proj| " U:term : term => - `((Proj.toLocallyRingedSpace 𝒜).restrict (Opens.openEmbedding (X := Proj.T) ($U : Opens Proj.T))) + `((Proj.toLocallyRingedSpace 𝒜).restrict + (Opens.isOpenEmbedding (X := Proj.T) ($U : Opens Proj.T))) /-- the underlying topological space of `Proj` restricted to some open set -/ local notation "Proj.T| " U => PresheafedSpace.carrier <| SheafedSpace.toPresheafedSpace <| LocallyRingedSpace.toSheafedSpace - <| (LocallyRingedSpace.restrict Proj (Opens.openEmbedding (X := Proj.T) (U : Opens Proj.T))) + <| (LocallyRingedSpace.restrict Proj (Opens.isOpenEmbedding (X := Proj.T) (U : Opens Proj.T))) /-- basic open sets in `Proj` -/ local notation "pbo " x => ProjectiveSpectrum.basicOpen 𝒜 x @@ -610,13 +611,13 @@ Mathematically, the map is the same as `awayToSection`. -/ def awayToΓ (f) : CommRingCat.of (A⁰_ f) ⟶ LocallyRingedSpace.Γ.obj (op <| Proj| pbo f) := awayToSection 𝒜 f ≫ (ProjectiveSpectrum.Proj.structureSheaf 𝒜).1.map - (homOfLE (Opens.openEmbedding_obj_top _).le).op + (homOfLE (Opens.isOpenEmbedding_obj_top _).le).op lemma awayToΓ_ΓToStalk (f) (x) : awayToΓ 𝒜 f ≫ (Proj| pbo f).presheaf.Γgerm x = HomogeneousLocalization.mapId 𝒜 (Submonoid.powers_le.mpr x.2) ≫ (Proj.stalkIso' 𝒜 x.1).toCommRingCatIso.inv ≫ - ((Proj.toLocallyRingedSpace 𝒜).restrictStalkIso (Opens.openEmbedding _) x).inv := by + ((Proj.toLocallyRingedSpace 𝒜).restrictStalkIso (Opens.isOpenEmbedding _) x).inv := by rw [awayToΓ, Category.assoc, ← Category.assoc _ (Iso.inv _), Iso.eq_comp_inv, Category.assoc, Category.assoc, Presheaf.Γgerm] rw [LocallyRingedSpace.restrictStalkIso_hom_eq_germ] @@ -781,7 +782,7 @@ lemma toStalk_specStalkEquiv (f) (x : pbo f) {m} (f_deg : f ∈ 𝒜 m) (hm : 0 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 ≫ - ((Proj.toLocallyRingedSpace 𝒜).restrictStalkIso (Opens.openEmbedding _) x).inv := + ((Proj.toLocallyRingedSpace 𝒜).restrictStalkIso (Opens.isOpenEmbedding _) x).inv := IsLocalization.ringHom_ext (R := A⁰_ f) ((toSpec 𝒜 f).base x).asIdeal.primeCompl (S := (Spec.structureSheaf (A⁰_ f)).presheaf.stalk ((toSpec 𝒜 f).base x)) <| (toStalk_stalkMap_toSpec _ _ _).trans <| by @@ -794,7 +795,7 @@ lemma isIso_toSpec (f) {m} (f_deg : f ∈ 𝒜 m) (hm : 0 < m) : rw [stalkMap_toSpec 𝒜 f x f_deg hm]; infer_instance haveI : LocallyRingedSpace.IsOpenImmersion (toSpec 𝒜 f) := LocallyRingedSpace.IsOpenImmersion.of_stalk_iso (toSpec 𝒜 f) - (TopCat.homeoOfIso (asIso <| (toSpec 𝒜 f).base)).openEmbedding + (TopCat.homeoOfIso (asIso <| (toSpec 𝒜 f).base)).isOpenEmbedding exact LocallyRingedSpace.IsOpenImmersion.to_iso _ end ProjectiveSpectrum.Proj diff --git a/Mathlib/AlgebraicGeometry/Properties.lean b/Mathlib/AlgebraicGeometry/Properties.lean index a5bbb08d90c154..84f113a767c022 100644 --- a/Mathlib/AlgebraicGeometry/Properties.lean +++ b/Mathlib/AlgebraicGeometry/Properties.lean @@ -39,8 +39,8 @@ instance : QuasiSober X := by quasiSober_of_open_cover (Set.range fun x => Set.range <| (X.affineCover.map x).base) · rintro ⟨_, i, rfl⟩; exact (X.affineCover.IsOpen i).base_open.isOpen_range · rintro ⟨_, i, rfl⟩ - exact @OpenEmbedding.quasiSober _ _ _ _ _ (Homeomorph.ofEmbedding _ - (X.affineCover.IsOpen i).base_open.toEmbedding).symm.openEmbedding PrimeSpectrum.quasiSober + exact @IsOpenEmbedding.quasiSober _ _ _ _ _ (Homeomorph.ofEmbedding _ + (X.affineCover.IsOpen i).base_open.toEmbedding).symm.isOpenEmbedding PrimeSpectrum.quasiSober · rw [Set.top_eq_univ, Set.sUnion_range, Set.eq_univ_iff_forall] intro x; exact ⟨_, ⟨_, rfl⟩, X.affineCover.covers x⟩ diff --git a/Mathlib/AlgebraicGeometry/Restrict.lean b/Mathlib/AlgebraicGeometry/Restrict.lean index 3eadf0265e3fc8..2e8d4801e0e781 100644 --- a/Mathlib/AlgebraicGeometry/Restrict.lean +++ b/Mathlib/AlgebraicGeometry/Restrict.lean @@ -41,7 +41,7 @@ namespace Scheme.Opens /-- Open subset of a scheme as a scheme. -/ @[coe] def toScheme {X : Scheme.{u}} (U : X.Opens) : Scheme.{u} := - X.restrict U.openEmbedding + X.restrict U.isOpenEmbedding instance : CoeOut X.Opens Scheme := ⟨toScheme⟩ @@ -85,7 +85,7 @@ lemma range_ι : Set.range U.ι.base = U := Subtype.range_val lemma ι_image_top : U.ι ''ᵁ ⊤ = U := - U.openEmbedding_obj_top + U.isOpenEmbedding_obj_top lemma ι_image_le (W : U.toScheme.Opens) : U.ι ''ᵁ W ≤ U := by simp_rw [← U.ι_image_top] @@ -105,7 +105,7 @@ lemma ι_app_self : U.ι.app U = X.presheaf.map (eqToHom (X := U.ι ''ᵁ _) (by lemma eq_presheaf_map_eqToHom {V W : Opens U} (e : U.ι ''ᵁ V = U.ι ''ᵁ W) : X.presheaf.map (eqToHom e).op = - U.toScheme.presheaf.map (eqToHom <| U.openEmbedding.functor_obj_injective e).op := rfl + U.toScheme.presheaf.map (eqToHom <| U.isOpenEmbedding.functor_obj_injective e).op := rfl @[simp] lemma nonempty_iff : Nonempty U.toScheme ↔ (U : Set X).Nonempty := by @@ -121,20 +121,20 @@ def topIso : Γ(U, ⊤) ≅ Γ(X, U) := /-- The stalks of an open subscheme are isomorphic to the stalks of the original scheme. -/ def stalkIso {X : Scheme.{u}} (U : X.Opens) (x : U) : U.toScheme.presheaf.stalk x ≅ X.presheaf.stalk x.1 := - X.restrictStalkIso (Opens.openEmbedding _) _ + X.restrictStalkIso (Opens.isOpenEmbedding _) _ @[reassoc (attr := simp)] lemma germ_stalkIso_hom {X : Scheme.{u}} (U : X.Opens) {V : U.toScheme.Opens} (x : U) (hx : x ∈ V) : U.toScheme.presheaf.germ V x hx ≫ (U.stalkIso x).hom = X.presheaf.germ (U.ι ''ᵁ V) x.1 ⟨x, hx, rfl⟩ := - PresheafedSpace.restrictStalkIso_hom_eq_germ _ U.openEmbedding _ _ _ + PresheafedSpace.restrictStalkIso_hom_eq_germ _ U.isOpenEmbedding _ _ _ @[reassoc] lemma germ_stalkIso_inv {X : Scheme.{u}} (U : X.Opens) (V : U.toScheme.Opens) (x : U) (hx : x ∈ V) : X.presheaf.germ (U.ι ''ᵁ V) x ⟨x, hx, rfl⟩ ≫ (U.stalkIso x).inv = U.toScheme.presheaf.germ V x hx := - PresheafedSpace.restrictStalkIso_inv_eq_germ X.toPresheafedSpace U.openEmbedding V x hx + PresheafedSpace.restrictStalkIso_inv_eq_germ X.toPresheafedSpace U.isOpenEmbedding V x hx end Scheme.Opens @@ -168,9 +168,9 @@ instance ΓRestrictAlgebra {X : Scheme.{u}} (U : X.Opens) : lemma Scheme.map_basicOpen' (r : Γ(U, ⊤)) : U.ι ''ᵁ (U.toScheme.basicOpen r) = X.basicOpen - (X.presheaf.map (eqToHom U.openEmbedding_obj_top.symm).op r) := by - refine (Scheme.image_basicOpen (X.ofRestrict U.openEmbedding) r).trans ?_ - rw [← Scheme.basicOpen_res_eq _ _ (eqToHom U.openEmbedding_obj_top).op] + (X.presheaf.map (eqToHom U.isOpenEmbedding_obj_top.symm).op r) := by + refine (Scheme.image_basicOpen (X.ofRestrict U.isOpenEmbedding) r).trans ?_ + rw [← Scheme.basicOpen_res_eq _ _ (eqToHom U.isOpenEmbedding_obj_top).op] rw [← comp_apply, ← CategoryTheory.Functor.map_comp, ← op_comp, eqToHom_trans, eqToHom_refl, op_id, CategoryTheory.Functor.map_id] congr @@ -231,7 +231,7 @@ theorem Scheme.restrictFunctor_map_ofRestrict {U V : X.Opens} (i : U ⟶ V) : theorem Scheme.restrictFunctor_map_base {U V : X.Opens} (i : U ⟶ V) : (X.restrictFunctor.map i).left.base = (Opens.toTopCat _).map i := by ext a; refine Subtype.ext ?_ -- Porting note: `ext` did not pick up `Subtype.ext` - exact (congr_arg (fun f : X.restrict U.openEmbedding ⟶ X => f.base a) + exact (congr_arg (fun f : X.restrict U.isOpenEmbedding ⟶ X => f.base a) (X.restrictFunctor_map_ofRestrict i)) theorem Scheme.restrictFunctor_map_app_aux {U V : X.Opens} (i : U ⟶ V) (W : Opens V) : @@ -258,7 +258,7 @@ isomorphic to the structure sheaf. -/ @[simps!] def Scheme.restrictFunctorΓ : X.restrictFunctor.op ⋙ (Over.forget X).op ⋙ Scheme.Γ ≅ X.presheaf := NatIso.ofComponents - (fun U => X.presheaf.mapIso ((eqToIso (unop U).openEmbedding_obj_top).symm.op : _)) + (fun U => X.presheaf.mapIso ((eqToIso (unop U).isOpenEmbedding_obj_top).symm.op : _)) (by intro U V i dsimp @@ -348,7 +348,7 @@ theorem isPullback_morphismRestrict {X Y : Scheme.{u}} (f : X ⟶ Y) (U : Y.Open rw [← Category.id_comp f] refine (IsPullback.of_horiz_isIso ⟨?_⟩).paste_horiz - (IsPullback.of_hasPullback f (Y.ofRestrict U.openEmbedding)).flip + (IsPullback.of_hasPullback f (Y.ofRestrict U.isOpenEmbedding)).flip -- Porting note: changed `rw` to `erw` erw [pullbackRestrictIsoRestrict_inv_fst]; rw [Category.comp_id] @@ -434,8 +434,8 @@ theorem morphismRestrict_appLE {X Y : Scheme.{u}} (f : X ⟶ Y) (U : Y.Opens) (V theorem Γ_map_morphismRestrict {X Y : Scheme.{u}} (f : X ⟶ Y) (U : Y.Opens) : Scheme.Γ.map (f ∣_ U).op = - Y.presheaf.map (eqToHom U.openEmbedding_obj_top.symm).op ≫ - f.app U ≫ X.presheaf.map (eqToHom (f ⁻¹ᵁ U).openEmbedding_obj_top).op := by + Y.presheaf.map (eqToHom U.isOpenEmbedding_obj_top.symm).op ≫ + f.app U ≫ X.presheaf.map (eqToHom (f ⁻¹ᵁ U).isOpenEmbedding_obj_top).op := by rw [Scheme.Γ_map_op, morphismRestrict_app f U ⊤, f.naturality_assoc, ← X.presheaf.map_comp] rfl @@ -486,7 +486,7 @@ def morphismRestrictRestrict {X Y : Scheme.{u}} (f : X ⟶ Y) (U : Y.Opens) (V : /-- Restricting a morphism twice onto a basic open set is isomorphic to one restriction. -/ def morphismRestrictRestrictBasicOpen {X Y : Scheme.{u}} (f : X ⟶ Y) (U : Y.Opens) (r : Γ(Y, U)) : Arrow.mk (f ∣_ U ∣_ - U.toScheme.basicOpen (Y.presheaf.map (eqToHom U.openEmbedding_obj_top).op r)) ≅ + U.toScheme.basicOpen (Y.presheaf.map (eqToHom U.isOpenEmbedding_obj_top).op r)) ≅ Arrow.mk (f ∣_ Y.basicOpen r) := by refine morphismRestrictRestrict _ _ _ ≪≫ morphismRestrictEq _ ?_ have e := Scheme.preimage_basicOpen U.ι r diff --git a/Mathlib/AlgebraicGeometry/Scheme.lean b/Mathlib/AlgebraicGeometry/Scheme.lean index d77a37bef9383a..18cc563e905617 100644 --- a/Mathlib/AlgebraicGeometry/Scheme.lean +++ b/Mathlib/AlgebraicGeometry/Scheme.lean @@ -46,7 +46,7 @@ structure Scheme extends LocallyRingedSpace where ∀ x : toLocallyRingedSpace, ∃ (U : OpenNhds x) (R : CommRingCat), Nonempty - (toLocallyRingedSpace.restrict U.openEmbedding ≅ Spec.toLocallyRingedSpace.obj (op R)) + (toLocallyRingedSpace.restrict U.isOpenEmbedding ≅ Spec.toLocallyRingedSpace.obj (op R)) namespace Scheme diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Manifold.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Manifold.lean index 2bc3767cffe152..45772d8d62ff68 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Manifold.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Manifold.lean @@ -19,10 +19,10 @@ open scoped UpperHalfPlane Manifold namespace UpperHalfPlane noncomputable instance : ChartedSpace ℂ ℍ := - UpperHalfPlane.openEmbedding_coe.singletonChartedSpace + UpperHalfPlane.isOpenEmbedding_coe.singletonChartedSpace instance : SmoothManifoldWithCorners 𝓘(ℂ) ℍ := - UpperHalfPlane.openEmbedding_coe.singleton_smoothManifoldWithCorners 𝓘(ℂ) + UpperHalfPlane.isOpenEmbedding_coe.singleton_smoothManifoldWithCorners 𝓘(ℂ) /-- The inclusion map `ℍ → ℂ` is a smooth map of manifolds. -/ theorem smooth_coe : Smooth 𝓘(ℂ) 𝓘(ℂ) ((↑) : ℍ → ℂ) := fun _ => contMDiffAt_extChartAt diff --git a/Mathlib/Analysis/Complex/UpperHalfPlane/Topology.lean b/Mathlib/Analysis/Complex/UpperHalfPlane/Topology.lean index caecc196aeb8d7..8aec80774131bd 100644 --- a/Mathlib/Analysis/Complex/UpperHalfPlane/Topology.lean +++ b/Mathlib/Analysis/Complex/UpperHalfPlane/Topology.lean @@ -30,8 +30,11 @@ namespace UpperHalfPlane instance : TopologicalSpace ℍ := instTopologicalSpaceSubtype -theorem openEmbedding_coe : OpenEmbedding ((↑) : ℍ → ℂ) := - IsOpen.openEmbedding_subtype_val <| isOpen_lt continuous_const Complex.continuous_im +theorem isOpenEmbedding_coe : IsOpenEmbedding ((↑) : ℍ → ℂ) := + IsOpen.isOpenEmbedding_subtypeVal <| isOpen_lt continuous_const Complex.continuous_im + +@[deprecated (since := "2024-10-18")] +alias openEmbedding_coe := isOpenEmbedding_coe theorem embedding_coe : Embedding ((↑) : ℍ → ℂ) := embedding_subtype_val @@ -55,7 +58,7 @@ instance : T4Space ℍ := inferInstance instance : ContractibleSpace ℍ := (convex_halfspace_im_gt 0).contractibleSpace ⟨I, one_pos.trans_eq I_im.symm⟩ -instance : LocPathConnectedSpace ℍ := openEmbedding_coe.locPathConnectedSpace +instance : LocPathConnectedSpace ℍ := isOpenEmbedding_coe.locPathConnectedSpace instance : NoncompactSpace ℍ := by refine ⟨fun h => ?_⟩ @@ -65,7 +68,7 @@ instance : NoncompactSpace ℍ := by exact absurd ((this 0).1 (@left_mem_Ici ℝ _ 0)) (@lt_irrefl ℝ _ 0) instance : LocallyCompactSpace ℍ := - openEmbedding_coe.locallyCompactSpace + isOpenEmbedding_coe.locallyCompactSpace section strips @@ -118,13 +121,13 @@ theorem ModularGroup_T_zpow_mem_verticalStrip (z : ℍ) {N : ℕ} (hn : 0 < N) : end strips /-- A continuous section `ℂ → ℍ` of the natural inclusion map, bundled as a `PartialHomeomorph`. -/ -def ofComplex : PartialHomeomorph ℂ ℍ := (openEmbedding_coe.toPartialHomeomorph _).symm +def ofComplex : PartialHomeomorph ℂ ℍ := (isOpenEmbedding_coe.toPartialHomeomorph _).symm /-- Extend a function on `ℍ` arbitrarily to a function on all of `ℂ`. -/ scoped notation "↑ₕ" f => f ∘ ofComplex lemma ofComplex_apply (z : ℍ) : ofComplex (z : ℂ) = z := - OpenEmbedding.toPartialHomeomorph_left_inv .. + IsOpenEmbedding.toPartialHomeomorph_left_inv .. lemma ofComplex_apply_eq_ite (w : ℂ) : ofComplex w = if hw : 0 < w.im then ⟨w, hw⟩ else Classical.choice inferInstance := by diff --git a/Mathlib/Analysis/Normed/Ring/Units.lean b/Mathlib/Analysis/Normed/Ring/Units.lean index 86883d4c5d0171..eed32209f935a1 100644 --- a/Mathlib/Analysis/Normed/Ring/Units.lean +++ b/Mathlib/Analysis/Normed/Ring/Units.lean @@ -200,15 +200,18 @@ open MulOpposite Filter 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. -/ -theorem openEmbedding_val : OpenEmbedding (val : Rˣ → R) where +theorem isOpenEmbedding_val : IsOpenEmbedding (val : Rˣ → R) where toEmbedding := embedding_val_mk' (fun _ ⟨u, hu⟩ ↦ hu ▸ (inverse_continuousAt u).continuousWithinAt) Ring.inverse_unit isOpen_range := Units.isOpen +@[deprecated (since := "2024-10-18")] +alias openEmbedding_val := isOpenEmbedding_val + /-- 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 map. -/ theorem isOpenMap_val : IsOpenMap (val : Rˣ → R) := - openEmbedding_val.isOpenMap + isOpenEmbedding_val.isOpenMap end Units diff --git a/Mathlib/Analysis/SpecialFunctions/Exp.lean b/Mathlib/Analysis/SpecialFunctions/Exp.lean index 5d7dc418a5c497..9a02b4d3dc8037 100644 --- a/Mathlib/Analysis/SpecialFunctions/Exp.lean +++ b/Mathlib/Analysis/SpecialFunctions/Exp.lean @@ -369,16 +369,19 @@ theorem tendsto_exp_comp_nhds_zero {f : α → ℝ} : Tendsto (fun x => exp (f x)) l (𝓝 0) ↔ Tendsto f l atBot := by simp_rw [← comp_apply (f := exp), ← tendsto_comap_iff, comap_exp_nhds_zero] -theorem openEmbedding_exp : OpenEmbedding exp := - isOpen_Ioi.openEmbedding_subtype_val.comp expOrderIso.toHomeomorph.openEmbedding +theorem isOpenEmbedding_exp : IsOpenEmbedding exp := + isOpen_Ioi.isOpenEmbedding_subtypeVal.comp expOrderIso.toHomeomorph.isOpenEmbedding + +@[deprecated (since := "2024-10-18")] +alias openEmbedding_exp := isOpenEmbedding_exp @[simp] theorem map_exp_nhds (x : ℝ) : map exp (𝓝 x) = 𝓝 (exp x) := - openEmbedding_exp.map_nhds_eq x + isOpenEmbedding_exp.map_nhds_eq x @[simp] theorem comap_exp_nhds_exp (x : ℝ) : comap exp (𝓝 (exp x)) = 𝓝 x := - (openEmbedding_exp.nhds_eq_comap x).symm + (isOpenEmbedding_exp.nhds_eq_comap x).symm theorem isLittleO_pow_exp_atTop {n : ℕ} : (fun x : ℝ => x ^ n) =o[atTop] Real.exp := by simpa [isLittleO_iff_tendsto fun x hx => ((exp_pos x).ne' hx).elim] using diff --git a/Mathlib/Geometry/Manifold/ChartedSpace.lean b/Mathlib/Geometry/Manifold/ChartedSpace.lean index 5acd6a8cea119a..006514be874870 100644 --- a/Mathlib/Geometry/Manifold/ChartedSpace.lean +++ b/Mathlib/Geometry/Manifold/ChartedSpace.lean @@ -1049,7 +1049,7 @@ variable (e : PartialHomeomorph α H) /-- If a single partial homeomorphism `e` from a space `α` into `H` has source covering the whole space `α`, then that partial homeomorphism induces an `H`-charted space structure on `α`. (This condition is equivalent to `e` being an open embedding of `α` into `H`; see -`OpenEmbedding.singletonChartedSpace`.) -/ +`IsOpenEmbedding.singletonChartedSpace`.) -/ def singletonChartedSpace (h : e.source = Set.univ) : ChartedSpace H α where atlas := {e} chartAt _ := e @@ -1085,24 +1085,24 @@ theorem singleton_hasGroupoid (h : e.source = Set.univ) (G : StructureGroupoid H end PartialHomeomorph -namespace OpenEmbedding +namespace IsOpenEmbedding variable [Nonempty α] /-- An open embedding of `α` into `H` induces an `H`-charted space structure on `α`. See `PartialHomeomorph.singletonChartedSpace`. -/ -def singletonChartedSpace {f : α → H} (h : OpenEmbedding f) : ChartedSpace H α := +def singletonChartedSpace {f : α → H} (h : IsOpenEmbedding f) : ChartedSpace H α := (h.toPartialHomeomorph f).singletonChartedSpace (toPartialHomeomorph_source _ _) -theorem singletonChartedSpace_chartAt_eq {f : α → H} (h : OpenEmbedding f) {x : α} : +theorem singletonChartedSpace_chartAt_eq {f : α → H} (h : IsOpenEmbedding f) {x : α} : ⇑(@chartAt H _ α _ h.singletonChartedSpace x) = f := rfl -theorem singleton_hasGroupoid {f : α → H} (h : OpenEmbedding f) (G : StructureGroupoid H) +theorem singleton_hasGroupoid {f : α → H} (h : IsOpenEmbedding f) (G : StructureGroupoid H) [ClosedUnderRestriction G] : @HasGroupoid _ _ _ _ h.singletonChartedSpace G := (h.toPartialHomeomorph f).singleton_hasGroupoid (toPartialHomeomorph_source _ _) G -end OpenEmbedding +end IsOpenEmbedding end Singleton diff --git a/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean b/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean index cd4f4365ba286d..b79ff42cc1ad91 100644 --- a/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean +++ b/Mathlib/Geometry/Manifold/ContMDiff/Basic.lean @@ -13,7 +13,7 @@ In this file, we show that standard operations on smooth maps between smooth man * `contMDiff_id` gives the smoothness of the identity * `contMDiff_const` gives the smoothness of constant functions * `contMDiff_inclusion` shows that the inclusion between open sets of a topological space is smooth -* `contMDiff_openEmbedding` shows that if `M` has a `ChartedSpace` structure induced by an open +* `contMDiff_isOpenEmbedding` shows that if `M` has a `ChartedSpace` structure induced by an open embedding `e : M → H`, then `e` is smooth. ## Tags @@ -358,11 +358,11 @@ end ChartedSpace section -variable {e : M → H} (h : OpenEmbedding e) {n : WithTop ℕ} +variable {e : M → H} (h : IsOpenEmbedding e) {n : WithTop ℕ} /-- If the `ChartedSpace` structure on a manifold `M` is given by an open embedding `e : M → H`, then `e` is smooth. -/ -lemma contMDiff_openEmbedding [Nonempty M] : +lemma contMDiff_isOpenEmbedding [Nonempty M] : haveI := h.singletonChartedSpace; ContMDiff I I n e := by haveI := h.singleton_smoothManifoldWithCorners I rw [@contMDiff_iff _ _ _ _ _ _ _ _ _ _ h.singletonChartedSpace] @@ -385,12 +385,15 @@ lemma contMDiff_openEmbedding [Nonempty M] : h.toPartialHomeomorph_target] at this exact this +@[deprecated (since := "2024-10-18")] +alias contMDiff_openEmbedding := contMDiff_isOpenEmbedding + variable {I I'} /-- If the `ChartedSpace` structure on a manifold `M` is given by an open embedding `e : M → H`, then the inverse of `e` is smooth. -/ -lemma contMDiffOn_openEmbedding_symm [Nonempty M] : +lemma contMDiffOn_isOpenEmbedding_symm [Nonempty M] : haveI := h.singletonChartedSpace; ContMDiffOn I I - n (OpenEmbedding.toPartialHomeomorph e h).symm (range e) := by + n (IsOpenEmbedding.toPartialHomeomorph e h).symm (range e) := by haveI := h.singleton_smoothManifoldWithCorners I rw [@contMDiffOn_iff] constructor @@ -409,21 +412,27 @@ lemma contMDiffOn_openEmbedding_symm [Nonempty M] : apply I.right_inv exact mem_of_subset_of_mem (extChartAt_target_subset_range _ _) hz.1 +@[deprecated (since := "2024-10-18")] +alias contMDiffOn_openEmbedding_symm := contMDiffOn_isOpenEmbedding_symm + variable [ChartedSpace H M] -variable [Nonempty M'] {e' : M' → H'} (h' : OpenEmbedding e') +variable [Nonempty M'] {e' : M' → H'} (h' : IsOpenEmbedding e') /-- Let `M'` be a manifold whose chart structure is given by an open embedding `e'` into its model space `H'`. Then the smoothness of `e' ∘ f : M → H'` implies the smoothness of `f`. This is useful, for example, when `e' ∘ f = g ∘ e` for smooth maps `e : M → X` and `g : X → H'`. -/ -lemma ContMDiff.of_comp_openEmbedding {f : M → M'} (hf : ContMDiff I I' n (e' ∘ f)) : +lemma ContMDiff.of_comp_isOpenEmbedding {f : M → M'} (hf : ContMDiff I I' n (e' ∘ f)) : haveI := h'.singletonChartedSpace; ContMDiff I I' n f := by have : f = (h'.toPartialHomeomorph e').symm ∘ e' ∘ f := by ext - rw [Function.comp_apply, Function.comp_apply, OpenEmbedding.toPartialHomeomorph_left_inv] + rw [Function.comp_apply, Function.comp_apply, IsOpenEmbedding.toPartialHomeomorph_left_inv] rw [this] apply @ContMDiffOn.comp_contMDiff _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ - h'.singletonChartedSpace _ _ (range e') _ (contMDiffOn_openEmbedding_symm h') hf + h'.singletonChartedSpace _ _ (range e') _ (contMDiffOn_isOpenEmbedding_symm h') hf simp +@[deprecated (since := "2024-10-18")] +alias ContMDiff.of_comp_openEmbedding := ContMDiff.of_comp_isOpenEmbedding + end diff --git a/Mathlib/Geometry/Manifold/Instances/UnitsOfNormedAlgebra.lean b/Mathlib/Geometry/Manifold/Instances/UnitsOfNormedAlgebra.lean index e7690b95e11f07..afe2f7f2112cb8 100644 --- a/Mathlib/Geometry/Manifold/Instances/UnitsOfNormedAlgebra.lean +++ b/Mathlib/Geometry/Manifold/Instances/UnitsOfNormedAlgebra.lean @@ -33,7 +33,7 @@ namespace Units variable {R : Type*} [NormedRing R] [CompleteSpace R] instance : ChartedSpace R Rˣ := - openEmbedding_val.singletonChartedSpace + isOpenEmbedding_val.singletonChartedSpace theorem chartAt_apply {a : Rˣ} {b : Rˣ} : chartAt R a b = b := rfl @@ -44,17 +44,17 @@ theorem chartAt_source {a : Rˣ} : (chartAt R a).source = Set.univ := variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] [NormedAlgebra 𝕜 R] instance : SmoothManifoldWithCorners 𝓘(𝕜, R) Rˣ := - openEmbedding_val.singleton_smoothManifoldWithCorners 𝓘(𝕜, R) + isOpenEmbedding_val.singleton_smoothManifoldWithCorners 𝓘(𝕜, R) /-- For a complete normed ring `R`, the embedding of the units `Rˣ` into `R` is a smooth map between manifolds. -/ lemma contMDiff_val {m : ℕ∞} : ContMDiff 𝓘(𝕜, R) 𝓘(𝕜, R) m (val : Rˣ → R) := - contMDiff_openEmbedding 𝓘(𝕜, R) Units.openEmbedding_val + contMDiff_isOpenEmbedding 𝓘(𝕜, R) Units.isOpenEmbedding_val /-- The units of a complete normed ring form a Lie group. -/ instance : LieGroup 𝓘(𝕜, R) Rˣ where smooth_mul := by - apply ContMDiff.of_comp_openEmbedding Units.openEmbedding_val + apply ContMDiff.of_comp_isOpenEmbedding Units.isOpenEmbedding_val have : (val : Rˣ → R) ∘ (fun x : Rˣ × Rˣ => x.1 * x.2) = (fun x : R × R => x.1 * x.2) ∘ (fun x : Rˣ × Rˣ => (x.1, x.2)) := by ext; simp rw [this] @@ -65,7 +65,7 @@ instance : LieGroup 𝓘(𝕜, R) Rˣ where rw [contMDiff_iff_contDiff] exact contDiff_mul smooth_inv := by - apply ContMDiff.of_comp_openEmbedding Units.openEmbedding_val + apply ContMDiff.of_comp_isOpenEmbedding Units.isOpenEmbedding_val have : (val : Rˣ → R) ∘ (fun x : Rˣ => x⁻¹) = Ring.inverse ∘ val := by ext; simp rw [this, ContMDiff] refine fun x => ContMDiffAt.comp x ?_ (contMDiff_val x) diff --git a/Mathlib/Geometry/Manifold/LocalInvariantProperties.lean b/Mathlib/Geometry/Manifold/LocalInvariantProperties.lean index 5ea4b4a42e6b88..6b89039b66f570 100644 --- a/Mathlib/Geometry/Manifold/LocalInvariantProperties.lean +++ b/Mathlib/Geometry/Manifold/LocalInvariantProperties.lean @@ -490,7 +490,7 @@ theorem liftPropAt_iff_comp_subtype_val (hG : LocalInvariantProp G G' P) {U : Op LiftPropAt P f x ↔ LiftPropAt P (f ∘ Subtype.val) x := by simp only [LiftPropAt, liftPropWithinAt_iff'] congrm ?_ ∧ ?_ - · simp_rw [continuousWithinAt_univ, U.openEmbedding'.continuousAt_iff] + · simp_rw [continuousWithinAt_univ, U.isOpenEmbedding'.continuousAt_iff] · apply hG.congr_iff exact (U.chartAt_subtype_val_symm_eventuallyEq).fun_comp (chartAt H' (f x) ∘ f) @@ -500,7 +500,7 @@ theorem liftPropAt_iff_comp_inclusion (hG : LocalInvariantProp G G' P) {U V : Op simp only [LiftPropAt, liftPropWithinAt_iff'] congrm ?_ ∧ ?_ · simp_rw [continuousWithinAt_univ, - (TopologicalSpace.Opens.openEmbedding_of_le hUV).continuousAt_iff] + (TopologicalSpace.Opens.isOpenEmbedding_of_le hUV).continuousAt_iff] · apply hG.congr_iff exact (TopologicalSpace.Opens.chartAt_inclusion_symm_eventuallyEq hUV).fun_comp (chartAt H' (f (Set.inclusion hUV x)) ∘ f) diff --git a/Mathlib/Geometry/Manifold/SmoothManifoldWithCorners.lean b/Mathlib/Geometry/Manifold/SmoothManifoldWithCorners.lean index d6cebfb34829fb..ac7279ed0be9ca 100644 --- a/Mathlib/Geometry/Manifold/SmoothManifoldWithCorners.lean +++ b/Mathlib/Geometry/Manifold/SmoothManifoldWithCorners.lean @@ -724,13 +724,17 @@ theorem PartialHomeomorph.singleton_smoothManifoldWithCorners @SmoothManifoldWithCorners.mk' _ _ _ _ _ _ _ _ _ _ (id _) <| e.singleton_hasGroupoid h (contDiffGroupoid ∞ I) -theorem OpenEmbedding.singleton_smoothManifoldWithCorners {𝕜 : Type*} [NontriviallyNormedField 𝕜] +theorem IsOpenEmbedding.singleton_smoothManifoldWithCorners {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) {M : Type*} [TopologicalSpace M] [Nonempty M] {f : M → H} - (h : OpenEmbedding f) : + (h : IsOpenEmbedding f) : @SmoothManifoldWithCorners 𝕜 _ E _ _ H _ I M _ h.singletonChartedSpace := (h.toPartialHomeomorph f).singleton_smoothManifoldWithCorners I (by simp) +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.singleton_smoothManifoldWithCorners := + IsOpenEmbedding.singleton_smoothManifoldWithCorners + namespace TopologicalSpace.Opens open TopologicalSpace diff --git a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean index f0aedb017be003..2fc0a8b8893ef7 100644 --- a/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean +++ b/Mathlib/Geometry/RingedSpace/LocallyRingedSpace.lean @@ -217,8 +217,8 @@ instance is_sheafedSpace_iso {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) [IsIso /-- The restriction of a locally ringed space along an open embedding. -/ @[simps!] -def restrict {U : TopCat} (X : LocallyRingedSpace.{u}) {f : U ⟶ X.toTopCat} (h : OpenEmbedding f) : - LocallyRingedSpace where +def restrict {U : TopCat} (X : LocallyRingedSpace.{u}) {f : U ⟶ X.toTopCat} + (h : IsOpenEmbedding f) : LocallyRingedSpace where localRing := by intro x -- We show that the stalk of the restriction is isomorphic to the original stalk, @@ -228,13 +228,13 @@ def restrict {U : TopCat} (X : LocallyRingedSpace.{u}) {f : U ⟶ X.toTopCat} (h /-- The canonical map from the restriction to the subspace. -/ def ofRestrict {U : TopCat} (X : LocallyRingedSpace.{u}) - {f : U ⟶ X.toTopCat} (h : OpenEmbedding f) : X.restrict h ⟶ X := + {f : U ⟶ X.toTopCat} (h : IsOpenEmbedding f) : X.restrict h ⟶ X := ⟨X.toPresheafedSpace.ofRestrict h, fun _ => inferInstance⟩ /-- The restriction of a locally ringed space `X` to the top subspace is isomorphic to `X` itself. -/ def restrictTopIso (X : LocallyRingedSpace.{u}) : - X.restrict (Opens.openEmbedding ⊤) ≅ X := + X.restrict (Opens.isOpenEmbedding ⊤) ≅ X := isoOfSheafedSpaceIso X.toSheafedSpace.restrictTopIso /-- The global sections, notated Gamma. @@ -436,7 +436,7 @@ theorem preimage_basicOpen {X Y : LocallyRingedSpace.{u}} (f : X ⟶ Y) {U : Ope rw [← stalkMap_germ_apply] at hx exact (isUnit_map_iff (f.toShHom.stalkMap _) _).mp hx -variable {U : TopCat} (X : LocallyRingedSpace.{u}) {f : U ⟶ X.toTopCat} (h : OpenEmbedding f) +variable {U : TopCat} (X : LocallyRingedSpace.{u}) {f : U ⟶ X.toTopCat} (h : IsOpenEmbedding f) (V : Opens U) (x : U) (hx : x ∈ V) /-- For an open embedding `f : U ⟶ X` and a point `x : U`, we get an isomorphism between the stalk diff --git a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean index 11dbae9b63d30f..f549a8e9ee8416 100644 --- a/Mathlib/Geometry/RingedSpace/OpenImmersion.lean +++ b/Mathlib/Geometry/RingedSpace/OpenImmersion.lean @@ -68,7 +68,7 @@ spaces, such that the sheaf map `Y(V) ⟶ f _* X(V)` is an iso for each `V ⊆ U class PresheafedSpace.IsOpenImmersion {X Y : PresheafedSpace C} (f : X ⟶ Y) : Prop where /-- the underlying continuous map of underlying spaces from the source to an open subset of the target. -/ - base_open : OpenEmbedding f.base + base_open : IsOpenEmbedding f.base /-- the underlying sheaf morphism is an isomorphism on each open subset -/ c_iso : ∀ U : Opens X, IsIso (f.c.app (op (base_open.isOpenMap.functor.obj U))) @@ -214,7 +214,7 @@ theorem app_inv_app' (U : Opens Y) (hU : (U : Set Y) ⊆ Set.range f.base) : /-- An isomorphism is an open immersion. -/ instance ofIso {X Y : PresheafedSpace C} (H : X ≅ Y) : IsOpenImmersion H.hom where - base_open := (TopCat.homeoOfIso ((forget C).mapIso H)).openEmbedding + base_open := (TopCat.homeoOfIso ((forget C).mapIso H)).isOpenEmbedding -- Porting note: `inferInstance` will fail if Lean is not told that `H.hom.c` is iso c_iso _ := letI : IsIso H.hom.c := c_isIso_of_iso H.hom; inferInstance @@ -223,7 +223,7 @@ instance (priority := 100) ofIsIso {X Y : PresheafedSpace C} (f : X ⟶ Y) [IsIs AlgebraicGeometry.PresheafedSpace.IsOpenImmersion.ofIso (asIso f) instance ofRestrict {X : TopCat} (Y : PresheafedSpace C) {f : X ⟶ Y.carrier} - (hf : OpenEmbedding f) : IsOpenImmersion (Y.ofRestrict hf) where + (hf : IsOpenEmbedding f) : IsOpenImmersion (Y.ofRestrict hf) where base_open := hf c_iso U := by dsimp @@ -243,7 +243,7 @@ instance ofRestrict {X : TopCat} (Y : PresheafedSpace C) {f : X ⟶ Y.carrier} @[elementwise, simp] theorem ofRestrict_invApp {C : Type*} [Category C] (X : PresheafedSpace C) {Y : TopCat} - {f : Y ⟶ TopCat.of X.carrier} (h : OpenEmbedding f) (U : Opens (X.restrict h).carrier) : + {f : Y ⟶ TopCat.of X.carrier} (h : IsOpenEmbedding f) (U : Opens (X.restrict h).carrier) : (PresheafedSpace.IsOpenImmersion.ofRestrict X h).invApp _ U = 𝟙 _ := by delta invApp rw [IsIso.comp_inv_eq, Category.id_comp] @@ -286,7 +286,7 @@ variable {X Y Z : PresheafedSpace C} (f : X ⟶ Z) [hf : IsOpenImmersion f] (g : /-- (Implementation.) The projection map when constructing the pullback along an open immersion. -/ def pullbackConeOfLeftFst : - Y.restrict (TopCat.snd_openEmbedding_of_left_openEmbedding hf.base_open g.base) ⟶ X where + Y.restrict (TopCat.snd_isOpenEmbedding_of_left hf.base_open g.base) ⟶ X where base := pullback.fst _ _ c := { app := fun U => @@ -377,7 +377,7 @@ def pullbackConeOfLeftLift : s.pt ⟶ (pullbackConeOfLeft f g).pt where dsimp [s'] rw [Function.comp_def, ← Set.preimage_preimage] rw [Set.preimage_image_eq _ - (TopCat.snd_openEmbedding_of_left_openEmbedding hf.base_open g.base).inj] + (TopCat.snd_isOpenEmbedding_of_left hf.base_open g.base).inj] rfl)) naturality := fun U V i => by erw [s.snd.c.naturality_assoc] @@ -727,7 +727,7 @@ whose forgetful functor reflects isomorphisms, preserves limits and filtered col Then a morphism `X ⟶ Y` that is a topological open embedding is an open immersion iff every stalk map is an iso. -/ -theorem of_stalk_iso {X Y : SheafedSpace C} (f : X ⟶ Y) (hf : OpenEmbedding f.base) +theorem of_stalk_iso {X Y : SheafedSpace C} (f : X ⟶ Y) (hf : IsOpenEmbedding f.base) [H : ∀ x : X.1, IsIso (f.stalkMap x)] : SheafedSpace.IsOpenImmersion f := { base_open := hf c_iso := fun U => by @@ -738,7 +738,7 @@ theorem of_stalk_iso {X Y : SheafedSpace C} (f : X ⟶ Y) (hf : OpenEmbedding f. specialize H y delta PresheafedSpace.Hom.stalkMap at H haveI H' := - TopCat.Presheaf.stalkPushforward.stalkPushforward_iso_of_openEmbedding C hf X.presheaf y + TopCat.Presheaf.stalkPushforward.stalkPushforward_iso_of_isOpenEmbedding C hf X.presheaf y have := IsIso.comp_isIso' H (@IsIso.inv_isIso _ _ _ _ _ H') rwa [Category.assoc, IsIso.hom_inv_id, Category.comp_id] at this } @@ -812,12 +812,12 @@ theorem app_inv_app' (U : Opens Y) (hU : (U : Set Y) ⊆ Set.range f.base) : PresheafedSpace.IsOpenImmersion.app_invApp f U instance ofRestrict {X : TopCat} (Y : SheafedSpace C) {f : X ⟶ Y.carrier} - (hf : OpenEmbedding f) : IsOpenImmersion (Y.ofRestrict hf) := + (hf : IsOpenEmbedding f) : IsOpenImmersion (Y.ofRestrict hf) := PresheafedSpace.IsOpenImmersion.ofRestrict _ hf @[elementwise, simp] theorem ofRestrict_invApp {C : Type*} [Category C] (X : SheafedSpace C) {Y : TopCat} - {f : Y ⟶ TopCat.of X.carrier} (h : OpenEmbedding f) (U : Opens (X.restrict h).carrier) : + {f : Y ⟶ TopCat.of X.carrier} (h : IsOpenEmbedding f) (U : Opens (X.restrict h).carrier) : (SheafedSpace.IsOpenImmersion.ofRestrict X h).invApp _ U = 𝟙 _ := PresheafedSpace.IsOpenImmersion.ofRestrict_invApp _ h U @@ -839,7 +839,7 @@ section Prod variable [HasLimits C] {ι : Type v} (F : Discrete ι ⥤ SheafedSpace.{_, v, v} C) [HasColimit F] (i : Discrete ι) -theorem sigma_ι_openEmbedding : OpenEmbedding (colimit.ι F i).base := by +theorem sigma_ι_isOpenEmbedding : IsOpenEmbedding (colimit.ι F i).base := by rw [← show _ = (colimit.ι F i).base from ι_preservesColimitsIso_inv (SheafedSpace.forget C) F i] have : _ = _ ≫ colimit.ι (Discrete.functor ((F ⋙ SheafedSpace.forget C).obj ∘ Discrete.mk)) i := HasColimit.isoOfNatIso_ι_hom Discrete.natIsoFunctor i @@ -850,17 +850,20 @@ theorem sigma_ι_openEmbedding : OpenEmbedding (colimit.ι F i).base := by rw [← Iso.eq_comp_inv] at this cases i rw [this, ← Category.assoc] - -- Porting note: `simp_rw` can't use `TopCat.openEmbedding_iff_comp_isIso` and - -- `TopCat.openEmbedding_iff_isIso_comp`. + -- Porting note: `simp_rw` can't use `TopCat.isOpenEmbedding_iff_comp_isIso` and + -- `TopCat.isOpenEmbedding_iff_isIso_comp`. -- See https://github.com/leanprover-community/mathlib4/issues/5026 - erw [TopCat.openEmbedding_iff_comp_isIso, TopCat.openEmbedding_iff_comp_isIso, - TopCat.openEmbedding_iff_comp_isIso, TopCat.openEmbedding_iff_isIso_comp] - exact openEmbedding_sigmaMk + erw [TopCat.isOpenEmbedding_iff_comp_isIso, TopCat.isOpenEmbedding_iff_comp_isIso, + TopCat.isOpenEmbedding_iff_comp_isIso, TopCat.isOpenEmbedding_iff_isIso_comp] + exact isOpenEmbedding_sigmaMk + +@[deprecated (since := "2024-10-18")] +alias sigma_ι_openEmbedding := sigma_ι_isOpenEmbedding theorem image_preimage_is_empty (j : Discrete ι) (h : i ≠ j) (U : Opens (F.obj i)) : (Opens.map (colimit.ι (F ⋙ SheafedSpace.forgetToPresheafedSpace) j).base).obj ((Opens.map (preservesColimitIso SheafedSpace.forgetToPresheafedSpace F).inv.base).obj - ((sigma_ι_openEmbedding F i).isOpenMap.functor.obj U)) = + ((sigma_ι_isOpenEmbedding F i).isOpenMap.functor.obj U)) = ⊥ := by ext x apply iff_false_intro @@ -880,15 +883,15 @@ theorem image_preimage_is_empty (j : Discrete ι) (h : i ≠ j) (U : Opens (F.ob instance sigma_ι_isOpenImmersion [HasStrictTerminalObjects C] : SheafedSpace.IsOpenImmersion (colimit.ι F i) where - base_open := sigma_ι_openEmbedding F i + base_open := sigma_ι_isOpenEmbedding F i c_iso U := by have e : colimit.ι F i = _ := (ι_preservesColimitsIso_inv SheafedSpace.forgetToPresheafedSpace F i).symm have H : - OpenEmbedding + IsOpenEmbedding (colimit.ι (F ⋙ SheafedSpace.forgetToPresheafedSpace) i ≫ (preservesColimitIso SheafedSpace.forgetToPresheafedSpace F).inv).base := - e ▸ sigma_ι_openEmbedding F i + e ▸ sigma_ι_isOpenEmbedding F i suffices IsIso <| (colimit.ι (F ⋙ SheafedSpace.forgetToPresheafedSpace) i ≫ (preservesColimitIso SheafedSpace.forgetToPresheafedSpace F).inv).c.app <| op (H.isOpenMap.functor.obj U) by @@ -921,7 +924,7 @@ end SheafedSpace.IsOpenImmersion namespace LocallyRingedSpace.IsOpenImmersion -instance (X : LocallyRingedSpace) {U : TopCat} (f : U ⟶ X.toTopCat) (hf : OpenEmbedding f) : +instance (X : LocallyRingedSpace) {U : TopCat} (f : U ⟶ X.toTopCat) (hf : IsOpenEmbedding f) : LocallyRingedSpace.IsOpenImmersion (X.ofRestrict hf) := PresheafedSpace.IsOpenImmersion.ofRestrict X.toPresheafedSpace hf @@ -951,7 +954,7 @@ set_option synthInstance.maxHeartbeats 40000 in /-- An explicit pullback cone over `cospan f g` if `f` is an open immersion. -/ def pullbackConeOfLeft : PullbackCone f g := by refine PullbackCone.mk ?_ - (Y.ofRestrict (TopCat.snd_openEmbedding_of_left_openEmbedding H.base_open g.base)) ?_ + (Y.ofRestrict (TopCat.snd_isOpenEmbedding_of_left H.base_open g.base)) ?_ · use PresheafedSpace.IsOpenImmersion.pullbackConeOfLeftFst f.1 g.1 intro x have := PresheafedSpace.stalkMap.congr_hom _ _ @@ -1154,7 +1157,7 @@ whose forgetful functor reflects isomorphisms, preserves limits and filtered col Then a morphism `X ⟶ Y` that is a topological open embedding is an open immersion iff every stalk map is an iso. -/ -theorem of_stalk_iso {X Y : LocallyRingedSpace} (f : X ⟶ Y) (hf : OpenEmbedding f.base) +theorem of_stalk_iso {X Y : LocallyRingedSpace} (f : X ⟶ Y) (hf : IsOpenEmbedding f.base) [stalk_iso : ∀ x : X.1, IsIso (f.stalkMap x)] : LocallyRingedSpace.IsOpenImmersion f := SheafedSpace.IsOpenImmersion.of_stalk_iso _ hf (H := stalk_iso) @@ -1223,12 +1226,12 @@ theorem app_inv_app' (U : Opens Y) (hU : (U : Set Y) ⊆ Set.range f.base) : PresheafedSpace.IsOpenImmersion.app_invApp f.1 U instance ofRestrict {X : TopCat} (Y : LocallyRingedSpace) {f : X ⟶ Y.carrier} - (hf : OpenEmbedding f) : IsOpenImmersion (Y.ofRestrict hf) := + (hf : IsOpenEmbedding f) : IsOpenImmersion (Y.ofRestrict hf) := PresheafedSpace.IsOpenImmersion.ofRestrict _ hf @[elementwise, simp] theorem ofRestrict_invApp (X : LocallyRingedSpace) {Y : TopCat} - {f : Y ⟶ TopCat.of X.carrier} (h : OpenEmbedding f) (U : Opens (X.restrict h).carrier) : + {f : Y ⟶ TopCat.of X.carrier} (h : IsOpenEmbedding f) (U : Opens (X.restrict h).carrier) : (LocallyRingedSpace.IsOpenImmersion.ofRestrict X h).invApp _ U = 𝟙 _ := PresheafedSpace.IsOpenImmersion.ofRestrict_invApp _ h U diff --git a/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean b/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean index 12c2d277fbd66d..366aeeda7b4b07 100644 --- a/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean +++ b/Mathlib/Geometry/RingedSpace/PresheafedSpace.lean @@ -293,7 +293,7 @@ section Restrict -/ @[simps] def restrict {U : TopCat} (X : PresheafedSpace C) {f : U ⟶ (X : TopCat)} - (h : OpenEmbedding f) : PresheafedSpace C where + (h : IsOpenEmbedding f) : PresheafedSpace C where carrier := U presheaf := h.isOpenMap.functor.op ⋙ X.presheaf @@ -301,7 +301,7 @@ def restrict {U : TopCat} (X : PresheafedSpace C) {f : U ⟶ (X : TopCat)} -/ @[simps] def ofRestrict {U : TopCat} (X : PresheafedSpace C) {f : U ⟶ (X : TopCat)} - (h : OpenEmbedding f) : X.restrict h ⟶ X where + (h : IsOpenEmbedding f) : X.restrict h ⟶ X where base := f c := { app := fun V => X.presheaf.map (h.isOpenMap.adjunction.counit.app V.unop).op @@ -310,8 +310,8 @@ def ofRestrict {U : TopCat} (X : PresheafedSpace C) {f : U ⟶ (X : TopCat)} rw [← map_comp, ← map_comp] rfl } -instance ofRestrict_mono {U : TopCat} (X : PresheafedSpace C) (f : U ⟶ X.1) (hf : OpenEmbedding f) : - Mono (X.ofRestrict hf) := by +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.inj constructor intro Z g₁ g₂ eq @@ -339,14 +339,14 @@ instance ofRestrict_mono {U : TopCat} (X : PresheafedSpace C) (f : U ⟶ X.1) (h simpa using h theorem restrict_top_presheaf (X : PresheafedSpace C) : - (X.restrict (Opens.openEmbedding ⊤)).presheaf = + (X.restrict (Opens.isOpenEmbedding ⊤)).presheaf = (Opens.inclusionTopIso X.carrier).inv _* X.presheaf := by dsimp rw [Opens.inclusion'_top_functor X.carrier] rfl theorem ofRestrict_top_c (X : PresheafedSpace C) : - (X.ofRestrict (Opens.openEmbedding ⊤)).c = + (X.ofRestrict (Opens.isOpenEmbedding ⊤)).c = eqToHom (by rw [restrict_top_presheaf, ← Presheaf.Pushforward.comp_eq] @@ -365,14 +365,14 @@ theorem ofRestrict_top_c (X : PresheafedSpace C) : subspace. -/ @[simps] -def toRestrictTop (X : PresheafedSpace C) : X ⟶ X.restrict (Opens.openEmbedding ⊤) where +def toRestrictTop (X : PresheafedSpace C) : X ⟶ X.restrict (Opens.isOpenEmbedding ⊤) where base := (Opens.inclusionTopIso X.carrier).inv c := eqToHom (restrict_top_presheaf X) /-- The isomorphism from the restriction to the top subspace. -/ @[simps] -def restrictTopIso (X : PresheafedSpace C) : X.restrict (Opens.openEmbedding ⊤) ≅ X where +def restrictTopIso (X : PresheafedSpace C) : X.restrict (Opens.isOpenEmbedding ⊤) ≅ X where hom := X.ofRestrict _ inv := X.toRestrictTop hom_inv_id := by diff --git a/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean b/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean index bcfd0917ee8440..16c8a582890017 100644 --- a/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean +++ b/Mathlib/Geometry/RingedSpace/PresheafedSpace/Gluing.lean @@ -121,14 +121,17 @@ abbrev toTopGlueData : TopCat.GlueData := { f_open := fun i j => (D.f_open i j).base_open toGlueData := 𝖣.mapGlueData (forget C) } -theorem ι_openEmbedding [HasLimits C] (i : D.J) : OpenEmbedding (𝖣.ι i).base := by +theorem ι_isOpenEmbedding [HasLimits C] (i : D.J) : IsOpenEmbedding (𝖣.ι i).base := by rw [← show _ = (𝖣.ι i).base from 𝖣.ι_gluedIso_inv (PresheafedSpace.forget _) _] -- Porting note: added this erewrite erw [coe_comp] refine - OpenEmbedding.comp - (TopCat.homeoOfIso (𝖣.gluedIso (PresheafedSpace.forget _)).symm).openEmbedding - (D.toTopGlueData.ι_openEmbedding i) + IsOpenEmbedding.comp + (TopCat.homeoOfIso (𝖣.gluedIso (PresheafedSpace.forget _)).symm).isOpenEmbedding + (D.toTopGlueData.ι_isOpenEmbedding i) + +@[deprecated (since := "2024-10-18")] +alias ι_openEmbedding := ι_isOpenEmbedding theorem pullback_base (i j k : D.J) (S : Set (D.V (i, j)).carrier) : (π₂ i, j, k) '' ((π₁ i, j, k) ⁻¹' S) = D.f i k ⁻¹' (D.f i j '' S) := by @@ -237,7 +240,7 @@ theorem snd_invApp_t_app (i j k : D.J) (U : Opens (pullback (D.f i j) (D.f i k)) variable [HasLimits C] theorem ι_image_preimage_eq (i j : D.J) (U : Opens (D.U i).carrier) : - (Opens.map (𝖣.ι j).base).obj ((D.ι_openEmbedding i).isOpenMap.functor.obj U) = + (Opens.map (𝖣.ι j).base).obj ((D.ι_isOpenEmbedding i).isOpenMap.functor.obj U) = (opensFunctor (D.f j i)).obj ((Opens.map (𝖣.t j i).base).obj ((Opens.map (𝖣.f i j).base).obj U)) := by ext1 @@ -265,7 +268,7 @@ theorem ι_image_preimage_eq (i j : D.J) (U : Opens (D.U i).carrier) : def opensImagePreimageMap (i j : D.J) (U : Opens (D.U i).carrier) : (D.U i).presheaf.obj (op U) ⟶ (D.U j).presheaf.obj (op <| - (Opens.map (𝖣.ι j).base).obj ((D.ι_openEmbedding i).isOpenMap.functor.obj U)) := + (Opens.map (𝖣.ι j).base).obj ((D.ι_isOpenEmbedding i).isOpenMap.functor.obj U)) := (D.f i j).c.app (op U) ≫ (D.t j i).c.app _ ≫ (D.f_open j i).invApp _ (unop _) ≫ @@ -311,7 +314,7 @@ the image `ι '' U` in the glued space is the limit of this diagram. -/ abbrev diagramOverOpen {i : D.J} (U : Opens (D.U i).carrier) : -- Porting note : ↓ these need to be explicit (WalkingMultispan D.diagram.fstFrom D.diagram.sndFrom)ᵒᵖ ⥤ C := - componentwiseDiagram 𝖣.diagram.multispan ((D.ι_openEmbedding i).isOpenMap.functor.obj U) + componentwiseDiagram 𝖣.diagram.multispan ((D.ι_isOpenEmbedding i).isOpenMap.functor.obj U) /-- (Implementation) The projection from the limit of `diagram_over_open` to a component of `D.U j`. -/ @@ -490,7 +493,7 @@ instance componentwise_diagram_π_isIso (i : D.J) (U : Opens (D.U i).carrier) : exact Iso.inv_hom_id ((D.U i).presheaf.mapIso (eqToIso _)) instance ιIsOpenImmersion (i : D.J) : IsOpenImmersion (𝖣.ι i) where - base_open := D.ι_openEmbedding i + base_open := D.ι_isOpenEmbedding i c_iso U := by erw [← colimitPresheafObjIsoComponentwiseLimit_hom_π]; infer_instance /-- The following diagram is a pullback, i.e. `Vᵢⱼ` is the intersection of `Uᵢ` and `Uⱼ` in `X`. diff --git a/Mathlib/Geometry/RingedSpace/SheafedSpace.lean b/Mathlib/Geometry/RingedSpace/SheafedSpace.lean index 3af5f2d7e91d0c..4a94f1819e128d 100644 --- a/Mathlib/Geometry/RingedSpace/SheafedSpace.lean +++ b/Mathlib/Geometry/RingedSpace/SheafedSpace.lean @@ -156,20 +156,20 @@ open TopCat.Presheaf /-- The restriction of a sheafed space along an open embedding into the space. -/ -def restrict {U : TopCat} (X : SheafedSpace C) {f : U ⟶ (X : TopCat)} (h : OpenEmbedding f) : +def restrict {U : TopCat} (X : SheafedSpace C) {f : U ⟶ (X : TopCat)} (h : IsOpenEmbedding f) : SheafedSpace C := - { X.toPresheafedSpace.restrict h with IsSheaf := isSheaf_of_openEmbedding h X.IsSheaf } + { X.toPresheafedSpace.restrict h with IsSheaf := isSheaf_of_isOpenEmbedding h X.IsSheaf } /-- The map from the restriction of a presheafed space. -/ @[simps!] def ofRestrict {U : TopCat} (X : SheafedSpace C) {f : U ⟶ (X : TopCat)} - (h : OpenEmbedding f) : X.restrict h ⟶ X := X.toPresheafedSpace.ofRestrict h + (h : IsOpenEmbedding f) : X.restrict h ⟶ X := X.toPresheafedSpace.ofRestrict h /-- The restriction of a sheafed space `X` to the top subspace is isomorphic to `X` itself. -/ @[simps! hom inv] -def restrictTopIso (X : SheafedSpace C) : X.restrict (Opens.openEmbedding ⊤) ≅ X := +def restrictTopIso (X : SheafedSpace C) : X.restrict (Opens.isOpenEmbedding ⊤) ≅ X := isoMk (X.toPresheafedSpace.restrictTopIso) /-- The global sections, notated Gamma. diff --git a/Mathlib/Geometry/RingedSpace/Stalks.lean b/Mathlib/Geometry/RingedSpace/Stalks.lean index 12c20e03483924..8f6f8f792d874b 100644 --- a/Mathlib/Geometry/RingedSpace/Stalks.lean +++ b/Mathlib/Geometry/RingedSpace/Stalks.lean @@ -57,7 +57,7 @@ section Restrict of `X` at `f x` and the stalk of the restriction of `X` along `f` at t `x`. -/ def restrictStalkIso {U : TopCat} (X : PresheafedSpace.{_, _, v} C) {f : U ⟶ (X : TopCat.{v})} - (h : OpenEmbedding f) (x : U) : (X.restrict h).presheaf.stalk x ≅ X.presheaf.stalk (f x) := + (h : IsOpenEmbedding f) (x : U) : (X.restrict h).presheaf.stalk x ≅ X.presheaf.stalk (f x) := haveI := initial_of_adjunction (h.isOpenMap.adjunctionNhds x) Final.colimitIso (h.isOpenMap.functorNhds x).op ((OpenNhds.inclusion (f x)).op ⋙ X.presheaf) -- As a left adjoint, the functor `h.is_open_map.functor_nhds x` is initial. @@ -67,7 +67,7 @@ def restrictStalkIso {U : TopCat} (X : PresheafedSpace.{_, _, v} C) {f : U ⟶ ( -- Porting note (#11119): removed `simp` attribute, for left hand side is not in simple normal form. @[elementwise, reassoc] theorem restrictStalkIso_hom_eq_germ {U : TopCat} (X : PresheafedSpace.{_, _, v} C) - {f : U ⟶ (X : TopCat.{v})} (h : OpenEmbedding f) (V : Opens U) (x : U) (hx : x ∈ V) : + {f : U ⟶ (X : TopCat.{v})} (h : IsOpenEmbedding f) (V : Opens U) (x : U) (hx : x ∈ V) : (X.restrict h).presheaf.germ _ x hx ≫ (restrictStalkIso X h x).hom = X.presheaf.germ (h.isOpenMap.functor.obj V) (f x) ⟨x, hx, rfl⟩ := colimit.ι_pre ((OpenNhds.inclusion (f x)).op ⋙ X.presheaf) (h.isOpenMap.functorNhds x).op @@ -77,14 +77,14 @@ theorem restrictStalkIso_hom_eq_germ {U : TopCat} (X : PresheafedSpace.{_, _, v} -- as the simpNF linter claims they never apply. @[simp, elementwise, reassoc] theorem restrictStalkIso_inv_eq_germ {U : TopCat} (X : PresheafedSpace.{_, _, v} C) - {f : U ⟶ (X : TopCat.{v})} (h : OpenEmbedding f) (V : Opens U) (x : U) (hx : x ∈ V) : + {f : U ⟶ (X : TopCat.{v})} (h : IsOpenEmbedding f) (V : Opens U) (x : U) (hx : x ∈ V) : X.presheaf.germ (h.isOpenMap.functor.obj V) (f x) ⟨x, hx, rfl⟩ ≫ (restrictStalkIso X h x).inv = (X.restrict h).presheaf.germ _ x hx := by rw [← restrictStalkIso_hom_eq_germ, Category.assoc, Iso.hom_inv_id, Category.comp_id] theorem restrictStalkIso_inv_eq_ofRestrict {U : TopCat} (X : PresheafedSpace.{_, _, v} C) - {f : U ⟶ (X : TopCat.{v})} (h : OpenEmbedding f) (x : U) : + {f : U ⟶ (X : TopCat.{v})} (h : IsOpenEmbedding f) (x : U) : (X.restrictStalkIso h x).inv = (X.ofRestrict h).stalkMap x := by -- We can't use `ext` here due to https://github.com/leanprover/std4/pull/159 refine colimit.hom_ext fun V => ?_ @@ -99,7 +99,7 @@ theorem restrictStalkIso_inv_eq_ofRestrict {U : TopCat} (X : PresheafedSpace.{_, exact (colimit.w ((OpenNhds.inclusion (f x)).op ⋙ X.presheaf) i.op).symm instance ofRestrict_stalkMap_isIso {U : TopCat} (X : PresheafedSpace.{_, _, v} C) - {f : U ⟶ (X : TopCat.{v})} (h : OpenEmbedding f) (x : U) : + {f : U ⟶ (X : TopCat.{v})} (h : IsOpenEmbedding f) (x : U) : IsIso ((X.ofRestrict h).stalkMap x) := by rw [← restrictStalkIso_inv_eq_ofRestrict]; infer_instance diff --git a/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean b/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean index a09f3bc5eb9bde..601ec698d26dd0 100644 --- a/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean +++ b/Mathlib/MeasureTheory/Constructions/BorelSpace/Basic.lean @@ -636,10 +636,13 @@ protected theorem ClosedEmbedding.measurableEmbedding {f : α → β} (h : Close MeasurableEmbedding f := h.toEmbedding.measurableEmbedding h.isClosed_range.measurableSet -protected theorem OpenEmbedding.measurableEmbedding {f : α → β} (h : OpenEmbedding f) : +protected theorem IsOpenEmbedding.measurableEmbedding {f : α → β} (h : IsOpenEmbedding f) : MeasurableEmbedding f := h.toEmbedding.measurableEmbedding h.isOpen_range.measurableSet +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.measurableEmbedding := IsOpenEmbedding.measurableEmbedding + instance Empty.borelSpace : BorelSpace Empty := ⟨borel_eq_top_of_discrete.symm⟩ diff --git a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/UniformConvergence.lean b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/UniformConvergence.lean index 7268d68dd42750..408d7863a320a7 100644 --- a/Mathlib/NumberTheory/ModularForms/EisensteinSeries/UniformConvergence.lean +++ b/Mathlib/NumberTheory/ModularForms/EisensteinSeries/UniformConvergence.lean @@ -190,7 +190,7 @@ lemma eisensteinSeries_tendstoLocallyUniformlyOn {k : ℤ} {N : ℕ} (hk : 3 ≤ apply TendstoLocallyUniformlyOn.comp (s := ⊤) _ _ _ (PartialHomeomorph.continuousOn_symm _) · simp only [SlashInvariantForm.toFun_eq_coe, Set.top_eq_univ, tendstoLocallyUniformlyOn_univ] apply eisensteinSeries_tendstoLocallyUniformly hk - · simp only [OpenEmbedding.toPartialHomeomorph_target, Set.top_eq_univ, mapsTo_range_iff, + · simp only [IsOpenEmbedding.toPartialHomeomorph_target, Set.top_eq_univ, mapsTo_range_iff, Set.mem_univ, forall_const] end summability diff --git a/Mathlib/Topology/Algebra/ConstMulAction.lean b/Mathlib/Topology/Algebra/ConstMulAction.lean index 7f721b2b8dbdd7..e8e5e5ff0b50e2 100644 --- a/Mathlib/Topology/Algebra/ConstMulAction.lean +++ b/Mathlib/Topology/Algebra/ConstMulAction.lean @@ -258,7 +258,7 @@ theorem subset_interior_smul_right {s : Set G} {t : Set α} : s • interior t @[to_additive (attr := simp)] theorem smul_mem_nhds_smul_iff {t : Set α} (g : G) {a : α} : g • t ∈ 𝓝 (g • a) ↔ t ∈ 𝓝 a := - (Homeomorph.smul g).openEmbedding.image_mem_nhds + (Homeomorph.smul g).isOpenEmbedding.image_mem_nhds @[to_additive] alias ⟨_, smul_mem_nhds_smul⟩ := smul_mem_nhds_smul_iff diff --git a/Mathlib/Topology/Algebra/Constructions/DomMulAct.lean b/Mathlib/Topology/Algebra/Constructions/DomMulAct.lean index 9c399af02e7899..a907bb2550a2a3 100644 --- a/Mathlib/Topology/Algebra/Constructions/DomMulAct.lean +++ b/Mathlib/Topology/Algebra/Constructions/DomMulAct.lean @@ -49,15 +49,21 @@ theorem coe_mkHomeomorph_symm : ⇑(mkHomeomorph : M ≃ₜ Mᵈᵐᵃ).symm = m @[to_additive] theorem inducing_mk : Inducing (@mk M) := mkHomeomorph.inducing @[to_additive] theorem embedding_mk : Embedding (@mk M) := mkHomeomorph.embedding -@[to_additive] theorem openEmbedding_mk : OpenEmbedding (@mk M) := mkHomeomorph.openEmbedding +@[to_additive] theorem isOpenEmbedding_mk : IsOpenEmbedding (@mk M) := mkHomeomorph.isOpenEmbedding @[to_additive] theorem closedEmbedding_mk : ClosedEmbedding (@mk M) := mkHomeomorph.closedEmbedding @[to_additive] theorem quotientMap_mk : QuotientMap (@mk M) := mkHomeomorph.quotientMap +@[deprecated (since := "2024-10-18")] +alias openEmbedding_mk := isOpenEmbedding_mk + @[to_additive] theorem inducing_mk_symm : Inducing (@mk M).symm := mkHomeomorph.symm.inducing @[to_additive] theorem embedding_mk_symm : Embedding (@mk M).symm := mkHomeomorph.symm.embedding @[to_additive] -theorem openEmbedding_mk_symm : OpenEmbedding (@mk M).symm := mkHomeomorph.symm.openEmbedding +theorem isOpenEmbedding_mk_symm : IsOpenEmbedding (@mk M).symm := mkHomeomorph.symm.isOpenEmbedding + +@[deprecated (since := "2024-10-18")] +alias openEmbedding_mk_symm := isOpenEmbedding_mk_symm @[to_additive] theorem closedEmbedding_mk_symm : ClosedEmbedding (@mk M).symm := mkHomeomorph.symm.closedEmbedding @@ -108,7 +114,7 @@ instance instCompactSpace [CompactSpace M] : CompactSpace Mᵈᵐᵃ := @[to_additive] instance instLocallyCompactSpace [LocallyCompactSpace M] : LocallyCompactSpace Mᵈᵐᵃ := - openEmbedding_mk_symm.locallyCompactSpace + isOpenEmbedding_mk_symm.locallyCompactSpace @[to_additive] instance instWeaklyLocallyCompactSpace [WeaklyLocallyCompactSpace M] : diff --git a/Mathlib/Topology/Algebra/Nonarchimedean/Basic.lean b/Mathlib/Topology/Algebra/Nonarchimedean/Basic.lean index 56b953c25c2717..06b301dde6cb39 100644 --- a/Mathlib/Topology/Algebra/Nonarchimedean/Basic.lean +++ b/Mathlib/Topology/Algebra/Nonarchimedean/Basic.lean @@ -60,7 +60,7 @@ variable {K : Type*} [Group K] [TopologicalSpace K] [NonarchimedeanGroup K] /-- If a topological group embeds into a nonarchimedean group, then it is nonarchimedean. -/ @[to_additive] -theorem nonarchimedean_of_emb (f : G →* H) (emb : OpenEmbedding f) : NonarchimedeanGroup H := +theorem nonarchimedean_of_emb (f : G →* H) (emb : IsOpenEmbedding f) : NonarchimedeanGroup H := { is_nonarchimedean := fun U hU => have h₁ : f ⁻¹' U ∈ 𝓝 (1 : G) := by apply emb.continuous.tendsto diff --git a/Mathlib/Topology/Bases.lean b/Mathlib/Topology/Bases.lean index 46d7a2dd5d1df1..e953974c7c1dd4 100644 --- a/Mathlib/Topology/Bases.lean +++ b/Mathlib/Topology/Bases.lean @@ -887,8 +887,8 @@ theorem IsTopologicalBasis.sum {s : Set (Set α)} (hs : IsTopologicalBasis s) {t IsTopologicalBasis ((fun u => Sum.inl '' u) '' s ∪ (fun u => Sum.inr '' u) '' t) := by apply isTopologicalBasis_of_isOpen_of_nhds · rintro u (⟨w, hw, rfl⟩ | ⟨w, hw, rfl⟩) - · exact openEmbedding_inl.isOpenMap w (hs.isOpen hw) - · exact openEmbedding_inr.isOpenMap w (ht.isOpen hw) + · exact isOpenEmbedding_inl.isOpenMap w (hs.isOpen hw) + · exact isOpenEmbedding_inr.isOpenMap w (ht.isOpen hw) · rintro (x | x) u hxu u_open · obtain ⟨v, vs, xv, vu⟩ : ∃ v ∈ s, x ∈ v ∧ v ⊆ Sum.inl ⁻¹' u := hs.exists_subset_of_mem_open hxu (isOpen_sum_iff.1 u_open).1 diff --git a/Mathlib/Topology/Category/CompHausLike/Limits.lean b/Mathlib/Topology/Category/CompHausLike/Limits.lean index 845abc60f56e77..3e5a965f2dce5c 100644 --- a/Mathlib/Topology/Category/CompHausLike/Limits.lean +++ b/Mathlib/Topology/Category/CompHausLike/Limits.lean @@ -150,20 +150,26 @@ variable {P : TopCat.{u} → Prop} [HasExplicitFiniteCoproducts.{0} P] example : HasFiniteCoproducts (CompHausLike.{u} P) := inferInstance /-- The inclusion maps into the explicit finite coproduct are open embeddings. -/ -lemma finiteCoproduct.openEmbedding_ι (a : α) : - OpenEmbedding (finiteCoproduct.ι X a) := - openEmbedding_sigmaMk (σ := fun a ↦ (X a)) +lemma finiteCoproduct.isOpenEmbedding_ι (a : α) : + IsOpenEmbedding (finiteCoproduct.ι X a) := + isOpenEmbedding_sigmaMk (σ := fun a ↦ (X a)) + +@[deprecated (since := "2024-10-18")] +alias finiteCoproduct.openEmbedding_ι := finiteCoproduct.isOpenEmbedding_ι /-- The inclusion maps into the abstract finite coproduct are open embeddings. -/ -lemma Sigma.openEmbedding_ι (a : α) : - OpenEmbedding (Sigma.ι X a) := by - refine OpenEmbedding.of_comp _ (homeoOfIso ((colimit.isColimit _).coconePointUniqueUpToIso - (finiteCoproduct.isColimit X))).openEmbedding ?_ - convert finiteCoproduct.openEmbedding_ι X a +lemma Sigma.isOpenEmbedding_ι (a : α) : + IsOpenEmbedding (Sigma.ι X a) := by + refine IsOpenEmbedding.of_comp _ (homeoOfIso ((colimit.isColimit _).coconePointUniqueUpToIso + (finiteCoproduct.isColimit X))).isOpenEmbedding ?_ + convert finiteCoproduct.isOpenEmbedding_ι X a ext x change (Sigma.ι X a ≫ _) x = _ simp +@[deprecated (since := "2024-10-18")] +alias Sigma.openEmbedding_ι := Sigma.isOpenEmbedding_ι + /-- The functor to `TopCat` preserves finite coproducts if they exist. -/ instance (P) [HasExplicitFiniteCoproducts.{0} P] : PreservesFiniteCoproducts (compHausLikeToTop P) := by @@ -332,12 +338,12 @@ instance [HasExplicitPullbacksOfInclusions P] : HasPullbacksOfInclusions (CompHa theorem hasPullbacksOfInclusions (hP' : ∀ ⦃X Y B : CompHausLike.{u} P⦄ (f : X ⟶ B) (g : Y ⟶ B) - (_ : OpenEmbedding f), HasExplicitPullback f g) : + (_ : IsOpenEmbedding f), HasExplicitPullback f g) : HasExplicitPullbacksOfInclusions P := { hasProp := by intro _ _ _ f apply hP' - exact Sigma.openEmbedding_ι _ _ } + exact Sigma.isOpenEmbedding_ι _ _ } /-- The functor to `TopCat` preserves pullbacks of inclusions if they exist. -/ noncomputable instance [HasExplicitPullbacksOfInclusions P] : @@ -350,7 +356,7 @@ instance [HasExplicitPullbacksOfInclusions P] : FinitaryExtensive (CompHausLike finitaryExtensive_of_preserves_and_reflects (compHausLikeToTop P) theorem finitaryExtensive (hP' : ∀ ⦃X Y B : CompHausLike.{u} P⦄ (f : X ⟶ B) (g : Y ⟶ B) - (_ : OpenEmbedding f), HasExplicitPullback f g) : + (_ : IsOpenEmbedding f), HasExplicitPullback f g) : FinitaryExtensive (CompHausLike P) := have := hasPullbacksOfInclusions hP' finitaryExtensive_of_preserves_and_reflects (compHausLikeToTop P) diff --git a/Mathlib/Topology/Category/Stonean/Limits.lean b/Mathlib/Topology/Category/Stonean/Limits.lean index 9a344de319c224..ed7151753cb738 100644 --- a/Mathlib/Topology/Category/Stonean/Limits.lean +++ b/Mathlib/Topology/Category/Stonean/Limits.lean @@ -24,7 +24,7 @@ namespace Stonean instance : HasExplicitFiniteCoproducts.{w, u} (fun Y ↦ ExtremallyDisconnected Y) where hasProp _ := { hasProp := show ExtremallyDisconnected (Σ (_a : _), _) from inferInstance} -variable {X Y Z : Stonean} {f : X ⟶ Z} (i : Y ⟶ Z) (hi : OpenEmbedding f) +variable {X Y Z : Stonean} {f : X ⟶ Z} (i : Y ⟶ Z) (hi : IsOpenEmbedding f) include hi lemma extremallyDisconnected_preimage : ExtremallyDisconnected (i ⁻¹' (Set.range f)) where @@ -35,7 +35,7 @@ lemma extremallyDisconnected_preimage : ExtremallyDisconnected (i ⁻¹' (Set.ra rw [← (closure U).preimage_image_eq Subtype.coe_injective, ← h.1.closedEmbedding_subtype_val.closure_image_eq U] exact isOpen_induced (ExtremallyDisconnected.open_closure _ - (h.2.openEmbedding_subtype_val.isOpenMap U hU)) + (h.2.isOpenEmbedding_subtypeVal.isOpenMap U hU)) lemma extremallyDisconnected_pullback : ExtremallyDisconnected {xy : X × Y | f xy.1 = i xy.2} := have := extremallyDisconnected_preimage i hi diff --git a/Mathlib/Topology/Category/TopCat/Basic.lean b/Mathlib/Topology/Category/TopCat/Basic.lean index f1a2371e9013c8..57a2905802c66d 100644 --- a/Mathlib/Topology/Category/TopCat/Basic.lean +++ b/Mathlib/Topology/Category/TopCat/Basic.lean @@ -168,29 +168,41 @@ lemma isIso_of_bijective_of_isClosedMap {X Y : TopCat.{u}} (f : X ⟶ Y) inferInstanceAs <| IsIso (TopCat.isoOfHomeo e).hom -- Porting note: simpNF requested partially simped version below -theorem openEmbedding_iff_comp_isIso {X Y Z : TopCat} (f : X ⟶ Y) (g : Y ⟶ Z) [IsIso g] : - OpenEmbedding (f ≫ g) ↔ OpenEmbedding f := - (TopCat.homeoOfIso (asIso g)).openEmbedding.of_comp_iff f +theorem isOpenEmbedding_iff_comp_isIso {X Y Z : TopCat} (f : X ⟶ Y) (g : Y ⟶ Z) [IsIso g] : + IsOpenEmbedding (f ≫ g) ↔ IsOpenEmbedding f := + (TopCat.homeoOfIso (asIso g)).isOpenEmbedding.of_comp_iff f + +@[deprecated (since := "2024-10-18")] +alias openEmbedding_iff_comp_isIso := isOpenEmbedding_iff_comp_isIso @[simp] -theorem openEmbedding_iff_comp_isIso' {X Y Z : TopCat} (f : X ⟶ Y) (g : Y ⟶ Z) [IsIso g] : - OpenEmbedding ((forget TopCat).map f ≫ (forget TopCat).map g) ↔ OpenEmbedding f := by +theorem isOpenEmbedding_iff_comp_isIso' {X Y Z : TopCat} (f : X ⟶ Y) (g : Y ⟶ Z) [IsIso g] : + IsOpenEmbedding ((forget TopCat).map f ≫ (forget TopCat).map g) ↔ IsOpenEmbedding f := by simp only [← Functor.map_comp] - exact openEmbedding_iff_comp_isIso f g + exact isOpenEmbedding_iff_comp_isIso f g + +@[deprecated (since := "2024-10-18")] +alias openEmbedding_iff_comp_isIso' := isOpenEmbedding_iff_comp_isIso' -- Porting note: simpNF requested partially simped version below -theorem openEmbedding_iff_isIso_comp {X Y Z : TopCat} (f : X ⟶ Y) (g : Y ⟶ Z) [IsIso f] : - OpenEmbedding (f ≫ g) ↔ OpenEmbedding g := by +theorem isOpenEmbedding_iff_isIso_comp {X Y Z : TopCat} (f : X ⟶ Y) (g : Y ⟶ Z) [IsIso f] : + IsOpenEmbedding (f ≫ g) ↔ IsOpenEmbedding g := by constructor · intro h - convert h.comp (TopCat.homeoOfIso (asIso f).symm).openEmbedding + convert h.comp (TopCat.homeoOfIso (asIso f).symm).isOpenEmbedding exact congrArg _ (IsIso.inv_hom_id_assoc f g).symm - · exact fun h => h.comp (TopCat.homeoOfIso (asIso f)).openEmbedding + · exact fun h => h.comp (TopCat.homeoOfIso (asIso f)).isOpenEmbedding + +@[deprecated (since := "2024-10-18")] +alias openEmbedding_iff_isIso_comp := isOpenEmbedding_iff_isIso_comp @[simp] -theorem openEmbedding_iff_isIso_comp' {X Y Z : TopCat} (f : X ⟶ Y) (g : Y ⟶ Z) [IsIso f] : - OpenEmbedding ((forget TopCat).map f ≫ (forget TopCat).map g) ↔ OpenEmbedding g := by +theorem isOpenEmbedding_iff_isIso_comp' {X Y Z : TopCat} (f : X ⟶ Y) (g : Y ⟶ Z) [IsIso f] : + IsOpenEmbedding ((forget TopCat).map f ≫ (forget TopCat).map g) ↔ IsOpenEmbedding g := by simp only [← Functor.map_comp] - exact openEmbedding_iff_isIso_comp f g + exact isOpenEmbedding_iff_isIso_comp f g + +@[deprecated (since := "2024-10-18")] +alias openEmbedding_iff_isIso_comp' := isOpenEmbedding_iff_isIso_comp' end TopCat diff --git a/Mathlib/Topology/Category/TopCat/Limits/Products.lean b/Mathlib/Topology/Category/TopCat/Limits/Products.lean index cd45197d42a40a..132e2144e20909 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Products.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Products.lean @@ -283,7 +283,8 @@ def binaryCofanIsColimit (X Y : TopCat.{u}) : IsColimit (TopCat.binaryCofan X Y) theorem binaryCofan_isColimit_iff {X Y : TopCat} (c : BinaryCofan X Y) : Nonempty (IsColimit c) ↔ - OpenEmbedding c.inl ∧ OpenEmbedding c.inr ∧ IsCompl (Set.range c.inl) (Set.range c.inr) := by + IsOpenEmbedding c.inl ∧ IsOpenEmbedding c.inr ∧ + IsCompl (Set.range c.inl) (Set.range c.inr) := by classical constructor · rintro ⟨h⟩ @@ -293,9 +294,9 @@ theorem binaryCofan_isColimit_iff {X Y : TopCat} (c : BinaryCofan X Y) : h.comp_coconePointUniqueUpToIso_inv (binaryCofanIsColimit X Y) ⟨WalkingPair.right⟩] dsimp refine ⟨(homeoOfIso <| h.coconePointUniqueUpToIso - (binaryCofanIsColimit X Y)).symm.openEmbedding.comp openEmbedding_inl, + (binaryCofanIsColimit X Y)).symm.isOpenEmbedding.comp isOpenEmbedding_inl, (homeoOfIso <| h.coconePointUniqueUpToIso - (binaryCofanIsColimit X Y)).symm.openEmbedding.comp openEmbedding_inr, ?_⟩ + (binaryCofanIsColimit X Y)).symm.isOpenEmbedding.comp isOpenEmbedding_inr, ?_⟩ erw [Set.range_comp, ← eq_compl_iff_isCompl, Set.range_comp _ Sum.inr, ← Set.image_compl_eq (homeoOfIso <| h.coconePointUniqueUpToIso (binaryCofanIsColimit X Y)).symm.bijective, Set.compl_range_inr, Set.image_comp] diff --git a/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean b/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean index 7427588e292b72..e51d68906803f0 100644 --- a/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean +++ b/Mathlib/Topology/Category/TopCat/Limits/Pullbacks.lean @@ -284,10 +284,10 @@ W ⟶ Y X ⟶ Z ``` -/ -theorem pullback_map_openEmbedding_of_open_embeddings {W X Y Z S T : TopCat.{u}} (f₁ : W ⟶ S) - (f₂ : X ⟶ S) (g₁ : Y ⟶ T) (g₂ : Z ⟶ T) {i₁ : W ⟶ Y} {i₂ : X ⟶ Z} (H₁ : OpenEmbedding i₁) - (H₂ : OpenEmbedding i₂) (i₃ : S ⟶ T) [H₃ : Mono i₃] (eq₁ : f₁ ≫ i₃ = i₁ ≫ g₁) - (eq₂ : f₂ ≫ i₃ = i₂ ≫ g₂) : OpenEmbedding (pullback.map f₁ f₂ g₁ g₂ i₁ i₂ i₃ eq₁ eq₂) := by +theorem pullback_map_isOpenEmbedding {W X Y Z S T : TopCat.{u}} (f₁ : W ⟶ S) + (f₂ : X ⟶ S) (g₁ : Y ⟶ T) (g₂ : Z ⟶ T) {i₁ : W ⟶ Y} {i₂ : X ⟶ Z} (H₁ : IsOpenEmbedding i₁) + (H₂ : IsOpenEmbedding i₂) (i₃ : S ⟶ T) [H₃ : Mono i₃] (eq₁ : f₁ ≫ i₃ = i₁ ≫ g₁) + (eq₂ : f₂ ≫ i₃ = i₂ ≫ g₂) : IsOpenEmbedding (pullback.map f₁ f₂ g₁ g₂ i₁ i₂ i₃ eq₁ eq₂) := by constructor · apply pullback_map_embedding_of_embeddings f₁ f₂ g₁ g₂ H₁.toEmbedding H₂.toEmbedding i₃ eq₁ eq₂ @@ -298,6 +298,9 @@ theorem pullback_map_openEmbedding_of_open_embeddings {W X Y Z S T : TopCat.{u}} · apply ContinuousMap.continuous_toFun · exact H₂.isOpen_range +@[deprecated (since := "2024-10-18")] +alias pullback_map_openEmbedding_of_open_embeddings := pullback_map_isOpenEmbedding + theorem snd_embedding_of_left_embedding {X Y S : TopCat} {f : X ⟶ S} (H : Embedding f) (g : Y ⟶ S) : Embedding <| ⇑(pullback.snd f g) := by convert (homeoOfIso (asIso (pullback.snd (𝟙 S) g))).embedding.comp @@ -320,30 +323,39 @@ theorem embedding_of_pullback_embeddings {X Y S : TopCat} {f : X ⟶ S} {g : Y rw [← coe_comp, ← limit.w _ WalkingCospan.Hom.inr] rfl -theorem snd_openEmbedding_of_left_openEmbedding {X Y S : TopCat} {f : X ⟶ S} (H : OpenEmbedding f) - (g : Y ⟶ S) : OpenEmbedding <| ⇑(pullback.snd f g) := by - convert (homeoOfIso (asIso (pullback.snd (𝟙 S) g))).openEmbedding.comp - (pullback_map_openEmbedding_of_open_embeddings (i₂ := 𝟙 Y) f g (𝟙 _) g H - (homeoOfIso (Iso.refl _)).openEmbedding (𝟙 _) rfl (by simp)) +theorem snd_isOpenEmbedding_of_left {X Y S : TopCat} {f : X ⟶ S} (H : IsOpenEmbedding f) + (g : Y ⟶ S) : IsOpenEmbedding <| ⇑(pullback.snd f g) := by + convert (homeoOfIso (asIso (pullback.snd (𝟙 S) g))).isOpenEmbedding.comp + (pullback_map_isOpenEmbedding (i₂ := 𝟙 Y) f g (𝟙 _) g H + (homeoOfIso (Iso.refl _)).isOpenEmbedding (𝟙 _) rfl (by simp)) erw [← coe_comp] simp -theorem fst_openEmbedding_of_right_openEmbedding {X Y S : TopCat} (f : X ⟶ S) {g : Y ⟶ S} - (H : OpenEmbedding g) : OpenEmbedding <| ⇑(pullback.fst f g) := by - convert (homeoOfIso (asIso (pullback.fst f (𝟙 S)))).openEmbedding.comp - (pullback_map_openEmbedding_of_open_embeddings (i₁ := 𝟙 X) f g f (𝟙 _) - (homeoOfIso (Iso.refl _)).openEmbedding H (𝟙 _) rfl (by simp)) +@[deprecated (since := "2024-10-18")] +alias snd_openEmbedding_of_left_openEmbedding := snd_isOpenEmbedding_of_left + +theorem fst_isOpenEmbedding_of_right {X Y S : TopCat} (f : X ⟶ S) {g : Y ⟶ S} + (H : IsOpenEmbedding g) : IsOpenEmbedding <| ⇑(pullback.fst f g) := by + convert (homeoOfIso (asIso (pullback.fst f (𝟙 S)))).isOpenEmbedding.comp + (pullback_map_isOpenEmbedding (i₁ := 𝟙 X) f g f (𝟙 _) + (homeoOfIso (Iso.refl _)).isOpenEmbedding H (𝟙 _) rfl (by simp)) erw [← coe_comp] simp +@[deprecated (since := "2024-10-18")] +alias fst_openEmbedding_of_right_openEmbedding := fst_isOpenEmbedding_of_right + /-- If `X ⟶ S`, `Y ⟶ S` are open embeddings, then so is `X ×ₛ Y ⟶ S`. -/ -theorem openEmbedding_of_pullback_open_embeddings {X Y S : TopCat} {f : X ⟶ S} {g : Y ⟶ S} - (H₁ : OpenEmbedding f) (H₂ : OpenEmbedding g) : - OpenEmbedding (limit.π (cospan f g) WalkingCospan.one) := by - convert H₂.comp (snd_openEmbedding_of_left_openEmbedding H₁ g) +theorem isOpenEmbedding_of_pullback_open_embeddings {X Y S : TopCat} {f : X ⟶ S} {g : Y ⟶ S} + (H₁ : IsOpenEmbedding f) (H₂ : IsOpenEmbedding g) : + IsOpenEmbedding (limit.π (cospan f g) WalkingCospan.one) := by + convert H₂.comp (snd_isOpenEmbedding_of_left H₁ g) rw [← coe_comp, ← limit.w _ WalkingCospan.Hom.inr] rfl +@[deprecated (since := "2024-10-18")] +alias openEmbedding_of_pullback_open_embeddings := isOpenEmbedding_of_pullback_open_embeddings + theorem fst_iso_of_right_embedding_range_subset {X Y S : TopCat} (f : X ⟶ S) {g : Y ⟶ S} (hg : Embedding g) (H : Set.range f ⊆ Set.range g) : IsIso (pullback.fst f g) := by diff --git a/Mathlib/Topology/Category/TopCat/OpenNhds.lean b/Mathlib/Topology/Category/TopCat/OpenNhds.lean index 863d3a8c4d612f..fdfe88f737c64a 100644 --- a/Mathlib/Topology/Category/TopCat/OpenNhds.lean +++ b/Mathlib/Topology/Category/TopCat/OpenNhds.lean @@ -86,8 +86,11 @@ def inclusion (x : X) : OpenNhds x ⥤ Opens X := theorem inclusion_obj (x : X) (U) (p) : (inclusion x).obj ⟨U, p⟩ = U := rfl -theorem openEmbedding {x : X} (U : OpenNhds x) : OpenEmbedding U.1.inclusion' := - U.1.openEmbedding +theorem isOpenEmbedding {x : X} (U : OpenNhds x) : IsOpenEmbedding U.1.inclusion' := + U.1.isOpenEmbedding + +@[deprecated (since := "2024-10-18")] +alias openEmbedding := isOpenEmbedding /-- The preimage functor from neighborhoods of `f x` to neighborhoods of `x`. -/ def map (x : X) : OpenNhds (f x) ⥤ OpenNhds x where diff --git a/Mathlib/Topology/Category/TopCat/Opens.lean b/Mathlib/Topology/Category/TopCat/Opens.lean index eb8eb48fb88be5..de97a8d22ea44a 100644 --- a/Mathlib/Topology/Category/TopCat/Opens.lean +++ b/Mathlib/Topology/Category/TopCat/Opens.lean @@ -119,8 +119,11 @@ def inclusion' {X : TopCat.{u}} (U : Opens X) : (toTopCat X).obj U ⟶ X where theorem coe_inclusion' {X : TopCat} {U : Opens X} : (inclusion' U : U → X) = Subtype.val := rfl -theorem openEmbedding {X : TopCat.{u}} (U : Opens X) : OpenEmbedding (inclusion' U) := - IsOpen.openEmbedding_subtype_val U.2 +theorem isOpenEmbedding {X : TopCat.{u}} (U : Opens X) : IsOpenEmbedding (inclusion' U) := + IsOpen.isOpenEmbedding_subtypeVal U.2 + +@[deprecated (since := "2024-10-18")] +alias openEmbedding := isOpenEmbedding /-- The inclusion of the top open subset (i.e. the whole space) is an isomorphism. -/ @@ -294,20 +297,26 @@ instance IsOpenMap.functorFullOfMono {X Y : TopCat} {f : X ⟶ Y} (hf : IsOpenMa instance IsOpenMap.functor_faithful {X Y : TopCat} {f : X ⟶ Y} (hf : IsOpenMap f) : hf.functor.Faithful where -lemma OpenEmbedding.functor_obj_injective {X Y : TopCat} {f : X ⟶ Y} (hf : OpenEmbedding f) : +lemma IsOpenEmbedding.functor_obj_injective {X Y : TopCat} {f : X ⟶ Y} (hf : IsOpenEmbedding f) : Function.Injective hf.isOpenMap.functor.obj := fun _ _ e ↦ Opens.ext (Set.image_injective.mpr hf.inj (congr_arg (↑· : Opens Y → Set Y) e)) +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.functor_obj_injective := IsOpenEmbedding.functor_obj_injective + namespace TopologicalSpace.Opens open TopologicalSpace @[simp] -theorem openEmbedding_obj_top {X : TopCat} (U : Opens X) : - U.openEmbedding.isOpenMap.functor.obj ⊤ = U := by +theorem isOpenEmbedding_obj_top {X : TopCat} (U : Opens X) : + U.isOpenEmbedding.isOpenMap.functor.obj ⊤ = U := by ext1 exact Set.image_univ.trans Subtype.range_coe +@[deprecated (since := "2024-10-18")] +alias openEmbedding_obj_top := isOpenEmbedding_obj_top + @[simp] theorem inclusion'_map_eq_top {X : TopCat} (U : Opens X) : (Opens.map U.inclusion').obj U = ⊤ := by ext1 @@ -315,10 +324,10 @@ theorem inclusion'_map_eq_top {X : TopCat} (U : Opens X) : (Opens.map U.inclusio @[simp] theorem adjunction_counit_app_self {X : TopCat} (U : Opens X) : - U.openEmbedding.isOpenMap.adjunction.counit.app U = eqToHom (by simp) := Subsingleton.elim _ _ + U.isOpenEmbedding.isOpenMap.adjunction.counit.app U = eqToHom (by simp) := Subsingleton.elim _ _ theorem inclusion'_top_functor (X : TopCat) : - (@Opens.openEmbedding X ⊤).isOpenMap.functor = map (inclusionTopIso X).inv := by + (@Opens.isOpenEmbedding X ⊤).isOpenMap.functor = map (inclusionTopIso X).inv := by refine CategoryTheory.Functor.ext ?_ ?_ · intro U ext x @@ -347,23 +356,23 @@ lemma set_range_inclusion' {X : TopCat} (U : Opens X) : @[simp] theorem functor_map_eq_inf {X : TopCat} (U V : Opens X) : - U.openEmbedding.isOpenMap.functor.obj ((Opens.map U.inclusion').obj V) = V ⊓ U := by + U.isOpenEmbedding.isOpenMap.functor.obj ((Opens.map U.inclusion').obj V) = V ⊓ U := by ext1 simp only [IsOpenMap.functor_obj_coe, map_coe, coe_inf, Set.image_preimage_eq_inter_range, set_range_inclusion' U] -theorem map_functor_eq' {X U : TopCat} (f : U ⟶ X) (hf : OpenEmbedding f) (V) : +theorem map_functor_eq' {X U : TopCat} (f : U ⟶ X) (hf : IsOpenEmbedding f) (V) : ((Opens.map f).obj <| hf.isOpenMap.functor.obj V) = V := Opens.ext <| Set.preimage_image_eq _ hf.inj @[simp] theorem map_functor_eq {X : TopCat} {U : Opens X} (V : Opens U) : - ((Opens.map U.inclusion').obj <| U.openEmbedding.isOpenMap.functor.obj V) = V := - TopologicalSpace.Opens.map_functor_eq' _ U.openEmbedding V + ((Opens.map U.inclusion').obj <| U.isOpenEmbedding.isOpenMap.functor.obj V) = V := + TopologicalSpace.Opens.map_functor_eq' _ U.isOpenEmbedding V @[simp] theorem adjunction_counit_map_functor {X : TopCat} {U : Opens X} (V : Opens U) : - U.openEmbedding.isOpenMap.adjunction.counit.app (U.openEmbedding.isOpenMap.functor.obj V) = + U.isOpenEmbedding.isOpenMap.adjunction.counit.app (U.isOpenEmbedding.isOpenMap.functor.obj V) = eqToHom (by dsimp; rw [map_functor_eq V]) := by subsingleton diff --git a/Mathlib/Topology/Clopen.lean b/Mathlib/Topology/Clopen.lean index ff10a04698b330..511935a8e3b986 100644 --- a/Mathlib/Topology/Clopen.lean +++ b/Mathlib/Topology/Clopen.lean @@ -118,7 +118,7 @@ theorem isClopen_range_inr : IsClopen (range (Sum.inr : Y → X ⊕ Y)) := theorem isClopen_range_sigmaMk {X : ι → Type*} [∀ i, TopologicalSpace (X i)] {i : ι} : IsClopen (Set.range (@Sigma.mk ι X i)) := - ⟨closedEmbedding_sigmaMk.isClosed_range, openEmbedding_sigmaMk.isOpen_range⟩ + ⟨closedEmbedding_sigmaMk.isClosed_range, isOpenEmbedding_sigmaMk.isOpen_range⟩ protected theorem QuotientMap.isClopen_preimage {f : X → Y} (hf : QuotientMap f) {s : Set Y} : IsClopen (f ⁻¹' s) ↔ IsClopen s := diff --git a/Mathlib/Topology/Compactification/OnePoint.lean b/Mathlib/Topology/Compactification/OnePoint.lean index 622f86227bd241..e870661f60d4f9 100644 --- a/Mathlib/Topology/Compactification/OnePoint.lean +++ b/Mathlib/Topology/Compactification/OnePoint.lean @@ -241,28 +241,31 @@ theorem continuous_coe : Continuous ((↑) : X → OnePoint X) := theorem isOpenMap_coe : IsOpenMap ((↑) : X → OnePoint X) := fun _ => isOpen_image_coe.2 -theorem openEmbedding_coe : OpenEmbedding ((↑) : X → OnePoint X) := - openEmbedding_of_continuous_injective_open continuous_coe coe_injective isOpenMap_coe +theorem isOpenEmbedding_coe : IsOpenEmbedding ((↑) : X → OnePoint X) := + isOpenEmbedding_of_continuous_injective_open continuous_coe coe_injective isOpenMap_coe + +@[deprecated (since := "2024-10-18")] +alias openEmbedding_coe := isOpenEmbedding_coe theorem isOpen_range_coe : IsOpen (range ((↑) : X → OnePoint X)) := - openEmbedding_coe.isOpen_range + isOpenEmbedding_coe.isOpen_range theorem isClosed_infty : IsClosed ({∞} : Set (OnePoint X)) := by rw [← compl_range_coe, isClosed_compl_iff] exact isOpen_range_coe theorem nhds_coe_eq (x : X) : 𝓝 ↑x = map ((↑) : X → OnePoint X) (𝓝 x) := - (openEmbedding_coe.map_nhds_eq x).symm + (isOpenEmbedding_coe.map_nhds_eq x).symm theorem nhdsWithin_coe_image (s : Set X) (x : X) : 𝓝[(↑) '' s] (x : OnePoint X) = map (↑) (𝓝[s] x) := - (openEmbedding_coe.toEmbedding.map_nhdsWithin_eq _ _).symm + (isOpenEmbedding_coe.toEmbedding.map_nhdsWithin_eq _ _).symm theorem nhdsWithin_coe (s : Set (OnePoint X)) (x : X) : 𝓝[s] ↑x = map (↑) (𝓝[(↑) ⁻¹' s] x) := - (openEmbedding_coe.map_nhdsWithin_preimage_eq _ _).symm + (isOpenEmbedding_coe.map_nhdsWithin_preimage_eq _ _).symm theorem comap_coe_nhds (x : X) : comap ((↑) : X → OnePoint X) (𝓝 x) = 𝓝 x := - (openEmbedding_coe.toInducing.nhds_eq_comap x).symm + (isOpenEmbedding_coe.toInducing.nhds_eq_comap x).symm /-- If `x` is not an isolated point of `X`, then `x : OnePoint X` is not an isolated point of `OnePoint X`. -/ @@ -427,18 +430,18 @@ theorem denseRange_coe [NoncompactSpace X] : DenseRange ((↑) : X → OnePoint exact dense_compl_singleton _ theorem isDenseEmbedding_coe [NoncompactSpace X] : IsDenseEmbedding ((↑) : X → OnePoint X) := - { openEmbedding_coe with dense := denseRange_coe } + { isOpenEmbedding_coe with dense := denseRange_coe } @[deprecated (since := "2024-09-30")] alias denseEmbedding_coe := isDenseEmbedding_coe @[simp, norm_cast] theorem specializes_coe {x y : X} : (x : OnePoint X) ⤳ y ↔ x ⤳ y := - openEmbedding_coe.toInducing.specializes_iff + isOpenEmbedding_coe.toInducing.specializes_iff @[simp, norm_cast] theorem inseparable_coe {x y : X} : Inseparable (x : OnePoint X) y ↔ Inseparable x y := - openEmbedding_coe.toInducing.inseparable_iff + isOpenEmbedding_coe.toInducing.inseparable_iff theorem not_specializes_infty_coe {x : X} : ¬Specializes ∞ (x : OnePoint X) := isClosed_infty.not_specializes rfl (coe_ne_infty x) diff --git a/Mathlib/Topology/Compactness/LocallyCompact.lean b/Mathlib/Topology/Compactness/LocallyCompact.lean index 8d10e1ce3da2ef..5bba2a34cb1278 100644 --- a/Mathlib/Topology/Compactness/LocallyCompact.lean +++ b/Mathlib/Topology/Compactness/LocallyCompact.lean @@ -199,10 +199,13 @@ protected theorem ClosedEmbedding.locallyCompactSpace [LocallyCompactSpace Y] {f (hf : ClosedEmbedding f) : LocallyCompactSpace X := hf.toInducing.locallyCompactSpace hf.isClosed_range.isLocallyClosed -protected theorem OpenEmbedding.locallyCompactSpace [LocallyCompactSpace Y] {f : X → Y} - (hf : OpenEmbedding f) : LocallyCompactSpace X := +protected theorem IsOpenEmbedding.locallyCompactSpace [LocallyCompactSpace Y] {f : X → Y} + (hf : IsOpenEmbedding f) : LocallyCompactSpace X := hf.toInducing.locallyCompactSpace hf.isOpen_range.isLocallyClosed +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.locallyCompactSpace := IsOpenEmbedding.locallyCompactSpace + protected theorem IsLocallyClosed.locallyCompactSpace [LocallyCompactSpace X] {s : Set X} (hs : IsLocallyClosed s) : LocallyCompactSpace s := embedding_subtype_val.locallyCompactSpace <| by rwa [Subtype.range_val] diff --git a/Mathlib/Topology/Connected/LocallyConnected.lean b/Mathlib/Topology/Connected/LocallyConnected.lean index 52d6a10719be2c..065d40db50471c 100644 --- a/Mathlib/Topology/Connected/LocallyConnected.lean +++ b/Mathlib/Topology/Connected/LocallyConnected.lean @@ -120,8 +120,8 @@ theorem locallyConnectedSpace_of_connected_bases {ι : Type*} (b : α → ι → (fun i hi => ⟨b x i, ⟨(hbasis x).mem_of_mem hi, hconnected x i hi⟩, subset_rfl⟩) fun s hs => ⟨(hbasis x).index s hs.1, ⟨(hbasis x).property_index hs.1, (hbasis x).set_index_subset hs.1⟩⟩ -theorem OpenEmbedding.locallyConnectedSpace [LocallyConnectedSpace α] [TopologicalSpace β] - {f : β → α} (h : OpenEmbedding f) : LocallyConnectedSpace β := by +theorem IsOpenEmbedding.locallyConnectedSpace [LocallyConnectedSpace α] [TopologicalSpace β] + {f : β → α} (h : IsOpenEmbedding f) : LocallyConnectedSpace β := by refine locallyConnectedSpace_of_connected_bases (fun _ s ↦ f ⁻¹' s) (fun x s ↦ (IsOpen s ∧ f x ∈ s ∧ IsConnected s) ∧ s ⊆ range f) (fun x ↦ ?_) (fun x s hxs ↦ hxs.1.2.2.isPreconnected.preimage_of_isOpenMap h.inj h.isOpenMap hxs.2) @@ -129,8 +129,11 @@ theorem OpenEmbedding.locallyConnectedSpace [LocallyConnectedSpace α] [Topologi exact LocallyConnectedSpace.open_connected_basis (f x) |>.restrict_subset (h.isOpen_range.mem_nhds <| mem_range_self _) |>.comap _ +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.locallyConnectedSpace := IsOpenEmbedding.locallyConnectedSpace + theorem IsOpen.locallyConnectedSpace [LocallyConnectedSpace α] {U : Set α} (hU : IsOpen U) : LocallyConnectedSpace U := - hU.openEmbedding_subtype_val.locallyConnectedSpace + hU.isOpenEmbedding_subtypeVal.locallyConnectedSpace end LocallyConnectedSpace diff --git a/Mathlib/Topology/Connected/PathConnected.lean b/Mathlib/Topology/Connected/PathConnected.lean index 93ef11a0f5e30c..3a8377f9381641 100644 --- a/Mathlib/Topology/Connected/PathConnected.lean +++ b/Mathlib/Topology/Connected/PathConnected.lean @@ -1154,7 +1154,7 @@ theorem pathConnected_subset_basis {U : Set X} (h : IsOpen U) (hx : x ∈ U) : (𝓝 x).HasBasis (fun s : Set X => s ∈ 𝓝 x ∧ IsPathConnected s ∧ s ⊆ U) id := (path_connected_basis x).hasBasis_self_subset (IsOpen.mem_nhds h hx) -theorem OpenEmbedding.locPathConnectedSpace {e : Y → X} (he : OpenEmbedding e) : +theorem IsOpenEmbedding.locPathConnectedSpace {e : Y → X} (he : IsOpenEmbedding e) : LocPathConnectedSpace Y := have (y : Y) : (𝓝 y).HasBasis (fun s ↦ s ∈ 𝓝 (e y) ∧ IsPathConnected s ∧ s ⊆ range e) (e ⁻¹' ·) := @@ -1162,8 +1162,11 @@ theorem OpenEmbedding.locPathConnectedSpace {e : Y → X} (he : OpenEmbedding e) .of_bases this fun x s ⟨_, hs, hse⟩ ↦ by rwa [he.isPathConnected_iff, image_preimage_eq_of_subset hse] +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.locPathConnectedSpace := IsOpenEmbedding.locPathConnectedSpace + theorem IsOpen.locPathConnectedSpace {U : Set X} (h : IsOpen U) : LocPathConnectedSpace U := - (openEmbedding_subtype_val h).locPathConnectedSpace + (isOpenEmbedding_subtypeVal h).locPathConnectedSpace @[deprecated (since := "2024-10-17")] alias locPathConnected_of_isOpen := IsOpen.locPathConnectedSpace diff --git a/Mathlib/Topology/Constructions.lean b/Mathlib/Topology/Constructions.lean index 82bce23e4c0c90..85297dd644e16f 100644 --- a/Mathlib/Topology/Constructions.lean +++ b/Mathlib/Topology/Constructions.lean @@ -823,11 +823,14 @@ protected theorem IsOpenMap.prodMap {f : X → Y} {g : Z → W} (hf : IsOpenMap @[deprecated (since := "2024-10-05")] alias IsOpenMap.prod := IsOpenMap.prodMap -protected theorem OpenEmbedding.prodMap {f : X → Y} {g : Z → W} (hf : OpenEmbedding f) - (hg : OpenEmbedding g) : OpenEmbedding (Prod.map f g) := - openEmbedding_of_embedding_open (hf.1.prodMap hg.1) (hf.isOpenMap.prodMap hg.isOpenMap) +protected theorem IsOpenEmbedding.prodMap {f : X → Y} {g : Z → W} (hf : IsOpenEmbedding f) + (hg : IsOpenEmbedding g) : IsOpenEmbedding (Prod.map f g) := + isOpenEmbedding_of_embedding_open (hf.1.prodMap hg.1) (hf.isOpenMap.prodMap hg.isOpenMap) -@[deprecated (since := "2024-10-05")] alias OpenEmbedding.prod := OpenEmbedding.prodMap +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.prodMap := IsOpenEmbedding.prodMap + +@[deprecated (since := "2024-10-05")] alias IsOpenEmbedding.prod := IsOpenEmbedding.prodMap theorem embedding_graph {f : X → Y} (hf : Continuous f) : Embedding fun x => (x, f x) := embedding_of_embedding_compose (continuous_id.prod_mk hf) continuous_fst embedding_id @@ -902,23 +905,29 @@ theorem isOpenMap_inl : IsOpenMap (@inl X Y) := fun u hu => by theorem isOpenMap_inr : IsOpenMap (@inr X Y) := fun u hu => by simpa [isOpen_sum_iff, preimage_image_eq u Sum.inr_injective] -theorem openEmbedding_inl : OpenEmbedding (@inl X Y) := - openEmbedding_of_continuous_injective_open continuous_inl inl_injective isOpenMap_inl +theorem isOpenEmbedding_inl : IsOpenEmbedding (@inl X Y) := + isOpenEmbedding_of_continuous_injective_open continuous_inl inl_injective isOpenMap_inl + +@[deprecated (since := "2024-10-18")] +alias openEmbedding_inl := isOpenEmbedding_inl + +theorem isOpenEmbedding_inr : IsOpenEmbedding (@inr X Y) := + isOpenEmbedding_of_continuous_injective_open continuous_inr inr_injective isOpenMap_inr -theorem openEmbedding_inr : OpenEmbedding (@inr X Y) := - openEmbedding_of_continuous_injective_open continuous_inr inr_injective isOpenMap_inr +@[deprecated (since := "2024-10-18")] +alias openEmbedding_inr := isOpenEmbedding_inr theorem embedding_inl : Embedding (@inl X Y) := - openEmbedding_inl.1 + isOpenEmbedding_inl.1 theorem embedding_inr : Embedding (@inr X Y) := - openEmbedding_inr.1 + isOpenEmbedding_inr.1 theorem isOpen_range_inl : IsOpen (range (inl : X → X ⊕ Y)) := - openEmbedding_inl.2 + isOpenEmbedding_inl.2 theorem isOpen_range_inr : IsOpen (range (inr : Y → X ⊕ Y)) := - openEmbedding_inr.2 + isOpenEmbedding_inr.2 theorem isClosed_range_inl : IsClosed (range (inl : X → X ⊕ Y)) := by rw [← isOpen_compl_iff, compl_range_inl] @@ -935,10 +944,10 @@ theorem closedEmbedding_inr : ClosedEmbedding (inr : Y → X ⊕ Y) := ⟨embedding_inr, isClosed_range_inr⟩ theorem nhds_inl (x : X) : 𝓝 (inl x : X ⊕ Y) = map inl (𝓝 x) := - (openEmbedding_inl.map_nhds_eq _).symm + (isOpenEmbedding_inl.map_nhds_eq _).symm theorem nhds_inr (y : Y) : 𝓝 (inr y : X ⊕ Y) = map inr (𝓝 y) := - (openEmbedding_inr.map_nhds_eq _).symm + (isOpenEmbedding_inr.map_nhds_eq _).symm @[simp] theorem continuous_sum_map {f : X → Y} {g : Z → W} : @@ -1006,12 +1015,15 @@ theorem Continuous.subtype_val {f : Y → Subtype p} (hf : Continuous f) : Continuous fun x => (f x : X) := continuous_subtype_val.comp hf -theorem IsOpen.openEmbedding_subtype_val {s : Set X} (hs : IsOpen s) : - OpenEmbedding ((↑) : s → X) := +theorem IsOpen.isOpenEmbedding_subtypeVal {s : Set X} (hs : IsOpen s) : + IsOpenEmbedding ((↑) : s → X) := ⟨embedding_subtype_val, (@Subtype.range_coe _ s).symm ▸ hs⟩ +@[deprecated (since := "2024-10-18")] +alias IsOpen.openEmbedding_subtype_val := IsOpen.isOpenEmbedding_subtypeVal + theorem IsOpen.isOpenMap_subtype_val {s : Set X} (hs : IsOpen s) : IsOpenMap ((↑) : s → X) := - hs.openEmbedding_subtype_val.isOpenMap + hs.isOpenEmbedding_subtypeVal.isOpenMap theorem IsOpenMap.restrict {f : X → Y} (hf : IsOpenMap f) {s : Set X} (hs : IsOpen s) : IsOpenMap (s.restrict f) := @@ -1123,8 +1135,8 @@ then its restriction to the preimage of an open set is a quotient map too. -/ theorem QuotientMap.restrictPreimage_isOpen {f : X → Y} (hf : QuotientMap f) {s : Set Y} (hs : IsOpen s) : QuotientMap (s.restrictPreimage f) := by refine quotientMap_iff.2 ⟨hf.surjective.restrictPreimage _, fun U ↦ ?_⟩ - rw [hs.openEmbedding_subtype_val.open_iff_image_open, ← hf.isOpen_preimage, - (hs.preimage hf.continuous).openEmbedding_subtype_val.open_iff_image_open, + rw [hs.isOpenEmbedding_subtypeVal.open_iff_image_open, ← hf.isOpen_preimage, + (hs.preimage hf.continuous).isOpenEmbedding_subtypeVal.open_iff_image_open, image_val_preimage_restrictPreimage] open scoped Set.Notation in @@ -1528,10 +1540,13 @@ theorem isClosedMap_sigmaMk {i : ι} : IsClosedMap (@Sigma.mk ι σ i) := by theorem isClosed_range_sigmaMk {i : ι} : IsClosed (range (@Sigma.mk ι σ i)) := isClosedMap_sigmaMk.isClosed_range -theorem openEmbedding_sigmaMk {i : ι} : OpenEmbedding (@Sigma.mk ι σ i) := - openEmbedding_of_continuous_injective_open continuous_sigmaMk sigma_mk_injective +theorem isOpenEmbedding_sigmaMk {i : ι} : IsOpenEmbedding (@Sigma.mk ι σ i) := + isOpenEmbedding_of_continuous_injective_open continuous_sigmaMk sigma_mk_injective isOpenMap_sigmaMk +@[deprecated (since := "2024-10-18")] +alias openEmbedding_sigmaMk := isOpenEmbedding_sigmaMk + theorem closedEmbedding_sigmaMk {i : ι} : ClosedEmbedding (@Sigma.mk ι σ i) := closedEmbedding_of_continuous_injective_closed continuous_sigmaMk sigma_mk_injective isClosedMap_sigmaMk @@ -1540,7 +1555,7 @@ theorem embedding_sigmaMk {i : ι} : Embedding (@Sigma.mk ι σ i) := closedEmbedding_sigmaMk.1 theorem Sigma.nhds_mk (i : ι) (x : σ i) : 𝓝 (⟨i, x⟩ : Sigma σ) = Filter.map (Sigma.mk i) (𝓝 x) := - (openEmbedding_sigmaMk.map_nhds_eq x).symm + (isOpenEmbedding_sigmaMk.map_nhds_eq x).symm theorem Sigma.nhds_eq (x : Sigma σ) : 𝓝 x = Filter.map (Sigma.mk x.1) (𝓝 x.2) := by cases x @@ -1600,7 +1615,7 @@ theorem isOpenMap_sigma {f : Sigma σ → X} : IsOpenMap f ↔ ∀ i, IsOpenMap theorem isOpenMap_sigma_map {f₁ : ι → κ} {f₂ : ∀ i, σ i → τ (f₁ i)} : IsOpenMap (Sigma.map f₁ f₂) ↔ ∀ i, IsOpenMap (f₂ i) := isOpenMap_sigma.trans <| - forall_congr' fun i => (@openEmbedding_sigmaMk _ _ _ (f₁ i)).isOpenMap_iff.symm + forall_congr' fun i => (@isOpenEmbedding_sigmaMk _ _ _ (f₁ i)).isOpenMap_iff.symm theorem inducing_sigma_map {f₁ : ι → κ} {f₂ : ∀ i, σ i → τ (f₁ i)} (h₁ : Injective f₁) : Inducing (Sigma.map f₁ f₂) ↔ ∀ i, Inducing (f₂ i) := by @@ -1611,11 +1626,14 @@ theorem embedding_sigma_map {f₁ : ι → κ} {f₂ : ∀ i, σ i → τ (f₁ Embedding (Sigma.map f₁ f₂) ↔ ∀ i, Embedding (f₂ i) := by simp only [embedding_iff, Injective.sigma_map, inducing_sigma_map h, forall_and, h.sigma_map_iff] -theorem openEmbedding_sigma_map {f₁ : ι → κ} {f₂ : ∀ i, σ i → τ (f₁ i)} (h : Injective f₁) : - OpenEmbedding (Sigma.map f₁ f₂) ↔ ∀ i, OpenEmbedding (f₂ i) := by - simp only [openEmbedding_iff_embedding_open, isOpenMap_sigma_map, embedding_sigma_map h, +theorem isOpenEmbedding_sigma_map {f₁ : ι → κ} {f₂ : ∀ i, σ i → τ (f₁ i)} (h : Injective f₁) : + IsOpenEmbedding (Sigma.map f₁ f₂) ↔ ∀ i, IsOpenEmbedding (f₂ i) := by + simp only [isOpenEmbedding_iff_embedding_open, isOpenMap_sigma_map, embedding_sigma_map h, forall_and] +@[deprecated (since := "2024-10-18")] +alias openEmbedding_sigma_map := isOpenEmbedding_sigma_map + end Sigma section ULift @@ -1688,4 +1706,4 @@ theorem Filter.Eventually.prod_nhdsSet {p : X × Y → Prop} {px : X → Prop} { end NhdsSet -set_option linter.style.longFile 1700 +set_option linter.style.longFile 1900 diff --git a/Mathlib/Topology/ContinuousOn.lean b/Mathlib/Topology/ContinuousOn.lean index d69f7aec791234..ef53ffeb6a3971 100644 --- a/Mathlib/Topology/ContinuousOn.lean +++ b/Mathlib/Topology/ContinuousOn.lean @@ -1081,12 +1081,15 @@ theorem Embedding.map_nhdsWithin_eq {f : α → β} (hf : Embedding f) (s : Set rw [nhdsWithin, Filter.map_inf hf.inj, hf.map_nhds_eq, map_principal, ← nhdsWithin_inter', inter_eq_self_of_subset_right (image_subset_range _ _)] -theorem OpenEmbedding.map_nhdsWithin_preimage_eq {f : α → β} (hf : OpenEmbedding f) (s : Set β) +theorem IsOpenEmbedding.map_nhdsWithin_preimage_eq {f : α → β} (hf : IsOpenEmbedding f) (s : Set β) (x : α) : map f (𝓝[f ⁻¹' s] x) = 𝓝[s] f x := by rw [hf.toEmbedding.map_nhdsWithin_eq, image_preimage_eq_inter_range] apply nhdsWithin_eq_nhdsWithin (mem_range_self _) hf.isOpen_range rw [inter_assoc, inter_self] +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.map_nhdsWithin_preimage_eq := IsOpenEmbedding.map_nhdsWithin_preimage_eq + theorem QuotientMap.continuousOn_isOpen_iff {f : α → β} {g : β → γ} (h : QuotientMap 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] diff --git a/Mathlib/Topology/Defs/Induced.lean b/Mathlib/Topology/Defs/Induced.lean index c64958ba704431..0aaa1d46b8de92 100644 --- a/Mathlib/Topology/Defs/Induced.lean +++ b/Mathlib/Topology/Defs/Induced.lean @@ -28,7 +28,7 @@ as well as topology inducing maps, topological embeddings, and quotient maps. * `Embedding`: a map `f : X → Y` is an *embedding*, if it is a topology inducing map and it is injective. -* `OpenEmbedding`: a map `f : X → Y` is an *open embedding*, +* `IsOpenEmbedding`: a map `f : X → Y` is an *open embedding*, if it is an embedding and its range is open. An open embedding is an open map. @@ -112,10 +112,13 @@ structure Embedding [TopologicalSpace X] [TopologicalSpace Y] (f : X → Y) exte /-- An open embedding is an embedding with open range. -/ @[mk_iff] -structure OpenEmbedding (f : X → Y) extends Embedding f : Prop where +structure IsOpenEmbedding (f : X → Y) extends Embedding f : Prop where /-- The range of an open embedding is an open set. -/ isOpen_range : IsOpen <| range f +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding := IsOpenEmbedding + /-- A closed embedding is an embedding with closed image. -/ @[mk_iff] structure ClosedEmbedding (f : X → Y) extends Embedding f : Prop where diff --git a/Mathlib/Topology/Gluing.lean b/Mathlib/Topology/Gluing.lean index 753550992301e1..87c5a52e0a4944 100644 --- a/Mathlib/Topology/Gluing.lean +++ b/Mathlib/Topology/Gluing.lean @@ -46,7 +46,7 @@ provided. * `TopCat.GlueData.preimage_range`: The preimage of the image of `U i` in `U j` is `V i j`. * `TopCat.GlueData.preimage_image_eq_image`: The preimage of the image of some `U ⊆ U i` is given by XXX. -* `TopCat.GlueData.ι_openEmbedding`: Each of the `ι i`s are open embeddings. +* `TopCat.GlueData.ι_isOpenEmbedding`: Each of the `ι i`s are open embeddings. -/ @@ -84,7 +84,7 @@ conditions are stated in a less categorical way. -/ -- porting note (#5171): removed @[nolint has_nonempty_instance] structure GlueData extends GlueData TopCat where - f_open : ∀ i j, OpenEmbedding (f i j) + f_open : ∀ i j, IsOpenEmbedding (f i j) f_mono := fun i j => (TopCat.mono_iff_injective _).mpr (f_open i j).toEmbedding.inj namespace GlueData @@ -292,10 +292,13 @@ theorem open_image_open (i : D.J) (U : Opens (𝖣.U i)) : IsOpen (𝖣.ι i '' apply (D.t j i ≫ D.f i j).continuous_toFun.isOpen_preimage exact U.isOpen -theorem ι_openEmbedding (i : D.J) : OpenEmbedding (𝖣.ι i) := - openEmbedding_of_continuous_injective_open (𝖣.ι i).continuous_toFun (D.ι_injective i) fun U h => +theorem ι_isOpenEmbedding (i : D.J) : IsOpenEmbedding (𝖣.ι i) := + isOpenEmbedding_of_continuous_injective_open (𝖣.ι i).continuous_toFun (D.ι_injective i) fun U h => D.open_image_open i ⟨U, h⟩ +@[deprecated (since := "2024-10-18")] +alias ι_openEmbedding := ι_isOpenEmbedding + /-- A family of gluing data consists of 1. An index type `J` 2. A bundled topological space `U i` for each `i : J`. @@ -356,7 +359,7 @@ def mk' (h : MkCore.{u}) : TopCat.GlueData where -- Porting note (#12129): additional beta reduction needed beta_reduce exact (h.V_id i).symm ▸ (Opens.inclusionTopIso (h.U i)).isIso_hom - f_open := fun i j : h.J => (h.V i j).openEmbedding + f_open := fun i j : h.J => (h.V i j).isOpenEmbedding t := h.t t_id i := by ext; rw [h.t_id]; rfl t' := h.t' @@ -404,7 +407,7 @@ def ofOpenSubsets : TopCat.GlueData.{u} := cocycle := fun _ _ _ _ _ => rfl } /-- The canonical map from the glue of a family of open subsets `α` into `α`. -This map is an open embedding (`fromOpenSubsetsGlue_openEmbedding`), +This map is an open embedding (`fromOpenSubsetsGlue_isOpenEmbedding`), and its range is `⋃ i, (U i : Set α)` (`range_fromOpenSubsetsGlue`). -/ def fromOpenSubsetsGlue : (ofOpenSubsets U).toGlueData.glued ⟶ TopCat.of α := @@ -439,7 +442,7 @@ theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by use Set.inter_subset_left constructor · rw [← Set.image_preimage_eq_inter_range] - apply (Opens.openEmbedding (X := TopCat.of α) (U i)).isOpenMap + apply (Opens.isOpenEmbedding (X := TopCat.of α) (U i)).isOpenMap convert hs i using 1 erw [← ι_fromOpenSubsetsGlue, coe_comp, Set.preimage_comp] -- porting note: `congr 1` did nothing, so I replaced it with `apply congr_arg` @@ -449,10 +452,13 @@ theorem fromOpenSubsetsGlue_isOpenMap : IsOpenMap (fromOpenSubsetsGlue U) := by rw [ι_fromOpenSubsetsGlue_apply] exact Set.mem_range_self _ -theorem fromOpenSubsetsGlue_openEmbedding : OpenEmbedding (fromOpenSubsetsGlue U) := - openEmbedding_of_continuous_injective_open (ContinuousMap.continuous_toFun _) +theorem fromOpenSubsetsGlue_isOpenEmbedding : IsOpenEmbedding (fromOpenSubsetsGlue U) := + isOpenEmbedding_of_continuous_injective_open (ContinuousMap.continuous_toFun _) (fromOpenSubsetsGlue_injective U) (fromOpenSubsetsGlue_isOpenMap U) +@[deprecated (since := "2024-10-18")] +alias fromOpenSubsetsGlue_openEmbedding := fromOpenSubsetsGlue_isOpenEmbedding + theorem range_fromOpenSubsetsGlue : Set.range (fromOpenSubsetsGlue U) = ⋃ i, (U i : Set α) := by ext constructor diff --git a/Mathlib/Topology/Homeomorph.lean b/Mathlib/Topology/Homeomorph.lean index c406c1e326c583..ce885a2ca891d1 100644 --- a/Mathlib/Topology/Homeomorph.lean +++ b/Mathlib/Topology/Homeomorph.lean @@ -332,8 +332,11 @@ theorem isClosed_image (h : X ≃ₜ Y) {s : Set X} : IsClosed (h '' s) ↔ IsCl protected theorem isClosedMap (h : X ≃ₜ Y) : IsClosedMap h := fun _ => h.isClosed_image.2 -protected theorem openEmbedding (h : X ≃ₜ Y) : OpenEmbedding h := - openEmbedding_of_embedding_open h.embedding h.isOpenMap +theorem isOpenEmbedding (h : X ≃ₜ Y) : IsOpenEmbedding h := + isOpenEmbedding_of_embedding_open h.embedding h.isOpenMap + +@[deprecated (since := "2024-10-18")] +alias openEmbedding := isOpenEmbedding protected theorem closedEmbedding (h : X ≃ₜ Y) : ClosedEmbedding h := closedEmbedding_of_embedding_closed h.embedding h.isClosedMap @@ -401,7 +404,7 @@ theorem locallyConnectedSpace [i : LocallyConnectedSpace Y] (h : X ≃ₜ Y) : the domain is a locally compact space. -/ theorem locallyCompactSpace_iff (h : X ≃ₜ Y) : LocallyCompactSpace X ↔ LocallyCompactSpace Y := by - exact ⟨fun _ => h.symm.openEmbedding.locallyCompactSpace, + exact ⟨fun _ => h.symm.isOpenEmbedding.locallyCompactSpace, fun _ => h.closedEmbedding.locallyCompactSpace⟩ /-- If a bijective map `e : X ≃ Y` is continuous and open, then it is a homeomorphism. -/ @@ -908,10 +911,13 @@ protected lemma isClosedMap : IsClosedMap f := (hf.homeomorph f).isClosedMap protected lemma inducing : Inducing f := (hf.homeomorph f).inducing protected lemma quotientMap : QuotientMap f := (hf.homeomorph f).quotientMap protected lemma embedding : Embedding f := (hf.homeomorph f).embedding -protected lemma openEmbedding : OpenEmbedding f := (hf.homeomorph f).openEmbedding +lemma isOpenEmbedding : IsOpenEmbedding f := (hf.homeomorph f).isOpenEmbedding protected lemma closedEmbedding : ClosedEmbedding f := (hf.homeomorph f).closedEmbedding lemma isDenseEmbedding : IsDenseEmbedding f := (hf.homeomorph f).isDenseEmbedding +@[deprecated (since := "2024-10-18")] +alias openEmbedding := isOpenEmbedding + @[deprecated (since := "2024-09-30")] alias denseEmbedding := isDenseEmbedding @@ -932,7 +938,7 @@ lemma isHomeomorph_iff_exists_inverse : IsHomeomorph f ↔ Continuous f ∧ ∃ /-- A map is a homeomorphism iff it is a surjective embedding. -/ lemma isHomeomorph_iff_embedding_surjective : IsHomeomorph f ↔ Embedding f ∧ Surjective f where mp hf := ⟨hf.embedding, hf.surjective⟩ - mpr h := ⟨h.1.continuous, ((openEmbedding_iff f).2 ⟨h.1, h.2.range_eq ▸ isOpen_univ⟩).isOpenMap, + mpr h := ⟨h.1.continuous, ((isOpenEmbedding_iff f).2 ⟨h.1, h.2.range_eq ▸ isOpen_univ⟩).isOpenMap, h.1.inj, h.2⟩ /-- A map is a homeomorphism iff it is continuous, closed and bijective. -/ diff --git a/Mathlib/Topology/Inseparable.lean b/Mathlib/Topology/Inseparable.lean index a179072f0d0725..85b288a5061a8f 100644 --- a/Mathlib/Topology/Inseparable.lean +++ b/Mathlib/Topology/Inseparable.lean @@ -369,9 +369,12 @@ lemma Inducing.generalizingMap (hf : Inducing f) (h : StableUnderGeneralization obtain ⟨y, rfl⟩ := h e ⟨x, rfl⟩ exact ⟨_, hf.specializes_iff.mp e, rfl⟩ -lemma OpenEmbedding.generalizingMap (hf : OpenEmbedding f) : GeneralizingMap f := +lemma IsOpenEmbedding.generalizingMap (hf : IsOpenEmbedding f) : GeneralizingMap f := hf.toInducing.generalizingMap hf.isOpen_range.stableUnderGeneralization +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.generalizingMap := IsOpenEmbedding.generalizingMap + lemma SpecializingMap.stableUnderSpecialization_range (h : SpecializingMap f) : StableUnderSpecialization (range f) := @image_univ _ _ f ▸ stableUnderSpecialization_univ.image h diff --git a/Mathlib/Topology/Instances/ENNReal.lean b/Mathlib/Topology/Instances/ENNReal.lean index 40974db3f97173..a6719468d25d3a 100644 --- a/Mathlib/Topology/Instances/ENNReal.lean +++ b/Mathlib/Topology/Instances/ENNReal.lean @@ -59,11 +59,14 @@ theorem isOpen_Ico_zero : IsOpen (Ico 0 b) := by rw [ENNReal.Ico_eq_Iio] exact isOpen_Iio -theorem openEmbedding_coe : OpenEmbedding ((↑) : ℝ≥0 → ℝ≥0∞) := +theorem isOpenEmbedding_coe : IsOpenEmbedding ((↑) : ℝ≥0 → ℝ≥0∞) := ⟨embedding_coe, by rw [range_coe']; exact isOpen_Iio⟩ +@[deprecated (since := "2024-10-18")] +alias openEmbedding_coe := isOpenEmbedding_coe + theorem coe_range_mem_nhds : range ((↑) : ℝ≥0 → ℝ≥0∞) ∈ 𝓝 (r : ℝ≥0∞) := - IsOpen.mem_nhds openEmbedding_coe.isOpen_range <| mem_range_self _ + IsOpen.mem_nhds isOpenEmbedding_coe.isOpen_range <| mem_range_self _ @[norm_cast] theorem tendsto_coe {f : Filter α} {m : α → ℝ≥0} {a : ℝ≥0} : @@ -79,7 +82,7 @@ theorem continuous_coe_iff {α} [TopologicalSpace α] {f : α → ℝ≥0} : embedding_coe.continuous_iff.symm theorem nhds_coe {r : ℝ≥0} : 𝓝 (r : ℝ≥0∞) = (𝓝 r).map (↑) := - (openEmbedding_coe.map_nhds_eq r).symm + (isOpenEmbedding_coe.map_nhds_eq r).symm theorem tendsto_nhds_coe_iff {α : Type*} {l : Filter α} {x : ℝ≥0} {f : ℝ≥0∞ → α} : Tendsto f (𝓝 ↑x) l ↔ Tendsto (f ∘ (↑) : ℝ≥0 → α) (𝓝 x) l := by @@ -91,7 +94,7 @@ theorem continuousAt_coe_iff {α : Type*} [TopologicalSpace α] {x : ℝ≥0} {f theorem nhds_coe_coe {r p : ℝ≥0} : 𝓝 ((r : ℝ≥0∞), (p : ℝ≥0∞)) = (𝓝 (r, p)).map fun p : ℝ≥0 × ℝ≥0 => (↑p.1, ↑p.2) := - ((openEmbedding_coe.prodMap openEmbedding_coe).map_nhds_eq (r, p)).symm + ((isOpenEmbedding_coe.prodMap isOpenEmbedding_coe).map_nhds_eq (r, p)).symm theorem continuous_ofReal : Continuous ENNReal.ofReal := (continuous_coe_iff.2 continuous_id).comp continuous_real_toNNReal diff --git a/Mathlib/Topology/Instances/ENat.lean b/Mathlib/Topology/Instances/ENat.lean index ee7773df5b64be..0217f6abc247c6 100644 --- a/Mathlib/Topology/Instances/ENat.lean +++ b/Mathlib/Topology/Instances/ENat.lean @@ -33,11 +33,14 @@ instance : OrderTopology ℕ∞ := ⟨rfl⟩ theorem embedding_natCast : Embedding ((↑) : ℕ → ℕ∞) := Nat.strictMono_cast.embedding_of_ordConnected <| range_natCast ▸ ordConnected_Iio -theorem openEmbedding_natCast : OpenEmbedding ((↑) : ℕ → ℕ∞) := +theorem isOpenEmbedding_natCast : IsOpenEmbedding ((↑) : ℕ → ℕ∞) := ⟨embedding_natCast, range_natCast ▸ isOpen_Iio⟩ +@[deprecated (since := "2024-10-18")] +alias openEmbedding_natCast := isOpenEmbedding_natCast + theorem nhds_natCast (n : ℕ) : 𝓝 (n : ℕ∞) = pure (n : ℕ∞) := by - simp [← openEmbedding_natCast.map_nhds_eq] + simp [← isOpenEmbedding_natCast.map_nhds_eq] @[simp] protected theorem nhds_eq_pure {n : ℕ∞} (h : n ≠ ⊤) : 𝓝 n = pure n := by diff --git a/Mathlib/Topology/Instances/EReal.lean b/Mathlib/Topology/Instances/EReal.lean index f6f81f163a7bd4..1b66243074048a 100644 --- a/Mathlib/Topology/Instances/EReal.lean +++ b/Mathlib/Topology/Instances/EReal.lean @@ -51,9 +51,12 @@ instance : SecondCountableTopology EReal := theorem embedding_coe : Embedding ((↑) : ℝ → EReal) := coe_strictMono.embedding_of_ordConnected <| by rw [range_coe_eq_Ioo]; exact ordConnected_Ioo -theorem openEmbedding_coe : OpenEmbedding ((↑) : ℝ → EReal) := +theorem isOpenEmbedding_coe : IsOpenEmbedding ((↑) : ℝ → EReal) := ⟨embedding_coe, by simp only [range_coe_eq_Ioo, isOpen_Ioo]⟩ +@[deprecated (since := "2024-10-18")] +alias openEmbedding_coe := isOpenEmbedding_coe + @[norm_cast] theorem tendsto_coe {α : Type*} {f : Filter α} {m : α → ℝ} {a : ℝ} : Tendsto (fun a => (m a : EReal)) f (𝓝 ↑a) ↔ Tendsto m f (𝓝 a) := @@ -66,11 +69,11 @@ theorem continuous_coe_iff {f : α → ℝ} : (Continuous fun a => (f a : EReal) embedding_coe.continuous_iff.symm theorem nhds_coe {r : ℝ} : 𝓝 (r : EReal) = (𝓝 r).map (↑) := - (openEmbedding_coe.map_nhds_eq r).symm + (isOpenEmbedding_coe.map_nhds_eq r).symm theorem nhds_coe_coe {r p : ℝ} : 𝓝 ((r : EReal), (p : EReal)) = (𝓝 (r, p)).map fun p : ℝ × ℝ => (↑p.1, ↑p.2) := - ((openEmbedding_coe.prodMap openEmbedding_coe).map_nhds_eq (r, p)).symm + ((isOpenEmbedding_coe.prodMap isOpenEmbedding_coe).map_nhds_eq (r, p)).symm theorem tendsto_toReal {a : EReal} (ha : a ≠ ⊤) (h'a : a ≠ ⊥) : Tendsto EReal.toReal (𝓝 a) (𝓝 a.toReal) := by diff --git a/Mathlib/Topology/Irreducible.lean b/Mathlib/Topology/Irreducible.lean index 17b268468df10a..4855d9e0f6e57d 100644 --- a/Mathlib/Topology/Irreducible.lean +++ b/Mathlib/Topology/Irreducible.lean @@ -297,7 +297,7 @@ theorem IsPreirreducible.interior (ht : IsPreirreducible t) : IsPreirreducible ( ht.open_subset isOpen_interior interior_subset theorem IsPreirreducible.preimage (ht : IsPreirreducible t) {f : Y → X} - (hf : OpenEmbedding f) : IsPreirreducible (f ⁻¹' t) := by + (hf : IsOpenEmbedding f) : IsPreirreducible (f ⁻¹' t) := by rintro U V hU hV ⟨x, hx, hx'⟩ ⟨y, hy, hy'⟩ obtain ⟨_, h₁, ⟨y, h₂, rfl⟩, ⟨y', h₃, h₄⟩⟩ := ht _ _ (hf.isOpenMap _ hU) (hf.isOpenMap _ hV) ⟨f x, hx, Set.mem_image_of_mem f hx'⟩ diff --git a/Mathlib/Topology/IsLocalHomeomorph.lean b/Mathlib/Topology/IsLocalHomeomorph.lean index 6351032d8967ec..d75d32d051089d 100644 --- a/Mathlib/Topology/IsLocalHomeomorph.lean +++ b/Mathlib/Topology/IsLocalHomeomorph.lean @@ -39,22 +39,26 @@ the source of some `e : PartialHomeomorph X Y` with `f = e`. -/ def IsLocalHomeomorphOn := ∀ x ∈ s, ∃ e : PartialHomeomorph X Y, x ∈ e.source ∧ f = e -theorem isLocalHomeomorphOn_iff_openEmbedding_restrict {f : X → Y} : - IsLocalHomeomorphOn f s ↔ ∀ x ∈ s, ∃ U ∈ 𝓝 x, OpenEmbedding (U.restrict f) := by +theorem isLocalHomeomorphOn_iff_isOpenEmbedding_restrict {f : X → Y} : + IsLocalHomeomorphOn f s ↔ ∀ x ∈ s, ∃ U ∈ 𝓝 x, IsOpenEmbedding (U.restrict 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.openEmbedding_restrict⟩ + exact ⟨e.source, e.open_source.mem_nhds hxe, e.isOpenEmbedding_restrict⟩ · obtain ⟨U, hU, emb⟩ := h x hx - have : OpenEmbedding ((interior U).restrict f) := by + have : IsOpenEmbedding ((interior U).restrict f) := by refine emb.comp ⟨embedding_inclusion interior_subset, ?_⟩ rw [Set.range_inclusion]; exact isOpen_induced isOpen_interior - obtain ⟨cont, inj, openMap⟩ := openEmbedding_iff_continuous_injective_open.mp this + obtain ⟨cont, inj, openMap⟩ := isOpenEmbedding_iff_continuous_injective_open.mp this haveI : Nonempty X := ⟨x⟩ exact ⟨PartialHomeomorph.ofContinuousOpenRestrict (Set.injOn_iff_injective.mpr inj).toPartialEquiv (continuousOn_iff_continuous_restrict.mpr cont) openMap isOpen_interior, mem_interior_iff_mem_nhds.mpr hU, rfl⟩ +@[deprecated (since := "2024-10-18")] +alias isLocalHomeomorphOn_iff_openEmbedding_restrict := + isLocalHomeomorphOn_iff_isOpenEmbedding_restrict + namespace IsLocalHomeomorphOn /-- Proves that `f` satisfies `IsLocalHomeomorphOn f s`. The condition `h` is weaker than the @@ -141,14 +145,20 @@ theorem isLocalHomeomorph_iff_isLocalHomeomorphOn_univ : protected theorem IsLocalHomeomorph.isLocalHomeomorphOn (hf : IsLocalHomeomorph f) : IsLocalHomeomorphOn f s := fun x _ ↦ hf x -theorem isLocalHomeomorph_iff_openEmbedding_restrict {f : X → Y} : - IsLocalHomeomorph f ↔ ∀ x : X, ∃ U ∈ 𝓝 x, OpenEmbedding (U.restrict f) := by +theorem isLocalHomeomorph_iff_isOpenEmbedding_restrict {f : X → Y} : + IsLocalHomeomorph f ↔ ∀ x : X, ∃ U ∈ 𝓝 x, IsOpenEmbedding (U.restrict f) := by simp_rw [isLocalHomeomorph_iff_isLocalHomeomorphOn_univ, - isLocalHomeomorphOn_iff_openEmbedding_restrict, imp_iff_right (Set.mem_univ _)] + isLocalHomeomorphOn_iff_isOpenEmbedding_restrict, imp_iff_right (Set.mem_univ _)] + +@[deprecated (since := "2024-10-18")] +alias isLocalHomeomorph_iff_openEmbedding_restrict := isLocalHomeomorph_iff_isOpenEmbedding_restrict + +theorem IsOpenEmbedding.isLocalHomeomorph (hf : IsOpenEmbedding f) : IsLocalHomeomorph f := + isLocalHomeomorph_iff_isOpenEmbedding_restrict.mpr fun _ ↦ + ⟨_, Filter.univ_mem, hf.comp (Homeomorph.Set.univ X).isOpenEmbedding⟩ -theorem OpenEmbedding.isLocalHomeomorph (hf : OpenEmbedding f) : IsLocalHomeomorph f := - isLocalHomeomorph_iff_openEmbedding_restrict.mpr fun _ ↦ - ⟨_, Filter.univ_mem, hf.comp (Homeomorph.Set.univ X).openEmbedding⟩ +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.isLocalHomeomorph := IsOpenEmbedding.isLocalHomeomorph variable (f) @@ -194,15 +204,18 @@ protected theorem comp (hg : IsLocalHomeomorph g) (hf : IsLocalHomeomorph f) : (hg.isLocalHomeomorphOn.comp hf.isLocalHomeomorphOn (Set.univ.mapsTo_univ f)) /-- An injective local homeomorphism is an open embedding. -/ -theorem openEmbedding_of_injective (hf : IsLocalHomeomorph f) (hi : f.Injective) : - OpenEmbedding f := - openEmbedding_of_continuous_injective_open hf.continuous hi hf.isOpenMap +theorem isOpenEmbedding_of_injective (hf : IsLocalHomeomorph f) (hi : f.Injective) : + IsOpenEmbedding f := + isOpenEmbedding_of_continuous_injective_open hf.continuous hi hf.isOpenMap + +@[deprecated (since := "2024-10-18")] +alias openEmbedding_of_injective := isOpenEmbedding_of_injective /-- A surjective embedding is a homeomorphism. -/ noncomputable def _root_.Embedding.toHomeomeomorph_of_surjective (hf : Embedding f) (hsurj : Function.Surjective f) : X ≃ₜ Y := Homeomorph.homeomorphOfContinuousOpen (Equiv.ofBijective f ⟨hf.inj, hsurj⟩) - hf.continuous (hf.toOpenEmbedding_of_surjective hsurj).isOpenMap + hf.continuous (hf.toIsOpenEmbedding_of_surjective hsurj).isOpenMap /-- A bijective local homeomorphism is a homeomorphism. -/ noncomputable def toHomeomorph_of_bijective (hf : IsLocalHomeomorph f) (hb : f.Bijective) : @@ -210,9 +223,12 @@ noncomputable def toHomeomorph_of_bijective (hf : IsLocalHomeomorph f) (hb : f.B Homeomorph.homeomorphOfContinuousOpen (Equiv.ofBijective f hb) hf.continuous hf.isOpenMap /-- Continuous local sections of a local homeomorphism are open embeddings. -/ -theorem openEmbedding_of_comp (hf : IsLocalHomeomorph g) (hgf : OpenEmbedding (g ∘ f)) - (cont : Continuous f) : OpenEmbedding f := - (hgf.isLocalHomeomorph.of_comp hf cont).openEmbedding_of_injective hgf.inj.of_comp +theorem isOpenEmbedding_of_comp (hf : IsLocalHomeomorph g) (hgf : IsOpenEmbedding (g ∘ f)) + (cont : Continuous f) : IsOpenEmbedding f := + (hgf.isLocalHomeomorph.of_comp hf cont).isOpenEmbedding_of_injective hgf.inj.of_comp + +@[deprecated (since := "2024-10-18")] +alias openEmbedding_of_comp := isOpenEmbedding_of_comp open TopologicalSpace in /-- Ranges of continuous local sections of a local homeomorphism @@ -221,7 +237,7 @@ theorem isTopologicalBasis (hf : IsLocalHomeomorph f) : IsTopologicalBasis {U : Set X | ∃ V : Set Y, IsOpen V ∧ ∃ s : C(V,X), f ∘ s = (↑) ∧ Set.range s = U} := by refine isTopologicalBasis_of_isOpen_of_nhds ?_ fun x U hx hU ↦ ?_ · rintro _ ⟨U, hU, s, hs, rfl⟩ - refine (openEmbedding_of_comp hf (hs ▸ ⟨embedding_subtype_val, ?_⟩) s.continuous).isOpen_range + refine (isOpenEmbedding_of_comp hf (hs ▸ ⟨embedding_subtype_val, ?_⟩) s.continuous).isOpen_range 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, diff --git a/Mathlib/Topology/LocalAtTarget.lean b/Mathlib/Topology/LocalAtTarget.lean index 184b90a9c30e40..4e1a6f06f340a1 100644 --- a/Mathlib/Topology/LocalAtTarget.lean +++ b/Mathlib/Topology/LocalAtTarget.lean @@ -12,7 +12,7 @@ import Mathlib.Topology.LocallyClosed We show that the following properties of continuous maps are local at the target : - `Inducing` - `Embedding` -- `OpenEmbedding` +- `IsOpenEmbedding` - `ClosedEmbedding` -/ @@ -40,12 +40,18 @@ theorem Set.restrictPreimage_embedding (s : Set β) (h : Embedding f) : alias Embedding.restrictPreimage := Set.restrictPreimage_embedding -theorem Set.restrictPreimage_openEmbedding (s : Set β) (h : OpenEmbedding f) : - OpenEmbedding (s.restrictPreimage f) := +theorem Set.restrictPreimage_isOpenEmbedding (s : Set β) (h : IsOpenEmbedding f) : + IsOpenEmbedding (s.restrictPreimage f) := ⟨h.1.restrictPreimage s, (s.range_restrictPreimage f).symm ▸ continuous_subtype_val.isOpen_preimage _ h.isOpen_range⟩ -alias OpenEmbedding.restrictPreimage := Set.restrictPreimage_openEmbedding +@[deprecated (since := "2024-10-18")] +alias Set.restrictPreimage_openEmbedding := Set.restrictPreimage_isOpenEmbedding + +alias IsOpenEmbedding.restrictPreimage := Set.restrictPreimage_isOpenEmbedding + +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.restrictPreimage := IsOpenEmbedding.restrictPreimage theorem Set.restrictPreimage_closedEmbedding (s : Set β) (h : ClosedEmbedding f) : ClosedEmbedding (s.restrictPreimage f) := @@ -96,7 +102,7 @@ theorem isOpen_iff_coe_preimage_of_iSup_eq_top (s : Set β) : -- Porting note: rewrote to avoid ´simp´ issues rw [isOpen_iff_inter_of_iSup_eq_top hU s] refine forall_congr' fun i => ?_ - rw [(U _).2.openEmbedding_subtype_val.open_iff_image_open] + rw [(U _).2.isOpenEmbedding_subtypeVal.open_iff_image_open] erw [Set.image_preimage_eq_inter_range] rw [Subtype.range_coe, Opens.carrier_eq_coe] @@ -110,7 +116,7 @@ theorem isLocallyClosed_iff_coe_preimage_of_iSup_eq_top (s : Set β) : rw [isOpen_iff_coe_preimage_of_iSup_eq_top hU] exact forall_congr' fun i ↦ by have : coborder ((↑) ⁻¹' s : Set (U i)) = Subtype.val ⁻¹' coborder s := by - exact (U i).isOpen.openEmbedding_subtype_val.coborder_preimage _ + exact (U i).isOpen.isOpenEmbedding_subtypeVal.coborder_preimage _ rw [this] theorem isOpenMap_iff_isOpenMap_of_iSup_eq_top : @@ -150,7 +156,7 @@ theorem inducing_iff_inducing_of_iSup_eq_top (h : Continuous f) : (show f x ∈ iSup U by rw [hU] trivial) - rw [← OpenEmbedding.map_nhds_eq (h.1 _ (U i).2).openEmbedding_subtype_val ⟨x, hi⟩, + rw [← IsOpenEmbedding.map_nhds_eq (h.1 _ (U i).2).isOpenEmbedding_subtypeVal ⟨x, hi⟩, (H i) ⟨x, hi⟩, Filter.subtype_coe_map_comap, Function.comp_apply, Subtype.coe_mk, inf_eq_left, Filter.le_principal_iff] exact Filter.preimage_mem_comap ((U i).2.mem_nhds hi) @@ -165,15 +171,19 @@ theorem embedding_iff_embedding_of_iSup_eq_top (h : Continuous f) : convert congr_arg SetLike.coe hU simp -theorem openEmbedding_iff_openEmbedding_of_iSup_eq_top (h : Continuous f) : - OpenEmbedding f ↔ ∀ i, OpenEmbedding ((U i).1.restrictPreimage f) := by - simp_rw [openEmbedding_iff] +theorem isOpenEmbedding_iff_isOpenEmbedding_of_iSup_eq_top (h : Continuous f) : + IsOpenEmbedding f ↔ ∀ i, IsOpenEmbedding ((U i).1.restrictPreimage f) := by + simp_rw [isOpenEmbedding_iff] rw [forall_and] apply and_congr · apply embedding_iff_embedding_of_iSup_eq_top <;> assumption · simp_rw [Set.range_restrictPreimage] apply isOpen_iff_coe_preimage_of_iSup_eq_top hU +@[deprecated (since := "2024-10-18")] +alias openEmbedding_iff_openEmbedding_of_iSup_eq_top := + isOpenEmbedding_iff_isOpenEmbedding_of_iSup_eq_top + theorem closedEmbedding_iff_closedEmbedding_of_iSup_eq_top (h : Continuous f) : ClosedEmbedding f ↔ ∀ i, ClosedEmbedding ((U i).1.restrictPreimage f) := by simp_rw [closedEmbedding_iff] diff --git a/Mathlib/Topology/LocallyClosed.lean b/Mathlib/Topology/LocallyClosed.lean index fd260f0e11c031..6aa387864372eb 100644 --- a/Mathlib/Topology/LocallyClosed.lean +++ b/Mathlib/Topology/LocallyClosed.lean @@ -91,10 +91,13 @@ lemma coborder_preimage (hf : IsOpenMap f) (hf' : Continuous f) (s : Set Y) : (hf.coborder_preimage_subset s).antisymm (hf'.preimage_coborder_subset s) protected -lemma OpenEmbedding.coborder_preimage (hf : OpenEmbedding f) (s : Set Y) : +lemma IsOpenEmbedding.coborder_preimage (hf : IsOpenEmbedding f) (s : Set Y) : coborder (f ⁻¹' s) = f ⁻¹' (coborder s) := coborder_preimage hf.isOpenMap hf.continuous s +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.coborder_preimage := IsOpenEmbedding.coborder_preimage + lemma isClosed_preimage_val_coborder : IsClosed (coborder s ↓∩ s) := by rw [isClosed_preimage_val, inter_eq_right.mpr subset_coborder, coborder_inter_closure] diff --git a/Mathlib/Topology/Maps/Basic.lean b/Mathlib/Topology/Maps/Basic.lean index de7a4ffef44993..c4aaea387693fe 100644 --- a/Mathlib/Topology/Maps/Basic.lean +++ b/Mathlib/Topology/Maps/Basic.lean @@ -20,7 +20,7 @@ This file introduces the following properties of a map `f : X → Y` between top are identified by `f` are also inseparable in the topology on `X`. * `Embedding f` means `f` is inducing and also injective. Equivalently, `f` identifies `X` with a subspace of `Y`. -* `OpenEmbedding f` means `f` is an embedding with open image, so it identifies `X` with an +* `IsOpenEmbedding f` means `f` is an embedding with open image, so it identifies `X` with an open subspace of `Y`. Equivalently, `f` is an embedding and an open map. * `ClosedEmbedding f` similarly means `f` is an embedding with closed image, so it identifies `X` with a closed subspace of `Y`. Equivalently, `f` is an embedding and a closed map. @@ -470,99 +470,138 @@ theorem IsClosedMap.mapClusterPt_iff_lift'_closure end IsClosedMap -section OpenEmbedding +section IsOpenEmbedding variable [TopologicalSpace X] [TopologicalSpace Y] -theorem OpenEmbedding.isOpenMap (hf : OpenEmbedding f) : IsOpenMap f := +theorem IsOpenEmbedding.isOpenMap (hf : IsOpenEmbedding f) : IsOpenMap f := hf.toEmbedding.toInducing.isOpenMap hf.isOpen_range -theorem OpenEmbedding.map_nhds_eq (hf : OpenEmbedding f) (x : X) : +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.isOpenMap := IsOpenEmbedding.isOpenMap + +theorem IsOpenEmbedding.map_nhds_eq (hf : IsOpenEmbedding f) (x : X) : map f (𝓝 x) = 𝓝 (f x) := hf.toEmbedding.map_nhds_of_mem _ <| hf.isOpen_range.mem_nhds <| mem_range_self _ -theorem OpenEmbedding.open_iff_image_open (hf : OpenEmbedding f) {s : Set X} : +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.map_nhds_eq := IsOpenEmbedding.map_nhds_eq + +theorem IsOpenEmbedding.open_iff_image_open (hf : IsOpenEmbedding f) {s : Set X} : IsOpen s ↔ IsOpen (f '' s) := ⟨hf.isOpenMap s, fun h => by convert ← h.preimage hf.toEmbedding.continuous apply preimage_image_eq _ hf.inj⟩ -theorem OpenEmbedding.tendsto_nhds_iff [TopologicalSpace Z] {f : ι → Y} {l : Filter ι} {y : Y} - (hg : OpenEmbedding g) : Tendsto f l (𝓝 y) ↔ Tendsto (g ∘ f) l (𝓝 (g y)) := +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.open_iff_image_open := IsOpenEmbedding.open_iff_image_open + +theorem IsOpenEmbedding.tendsto_nhds_iff [TopologicalSpace Z] {f : ι → Y} {l : Filter ι} {y : Y} + (hg : IsOpenEmbedding g) : Tendsto f l (𝓝 y) ↔ Tendsto (g ∘ f) l (𝓝 (g y)) := hg.toEmbedding.tendsto_nhds_iff -theorem OpenEmbedding.tendsto_nhds_iff' (hf : OpenEmbedding f) {l : Filter Z} {x : X} : +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.tendsto_nhds_iff := IsOpenEmbedding.tendsto_nhds_iff + +theorem IsOpenEmbedding.tendsto_nhds_iff' (hf : IsOpenEmbedding f) {l : Filter Z} {x : X} : Tendsto (g ∘ f) (𝓝 x) l ↔ Tendsto g (𝓝 (f x)) l := by rw [Tendsto, ← map_map, hf.map_nhds_eq]; rfl -theorem OpenEmbedding.continuousAt_iff [TopologicalSpace Z] (hf : OpenEmbedding f) {x : X} : +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.tendsto_nhds_iff' := IsOpenEmbedding.tendsto_nhds_iff' + +theorem IsOpenEmbedding.continuousAt_iff [TopologicalSpace Z] (hf : IsOpenEmbedding f) {x : X} : ContinuousAt (g ∘ f) x ↔ ContinuousAt g (f x) := hf.tendsto_nhds_iff' -theorem OpenEmbedding.continuous (hf : OpenEmbedding f) : Continuous f := +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.continuousAt_iff := IsOpenEmbedding.continuousAt_iff + +theorem IsOpenEmbedding.continuous (hf : IsOpenEmbedding f) : Continuous f := hf.toEmbedding.continuous -theorem OpenEmbedding.open_iff_preimage_open (hf : OpenEmbedding f) {s : Set Y} +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.continuous := IsOpenEmbedding.continuous + +theorem IsOpenEmbedding.open_iff_preimage_open (hf : IsOpenEmbedding f) {s : Set Y} (hs : s ⊆ range f) : IsOpen s ↔ IsOpen (f ⁻¹' s) := by rw [hf.open_iff_image_open, image_preimage_eq_inter_range, inter_eq_self_of_subset_left hs] -theorem openEmbedding_of_embedding_open (h₁ : Embedding f) (h₂ : IsOpenMap f) : - OpenEmbedding f := +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.open_iff_preimage_open := IsOpenEmbedding.open_iff_preimage_open + +theorem isOpenEmbedding_of_embedding_open (h₁ : Embedding f) (h₂ : IsOpenMap f) : + IsOpenEmbedding f := ⟨h₁, h₂.isOpen_range⟩ -/-- A surjective embedding is an `OpenEmbedding`. -/ -theorem _root_.Embedding.toOpenEmbedding_of_surjective (hf : Embedding f) (hsurj : f.Surjective) : - OpenEmbedding f := +@[deprecated (since := "2024-10-18")] +alias openEmbedding_of_embedding_open := isOpenEmbedding_of_embedding_open + +/-- A surjective embedding is an `IsOpenEmbedding`. -/ +theorem _root_.Embedding.toIsOpenEmbedding_of_surjective (hf : Embedding f) (hsurj : f.Surjective) : + IsOpenEmbedding f := ⟨hf, hsurj.range_eq ▸ isOpen_univ⟩ -theorem openEmbedding_iff_embedding_open : - OpenEmbedding f ↔ Embedding f ∧ IsOpenMap f := - ⟨fun h => ⟨h.1, h.isOpenMap⟩, fun h => openEmbedding_of_embedding_open h.1 h.2⟩ +@[deprecated (since := "2024-10-18")] +alias _root_.Embedding.toOpenEmbedding_of_surjective := Embedding.toIsOpenEmbedding_of_surjective + +theorem isOpenEmbedding_iff_embedding_open : + IsOpenEmbedding f ↔ Embedding f ∧ IsOpenMap f := + ⟨fun h => ⟨h.1, h.isOpenMap⟩, fun h => isOpenEmbedding_of_embedding_open h.1 h.2⟩ -theorem openEmbedding_of_continuous_injective_open - (h₁ : Continuous f) (h₂ : Injective f) (h₃ : IsOpenMap f) : OpenEmbedding f := by - simp only [openEmbedding_iff_embedding_open, embedding_iff, inducing_iff_nhds, *, and_true] +@[deprecated (since := "2024-10-18")] +alias openEmbedding_iff_embedding_open := isOpenEmbedding_iff_embedding_open + +theorem isOpenEmbedding_of_continuous_injective_open + (h₁ : Continuous f) (h₂ : Injective f) (h₃ : IsOpenMap f) : IsOpenEmbedding f := by + simp only [isOpenEmbedding_iff_embedding_open, embedding_iff, inducing_iff_nhds, *, and_true] exact fun x => le_antisymm (h₁.tendsto _).le_comap (@comap_map _ _ (𝓝 x) _ h₂ ▸ comap_mono (h₃.nhds_le _)) -theorem openEmbedding_iff_continuous_injective_open : - OpenEmbedding f ↔ Continuous f ∧ Injective f ∧ IsOpenMap f := +theorem isOpenEmbedding_iff_continuous_injective_open : + IsOpenEmbedding f ↔ Continuous f ∧ Injective f ∧ IsOpenMap f := ⟨fun h => ⟨h.continuous, h.inj, h.isOpenMap⟩, fun h => - openEmbedding_of_continuous_injective_open h.1 h.2.1 h.2.2⟩ + isOpenEmbedding_of_continuous_injective_open h.1 h.2.1 h.2.2⟩ + +@[deprecated (since := "2024-10-18")] +alias openEmbedding_iff_continuous_injective_open := isOpenEmbedding_iff_continuous_injective_open -theorem openEmbedding_id : OpenEmbedding (@id X) := +theorem isOpenEmbedding_id : IsOpenEmbedding (@id X) := ⟨embedding_id, IsOpenMap.id.isOpen_range⟩ -namespace OpenEmbedding +@[deprecated (since := "2024-10-18")] +alias openEmbedding_id := isOpenEmbedding_id + +namespace IsOpenEmbedding variable [TopologicalSpace Z] -protected theorem comp (hg : OpenEmbedding g) - (hf : OpenEmbedding f) : OpenEmbedding (g ∘ f) := +protected theorem comp (hg : IsOpenEmbedding g) + (hf : IsOpenEmbedding f) : IsOpenEmbedding (g ∘ f) := ⟨hg.1.comp hf.1, (hg.isOpenMap.comp hf.isOpenMap).isOpen_range⟩ -theorem isOpenMap_iff (hg : OpenEmbedding g) : +theorem isOpenMap_iff (hg : IsOpenEmbedding g) : IsOpenMap f ↔ IsOpenMap (g ∘ f) := by simp_rw [isOpenMap_iff_nhds_le, ← map_map, comp, ← hg.map_nhds_eq, Filter.map_le_map_iff hg.inj] -theorem of_comp_iff (f : X → Y) (hg : OpenEmbedding g) : - OpenEmbedding (g ∘ f) ↔ OpenEmbedding f := by - simp only [openEmbedding_iff_continuous_injective_open, ← hg.isOpenMap_iff, ← +theorem of_comp_iff (f : X → Y) (hg : IsOpenEmbedding g) : + IsOpenEmbedding (g ∘ f) ↔ IsOpenEmbedding f := by + simp only [isOpenEmbedding_iff_continuous_injective_open, ← hg.isOpenMap_iff, ← hg.1.continuous_iff, hg.inj.of_comp_iff] -theorem of_comp (f : X → Y) (hg : OpenEmbedding g) - (h : OpenEmbedding (g ∘ f)) : OpenEmbedding f := - (OpenEmbedding.of_comp_iff f hg).1 h +theorem of_comp (f : X → Y) (hg : IsOpenEmbedding g) + (h : IsOpenEmbedding (g ∘ f)) : IsOpenEmbedding f := + (IsOpenEmbedding.of_comp_iff f hg).1 h -theorem of_isEmpty [IsEmpty X] (f : X → Y) : OpenEmbedding f := - openEmbedding_of_embedding_open (.of_subsingleton f) (IsOpenMap.of_isEmpty f) +theorem of_isEmpty [IsEmpty X] (f : X → Y) : IsOpenEmbedding f := + isOpenEmbedding_of_embedding_open (.of_subsingleton f) (IsOpenMap.of_isEmpty f) -theorem image_mem_nhds {f : X → Y} (hf : OpenEmbedding f) {s : Set X} {x : X} : +theorem image_mem_nhds {f : X → Y} (hf : IsOpenEmbedding f) {s : Set X} {x : X} : f '' s ∈ 𝓝 (f x) ↔ s ∈ 𝓝 x := by rw [← hf.map_nhds_eq, mem_map, preimage_image_eq _ hf.inj] -end OpenEmbedding +end IsOpenEmbedding -end OpenEmbedding +end IsOpenEmbedding section ClosedEmbedding diff --git a/Mathlib/Topology/PartialHomeomorph.lean b/Mathlib/Topology/PartialHomeomorph.lean index 3cecb43406b4ef..4d2b050b3eb3cb 100644 --- a/Mathlib/Topology/PartialHomeomorph.lean +++ b/Mathlib/Topology/PartialHomeomorph.lean @@ -1092,18 +1092,24 @@ def toHomeomorphOfSourceEqUnivTargetEqUniv (h : e.source = (univ : Set X)) (h' : continuous_invFun := by simpa only [continuous_iff_continuousOn_univ, h'] using e.continuousOn_symm -theorem openEmbedding_restrict : OpenEmbedding (e.source.restrict e) := by - refine openEmbedding_of_continuous_injective_open (e.continuousOn.comp_continuous +theorem isOpenEmbedding_restrict : IsOpenEmbedding (e.source.restrict e) := by + refine isOpenEmbedding_of_continuous_injective_open (e.continuousOn.comp_continuous continuous_subtype_val Subtype.prop) e.injOn.injective fun V hV ↦ ?_ rw [Set.restrict_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 +@[deprecated (since := "2024-10-18")] +alias openEmbedding_restrict := isOpenEmbedding_restrict + /-- A partial homeomorphism whose source is all of `X` defines an open embedding of `X` into `Y`. -The converse is also true; see `OpenEmbedding.toPartialHomeomorph`. -/ -theorem to_openEmbedding (h : e.source = Set.univ) : OpenEmbedding e := - e.openEmbedding_restrict.comp - ((Homeomorph.setCongr h).trans <| Homeomorph.Set.univ X).symm.openEmbedding +The converse is also true; see `IsOpenEmbedding.toPartialHomeomorph`. -/ +theorem to_isOpenEmbedding (h : e.source = Set.univ) : IsOpenEmbedding e := + e.isOpenEmbedding_restrict.comp + ((Homeomorph.setCongr h).trans <| Homeomorph.Set.univ X).symm.isOpenEmbedding + +@[deprecated (since := "2024-10-18")] +alias to_openEmbedding := to_isOpenEmbedding end PartialHomeomorph @@ -1156,12 +1162,13 @@ theorem trans_transPartialHomeomorph (e : X ≃ₜ Y) (e' : Y ≃ₜ Z) (f'' : P end Homeomorph -namespace OpenEmbedding +namespace IsOpenEmbedding -variable (f : X → Y) (h : OpenEmbedding f) +variable (f : X → Y) (h : IsOpenEmbedding f) /-- An open 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.to_openEmbedding`. -/ +whose source is all of `X`. The converse is also true; see +`PartialHomeomorph.to_isOpenEmbedding`. -/ @[simps! (config := mfld_cfg) apply source target] noncomputable def toPartialHomeomorph [Nonempty X] : PartialHomeomorph X Y := PartialHomeomorph.ofContinuousOpen (h.toEmbedding.inj.injOn.toPartialEquiv f univ) @@ -1178,7 +1185,7 @@ lemma toPartialHomeomorph_right_inv {x : Y} (hx : x ∈ Set.range f) : rw [← congr_fun (h.toPartialHomeomorph_apply f), PartialHomeomorph.right_inv] rwa [toPartialHomeomorph_target] -end OpenEmbedding +end IsOpenEmbedding /-! inclusion of an open set in a topological space -/ namespace TopologicalSpace.Opens @@ -1191,7 +1198,7 @@ variable (s : Opens X) (hs : Nonempty s) /-- The inclusion of an open subset `s` of a space `X` into `X` is a partial homeomorphism from the subtype `s` to `X`. -/ noncomputable def partialHomeomorphSubtypeCoe : PartialHomeomorph s X := - OpenEmbedding.toPartialHomeomorph _ s.2.openEmbedding_subtype_val + IsOpenEmbedding.toPartialHomeomorph _ s.2.isOpenEmbedding_subtypeVal @[simp, mfld_simps] theorem partialHomeomorphSubtypeCoe_coe : (s.partialHomeomorphSubtypeCoe hs : s → X) = (↑) := diff --git a/Mathlib/Topology/QuasiSeparated.lean b/Mathlib/Topology/QuasiSeparated.lean index 869b89e96ebba6..73240b9ea2c7e2 100644 --- a/Mathlib/Topology/QuasiSeparated.lean +++ b/Mathlib/Topology/QuasiSeparated.lean @@ -22,7 +22,7 @@ open subsets, but their intersection `(0, 1]` is not. of any pairs of compact open subsets of `s` are still compact. - `QuasiSeparatedSpace`: A topological space is quasi-separated if the intersections of any pairs of compact open subsets are still compact. -- `QuasiSeparatedSpace.of_openEmbedding`: If `f : α → β` is an open embedding, and `β` is +- `QuasiSeparatedSpace.of_isOpenEmbedding`: If `f : α → β` is an open embedding, and `β` is a quasi-separated space, then so is `α`. -/ @@ -79,7 +79,7 @@ theorem IsQuasiSeparated.image_of_embedding {s : Set α} (H : IsQuasiSeparated s rw [Set.image_preimage_eq_inter_range, Set.inter_eq_left] exact hV.trans (Set.image_subset_range _ _) -theorem OpenEmbedding.isQuasiSeparated_iff (h : OpenEmbedding f) {s : Set α} : +theorem IsOpenEmbedding.isQuasiSeparated_iff (h : IsOpenEmbedding f) {s : Set α} : IsQuasiSeparated s ↔ IsQuasiSeparated (f '' s) := by refine ⟨fun hs => hs.image_of_embedding h.toEmbedding, ?_⟩ intro H U V hU hU' hU'' hV hV' hV'' @@ -88,10 +88,13 @@ theorem OpenEmbedding.isQuasiSeparated_iff (h : OpenEmbedding f) {s : Set α} : H (f '' U) (f '' V) (Set.image_subset _ hU) (h.isOpenMap _ hU') (hU''.image h.continuous) (Set.image_subset _ hV) (h.isOpenMap _ hV') (hV''.image h.continuous) +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.isQuasiSeparated_iff := IsOpenEmbedding.isQuasiSeparated_iff + theorem isQuasiSeparated_iff_quasiSeparatedSpace (s : Set α) (hs : IsOpen s) : IsQuasiSeparated s ↔ QuasiSeparatedSpace s := by rw [← isQuasiSeparated_univ_iff] - convert (hs.openEmbedding_subtype_val.isQuasiSeparated_iff (s := Set.univ)).symm + convert (hs.isOpenEmbedding_subtypeVal.isQuasiSeparated_iff (s := Set.univ)).symm simp theorem IsQuasiSeparated.of_subset {s t : Set α} (ht : IsQuasiSeparated t) (h : s ⊆ t) : @@ -110,7 +113,10 @@ theorem IsQuasiSeparated.of_quasiSeparatedSpace (s : Set α) [QuasiSeparatedSpac IsQuasiSeparated s := isQuasiSeparated_univ.of_subset (Set.subset_univ _) -theorem QuasiSeparatedSpace.of_openEmbedding (h : OpenEmbedding f) [QuasiSeparatedSpace β] : +theorem QuasiSeparatedSpace.of_isOpenEmbedding (h : IsOpenEmbedding f) [QuasiSeparatedSpace β] : QuasiSeparatedSpace α := isQuasiSeparated_univ_iff.mp (h.isQuasiSeparated_iff.mpr <| IsQuasiSeparated.of_quasiSeparatedSpace _) + +@[deprecated (since := "2024-10-18")] +alias QuasiSeparatedSpace.of_openEmbedding := QuasiSeparatedSpace.of_isOpenEmbedding diff --git a/Mathlib/Topology/SeparatedMap.lean b/Mathlib/Topology/SeparatedMap.lean index 471b35d8086e1d..ccb0ea0f688df2 100644 --- a/Mathlib/Topology/SeparatedMap.lean +++ b/Mathlib/Topology/SeparatedMap.lean @@ -141,15 +141,18 @@ theorem isLocallyInjective_iff_isOpen_diagonal {f : X → Y} : exact ⟨t₁ ∩ t₂, Filter.inter_mem h₁ h₂, fun x₁ h₁ x₂ h₂ he ↦ @t_sub ⟨(x₁, x₂), he⟩ (prod_sub ⟨h₁.1, h₂.2⟩)⟩ -theorem IsLocallyInjective_iff_openEmbedding {f : X → Y} : - IsLocallyInjective f ↔ OpenEmbedding (toPullbackDiag f) := by +theorem IsLocallyInjective_iff_isOpenEmbedding {f : X → Y} : + IsLocallyInjective f ↔ IsOpenEmbedding (toPullbackDiag f) := by rw [isLocallyInjective_iff_isOpen_diagonal, ← range_toPullbackDiag] exact ⟨fun h ↦ ⟨embedding_toPullbackDiag f, h⟩, fun h ↦ h.isOpen_range⟩ +@[deprecated (since := "2024-10-18")] +alias IsLocallyInjective_iff_openEmbedding := IsLocallyInjective_iff_isOpenEmbedding + theorem isLocallyInjective_iff_isOpenMap {f : X → Y} : IsLocallyInjective f ↔ IsOpenMap (toPullbackDiag f) := - IsLocallyInjective_iff_openEmbedding.trans - ⟨OpenEmbedding.isOpenMap, openEmbedding_of_continuous_injective_open + IsLocallyInjective_iff_isOpenEmbedding.trans + ⟨IsOpenEmbedding.isOpenMap, isOpenEmbedding_of_continuous_injective_open (embedding_toPullbackDiag f).continuous (injective_toPullbackDiag f)⟩ theorem discreteTopology_iff_locallyInjective (y : Y) : diff --git a/Mathlib/Topology/Separation.lean b/Mathlib/Topology/Separation.lean index 792e2e67b25444..1ba06927812ebc 100644 --- a/Mathlib/Topology/Separation.lean +++ b/Mathlib/Topology/Separation.lean @@ -1544,7 +1544,7 @@ Hausdorff spaces: `f x ≠ f y`. We use this lemma to prove that topological spaces defined using `induced` are Hausdorff spaces. -* `separated_by_openEmbedding` says that for an open embedding `f : X → Y` of a Hausdorff space +* `separated_by_isOpenEmbedding` says that for an open embedding `f : X → Y` of a Hausdorff space `X`, the images of two distinct points `x y : X`, `x ≠ y` can be separated by open neighborhoods. We use this lemma to prove that topological spaces defined using `coinduced` are Hausdorff spaces. -/ @@ -1560,13 +1560,16 @@ theorem separated_by_continuous [TopologicalSpace Y] [T2Space Y] let ⟨u, v, uo, vo, xu, yv, uv⟩ := t2_separation h ⟨f ⁻¹' u, f ⁻¹' v, uo.preimage hf, vo.preimage hf, xu, yv, uv.preimage _⟩ -theorem separated_by_openEmbedding [TopologicalSpace Y] [T2Space X] - {f : X → Y} (hf : OpenEmbedding f) {x y : X} (h : x ≠ y) : +theorem separated_by_isOpenEmbedding [TopologicalSpace Y] [T2Space X] + {f : X → Y} (hf : IsOpenEmbedding f) {x y : X} (h : x ≠ y) : ∃ u v : Set Y, IsOpen u ∧ IsOpen v ∧ f x ∈ u ∧ f y ∈ v ∧ Disjoint u v := let ⟨u, v, uo, vo, xu, yv, uv⟩ := t2_separation h ⟨f '' u, f '' v, hf.isOpenMap _ uo, hf.isOpenMap _ vo, mem_image_of_mem _ xu, mem_image_of_mem _ yv, disjoint_image_of_injective hf.inj uv⟩ +@[deprecated (since := "2024-10-18")] +alias separated_by_openEmbedding := separated_by_isOpenEmbedding + instance {p : X → Prop} [T2Space X] : T2Space (Subtype p) := inferInstance instance Prod.t2Space [T2Space X] [TopologicalSpace Y] [T2Space Y] : T2Space (X × Y) := @@ -1591,10 +1594,10 @@ instance [T2Space X] [TopologicalSpace Y] [T2Space Y] : T2Space (X ⊕ Y) := by constructor rintro (x | x) (y | y) h - · exact separated_by_openEmbedding openEmbedding_inl <| ne_of_apply_ne _ h + · exact separated_by_isOpenEmbedding isOpenEmbedding_inl <| ne_of_apply_ne _ h · exact separated_by_continuous continuous_isLeft <| by simp · exact separated_by_continuous continuous_isLeft <| by simp - · exact separated_by_openEmbedding openEmbedding_inr <| ne_of_apply_ne _ h + · exact separated_by_isOpenEmbedding isOpenEmbedding_inr <| ne_of_apply_ne _ h instance Pi.t2Space {Y : X → Type v} [∀ a, TopologicalSpace (Y a)] [∀ a, T2Space (Y a)] : T2Space (∀ a, Y a) := @@ -1606,7 +1609,7 @@ instance Sigma.t2Space {ι} {X : ι → Type*} [∀ i, TopologicalSpace (X i)] [ rintro ⟨i, x⟩ ⟨j, y⟩ neq rcases eq_or_ne i j with (rfl | h) · replace neq : x ≠ y := ne_of_apply_ne _ neq - exact separated_by_openEmbedding openEmbedding_sigmaMk neq + exact separated_by_isOpenEmbedding isOpenEmbedding_sigmaMk neq · let _ := (⊥ : TopologicalSpace ι); have : DiscreteTopology ι := ⟨rfl⟩ exact separated_by_continuous (continuous_def.2 fun u _ => isOpen_sigma_fst_preimage u) h @@ -2597,7 +2600,7 @@ theorem loc_compact_Haus_tot_disc_of_zero_dim [TotallyDisconnectedSpace H] : let v : Set u := ((↑) : u → s) ⁻¹' V have : ((↑) : u → H) = ((↑) : s → H) ∘ ((↑) : u → s) := rfl have f0 : Embedding ((↑) : u → H) := embedding_subtype_val.comp embedding_subtype_val - have f1 : OpenEmbedding ((↑) : u → H) := by + have f1 : IsOpenEmbedding ((↑) : u → H) := by refine ⟨f0, ?_⟩ · have : Set.range ((↑) : u → H) = interior s := by rw [this, Set.range_comp, Subtype.range_coe, Subtype.image_preimage_coe] diff --git a/Mathlib/Topology/Sets/Opens.lean b/Mathlib/Topology/Sets/Opens.lean index bd142710c09905..1252c062af2274 100644 --- a/Mathlib/Topology/Sets/Opens.lean +++ b/Mathlib/Topology/Sets/Opens.lean @@ -243,16 +243,22 @@ def frameMinimalAxioms : Frame.MinimalAxioms (Opens α) where instance instFrame : Frame (Opens α) := .ofMinimalAxioms frameMinimalAxioms -theorem openEmbedding' (U : Opens α) : OpenEmbedding (Subtype.val : U → α) := - U.isOpen.openEmbedding_subtype_val +theorem isOpenEmbedding' (U : Opens α) : IsOpenEmbedding (Subtype.val : U → α) := + U.isOpen.isOpenEmbedding_subtypeVal -theorem openEmbedding_of_le {U V : Opens α} (i : U ≤ V) : - OpenEmbedding (Set.inclusion <| SetLike.coe_subset_coe.2 i) := +@[deprecated (since := "2024-10-18")] +alias openEmbedding' := isOpenEmbedding' + +theorem isOpenEmbedding_of_le {U V : Opens α} (i : U ≤ V) : + IsOpenEmbedding (Set.inclusion <| SetLike.coe_subset_coe.2 i) := { toEmbedding := embedding_inclusion i isOpen_range := by rw [Set.range_inclusion i] exact U.isOpen.preimage continuous_subtype_val } +@[deprecated (since := "2024-10-18")] +alias openEmbedding_of_le := isOpenEmbedding_of_le + theorem not_nonempty_iff_eq_bot (U : Opens α) : ¬Set.Nonempty (U : Set α) ↔ U = ⊥ := by rw [← coe_inj, coe_bot, ← Set.not_nonempty_iff_eq_empty] diff --git a/Mathlib/Topology/Sheaves/LocalPredicate.lean b/Mathlib/Topology/Sheaves/LocalPredicate.lean index 8d32b5f87a342d..bf6e5eb7f9b014 100644 --- a/Mathlib/Topology/Sheaves/LocalPredicate.lean +++ b/Mathlib/Topology/Sheaves/LocalPredicate.lean @@ -73,7 +73,7 @@ variable (X) @[simps!] def continuousPrelocal (T : TopCat.{v}) : PrelocalPredicate fun _ : X => T where pred {_} f := Continuous f - res {_ _} i _ h := Continuous.comp h (Opens.openEmbedding_of_le i.le).continuous + res {_ _} i _ h := Continuous.comp h (Opens.isOpenEmbedding_of_le i.le).continuous /-- Satisfying the inhabited linter. -/ instance inhabitedPrelocalPredicate (T : TopCat.{v}) : @@ -114,7 +114,7 @@ def continuousLocal (T : TopCat.{v}) : LocalPredicate fun _ : X => T := dsimp at w rw [continuous_iff_continuousAt] at w specialize w ⟨x, m⟩ - simpa using (Opens.openEmbedding_of_le i.le).continuousAt_iff.1 w } + simpa using (Opens.isOpenEmbedding_of_le i.le).continuousAt_iff.1 w } /-- Satisfying the inhabited linter. -/ instance inhabitedLocalPredicate (T : TopCat.{v}) : Inhabited (LocalPredicate fun _ : X => T) := diff --git a/Mathlib/Topology/Sheaves/SheafCondition/Sites.lean b/Mathlib/Topology/Sheaves/SheafCondition/Sites.lean index 07a4029efeb34e..88541de424f6bc 100644 --- a/Mathlib/Topology/Sheaves/SheafCondition/Sites.lean +++ b/Mathlib/Topology/Sheaves/SheafCondition/Sites.lean @@ -136,14 +136,14 @@ theorem coverDense_inducedFunctor {B : ι → Opens X} (h : Opens.IsBasis (Set.r end TopCat.Opens -section OpenEmbedding +section IsOpenEmbedding open TopCat.Presheaf Opposite variable {C : Type u} [Category.{v} C] variable {X Y : TopCat.{w}} {f : X ⟶ Y} {F : Y.Presheaf C} -theorem OpenEmbedding.compatiblePreserving (hf : OpenEmbedding f) : +theorem IsOpenEmbedding.compatiblePreserving (hf : IsOpenEmbedding f) : CompatiblePreserving (Opens.grothendieckTopology Y) hf.isOpenMap.functor := by haveI : Mono f := (TopCat.mono_iff_injective f).mpr hf.inj apply compatiblePreservingOfDownwardsClosed @@ -152,6 +152,9 @@ theorem OpenEmbedding.compatiblePreserving (hf : OpenEmbedding f) : obtain ⟨_, _, rfl⟩ := i.le h exact ⟨_, rfl⟩ +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.compatiblePreserving := IsOpenEmbedding.compatiblePreserving + theorem IsOpenMap.coverPreserving (hf : IsOpenMap f) : CoverPreserving (Opens.grothendieckTopology X) (Opens.grothendieckTopology Y) hf.functor := by constructor @@ -160,18 +163,24 @@ theorem IsOpenMap.coverPreserving (hf : IsOpenMap f) : exact ⟨_, hf.functor.map i, ⟨_, i, 𝟙 _, hV, rfl⟩, Set.mem_image_of_mem f hxV⟩ -lemma OpenEmbedding.functor_isContinuous (h : OpenEmbedding f) : +lemma IsOpenEmbedding.functor_isContinuous (h : IsOpenEmbedding f) : h.isOpenMap.functor.IsContinuous (Opens.grothendieckTopology X) (Opens.grothendieckTopology Y) := by apply Functor.isContinuous_of_coverPreserving · exact h.compatiblePreserving · exact h.isOpenMap.coverPreserving -theorem TopCat.Presheaf.isSheaf_of_openEmbedding (h : OpenEmbedding f) (hF : F.IsSheaf) : +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.functor_isContinuous := IsOpenEmbedding.functor_isContinuous + +theorem TopCat.Presheaf.isSheaf_of_isOpenEmbedding (h : IsOpenEmbedding f) (hF : F.IsSheaf) : IsSheaf (h.isOpenMap.functor.op ⋙ F) := by have := h.functor_isContinuous exact Functor.op_comp_isSheaf _ _ _ ⟨_, hF⟩ +@[deprecated (since := "2024-10-18")] +alias TopCat.Presheaf.isSheaf_of_openEmbedding := TopCat.Presheaf.isSheaf_of_isOpenEmbedding + variable (f) instance : RepresentablyFlat (Opens.map f) := by @@ -203,7 +212,7 @@ instance : (Opens.map f).IsContinuous (Opens.grothendieckTopology Y) · exact compatiblePreserving_opens_map f · exact coverPreserving_opens_map f -end OpenEmbedding +end IsOpenEmbedding namespace TopCat.Sheaf diff --git a/Mathlib/Topology/Sheaves/Stalks.lean b/Mathlib/Topology/Sheaves/Stalks.lean index 74df85eb39c033..125a7e70f0fc49 100644 --- a/Mathlib/Topology/Sheaves/Stalks.lean +++ b/Mathlib/Topology/Sheaves/Stalks.lean @@ -208,8 +208,8 @@ theorem comp (ℱ : X.Presheaf C) (f : X ⟶ Y) (g : Y ⟶ Z) (x : X) : ext simp [germ, stalkPushforward] -theorem stalkPushforward_iso_of_openEmbedding {f : X ⟶ Y} (hf : OpenEmbedding f) (F : X.Presheaf C) - (x : X) : IsIso (F.stalkPushforward _ f x) := by +theorem stalkPushforward_iso_of_isOpenEmbedding {f : X ⟶ Y} (hf : IsOpenEmbedding f) + (F : X.Presheaf C) (x : X) : IsIso (F.stalkPushforward _ f x) := by haveI := Functor.initial_of_adjunction (hf.isOpenMap.adjunctionNhds x) convert ((Functor.Final.colimitIso (hf.isOpenMap.functorNhds x).op @@ -234,6 +234,9 @@ theorem stalkPushforward_iso_of_openEmbedding {f : X ⟶ Y} (hf : OpenEmbedding refine ((homOfLE ?_).op : op (unop U) ⟶ _) exact Set.image_preimage_subset _ _ +@[deprecated (since := "2024-10-18")] +alias stalkPushforward_iso_of_openEmbedding := stalkPushforward_iso_of_isOpenEmbedding + end stalkPushforward section stalkPullback diff --git a/Mathlib/Topology/Sober.lean b/Mathlib/Topology/Sober.lean index 82c12d98222d64..06f9286a3e5d3e 100644 --- a/Mathlib/Topology/Sober.lean +++ b/Mathlib/Topology/Sober.lean @@ -182,7 +182,7 @@ theorem ClosedEmbedding.quasiSober {f : α → β} (hf : ClosedEmbedding f) [Qua apply image_injective.mpr hf.inj rw [← hx.def, ← hf.closure_image_eq, image_singleton] -theorem OpenEmbedding.quasiSober {f : α → β} (hf : OpenEmbedding f) [QuasiSober β] : +theorem IsOpenEmbedding.quasiSober {f : α → β} (hf : IsOpenEmbedding f) [QuasiSober β] : QuasiSober α where sober hS hS' := by have hS'' := hS.image f hf.continuous.continuousOn @@ -205,6 +205,9 @@ theorem OpenEmbedding.quasiSober {f : α → β} (hf : OpenEmbedding f) [QuasiSo exact fun hy => ⟨fun h => hT.closure_eq ▸ closure_mono inter_subset_left h, fun h => subset_closure ⟨h, hy⟩⟩ +@[deprecated (since := "2024-10-18")] +alias OpenEmbedding.quasiSober := IsOpenEmbedding.quasiSober + /-- A space is quasi sober if it can be covered by open quasi sober subsets. -/ theorem quasiSober_of_open_cover (S : Set (Set α)) (hS : ∀ s : S, IsOpen (s : Set α)) [hS' : ∀ s : S, QuasiSober s] (hS'' : ⋃₀ S = ⊤) : QuasiSober α := by @@ -216,7 +219,7 @@ theorem quasiSober_of_open_cover (S : Set (Set α)) (hS : ∀ s : S, IsOpen (s : trivial haveI : QuasiSober U := hS' ⟨U, hU⟩ have H : IsPreirreducible ((↑) ⁻¹' t : Set U) := - h.2.preimage (hS ⟨U, hU⟩).openEmbedding_subtype_val + h.2.preimage (hS ⟨U, hU⟩).isOpenEmbedding_subtypeVal replace H : IsIrreducible ((↑) ⁻¹' t : Set U) := ⟨⟨⟨x, hU'⟩, by simpa using hx⟩, H⟩ use H.genericPoint have := continuous_subtype_val.closure_preimage_subset _ H.isGenericPoint_genericPoint_closure.mem diff --git a/Mathlib/Topology/Support.lean b/Mathlib/Topology/Support.lean index c0f19ee3e63a78..11a71da0311a56 100644 --- a/Mathlib/Topology/Support.lean +++ b/Mathlib/Topology/Support.lean @@ -257,7 +257,7 @@ theorem continuous_extend_one [TopologicalSpace β] {U : Set α'} (hU : IsOpen U continuous_of_mulTSupport fun x h ↦ by rw [show x = ↑(⟨x, Subtype.coe_image_subset _ _ (supp.mulTSupport_extend_one_subset continuous_subtype_val h)⟩ : U) by rfl, - ← (hU.openEmbedding_subtype_val).continuousAt_iff, extend_comp Subtype.val_injective] + ← (hU.isOpenEmbedding_subtypeVal).continuousAt_iff, extend_comp Subtype.val_injective] exact cont.continuousAt /-- If `f` has compact multiplicative support, then `f` tends to 1 at infinity. -/ diff --git a/scripts/no_lints_prime_decls.txt b/scripts/no_lints_prime_decls.txt index 671479377b629d..e1817a20922398 100644 --- a/scripts/no_lints_prime_decls.txt +++ b/scripts/no_lints_prime_decls.txt @@ -3521,7 +3521,7 @@ ONote.NF.below_of_lt' ONote.nf_repr_split' ONote.NF.snd' ONote.split_eq_scale_split' -OpenEmbedding.tendsto_nhds_iff' +IsOpenEmbedding.tendsto_nhds_iff' openSegment_eq_image' openSegment_eq_Ioo' Option.bind_congr' @@ -4639,8 +4639,8 @@ toIocMod_sub_zsmul' toIocMod_zsmul_add' toIxxMod_total' TopCat.GlueData.preimage_image_eq_image' -TopCat.openEmbedding_iff_comp_isIso' -TopCat.openEmbedding_iff_isIso_comp' +TopCat.isOpenEmbedding_iff_comp_isIso' +TopCat.isOpenEmbedding_iff_isIso_comp' TopCat.Presheaf.germ_stalkSpecializes' TopCat.Presheaf.pushforward_eq' TopCat.Presheaf.pushforward_map_app' @@ -4650,7 +4650,7 @@ TopologicalSpace.Opens.coe_inclusion' TopologicalSpace.Opens.map_comp_obj' TopologicalSpace.Opens.map_functor_eq' TopologicalSpace.Opens.map_id_obj' -TopologicalSpace.Opens.openEmbedding' +TopologicalSpace.Opens.isOpenEmbedding' TopologicalSpace.Opens.set_range_forget_map_inclusion' TopologicalSpace.Opens.set_range_inclusion' TopologicalSpace.SecondCountableTopology.mk' From b9efa9d8b132e603ec517380352c5b5a29a25e88 Mon Sep 17 00:00:00 2001 From: peabrainiac Date: Fri, 18 Oct 2024 21:51:41 +0000 Subject: [PATCH 403/425] feat(Topology/Connected/PathConnected): some lemmas for `pathComponentIn` (#16983) Adds some basic lemmas about `pathComponentIn`, analogous to existing lemmas about `pathComponent` and `connectedComponentIn`. Co-authored-by: peabrainiac <43812953+peabrainiac@users.noreply.github.com> --- Mathlib/Topology/Connected/PathConnected.lean | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/Mathlib/Topology/Connected/PathConnected.lean b/Mathlib/Topology/Connected/PathConnected.lean index 3a8377f9381641..b9a49ba4fcd65f 100644 --- a/Mathlib/Topology/Connected/PathConnected.lean +++ b/Mathlib/Topology/Connected/PathConnected.lean @@ -848,6 +848,24 @@ theorem Joined.mem_pathComponent (hyz : Joined y z) (hxy : y ∈ pathComponent x z ∈ pathComponent x := hxy.trans hyz +theorem mem_pathComponentIn_self (h : x ∈ F) : x ∈ pathComponentIn x F := + JoinedIn.refl h + +theorem pathComponentIn_subset : pathComponentIn x F ⊆ F := + fun _ hy ↦ hy.target_mem + +theorem pathComponentIn_nonempty_iff : (pathComponentIn x F).Nonempty ↔ x ∈ F := + ⟨fun ⟨_, ⟨γ, hγ⟩⟩ ↦ γ.source ▸ hγ 0, fun hx ↦ ⟨x, mem_pathComponentIn_self hx⟩⟩ + +theorem pathComponentIn_congr (h : x ∈ pathComponentIn y F) : + pathComponentIn x F = pathComponentIn y F := by + ext; exact ⟨h.trans, h.symm.trans⟩ + +@[gcongr] +theorem pathComponentIn_mono {G : Set X} (h : F ⊆ G) : + pathComponentIn x F ⊆ pathComponentIn x G := + fun _ ⟨γ, hγ⟩ ↦ ⟨γ, fun t ↦ h (hγ t)⟩ + /-! ### Path connected sets -/ @@ -913,11 +931,26 @@ theorem IsPathConnected.mem_pathComponent (h : IsPathConnected F) (x_in : x ∈ theorem IsPathConnected.subset_pathComponent (h : IsPathConnected F) (x_in : x ∈ F) : F ⊆ pathComponent x := fun _y y_in => h.mem_pathComponent x_in y_in +theorem IsPathConnected.subset_pathComponentIn {s : Set X} (hs : IsPathConnected s) + (hxs : x ∈ s) (hsF : s ⊆ F) : s ⊆ pathComponentIn x F := + fun y hys ↦ (hs.joinedIn x hxs y hys).mono hsF + theorem isPathConnected_singleton (x : X) : IsPathConnected ({x} : Set X) := by refine ⟨x, rfl, ?_⟩ rintro y rfl exact JoinedIn.refl rfl +theorem isPathConnected_pathComponentIn (h : x ∈ F) : IsPathConnected (pathComponentIn x F) := + ⟨x, mem_pathComponentIn_self h, fun ⟨γ, hγ⟩ ↦ by + refine ⟨γ, fun t ↦ + ⟨(γ.truncateOfLE t.2.1).cast (γ.extend_zero.symm) (γ.extend_extends' t).symm, fun t' ↦ ?_⟩⟩ + dsimp [Path.truncateOfLE, Path.truncate] + exact γ.extend_extends' ⟨min (max t'.1 0) t.1, by simp [t.2.1, t.2.2]⟩ ▸ hγ _⟩ + +theorem isPathConnected_pathComponent : IsPathConnected (pathComponent x) := by + rw [← pathComponentIn_univ] + exact isPathConnected_pathComponentIn (mem_univ x) + theorem IsPathConnected.union {U V : Set X} (hU : IsPathConnected U) (hV : IsPathConnected V) (hUV : (U ∩ V).Nonempty) : IsPathConnected (U ∪ V) := by rcases hUV with ⟨x, xU, xV⟩ From fa8e2105aa86b708d0b03e08ba31c88c1a1f982c Mon Sep 17 00:00:00 2001 From: mathlib4-update-dependencies-bot <150093616+mathlib-bors@users.noreply.github.com> Date: Fri, 18 Oct 2024 21:51:43 +0000 Subject: [PATCH 404/425] chore: update Mathlib dependencies 2024-10-18 (#17929) 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 c93ba44db832ee..f8536ac19fc8c6 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "c521f0185f4dd42b6aa4898010d5ba5357c57c9f", + "rev": "9e3d0d810e9021767c360756f066574f72e8fcce", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From 464f2c556e7870d1c3988d71536b58bbe31640df Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Sat, 19 Oct 2024 09:28:48 +1100 Subject: [PATCH 405/425] unused variable --- Archive/Wiedijk100Theorems/BuffonsNeedle.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Archive/Wiedijk100Theorems/BuffonsNeedle.lean b/Archive/Wiedijk100Theorems/BuffonsNeedle.lean index e27b8be9851f22..a6a4d55b6ac574 100644 --- a/Archive/Wiedijk100Theorems/BuffonsNeedle.lean +++ b/Archive/Wiedijk100Theorems/BuffonsNeedle.lean @@ -201,7 +201,7 @@ include hd hB hBₘ in lemma buffon_integral : 𝔼[N l B] = (d * π) ⁻¹ * ∫ (θ : ℝ) in Set.Icc 0 π, - ∫ (x : ℝ) in Set.Icc (-d / 2) (d / 2) ∩ Set.Icc (-θ.sin * l / 2) (θ.sin * l / 2), 1 := by + ∫ (_ : ℝ) in Set.Icc (-d / 2) (d / 2) ∩ Set.Icc (-θ.sin * l / 2) (θ.sin * l / 2), 1 := by simp_rw [N, Function.comp_apply] rw [ ← MeasureTheory.integral_map hBₘ.aemeasurable From 992ec73d5d2540c7d7bd628b704ef49909a13835 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Sat, 19 Oct 2024 00:06:23 +0000 Subject: [PATCH 406/425] feat: generalize `LinearMap.exists_rightInverse_of_surjective` to projective modules (#17560) Previously it only held in vector spaces. --- Mathlib/Algebra/Module/Projective.lean | 6 +++++- Mathlib/LinearAlgebra/Basis/VectorSpace.lean | 9 --------- Mathlib/LinearAlgebra/Dimension/LinearMap.lean | 1 + Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean | 1 + Mathlib/Topology/Algebra/SeparationQuotient.lean | 1 + 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/Mathlib/Algebra/Module/Projective.lean b/Mathlib/Algebra/Module/Projective.lean index b4387f01f63c99..7a68117b7f456e 100644 --- a/Mathlib/Algebra/Module/Projective.lean +++ b/Mathlib/Algebra/Module/Projective.lean @@ -91,7 +91,7 @@ theorem projective_def' : /-- A projective R-module has the property that maps from it lift along surjections. -/ theorem projective_lifting_property [h : Projective R P] (f : M →ₗ[R] N) (g : P →ₗ[R] N) - (hf : Function.Surjective f) : ∃ h : P →ₗ[R] M, f.comp h = g := by + (hf : Function.Surjective f) : ∃ h : P →ₗ[R] M, f ∘ₗ h = g := by /- Here's the first step of the proof. Recall that `X →₀ R` is Lean's way of talking about the free `R`-module @@ -110,6 +110,10 @@ theorem projective_lifting_property [h : Projective R P] (f : M →ₗ[R] N) (g conv_rhs => rw [← hs p] simp [φ, Finsupp.linearCombination_apply, Function.surjInv_eq hf, map_finsupp_sum] +theorem _root_.LinearMap.exists_rightInverse_of_surjective [Projective R P] + (f : M →ₗ[R] P) (hf_surj : range f = ⊤) : ∃ g : P →ₗ[R] M, f ∘ₗ g = LinearMap.id := + projective_lifting_property f (.id : P →ₗ[R] P) (LinearMap.range_eq_top.1 hf_surj) + /-- A module which satisfies the universal property is projective: If all surjections of `R`-modules `(P →₀ R) →ₗ[R] P` have `R`-linear left inverse maps, then `P` is projective. -/ diff --git a/Mathlib/LinearAlgebra/Basis/VectorSpace.lean b/Mathlib/LinearAlgebra/Basis/VectorSpace.lean index e7a219e569dab2..c16a5b57e71ea8 100644 --- a/Mathlib/LinearAlgebra/Basis/VectorSpace.lean +++ b/Mathlib/LinearAlgebra/Basis/VectorSpace.lean @@ -266,15 +266,6 @@ theorem Submodule.exists_isCompl (p : Submodule K V) : ∃ q : Submodule K V, Is instance Submodule.complementedLattice : ComplementedLattice (Submodule K V) := ⟨Submodule.exists_isCompl⟩ -theorem LinearMap.exists_rightInverse_of_surjective (f : V →ₗ[K] V') (hf_surj : range f = ⊤) : - ∃ g : V' →ₗ[K] V, f.comp g = LinearMap.id := by - let C := Basis.ofVectorSpaceIndex K V' - let hC := Basis.ofVectorSpace K V' - haveI : Inhabited V := ⟨0⟩ - refine ⟨(hC.constr ℕ : _ → _) (C.restrict (invFun f)), hC.ext fun c => ?_⟩ - rw [LinearMap.comp_apply, hC.constr_basis] - simp [hC, rightInverse_invFun (LinearMap.range_eq_top.1 hf_surj) c] - /-- Any linear map `f : p →ₗ[K] V'` defined on a subspace `p` can be extended to the whole space. -/ theorem LinearMap.exists_extend {p : Submodule K V} (f : p →ₗ[K] V') : diff --git a/Mathlib/LinearAlgebra/Dimension/LinearMap.lean b/Mathlib/LinearAlgebra/Dimension/LinearMap.lean index ca2cb869a8ec5f..d9f144980e339e 100644 --- a/Mathlib/LinearAlgebra/Dimension/LinearMap.lean +++ b/Mathlib/LinearAlgebra/Dimension/LinearMap.lean @@ -3,6 +3,7 @@ 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 -/ +import Mathlib.Algebra.Module.Projective import Mathlib.LinearAlgebra.Dimension.DivisionRing import Mathlib.LinearAlgebra.Dimension.FreeAndStrongRankCondition diff --git a/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean b/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean index 172f5f1c0d87af..372c3c0e745523 100644 --- a/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean +++ b/Mathlib/LinearAlgebra/FiniteDimensional/Defs.lean @@ -3,6 +3,7 @@ Copyright (c) 2019 Chris Hughes. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Chris Hughes -/ +import Mathlib.Algebra.Module.Projective import Mathlib.FieldTheory.Finiteness /-! diff --git a/Mathlib/Topology/Algebra/SeparationQuotient.lean b/Mathlib/Topology/Algebra/SeparationQuotient.lean index 83775bba6cbe3a..8a99f4dc7ef343 100644 --- a/Mathlib/Topology/Algebra/SeparationQuotient.lean +++ b/Mathlib/Topology/Algebra/SeparationQuotient.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Yury Kudryashov -/ import Mathlib.LinearAlgebra.Basis.VectorSpace +import Mathlib.Algebra.Module.Projective import Mathlib.Topology.Algebra.Module.Basic import Mathlib.Topology.Maps.OpenQuotient From 6e38c6649191d8bf77deb739de42ae8df4581c0d Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Sat, 19 Oct 2024 00:45:04 +0000 Subject: [PATCH 407/425] feat: algebraic properties of `LinearMap.compMultilinear` (#17932) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This also demotes `LinearMap.compAlternatingMap` to a plain function, for consistency. To make up for this loss, it introduces `LinearMap.compAlternatingMapₗ` as the stronger linear version. --- Mathlib/LinearAlgebra/Alternating/Basic.lean | 56 ++++++++++++++++---- Mathlib/LinearAlgebra/Multilinear/Basic.lean | 47 ++++++++++++++-- 2 files changed, 88 insertions(+), 15 deletions(-) diff --git a/Mathlib/LinearAlgebra/Alternating/Basic.lean b/Mathlib/LinearAlgebra/Alternating/Basic.lean index 994b3b3d983dbc..f3a7aafc8973ae 100644 --- a/Mathlib/LinearAlgebra/Alternating/Basic.lean +++ b/Mathlib/LinearAlgebra/Alternating/Basic.lean @@ -407,19 +407,12 @@ end AlternatingMap namespace LinearMap -variable {N₂ : Type*} [AddCommMonoid N₂] [Module R N₂] +variable {S : Type*} {N₂ : Type*} [AddCommMonoid N₂] [Module R N₂] /-- Composing an alternating map with a linear map on the left gives again an alternating map. -/ -def compAlternatingMap (g : N →ₗ[R] N₂) : (M [⋀^ι]→ₗ[R] N) →+ (M [⋀^ι]→ₗ[R] N₂) where - toFun f := - { g.compMultilinearMap (f : MultilinearMap R (fun _ : ι => M) N) with - map_eq_zero_of_eq' := fun v i j h hij => by simp [f.map_eq_zero_of_eq v h hij] } - map_zero' := by - ext - simp - map_add' a b := by - ext - simp +def compAlternatingMap (g : N →ₗ[R] N₂) (f : M [⋀^ι]→ₗ[R] N) : M [⋀^ι]→ₗ[R] N₂ where + __ := g.compMultilinearMap (f : MultilinearMap R (fun _ : ι => M) N) + map_eq_zero_of_eq' v i j h hij := by simp [f.map_eq_zero_of_eq v h hij] @[simp] theorem coe_compAlternatingMap (g : N →ₗ[R] N₂) (f : M [⋀^ι]→ₗ[R] N) : @@ -431,6 +424,47 @@ theorem compAlternatingMap_apply (g : N →ₗ[R] N₂) (f : M [⋀^ι]→ₗ[R] g.compAlternatingMap f m = g (f m) := rfl +@[simp] +theorem compAlternatingMap_zero (g : N →ₗ[R] N₂) : + g.compAlternatingMap (0 : M [⋀^ι]→ₗ[R] N) = 0 := + AlternatingMap.ext fun _ => map_zero g + +@[simp] +theorem zero_compAlternatingMap (f: M [⋀^ι]→ₗ[R] N) : + (0 : N →ₗ[R] N₂).compAlternatingMap f = 0 := rfl + +@[simp] +theorem compAlternatingMap_add (g : N →ₗ[R] N₂) (f₁ f₂ : M [⋀^ι]→ₗ[R] N) : + g.compAlternatingMap (f₁ + f₂) = g.compAlternatingMap f₁ + g.compAlternatingMap f₂ := + AlternatingMap.ext fun _ => map_add g _ _ + +@[simp] +theorem add_compAlternatingMap (g₁ g₂ : N →ₗ[R] N₂) (f: M [⋀^ι]→ₗ[R] N) : + (g₁ + g₂).compAlternatingMap f = g₁.compAlternatingMap f + g₂.compAlternatingMap f := rfl + +@[simp] +theorem compAlternatingMap_smul [Monoid S] [DistribMulAction S N] [DistribMulAction S N₂] + [SMulCommClass R S N] [SMulCommClass R S N₂] [CompatibleSMul N N₂ S R] + (g : N →ₗ[R] N₂) (s : S) (f : M [⋀^ι]→ₗ[R] N) : + g.compAlternatingMap (s • f) = s • g.compAlternatingMap f := + AlternatingMap.ext fun _ => g.map_smul_of_tower _ _ + +@[simp] +theorem smul_compAlternatingMap [Monoid S] [DistribMulAction S N₂] [SMulCommClass R S N₂] + (g : N →ₗ[R] N₂) (s : S) (f : M [⋀^ι]→ₗ[R] N) : + (s • g).compAlternatingMap f = s • g.compAlternatingMap f := rfl + +variable (S) in +/-- `LinearMap.compAlternatingMap` as an `S`-linear map. -/ +@[simps] +def compAlternatingMapₗ [Semiring S] [Module S N] [Module S N₂] + [SMulCommClass R S N] [SMulCommClass R S N₂] [LinearMap.CompatibleSMul N N₂ S R] + (g : N →ₗ[R] N₂) : + (M [⋀^ι]→ₗ[R] N) →ₗ[S] (M [⋀^ι]→ₗ[R] N₂) where + toFun := g.compAlternatingMap + map_add' := g.compAlternatingMap_add + map_smul' := g.compAlternatingMap_smul + theorem smulRight_eq_comp {R M₁ M₂ ι : Type*} [CommSemiring R] [AddCommMonoid M₁] [AddCommMonoid M₂] [Module R M₁] [Module R M₂] (f : M₁ [⋀^ι]→ₗ[R] R) (z : M₂) : f.smulRight z = (LinearMap.id.smulRight z).compAlternatingMap f := diff --git a/Mathlib/LinearAlgebra/Multilinear/Basic.lean b/Mathlib/LinearAlgebra/Multilinear/Basic.lean index 5fa2ebd1c7ff4f..8db7f46936b451 100644 --- a/Mathlib/LinearAlgebra/Multilinear/Basic.lean +++ b/Mathlib/LinearAlgebra/Multilinear/Basic.lean @@ -787,6 +787,36 @@ theorem compMultilinearMap_apply (g : M₂ →ₗ[R] M₃) (f : MultilinearMap R g.compMultilinearMap f m = g (f m) := rfl +@[simp] +theorem compMultilinearMap_zero (g : M₂ →ₗ[R] M₃) : + g.compMultilinearMap (0 : MultilinearMap R M₁ M₂) = 0 := + MultilinearMap.ext fun _ => map_zero g + +@[simp] +theorem zero_compMultilinearMap (f: MultilinearMap R M₁ M₂) : + (0 : M₂ →ₗ[R] M₃).compMultilinearMap f = 0 := rfl + +@[simp] +theorem compMultilinearMap_add (g : M₂ →ₗ[R] M₃) (f₁ f₂ : MultilinearMap R M₁ M₂) : + g.compMultilinearMap (f₁ + f₂) = g.compMultilinearMap f₁ + g.compMultilinearMap f₂ := + MultilinearMap.ext fun _ => map_add g _ _ + +@[simp] +theorem add_compMultilinearMap (g₁ g₂ : M₂ →ₗ[R] M₃) (f: MultilinearMap R M₁ M₂) : + (g₁ + g₂).compMultilinearMap f = g₁.compMultilinearMap f + g₂.compMultilinearMap f := rfl + +@[simp] +theorem compMultilinearMap_smul [Monoid S] [DistribMulAction S M₂] [DistribMulAction S M₃] + [SMulCommClass R S M₂] [SMulCommClass R S M₃] [CompatibleSMul M₂ M₃ S R] + (g : M₂ →ₗ[R] M₃) (s : S) (f : MultilinearMap R M₁ M₂) : + g.compMultilinearMap (s • f) = s • g.compMultilinearMap f := + MultilinearMap.ext fun _ => g.map_smul_of_tower _ _ + +@[simp] +theorem smul_compMultilinearMap [Monoid S] [DistribMulAction S M₃] [SMulCommClass R S M₃] + (g : M₂ →ₗ[R] M₃) (s : S) (f : MultilinearMap R M₁ M₂) : + (s • g).compMultilinearMap f = s • g.compMultilinearMap f := rfl + /-- The multilinear version of `LinearMap.subtype_comp_codRestrict` -/ @[simp] theorem subtype_compMultilinearMap_codRestrict (f : MultilinearMap R M₁ M₂) (p : Submodule R M₂) @@ -835,12 +865,23 @@ instance : Module S (MultilinearMap R M₁ M₂) := instance [NoZeroSMulDivisors S M₂] : NoZeroSMulDivisors S (MultilinearMap R M₁ M₂) := coe_injective.noZeroSMulDivisors _ rfl coe_smul +variable [AddCommMonoid M₃] [Module S M₃] [Module R M₃] [SMulCommClass R S M₃] + +variable (S) in +/-- `LinearMap.compMultilinearMap` as an `S`-linear map. -/ +@[simps] +def _root_.LinearMap.compMultilinearMapₗ [Semiring S] [Module S M₂] [Module S M₃] + [SMulCommClass R S M₂] [SMulCommClass R S M₃] [LinearMap.CompatibleSMul M₂ M₃ S R] + (g : M₂ →ₗ[R] M₃) : + MultilinearMap R M₁ M₂ →ₗ[S] MultilinearMap R M₁ M₃ where + toFun := g.compMultilinearMap + map_add' := g.compMultilinearMap_add + map_smul' := g.compMultilinearMap_smul + variable (R S M₁ M₂ M₃) section OfSubsingleton -variable [AddCommMonoid M₃] [Module S M₃] [Module R M₃] [SMulCommClass R S M₃] - /-- Linear equivalence between linear maps `M₂ →ₗ[R] M₃` and one-multilinear maps `MultilinearMap R (fun _ : ι ↦ M₂) M₃`. -/ @[simps (config := { simpRhs := true })] @@ -904,8 +945,6 @@ def constLinearEquivOfIsEmpty [IsEmpty ι] : M₂ ≃ₗ[S] MultilinearMap R M left_inv _ := rfl right_inv f := ext fun _ => MultilinearMap.congr_arg f <| Subsingleton.elim _ _ -variable [AddCommMonoid M₃] [Module R M₃] [Module S M₃] [SMulCommClass R S M₃] - /-- `MultilinearMap.domDomCongr` as a `LinearEquiv`. -/ @[simps apply symm_apply] def domDomCongrLinearEquiv {ι₁ ι₂} (σ : ι₁ ≃ ι₂) : From f6b96180cc040c8fdf7eb10746000229ef5eba25 Mon Sep 17 00:00:00 2001 From: mathlib4-update-dependencies-bot <150093616+mathlib-bors@users.noreply.github.com> Date: Sat, 19 Oct 2024 01:19:58 +0000 Subject: [PATCH 408/425] chore: update Mathlib dependencies 2024-10-19 (#17933) 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 f8536ac19fc8c6..6f116ba1524dd0 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "9e3d0d810e9021767c360756f066574f72e8fcce", + "rev": "1e0bf50b357069e1d658512a579a5faac6587c40", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", From bd5ba6b8fd201d0165ca6068e0a9437a56c4b58f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Sat, 19 Oct 2024 02:20:12 +0000 Subject: [PATCH 409/425] chore(SetTheory/Ordinal/Basic): deprecate duplicate `Nat.cast` lemmas (#17857) --- Mathlib/SetTheory/Ordinal/Arithmetic.lean | 37 +++++++++++------------ Mathlib/SetTheory/Ordinal/Notation.lean | 18 +++++------ 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/Mathlib/SetTheory/Ordinal/Arithmetic.lean b/Mathlib/SetTheory/Ordinal/Arithmetic.lean index 90d58666720d45..b43f781637c4ab 100644 --- a/Mathlib/SetTheory/Ordinal/Arithmetic.lean +++ b/Mathlib/SetTheory/Ordinal/Arithmetic.lean @@ -2099,6 +2099,10 @@ theorem Ordinal.not_bddAbove_compl_of_small (s : Set Ordinal.{u}) [hs : Small.{u namespace Ordinal +instance instCharZero : CharZero Ordinal := by + refine ⟨fun a b h ↦ ?_⟩ + rwa [← Cardinal.ord_nat, ← Cardinal.ord_nat, Cardinal.ord_inj, Nat.cast_inj] at h + @[simp] theorem one_add_natCast (m : ℕ) : 1 + (m : Ordinal) = succ m := by rw [← Nat.cast_one, ← Nat.cast_add, add_comm] @@ -2121,42 +2125,37 @@ theorem natCast_mul (m : ℕ) : ∀ n : ℕ, ((m * n : ℕ) : Ordinal) = m * n @[deprecated (since := "2024-04-17")] alias nat_cast_mul := natCast_mul -/-- Alias of `Nat.cast_le`, specialized to `Ordinal` --/ -theorem natCast_le {m n : ℕ} : (m : Ordinal) ≤ n ↔ m ≤ n := by - rw [← Cardinal.ord_nat, ← Cardinal.ord_nat, Cardinal.ord_le_ord, Cardinal.natCast_le] +@[deprecated Nat.cast_le (since := "2024-10-17")] +theorem natCast_le {m n : ℕ} : (m : Ordinal) ≤ n ↔ m ≤ n := Nat.cast_le @[deprecated (since := "2024-04-17")] alias nat_cast_le := natCast_le -/-- Alias of `Nat.cast_inj`, specialized to `Ordinal` --/ -theorem natCast_inj {m n : ℕ} : (m : Ordinal) = n ↔ m = n := by - simp only [le_antisymm_iff, natCast_le] +@[deprecated Nat.cast_inj (since := "2024-10-17")] +theorem natCast_inj {m n : ℕ} : (m : Ordinal) = n ↔ m = n := Nat.cast_inj @[deprecated (since := "2024-04-17")] alias nat_cast_inj := natCast_inj -instance charZero : CharZero Ordinal where - cast_injective _ _ := natCast_inj.mp - -/-- Alias of `Nat.cast_lt`, specialized to `Ordinal` --/ +@[deprecated Nat.cast_lt (since := "2024-10-17")] theorem natCast_lt {m n : ℕ} : (m : Ordinal) < n ↔ m < n := Nat.cast_lt @[deprecated (since := "2024-04-17")] alias nat_cast_lt := natCast_lt -/-- Alias of `Nat.cast_eq_zero`, specialized to `Ordinal` --/ +@[deprecated Nat.cast_eq_zero (since := "2024-10-17")] theorem natCast_eq_zero {n : ℕ} : (n : Ordinal) = 0 ↔ n = 0 := Nat.cast_eq_zero @[deprecated (since := "2024-04-17")] alias nat_cast_eq_zero := natCast_eq_zero -/-- Alias of `Nat.cast_eq_zero`, specialized to `Ordinal` --/ +@[deprecated Nat.cast_ne_zero (since := "2024-10-17")] theorem natCast_ne_zero {n : ℕ} : (n : Ordinal) ≠ 0 ↔ n ≠ 0 := Nat.cast_ne_zero @[deprecated (since := "2024-04-17")] alias nat_cast_ne_zero := natCast_ne_zero -/-- Alias of `Nat.cast_pos'`, specialized to `Ordinal` --/ +@[deprecated Nat.cast_pos' (since := "2024-10-17")] theorem natCast_pos {n : ℕ} : (0 : Ordinal) < n ↔ 0 < n := Nat.cast_pos' @[deprecated (since := "2024-04-17")] @@ -2165,10 +2164,10 @@ alias nat_cast_pos := natCast_pos @[simp, norm_cast] theorem natCast_sub (m n : ℕ) : ((m - n : ℕ) : Ordinal) = m - n := by rcases le_total m n with h | h - · rw [tsub_eq_zero_iff_le.2 h, Ordinal.sub_eq_zero_iff_le.2 (natCast_le.2 h)] + · rw [tsub_eq_zero_iff_le.2 h, Ordinal.sub_eq_zero_iff_le.2 (Nat.cast_le.2 h)] rfl · apply (add_left_cancel n).1 - rw [← Nat.cast_add, add_tsub_cancel_of_le h, Ordinal.add_sub_cancel_of_le (natCast_le.2 h)] + rw [← Nat.cast_add, add_tsub_cancel_of_le h, Ordinal.add_sub_cancel_of_le (Nat.cast_le.2 h)] @[deprecated (since := "2024-04-17")] alias nat_cast_sub := natCast_sub @@ -2177,12 +2176,12 @@ alias nat_cast_sub := natCast_sub theorem natCast_div (m n : ℕ) : ((m / n : ℕ) : Ordinal) = m / n := by rcases eq_or_ne n 0 with (rfl | hn) · simp - · have hn' := natCast_ne_zero.2 hn + · have hn' : (n : Ordinal) ≠ 0 := Nat.cast_ne_zero.2 hn apply le_antisymm - · rw [le_div hn', ← natCast_mul, natCast_le, mul_comm] + · rw [le_div hn', ← natCast_mul, Nat.cast_le, mul_comm] apply Nat.div_mul_le_self - · rw [div_le hn', ← add_one_eq_succ, ← Nat.cast_succ, ← natCast_mul, natCast_lt, mul_comm, ← - Nat.div_lt_iff_lt_mul (Nat.pos_of_ne_zero hn)] + · rw [div_le hn', ← add_one_eq_succ, ← Nat.cast_succ, ← natCast_mul, Nat.cast_lt, mul_comm, + ← Nat.div_lt_iff_lt_mul (Nat.pos_of_ne_zero hn)] apply Nat.lt_succ_self @[deprecated (since := "2024-04-17")] diff --git a/Mathlib/SetTheory/Ordinal/Notation.lean b/Mathlib/SetTheory/Ordinal/Notation.lean index 050c6b4f8f6534..bab9ce4002c725 100644 --- a/Mathlib/SetTheory/Ordinal/Notation.lean +++ b/Mathlib/SetTheory/Ordinal/Notation.lean @@ -139,7 +139,7 @@ theorem repr_one : repr (ofNat 1) = (1 : ℕ) := repr_ofNat 1 theorem omega0_le_oadd (e n a) : ω ^ repr e ≤ repr (oadd e n a) := by refine le_trans ?_ (le_add_right _ _) - simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos (repr e) omega0_pos).2 (natCast_le.2 n.2) + simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos (repr e) omega0_pos).2 (Nat.cast_le.2 n.2) @[deprecated (since := "2024-09-30")] alias omega_le_oadd := omega0_le_oadd @@ -275,7 +275,7 @@ theorem oadd_lt_oadd_2 {e o₁ o₂ : ONote} {n₁ n₂ : ℕ+} (h₁ : NF (oadd oadd e n₁ o₁ < oadd e n₂ o₂ := by simp only [lt_def, repr] refine lt_of_lt_of_le ((add_lt_add_iff_left _).2 h₁.snd'.repr_lt) (le_trans ?_ (le_add_right _ _)) - rwa [← mul_succ,Ordinal.mul_le_mul_iff_left (opow_pos _ omega0_pos), succ_le_iff, natCast_lt] + rwa [← mul_succ,Ordinal.mul_le_mul_iff_left (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 rw [lt_def]; unfold repr @@ -451,7 +451,7 @@ theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = rep cases he' : e' <;> simp only [he', zero_def, opow_zero, repr, gt_iff_lt] at this ⊢ <;> exact lt_of_le_of_lt (le_add_right _ _) this · simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos (repr e') omega0_pos).2 - (natCast_le.2 n'.pos) + (Nat.cast_le.2 n'.pos) · rw [ee, ← add_assoc, ← mul_add] theorem sub_nfBelow : ∀ {o₁ o₂ b}, NFBelow o₁ b → NF o₂ → NFBelow (o₁ - o₂) b @@ -507,7 +507,7 @@ theorem repr_sub : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ - o₂) = rep refine (Ordinal.sub_eq_of_add_eq <| add_absorp h₂.snd'.repr_lt <| le_trans ?_ (le_add_right _ _)).symm - simpa using mul_le_mul_left' (natCast_le.2 <| Nat.succ_pos _) _ + exact Ordinal.le_mul_left _ (Nat.cast_lt.2 <| Nat.succ_pos _) · exact (Ordinal.sub_eq_of_add_eq <| add_absorp (h₂.below_of_lt ee).repr_lt <| omega0_le_oadd _ _ _).symm @@ -564,7 +564,7 @@ theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = rep simp [(· * ·)] have ao : repr a₁ + ω ^ repr e₁ * (n₁ : ℕ) = ω ^ repr e₁ * (n₁ : ℕ) := by apply add_absorp h₁.snd'.repr_lt - simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos _ omega0_pos).2 (natCast_le.2 n₁.2) + simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos _ omega0_pos).2 (Nat.cast_le.2 n₁.2) by_cases e0 : e₂ = 0 · cases' Nat.exists_eq_succ_of_ne_zero n₂.ne_zero with x xe simp only [e0, repr, PNat.mul_coe, natCast_mul, opow_zero, one_mul] @@ -578,7 +578,7 @@ theorem repr_mul : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ * o₂) = rep congr 2 have := mt repr_inj.1 e0 rw [add_mul_limit ao (isLimit_opow_left isLimit_omega0 this), mul_assoc, - mul_omega0_dvd (natCast_pos.2 n₁.pos) (nat_lt_omega0 _)] + mul_omega0_dvd (Nat.cast_pos'.2 n₁.pos) (nat_lt_omega0 _)] simpa using opow_dvd_opow ω (one_le_iff_ne_zero.2 this) /-- Calculate division and remainder of `o` mod `ω`: @@ -857,7 +857,7 @@ theorem repr_opow_aux₂ {a0 a'} [N0 : NF a0] [Na' : NF a'] (m : ℕ) (d : ω · exact lt_of_lt_of_le Rl (opow_le_opow_right omega0_pos <| - mul_le_mul_left' (succ_le_succ_iff.2 (natCast_le.2 (le_of_lt k.lt_succ_self))) _) + mul_le_mul_left' (succ_le_succ_iff.2 (Nat.cast_le.2 (le_of_lt k.lt_succ_self))) _) calc (ω0 ^ (k.succ : Ordinal)) * α' + R' _ = (ω0 ^ succ (k : Ordinal)) * α' + ((ω0 ^ (k : Ordinal)) * α' * m + R) := by @@ -869,12 +869,12 @@ theorem repr_opow_aux₂ {a0 a'} [N0 : NF a0] [Na' : NF a'] (m : ℕ) (d : ω dvd_add (dvd_mul_of_dvd_left (by simpa using opow_dvd_opow ω (one_le_iff_ne_zero.2 e0)) _) d rw [mul_add (ω0 ^ (k : Ordinal)), add_assoc, ← mul_assoc, ← opow_succ, add_mul_limit _ (isLimit_iff_omega0_dvd.2 ⟨ne_of_gt α0, αd⟩), mul_assoc, - @mul_omega0_dvd n (natCast_pos.2 n.pos) (nat_lt_omega0 _) _ αd] + @mul_omega0_dvd n (Nat.cast_pos'.2 n.pos) (nat_lt_omega0 _) _ αd] apply @add_absorp _ (repr a0 * succ ↑k) · refine principal_add_omega0_opow _ ?_ Rl rw [opow_mul, opow_succ, Ordinal.mul_lt_mul_iff_left ω00] exact No.snd'.repr_lt - · have := mul_le_mul_left' (one_le_iff_pos.2 <| natCast_pos.2 n.pos) (ω0 ^ succ (k : Ordinal)) + · have := mul_le_mul_left' (one_le_iff_pos.2 <| Nat.cast_pos'.2 n.pos) (ω0 ^ succ (k : Ordinal)) rw [opow_mul] simpa [-opow_succ] · cases m From 81e65433ee271e679931bc2674586fce8fd5db8e Mon Sep 17 00:00:00 2001 From: FR Date: Sat, 19 Oct 2024 05:19:36 +0000 Subject: [PATCH 410/425] chore(Data/Nat/{Bits, Bitwise}): use `Bool.toNat` (#17925) --- Mathlib/Data/Nat/Bits.lean | 6 +++--- Mathlib/Data/Nat/Bitwise.lean | 12 ++++-------- Mathlib/Data/Nat/Size.lean | 4 ++-- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/Mathlib/Data/Nat/Bits.lean b/Mathlib/Data/Nat/Bits.lean index 371661d05995b7..71f01660fc34f2 100644 --- a/Mathlib/Data/Nat/Bits.lean +++ b/Mathlib/Data/Nat/Bits.lean @@ -73,7 +73,7 @@ lemma bodd_mul (m n : ℕ) : bodd (m * n) = (bodd m && bodd n) := by simp only [mul_succ, bodd_add, IH, bodd_succ] cases bodd m <;> cases bodd n <;> rfl -lemma mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by +lemma mod_two_of_bodd (n : ℕ) : n % 2 = (bodd n).toNat := by have := congr_arg bodd (mod_add_div n 2) simp? [not] at this says simp only [bodd_add, bodd_mul, bodd_succ, not, bodd_zero, Bool.false_and, Bool.bne_false] @@ -100,7 +100,7 @@ lemma div2_succ (n : ℕ) : div2 (n + 1) = cond (bodd n) (succ (div2 n)) (div2 n attribute [local simp] Nat.add_comm Nat.add_assoc Nat.add_left_comm Nat.mul_comm Nat.mul_assoc -lemma bodd_add_div2 : ∀ n, cond (bodd n) 1 0 + 2 * div2 n = n +lemma bodd_add_div2 : ∀ n, (bodd n).toNat + 2 * div2 n = n | 0 => rfl | succ n => by simp only [bodd_succ, Bool.cond_not, div2_succ, Nat.mul_comm] @@ -117,7 +117,7 @@ lemma div2_val (n) : div2 n = n / 2 := by /-- `bit b` appends the digit `b` to the binary representation of its natural number input. -/ def bit (b : Bool) : ℕ → ℕ := cond b (2 * · + 1) (2 * ·) -lemma bit_val (b n) : bit b n = 2 * n + cond b 1 0 := by +lemma bit_val (b n) : bit b n = 2 * n + b.toNat := by cases b <;> rfl lemma bit_decomp (n : Nat) : bit (bodd n) (div2 n) = n := diff --git a/Mathlib/Data/Nat/Bitwise.lean b/Mathlib/Data/Nat/Bitwise.lean index 2a45dc564a4b8d..cce15c0d55eee4 100644 --- a/Mathlib/Data/Nat/Bitwise.lean +++ b/Mathlib/Data/Nat/Bitwise.lean @@ -89,22 +89,18 @@ lemma bitwise_bit {f : Bool → Bool → Bool} (h : f false false = false := by <;> simp_all (config := {decide := true}) [two_mul] lemma bit_mod_two (a : Bool) (x : ℕ) : - bit a x % 2 = if a then 1 else 0 := by - #adaptation_note /-- nightly-2024-03-16: simp was - -- simp (config := { unfoldPartialApp := true }) only [bit, bit1, bit0, ← mul_two, - -- Bool.cond_eq_ite] -/ - simp only [bit, ite_apply, ← mul_two, Bool.cond_eq_ite] - split_ifs <;> simp [Nat.add_mod] + bit a x % 2 = a.toNat := by + cases a <;> simp [bit_val, mul_add_mod] @[simp] lemma bit_mod_two_eq_zero_iff (a x) : bit a x % 2 = 0 ↔ !a := by - rw [bit_mod_two]; split_ifs <;> simp_all + simp [bit_mod_two] @[simp] lemma bit_mod_two_eq_one_iff (a x) : bit a x % 2 = 1 ↔ a := by - rw [bit_mod_two]; split_ifs <;> simp_all + simp [bit_mod_two] @[simp] theorem lor_bit : ∀ a m b n, bit a m ||| bit b n = bit (a || b) (m ||| n) := diff --git a/Mathlib/Data/Nat/Size.lean b/Mathlib/Data/Nat/Size.lean index 1fdafff0b8fd02..fec3892450d06e 100644 --- a/Mathlib/Data/Nat/Size.lean +++ b/Mathlib/Data/Nat/Size.lean @@ -19,8 +19,8 @@ theorem shiftLeft_eq_mul_pow (m) : ∀ n, m <<< n = m * 2 ^ n := shiftLeft_eq _ theorem shiftLeft'_tt_eq_mul_pow (m) : ∀ n, shiftLeft' true m n + 1 = (m + 1) * 2 ^ n | 0 => by simp [shiftLeft', pow_zero, Nat.one_mul] | k + 1 => by - rw [shiftLeft', bit_val, cond_true, add_assoc, ← Nat.mul_add_one, shiftLeft'_tt_eq_mul_pow m k, - mul_left_comm, mul_comm 2, pow_succ] + rw [shiftLeft', bit_val, Bool.toNat_true, add_assoc, ← Nat.mul_add_one, + shiftLeft'_tt_eq_mul_pow m k, mul_left_comm, mul_comm 2, pow_succ] end From 74600feef71163f17723cd491710cbe1cec142d7 Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Sat, 19 Oct 2024 06:27:29 +0000 Subject: [PATCH 411/425] refactor(Order/Filter): don't use `generate` for `CompleteLattice` (#17799) --- Mathlib/Analysis/Complex/Basic.lean | 4 +- .../RotationNumber/TranslationNumber.lean | 2 +- Mathlib/MeasureTheory/Group/Measure.lean | 2 +- Mathlib/Order/Filter/Basic.lean | 44 ++++++-------- Mathlib/Order/Filter/Defs.lean | 59 +++++++++++-------- 5 files changed, 56 insertions(+), 55 deletions(-) diff --git a/Mathlib/Analysis/Complex/Basic.lean b/Mathlib/Analysis/Complex/Basic.lean index e4257988bc45bf..55726f263e5bf9 100644 --- a/Mathlib/Analysis/Complex/Basic.lean +++ b/Mathlib/Analysis/Complex/Basic.lean @@ -598,10 +598,10 @@ theorem ofReal_tsum (f : α → ℝ) : (↑(∑' a, f a) : ℂ) = ∑' a, ↑(f RCLike.ofReal_tsum _ _ theorem hasSum_re {f : α → ℂ} {x : ℂ} (h : HasSum f x) : HasSum (fun x => (f x).re) x.re := - RCLike.hasSum_re _ h + RCLike.hasSum_re ℂ h theorem hasSum_im {f : α → ℂ} {x : ℂ} (h : HasSum f x) : HasSum (fun x => (f x).im) x.im := - RCLike.hasSum_im _ h + RCLike.hasSum_im ℂ h theorem re_tsum {f : α → ℂ} (h : Summable f) : (∑' a, f a).re = ∑' a, (f a).re := RCLike.re_tsum _ h diff --git a/Mathlib/Dynamics/Circle/RotationNumber/TranslationNumber.lean b/Mathlib/Dynamics/Circle/RotationNumber/TranslationNumber.lean index 745facc0985ce4..65ee8350a44519 100644 --- a/Mathlib/Dynamics/Circle/RotationNumber/TranslationNumber.lean +++ b/Mathlib/Dynamics/Circle/RotationNumber/TranslationNumber.lean @@ -607,7 +607,7 @@ theorem tendsto_translationNumber_of_dist_bounded_aux (x : ℕ → ℝ) (C : ℝ theorem translationNumber_eq_of_dist_bounded {f g : CircleDeg1Lift} (C : ℝ) (H : ∀ n : ℕ, dist ((f ^ n) 0) ((g ^ n) 0) ≤ C) : τ f = τ g := Eq.symm <| g.translationNumber_eq_of_tendsto_aux <| - f.tendsto_translationNumber_of_dist_bounded_aux _ C H + f.tendsto_translationNumber_of_dist_bounded_aux (fun n ↦ (g ^ n) 0) C H @[simp] theorem translationNumber_one : τ 1 = 0 := diff --git a/Mathlib/MeasureTheory/Group/Measure.lean b/Mathlib/MeasureTheory/Group/Measure.lean index 3e36cb114970b5..e058bb5e8e9af6 100644 --- a/Mathlib/MeasureTheory/Group/Measure.lean +++ b/Mathlib/MeasureTheory/Group/Measure.lean @@ -775,7 +775,7 @@ nonrec theorem _root_.MulEquiv.isHaarMeasure_map [BorelSpace G] [TopologicalGrou [TopologicalGroup H] (e : G ≃* H) (he : Continuous e) (hesymm : Continuous e.symm) : IsHaarMeasure (Measure.map e μ) := let f : G ≃ₜ H := .mk e - isHaarMeasure_map μ e he e.surjective f.closedEmbedding.tendsto_cocompact + isHaarMeasure_map μ (e : G →* H) he e.surjective f.closedEmbedding.tendsto_cocompact /-- A convenience wrapper for MeasureTheory.Measure.isAddHaarMeasure_map`. -/ instance _root_.ContinuousLinearEquiv.isAddHaarMeasure_map diff --git a/Mathlib/Order/Filter/Basic.lean b/Mathlib/Order/Filter/Basic.lean index 84c4397e07ac66..8b546db30b1505 100644 --- a/Mathlib/Order/Filter/Basic.lean +++ b/Mathlib/Order/Filter/Basic.lean @@ -83,6 +83,9 @@ instance inhabitedMem : Inhabited { s : Set α // s ∈ f } := theorem filter_eq_iff : f = g ↔ f.sets = g.sets := ⟨congr_arg _, filter_eq⟩ +@[simp] theorem sets_subset_sets : f.sets ⊆ g.sets ↔ g ≤ f := .rfl +@[simp] theorem sets_ssubset_sets : f.sets ⊂ g.sets ↔ g < f := .rfl + /-- An extensionality lemma that is useful for filters with good lemmas about `sᶜ ∈ f` (e.g., `Filter.comap`, `Filter.coprod`, `Filter.Coprod`, `Filter.cofinite`). -/ protected theorem coext (h : ∀ s, sᶜ ∈ f ↔ sᶜ ∈ g) : f = g := @@ -253,21 +256,20 @@ theorem mem_inf_iff_superset {f g : Filter α} {s : Set α} : section CompleteLattice -/- We lift the complete lattice along the Galois connection `generate` / `sets`. Unfortunately, - we want to have different definitional equalities for some lattice operations. So we define them - upfront and change the lattice operations for the complete lattice instance. -/ -instance instCompleteLatticeFilter : CompleteLattice (Filter α) := - { @OrderDual.instCompleteLattice _ (giGenerate α).liftCompleteLattice with - le := (· ≤ ·) - top := ⊤ - le_top := fun _ _s hs => (mem_top.1 hs).symm ▸ univ_mem - inf := (· ⊓ ·) - inf_le_left := fun _ _ _ => mem_inf_of_left - inf_le_right := fun _ _ _ => mem_inf_of_right - le_inf := fun _ _ _ h₁ h₂ _s ⟨_a, ha, _b, hb, hs⟩ => hs.symm ▸ inter_mem (h₁ ha) (h₂ hb) - sSup := join ∘ 𝓟 - le_sSup := fun _ _f hf _s hs => hs hf - sSup_le := fun _ _f hf _s hs _g hg => hf _ hg hs } +/- Complete lattice structure on `Filter α`. -/ +instance instCompleteLatticeFilter : CompleteLattice (Filter α) where + le_sup_left _ _ _ h := h.1 + le_sup_right _ _ _ h := h.2 + sup_le _ _ _ h₁ h₂ _ h := ⟨h₁ h, h₂ h⟩ + inf_le_left _ _ _ := mem_inf_of_left + inf_le_right _ _ _ := mem_inf_of_right + le_inf := fun _ _ _ h₁ h₂ _s ⟨_a, ha, _b, hb, hs⟩ => hs.symm ▸ inter_mem (h₁ ha) (h₂ hb) + le_sSup _ _ h₁ _ h₂ := h₂ h₁ + sSup_le _ _ h₁ _ h₂ _ h₃ := h₁ _ h₃ h₂ + sInf_le _ _ h₁ _ h₂ := by rw [← Filter.sSup_lowerBounds]; exact fun _ h₃ ↦ h₃ h₁ h₂ + le_sInf _ _ h₁ _ h₂ := by rw [← Filter.sSup_lowerBounds] at h₂; exact h₂ h₁ + le_top _ _ := univ_mem' + bot_le _ _ _ := trivial instance : Inhabited (Filter α) := ⟨⊥⟩ @@ -324,10 +326,6 @@ theorem mem_sup {f g : Filter α} {s : Set α} : s ∈ f ⊔ g ↔ s ∈ f ∧ s theorem union_mem_sup {f g : Filter α} {s t : Set α} (hs : s ∈ f) (ht : t ∈ g) : s ∪ t ∈ f ⊔ g := ⟨mem_of_superset hs subset_union_left, mem_of_superset ht subset_union_right⟩ -@[simp] -theorem mem_sSup {x : Set α} {s : Set (Filter α)} : x ∈ sSup s ↔ ∀ f ∈ s, x ∈ (f : Filter α) := - Iff.rfl - @[simp] theorem mem_iSup {x : Set α} {f : ι → Filter α} : x ∈ iSup f ↔ ∀ i, x ∈ f i := by simp only [← Filter.mem_sets, iSup_sets_eq, mem_iInter] @@ -337,7 +335,7 @@ theorem iSup_neBot {f : ι → Filter α} : (⨆ i, f i).NeBot ↔ ∃ i, (f i). simp [neBot_iff] theorem iInf_eq_generate (s : ι → Filter α) : iInf s = generate (⋃ i, (s i).sets) := - show generate _ = generate _ from congr_arg _ <| congr_arg sSup <| (range_comp _ _).symm + eq_of_forall_le_iff fun _ ↦ by simp [le_generate_iff] theorem mem_iInf_of_mem {f : ι → Filter α} (i : ι) {s} (hs : s ∈ f i) : s ∈ ⨅ i, f i := iInf_le f i hs @@ -598,7 +596,7 @@ abbrev coframeMinimalAxioms : Coframe.MinimalAxioms (Filter α) := iInf_sup_le_sup_sInf := fun f s t ⟨h₁, h₂⟩ => by classical rw [iInf_subtype'] - rw [sInf_eq_iInf', iInf_sets_eq_finite, mem_iUnion] at h₂ + rw [sInf_eq_iInf', ← Filter.mem_sets, iInf_sets_eq_finite, mem_iUnion] at h₂ obtain ⟨u, hu⟩ := h₂ rw [← Finset.inf_eq_iInf] at hu suffices ⨅ i : s, f ⊔ ↑i ≤ f ⊔ u.inf fun i => ↑i from this ⟨h₁, hu⟩ @@ -1572,10 +1570,6 @@ instance : LawfulFunctor (Filter : Type u → Type u) where theorem pure_sets (a : α) : (pure a : Filter α).sets = { s | a ∈ s } := rfl -@[simp] -theorem mem_pure {a : α} {s : Set α} : s ∈ (pure a : Filter α) ↔ a ∈ s := - Iff.rfl - @[simp] theorem eventually_pure {a : α} {p : α → Prop} : (∀ᶠ x in pure a, p x) ↔ p a := Iff.rfl diff --git a/Mathlib/Order/Filter/Defs.lean b/Mathlib/Order/Filter/Defs.lean index cd23371bb3f2fd..06e6369f2f3014 100644 --- a/Mathlib/Order/Filter/Defs.lean +++ b/Mathlib/Order/Filter/Defs.lean @@ -5,6 +5,7 @@ Authors: Johannes Hölzl, Jeremy Avigad -/ import Mathlib.Data.Set.Basic import Mathlib.Order.SetNotation +import Mathlib.Order.Bounds.Defs /-! # Definitions about filters @@ -141,6 +142,15 @@ scoped notation "𝓟" => Filter.principal @[simp] theorem mem_principal : s ∈ 𝓟 t ↔ t ⊆ s := Iff.rfl +/-- `pure x` is the set of sets that contain `x`. It is equal to `𝓟 {x}` but +with this definition we have `s ∈ pure a` defeq `a ∈ s`. -/ +instance : Pure Filter where + pure x := .copy (𝓟 {x}) {s | x ∈ s} fun _ ↦ by simp + +@[simp] +theorem mem_pure {a : α} {s : Set α} : s ∈ (pure a : Filter α) ↔ a ∈ s := + Iff.rfl + /-- The *kernel* of a filter is the intersection of all its sets. -/ def ker (f : Filter α) : Set α := ⋂₀ f.sets @@ -164,11 +174,25 @@ instance : PartialOrder (Filter α) where theorem le_def : f ≤ g ↔ ∀ x ∈ g, x ∈ f := Iff.rfl -instance : Top (Filter α) := - ⟨{ sets := { s | ∀ x, x ∈ s } - univ_sets := fun x => mem_univ x - sets_of_superset := fun hx hxy a => hxy (hx a) - inter_sets := fun hx hy _ => mem_inter (hx _) (hy _) }⟩ +instance instSupSet : SupSet (Filter α) where + sSup S := join (𝓟 S) + +@[simp] theorem mem_sSup {S : Set (Filter α)} : s ∈ sSup S ↔ ∀ f ∈ S, s ∈ f := .rfl + +/-- Infimum of a set of filters. +This definition is marked as irreducible +so that Lean doesn't try to unfold it when unifying expressions. -/ +@[irreducible] +protected def sInf (s : Set (Filter α)) : Filter α := sSup (lowerBounds s) + +instance instInfSet : InfSet (Filter α) where + sInf := Filter.sInf + +protected theorem sSup_lowerBounds (s : Set (Filter α)) : sSup (lowerBounds s) = sInf s := by + simp [sInf, Filter.sInf] + +instance : Top (Filter α) where + top := .copy (sSup (Set.range pure)) {s | ∀ x, x ∈ s} <| by simp theorem mem_top_iff_forall {s : Set α} : s ∈ (⊤ : Filter α) ↔ ∀ x, x ∈ s := Iff.rfl @@ -178,11 +202,7 @@ theorem mem_top {s : Set α} : s ∈ (⊤ : Filter α) ↔ s = univ := by rw [mem_top_iff_forall, eq_univ_iff_forall] instance : Bot (Filter α) where - bot := - { sets := univ - univ_sets := trivial - sets_of_superset := fun _ _ ↦ trivial - inter_sets := fun _ _ ↦ trivial } + bot := .copy (sSup ∅) univ <| by simp @[simp] theorem mem_bot {s : Set α} : s ∈ (⊥ : Filter α) := @@ -190,7 +210,7 @@ theorem mem_bot {s : Set α} : s ∈ (⊥ : Filter α) := /-- The infimum of filters is the filter generated by intersections of elements of the two filters. -/ -instance : Inf (Filter α) := +instance instInf : Inf (Filter α) := ⟨fun f g : Filter α => { sets := { s | ∃ a ∈ f, ∃ b ∈ g, s = a ∩ b } univ_sets := ⟨_, univ_mem, _, univ_mem, by simp⟩ @@ -205,12 +225,8 @@ instance : Inf (Filter α) := ac_rfl }⟩ /-- The supremum of two filters is the filter that contains sets that belong to both filters. -/ -instance : Sup (Filter α) where - sup f g := - { sets := {s | s ∈ f ∧ s ∈ g} - univ_sets := ⟨univ_mem, univ_mem⟩ - sets_of_superset := fun h₁ h₂ ↦ ⟨mem_of_superset h₁.1 h₂, mem_of_superset h₁.2 h₂⟩ - inter_sets := fun h₁ h₂ ↦ ⟨inter_mem h₁.1 h₂.1, inter_mem h₁.2 h₂.2⟩ } +instance instSup : Sup (Filter α) where + sup f g := .copy (sSup {f, g}) {s | s ∈ f ∧ s ∈ g} <| by simp /-- A filter is `NeBot` if it is not equal to `⊥`, or equivalently the empty set does not belong to the filter. Bourbaki include this assumption in the definition of a filter but we prefer to have a @@ -319,15 +335,6 @@ in adding quantifiers to the middle of `Tendsto`s. See def curry (f : Filter α) (g : Filter β) : Filter (α × β) := bind f fun a ↦ map (a, ·) g -/-- `pure x` is the set of sets that contain `x`. It is equal to `𝓟 {x}` but -with this definition we have `s ∈ pure a` defeq `a ∈ s`. -/ -instance : Pure Filter := - ⟨fun x => - { sets := { s | x ∈ s } - inter_sets := And.intro - sets_of_superset := fun hs hst => hst hs - univ_sets := trivial }⟩ - instance : Bind Filter := ⟨@Filter.bind⟩ From a0521c9b7e636372cca49d817075d7da0fd4a681 Mon Sep 17 00:00:00 2001 From: FR Date: Sat, 19 Oct 2024 06:53:15 +0000 Subject: [PATCH 412/425] chore: deprecate `Setoid.Rel` (#16260) --- .../Limits/Shapes/SingleObj.lean | 2 +- Mathlib/Data/Quot.lean | 2 + Mathlib/Data/Setoid/Basic.lean | 94 ++++++++++--------- Mathlib/Data/Setoid/Partition.lean | 38 ++++---- Mathlib/GroupTheory/Congruence/Defs.lean | 8 +- Mathlib/GroupTheory/DoubleCoset.lean | 10 +- Mathlib/GroupTheory/GroupAction/Basic.lean | 17 ++-- Mathlib/GroupTheory/GroupAction/ConjAct.lean | 2 +- Mathlib/GroupTheory/GroupAction/Quotient.lean | 9 +- Mathlib/Order/Partition/Finpartition.lean | 4 +- .../RingTheory/AdicCompletion/Algebra.lean | 2 +- Mathlib/RingTheory/Congruence/Basic.lean | 4 +- .../RingTheory/Valuation/ValuationRing.lean | 14 +-- .../Topology/Algebra/ProperAction/Basic.lean | 2 +- Mathlib/Topology/DiscreteQuotient.lean | 16 ++-- Mathlib/Topology/MetricSpace/Contracting.lean | 4 +- Mathlib/Topology/Separation.lean | 2 +- 17 files changed, 118 insertions(+), 112 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/SingleObj.lean b/Mathlib/CategoryTheory/Limits/Shapes/SingleObj.lean index e501871d0f7575..a4e8274b8176e4 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/SingleObj.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/SingleObj.lean @@ -75,7 +75,7 @@ variable {G : Type v} [Group G] (J : SingleObj G ⥤ Type u) equivalent to the `MulAction.orbitRel` equivalence relation on `J.obj (SingleObj.star G)`. -/ lemma Types.Quot.Rel.iff_orbitRel (x y : J.obj (SingleObj.star G)) : Types.Quot.Rel J ⟨SingleObj.star G, x⟩ ⟨SingleObj.star G, y⟩ - ↔ Setoid.Rel (MulAction.orbitRel G (J.obj (SingleObj.star G))) x y := by + ↔ MulAction.orbitRel G (J.obj (SingleObj.star G)) x y := by have h (g : G) : y = g • x ↔ g • x = y := ⟨symm, symm⟩ conv => rhs; rw [Setoid.comm'] show (∃ g : G, y = g • x) ↔ (∃ g : G, g • x = y) diff --git a/Mathlib/Data/Quot.lean b/Mathlib/Data/Quot.lean index a11fa73582072b..2bec860ba95b91 100644 --- a/Mathlib/Data/Quot.lean +++ b/Mathlib/Data/Quot.lean @@ -26,6 +26,8 @@ run_cmd Lean.Elab.Command.liftTermElabM do Lean.Meta.registerCoercion ``Setoid.r (some { numArgs := 2, coercee := 1, type := .coeFun }) +/-- When writing a lemma about `someSetoid x y` (which uses this instance), +call it `someSetoid_apply` not `someSetoid_r`. -/ instance : CoeFun (Setoid α) (fun _ ↦ α → α → Prop) where coe := @Setoid.r _ diff --git a/Mathlib/Data/Setoid/Basic.lean b/Mathlib/Data/Setoid/Basic.lean index c34439b36e1e10..e4b60325f1b217 100644 --- a/Mathlib/Data/Setoid/Basic.lean +++ b/Mathlib/Data/Setoid/Basic.lean @@ -15,9 +15,6 @@ theorems for quotients of arbitrary types. ## Implementation notes -The function `Rel` and lemmas ending in ' make it easier to talk about different -equivalence relations on the same type. - The complete lattice instance for equivalence relations could have been defined by lifting the Galois insertion of equivalence relations on α into binary relations on α, and then using `CompleteLattice.copy` to define a complete lattice instance with more appropriate @@ -39,47 +36,57 @@ attribute [trans] Setoid.trans variable {α : Type*} {β : Type*} /-- A version of `Setoid.r` that takes the equivalence relation as an explicit argument. -/ +@[deprecated (since := "2024-08-29")] def Setoid.Rel (r : Setoid α) : α → α → Prop := @Setoid.r _ r +set_option linter.deprecated false in +@[deprecated (since := "2024-10-09")] instance Setoid.decidableRel (r : Setoid α) [h : DecidableRel r.r] : DecidableRel r.Rel := h +set_option linter.deprecated false in /-- A version of `Quotient.eq'` compatible with `Setoid.Rel`, to make rewriting possible. -/ +@[deprecated Quotient.eq' (since := "2024-10-09")] theorem Quotient.eq_rel {r : Setoid α} {x y} : (Quotient.mk' x : Quotient r) = Quotient.mk' y ↔ r.Rel x y := Quotient.eq namespace Setoid -@[ext] +attribute [ext] ext + +set_option linter.deprecated false in +@[deprecated Setoid.ext (since := "2024-10-09")] theorem ext' {r s : Setoid α} (H : ∀ a b, r.Rel a b ↔ s.Rel a b) : r = s := ext H -theorem ext_iff {r s : Setoid α} : r = s ↔ ∀ a b, r.Rel a b ↔ s.Rel a b := +set_option linter.deprecated false in +@[deprecated Setoid.ext_iff (since := "2024-10-09")] +theorem ext'_iff {r s : Setoid α} : r = s ↔ ∀ a b, r.Rel a b ↔ s.Rel a b := ⟨fun h _ _ => h ▸ Iff.rfl, ext'⟩ /-- Two equivalence relations are equal iff their underlying binary operations are equal. -/ -theorem eq_iff_rel_eq {r₁ r₂ : Setoid α} : r₁ = r₂ ↔ r₁.Rel = r₂.Rel := - ⟨fun h => h ▸ rfl, fun h => Setoid.ext' fun _ _ => h ▸ Iff.rfl⟩ +theorem eq_iff_rel_eq {r₁ r₂ : Setoid α} : r₁ = r₂ ↔ ⇑r₁ = ⇑r₂ := + ⟨fun h => h ▸ rfl, fun h => Setoid.ext fun _ _ => h ▸ Iff.rfl⟩ /-- Defining `≤` for equivalence relations. -/ instance : LE (Setoid α) := - ⟨fun r s => ∀ ⦃x y⦄, r.Rel x y → s.Rel x y⟩ + ⟨fun r s => ∀ ⦃x y⦄, r x y → s x y⟩ -theorem le_def {r s : Setoid α} : r ≤ s ↔ ∀ {x y}, r.Rel x y → s.Rel x y := +theorem le_def {r s : Setoid α} : r ≤ s ↔ ∀ {x y}, r x y → s x y := Iff.rfl @[refl] -theorem refl' (r : Setoid α) (x) : r.Rel x x := r.iseqv.refl x +theorem refl' (r : Setoid α) (x) : r x x := r.iseqv.refl x @[symm] -theorem symm' (r : Setoid α) : ∀ {x y}, r.Rel x y → r.Rel y x := r.iseqv.symm +theorem symm' (r : Setoid α) : ∀ {x y}, r x y → r y x := r.iseqv.symm @[trans] -theorem trans' (r : Setoid α) : ∀ {x y z}, r.Rel x y → r.Rel y z → r.Rel x z := r.iseqv.trans +theorem trans' (r : Setoid α) : ∀ {x y z}, r x y → r y z → r x z := r.iseqv.trans -theorem comm' (s : Setoid α) {x y} : s.Rel x y ↔ s.Rel y x := +theorem comm' (s : Setoid α) {x y} : s x y ↔ s y x := ⟨s.symm', s.symm'⟩ /-- The kernel of a function is an equivalence relation. -/ @@ -89,7 +96,7 @@ def ker (f : α → β) : Setoid α := /-- The kernel of the quotient map induced by an equivalence relation r equals r. -/ @[simp] theorem ker_mk_eq (r : Setoid α) : ker (@Quotient.mk'' _ r) = r := - ext' fun _ _ => Quotient.eq + ext fun _ _ => Quotient.eq theorem ker_apply_mk_out {f : α → β} (a : α) : f (⟦a⟧ : Quotient (Setoid.ker f)).out = f a := @Quotient.mk_out _ (Setoid.ker f) a @@ -98,7 +105,7 @@ theorem ker_apply_mk_out' {f : α → β} (a : α) : f (Quotient.mk _ a : Quotient <| Setoid.ker f).out' = f a := @Quotient.mk_out' _ (Setoid.ker f) a -theorem ker_def {f : α → β} {x y : α} : (ker f).Rel x y ↔ f x = f y := +theorem ker_def {f : α → β} {x y : α} : ker f x y ↔ f x = f y := Iff.rfl /-- Given types `α`, `β`, the product of two equivalence relations `r` on `α` and `s` on `β`: @@ -106,7 +113,7 @@ theorem ker_def {f : α → β} {x y : α} : (ker f).Rel x y ↔ f x = f y := by `r` and `x₂` is related to `y₂` by `s`. -/ protected def prod (r : Setoid α) (s : Setoid β) : Setoid (α × β) where - r x y := r.Rel x.1 y.1 ∧ s.Rel x.2 y.2 + r x y := r x.1 y.1 ∧ s x.2 y.2 iseqv := ⟨fun x => ⟨r.refl' x.1, s.refl' x.2⟩, fun h => ⟨r.symm' h.1, s.symm' h.2⟩, fun h₁ h₂ => ⟨r.trans' h₁.1 h₂.1, s.trans' h₁.2 h₂.2⟩⟩ @@ -157,28 +164,28 @@ noncomputable def piQuotientEquiv {ι : Sort*} {α : ι → Sort*} (r : ∀ i, S /-- The infimum of two equivalence relations. -/ instance : Inf (Setoid α) := ⟨fun r s => - ⟨fun x y => r.Rel x y ∧ s.Rel x y, + ⟨fun x y => r x y ∧ s x y, ⟨fun x => ⟨r.refl' x, s.refl' x⟩, fun h => ⟨r.symm' h.1, s.symm' h.2⟩, fun h1 h2 => ⟨r.trans' h1.1 h2.1, s.trans' h1.2 h2.2⟩⟩⟩⟩ /-- The infimum of 2 equivalence relations r and s is the same relation as the infimum of the underlying binary operations. -/ -theorem inf_def {r s : Setoid α} : (r ⊓ s).Rel = r.Rel ⊓ s.Rel := +theorem inf_def {r s : Setoid α} : ⇑(r ⊓ s) = ⇑r ⊓ ⇑s := rfl -theorem inf_iff_and {r s : Setoid α} {x y} : (r ⊓ s).Rel x y ↔ r.Rel x y ∧ s.Rel x y := +theorem inf_iff_and {r s : Setoid α} {x y} : (r ⊓ s) x y ↔ r x y ∧ s x y := Iff.rfl /-- The infimum of a set of equivalence relations. -/ instance : InfSet (Setoid α) := ⟨fun S => - { r := fun x y => ∀ r ∈ S, r.Rel x y + { r := fun x y => ∀ r ∈ S, r x y iseqv := ⟨fun x r _ => r.refl' x, fun h r hr => r.symm' <| h r hr, fun h1 h2 r hr => r.trans' (h1 r hr) <| h2 r hr⟩ }⟩ /-- The underlying binary operation of the infimum of a set of equivalence relations is the infimum of the set's image under the map to the underlying binary operation. -/ -theorem sInf_def {s : Set (Setoid α)} : (sInf s).Rel = sInf (Rel '' s) := by +theorem sInf_def {s : Set (Setoid α)} : ⇑(sInf s) = sInf ((⇑) '' s) := by ext simp only [sInf_image, iInf_apply, iInf_Prop_eq] rfl @@ -189,7 +196,7 @@ instance : PartialOrder (Setoid α) where le_refl _ _ _ := id le_trans _ _ _ hr hs _ _ h := hs <| hr h lt_iff_le_not_le _ _ := Iff.rfl - le_antisymm _ _ h1 h2 := Setoid.ext' fun _ _ => ⟨fun h => h1 h, fun h => h2 h⟩ + le_antisymm _ _ h1 h2 := Setoid.ext fun _ _ => ⟨fun h => h1 h, fun h => h2 h⟩ /-- The complete lattice of equivalence relations on a type, with bottom element `=` and top element the trivial equivalence relation. -/ @@ -206,20 +213,20 @@ instance completeLattice : CompleteLattice (Setoid α) := bot_le := fun r x _ h => h ▸ r.2.1 x } @[simp] -theorem top_def : (⊤ : Setoid α).Rel = ⊤ := +theorem top_def : ⇑(⊤ : Setoid α) = ⊤ := rfl @[simp] -theorem bot_def : (⊥ : Setoid α).Rel = (· = ·) := +theorem bot_def : ⇑(⊥ : Setoid α) = (· = ·) := rfl -theorem eq_top_iff {s : Setoid α} : s = (⊤ : Setoid α) ↔ ∀ x y : α, s.Rel x y := by +theorem eq_top_iff {s : Setoid α} : s = (⊤ : Setoid α) ↔ ∀ x y : α, s x y := by rw [_root_.eq_top_iff, Setoid.le_def, Setoid.top_def] simp only [Pi.top_apply, Prop.top_eq_true, forall_true_left] lemma sInf_equiv {S : Set (Setoid α)} {x y : α} : letI := sInf S - x ≈ y ↔ ∀ s ∈ S, s.Rel x y := Iff.rfl + x ≈ y ↔ ∀ s ∈ S, s x y := Iff.rfl lemma sInf_iff {S : Set (Setoid α)} {x y : α} : sInf S x y ↔ ∀ s ∈ S, s x y := Iff.rfl @@ -245,7 +252,7 @@ open Relation /-- The inductively defined equivalence closure of a binary relation r is the infimum of the set of all equivalence relations containing r. -/ theorem eqvGen_eq (r : α → α → Prop) : - EqvGen.setoid r = sInf { s : Setoid α | ∀ ⦃x y⦄, r x y → s.Rel x y } := + EqvGen.setoid r = sInf { s : Setoid α | ∀ ⦃x y⦄, r x y → s x y } := le_antisymm (fun _ _ H => EqvGen.rec (fun _ _ h _ hs => hs h) (refl' _) (fun _ _ _ => symm' _) @@ -255,20 +262,20 @@ theorem eqvGen_eq (r : α → α → Prop) : /-- The supremum of two equivalence relations r and s is the equivalence closure of the binary relation `x is related to y by r or s`. -/ theorem sup_eq_eqvGen (r s : Setoid α) : - r ⊔ s = EqvGen.setoid fun x y => r.Rel x y ∨ s.Rel x y := by + r ⊔ s = EqvGen.setoid fun x y => r x y ∨ s x y := by rw [eqvGen_eq] apply congr_arg sInf simp only [le_def, or_imp, ← forall_and] /-- The supremum of 2 equivalence relations r and s is the equivalence closure of the supremum of the underlying binary operations. -/ -theorem sup_def {r s : Setoid α} : r ⊔ s = EqvGen.setoid (r.Rel ⊔ s.Rel) := by +theorem sup_def {r s : Setoid α} : r ⊔ s = EqvGen.setoid (⇑r ⊔ ⇑s) := by rw [sup_eq_eqvGen]; rfl /-- The supremum of a set S of equivalence relations is the equivalence closure of the binary relation `there exists r ∈ S relating x and y`. -/ theorem sSup_eq_eqvGen (S : Set (Setoid α)) : - sSup S = EqvGen.setoid fun x y => ∃ r : Setoid α, r ∈ S ∧ r.Rel x y := by + sSup S = EqvGen.setoid fun x y => ∃ r : Setoid α, r ∈ S ∧ r x y := by rw [eqvGen_eq] apply congr_arg sInf simp only [upperBounds, le_def, and_imp, exists_imp] @@ -277,7 +284,7 @@ theorem sSup_eq_eqvGen (S : Set (Setoid α)) : /-- The supremum of a set of equivalence relations is the equivalence closure of the supremum of the set's image under the map to the underlying binary operation. -/ -theorem sSup_def {s : Set (Setoid α)} : sSup s = EqvGen.setoid (sSup (Rel '' s)) := by +theorem sSup_def {s : Set (Setoid α)} : sSup s = EqvGen.setoid (sSup ((⇑) '' s)) := by rw [sSup_eq_eqvGen, sSup_image] congr with (x y) simp only [iSup_apply, iSup_Prop_eq, exists_prop] @@ -288,13 +295,12 @@ theorem eqvGen_of_setoid (r : Setoid α) : EqvGen.setoid r.r = r := le_antisymm (by rw [eqvGen_eq]; exact sInf_le fun _ _ => id) EqvGen.rel /-- Equivalence closure is idempotent. -/ -@[simp] -theorem eqvGen_idem (r : α → α → Prop) : EqvGen.setoid (EqvGen.setoid r).Rel = EqvGen.setoid r := +theorem eqvGen_idem (r : α → α → Prop) : EqvGen.setoid (EqvGen.setoid r) = EqvGen.setoid r := eqvGen_of_setoid _ /-- The equivalence closure of a binary relation r is contained in any equivalence relation containing r. -/ -theorem eqvGen_le {r : α → α → Prop} {s : Setoid α} (h : ∀ x y, r x y → s.Rel x y) : +theorem eqvGen_le {r : α → α → Prop} {s : Setoid α} (h : ∀ x y, r x y → s x y) : EqvGen.setoid r ≤ s := by rw [eqvGen_eq]; exact sInf_le h /-- Equivalence closure of binary relations is monotone. -/ @@ -304,7 +310,7 @@ theorem eqvGen_mono {r s : α → α → Prop} (h : ∀ x y, r x y → s x y) : /-- There is a Galois insertion of equivalence relations on α into binary relations on α, with equivalence closure the lower adjoint. -/ -def gi : @GaloisInsertion (α → α → Prop) (Setoid α) _ _ EqvGen.setoid Rel where +def gi : @GaloisInsertion (α → α → Prop) (Setoid α) _ _ EqvGen.setoid (⇑) where choice r _ := EqvGen.setoid r gc _ s := ⟨fun H _ _ h => H <| EqvGen.rel _ _ h, fun H => eqvGen_of_setoid s ▸ eqvGen_mono H⟩ le_l_u x := (eqvGen_of_setoid x).symm ▸ le_refl x @@ -320,7 +326,7 @@ theorem injective_iff_ker_bot (f : α → β) : Injective f ↔ ker f = ⊥ := (@eq_bot_iff (Setoid α) _ _ (ker f)).symm /-- The elements related to x ∈ α by the kernel of f are those in the preimage of f(x) under f. -/ -theorem ker_iff_mem_preimage {f : α → β} {x y} : (ker f).Rel x y ↔ x ∈ f ⁻¹' {f y} := +theorem ker_iff_mem_preimage {f : α → β} {x y} : ker f x y ↔ x ∈ f ⁻¹' {f y} := Iff.rfl /-- Equivalence between functions `α → β` such that `r x y → f x = f y` and functions @@ -345,7 +351,7 @@ theorem ker_lift_injective (f : α → β) : Injective (@Quotient.lift _ _ (ker /-- Given a map f from α to β, the kernel of f is the unique equivalence relation on α whose induced map from the quotient of α to β is injective. -/ -theorem ker_eq_lift_of_injective {r : Setoid α} (f : α → β) (H : ∀ x y, r.Rel x y → f x = f y) +theorem ker_eq_lift_of_injective {r : Setoid α} (f : α → β) (H : ∀ x y, r x y → f x = f y) (h : Injective (Quotient.lift f H)) : ker f = r := le_antisymm (fun x y hk => @@ -387,13 +393,13 @@ variable {r f} 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`.' -/ def map (r : Setoid α) (f : α → β) : Setoid β := - Relation.EqvGen.setoid fun x y => ∃ a b, f a = x ∧ f b = y ∧ r.Rel a b + Relation.EqvGen.setoid fun x y => ∃ a b, f a = x ∧ f b = y ∧ r a b /-- 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. -/ def mapOfSurjective (r) (f : α → β) (h : ker f ≤ r) (hf : Surjective f) : Setoid β := - ⟨fun x y => ∃ a b, f a = x ∧ f b = y ∧ r.Rel a b, + ⟨fun x y => ∃ a b, f a = x ∧ f b = y ∧ r a b, ⟨fun x => let ⟨y, hy⟩ := hf x ⟨y, y, hy, hy, r.refl' y⟩, @@ -411,9 +417,9 @@ relation on `α` defined by '`x ≈ y` iff `f(x)` is related to `f(y)` by `r`'. See note [reducible non-instances]. -/ abbrev comap (f : α → β) (r : Setoid β) : Setoid α := - ⟨r.Rel on f, r.iseqv.comap _⟩ + ⟨r on f, r.iseqv.comap _⟩ -theorem comap_rel (f : α → β) (r : Setoid β) (x y : α) : (comap f r).Rel x y ↔ r.Rel (f x) (f y) := +theorem comap_rel (f : α → β) (r : Setoid β) (x y : α) : comap f r x y ↔ r (f x) (f y) := Iff.rfl /-- Given a map `f : N → M` and an equivalence relation `r` on `β`, the equivalence relation @@ -424,7 +430,8 @@ theorem comap_eq {f : α → β} {r : Setoid β} : comap f r = ker (@Quotient.mk /-- The second isomorphism theorem for sets. -/ noncomputable def comapQuotientEquiv (f : α → β) (r : Setoid β) : Quotient (comap f r) ≃ Set.range (@Quotient.mk'' _ r ∘ f) := - (Quotient.congrRight <| ext_iff.1 comap_eq).trans <| quotientKerEquivRange <| Quotient.mk'' ∘ f + (Quotient.congrRight <| Setoid.ext_iff.1 comap_eq).trans <| quotientKerEquivRange <| + Quotient.mk'' ∘ f variable (r f) @@ -454,7 +461,7 @@ def correspondence (r : Setoid α) : { s // r ≤ s } ≃o Setoid (Quotient r) w (fun h ↦ s.1.trans' (s.1.trans' (s.2 h₁) h) (s.1.symm' (s.2 h₂))), ⟨Quotient.ind s.1.2.1, @fun x y ↦ Quotient.inductionOn₂ x y fun _ _ ↦ s.1.2.2, @fun x y z ↦ Quotient.inductionOn₃ x y z fun _ _ _ ↦ s.1.2.3⟩⟩ - invFun s := ⟨comap Quotient.mk' s, fun x y h => by rw [comap_rel, eq_rel.2 h]⟩ + invFun s := ⟨comap Quotient.mk' s, fun x y h => by rw [comap_rel, Quotient.eq'.2 h]⟩ left_inv _ := rfl right_inv _ := ext fun x y ↦ Quotient.inductionOn₂ x y fun _ _ ↦ Iff.rfl map_rel_iff' := @@ -478,7 +485,6 @@ theorem Quotient.subsingleton_iff {s : Setoid α} : Subsingleton (Quotient s) refine (surjective_quotient_mk' _).forall.trans (forall_congr' fun a => ?_) refine (surjective_quotient_mk' _).forall.trans (forall_congr' fun b => ?_) simp_rw [Prop.top_eq_true, true_implies, Quotient.eq'] - rfl theorem Quot.subsingleton_iff (r : α → α → Prop) : Subsingleton (Quot r) ↔ Relation.EqvGen r = ⊤ := by diff --git a/Mathlib/Data/Setoid/Partition.lean b/Mathlib/Data/Setoid/Partition.lean index b44853cfa153b7..27e668bcb2eceb 100644 --- a/Mathlib/Data/Setoid/Partition.lean +++ b/Mathlib/Data/Setoid/Partition.lean @@ -53,9 +53,9 @@ def mkClasses (c : Set (Set α)) (H : ∀ a, ∃! b ∈ c, a ∈ b) : Setoid α /-- Makes the equivalence classes of an equivalence relation. -/ def classes (r : Setoid α) : Set (Set α) := - { s | ∃ y, s = { x | r.Rel x y } } + { s | ∃ y, s = { x | r x y } } -theorem mem_classes (r : Setoid α) (y) : { x | r.Rel x y } ∈ r.classes := +theorem mem_classes (r : Setoid α) (y) : { x | r x y } ∈ r.classes := ⟨y, rfl⟩ theorem classes_ker_subset_fiber_set {β : Type*} (f : α → β) : @@ -74,17 +74,17 @@ theorem card_classes_ker_le {α β : Type*} [Fintype β] (f : α → β) /-- Two equivalence relations are equal iff all their equivalence classes are equal. -/ theorem eq_iff_classes_eq {r₁ r₂ : Setoid α} : - r₁ = r₂ ↔ ∀ x, { y | r₁.Rel x y } = { y | r₂.Rel x y } := - ⟨fun h _x => h ▸ rfl, fun h => ext' fun x => Set.ext_iff.1 <| h x⟩ + r₁ = r₂ ↔ ∀ x, { y | r₁ x y } = { y | r₂ x y } := + ⟨fun h _x => h ▸ rfl, fun h => ext fun x => Set.ext_iff.1 <| h x⟩ -theorem rel_iff_exists_classes (r : Setoid α) {x y} : r.Rel x y ↔ ∃ c ∈ r.classes, x ∈ c ∧ y ∈ c := +theorem rel_iff_exists_classes (r : Setoid α) {x y} : r x y ↔ ∃ c ∈ r.classes, x ∈ c ∧ y ∈ c := ⟨fun h => ⟨_, r.mem_classes y, h, r.refl' y⟩, fun ⟨c, ⟨z, hz⟩, hx, hy⟩ => by subst c exact r.trans' hx (r.symm' hy)⟩ /-- Two equivalence relations are equal iff their equivalence classes are equal. -/ theorem classes_inj {r₁ r₂ : Setoid α} : r₁ = r₂ ↔ r₁.classes = r₂.classes := - ⟨fun h => h ▸ rfl, fun h => ext' fun a b => by simp only [rel_iff_exists_classes, exists_prop, h]⟩ + ⟨fun h => h ▸ rfl, fun h => ext fun a b => by simp only [rel_iff_exists_classes, exists_prop, h]⟩ /-- The empty set is not an equivalence class. -/ theorem empty_not_mem_classes {r : Setoid α} : ∅ ∉ r.classes := fun ⟨y, hy⟩ => @@ -92,7 +92,7 @@ theorem empty_not_mem_classes {r : Setoid α} : ∅ ∉ r.classes := fun ⟨y, h /-- Equivalence classes partition the type. -/ theorem classes_eqv_classes {r : Setoid α} (a) : ∃! b ∈ r.classes, a ∈ b := - ExistsUnique.intro { x | r.Rel x a } ⟨r.mem_classes a, r.refl' _⟩ <| by + ExistsUnique.intro { x | r x a } ⟨r.mem_classes a, r.refl' _⟩ <| by rintro y ⟨⟨_, rfl⟩, ha⟩ ext x exact ⟨fun hx => r.trans' hx (r.symm' ha), fun hx => r.trans' hx ha⟩ @@ -105,7 +105,7 @@ theorem eq_of_mem_classes {r : Setoid α} {x b} (hc : b ∈ r.classes) (hb : x /-- The elements of a set of sets partitioning α are the equivalence classes of the equivalence relation defined by the set of sets. -/ theorem eq_eqv_class_of_mem {c : Set (Set α)} (H : ∀ a, ∃! b ∈ c, a ∈ b) {s y} - (hs : s ∈ c) (hy : y ∈ s) : s = { x | (mkClasses c H).Rel x y } := by + (hs : s ∈ c) (hy : y ∈ s) : s = { x | mkClasses c H x y } := by ext x constructor · intro hx _s' hs' hx' @@ -117,11 +117,11 @@ theorem eq_eqv_class_of_mem {c : Set (Set α)} (H : ∀ a, ∃! b ∈ c, a ∈ b /-- The equivalence classes of the equivalence relation defined by a set of sets partitioning α are elements of the set of sets. -/ theorem eqv_class_mem {c : Set (Set α)} (H : ∀ a, ∃! b ∈ c, a ∈ b) {y} : - { x | (mkClasses c H).Rel x y } ∈ c := + { x | mkClasses c H x y } ∈ c := (H y).elim fun _ hc _ => eq_eqv_class_of_mem H hc.1 hc.2 ▸ hc.1 theorem eqv_class_mem' {c : Set (Set α)} (H : ∀ a, ∃! b ∈ c, a ∈ b) {x} : - { y : α | (mkClasses c H).Rel x y } ∈ c := by + { y : α | mkClasses c H x y } ∈ c := by convert @Setoid.eqv_class_mem _ _ H x using 3 rw [Setoid.comm'] @@ -145,13 +145,13 @@ def setoidOfDisjointUnion {c : Set (Set α)} (hu : Set.sUnion c = @Set.univ α) /-- The equivalence relation made from the equivalence classes of an equivalence relation r equals r. -/ theorem mkClasses_classes (r : Setoid α) : mkClasses r.classes classes_eqv_classes = r := - ext' fun x _y => - ⟨fun h => r.symm' (h { z | r.Rel z x } (r.mem_classes x) <| r.refl' x), fun h _b hb hx => + ext fun x _y => + ⟨fun h => r.symm' (h { z | r z x } (r.mem_classes x) <| r.refl' x), fun h _b hb hx => eq_of_mem_classes (r.mem_classes x) (r.refl' x) hb hx ▸ r.symm' h⟩ @[simp] theorem sUnion_classes (r : Setoid α) : ⋃₀ r.classes = Set.univ := - Set.eq_univ_of_forall fun x => Set.mem_sUnion.2 ⟨{ y | r.Rel y x }, ⟨x, rfl⟩, Setoid.refl _⟩ + Set.eq_univ_of_forall fun x => Set.mem_sUnion.2 ⟨{ y | r y x }, ⟨x, rfl⟩, Setoid.refl _⟩ /-- The equivalence between the quotient by an equivalence relation and its type of equivalence classes. -/ @@ -177,8 +177,8 @@ noncomputable def quotientEquivClasses (r : Setoid α) : Quotient r ≃ Setoid.c @[simp] lemma quotientEquivClasses_mk_eq (r : Setoid α) (a : α) : - (quotientEquivClasses r (Quotient.mk r a) : Set α) = { x | r.Rel x a } := - (@Subtype.ext_iff_val _ _ _ ⟨{ x | r.Rel x a }, Setoid.mem_classes r a⟩).mp rfl + (quotientEquivClasses r (Quotient.mk r a) : Set α) = { x | r x a } := + (@Subtype.ext_iff_val _ _ _ ⟨{ x | r x a }, Setoid.mem_classes r a⟩).mp rfl section Partition @@ -217,7 +217,7 @@ theorem IsPartition.sUnion_eq_univ {c : Set (Set α)} (hc : IsPartition c) : ⋃ /-- All elements of a partition of α are the equivalence class of some y ∈ α. -/ theorem exists_of_mem_partition {c : Set (Set α)} (hc : IsPartition c) {s} (hs : s ∈ c) : - ∃ y, s = { x | (mkClasses c hc.2).Rel x y } := + ∃ y, s = { x | mkClasses c hc.2 x y } := let ⟨y, hy⟩ := nonempty_of_mem_partition hc hs ⟨y, eq_eqv_class_of_mem hc.2 hs hy⟩ @@ -367,7 +367,7 @@ protected abbrev setoid (hs : IndexedPartition s) : Setoid α := theorem index_some (i : ι) : hs.index (hs.some i) = i := (mem_iff_index_eq _).1 <| hs.some_mem i -theorem some_index (x : α) : hs.setoid.Rel (hs.some (hs.index x)) x := +theorem some_index (x : α) : hs.setoid (hs.some (hs.index x)) x := hs.index_some (hs.index x) /-- The quotient associated to an indexed partition. -/ @@ -382,7 +382,7 @@ instance [Inhabited α] : Inhabited hs.Quotient := ⟨hs.proj default⟩ theorem proj_eq_iff {x y : α} : hs.proj x = hs.proj y ↔ hs.index x = hs.index y := - Quotient.eq_rel + Quotient.eq'' @[simp] theorem proj_some_index (x : α) : hs.proj (hs.some (hs.index x)) = hs.proj x := @@ -423,7 +423,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.Rel x) = s (hs.index x) := +theorem class_of {x : α} : setOf (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/GroupTheory/Congruence/Defs.lean b/Mathlib/GroupTheory/Congruence/Defs.lean index ced9c0f1660d13..118baa87520bd9 100644 --- a/Mathlib/GroupTheory/Congruence/Defs.lean +++ b/Mathlib/GroupTheory/Congruence/Defs.lean @@ -166,7 +166,7 @@ theorem ext {c d : Con M} (H : ∀ x y, c x y ↔ d x y) : c = d := @[to_additive "The map sending an additive congruence relation to its underlying equivalence relation is injective."] theorem toSetoid_inj {c d : Con M} (H : c.toSetoid = d.toSetoid) : c = d := - ext <| ext_iff.1 H + ext <| Setoid.ext_iff.1 H /-- Two congruence relations are equal iff their underlying binary relations are equal. -/ @[to_additive "Two additive congruence relations are equal iff their underlying binary relations @@ -334,7 +334,7 @@ instance : InfSet (Con M) where @[to_additive "The infimum of a set of additive congruence relations is the same as the infimum of the set's image under the map to the underlying equivalence relation."] theorem sInf_toSetoid (S : Set (Con M)) : (sInf S).toSetoid = sInf (toSetoid '' S) := - Setoid.ext' fun x y => + Setoid.ext fun x y => ⟨fun h r ⟨c, hS, hr⟩ => by rw [← hr]; exact h c hS, fun h c hS => h c.toSetoid ⟨c, hS, rfl⟩⟩ /-- The infimum of a set of congruence relations is the same as the infimum of the set's image @@ -572,8 +572,8 @@ def correspondence : { d // c ≤ d } ≃o Con c.Quotient where constructor · intros h x y hs rcases h ⟨x, y, rfl, rfl, hs⟩ with ⟨a, b, hx, hy, ht⟩ - exact t.1.trans (t.1.symm <| t.2 <| Quotient.eq_rel.1 hx) - (t.1.trans ht (t.2 <| Quotient.eq_rel.1 hy)) + exact t.1.trans (t.1.symm <| t.2 <| Quotient.eq'.1 hx) + (t.1.trans ht (t.2 <| Quotient.eq'.1 hy)) · intros h _ _ hs rcases hs with ⟨a, b, hx, hy, Hs⟩ exact ⟨a, b, hx, hy, h Hs⟩ diff --git a/Mathlib/GroupTheory/DoubleCoset.lean b/Mathlib/GroupTheory/DoubleCoset.lean index a7d7e296385104..d80688cff9e27d 100644 --- a/Mathlib/GroupTheory/DoubleCoset.lean +++ b/Mathlib/GroupTheory/DoubleCoset.lean @@ -72,15 +72,15 @@ def Quotient (H K : Set G) : Type _ := _root_.Quotient (setoid H K) theorem rel_iff {H K : Subgroup G} {x y : G} : - (setoid ↑H ↑K).Rel x y ↔ ∃ a ∈ H, ∃ b ∈ K, y = a * x * b := + setoid ↑H ↑K x y ↔ ∃ a ∈ H, ∃ b ∈ K, y = a * x * b := Iff.trans ⟨fun (hxy : doset x H K = doset y H K) => hxy ▸ mem_doset_self H K y, fun hxy => (doset_eq_of_mem hxy).symm⟩ mem_doset theorem bot_rel_eq_leftRel (H : Subgroup G) : - (setoid ↑(⊥ : Subgroup G) ↑H).Rel = (QuotientGroup.leftRel H).Rel := by + ⇑(setoid ↑(⊥ : Subgroup G) ↑H) = ⇑(QuotientGroup.leftRel H) := by ext a b - rw [rel_iff, Setoid.Rel, QuotientGroup.leftRel_apply] + rw [rel_iff, QuotientGroup.leftRel_apply] constructor · rintro ⟨a, rfl : a = 1, b, hb, rfl⟩ change a⁻¹ * (1 * a * b) ∈ H @@ -89,9 +89,9 @@ theorem bot_rel_eq_leftRel (H : Subgroup G) : exact ⟨1, rfl, a⁻¹ * b, h, by rw [one_mul, mul_inv_cancel_left]⟩ theorem rel_bot_eq_right_group_rel (H : Subgroup G) : - (setoid ↑H ↑(⊥ : Subgroup G)).Rel = (QuotientGroup.rightRel H).Rel := by + ⇑(setoid ↑H ↑(⊥ : Subgroup G)) = ⇑(QuotientGroup.rightRel H) := by ext a b - rw [rel_iff, Setoid.Rel, QuotientGroup.rightRel_apply] + rw [rel_iff, QuotientGroup.rightRel_apply] constructor · rintro ⟨b, hb, a, rfl : a = 1, rfl⟩ change b * a * 1 * a⁻¹ ∈ H diff --git a/Mathlib/GroupTheory/GroupAction/Basic.lean b/Mathlib/GroupTheory/GroupAction/Basic.lean index 9f99144a7769a7..547d1fc8f93c99 100644 --- a/Mathlib/GroupTheory/GroupAction/Basic.lean +++ b/Mathlib/GroupTheory/GroupAction/Basic.lean @@ -373,12 +373,11 @@ def orbitRel : Setoid α where variable {G α} @[to_additive] -theorem orbitRel_apply {a b : α} : (orbitRel G α).Rel a b ↔ a ∈ orbit G b := +theorem orbitRel_apply {a b : α} : orbitRel G α a b ↔ a ∈ orbit G b := Iff.rfl -@[to_additive] -lemma orbitRel_r_apply {a b : α} : (orbitRel G _).r a b ↔ a ∈ orbit G b := - Iff.rfl +@[to_additive (attr := deprecated (since := "2024-10-18"))] +alias orbitRel_r_apply := orbitRel_apply @[to_additive] lemma orbitRel_subgroup_le (H : Subgroup G) : orbitRel H α ≤ orbitRel G α := @@ -468,7 +467,7 @@ theorem pretransitive_iff_subsingleton_quotient : · refine Quot.inductionOn a (fun x ↦ ?_) exact Quot.inductionOn b (fun y ↦ Quot.sound <| exists_smul_eq G y x) · have h : Quotient.mk (orbitRel G α) b = ⟦a⟧ := Subsingleton.elim _ _ - exact Quotient.eq_rel.mp h + exact Quotient.eq''.mp h /-- If `α` is non-empty, an action is pretransitive if and only if the quotient has exactly one element. -/ @@ -511,7 +510,7 @@ lemma orbitRel.Quotient.orbit_injective : Injective (orbitRel.Quotient.orbit : orbitRel.Quotient G α → Set α) := by intro x y h simp_rw [orbitRel.Quotient.orbit_eq_orbit_out _ Quotient.out_eq', orbit_eq_iff, - ← orbitRel_r_apply] at h + ← orbitRel_apply] at h simpa [← Quotient.eq''] using h @[to_additive (attr := simp)] @@ -596,7 +595,7 @@ lemma orbitRel.Quotient.mem_subgroup_orbit_iff' {H : Subgroup G} {x : orbitRel.Q at hb rw [orbitRel.Quotient.mem_subgroup_orbit_iff] convert hb using 1 - rw [orbit_eq_iff, ← orbitRel_r_apply, ← Quotient.eq'', Quotient.out_eq', @Quotient.mk''_eq_mk] + rw [orbit_eq_iff, ← orbitRel_apply, ← Quotient.eq'', Quotient.out_eq', @Quotient.mk''_eq_mk] rw [orbitRel.Quotient.mem_orbit, h, @Quotient.mk''_eq_mk] variable (G) (α) @@ -725,7 +724,7 @@ theorem stabilizer_smul_eq_stabilizer_map_conj (g : G) (a : α) : inv_mul_cancel, one_smul, ← mem_stabilizer_iff, Subgroup.mem_map_equiv, MulAut.conj_symm_apply] /-- A bijection between the stabilizers of two elements in the same orbit. -/ -noncomputable def stabilizerEquivStabilizerOfOrbitRel {a b : α} (h : (orbitRel G α).Rel a b) : +noncomputable def stabilizerEquivStabilizerOfOrbitRel {a b : α} (h : orbitRel G α a b) : stabilizer G a ≃* stabilizer G b := let g : G := Classical.choose h have hg : g • b = a := Classical.choose_spec h @@ -749,7 +748,7 @@ theorem stabilizer_vadd_eq_stabilizer_map_conj (g : G) (a : α) : AddAut.conj_symm_apply] /-- A bijection between the stabilizers of two elements in the same orbit. -/ -noncomputable def stabilizerEquivStabilizerOfOrbitRel {a b : α} (h : (orbitRel G α).Rel a b) : +noncomputable def stabilizerEquivStabilizerOfOrbitRel {a b : α} (h : orbitRel G α a b) : stabilizer G a ≃+ stabilizer G b := let g : G := Classical.choose h have hg : g +ᵥ b = a := Classical.choose_spec h diff --git a/Mathlib/GroupTheory/GroupAction/ConjAct.lean b/Mathlib/GroupTheory/GroupAction/ConjAct.lean index 1f5c561c568efb..866e1f3b363046 100644 --- a/Mathlib/GroupTheory/GroupAction/ConjAct.lean +++ b/Mathlib/GroupTheory/GroupAction/ConjAct.lean @@ -246,7 +246,7 @@ theorem fixedPoints_eq_center : fixedPoints (ConjAct G) G = center G := by theorem mem_orbit_conjAct {g h : G} : g ∈ orbit (ConjAct G) h ↔ IsConj g h := by rw [isConj_comm, isConj_iff, mem_orbit_iff]; rfl -theorem orbitRel_conjAct : (orbitRel (ConjAct G) G).Rel = IsConj := +theorem orbitRel_conjAct : ⇑(orbitRel (ConjAct G) G) = IsConj := funext₂ fun g h => by rw [orbitRel_apply, mem_orbit_conjAct] theorem orbit_eq_carrier_conjClasses (g : G) : diff --git a/Mathlib/GroupTheory/GroupAction/Quotient.lean b/Mathlib/GroupTheory/GroupAction/Quotient.lean index 3babc32ec40718..f58416df124ac0 100644 --- a/Mathlib/GroupTheory/GroupAction/Quotient.lean +++ b/Mathlib/GroupTheory/GroupAction/Quotient.lean @@ -329,8 +329,7 @@ noncomputable def equivSubgroupOrbitsSetoidComap (H : Subgroup α) (ω : Ω) : have hx := x.property simp only [Set.mem_preimage, Set.mem_singleton_iff] at hx rwa [orbitRel.Quotient.mem_orbit, @Quotient.mk''_eq_mk]⟩⟧) fun a b h ↦ by - change Setoid.Rel _ _ _ at h - rw [Setoid.comap_rel, Setoid.Rel, ← Quotient.eq'', @Quotient.mk''_eq_mk] at h + rw [Setoid.comap_rel, ← Quotient.eq'', @Quotient.mk''_eq_mk] at h simp only [orbitRel.Quotient.subgroup_quotient_eq_iff] exact h left_inv := by @@ -373,7 +372,7 @@ noncomputable def equivSubgroupOrbitsQuotientGroup [IsPretransitive α β] orbitRel.Quotient H β ≃ α ⧸ H where toFun := fun q ↦ q.liftOn' (fun y ↦ (exists_smul_eq α y x).choose) (by intro y₁ y₂ h - rw [orbitRel_r_apply] at h + rw [orbitRel_apply] at h rw [Quotient.eq'', leftRel_eq] dsimp only rcases h with ⟨g, rfl⟩ @@ -389,12 +388,12 @@ noncomputable def equivSubgroupOrbitsQuotientGroup [IsPretransitive α β] intro g₁ g₂ h rw [leftRel_eq] at h simp only - rw [← @Quotient.mk''_eq_mk, Quotient.eq'', orbitRel_r_apply] + rw [← @Quotient.mk''_eq_mk, Quotient.eq'', orbitRel_apply] exact ⟨⟨_, h⟩, by simp [mul_smul]⟩) left_inv := fun y ↦ by induction' y using Quotient.inductionOn' with y simp only [Quotient.liftOn'_mk''] - rw [← @Quotient.mk''_eq_mk, Quotient.eq'', orbitRel_r_apply] + rw [← @Quotient.mk''_eq_mk, Quotient.eq'', orbitRel_apply] convert mem_orbit_self _ rw [inv_smul_eq_iff, (exists_smul_eq α y x).choose_spec] right_inv := fun g ↦ by diff --git a/Mathlib/Order/Partition/Finpartition.lean b/Mathlib/Order/Partition/Finpartition.lean index 2392533c815c4b..0c1bbdebaec82e 100644 --- a/Mathlib/Order/Partition/Finpartition.lean +++ b/Mathlib/Order/Partition/Finpartition.lean @@ -581,12 +581,12 @@ def ofSetoid (s : Setoid α) [DecidableRel s.r] : Finpartition (univ : Finset α sup_parts := by ext a simp only [sup_image, Function.id_comp, mem_univ, mem_sup, mem_filter, true_and, iff_true] - use a; exact s.refl a + use a not_bot_mem := by rw [bot_eq_empty, mem_image, not_exists] intro a simp only [filter_eq_empty_iff, not_forall, mem_univ, forall_true_left, true_and, not_not] - use a; exact s.refl a + use a theorem mem_part_ofSetoid_iff_rel {s : Setoid α} [DecidableRel s.r] {b : α} : b ∈ (ofSetoid s).part a ↔ s.r a b := by diff --git a/Mathlib/RingTheory/AdicCompletion/Algebra.lean b/Mathlib/RingTheory/AdicCompletion/Algebra.lean index f9ab3648fed208..6f7c6168e2c6c1 100644 --- a/Mathlib/RingTheory/AdicCompletion/Algebra.lean +++ b/Mathlib/RingTheory/AdicCompletion/Algebra.lean @@ -197,7 +197,7 @@ theorem smul_mk {m n : ℕ} (hmn : m ≤ n) (r : AdicCauchySequence I R) good definitional behaviour for the module instance on adic completions -/ instance : SMul (R ⧸ (I • ⊤ : Ideal R)) (M ⧸ (I • ⊤ : Submodule R M)) where smul r x := - Quotient.liftOn r (· • x) fun b₁ b₂ (h : Setoid.Rel _ b₁ b₂) ↦ by + Quotient.liftOn r (· • x) fun b₁ b₂ h ↦ by refine Quotient.inductionOn' x (fun x ↦ ?_) have h : b₁ - b₂ ∈ (I : Submodule R R) := by rwa [show I = I • ⊤ by simp, ← Submodule.quotientRel_def] diff --git a/Mathlib/RingTheory/Congruence/Basic.lean b/Mathlib/RingTheory/Congruence/Basic.lean index 131575077c37b1..90eea0cd93488b 100644 --- a/Mathlib/RingTheory/Congruence/Basic.lean +++ b/Mathlib/RingTheory/Congruence/Basic.lean @@ -74,7 +74,7 @@ instance : FunLike (RingCon R) R (R → Prop) where rcases x with ⟨⟨x, _⟩, _⟩ rcases y with ⟨⟨y, _⟩, _⟩ congr! - rw [Setoid.ext_iff, (show x.Rel = y.Rel from h)] + rw [Setoid.ext_iff, (show ⇑x = ⇑y from h)] simp theorem rel_eq_coe : c.r = c := @@ -445,7 +445,7 @@ instance : InfSet (RingCon R) where /-- The infimum of a set of congruence relations is the same as the infimum of the set's image under the map to the underlying equivalence relation. -/ theorem sInf_toSetoid (S : Set (RingCon R)) : (sInf S).toSetoid = sInf ((·.toSetoid) '' S) := - Setoid.ext' fun x y => + Setoid.ext fun x y => ⟨fun h r ⟨c, hS, hr⟩ => by rw [← hr]; exact h c hS, fun h c hS => h c.toSetoid ⟨c, hS, rfl⟩⟩ /-- The infimum of a set of congruence relations is the same as the infimum of the set's image diff --git a/Mathlib/RingTheory/Valuation/ValuationRing.lean b/Mathlib/RingTheory/Valuation/ValuationRing.lean index e95d7d322ff0d1..266cd8e9d58844 100644 --- a/Mathlib/RingTheory/Valuation/ValuationRing.lean +++ b/Mathlib/RingTheory/Valuation/ValuationRing.lean @@ -142,22 +142,22 @@ noncomputable instance linearOrder : LinearOrder (ValueGroup A K) where noncomputable instance linearOrderedCommGroupWithZero : LinearOrderedCommGroupWithZero (ValueGroup A K) := { linearOrder .. with - mul_assoc := by rintro ⟨a⟩ ⟨b⟩ ⟨c⟩; apply Quotient.sound'; rw [mul_assoc]; apply Setoid.refl' - one_mul := by rintro ⟨a⟩; apply Quotient.sound'; rw [one_mul]; apply Setoid.refl' - mul_one := by rintro ⟨a⟩; apply Quotient.sound'; rw [mul_one]; apply Setoid.refl' - mul_comm := by rintro ⟨a⟩ ⟨b⟩; apply Quotient.sound'; rw [mul_comm]; apply Setoid.refl' + mul_assoc := by rintro ⟨a⟩ ⟨b⟩ ⟨c⟩; apply Quotient.sound'; rw [mul_assoc] + one_mul := by rintro ⟨a⟩; apply Quotient.sound'; rw [one_mul] + mul_one := by rintro ⟨a⟩; apply Quotient.sound'; rw [mul_one] + mul_comm := by rintro ⟨a⟩ ⟨b⟩; apply Quotient.sound'; rw [mul_comm] mul_le_mul_left := by rintro ⟨a⟩ ⟨b⟩ ⟨c, rfl⟩ ⟨d⟩ use c; simp only [Algebra.smul_def]; ring - zero_mul := by rintro ⟨a⟩; apply Quotient.sound'; rw [zero_mul]; apply Setoid.refl' - mul_zero := by rintro ⟨a⟩; apply Quotient.sound'; rw [mul_zero]; apply Setoid.refl' + zero_mul := by rintro ⟨a⟩; apply Quotient.sound'; rw [zero_mul] + mul_zero := by rintro ⟨a⟩; apply Quotient.sound'; rw [mul_zero] zero_le_one := ⟨0, by rw [zero_smul]⟩ exists_pair_ne := by use 0, 1 intro c; obtain ⟨d, hd⟩ := Quotient.exact' c apply_fun fun t => d⁻¹ • t at hd simp only [inv_smul_smul, smul_zero, one_ne_zero] at hd - inv_zero := by apply Quotient.sound'; rw [inv_zero]; apply Setoid.refl' + inv_zero := by apply Quotient.sound'; rw [inv_zero] mul_inv_cancel := by rintro ⟨a⟩ ha apply Quotient.sound' diff --git a/Mathlib/Topology/Algebra/ProperAction/Basic.lean b/Mathlib/Topology/Algebra/ProperAction/Basic.lean index fa7a99510f216a..92fc69d56d9f4a 100644 --- a/Mathlib/Topology/Algebra/ProperAction/Basic.lean +++ b/Mathlib/Topology/Algebra/ProperAction/Basic.lean @@ -118,7 +118,7 @@ theorem t2Space_quotient_mulAction_of_properSMul [ProperSMul G X] : · ext ⟨x₁, x₂⟩ simp only [mem_preimage, map_apply, mem_diagonal_iff, mem_range, Prod.mk.injEq, Prod.exists, exists_eq_right] - rw [Quotient.eq_rel, MulAction.orbitRel_apply, MulAction.mem_orbit_iff] + rw [Quotient.eq', MulAction.orbitRel_apply, MulAction.mem_orbit_iff] all_goals infer_instance /-- If a T2 group acts properly on a topological space, then this topological space is T2. -/ diff --git a/Mathlib/Topology/DiscreteQuotient.lean b/Mathlib/Topology/DiscreteQuotient.lean index ed3253cad0993e..bad892ec52aeb4 100644 --- a/Mathlib/Topology/DiscreteQuotient.lean +++ b/Mathlib/Topology/DiscreteQuotient.lean @@ -69,7 +69,7 @@ variable {α X Y Z : Type*} [TopologicalSpace X] [TopologicalSpace Y] [Topologic @[ext] -- Porting note: in Lean 4, uses projection to `r` instead of `Setoid`. 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.Rel x)) + protected isOpen_setOf_rel : ∀ x, IsOpen (setOf (toSetoid x)) namespace DiscreteQuotient @@ -81,13 +81,13 @@ lemma toSetoid_injective : Function.Injective (@toSetoid X _) /-- 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 [Setoid.Rel, hx, h.1, h.2, ← compl_setOf] + isOpen_setOf_rel x := by by_cases hx : x ∈ A <;> simp [hx, h.1, h.2, ← compl_setOf] -theorem refl : ∀ x, S.Rel x x := S.refl' +theorem refl : ∀ x, S.toSetoid x x := S.refl' -theorem symm (x y : X) : S.Rel x y → S.Rel y x := S.symm' +theorem symm (x y : X) : S.toSetoid x y → S.toSetoid y x := S.symm' -theorem trans (x y z : X) : S.Rel x y → S.Rel y z → S.Rel x z := S.trans' +theorem trans (x y z : X) : S.toSetoid x y → S.toSetoid y z → S.toSetoid x z := S.trans' /-- The setoid whose quotient yields the discrete quotient. -/ add_decl_doc toSetoid @@ -101,7 +101,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.Rel x) := +theorem fiber_eq (x : X) : S.proj ⁻¹' {S.proj x} = setOf (S.toSetoid x) := Set.ext fun _ => eq_comm.trans Quotient.eq'' theorem proj_surjective : Function.Surjective S.proj := @@ -130,7 +130,7 @@ 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.Rel x)) := by +theorem isClopen_setOf_rel (x : X) : IsClopen (setOf (S.toSetoid x)) := by rw [← fiber_eq] apply isClopen_preimage @@ -359,7 +359,7 @@ lemma comp_finsetClopens [CompactSpace X] : (Set.image (fun (t : Clopens X) ↦ t.carrier) ∘ Finset.toSet) ∘ finsetClopens X = fun ⟨f, _⟩ ↦ f.classes := by ext d - simp only [Setoid.classes, Setoid.Rel, Set.mem_setOf_eq, Function.comp_apply, + simp only [Setoid.classes, Set.mem_setOf_eq, Function.comp_apply, finsetClopens, Set.coe_toFinset, Set.mem_image, Set.mem_range, exists_exists_eq_and] constructor diff --git a/Mathlib/Topology/MetricSpace/Contracting.lean b/Mathlib/Topology/MetricSpace/Contracting.lean index 2fcec8e182a86a..ac3f24a9253fa5 100644 --- a/Mathlib/Topology/MetricSpace/Contracting.lean +++ b/Mathlib/Topology/MetricSpace/Contracting.lean @@ -137,7 +137,7 @@ theorem efixedPoint_eq_of_edist_lt_top (hf : ContractingWith K f) {x : α} (hx : efixedPoint f hf x hx = efixedPoint f hf y hy := by refine (hf.eq_or_edist_eq_top_of_fixedPoints ?_ ?_).elim id fun h' ↦ False.elim (ne_of_lt ?_ h') <;> try apply efixedPoint_isFixedPt - change edistLtTopSetoid.Rel _ _ + change edistLtTopSetoid _ _ trans x · apply Setoid.symm' -- Porting note: Originally `symm` exact hf.edist_efixedPoint_lt_top hx @@ -221,7 +221,7 @@ theorem efixedPoint_eq_of_edist_lt_top' (hf : ContractingWith K f) {s : Set α} efixedPoint' f hsc hsf hfs x hxs hx = efixedPoint' f htc htf hft y hyt hy := by refine (hf.eq_or_edist_eq_top_of_fixedPoints ?_ ?_).elim id fun h' ↦ False.elim (ne_of_lt ?_ h') <;> try apply efixedPoint_isFixedPt' - change edistLtTopSetoid.Rel _ _ + change edistLtTopSetoid _ _ trans x · apply Setoid.symm' -- Porting note: Originally `symm` apply edist_efixedPoint_lt_top' diff --git a/Mathlib/Topology/Separation.lean b/Mathlib/Topology/Separation.lean index 1ba06927812ebc..d2e132acfed383 100644 --- a/Mathlib/Topology/Separation.lean +++ b/Mathlib/Topology/Separation.lean @@ -1632,7 +1632,7 @@ instance : TopologicalSpace (t2Quotient X) := /-- The map from a topological space to its largest T2 quotient. -/ def mk : X → t2Quotient X := Quotient.mk (t2Setoid X) -lemma mk_eq {x y : X} : mk x = mk y ↔ ∀ s : Setoid X, T2Space (Quotient s) → s.Rel x y := +lemma mk_eq {x y : X} : mk x = mk y ↔ ∀ s : Setoid X, T2Space (Quotient s) → s x y := Setoid.quotient_mk_sInf_eq variable (X) From 90c6be64b3540bf42afd057554434af4597f1367 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C3=ABl=20Dillies?= Date: Sat, 19 Oct 2024 06:53:17 +0000 Subject: [PATCH 413/425] =?UTF-8?q?feat(MeasureTheory):=20`=CE=BC.comap=20?= =?UTF-8?q?Prod.swap=20=3D=20=CE=BC.map=20Prod.swap`=20(#17918)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From PFR --- Mathlib/MeasureTheory/Measure/MeasureSpace.lean | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Mathlib/MeasureTheory/Measure/MeasureSpace.lean b/Mathlib/MeasureTheory/Measure/MeasureSpace.lean index 7a7ab5f8c32c69..3c03fb33601d8e 100644 --- a/Mathlib/MeasureTheory/Measure/MeasureSpace.lean +++ b/Mathlib/MeasureTheory/Measure/MeasureSpace.lean @@ -1975,6 +1975,13 @@ theorem quasiMeasurePreserving_symm (μ : Measure α) (e : α ≃ᵐ β) : end MeasurableEquiv +namespace MeasureTheory.Measure +variable {mα : MeasurableSpace α} {mβ : MeasurableSpace β} + +lemma comap_swap (μ : Measure (α × β)) : μ.comap Prod.swap = μ.map Prod.swap := + (MeasurableEquiv.prodComm ..).comap_symm + +end MeasureTheory.Measure end set_option linter.style.longFile 2000 From 61509b3d7569a6b81e6686f22dd8db1b56156e09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violeta=20Hern=C3=A1ndez?= Date: Sat, 19 Oct 2024 07:30:32 +0000 Subject: [PATCH 414/425] chore(SetTheory/Ordinal/Basic): make `Ordinal.typein` a `PrincipalSeg` (#17599) This allows us to golf most of its API down to one-liners. --- Mathlib/Order/InitialSeg.lean | 7 ++ Mathlib/SetTheory/Ordinal/Basic.lean | 113 ++++++++++++++------------- 2 files changed, 65 insertions(+), 55 deletions(-) diff --git a/Mathlib/Order/InitialSeg.lean b/Mathlib/Order/InitialSeg.lean index e53d78efa02774..b1e211077acf29 100644 --- a/Mathlib/Order/InitialSeg.lean +++ b/Mathlib/Order/InitialSeg.lean @@ -289,6 +289,10 @@ theorem mem_range_of_rel [IsTrans β s] (f : r ≺i s) {a : α} {b : β} (h : s @[deprecated mem_range_of_rel (since := "2024-09-21")] alias init := mem_range_of_rel +theorem surjOn (f : r ≺i s) : Set.SurjOn f Set.univ { b | s b f.top } := by + intro b h + simpa using mem_range_of_rel_top _ h + /-- A principal segment is in particular an initial segment. -/ instance hasCoeInitialSeg [IsTrans β s] : Coe (r ≺i s) (r ≼i s) := ⟨fun f => ⟨f.toRelEmbedding, fun _ _ => f.mem_range_of_rel⟩⟩ @@ -383,6 +387,9 @@ instance [IsWellOrder β s] : Subsingleton (r ≺i s) := cases g have := RelEmbedding.coe_fn_injective ef; congr ⟩ +protected theorem eq [IsWellOrder β s] (f g : r ≺i s) (a) : f a = g a := by + rw [Subsingleton.elim f g] + theorem top_eq [IsWellOrder γ t] (e : r ≃r s) (f : r ≺i t) (g : s ≺i t) : f.top = g.top := by rw [Subsingleton.elim f (PrincipalSeg.equivLT e g)]; rfl diff --git a/Mathlib/SetTheory/Ordinal/Basic.lean b/Mathlib/SetTheory/Ordinal/Basic.lean index 2de607c6ac4062..bc2a81d9ed4ff4 100644 --- a/Mathlib/SetTheory/Ordinal/Basic.lean +++ b/Mathlib/SetTheory/Ordinal/Basic.lean @@ -139,11 +139,6 @@ instance inhabited : Inhabited Ordinal := instance one : One Ordinal := ⟨type <| @EmptyRelation PUnit⟩ -/-- The order type of an element inside a well order. For the embedding as a principal segment, see -`typein.principalSeg`. -/ -def typein (r : α → α → Prop) [IsWellOrder α r] (a : α) : Ordinal := - type (Subrel r { b | r b a }) - @[simp] theorem type_def' (w : WellOrder) : ⟦w⟧ = type w.r := by cases w @@ -375,69 +370,73 @@ def principalSegToType {α β : Ordinal} (h : α < β) : α.toType by - rcases f.mem_range_of_rel_top h with ⟨b, rfl⟩; exact ⟨b, rfl⟩⟩ - -@[simp] -theorem typein_apply {α β} {r : α → α → Prop} {s : β → β → Prop} [IsWellOrder α r] [IsWellOrder β s] - (f : r ≼i s) (a : α) : Ordinal.typein s (f a) = Ordinal.typein r a := - Eq.symm <| - Quotient.sound - ⟨RelIso.ofSurjective - (RelEmbedding.codRestrict _ ((Subrel.relEmbedding _ _).trans f) fun ⟨x, h⟩ => by - rw [RelEmbedding.trans_apply]; exact f.toRelEmbedding.map_rel_iff.2 h) - fun ⟨y, h⟩ => by - rcases f.mem_range_of_rel h with ⟨a, rfl⟩ - exact ⟨⟨a, f.toRelEmbedding.map_rel_iff.1 h⟩, - Subtype.eq <| RelEmbedding.trans_apply _ _ _⟩⟩ +theorem typein_top {α β} {r : α → α → Prop} {s : β → β → Prop} + [IsWellOrder α r] [IsWellOrder β s] (f : r ≺i s) : typein s f.top = type r := + f.subrelIso.ordinal_type_eq @[simp] theorem typein_lt_typein (r : α → α → Prop) [IsWellOrder α r] {a b : α} : typein r a < typein r b ↔ r a b := - ⟨fun ⟨f⟩ => by - have : f.top.1 = a := by - let f' := PrincipalSeg.ofElement r a - let g' := f.trans (PrincipalSeg.ofElement r b) - have : g'.top = f'.top := by rw [Subsingleton.elim f' g'] - exact this - rw [← this] - exact f.top.2, fun h => - ⟨PrincipalSeg.codRestrict _ (PrincipalSeg.ofElement r a) (fun x => @trans _ r _ _ _ _ x.2 h) h⟩⟩ + (typein r).map_rel_iff + +theorem mem_range_typein_iff (r : α → α → Prop) [IsWellOrder α r] {o} : + o ∈ Set.range (typein r) ↔ o < type r := + (typein r).mem_range_iff_rel theorem typein_surj (r : α → α → Prop) [IsWellOrder α r] {o} (h : o < type r) : - ∃ a, typein r a = o := - inductionOn o (fun _ _ _ ⟨f⟩ => ⟨f.top, typein_top _⟩) h + o ∈ Set.range (typein r) := + (typein r).mem_range_of_rel_top h + +theorem typein_surjOn (r : α → α → Prop) [IsWellOrder α r] : + Set.SurjOn (typein r) Set.univ (Set.Iio (type r)) := + (typein r).surjOn theorem typein_injective (r : α → α → Prop) [IsWellOrder α r] : Injective (typein r) := - injective_of_increasing r (· < ·) (typein r) (typein_lt_typein r).2 + (typein r).injective -@[simp] theorem typein_inj (r : α → α → Prop) [IsWellOrder α r] {a b} : typein r a = typein r b ↔ a = b := - (typein_injective r).eq_iff - -/-- Principal segment version of the `typein` function, embedding a well order into ordinals as a -principal segment. -/ -def typein.principalSeg {α : Type u} (r : α → α → Prop) [IsWellOrder α r] : - @PrincipalSeg α Ordinal.{u} r (· < ·) := - ⟨⟨⟨typein r, typein_injective r⟩, typein_lt_typein r⟩, type r, - fun _ ↦ ⟨fun ⟨a, h⟩ ↦ h ▸ typein_lt_type r a, typein_surj r⟩⟩ - -@[simp] -theorem typein.principalSeg_coe (r : α → α → Prop) [IsWellOrder α r] : - (typein.principalSeg r : α → Ordinal) = typein r := - rfl + (typein r).inj /-! ### Enumerating elements in a well-order with ordinals. -/ @@ -450,16 +449,16 @@ the elements of `α`. -/ @[simps! symm_apply_coe] def enum (r : α → α → Prop) [IsWellOrder α r] : @RelIso { o // o < type r } α (Subrel (· < ·) { o | o < type r }) r := - (typein.principalSeg r).subrelIso + (typein r).subrelIso @[simp] theorem typein_enum (r : α → α → Prop) [IsWellOrder α r] {o} (h : o < type r) : typein r (enum r ⟨o, h⟩) = o := - (typein.principalSeg r).apply_subrelIso _ + (typein r).apply_subrelIso _ theorem enum_type {α β} {r : α → α → Prop} {s : β → β → Prop} [IsWellOrder α r] [IsWellOrder β s] (f : s ≺i r) {h : type s < type r} : enum r ⟨type s, h⟩ = f.top := - (typein.principalSeg r).injective <| (typein_enum _ _).trans (typein_top _).symm + (typein r).injective <| (typein_enum _ _).trans (typein_top _).symm @[simp] theorem enum_typein (r : α → α → Prop) [IsWellOrder α r] (a : α) : @@ -502,6 +501,10 @@ theorem induction {p : Ordinal.{u} → Prop} (i : Ordinal.{u}) (h : ∀ j, (∀ p i := lt_wf.induction i h +theorem typein_apply {α β} {r : α → α → Prop} {s : β → β → Prop} [IsWellOrder α r] [IsWellOrder β s] + (f : r ≼i s) (a : α) : typein s (f a) = typein r a := by + rw [← f.leLT_apply _ a, (f.leLT _).eq] + /-! ### Cardinality of ordinals -/ @@ -1031,7 +1034,7 @@ def liftPrincipalSeg : Ordinal.{u} Date: Sat, 19 Oct 2024 07:30:33 +0000 Subject: [PATCH 415/425] chore(Algebra/Module): split off `NoZeroSMulDivisors` (#17909) The definition of `NoZeroSMulDivisors` doesn't require us to know about modules. By splitting off this definition, we can streamline the downstream import graph a bit. In the process, generalize a few instances from `Module` to `SMulWithZero`. New files: * `NoZeroSMulDivisors/Defs.lean`: definition and basic results that don't require `Module` * `NoZeroSMulDivisors/Basic.lean`: basic results that require `Module` * `NoZeroSMulDivisors/Pi.lean`: results on `NoZeroSMulDivisors _ (_ -> _)` that don't require `Module` * `NoZeroSMulDivisors/Prod.lean`: results on `NoZeroSMulDivisors _ (_ x _)` that don't require `Module` --- Mathlib.lean | 4 + Mathlib/Algebra/Algebra/Basic.lean | 1 + Mathlib/Algebra/BigOperators/Finprod.lean | 2 +- Mathlib/Algebra/Group/EvenFunction.lean | 4 +- Mathlib/Algebra/ModEq.lean | 1 + Mathlib/Algebra/Module/Basic.lean | 25 +-- Mathlib/Algebra/Module/Card.lean | 2 +- Mathlib/Algebra/Module/Defs.lean | 176 ------------------ Mathlib/Algebra/Module/LinearMap/Basic.lean | 2 +- Mathlib/Algebra/Module/LinearMap/End.lean | 1 + Mathlib/Algebra/Module/Pi.lean | 13 -- Mathlib/Algebra/Module/Prod.lean | 13 -- Mathlib/Algebra/Module/Rat.lean | 1 + Mathlib/Algebra/NoZeroSMulDivisors/Basic.lean | 155 +++++++++++++++ Mathlib/Algebra/NoZeroSMulDivisors/Defs.lean | 78 ++++++++ Mathlib/Algebra/NoZeroSMulDivisors/Pi.lean | 34 ++++ Mathlib/Algebra/NoZeroSMulDivisors/Prod.lean | 32 ++++ Mathlib/Algebra/Order/Module/Defs.lean | 2 +- Mathlib/Algebra/Order/Star/Basic.lean | 1 + Mathlib/Data/ENNReal/Operations.lean | 1 - Mathlib/Data/Set/Pointwise/SMul.lean | 1 + Mathlib/GroupTheory/Subgroup/Saturated.lean | 2 +- Mathlib/LinearAlgebra/BilinearMap.lean | 1 + Mathlib/LinearAlgebra/LinearPMap.lean | 1 - Mathlib/LinearAlgebra/Multilinear/Basic.lean | 1 + Mathlib/LinearAlgebra/Span.lean | 1 + Mathlib/RingTheory/Nilpotent/Basic.lean | 2 +- 27 files changed, 321 insertions(+), 236 deletions(-) create mode 100644 Mathlib/Algebra/NoZeroSMulDivisors/Basic.lean create mode 100644 Mathlib/Algebra/NoZeroSMulDivisors/Defs.lean create mode 100644 Mathlib/Algebra/NoZeroSMulDivisors/Pi.lean create mode 100644 Mathlib/Algebra/NoZeroSMulDivisors/Prod.lean diff --git a/Mathlib.lean b/Mathlib.lean index c66a3419a9aeb8..66e48c38b8ae0d 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -544,6 +544,10 @@ import Mathlib.Algebra.MvPolynomial.Rename import Mathlib.Algebra.MvPolynomial.Supported import Mathlib.Algebra.MvPolynomial.Variables import Mathlib.Algebra.NeZero +import Mathlib.Algebra.NoZeroSMulDivisors.Basic +import Mathlib.Algebra.NoZeroSMulDivisors.Defs +import Mathlib.Algebra.NoZeroSMulDivisors.Pi +import Mathlib.Algebra.NoZeroSMulDivisors.Prod import Mathlib.Algebra.Notation import Mathlib.Algebra.Opposites import Mathlib.Algebra.Order.AbsoluteValue diff --git a/Mathlib/Algebra/Algebra/Basic.lean b/Mathlib/Algebra/Algebra/Basic.lean index 66932daf4008da..e9e129ad5c0fdc 100644 --- a/Mathlib/Algebra/Algebra/Basic.lean +++ b/Mathlib/Algebra/Algebra/Basic.lean @@ -9,6 +9,7 @@ import Mathlib.Algebra.Module.Equiv.Basic import Mathlib.Algebra.Module.Submodule.Ker import Mathlib.Algebra.Module.Submodule.RestrictScalars import Mathlib.Algebra.Module.ULift +import Mathlib.Algebra.NoZeroSMulDivisors.Basic import Mathlib.Algebra.Ring.Subring.Basic import Mathlib.Data.Nat.Cast.Order.Basic import Mathlib.Data.Int.CharZero diff --git a/Mathlib/Algebra/BigOperators/Finprod.lean b/Mathlib/Algebra/BigOperators/Finprod.lean index fbfabaaebfca3c..b6b2d96428073e 100644 --- a/Mathlib/Algebra/BigOperators/Finprod.lean +++ b/Mathlib/Algebra/BigOperators/Finprod.lean @@ -5,7 +5,7 @@ Authors: Kexing Ying, Kevin Buzzard, Yury Kudryashov -/ import Mathlib.Algebra.BigOperators.GroupWithZero.Finset import Mathlib.Algebra.Group.FiniteSupport -import Mathlib.Algebra.Module.Defs +import Mathlib.Algebra.NoZeroSMulDivisors.Basic import Mathlib.Algebra.Order.BigOperators.Group.Finset import Mathlib.Data.Set.Subsingleton diff --git a/Mathlib/Algebra/Group/EvenFunction.lean b/Mathlib/Algebra/Group/EvenFunction.lean index 4713a0549c61fa..81ddf35dcd57c8 100644 --- a/Mathlib/Algebra/Group/EvenFunction.lean +++ b/Mathlib/Algebra/Group/EvenFunction.lean @@ -3,9 +3,9 @@ Copyright (c) 2024 David Loeffler. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: David Loeffler -/ -import Mathlib.Algebra.Group.Action.Pi -import Mathlib.Algebra.Module.Defs import Mathlib.Algebra.BigOperators.Group.Finset +import Mathlib.Algebra.Group.Action.Pi +import Mathlib.Algebra.NoZeroSMulDivisors.Basic /-! # Even and odd functions diff --git a/Mathlib/Algebra/ModEq.lean b/Mathlib/Algebra/ModEq.lean index a275aad2c72547..2744ba932b93f4 100644 --- a/Mathlib/Algebra/ModEq.lean +++ b/Mathlib/Algebra/ModEq.lean @@ -5,6 +5,7 @@ Authors: Yaël Dillies -/ import Mathlib.Data.Int.ModEq import Mathlib.Algebra.Field.Basic +import Mathlib.Algebra.NoZeroSMulDivisors.Basic import Mathlib.Algebra.Order.Ring.Int import Mathlib.GroupTheory.QuotientGroup.Basic diff --git a/Mathlib/Algebra/Module/Basic.lean b/Mathlib/Algebra/Module/Basic.lean index 8656e47667f241..18deb70317a226 100644 --- a/Mathlib/Algebra/Module/Basic.lean +++ b/Mathlib/Algebra/Module/Basic.lean @@ -7,6 +7,7 @@ import Mathlib.Algebra.Field.Basic import Mathlib.Algebra.Group.Action.Pi import Mathlib.Algebra.Group.Indicator import Mathlib.Algebra.Module.Defs +import Mathlib.Algebra.NoZeroSMulDivisors.Defs /-! # Further basic results about modules. @@ -95,30 +96,6 @@ theorem inv_intCast_smul_comm {α E : Type*} (R : Type*) [AddCommGroup E] [Divis @[deprecated (since := "2024-04-17")] alias inv_int_cast_smul_comm := inv_intCast_smul_comm - - -section NoZeroSMulDivisors - -section Module - -instance [AddCommGroup M] [NoZeroSMulDivisors ℤ M] : NoZeroSMulDivisors ℕ M := - ⟨fun {c x} hcx ↦ by rwa [← Nat.cast_smul_eq_nsmul ℤ c x, smul_eq_zero, Nat.cast_eq_zero] at hcx⟩ - -end Module - -section GroupWithZero - -variable [GroupWithZero R] [AddMonoid M] [DistribMulAction R M] - --- see note [lower instance priority] -/-- This instance applies to `DivisionSemiring`s, in particular `NNReal` and `NNRat`. -/ -instance (priority := 100) GroupWithZero.toNoZeroSMulDivisors : NoZeroSMulDivisors R M := - ⟨fun {a _} h ↦ or_iff_not_imp_left.2 fun ha ↦ (smul_eq_zero_iff_eq <| Units.mk0 a ha).1 h⟩ - -end GroupWithZero - -end NoZeroSMulDivisors - namespace Function lemma support_smul_subset_left [Zero R] [Zero M] [SMulWithZero R M] (f : α → R) (g : α → M) : diff --git a/Mathlib/Algebra/Module/Card.lean b/Mathlib/Algebra/Module/Card.lean index e9c8b1d5446ec5..3941ffd972d1d7 100644 --- a/Mathlib/Algebra/Module/Card.lean +++ b/Mathlib/Algebra/Module/Card.lean @@ -3,7 +3,7 @@ Copyright (c) 2023 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.Algebra.Module.Defs +import Mathlib.Algebra.NoZeroSMulDivisors.Basic import Mathlib.SetTheory.Cardinal.Basic /-! diff --git a/Mathlib/Algebra/Module/Defs.lean b/Mathlib/Algebra/Module/Defs.lean index a024554de986a6..c51d03d323fe8a 100644 --- a/Mathlib/Algebra/Module/Defs.lean +++ b/Mathlib/Algebra/Module/Defs.lean @@ -408,182 +408,6 @@ instance AddCommGroup.intIsScalarTower {R : Type u} {M : Type v} [Ring R] [AddCo [Module R M] : IsScalarTower ℤ R M where smul_assoc n x y := ((smulAddHom R M).flip y).map_zsmul x n -section NoZeroSMulDivisors - -/-! ### `NoZeroSMulDivisors` - -This section defines the `NoZeroSMulDivisors` class, and includes some tests -for the vanishing of elements (especially in modules over division rings). --/ - - -/-- `NoZeroSMulDivisors R M` states that a scalar multiple is `0` only if either argument is `0`. -This is a version of saying that `M` is torsion free, without assuming `R` is zero-divisor free. - -The main application of `NoZeroSMulDivisors R M`, when `M` is a module, -is the result `smul_eq_zero`: a scalar multiple is `0` iff either argument is `0`. - -It is a generalization of the `NoZeroDivisors` class to heterogeneous multiplication. --/ -@[mk_iff] -class NoZeroSMulDivisors (R M : Type*) [Zero R] [Zero M] [SMul R M] : Prop where - /-- If scalar multiplication yields zero, either the scalar or the vector was zero. -/ - eq_zero_or_eq_zero_of_smul_eq_zero : ∀ {c : R} {x : M}, c • x = 0 → c = 0 ∨ x = 0 - -export NoZeroSMulDivisors (eq_zero_or_eq_zero_of_smul_eq_zero) - -/-- Pullback a `NoZeroSMulDivisors` instance along an injective function. -/ -theorem Function.Injective.noZeroSMulDivisors {R M N : Type*} [Zero R] [Zero M] [Zero N] - [SMul R M] [SMul R N] [NoZeroSMulDivisors R N] (f : M → N) (hf : Function.Injective f) - (h0 : f 0 = 0) (hs : ∀ (c : R) (x : M), f (c • x) = c • f x) : NoZeroSMulDivisors R M := - ⟨fun {_ _} h => - Or.imp_right (@hf _ _) <| h0.symm ▸ eq_zero_or_eq_zero_of_smul_eq_zero (by rw [← hs, h, h0])⟩ - --- See note [lower instance priority] -instance (priority := 100) NoZeroDivisors.toNoZeroSMulDivisors [Zero R] [Mul R] - [NoZeroDivisors R] : NoZeroSMulDivisors R R := - ⟨fun {_ _} => eq_zero_or_eq_zero_of_mul_eq_zero⟩ - -theorem smul_ne_zero [Zero R] [Zero M] [SMul R M] [NoZeroSMulDivisors R M] {c : R} {x : M} - (hc : c ≠ 0) (hx : x ≠ 0) : c • x ≠ 0 := fun h => - (eq_zero_or_eq_zero_of_smul_eq_zero h).elim hc hx - -section SMulWithZero - -variable [Zero R] [Zero M] [SMulWithZero R M] [NoZeroSMulDivisors R M] {c : R} {x : M} - -@[simp] -theorem smul_eq_zero : c • x = 0 ↔ c = 0 ∨ x = 0 := - ⟨eq_zero_or_eq_zero_of_smul_eq_zero, fun h => - h.elim (fun h => h.symm ▸ zero_smul R x) fun h => h.symm ▸ smul_zero c⟩ - -theorem smul_ne_zero_iff : c • x ≠ 0 ↔ c ≠ 0 ∧ x ≠ 0 := by rw [Ne, smul_eq_zero, not_or] - -lemma smul_eq_zero_iff_left (hx : x ≠ 0) : c • x = 0 ↔ c = 0 := by simp [hx] -lemma smul_eq_zero_iff_right (hc : c ≠ 0) : c • x = 0 ↔ x = 0 := by simp [hc] -lemma smul_ne_zero_iff_left (hx : x ≠ 0) : c • x ≠ 0 ↔ c ≠ 0 := by simp [hx] -lemma smul_ne_zero_iff_right (hc : c ≠ 0) : c • x ≠ 0 ↔ x ≠ 0 := by simp [hc] - -end SMulWithZero - -section Module - -section Nat - -theorem Nat.noZeroSMulDivisors - (R) (M) [Semiring R] [CharZero R] [AddCommMonoid M] [Module R M] [NoZeroSMulDivisors R M] : - NoZeroSMulDivisors ℕ M where - eq_zero_or_eq_zero_of_smul_eq_zero {c x} := by rw [← Nat.cast_smul_eq_nsmul R, smul_eq_zero]; simp - -theorem two_nsmul_eq_zero - (R) (M) [Semiring R] [CharZero R] [AddCommMonoid M] [Module R M] [NoZeroSMulDivisors R M] - {v : M} : 2 • v = 0 ↔ v = 0 := by - haveI := Nat.noZeroSMulDivisors R M - simp [smul_eq_zero] - -end Nat - -variable [Semiring R] -variable (R M) - -/-- If `M` is an `R`-module with one and `M` has characteristic zero, then `R` has characteristic -zero as well. Usually `M` is an `R`-algebra. -/ -theorem CharZero.of_module (M) [AddCommMonoidWithOne M] [CharZero M] [Module R M] : CharZero R := by - refine ⟨fun m n h => @Nat.cast_injective M _ _ _ _ ?_⟩ - rw [← nsmul_one, ← nsmul_one, ← Nat.cast_smul_eq_nsmul R, ← Nat.cast_smul_eq_nsmul R, h] - -end Module - -section AddCommGroup - --- `R` can still be a semiring here -variable [Semiring R] [AddCommGroup M] [Module R M] - -section SMulInjective - -variable (M) - -theorem smul_right_injective [NoZeroSMulDivisors R M] {c : R} (hc : c ≠ 0) : - Function.Injective (c • · : M → M) := - (injective_iff_map_eq_zero (smulAddHom R M c)).2 fun _ ha => (smul_eq_zero.mp ha).resolve_left hc - -variable {M} - -theorem smul_right_inj [NoZeroSMulDivisors R M] {c : R} (hc : c ≠ 0) {x y : M} : - c • x = c • y ↔ x = y := - (smul_right_injective M hc).eq_iff - -end SMulInjective - -section Nat - -theorem self_eq_neg - (R) (M) [Semiring R] [CharZero R] [AddCommGroup M] [Module R M] [NoZeroSMulDivisors R M] - {v : M} : v = -v ↔ v = 0 := by - rw [← two_nsmul_eq_zero R M, two_smul, add_eq_zero_iff_eq_neg] - -theorem neg_eq_self - (R) (M) [Semiring R] [CharZero R] [AddCommGroup M] [Module R M] [NoZeroSMulDivisors R M] - {v : M} : -v = v ↔ v = 0 := by - rw [eq_comm, self_eq_neg R M] - -theorem self_ne_neg - (R) (M) [Semiring R] [CharZero R] [AddCommGroup M] [Module R M] [NoZeroSMulDivisors R M] - {v : M} : v ≠ -v ↔ v ≠ 0 := - (self_eq_neg R M).not - -theorem neg_ne_self - (R) (M) [Semiring R] [CharZero R] [AddCommGroup M] [Module R M] [NoZeroSMulDivisors R M] - {v : M} : -v ≠ v ↔ v ≠ 0 := - (neg_eq_self R M).not - -end Nat - -end AddCommGroup - -section Module - -variable [Ring R] [AddCommGroup M] [Module R M] - -section SMulInjective - -variable (R) -variable [NoZeroSMulDivisors R M] - -theorem smul_left_injective {x : M} (hx : x ≠ 0) : Function.Injective fun c : R => c • x := - fun c d h => - sub_eq_zero.mp - ((smul_eq_zero.mp - (calc - (c - d) • x = c • x - d • x := sub_smul c d x - _ = 0 := sub_eq_zero.mpr h - )).resolve_right - hx) - -end SMulInjective - -instance [NoZeroSMulDivisors ℤ M] : NoZeroSMulDivisors ℕ M := - ⟨fun {c x} hcx ↦ by rwa [← Nat.cast_smul_eq_nsmul ℤ, smul_eq_zero, Nat.cast_eq_zero] at hcx⟩ - -variable (R M) - -theorem NoZeroSMulDivisors.int_of_charZero - (R) (M) [Ring R] [AddCommGroup M] [Module R M] [NoZeroSMulDivisors R M] [CharZero R] : - NoZeroSMulDivisors ℤ M := - ⟨fun {z x} h ↦ by simpa [← smul_one_smul R z x] using h⟩ - -/-- Only a ring of characteristic zero can have a non-trivial module without additive or -scalar torsion. -/ -theorem CharZero.of_noZeroSMulDivisors [Nontrivial M] [NoZeroSMulDivisors ℤ M] : CharZero R := by - refine ⟨fun {n m h} ↦ ?_⟩ - obtain ⟨x, hx⟩ := exists_ne (0 : M) - replace h : (n : ℤ) • x = (m : ℤ) • x := by simp [← Nat.cast_smul_eq_nsmul R, h] - simpa using smul_left_injective ℤ hx h - -end Module - -end NoZeroSMulDivisors - -- Porting note (#10618): simp can prove this --@[simp] theorem Nat.smul_one_eq_cast {R : Type*} [NonAssocSemiring R] (m : ℕ) : m • (1 : R) = ↑m := by diff --git a/Mathlib/Algebra/Module/LinearMap/Basic.lean b/Mathlib/Algebra/Module/LinearMap/Basic.lean index 1a68ecbd89506a..baff9dbf891d43 100644 --- a/Mathlib/Algebra/Module/LinearMap/Basic.lean +++ b/Mathlib/Algebra/Module/LinearMap/Basic.lean @@ -5,7 +5,7 @@ Authors: Nathaniel Thomas, Jeremy Avigad, Johannes Hölzl, Mario Carneiro, Anne Frédéric Dupuis, Heather Macbeth -/ import Mathlib.Algebra.Module.LinearMap.Defs -import Mathlib.Algebra.Module.Pi +import Mathlib.Algebra.NoZeroSMulDivisors.Pi import Mathlib.GroupTheory.GroupAction.DomAct.Basic /-! diff --git a/Mathlib/Algebra/Module/LinearMap/End.lean b/Mathlib/Algebra/Module/LinearMap/End.lean index f75595188a8c15..a861127390ad88 100644 --- a/Mathlib/Algebra/Module/LinearMap/End.lean +++ b/Mathlib/Algebra/Module/LinearMap/End.lean @@ -6,6 +6,7 @@ Authors: Nathaniel Thomas, Jeremy Avigad, Johannes Hölzl, Mario Carneiro, Anne -/ import Mathlib.Algebra.GroupPower.IterateHom import Mathlib.Algebra.Module.LinearMap.Defs +import Mathlib.Algebra.NoZeroSMulDivisors.Defs /-! # Endomorphisms of a module diff --git a/Mathlib/Algebra/Module/Pi.lean b/Mathlib/Algebra/Module/Pi.lean index 1d6a967b8db91a..23c86123bb9477 100644 --- a/Mathlib/Algebra/Module/Pi.lean +++ b/Mathlib/Algebra/Module/Pi.lean @@ -83,17 +83,4 @@ instance module' {g : I → Type*} {r : ∀ i, Semiring (f i)} {m : ∀ i, AddCo -- Porting note: not sure why `apply zero_smul` fails here. rw [zero_smul] -instance noZeroSMulDivisors (α) [Semiring α] [∀ i, AddCommMonoid <| f i] - [∀ i, Module α <| f i] [∀ i, NoZeroSMulDivisors α <| f i] : - NoZeroSMulDivisors α (∀ i : I, f i) := - ⟨fun {_ _} h => - or_iff_not_imp_left.mpr fun hc => - funext fun i => (smul_eq_zero.mp (congr_fun h i)).resolve_left hc⟩ - -/-- A special case of `Pi.noZeroSMulDivisors` for non-dependent types. Lean struggles to -synthesize this instance by itself elsewhere in the library. -/ -instance _root_.Function.noZeroSMulDivisors {ι α β : Type*} [Semiring α] [AddCommMonoid β] - [Module α β] [NoZeroSMulDivisors α β] : NoZeroSMulDivisors α (ι → β) := - Pi.noZeroSMulDivisors _ - end Pi diff --git a/Mathlib/Algebra/Module/Prod.lean b/Mathlib/Algebra/Module/Prod.lean index 11b934777a06a2..de41fcccad5364 100644 --- a/Mathlib/Algebra/Module/Prod.lean +++ b/Mathlib/Algebra/Module/Prod.lean @@ -35,17 +35,4 @@ instance instModule [Semiring R] [AddCommMonoid M] [AddCommMonoid N] [Module R M add_smul := fun _ _ _ => mk.inj_iff.mpr ⟨add_smul _ _ _, add_smul _ _ _⟩ zero_smul := fun _ => mk.inj_iff.mpr ⟨zero_smul _ _, zero_smul _ _⟩ } -instance noZeroSMulDivisors {r : Semiring R} [AddCommMonoid M] [AddCommMonoid N] - [Module R M] [Module R N] [NoZeroSMulDivisors R M] [NoZeroSMulDivisors R N] : - NoZeroSMulDivisors R (M × N) := - { eq_zero_or_eq_zero_of_smul_eq_zero := by -- Porting note: in mathlib3 there is no need for `by`/ - -- `intro`/`exact`, i.e. the following works: - -- ⟨fun c ⟨x, y⟩ h => - -- or_iff_not_imp_left.mpr fun hc => - intro c ⟨x, y⟩ h - exact or_iff_not_imp_left.mpr fun hc => - mk.inj_iff.mpr - ⟨(smul_eq_zero.mp (congr_arg fst h)).resolve_left hc, - (smul_eq_zero.mp (congr_arg snd h)).resolve_left hc⟩ } - end Prod diff --git a/Mathlib/Algebra/Module/Rat.lean b/Mathlib/Algebra/Module/Rat.lean index c0ed84a4366ed1..3ce5e5ac011a8b 100644 --- a/Mathlib/Algebra/Module/Rat.lean +++ b/Mathlib/Algebra/Module/Rat.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Nathaniel Thomas, Jeremy Avigad, Johannes Hölzl, Mario Carneiro -/ import Mathlib.Algebra.Module.Basic +import Mathlib.Algebra.NoZeroSMulDivisors.Basic import Mathlib.Algebra.Field.Rat import Mathlib.Algebra.Order.Field.Rat diff --git a/Mathlib/Algebra/NoZeroSMulDivisors/Basic.lean b/Mathlib/Algebra/NoZeroSMulDivisors/Basic.lean new file mode 100644 index 00000000000000..f33114e9583a3e --- /dev/null +++ b/Mathlib/Algebra/NoZeroSMulDivisors/Basic.lean @@ -0,0 +1,155 @@ +/- +Copyright (c) 2015 Nathaniel Thomas. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Anne Baanen, Yury Kudryashov, Joseph Myers, Heather Macbeth, Kim Morrison, Yaël Dillies +-/ +import Mathlib.Algebra.Module.Defs +import Mathlib.Algebra.NoZeroSMulDivisors.Defs + +/-! +# `NoZeroSMulDivisors` + +This file defines the `NoZeroSMulDivisors` class, and includes some tests +for the vanishing of elements (especially in modules over division rings). +-/ + +assert_not_exists Multiset +assert_not_exists Set.indicator +assert_not_exists Pi.single_smul₀ +assert_not_exists Field + +section NoZeroSMulDivisors + +variable {R M : Type*} + +section Module + +section Nat + +theorem Nat.noZeroSMulDivisors + (R) (M) [Semiring R] [CharZero R] [AddCommMonoid M] [Module R M] [NoZeroSMulDivisors R M] : + NoZeroSMulDivisors ℕ M where + eq_zero_or_eq_zero_of_smul_eq_zero {c x} := by rw [← Nat.cast_smul_eq_nsmul R, smul_eq_zero]; simp + +theorem two_nsmul_eq_zero + (R) (M) [Semiring R] [CharZero R] [AddCommMonoid M] [Module R M] [NoZeroSMulDivisors R M] + {v : M} : 2 • v = 0 ↔ v = 0 := by + haveI := Nat.noZeroSMulDivisors R M + simp [smul_eq_zero] + +end Nat + +variable [Semiring R] +variable (R M) + +/-- If `M` is an `R`-module with one and `M` has characteristic zero, then `R` has characteristic +zero as well. Usually `M` is an `R`-algebra. -/ +theorem CharZero.of_module (M) [AddCommMonoidWithOne M] [CharZero M] [Module R M] : CharZero R := by + refine ⟨fun m n h => @Nat.cast_injective M _ _ _ _ ?_⟩ + rw [← nsmul_one, ← nsmul_one, ← Nat.cast_smul_eq_nsmul R, ← Nat.cast_smul_eq_nsmul R, h] + +end Module + +section AddCommGroup + +-- `R` can still be a semiring here +variable [Semiring R] [AddCommGroup M] [Module R M] + +section SMulInjective + +variable (M) + +theorem smul_right_injective [NoZeroSMulDivisors R M] {c : R} (hc : c ≠ 0) : + Function.Injective (c • · : M → M) := + (injective_iff_map_eq_zero (smulAddHom R M c)).2 fun _ ha => (smul_eq_zero.mp ha).resolve_left hc + +variable {M} + +theorem smul_right_inj [NoZeroSMulDivisors R M] {c : R} (hc : c ≠ 0) {x y : M} : + c • x = c • y ↔ x = y := + (smul_right_injective M hc).eq_iff + +end SMulInjective + +section Nat + +theorem self_eq_neg + (R) (M) [Semiring R] [CharZero R] [AddCommGroup M] [Module R M] [NoZeroSMulDivisors R M] + {v : M} : v = -v ↔ v = 0 := by + rw [← two_nsmul_eq_zero R M, two_smul, add_eq_zero_iff_eq_neg] + +theorem neg_eq_self + (R) (M) [Semiring R] [CharZero R] [AddCommGroup M] [Module R M] [NoZeroSMulDivisors R M] + {v : M} : -v = v ↔ v = 0 := by + rw [eq_comm, self_eq_neg R M] + +theorem self_ne_neg + (R) (M) [Semiring R] [CharZero R] [AddCommGroup M] [Module R M] [NoZeroSMulDivisors R M] + {v : M} : v ≠ -v ↔ v ≠ 0 := + (self_eq_neg R M).not + +theorem neg_ne_self + (R) (M) [Semiring R] [CharZero R] [AddCommGroup M] [Module R M] [NoZeroSMulDivisors R M] + {v : M} : -v ≠ v ↔ v ≠ 0 := + (neg_eq_self R M).not + +end Nat + +end AddCommGroup + +section Module + +variable [Ring R] [AddCommGroup M] [Module R M] + +section SMulInjective + +variable (R) +variable [NoZeroSMulDivisors R M] + +theorem smul_left_injective {x : M} (hx : x ≠ 0) : Function.Injective fun c : R => c • x := + fun c d h => + sub_eq_zero.mp + ((smul_eq_zero.mp + (calc + (c - d) • x = c • x - d • x := sub_smul c d x + _ = 0 := sub_eq_zero.mpr h + )).resolve_right + hx) + +end SMulInjective + +instance [NoZeroSMulDivisors ℤ M] : NoZeroSMulDivisors ℕ M := + ⟨fun {c x} hcx ↦ by rwa [← Nat.cast_smul_eq_nsmul ℤ, smul_eq_zero, Nat.cast_eq_zero] at hcx⟩ + +variable (R M) + +theorem NoZeroSMulDivisors.int_of_charZero + (R) (M) [Ring R] [AddCommGroup M] [Module R M] [NoZeroSMulDivisors R M] [CharZero R] : + NoZeroSMulDivisors ℤ M := + ⟨fun {z x} h ↦ by simpa [← smul_one_smul R z x] using h⟩ + +/-- Only a ring of characteristic zero can have a non-trivial module without additive or +scalar torsion. -/ +theorem CharZero.of_noZeroSMulDivisors [Nontrivial M] [NoZeroSMulDivisors ℤ M] : CharZero R := by + refine ⟨fun {n m h} ↦ ?_⟩ + obtain ⟨x, hx⟩ := exists_ne (0 : M) + replace h : (n : ℤ) • x = (m : ℤ) • x := by simp [← Nat.cast_smul_eq_nsmul R, h] + simpa using smul_left_injective ℤ hx h + +instance [AddCommGroup M] [NoZeroSMulDivisors ℤ M] : NoZeroSMulDivisors ℕ M := + ⟨fun {c x} hcx ↦ by rwa [← Nat.cast_smul_eq_nsmul ℤ c x, smul_eq_zero, Nat.cast_eq_zero] at hcx⟩ + +end Module + +section GroupWithZero + +variable [GroupWithZero R] [AddMonoid M] [DistribMulAction R M] + +-- see note [lower instance priority] +/-- This instance applies to `DivisionSemiring`s, in particular `NNReal` and `NNRat`. -/ +instance (priority := 100) GroupWithZero.toNoZeroSMulDivisors : NoZeroSMulDivisors R M := + ⟨fun {a _} h ↦ or_iff_not_imp_left.2 fun ha ↦ (smul_eq_zero_iff_eq <| Units.mk0 a ha).1 h⟩ + +end GroupWithZero + +end NoZeroSMulDivisors diff --git a/Mathlib/Algebra/NoZeroSMulDivisors/Defs.lean b/Mathlib/Algebra/NoZeroSMulDivisors/Defs.lean new file mode 100644 index 00000000000000..caa70e20f08e3d --- /dev/null +++ b/Mathlib/Algebra/NoZeroSMulDivisors/Defs.lean @@ -0,0 +1,78 @@ +/- +Copyright (c) 2015 Nathaniel Thomas. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Anne Baanen, Yury Kudryashov, Joseph Myers, Heather Macbeth, Kim Morrison, Yaël Dillies +-/ +import Mathlib.Algebra.SMulWithZero + +/-! +# `NoZeroSMulDivisors` + +This file defines the `NoZeroSMulDivisors` class, and includes some tests +for the vanishing of elements (especially in modules over division rings). +-/ + +assert_not_exists Multiset +assert_not_exists Set.indicator +assert_not_exists Pi.single_smul₀ +assert_not_exists Field +assert_not_exists Module + +section NoZeroSMulDivisors + +/-! ### `NoZeroSMulDivisors` + +-/ + +variable {R M : Type*} + +/-- `NoZeroSMulDivisors R M` states that a scalar multiple is `0` only if either argument is `0`. +This is a version of saying that `M` is torsion free, without assuming `R` is zero-divisor free. + +The main application of `NoZeroSMulDivisors R M`, when `M` is a module, +is the result `smul_eq_zero`: a scalar multiple is `0` iff either argument is `0`. + +It is a generalization of the `NoZeroDivisors` class to heterogeneous multiplication. +-/ +@[mk_iff] +class NoZeroSMulDivisors (R M : Type*) [Zero R] [Zero M] [SMul R M] : Prop where + /-- If scalar multiplication yields zero, either the scalar or the vector was zero. -/ + eq_zero_or_eq_zero_of_smul_eq_zero : ∀ {c : R} {x : M}, c • x = 0 → c = 0 ∨ x = 0 + +export NoZeroSMulDivisors (eq_zero_or_eq_zero_of_smul_eq_zero) + +/-- Pullback a `NoZeroSMulDivisors` instance along an injective function. -/ +theorem Function.Injective.noZeroSMulDivisors {R M N : Type*} [Zero R] [Zero M] [Zero N] + [SMul R M] [SMul R N] [NoZeroSMulDivisors R N] (f : M → N) (hf : Function.Injective f) + (h0 : f 0 = 0) (hs : ∀ (c : R) (x : M), f (c • x) = c • f x) : NoZeroSMulDivisors R M := + ⟨fun {_ _} h => + Or.imp_right (@hf _ _) <| h0.symm ▸ eq_zero_or_eq_zero_of_smul_eq_zero (by rw [← hs, h, h0])⟩ + +-- See note [lower instance priority] +instance (priority := 100) NoZeroDivisors.toNoZeroSMulDivisors [Zero R] [Mul R] + [NoZeroDivisors R] : NoZeroSMulDivisors R R := + ⟨fun {_ _} => eq_zero_or_eq_zero_of_mul_eq_zero⟩ + +theorem smul_ne_zero [Zero R] [Zero M] [SMul R M] [NoZeroSMulDivisors R M] {c : R} {x : M} + (hc : c ≠ 0) (hx : x ≠ 0) : c • x ≠ 0 := fun h => + (eq_zero_or_eq_zero_of_smul_eq_zero h).elim hc hx + +section SMulWithZero + +variable [Zero R] [Zero M] [SMulWithZero R M] [NoZeroSMulDivisors R M] {c : R} {x : M} + +@[simp] +theorem smul_eq_zero : c • x = 0 ↔ c = 0 ∨ x = 0 := + ⟨eq_zero_or_eq_zero_of_smul_eq_zero, fun h => + h.elim (fun h => h.symm ▸ zero_smul R x) fun h => h.symm ▸ smul_zero c⟩ + +theorem smul_ne_zero_iff : c • x ≠ 0 ↔ c ≠ 0 ∧ x ≠ 0 := by rw [Ne, smul_eq_zero, not_or] + +lemma smul_eq_zero_iff_left (hx : x ≠ 0) : c • x = 0 ↔ c = 0 := by simp [hx] +lemma smul_eq_zero_iff_right (hc : c ≠ 0) : c • x = 0 ↔ x = 0 := by simp [hc] +lemma smul_ne_zero_iff_left (hx : x ≠ 0) : c • x ≠ 0 ↔ c ≠ 0 := by simp [hx] +lemma smul_ne_zero_iff_right (hc : c ≠ 0) : c • x ≠ 0 ↔ x ≠ 0 := by simp [hc] + +end SMulWithZero + +end NoZeroSMulDivisors diff --git a/Mathlib/Algebra/NoZeroSMulDivisors/Pi.lean b/Mathlib/Algebra/NoZeroSMulDivisors/Pi.lean new file mode 100644 index 00000000000000..ac7b42a019040f --- /dev/null +++ b/Mathlib/Algebra/NoZeroSMulDivisors/Pi.lean @@ -0,0 +1,34 @@ +/- +Copyright (c) 2018 Simon Hudon. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Anne Baanen, Yaël Dillies +-/ +import Mathlib.Algebra.NoZeroSMulDivisors.Defs +import Mathlib.Algebra.Group.Action.Pi + +/-! +# Pi instances for NoZeroSMulDivisors + +This file defines instances for NoZeroSMulDivisors on Pi types. +-/ + + +universe u v + +variable {I : Type u} + +-- The indexing type +variable {f : I → Type v} + +instance Pi.noZeroSMulDivisors (α) [Zero α] [∀ i, Zero <| f i] + [∀ i, SMulWithZero α <| f i] [∀ i, NoZeroSMulDivisors α <| f i] : + NoZeroSMulDivisors α (∀ i : I, f i) := + ⟨fun {_ _} h => + or_iff_not_imp_left.mpr fun hc => + funext fun i => (smul_eq_zero.mp (congr_fun h i)).resolve_left hc⟩ + +/-- A special case of `Pi.noZeroSMulDivisors` for non-dependent types. Lean struggles to +synthesize this instance by itself elsewhere in the library. -/ +instance _root_.Function.noZeroSMulDivisors {ι α β : Type*} [Zero α] [Zero β] + [SMulWithZero α β] [NoZeroSMulDivisors α β] : NoZeroSMulDivisors α (ι → β) := + Pi.noZeroSMulDivisors _ diff --git a/Mathlib/Algebra/NoZeroSMulDivisors/Prod.lean b/Mathlib/Algebra/NoZeroSMulDivisors/Prod.lean new file mode 100644 index 00000000000000..e836979c0377a0 --- /dev/null +++ b/Mathlib/Algebra/NoZeroSMulDivisors/Prod.lean @@ -0,0 +1,32 @@ +/- +Copyright (c) 2018 Simon Hudon. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Anne Baanen +-/ +import Mathlib.Algebra.NoZeroSMulDivisors.Defs +import Mathlib.Algebra.Group.Action.Prod + +/-! +# Prod instances for NoZeroSMulDivisors + +This file defines a NoZeroSMulDivisors instance for the binary product of actions. +-/ + +variable {R M N : Type*} + +namespace Prod + +instance noZeroSMulDivisors [Zero R] [Zero M] [Zero N] + [SMulWithZero R M] [SMulWithZero R N] [NoZeroSMulDivisors R M] [NoZeroSMulDivisors R N] : + NoZeroSMulDivisors R (M × N) := + { eq_zero_or_eq_zero_of_smul_eq_zero := by -- Porting note: in mathlib3 there is no need for `by`/ + -- `intro`/`exact`, i.e. the following works: + -- ⟨fun c ⟨x, y⟩ h => + -- or_iff_not_imp_left.mpr fun hc => + intro c ⟨x, y⟩ h + exact or_iff_not_imp_left.mpr fun hc => + mk.inj_iff.mpr + ⟨(smul_eq_zero.mp (congr_arg fst h)).resolve_left hc, + (smul_eq_zero.mp (congr_arg snd h)).resolve_left hc⟩ } + +end Prod diff --git a/Mathlib/Algebra/Order/Module/Defs.lean b/Mathlib/Algebra/Order/Module/Defs.lean index 8323669b294347..a1172e5a8524da 100644 --- a/Mathlib/Algebra/Order/Module/Defs.lean +++ b/Mathlib/Algebra/Order/Module/Defs.lean @@ -3,7 +3,7 @@ Copyright (c) 2023 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.Module.Defs +import Mathlib.Algebra.NoZeroSMulDivisors.Basic import Mathlib.Algebra.Order.Field.Defs import Mathlib.Algebra.Order.GroupWithZero.Action.Synonym import Mathlib.Tactic.GCongr diff --git a/Mathlib/Algebra/Order/Star/Basic.lean b/Mathlib/Algebra/Order/Star/Basic.lean index 6370c2c91944e5..6df890e8638a3c 100644 --- a/Mathlib/Algebra/Order/Star/Basic.lean +++ b/Mathlib/Algebra/Order/Star/Basic.lean @@ -3,6 +3,7 @@ Copyright (c) 2023 Kim Morrison. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Kim Morrison -/ +import Mathlib.Algebra.NoZeroSMulDivisors.Defs import Mathlib.Algebra.Order.Group.Defs import Mathlib.Algebra.Order.Group.Nat import Mathlib.Algebra.Star.SelfAdjoint diff --git a/Mathlib/Data/ENNReal/Operations.lean b/Mathlib/Data/ENNReal/Operations.lean index 473c3d6c65d78d..26c974025ccf6d 100644 --- a/Mathlib/Data/ENNReal/Operations.lean +++ b/Mathlib/Data/ENNReal/Operations.lean @@ -5,7 +5,6 @@ Authors: Johannes Hölzl, Yury Kudryashov -/ import Mathlib.Algebra.BigOperators.WithTop import Mathlib.Algebra.GroupWithZero.Divisibility -import Mathlib.Algebra.Module.Basic import Mathlib.Data.ENNReal.Basic /-! diff --git a/Mathlib/Data/Set/Pointwise/SMul.lean b/Mathlib/Data/Set/Pointwise/SMul.lean index 9e6917fe0172c9..bd562b3fb02ad2 100644 --- a/Mathlib/Data/Set/Pointwise/SMul.lean +++ b/Mathlib/Data/Set/Pointwise/SMul.lean @@ -7,6 +7,7 @@ import Mathlib.Algebra.Group.Pi.Basic import Mathlib.Algebra.Group.Pointwise.Set.Basic import Mathlib.Algebra.GroupWithZero.Action.Basic import Mathlib.Algebra.Module.Defs +import Mathlib.Algebra.NoZeroSMulDivisors.Defs import Mathlib.Data.Set.Pairwise.Basic /-! diff --git a/Mathlib/GroupTheory/Subgroup/Saturated.lean b/Mathlib/GroupTheory/Subgroup/Saturated.lean index 1d7d366b914ad7..6cbc7b2c45d712 100644 --- a/Mathlib/GroupTheory/Subgroup/Saturated.lean +++ b/Mathlib/GroupTheory/Subgroup/Saturated.lean @@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Johan Commelin -/ import Mathlib.Algebra.Group.Subgroup.Basic -import Mathlib.Algebra.Module.Defs +import Mathlib.Algebra.NoZeroSMulDivisors.Defs /-! # Saturated subgroups diff --git a/Mathlib/LinearAlgebra/BilinearMap.lean b/Mathlib/LinearAlgebra/BilinearMap.lean index 0430d8a20645b6..c720aff5ff9b63 100644 --- a/Mathlib/LinearAlgebra/BilinearMap.lean +++ b/Mathlib/LinearAlgebra/BilinearMap.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Kenny Lau, Mario Carneiro -/ import Mathlib.Algebra.Module.Submodule.Ker +import Mathlib.Algebra.NoZeroSMulDivisors.Basic /-! # Basics on bilinear maps diff --git a/Mathlib/LinearAlgebra/LinearPMap.lean b/Mathlib/LinearAlgebra/LinearPMap.lean index ff0ddc27cc274a..6cc05feeabb399 100644 --- a/Mathlib/LinearAlgebra/LinearPMap.lean +++ b/Mathlib/LinearAlgebra/LinearPMap.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Yury Kudryashov, Moritz Doll -/ import Mathlib.LinearAlgebra.Prod -import Mathlib.Algebra.Module.Basic /-! # Partially defined linear maps diff --git a/Mathlib/LinearAlgebra/Multilinear/Basic.lean b/Mathlib/LinearAlgebra/Multilinear/Basic.lean index 8db7f46936b451..ea1242276149da 100644 --- a/Mathlib/LinearAlgebra/Multilinear/Basic.lean +++ b/Mathlib/LinearAlgebra/Multilinear/Basic.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Sébastien Gouëzel -/ import Mathlib.Algebra.Algebra.Defs +import Mathlib.Algebra.NoZeroSMulDivisors.Pi import Mathlib.Algebra.Order.BigOperators.Group.Finset import Mathlib.Data.Fintype.BigOperators import Mathlib.Data.Fintype.Sort diff --git a/Mathlib/LinearAlgebra/Span.lean b/Mathlib/LinearAlgebra/Span.lean index 8e873cfc1c5336..478735c1391253 100644 --- a/Mathlib/LinearAlgebra/Span.lean +++ b/Mathlib/LinearAlgebra/Span.lean @@ -8,6 +8,7 @@ import Mathlib.Algebra.Module.Prod import Mathlib.Algebra.Module.Submodule.EqLocus import Mathlib.Algebra.Module.Submodule.Equiv import Mathlib.Algebra.Module.Submodule.RestrictScalars +import Mathlib.Algebra.NoZeroSMulDivisors.Basic import Mathlib.Algebra.Ring.Idempotents import Mathlib.Data.Set.Pointwise.SMul import Mathlib.Order.CompactlyGenerated.Basic diff --git a/Mathlib/RingTheory/Nilpotent/Basic.lean b/Mathlib/RingTheory/Nilpotent/Basic.lean index 71e196c394db9b..9eddb6417010ad 100644 --- a/Mathlib/RingTheory/Nilpotent/Basic.lean +++ b/Mathlib/RingTheory/Nilpotent/Basic.lean @@ -7,7 +7,7 @@ import Mathlib.Algebra.Associated.Basic import Mathlib.Algebra.GeomSum import Mathlib.Algebra.Group.Action.Prod import Mathlib.Algebra.GroupWithZero.NonZeroDivisors -import Mathlib.Algebra.Module.Defs +import Mathlib.Algebra.NoZeroSMulDivisors.Defs import Mathlib.Algebra.SMulWithZero import Mathlib.Data.Nat.Choose.Sum import Mathlib.Data.Nat.Lattice From 418a5eb7aec3fb639097cb13f74fc031ac4057f2 Mon Sep 17 00:00:00 2001 From: Anne Baanen Date: Sat, 19 Oct 2024 07:30:34 +0000 Subject: [PATCH 416/425] chore: remove CoeFun instances where FunLike is available (#17911) During the port we found that `FunLike` is robust enough not to need an extra `CoeFun` shortcut. Let's see if that rule can be consistently applied to the whole of the library. There is still duplication between `FunLike` and `CoeFun` for `Grp`, `Mon`, `CommGrp` and `CommMon`, which will need a more thorough fix. See also #17866. I am currently bisecting to figure out exactly why the benchmarks are indicating a slowdown with no obvious cause. --- Mathlib/Algebra/Order/AbsoluteValue.lean | 5 ----- Mathlib/Algebra/Ring/CentroidHom.lean | 7 ------- .../Analysis/Distribution/SchwartzSpace.lean | 4 ---- Mathlib/Analysis/Normed/Algebra/Norm.lean | 8 ------- Mathlib/Analysis/Normed/Group/Seminorm.lean | 21 ------------------- 5 files changed, 45 deletions(-) diff --git a/Mathlib/Algebra/Order/AbsoluteValue.lean b/Mathlib/Algebra/Order/AbsoluteValue.lean index 0dcc6acdcfbb4e..fae16b0ffcd6d7 100644 --- a/Mathlib/Algebra/Order/AbsoluteValue.lean +++ b/Mathlib/Algebra/Order/AbsoluteValue.lean @@ -77,11 +77,6 @@ def Simps.apply (f : AbsoluteValue R S) : R → S := initialize_simps_projections AbsoluteValue (toMulHom_toFun → apply) -/-- Helper instance for when there's too many metavariables to apply `DFunLike.has_coe_to_fun` -directly. -/ -instance : CoeFun (AbsoluteValue R S) fun _ => R → S := - DFunLike.hasCoeToFun - @[simp] theorem coe_toMulHom : ⇑abv.toMulHom = abv := rfl diff --git a/Mathlib/Algebra/Ring/CentroidHom.lean b/Mathlib/Algebra/Ring/CentroidHom.lean index 37a70431efb16b..b1b90bb34b9d18 100644 --- a/Mathlib/Algebra/Ring/CentroidHom.lean +++ b/Mathlib/Algebra/Ring/CentroidHom.lean @@ -102,13 +102,6 @@ instance : CentroidHomClass (CentroidHom α) α where map_mul_right f := f.map_mul_right' -/-- Helper instance for when there's too many metavariables to apply `DFunLike.CoeFun` -directly. -/ -/- Porting note: Lean gave me `unknown constant 'DFunLike.CoeFun'` and says `CoeFun` is a type -mismatch, so I used `library_search`. -/ -instance : CoeFun (CentroidHom α) fun _ ↦ α → α := - inferInstanceAs (CoeFun (CentroidHom α) fun _ ↦ α → α) - -- Porting note: removed @[simp]; not in normal form. (`toAddMonoidHom_eq_coe` below ensures that -- the LHS simplifies to the RHS anyway.) theorem toFun_eq_coe {f : CentroidHom α} : f.toFun = f := rfl diff --git a/Mathlib/Analysis/Distribution/SchwartzSpace.lean b/Mathlib/Analysis/Distribution/SchwartzSpace.lean index ba8aae073aff97..a9cd6e02b3fbe9 100644 --- a/Mathlib/Analysis/Distribution/SchwartzSpace.lean +++ b/Mathlib/Analysis/Distribution/SchwartzSpace.lean @@ -90,10 +90,6 @@ instance instFunLike : FunLike 𝓢(E, F) E F where coe f := f.toFun coe_injective' f g h := by cases f; cases g; congr -/-- Helper instance for when there's too many metavariables to apply `DFunLike.hasCoeToFun`. -/ -instance instCoeFun : CoeFun 𝓢(E, F) fun _ => E → F := - DFunLike.hasCoeToFun - /-- All derivatives of a Schwartz function are rapidly decaying. -/ theorem decay (f : 𝓢(E, F)) (k n : ℕ) : ∃ C : ℝ, 0 < C ∧ ∀ x, ‖x‖ ^ k * ‖iteratedFDeriv ℝ n f x‖ ≤ C := by diff --git a/Mathlib/Analysis/Normed/Algebra/Norm.lean b/Mathlib/Analysis/Normed/Algebra/Norm.lean index eb815ac91298e0..715ad8694cf6fe 100644 --- a/Mathlib/Analysis/Normed/Algebra/Norm.lean +++ b/Mathlib/Analysis/Normed/Algebra/Norm.lean @@ -70,10 +70,6 @@ instance algebraNormClass : AlgebraNormClass (AlgebraNorm R S) R S where eq_zero_of_map_eq_zero f := f.eq_zero_of_map_eq_zero' _ map_smul_eq_mul f := f.smul' -/-- Helper instance for when there's too many metavariables to apply `fun_like.has_coe_to_fun`. -/ -instance : CoeFun (AlgebraNorm R S) fun _ => S → ℝ := - DFunLike.hasCoeToFun - theorem toFun_eq_coe (p : AlgebraNorm R S) : p.toFun = p := rfl @[ext] @@ -160,10 +156,6 @@ instance mulAlgebraNormClass : MulAlgebraNormClass (MulAlgebraNorm R S) R S wher eq_zero_of_map_eq_zero f := f.eq_zero_of_map_eq_zero' _ map_smul_eq_mul f := f.smul' -/-- Helper instance for when there's too many metavariables to apply `fun_like.has_coe_to_fun`. -/ -instance : CoeFun (MulAlgebraNorm R S) fun _ => S → ℝ := - DFunLike.hasCoeToFun - theorem toFun_eq_coe (p : MulAlgebraNorm R S) : p.toFun = p := rfl @[ext] diff --git a/Mathlib/Analysis/Normed/Group/Seminorm.lean b/Mathlib/Analysis/Normed/Group/Seminorm.lean index eede911fb046db..a8d9220ba89cc6 100644 --- a/Mathlib/Analysis/Normed/Group/Seminorm.lean +++ b/Mathlib/Analysis/Normed/Group/Seminorm.lean @@ -181,12 +181,6 @@ instance groupSeminormClass : GroupSeminormClass (GroupSeminorm E) E ℝ where map_mul_le_add f := f.mul_le' map_inv_eq_map f := f.inv' -/-- Helper instance for when there's too many metavariables to apply `DFunLike.hasCoeToFun`. -/ -@[to_additive "Helper instance for when there's too many metavariables to apply -`DFunLike.hasCoeToFun`. "] -instance : CoeFun (GroupSeminorm E) fun _ => E → ℝ := - ⟨DFunLike.coe⟩ - @[to_additive (attr := simp)] theorem toFun_eq_coe : p.toFun = p := rfl @@ -447,10 +441,6 @@ instance nonarchAddGroupSeminormClass : map_zero f := f.map_zero' map_neg_eq_map' f := f.neg' -/-- Helper instance for when there's too many metavariables to apply `DFunLike.hasCoeToFun`. -/ -instance : CoeFun (NonarchAddGroupSeminorm E) fun _ => E → ℝ := - ⟨DFunLike.coe⟩ - -- Porting note: `simpNF` said the left hand side simplified to this @[simp] theorem toZeroHom_eq_coe : ⇑p.toZeroHom = p := by @@ -667,13 +657,6 @@ instance groupNormClass : GroupNormClass (GroupNorm E) E ℝ where map_inv_eq_map f := f.inv' eq_one_of_map_eq_zero f := f.eq_one_of_map_eq_zero' _ -/-- Helper instance for when there's too many metavariables to apply `DFunLike.hasCoeToFun` -directly. -/ -@[to_additive "Helper instance for when there's too many metavariables to apply -`DFunLike.hasCoeToFun` directly. "] -instance : CoeFun (GroupNorm E) fun _ => E → ℝ := - DFunLike.hasCoeToFun - -- Porting note: `simpNF` told me the left-hand side simplified to this @[to_additive (attr := simp)] theorem toGroupSeminorm_eq_coe : ⇑p.toGroupSeminorm = p := @@ -799,10 +782,6 @@ instance nonarchAddGroupNormClass : NonarchAddGroupNormClass (NonarchAddGroupNor map_neg_eq_map' f := f.neg' eq_zero_of_map_eq_zero f := f.eq_zero_of_map_eq_zero' _ -/-- Helper instance for when there's too many metavariables to apply `DFunLike.hasCoeToFun`. -/ -noncomputable instance : CoeFun (NonarchAddGroupNorm E) fun _ => E → ℝ := - DFunLike.hasCoeToFun - -- Porting note: `simpNF` told me the left-hand side simplified to this @[simp] theorem toNonarchAddGroupSeminorm_eq_coe : ⇑p.toNonarchAddGroupSeminorm = p := From 293a152f7a0903b04859797ed3c88f7eaac5f8fd Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Sat, 19 Oct 2024 18:31:55 +1100 Subject: [PATCH 417/425] fix tests --- test/Check.lean | 1 + test/FlexibleLinter.lean | 1 + test/dfinsupp_notation.lean | 8 +++++++- test/finsupp_notation.lean | 8 ++++++-- test/interval_cases.lean | 1 + test/itauto.lean | 1 + test/meta.lean | 1 + test/norm_cast.lean | 1 + test/push_neg.lean | 4 ++++ 9 files changed, 23 insertions(+), 3 deletions(-) diff --git a/test/Check.lean b/test/Check.lean index baa5c95f009a56..911e8359858fad 100644 --- a/test/Check.lean +++ b/test/Check.lean @@ -7,6 +7,7 @@ open Lean PrettyPrinter Delaborator in @[delab mvar] def delabMVar : Delab := do `(?m) set_option linter.unusedTactic false +set_option linter.unusedVariables false /-! Basic check of `#check` diff --git a/test/FlexibleLinter.lean b/test/FlexibleLinter.lean index d6d26d250e223d..eefecf28fe69af 100644 --- a/test/FlexibleLinter.lean +++ b/test/FlexibleLinter.lean @@ -4,6 +4,7 @@ import Mathlib.Tactic.Abel import Mathlib.Tactic.Ring set_option linter.flexible true +set_option linter.unusedVariables false /-- warning: 'simp at h' is a flexible tactic modifying 'h'… diff --git a/test/dfinsupp_notation.lean b/test/dfinsupp_notation.lean index afea3446c21f0c..1f41769bef643a 100644 --- a/test/dfinsupp_notation.lean +++ b/test/dfinsupp_notation.lean @@ -7,6 +7,7 @@ example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4 : Π₀ i, Fin (i + 10)) 1 = 3 := by example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4 : Π₀ i, Fin (i + 10)) 2 = 3 := by simp example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4 : Π₀ i, Fin (i + 10)) 3 = 4 := by simp +/-- info: fun₀ | 1 => 3 | 2 => 3 : Π₀ (i : ℕ), Fin (i + 10) -/ #guard_msgs in #check (fun₀ | 1 => 3 | 2 => 3 : Π₀ i, Fin (i + 10)) @@ -14,13 +15,18 @@ example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4 : Π₀ i, Fin (i + 10)) 3 = 4 := by #guard_msgs in #eval ((fun₀ | 1 => 3 | 2 => 3) + (fun₀ | 1 => -3 | 2 => 4) : Π₀ _, ℤ) +/-- +info: fun₀ + | ["there are five words here", "and five more words here"] => 5 + | ["there are seven words but only here"] => 7 + | ["just two"] => 2 +-/ #guard_msgs in #eval (fun₀ | ["there are five words here", "and five more words here"] => 5 | ["there are seven words but only here"] => 7 | ["just two"] => 2 : Π₀ _ : List String, ℕ) -end Repr section PrettyPrinter /-- diff --git a/test/finsupp_notation.lean b/test/finsupp_notation.lean index 84b4d5ca078c18..d636fa3d7e7508 100644 --- a/test/finsupp_notation.lean +++ b/test/finsupp_notation.lean @@ -12,6 +12,12 @@ example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4) 2 = 3 := by example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4) 3 = 4 := by simp +/-- +info: fun₀ + | ["there are five words here", "and five more words here"] => 5 + | ["there are seven words but only here"] => 7 + | ["just two"] => 2 +-/ #guard_msgs in #eval Finsupp.mk {["there are five words here", "and five more words here"], @@ -24,8 +30,6 @@ example : (fun₀ | 1 | 2 | 3 => 3 | 3 => 4) 3 = 4 := by | _ => 0) (fun x => by aesop) -end repr - section PrettyPrinter /-- diff --git a/test/interval_cases.lean b/test/interval_cases.lean index 02cbfc56c324a2..646186f2ecf27f 100644 --- a/test/interval_cases.lean +++ b/test/interval_cases.lean @@ -7,6 +7,7 @@ Authors: Kim Morrison import Mathlib.Tactic.IntervalCases import Mathlib.Tactic.Set +set_option linter.unusedVariables false in example (n : ℕ) : True := by fail_if_success interval_cases n trivial diff --git a/test/itauto.lean b/test/itauto.lean index 94353f251dd304..032b78ab997556 100644 --- a/test/itauto.lean +++ b/test/itauto.lean @@ -55,6 +55,7 @@ example (b : Bool) : ¬b ∨ b := by itauto * example (p : Prop) : ¬p ∨ p := by itauto! [p] example (p : Prop) : ¬p ∨ p := by itauto! * +set_option linter.unusedVariables false in set_option linter.unusedTactic false in -- failure tests example (p q r : Prop) : True := by diff --git a/test/meta.lean b/test/meta.lean index 3d5620d3af41cb..a32d282f8922ba 100644 --- a/test/meta.lean +++ b/test/meta.lean @@ -61,6 +61,7 @@ elab "test_forallNot_of_notExists" t:term : tactic => do logInfo m!"{ety'}" set_option linter.unusedTactic false +set_option linter.unusedVariables false /-- info: ∀ (x : Nat), ¬0 < x -/ #guard_msgs in diff --git a/test/norm_cast.lean b/test/norm_cast.lean index 8c6392c40afc21..cb792593c1ef5a 100644 --- a/test/norm_cast.lean +++ b/test/norm_cast.lean @@ -9,6 +9,7 @@ import Mathlib.Data.ENNReal.Inv -- set_option trace.Tactic.norm_cast true -- set_option trace.Meta.Tactic.simp true set_option autoImplicit true +set_option linter.unusedVariables false variable (an bn cn dn : ℕ) (az bz cz dz : ℤ) variable (aq bq cq dq : ℚ) diff --git a/test/push_neg.lean b/test/push_neg.lean index 57750f1fca76e1..571b3a5f85cab0 100644 --- a/test/push_neg.lean +++ b/test/push_neg.lean @@ -80,6 +80,7 @@ example (x y : β) (h : y < x) : ¬¬¬ (x ≤ y) := by guard_target = y < x exact h +set_option linter.unusedVariables false in example (x y : β) (h₁ : ¬¬¬(x < y)) (h₂ : ¬∃ (x y : Nat), x = y) : ¬ ∀(x y : Nat), x = y := by push_neg at * guard_target = ∃ (x y : Nat), x ≠ y @@ -87,6 +88,7 @@ example (x y : β) (h₁ : ¬¬¬(x < y)) (h₂ : ¬∃ (x y : Nat), x = y) : ¬ guard_hyp h₂ : ∀ (x y : Nat), x ≠ y exact ⟨0, 1, by simp⟩ +set_option linter.unusedVariables false in example (x y : β) (h₁ : ¬¬¬(x < y)) (h₂ : ¬∃ (x y : Nat), x = y) : ¬ ∀(x y : Nat), x = y := by push_neg at h₁ h₂ ⊢ guard_target = ∃ (x y : Nat), x ≠ y @@ -104,11 +106,13 @@ example (a : β) : ¬ ∀ x : β, x < a → ∃ y : β, (y < a) ∧ ∀ z : β, guard_target = ∃ x, x < a ∧ ∀ (y : β), y < a → ∃ z, x ≠ z exact test_sorry +set_option linter.unusedVariables false in example {α} [Preorder α] (m n : α) (h : ¬(∃ k : α, m ≤ k)) (h₂ : m ≤ n) : m ≤ n := by push_neg at h guard_hyp h : ∀ k, ¬(m ≤ k) exact h₂ +set_option linter.unusedVariables false in example {α} [Preorder α] (m n : α) (h : ¬(∃ k : α, m < k)) (h₂ : m ≤ n) : m ≤ n := by push_neg at h guard_hyp h : ∀ k, ¬(m < k) From 26e90a66fc52dea7f28b2c9b74324fa4f0eebdf8 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Sat, 19 Oct 2024 18:40:59 +1100 Subject: [PATCH 418/425] fix tests --- test/Clear!.lean | 2 ++ test/ClearExcept.lean | 1 + test/ExtractLets.lean | 2 ++ test/LibrarySearch/observe.lean | 3 +++ test/congr.lean | 1 + test/fin_cases.lean | 1 + test/propose.lean | 1 + 7 files changed, 11 insertions(+) diff --git a/test/Clear!.lean b/test/Clear!.lean index cf2817c2edc179..d872581a51c338 100644 --- a/test/Clear!.lean +++ b/test/Clear!.lean @@ -1,5 +1,7 @@ import Mathlib.Tactic.ClearExclamation +set_option linter.unusedVariables false + -- Most basic test example (delete_this : Nat) (_delete_this_dep : delete_this = delete_this) : Nat := by clear! delete_this diff --git a/test/ClearExcept.lean b/test/ClearExcept.lean index 63bdec1685482c..4b870154d520ea 100644 --- a/test/ClearExcept.lean +++ b/test/ClearExcept.lean @@ -1,6 +1,7 @@ import Mathlib.Tactic.ClearExcept set_option linter.unusedTactic false +set_option linter.unusedVariables false -- Most basic test example (_delete_this : Nat) (dont_delete_this : Int) : Nat := by diff --git a/test/ExtractLets.lean b/test/ExtractLets.lean index b2ff5f1b6ecb4b..b4935990cd6ea3 100644 --- a/test/ExtractLets.lean +++ b/test/ExtractLets.lean @@ -1,5 +1,7 @@ import Mathlib.Tactic.ExtractLets +set_option linter.unusedVariables false + example (h : let x := 1; x = x) : True := by extract_lets y at h fail_if_success extract_lets a at h diff --git a/test/LibrarySearch/observe.lean b/test/LibrarySearch/observe.lean index 91428e1247ad77..dba1f58608cea1 100644 --- a/test/LibrarySearch/observe.lean +++ b/test/LibrarySearch/observe.lean @@ -1,4 +1,7 @@ import Mathlib.Tactic.Observe + +set_option linter.unusedVariables false + /-- info: Try this: have h : x + y = y + x := Nat.add_comm x y -/ #guard_msgs in example (x y : Nat) : True := by diff --git a/test/congr.lean b/test/congr.lean index d1e2254a6dd4a7..ee818a9ff7f32b 100644 --- a/test/congr.lean +++ b/test/congr.lean @@ -233,6 +233,7 @@ example {α β} {F : _ → β} {f g : {f : α → β // f = f}} ext x apply h +set_option linter.unusedVariables false in example {ls : List ℕ} : ls.map (fun x => (ls.map (fun y => 1 + y)).sum + 1) = ls.map (fun x => (ls.map (fun y => Nat.succ y)).sum + 1) := by diff --git a/test/fin_cases.lean b/test/fin_cases.lean index dbf7c0cdcafc66..f409e3cb8df915 100644 --- a/test/fin_cases.lean +++ b/test/fin_cases.lean @@ -41,6 +41,7 @@ example (p : ℕ) (h2 : 2 < p) (h5 : p < 5) : p = 3 ∨ p = 4 := by -- TODO Restore the remaining tests from mathlib3: -- Some of these test the `with` and `using` clauses which haven't been re-implemented. +set_option linter.unusedVariables false in example (x2 : Fin 2) (x3 : Fin 3) (n : Nat) (y : Fin n) : x2.val * x3.val = x3.val * x2.val := by fin_cases x2 <;> fin_cases x3 fail_if_success diff --git a/test/propose.lean b/test/propose.lean index 04d97bb804156d..9fb6910a4bd4a2 100644 --- a/test/propose.lean +++ b/test/propose.lean @@ -8,6 +8,7 @@ import Batteries.Data.List.Lemmas -- set_option trace.Tactic.propose true -- set_option trace.Meta.Tactic.solveByElim true set_option autoImplicit true +set_option linter.unusedVariables false theorem foo (L M : List α) (w : L.Disjoint M) (m : a ∈ L) : a ∉ M := fun h => w m h From 66f63643834286e06540e60e459b22c7bbd25475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20G=2E=20Dorais?= Date: Sat, 19 Oct 2024 08:15:11 +0000 Subject: [PATCH 419/425] chore: move trans tactic to Batteries (batteries#1001) (#17931) Co-authored-by: F. G. Dorais --- Mathlib.lean | 1 - Mathlib/Algebra/Notation.lean | 1 + Mathlib/Order/Defs.lean | 2 +- Mathlib/Tactic.lean | 1 - Mathlib/Tactic/Common.lean | 1 - Mathlib/Tactic/MoveAdd.lean | 1 + Mathlib/Tactic/Relation/Trans.lean | 222 ------------------------ Mathlib/Tactic/ToAdditive/Frontend.lean | 4 +- Mathlib/Tactic/Widget/CongrM.lean | 1 + lake-manifest.json | 2 +- scripts/noshake.json | 2 +- test/trans.lean | 109 ------------ 12 files changed, 8 insertions(+), 339 deletions(-) delete mode 100644 Mathlib/Tactic/Relation/Trans.lean delete mode 100644 test/trans.lean diff --git a/Mathlib.lean b/Mathlib.lean index 66e48c38b8ae0d..e24762ba7699b7 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -4447,7 +4447,6 @@ import Mathlib.Tactic.ReduceModChar import Mathlib.Tactic.ReduceModChar.Ext import Mathlib.Tactic.Relation.Rfl import Mathlib.Tactic.Relation.Symm -import Mathlib.Tactic.Relation.Trans import Mathlib.Tactic.Rename import Mathlib.Tactic.RenameBVar import Mathlib.Tactic.Replace diff --git a/Mathlib/Algebra/Notation.lean b/Mathlib/Algebra/Notation.lean index 0ea472b668eb9b..ffb3097c7ba736 100644 --- a/Mathlib/Algebra/Notation.lean +++ b/Mathlib/Algebra/Notation.lean @@ -3,6 +3,7 @@ Copyright (c) 2024 Jireh Loreaux. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Jireh Loreaux -/ +import Mathlib.Tactic.TypeStar import Mathlib.Tactic.ToAdditive /-! diff --git a/Mathlib/Order/Defs.lean b/Mathlib/Order/Defs.lean index 7a46f0ce76cf70..75d603ee2c080b 100644 --- a/Mathlib/Order/Defs.lean +++ b/Mathlib/Order/Defs.lean @@ -4,9 +4,9 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Leonardo de Moura -/ import Batteries.Classes.Order +import Batteries.Tactic.Trans import Mathlib.Data.Ordering.Basic import Mathlib.Tactic.Lemma -import Mathlib.Tactic.Relation.Trans import Mathlib.Tactic.SplitIfs import Mathlib.Tactic.TypeStar diff --git a/Mathlib/Tactic.lean b/Mathlib/Tactic.lean index cd494193a67b40..efac05b1b7da13 100644 --- a/Mathlib/Tactic.lean +++ b/Mathlib/Tactic.lean @@ -203,7 +203,6 @@ import Mathlib.Tactic.ReduceModChar import Mathlib.Tactic.ReduceModChar.Ext import Mathlib.Tactic.Relation.Rfl import Mathlib.Tactic.Relation.Symm -import Mathlib.Tactic.Relation.Trans import Mathlib.Tactic.Rename import Mathlib.Tactic.RenameBVar import Mathlib.Tactic.Replace diff --git a/Mathlib/Tactic/Common.lean b/Mathlib/Tactic/Common.lean index f9c7a25eb782c0..c864e4fc60f267 100644 --- a/Mathlib/Tactic/Common.lean +++ b/Mathlib/Tactic/Common.lean @@ -79,7 +79,6 @@ import Mathlib.Tactic.PushNeg import Mathlib.Tactic.RSuffices import Mathlib.Tactic.Recover import Mathlib.Tactic.Relation.Rfl -import Mathlib.Tactic.Relation.Trans import Mathlib.Tactic.Rename import Mathlib.Tactic.RenameBVar import Mathlib.Tactic.Says diff --git a/Mathlib/Tactic/MoveAdd.lean b/Mathlib/Tactic/MoveAdd.lean index 094ce46b602656..87cf3bdb6add42 100644 --- a/Mathlib/Tactic/MoveAdd.lean +++ b/Mathlib/Tactic/MoveAdd.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Arthur Paulino, Damiano Testa -/ import Mathlib.Algebra.Group.Basic +import Mathlib.Lean.Meta /-! diff --git a/Mathlib/Tactic/Relation/Trans.lean b/Mathlib/Tactic/Relation/Trans.lean deleted file mode 100644 index 290d23e9aeb70b..00000000000000 --- a/Mathlib/Tactic/Relation/Trans.lean +++ /dev/null @@ -1,222 +0,0 @@ -/- -Copyright (c) 2022 Siddhartha Gadgil. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Siddhartha Gadgil, Mario Carneiro --/ -import Mathlib.Lean.Meta -import Mathlib.Lean.Elab.Tactic.Basic -import Lean.Elab.Tactic.ElabTerm -import Mathlib.Tactic.TypeStar - -/-! -# `trans` tactic - -This implements the `trans` tactic, which can apply transitivity theorems with an optional middle -variable argument. --/ - -namespace Mathlib.Tactic -open Lean Meta Elab - -initialize registerTraceClass `Tactic.trans - -/-- Discrimation tree settings for the `trans` extension. -/ -def transExt.config : WhnfCoreConfig := {} - -/-- Environment extension storing transitivity lemmas -/ -initialize transExt : - SimpleScopedEnvExtension (Name × Array DiscrTree.Key) (DiscrTree Name) ← - registerSimpleScopedEnvExtension { - addEntry := fun dt (n, ks) ↦ dt.insertCore ks n - initial := {} - } - -initialize registerBuiltinAttribute { - name := `trans - descr := "transitive relation" - add := fun decl _ kind ↦ MetaM.run' do - let declTy := (← getConstInfo decl).type - let (xs, _, targetTy) ← withReducible <| forallMetaTelescopeReducing declTy - let fail := throwError - "@[trans] attribute only applies to lemmas proving - x ∼ y → y ∼ z → x ∼ z, got {indentExpr declTy} with target {indentExpr targetTy}" - let .app (.app rel _) _ := targetTy | fail - let some yzHyp := xs.back? | fail - let some xyHyp := xs.pop.back? | fail - let .app (.app _ _) _ ← inferType yzHyp | fail - let .app (.app _ _) _ ← inferType xyHyp | fail - let key ← withReducible <| DiscrTree.mkPath rel transExt.config - transExt.add (decl, key) kind -} - -universe u v in -/-- Composition using the `Trans` class in the homogeneous case. -/ -def _root_.Trans.simple {α : Sort u} {r : α → α → Sort v} {a b c : α} [Trans r r r] : - r a b → r b c → r a c := trans - -universe u v w in -/-- Composition using the `Trans` class in the general case. -/ -def _root_.Trans.het {α β γ : Sort*} {a : α} {b : β} {c : γ} - {r : α → β → Sort u} {s : β → γ → Sort v} {t : outParam (α → γ → Sort w)} [Trans r s t] : - r a b → s b c → t a c := trans - -open Lean.Elab.Tactic - -/-- solving `e ← mkAppM' f #[x]` -/ -def getExplicitFuncArg? (e : Expr) : MetaM (Option <| Expr × Expr) := do - match e with - | Expr.app f a => do - if ← isDefEq (← mkAppM' f #[a]) e then - return some (f, a) - else - getExplicitFuncArg? f - | _ => return none - -/-- solving `tgt ← mkAppM' rel #[x, z]` given `tgt = f z` -/ -def getExplicitRelArg? (tgt f z : Expr) : MetaM (Option <| Expr × Expr) := do - match f with - | Expr.app rel x => do - let check: Bool ← do - try - let folded ← mkAppM' rel #[x, z] - isDefEq folded tgt - catch _ => - pure false - if check then - return some (rel, x) - else - getExplicitRelArg? tgt rel z - | _ => return none - -/-- refining `tgt ← mkAppM' rel #[x, z]` dropping more arguments if possible -/ -def getExplicitRelArgCore (tgt rel x z : Expr) : MetaM (Expr × Expr) := do - match rel with - | Expr.app rel' _ => do - let check: Bool ← do - try - let folded ← mkAppM' rel' #[x, z] - isDefEq folded tgt - catch _ => - pure false - if !check then - return (rel, x) - else - getExplicitRelArgCore tgt rel' x z - | _ => return (rel ,x) - -/-- Internal definition for `trans` tactic. Either a binary relation or a non-dependent -arrow. -/ -inductive TransRelation - | app (rel : Expr) - | implies (name : Name) (bi : BinderInfo) - -/-- Finds an explicit binary relation in the argument, if possible. -/ -def getRel (tgt : Expr) : MetaM (Option (TransRelation × Expr × Expr)) := do - match tgt with - | .forallE name binderType body info => return .some (.implies name info, binderType, body) - | .app f z => - match (← getExplicitRelArg? tgt f z) with - | some (rel, x) => - let (rel, x) ← getExplicitRelArgCore tgt rel x z - return some (.app rel, x, z) - | none => - return none - | _ => return none - -/-- -`trans` applies to a goal whose target has the form `t ~ u` where `~` is a transitive relation, -that is, a relation which has a transitivity lemma tagged with the attribute [trans]. - -* `trans s` replaces the goal with the two subgoals `t ~ s` and `s ~ u`. -* If `s` is omitted, then a metavariable is used instead. - -Additionally, `trans` also applies to a goal whose target has the form `t → u`, -in which case it replaces the goal with `t → s` and `s → u`. --/ -elab "trans" t?:(ppSpace colGt term)? : tactic => withMainContext do - let tgt ← getMainTarget'' - let .some (rel, x, z) ← getRel tgt | - throwError (m!"transitivity lemmas only apply to binary relations and " ++ - m!"non-dependent arrows, not {indentExpr tgt}") - match rel with - | .implies name info => - -- only consider non-dependent arrows - if z.hasLooseBVars then - throwError "`trans` is not implemented for dependent arrows{indentExpr tgt}" - -- parse the intermeditate term - let middleType ← mkFreshExprMVar none - let t'? ← t?.mapM (elabTermWithHoles · middleType (← getMainTag)) - let middle ← (t'?.map (pure ·.1)).getD (mkFreshExprMVar middleType) - liftMetaTactic fun goal => do - -- create two new goals - let g₁ ← mkFreshExprMVar (some <| .forallE name x middle info) .synthetic - let g₂ ← mkFreshExprMVar (some <| .forallE name middle z info) .synthetic - -- close the original goal with `fun x => g₂ (g₁ x)` - goal.assign (.lam name x (.app g₂ (.app g₁ (.bvar 0))) .default) - pure <| [g₁.mvarId!, g₂.mvarId!] ++ if let some (_, gs') := t'? then gs' else [middle.mvarId!] - return - | .app rel => - trace[Tactic.trans]"goal decomposed" - trace[Tactic.trans]"rel: {indentExpr rel}" - trace[Tactic.trans]"x: {indentExpr x}" - trace[Tactic.trans]"z: {indentExpr z}" - -- first trying the homogeneous case - try - let ty ← inferType x - let t'? ← t?.mapM (elabTermWithHoles · ty (← getMainTag)) - let s ← saveState - trace[Tactic.trans]"trying homogeneous case" - let lemmas := - (← (transExt.getState (← getEnv)).getUnify rel transExt.config).push ``Trans.simple - for lem in lemmas do - trace[Tactic.trans]"trying lemma {lem}" - try - liftMetaTactic fun g ↦ do - let lemTy ← inferType (← mkConstWithLevelParams lem) - let arity ← withReducible <| forallTelescopeReducing lemTy fun es _ ↦ pure es.size - let y ← (t'?.map (pure ·.1)).getD (mkFreshExprMVar ty) - let g₁ ← mkFreshExprMVar (some <| ← mkAppM' rel #[x, y]) .synthetic - let g₂ ← mkFreshExprMVar (some <| ← mkAppM' rel #[y, z]) .synthetic - g.assign (← mkAppOptM lem (mkArray (arity - 2) none ++ #[some g₁, some g₂])) - pure <| [g₁.mvarId!, g₂.mvarId!] ++ - if let some (_, gs') := t'? then gs' else [y.mvarId!] - return - catch _ => s.restore - pure () - catch _ => - trace[Tactic.trans]"trying heterogeneous case" - let t'? ← t?.mapM (elabTermWithHoles · none (← getMainTag)) - let s ← saveState - for lem in (← (transExt.getState (← getEnv)).getUnify rel transExt.config).push - ``HEq.trans |>.push ``HEq.trans do - try - liftMetaTactic fun g ↦ do - trace[Tactic.trans]"trying lemma {lem}" - let lemTy ← inferType (← mkConstWithLevelParams lem) - let arity ← withReducible <| forallTelescopeReducing lemTy fun es _ ↦ pure es.size - trace[Tactic.trans]"arity: {arity}" - trace[Tactic.trans]"lemma-type: {lemTy}" - let y ← (t'?.map (pure ·.1)).getD (mkFreshExprMVar none) - trace[Tactic.trans]"obtained y: {y}" - trace[Tactic.trans]"rel: {indentExpr rel}" - trace[Tactic.trans]"x:{indentExpr x}" - trace[Tactic.trans]"z: {indentExpr z}" - let g₂ ← mkFreshExprMVar (some <| ← mkAppM' rel #[y, z]) .synthetic - trace[Tactic.trans]"obtained g₂: {g₂}" - let g₁ ← mkFreshExprMVar (some <| ← mkAppM' rel #[x, y]) .synthetic - trace[Tactic.trans]"obtained g₁: {g₁}" - g.assign (← mkAppOptM lem (mkArray (arity - 2) none ++ #[some g₁, some g₂])) - pure <| [g₁.mvarId!, g₂.mvarId!] ++ if let some (_, gs') := t'? then gs' else [y.mvarId!] - return - catch e => - trace[Tactic.trans]"failed: {e.toMessageData}" - s.restore - throwError m!"no applicable transitivity lemma found for {indentExpr tgt}" - -syntax "transitivity" (ppSpace colGt term)? : tactic -set_option hygiene false in -macro_rules - | `(tactic| transitivity) => `(tactic| trans) - | `(tactic| transitivity $e) => `(tactic| trans $e) - -end Mathlib.Tactic diff --git a/Mathlib/Tactic/ToAdditive/Frontend.lean b/Mathlib/Tactic/ToAdditive/Frontend.lean index 277e01a289f6b3..c0d0ef7afdcfa1 100644 --- a/Mathlib/Tactic/ToAdditive/Frontend.lean +++ b/Mathlib/Tactic/ToAdditive/Frontend.lean @@ -16,7 +16,7 @@ import Lean.Meta.Tactic.Rfl import Lean.Meta.Match.MatcherInfo import Batteries.Lean.NameMapAttribute import Batteries.Tactic.Lint -- useful to lint this file and for DiscrTree.elements -import Mathlib.Tactic.Relation.Trans -- just to copy the attribute +import Batteries.Tactic.Trans import Mathlib.Tactic.Eqns -- just to copy the attribute import Mathlib.Tactic.Simps.Basic @@ -1167,7 +1167,7 @@ partial def applyAttributes (stx : Syntax) (rawAttrs : Array Syntax) (thisAttr s (fun b n => (b.tree.values.any fun t => t.declName = n)) thisAttr `ext src tgt warnAttr stx Lean.Meta.Rfl.reflExt (·.values.contains ·) thisAttr `refl src tgt warnAttr stx Lean.Meta.Symm.symmExt (·.values.contains ·) thisAttr `symm src tgt - warnAttr stx Mathlib.Tactic.transExt (·.values.contains ·) thisAttr `trans src tgt + warnAttr stx Batteries.Tactic.transExt (·.values.contains ·) thisAttr `trans src tgt warnAttr stx Lean.Meta.coeExt (·.contains ·) thisAttr `coe src tgt warnParametricAttr stx Lean.Linter.deprecatedAttr thisAttr `deprecated src tgt -- the next line also warns for `@[to_additive, simps]`, because of the application times diff --git a/Mathlib/Tactic/Widget/CongrM.lean b/Mathlib/Tactic/Widget/CongrM.lean index 9c259c3daaf304..dad4520d652cc6 100644 --- a/Mathlib/Tactic/Widget/CongrM.lean +++ b/Mathlib/Tactic/Widget/CongrM.lean @@ -6,6 +6,7 @@ Authors: Patrick Massot import Mathlib.Tactic.Widget.SelectPanelUtils import Mathlib.Tactic.CongrM +import Batteries.Lean.Position /-! # CongrM widget diff --git a/lake-manifest.json b/lake-manifest.json index 6f116ba1524dd0..8d8fe8356466ad 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "1e0bf50b357069e1d658512a579a5faac6587c40", + "rev": "10130798199d306703dee5ab2567961444ebbd04", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "main", diff --git a/scripts/noshake.json b/scripts/noshake.json index 3e93d378ca0e2f..a98fca062e875c 100644 --- a/scripts/noshake.json +++ b/scripts/noshake.json @@ -148,7 +148,6 @@ "Mathlib.Tactic.Recover", "Mathlib.Tactic.ReduceModChar.Ext", "Mathlib.Tactic.Relation.Symm", - "Mathlib.Tactic.Relation.Trans", "Mathlib.Tactic.Rename", "Mathlib.Tactic.RenameBVar", "Mathlib.Tactic.Replace", @@ -325,6 +324,7 @@ "Mathlib.Order.RelClasses": ["Batteries.WF"], "Mathlib.Order.Filter.ListTraverse": ["Mathlib.Control.Traversable.Instances"], + "Mathlib.Order.Defs": ["Batteries.Tactic.Trans"], "Mathlib.Order.Basic": ["Batteries.Tactic.Classical"], "Mathlib.NumberTheory.Harmonic.Defs": ["Mathlib.Algebra.Order.BigOperators.Ring.Finset", diff --git a/test/trans.lean b/test/trans.lean deleted file mode 100644 index 50b5bc01e7b20c..00000000000000 --- a/test/trans.lean +++ /dev/null @@ -1,109 +0,0 @@ -import Mathlib.Tactic.Relation.Trans -import Mathlib.Tactic.GuardGoalNums - -set_option autoImplicit true --- testing that the attribute is recognized and used -def nleq (a b : Nat) : Prop := a ≤ b - -@[trans] def nleq_trans : nleq a b → nleq b c → nleq a c := Nat.le_trans - -example (a b c : Nat) : nleq a b → nleq b c → nleq a c := by - intro h₁ h₂ - trans b - assumption - assumption - -example (a b c : Nat) : nleq a b → nleq b c → nleq a c := by intros; trans <;> assumption - --- using `Trans` typeclass -@[trans] def eq_trans {a b c : α} : a = b → b = c → a = c := by - intro h₁ h₂ - apply Eq.trans h₁ h₂ - -example (a b c : Nat) : a = b → b = c → a = c := by intros; trans <;> assumption - -example (a b c : Nat) : a = b → b = c → a = c := by - intro h₁ h₂ - trans b - assumption - assumption - -example : @Trans Nat Nat Nat (· ≤ ·) (· ≤ ·) (· ≤ ·) := inferInstance - -example (a b c : Nat) : a ≤ b → b ≤ c → a ≤ c := by - intros h₁ h₂ - trans ?b - case b => exact b - exact h₁ - exact h₂ - -example (a b c : α) (R : α → α → Prop) [Trans R R R] : R a b → R b c → R a c := by - intros h₁ h₂ - trans ?b - case b => exact b - exact h₁ - exact h₂ - -example (a b c : Nat) : a ≤ b → b ≤ c → a ≤ c := by - intros h₁ h₂ - trans - exact h₁ - exact h₂ - -example (a b c : Nat) : a ≤ b → b ≤ c → a ≤ c := by intros; trans <;> assumption - -example (a b c : Nat) : a < b → b < c → a < c := by - intro h₁ h₂ - trans b - assumption - assumption - -example (a b c : Nat) : a < b → b < c → a < c := by intros; trans <;> assumption - -example (x n p : Nat) (h₁ : n * Nat.succ p ≤ x) : n * p ≤ x := by - trans - · apply Nat.mul_le_mul_left; apply Nat.le_succ - · apply h₁ - -example (a : α) (c : γ) : ∀ b : β, HEq a b → HEq b c → HEq a c := by - intro b h₁ h₂ - trans b - assumption - assumption - -def MyLE (n m : Nat) := ∃ k, n + k = m - -@[trans] theorem MyLE.trans {n m k : Nat} (h1 : MyLE n m) (h2 : MyLE m k) : MyLE n k := by - cases h1 - cases h2 - subst_vars - exact ⟨_, Eq.symm <| Nat.add_assoc _ _ _⟩ - -example {n m k : Nat} (h1 : MyLE n m) (h2 : MyLE m k) : MyLE n k := by - trans <;> assumption - -/-- `trans` for implications. -/ -example {A B C : Prop} (h : A → B) (g : B → C) : A → C := by - trans B - · guard_target =ₛ A → B -- ensure we have `B` and not a free metavariable. - exact h - · guard_target =ₛ B → C - exact g - -set_option linter.unusedTactic false in -/-- `trans` for arrows between types. -/ -example {A B C : Type} (h : A → B) (g : B → C) : A → C := by - trans - guard_goal_nums 3 -- 3rd goal is the middle term - · exact h - · exact g - -universe u v w - -set_option linter.unusedTactic false in -/-- `trans` for arrows between types. -/ -example {A : Type u} {B : Type v} {C : Type w} (h : A → B) (g : B → C) : A → C := by - trans - guard_goal_nums 3 -- 3rd goal is the middle term - · exact h - · exact g From a1b122f315bbf37b260c1088f27cb17b8ffc34c6 Mon Sep 17 00:00:00 2001 From: leanprover-community-mathlib4-bot Date: Sat, 19 Oct 2024 08:22:35 +0000 Subject: [PATCH 420/425] chore: bump to nightly-2024-10-19 --- lean-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lean-toolchain b/lean-toolchain index 4c427a2de2a633..c34e35287d8481 100644 --- a/lean-toolchain +++ b/lean-toolchain @@ -1 +1 @@ -leanprover/lean4:nightly-2024-10-18 +leanprover/lean4:nightly-2024-10-19 From cac62d8cf9a832434396563614046e3cc5bf1b25 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Sat, 19 Oct 2024 20:12:12 +1100 Subject: [PATCH 421/425] fix tests --- test/GCongr/inequalities.lean | 1 + test/NoncommRing.lean | 2 ++ test/Rify.lean | 2 ++ test/Simps.lean | 1 + test/SplitIfs.lean | 1 + test/Zify.lean | 2 ++ test/abel.lean | 2 ++ test/algebraize.lean | 2 ++ test/apply_fun.lean | 2 ++ test/basicTactics.lean | 1 + test/cases.lean | 1 + test/casesm.lean | 1 + test/lift.lean | 4 +++- test/linear_combination'.lean | 1 + test/linear_combination.lean | 1 + test/matrix.lean | 4 ++-- test/nontriviality.lean | 2 +- test/norm_num.lean | 1 + test/positivity.lean | 1 + test/solve_by_elim/basic.lean | 2 ++ test/success_if_fail_with_msg.lean | 1 + 21 files changed, 31 insertions(+), 4 deletions(-) diff --git a/test/GCongr/inequalities.lean b/test/GCongr/inequalities.lean index 02f0a2850793ce..5732af9bcb4771 100644 --- a/test/GCongr/inequalities.lean +++ b/test/GCongr/inequalities.lean @@ -100,6 +100,7 @@ example (n k : ℕ) (H : n ^ k + 1 ≤ k ^ n + 1) : n ^ k ≤ k ^ n := by (gcongr) linarith +set_option linter.unusedVariables false in example {x : ℤ} (hx : x ≥ 12) (h : Even x) : Even x := by success_if_fail_with_msg "rel failed, goal not a relation" (rel [hx]) exact h diff --git a/test/NoncommRing.lean b/test/NoncommRing.lean index 8eede35df2deec..5b84ad06a5f016 100644 --- a/test/NoncommRing.lean +++ b/test/NoncommRing.lean @@ -67,6 +67,8 @@ example : a ^ 50 * a ^ 37 = a ^ 23 * a ^ 64 := by noncomm_ring /- some examples using arguments -/ example (h : ∀ a : R, (2 : ℤ) • a = 0) : (a + 1) ^ 2 = a ^ 2 + 1 := by noncomm_ring [h] + +set_option linter.unusedVariables false in example (h : a = b) (h2 : a = c) : a = c := by fail_if_success noncomm_ring [h] noncomm_ring [h2] diff --git a/test/Rify.lean b/test/Rify.lean index 38c41308e80716..32d39179274239 100644 --- a/test/Rify.lean +++ b/test/Rify.lean @@ -1,6 +1,8 @@ import Mathlib.Tactic.Linarith import Mathlib.Tactic.Rify +set_option linter.unusedVariables false + example {n : ℕ} {k : ℤ} (hn : 8 ≤ n) (hk : 2 * k ≤ n + 2) : (0 : ℝ) < n - k - 1 := by rify at hn hk diff --git a/test/Simps.lean b/test/Simps.lean index cb6c499476837b..3b31ef9f54bcde 100644 --- a/test/Simps.lean +++ b/test/Simps.lean @@ -938,6 +938,7 @@ structure MyType where ⟨{ _x : Fin (Nat.add 3 0) // 1 + 1 = 2 }⟩ -- todo: this fails in Lean 4, not sure what is going on +set_option linter.unusedVariables false in example (h : false) (x y : { x : Fin (Nat.add 3 0) // 1 + 1 = 2 }) : myTypeDef.A = Unit := by simp only [myTypeDef_A] guard_target = { _x : Fin 3 // True } = Unit diff --git a/test/SplitIfs.lean b/test/SplitIfs.lean index 1809a04cb709ef..ada62913a3cd32 100644 --- a/test/SplitIfs.lean +++ b/test/SplitIfs.lean @@ -66,6 +66,7 @@ example : True := by trivial open scoped Classical in +set_option linter.unusedVariables false in example (P Q : Prop) (w : if P then (if Q then true else true) else true = true) : true := by split_ifs at w -- check that we've fully split w into three subgoals diff --git a/test/Zify.lean b/test/Zify.lean index a61537de310b26..5f3a27553df564 100644 --- a/test/Zify.lean +++ b/test/Zify.lean @@ -7,6 +7,8 @@ Authors: Moritz Doll, Robert Y. Lewis import Mathlib.Tactic.Zify import Mathlib.Algebra.Ring.Int +set_option linter.unusedVariables false + private axiom test_sorry : ∀ {α}, α example (a b c x y z : ℕ) (h : ¬ x*y*z < 0) : c < a + 3*b := by zify diff --git a/test/abel.lean b/test/abel.lean index 7338aa7490d9f8..d59304f17cbfbd 100644 --- a/test/abel.lean +++ b/test/abel.lean @@ -1,5 +1,7 @@ import Mathlib.Tactic.Abel +set_option linter.unusedVariables false + variable {α : Type _} {a b : α} example [AddCommMonoid α] : a + (b + a) = a + a + b := by abel diff --git a/test/algebraize.lean b/test/algebraize.lean index 1ccd695d0b9205..bdd3c99219a1a3 100644 --- a/test/algebraize.lean +++ b/test/algebraize.lean @@ -1,5 +1,7 @@ import Mathlib.Tactic.Algebraize +set_option linter.unusedVariables false + section example_definitions /-- Test property for when `RingHom` and `Algebra` properties are definitionally the same, diff --git a/test/apply_fun.lean b/test/apply_fun.lean index 65e598ff58779b..cc2916c0a463b3 100644 --- a/test/apply_fun.lean +++ b/test/apply_fun.lean @@ -8,6 +8,8 @@ import Mathlib.Data.Matrix.Basic private axiom test_sorry : ∀ {α}, α set_option autoImplicit true +set_option linter.unusedVariables false + open Function example (f : ℕ → ℕ) (h : f x = f y) : x = y := by diff --git a/test/basicTactics.lean b/test/basicTactics.lean index 2eaa3aee8ce7ed..b29b8f2bd836b9 100644 --- a/test/basicTactics.lean +++ b/test/basicTactics.lean @@ -11,6 +11,7 @@ example (n : Nat) : n = n := by exacts [rfl, rfl] exacts [] +set_option linter.unusedVariables false in example (n : Nat) : Nat := by guard_hyp n : Nat let m : Nat := 1 diff --git a/test/cases.lean b/test/cases.lean index 664d0db8f51f83..2bc7b9785755ed 100644 --- a/test/cases.lean +++ b/test/cases.lean @@ -60,6 +60,7 @@ example (n : Nat) (h : n < 5) : n = n := by · guard_hyp n : Nat; guard_hyp ih : n < 5 → n = n; guard_hyp h :ₛ n + 1 < 5 guard_target =ₛ n + 1 = n + 1; rfl +set_option linter.unusedVariables false in example (n : Nat) {m} (h : m < 5) : n = n := by induction' n with n ih · guard_target = Nat.zero = Nat.zero; rfl diff --git a/test/casesm.lean b/test/casesm.lean index 327f1e0bda1633..2a765ce9e8e7bf 100644 --- a/test/casesm.lean +++ b/test/casesm.lean @@ -1,6 +1,7 @@ import Mathlib.Tactic.CasesM set_option autoImplicit true +set_option linter.unusedVariables false set_option linter.unusedTactic false in example (h : a ∧ b ∨ c ∧ d) (h2 : e ∧ f) : True := by diff --git a/test/lift.lean b/test/lift.lean index 979eed74ce45cc..44233ad679a49a 100644 --- a/test/lift.lean +++ b/test/lift.lean @@ -76,7 +76,7 @@ example (α : Type _) (f : α → ℤ) (hf : ∀ a, 0 ≤ f a) (hf' : ∀ a, f a guard_hyp hf' : ∀ a, ((fun i : α ↦ (f i : ℤ)) a) < 1 constructor -example (α : Type _) (f : α → ℤ) (hf : ∀ a, 0 ≤ f a) (hf' : ∀ a, f a < 1) (a : α) : +example (α : Type _) (f : α → ℤ) (hf : ∀ a, 0 ≤ f a) (_ : ∀ a, f a < 1) (a : α) : 0 ≤ 2 * f a := by lift f to α → ℕ using hf with g hg guard_target =ₛ 0 ≤ 2 * (g a : Int) @@ -101,11 +101,13 @@ example (h : False) : let n : ℤ := 3; n = 3 := by instance canLift_unit : CanLift Unit Unit id (fun _ ↦ true) := ⟨fun x _ ↦ ⟨x, rfl⟩⟩ +set_option linter.unusedVariables false in example (n : ℤ) (hn : 0 < n) : True := by fail_if_success lift n to ℕ using hn fail_if_success lift (n : Option ℤ) to ℕ trivial +set_option linter.unusedVariables false in example (n : ℤ) : ℕ := by fail_if_success lift n to ℕ exact 0 diff --git a/test/linear_combination'.lean b/test/linear_combination'.lean index 36056748d622d1..ef74d22a1789dd 100644 --- a/test/linear_combination'.lean +++ b/test/linear_combination'.lean @@ -219,6 +219,7 @@ example (a _b : ℕ) (h1 : a = 3) : a = 3 := by fail_if_success linear_combination' h1 linear_combination2 h1 +set_option linter.unusedVariables false in example (a b : ℤ) (x y : ℝ) (hab : a = b) (hxy : x = y) : 2 * x = 2 * y := by fail_if_success linear_combination' 2 * hab linear_combination' 2 * hxy diff --git a/test/linear_combination.lean b/test/linear_combination.lean index 6e8b23a79630f5..6a5356f2beb967 100644 --- a/test/linear_combination.lean +++ b/test/linear_combination.lean @@ -266,6 +266,7 @@ but is expected to have type example (x y : ℤ) (h1 : x * y + 2 * x = 1) (h2 : x = y) : x * y + 2 * x = 1 := by linear_combination h1 + (0 : ℝ) * h2 +set_option linter.unusedVariables false in example (a b : ℤ) (x y : ℝ) (hab : a = b) (hxy : x = y) : 2 * x = 2 * y := by fail_if_success linear_combination 2 * hab linear_combination 2 * hxy diff --git a/test/matrix.lean b/test/matrix.lean index 522acbe923c7d2..d8571679b3a9c8 100644 --- a/test/matrix.lean +++ b/test/matrix.lean @@ -189,11 +189,11 @@ example : Matrix.col _ ![1, 1] = !![1; 1] := by ext i j fin_cases i <;> simp -example (ι : Type*) [Inhabited ι] : Matrix.row ι (fun (n : Fin 3) => 0) = 0 := by +example (ι : Type*) [Inhabited ι] : Matrix.row ι (fun (_ : Fin 3) => 0) = 0 := by simp_all rfl -example (ι : Type*) [Inhabited ι] : Matrix.col ι (fun (n : Fin 3) => 0) = 0 := by +example (ι : Type*) [Inhabited ι] : Matrix.col ι (fun (_ : Fin 3) => 0) = 0 := by simp_all rfl diff --git a/test/nontriviality.lean b/test/nontriviality.lean index 26347bbe71a6f5..59b16c47b846e2 100644 --- a/test/nontriviality.lean +++ b/test/nontriviality.lean @@ -36,7 +36,7 @@ example {R : Type} [OrderedRing R] : 0 ≤ (2 : R) := by fail_if_success nontriviality PUnit exact zero_le_two -example {R : Type} [OrderedRing R] {a : R} (h : 0 < a) : 2 ∣ 4 := by +example {R : Type} [OrderedRing R] {a : R} (_ : 0 < a) : 2 ∣ 4 := by nontriviality R rename_i inst; guard_hyp inst : Nontrivial R decide diff --git a/test/norm_num.lean b/test/norm_num.lean index 91589ac6a1d1c7..23c7b4be585888 100644 --- a/test/norm_num.lean +++ b/test/norm_num.lean @@ -370,6 +370,7 @@ example : (2 * 12868 + 25705) * 11621 ^ 2 ≤ 23235 ^ 2 * 12868 := by norm_num1 -- let n : ℕ := by apply_normed (2^32 - 71) -- exact n +set_option linter.unusedVariables false in example (a : ℚ) (h : 3⁻¹ * a = a) : True := by norm_num1 at h guard_hyp h : 1 / 3 * a = a diff --git a/test/positivity.lean b/test/positivity.lean index fc773c8abd9622..67ed0b2932e091 100644 --- a/test/positivity.lean +++ b/test/positivity.lean @@ -393,6 +393,7 @@ example (s : Finset ℕ) (f : ℕ → ℕ) (a : ℕ) : 0 ≤ s.sum (f a) := by p set_option linter.unusedVariables false in example (f : ℕ → ℕ) (hf : 0 ≤ f 0) : 0 ≤ ∑ n ∈ Finset.range 10, f n := by positivity +set_option linter.unusedVariables false in example (n : ℕ) : ∏ j ∈ range n, (-1) ≠ 0 := by positivity example (n : ℕ) (a : ℕ → ℤ) : 0 ≤ ∏ j ∈ range n, a j^2 := by positivity example (a : ULift.{2} ℕ → ℤ) (s : Finset (ULift.{2} ℕ)) : 0 ≤ ∏ j ∈ s, a j^2 := by positivity diff --git a/test/solve_by_elim/basic.lean b/test/solve_by_elim/basic.lean index ce407f3089f28e..fe26dbdc0c675c 100644 --- a/test/solve_by_elim/basic.lean +++ b/test/solve_by_elim/basic.lean @@ -30,6 +30,7 @@ example {α β : Type} (f : α → β) (a : α) : β := by fail_if_success solve_by_elim only [f] solve_by_elim +set_option linter.unusedVariables false in example {α β γ : Type} (f : α → β) (g : β → γ) (b : β) : γ := by fail_if_success solve_by_elim [-g] solve_by_elim [-f] @@ -42,6 +43,7 @@ example {α β γ : Type} (_f : α → β) (g : β → γ) (b : β) : γ := by s example {α : Nat → Type} (f : (n : Nat) → α n → α (n+1)) (a : α 0) : α 4 := by solve_by_elim only [f, a] +set_option linter.unusedVariables false in example (h₁ h₂ : False) : Empty := by -- 'It doesn't make sense to remove local hypotheses when using `only` without `*`.' fail_if_success solve_by_elim only [-h₁] diff --git a/test/success_if_fail_with_msg.lean b/test/success_if_fail_with_msg.lean index 1e190fde9d2c32..dcbafdaf29dcb6 100644 --- a/test/success_if_fail_with_msg.lean +++ b/test/success_if_fail_with_msg.lean @@ -20,6 +20,7 @@ n : Nat "not that message ⊢ True" +set_option linter.unusedVariables false in example (n : Nat) : True := by success_if_fail_with_msg (err true) rw [Nat.le_succ n] trivial From 55367600b84ef4a491d57f4e82c670e9ffa7cc4d Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Sat, 19 Oct 2024 20:12:53 +1100 Subject: [PATCH 422/425] fix test --- test/norm_num_ext.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/norm_num_ext.lean b/test/norm_num_ext.lean index 4db23b8b748f98..8dd7ee9a684788 100644 --- a/test/norm_num_ext.lean +++ b/test/norm_num_ext.lean @@ -356,7 +356,7 @@ example (f : ℕ → α) : ∏ i ∈ Finset.range 0, f i = 1 := by norm_num1 example (f : Fin 0 → α) : ∏ i : Fin 0, f i = 1 := by norm_num1 example (f : Fin 0 → α) : ∑ i : Fin 0, f i = 0 := by norm_num1 example (f : ℕ → α) : ∑ i ∈ (∅ : Finset ℕ), f i = 0 := by norm_num1 -example : ∑ i : Fin 3, 1 = 3 := by norm_num1 +example : ∑ _ : Fin 3, 1 = 3 := by norm_num1 /- example : ∑ i : Fin 3, (i : ℕ) = 3 := by norm_num1 example : ((0 : Fin 3) : ℕ) = 0 := by norm_num1 From c2067f2d8656c8fa417133d981b027b99f47a227 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Sat, 19 Oct 2024 22:09:34 +1100 Subject: [PATCH 423/425] fixes for leanprover/lean4#5650 --- Mathlib/Tactic/Core.lean | 1 + Mathlib/Tactic/DeriveTraversable.lean | 3 +++ Mathlib/Tactic/HigherOrder.lean | 4 ++-- Mathlib/Tactic/MinImports.lean | 2 +- Mathlib/Tactic/MkIffOfInductiveProp.lean | 6 +++--- Mathlib/Tactic/Simps/Basic.lean | 4 ++-- Mathlib/Tactic/ToAdditive/Frontend.lean | 4 ++-- Mathlib/Util/AddRelatedDecl.lean | 4 ++-- lake-manifest.json | 2 +- 9 files changed, 17 insertions(+), 13 deletions(-) diff --git a/Mathlib/Tactic/Core.lean b/Mathlib/Tactic/Core.lean index fc6cf43ed4dc64..b2beb80df27821 100644 --- a/Mathlib/Tactic/Core.lean +++ b/Mathlib/Tactic/Core.lean @@ -31,6 +31,7 @@ def toModifiers (nm : Name) (newDoc : Option String := none) : let d ← getConstInfo nm let mods : Modifiers := { docString? := newDoc + stx := ⟨.missing⟩ visibility := if isPrivateNameExport nm then Visibility.private diff --git a/Mathlib/Tactic/DeriveTraversable.lean b/Mathlib/Tactic/DeriveTraversable.lean index 9b4bba79c6c92d..fe0b16401564c7 100644 --- a/Mathlib/Tactic/DeriveTraversable.lean +++ b/Mathlib/Tactic/DeriveTraversable.lean @@ -173,6 +173,7 @@ def deriveFunctor (m : MVarId) : TermElabM Unit := do levelParams := levels modifiers := { isUnsafe := d.isUnsafe + stx := ⟨.missing⟩ attrs := #[{ kind := .global name := `specialize @@ -239,6 +240,7 @@ def mkOneInstance (n cls : Name) (tac : MVarId → TermElabM Unit) levelParams := decl.levelParams modifiers := { isUnsafe + stx := ⟨.missing⟩ attrs := #[{ kind := .global name := `instance @@ -414,6 +416,7 @@ def deriveTraversable (m : MVarId) : TermElabM Unit := do levelParams := levels modifiers := { isUnsafe := d.isUnsafe + stx := ⟨.missing⟩ visibility := .protected } declName := n' type := t' diff --git a/Mathlib/Tactic/HigherOrder.lean b/Mathlib/Tactic/HigherOrder.lean index b6744d6df37592..c6c58ca27cb30a 100644 --- a/Mathlib/Tactic/HigherOrder.lean +++ b/Mathlib/Tactic/HigherOrder.lean @@ -92,8 +92,8 @@ def higherOrderGetParam (thm : Name) (stx : Syntax) : AttrM Name := do type := hot value := prf } addDeclarationRanges hothmName - { range := ← getDeclarationRange (← getRef) - selectionRange := ← getDeclarationRange ref } + { range := (← getDeclarationRange? (← getRef)).get! + selectionRange := (← getDeclarationRange? ref).get! } _ ← addTermInfo (isBinder := true) ref <| ← mkConstWithLevelParams hothmName let hsm := simpExtension.getState (← getEnv) |>.lemmaNames.contains (.decl thm) if hsm then diff --git a/Mathlib/Tactic/MinImports.lean b/Mathlib/Tactic/MinImports.lean index f079b40e3b93d1..5ab5291ec79c36 100644 --- a/Mathlib/Tactic/MinImports.lean +++ b/Mathlib/Tactic/MinImports.lean @@ -84,7 +84,7 @@ def getId (stx : Syntax) : CommandElabM Syntax := do | none => return .missing | some stx => do -- if it is a nameless `instance`, we retrieve the autogenerated name - let dv ← mkDefViewOfInstance {} stx + let dv ← mkDefViewOfInstance { stx := ⟨stx⟩ } stx return dv.declId[0] /-- `getIds stx` extracts all identifiers, collecting them in a `NameSet`. -/ diff --git a/Mathlib/Tactic/MkIffOfInductiveProp.lean b/Mathlib/Tactic/MkIffOfInductiveProp.lean index 151383da0f1f03..9314f77ddb99dd 100644 --- a/Mathlib/Tactic/MkIffOfInductiveProp.lean +++ b/Mathlib/Tactic/MkIffOfInductiveProp.lean @@ -328,8 +328,8 @@ def mkIffOfInductivePropImpl (ind : Name) (rel : Name) (relStx : Syntax) : MetaM value := ← instantiateMVars mvar } addDeclarationRanges rel { - range := ← getDeclarationRange (← getRef) - selectionRange := ← getDeclarationRange relStx + range := (← getDeclarationRange? (← getRef)).get! + selectionRange := (← getDeclarationRange? relStx).get! } addConstInfo relStx rel @@ -406,7 +406,7 @@ initialize Lean.registerBuiltinAttribute { add := fun decl stx _ => Lean.Meta.MetaM.run' do let (tgt, idStx) ← match stx with | `(attr| mk_iff $tgt:ident) => - pure ((← mkDeclName (← getCurrNamespace) {} tgt.getId).1, tgt.raw) + pure ((← mkDeclName (← getCurrNamespace) { stx := ⟨.missing⟩ } tgt.getId).1, tgt.raw) | `(attr| mk_iff) => pure (decl.decapitalize.appendAfter "_iff", stx) | _ => throwError "unrecognized syntax" mkIffOfInductivePropImpl decl tgt idStx diff --git a/Mathlib/Tactic/Simps/Basic.lean b/Mathlib/Tactic/Simps/Basic.lean index 2e1f92afe80f39..08ca32c5dc8e15 100644 --- a/Mathlib/Tactic/Simps/Basic.lean +++ b/Mathlib/Tactic/Simps/Basic.lean @@ -975,8 +975,8 @@ def addProjection (declName : Name) (type lhs rhs : Expr) (args : Array Expr) catch ex => throwError "Failed to add projection lemma {declName}. Nested error:\n{ex.toMessageData}" addDeclarationRanges declName { - range := ← getDeclarationRange (← getRef) - selectionRange := ← getDeclarationRange ref } + range := (← getDeclarationRange? (← getRef)).get! + selectionRange := (← getDeclarationRange? ref).get! } _ ← MetaM.run' <| TermElabM.run' <| addTermInfo (isBinder := true) ref <| ← mkConstWithLevelParams declName if cfg.isSimp then diff --git a/Mathlib/Tactic/ToAdditive/Frontend.lean b/Mathlib/Tactic/ToAdditive/Frontend.lean index 196303d07578ba..b4388a6778e846 100644 --- a/Mathlib/Tactic/ToAdditive/Frontend.lean +++ b/Mathlib/Tactic/ToAdditive/Frontend.lean @@ -813,8 +813,8 @@ partial def transformDeclAux -- note: we currently also do this for auxiliary declarations, while they are not normally -- generated for those. We could change that. addDeclarationRanges tgt { - range := ← getDeclarationRange (← getRef) - selectionRange := ← getDeclarationRange cfg.ref } + range := (← getDeclarationRange? (← getRef)).get! + selectionRange := (← getDeclarationRange? cfg.ref).get! } if isProtected (← getEnv) src then setEnv <| addProtected (← getEnv) tgt if let some matcherInfo ← getMatcherInfo? src then diff --git a/Mathlib/Util/AddRelatedDecl.lean b/Mathlib/Util/AddRelatedDecl.lean index ecea6a5c315b86..c07862a04b2c8e 100644 --- a/Mathlib/Util/AddRelatedDecl.lean +++ b/Mathlib/Util/AddRelatedDecl.lean @@ -49,8 +49,8 @@ def addRelatedDecl (src : Name) (suffix : String) (ref : Syntax) | Name.str n s => Name.mkStr n <| s ++ suffix | x => x addDeclarationRanges tgt { - range := ← getDeclarationRange (← getRef) - selectionRange := ← getDeclarationRange ref } + range := (← getDeclarationRange? (← getRef)).get! + selectionRange := (← getDeclarationRange? ref).get! } let info ← getConstInfo src let (newValue, newLevels) ← construct info.type info.value! info.levelParams let newValue ← instantiateMVars newValue diff --git a/lake-manifest.json b/lake-manifest.json index dc7250b5e603f6..9c9b723e302df6 100644 --- a/lake-manifest.json +++ b/lake-manifest.json @@ -5,7 +5,7 @@ "type": "git", "subDir": null, "scope": "leanprover-community", - "rev": "924b31f5c475f7fa3ea30b24cfca2b21fb90ae71", + "rev": "46aeb3a35eea7490f9baf307f9c931c9b229310d", "name": "batteries", "manifestFile": "lake-manifest.json", "inputRev": "nightly-testing", From 4f6fe87330270550634d33b697ee21d8ec11fc43 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Sat, 19 Oct 2024 22:30:57 +1100 Subject: [PATCH 424/425] shake --- Mathlib/Algebra/BigOperators/Group/List.lean | 1 - Mathlib/Order/Defs.lean | 1 - Mathlib/Tactic/Linter/FlexibleLinter.lean | 1 - 3 files changed, 3 deletions(-) diff --git a/Mathlib/Algebra/BigOperators/Group/List.lean b/Mathlib/Algebra/BigOperators/Group/List.lean index a7bbbd486cdf5c..08b3745443eb98 100644 --- a/Mathlib/Algebra/BigOperators/Group/List.lean +++ b/Mathlib/Algebra/BigOperators/Group/List.lean @@ -9,7 +9,6 @@ import Mathlib.Algebra.Group.Nat import Mathlib.Algebra.Group.Opposite import Mathlib.Algebra.Group.Units.Basic import Mathlib.Data.List.Perm -import Mathlib.Data.List.ProdSigma import Mathlib.Data.List.Range import Mathlib.Data.List.Rotate import Mathlib.Data.List.Pairwise diff --git a/Mathlib/Order/Defs.lean b/Mathlib/Order/Defs.lean index 75d603ee2c080b..14a3cebd9de8f1 100644 --- a/Mathlib/Order/Defs.lean +++ b/Mathlib/Order/Defs.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Leonardo de Moura -/ import Batteries.Classes.Order -import Batteries.Tactic.Trans import Mathlib.Data.Ordering.Basic import Mathlib.Tactic.Lemma import Mathlib.Tactic.SplitIfs diff --git a/Mathlib/Tactic/Linter/FlexibleLinter.lean b/Mathlib/Tactic/Linter/FlexibleLinter.lean index ae157b8775b05f..f4408bdd146935 100644 --- a/Mathlib/Tactic/Linter/FlexibleLinter.lean +++ b/Mathlib/Tactic/Linter/FlexibleLinter.lean @@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Damiano Testa -/ import Lean.Elab.Command -import Batteries.Data.Array.Basic /-! # The "flexible" linter From 407a4459e2005e212bb230d2746afe980eba7003 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Sat, 19 Oct 2024 22:34:07 +1100 Subject: [PATCH 425/425] shake update --- Mathlib/Algebra/BigOperators/Group/List.lean | 1 + Mathlib/Order/Defs.lean | 1 + scripts/noshake.json | 2 ++ 3 files changed, 4 insertions(+) diff --git a/Mathlib/Algebra/BigOperators/Group/List.lean b/Mathlib/Algebra/BigOperators/Group/List.lean index 08b3745443eb98..7944a074da49ea 100644 --- a/Mathlib/Algebra/BigOperators/Group/List.lean +++ b/Mathlib/Algebra/BigOperators/Group/List.lean @@ -13,6 +13,7 @@ import Mathlib.Data.List.Range import Mathlib.Data.List.Rotate import Mathlib.Data.List.Pairwise import Mathlib.Data.List.Join +import Mathlib.Data.List.ProdSigma /-! # Sums and products from lists diff --git a/Mathlib/Order/Defs.lean b/Mathlib/Order/Defs.lean index 14a3cebd9de8f1..75d603ee2c080b 100644 --- a/Mathlib/Order/Defs.lean +++ b/Mathlib/Order/Defs.lean @@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE. Authors: Leonardo de Moura -/ import Batteries.Classes.Order +import Batteries.Tactic.Trans import Mathlib.Data.Ordering.Basic import Mathlib.Tactic.Lemma import Mathlib.Tactic.SplitIfs diff --git a/scripts/noshake.json b/scripts/noshake.json index b0c52f74712096..97b19e40ac899d 100644 --- a/scripts/noshake.json +++ b/scripts/noshake.json @@ -325,6 +325,7 @@ "Mathlib.Order.RelClasses": ["Batteries.WF"], "Mathlib.Order.Filter.ListTraverse": ["Mathlib.Control.Traversable.Instances"], + "Mathlib.Order.Defs": ["Batteries.Tactic.Trans"], "Mathlib.NumberTheory.Harmonic.Defs": ["Mathlib.Algebra.Order.BigOperators.Ring.Finset", "Mathlib.Algebra.Order.Field.Basic"], @@ -427,6 +428,7 @@ ["Mathlib.CategoryTheory.ConcreteCategory.ReflectsIso"], "Mathlib.Algebra.Category.MonCat.Basic": ["Mathlib.Algebra.Ring.Action.Group"], + "Mathlib.Algebra.BigOperators.Group.List": ["Mathlib.Data.List.ProdSigma"], "Mathlib.Algebra.Algebra.Subalgebra.Order": ["Mathlib.Algebra.Module.Submodule.Order"], "Batteries.Tactic.OpenPrivate": ["Lean.Parser.Module"],