From bace3558e3415747125be878c33c049640dfbfe4 Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Wed, 28 Jun 2023 12:38:36 -0500 Subject: [PATCH 001/127] first attempt --- Mathlib/Algebra/Group/Defs.lean | 36 +++++++++++++++++++++++++++++++++ Mathlib/Tactic/ToAdditive.lean | 1 + 2 files changed, 37 insertions(+) diff --git a/Mathlib/Algebra/Group/Defs.lean b/Mathlib/Algebra/Group/Defs.lean index d958592d082c02..e76a003ea4345c 100644 --- a/Mathlib/Algebra/Group/Defs.lean +++ b/Mathlib/Algebra/Group/Defs.lean @@ -243,11 +243,43 @@ end IsRightCancelMul end Mul +/- +There are several important design decisions to mention here. + +1. We don't phrase the power operation in semigroups in terms of `PNat := {x : ℕ // 0 < x}` because + this would require making a portion of the order hierarchy a dependency of this file. +2. We enforce the `n ≠ 0` requirement in `Semigroup.ppow` because a semigroup may be empty. + While we *could* just provide a junk value (e.g., `id`) when `n = 0`, we would lose the + extensionality of `Semigroup` as depending only on `Mul`. +-/ + +-- use `x * ppowRec n x` and not `ppowRec n x * x` in the definition to make sure that +-- definitional unfolding of `ppowRec` is blocked, to avoid deep recursion issues. +/-- The fundamental power operation in a semigroup. `ppowRec n a = a*a*...*a` n times. +Use instead `a ^ n`, which has better definitional behavior. -/ +def ppowRec [Mul M] : ∀ n : ℕ, n ≠ 0 → M → M + | 0, h, _ => (h rfl).elim + | 1, _, a => a + | n + 2, _, a => a * ppowRec (n + 1) n.succ_ne_zero a + +/-- The fundamental scalar multipication in an additive semigroup. `psmulRec n a = a+a+...+a` n +times. Use instead `a ^ n`, which has better definitional behavior. -/ +def psmulRec [Add M] : ∀ n : ℕ, n ≠ 0 → M → M + | 0, h, _ => (h rfl).elim + | 1, _, a => a + | n + 2, _, a => a + psmulRec (n + 1) n.succ_ne_zero a + +attribute [to_additive existing] ppowRec + /-- A semigroup is a type with an associative `(*)`. -/ @[ext] class Semigroup (G : Type u) extends Mul G where /-- Multiplication is associative -/ mul_assoc : ∀ a b c : G, a * b * c = a * (b * c) + ppow : ∀ n : ℕ, n ≠ 0 → G → G := ppowRec + ppow_one : ∀ g, ppow 1 Nat.one_ne_zero g = g := by intros; rfl + ppow_succ : ∀ g n, ppow (n + 2) (n + 1).succ_ne_zero g = g * ppow (n + 1) n.succ_ne_zero g := + by intros; rfl #align semigroup Semigroup #align semigroup.ext Semigroup.ext #align semigroup.ext_iff Semigroup.ext_iff @@ -257,6 +289,10 @@ class Semigroup (G : Type u) extends Mul G where class AddSemigroup (G : Type u) extends Add G where /-- Addition is associative -/ add_assoc : ∀ a b c : G, a + b + c = a + (b + c) + psmul : ∀ n : ℕ, n ≠ 0 → G → G := psmulRec + psmul_one : ∀ g, psmul 1 Nat.one_ne_zero g = g := by intros; rfl + psmul_succ : ∀ g n, psmul (n + 2) (n + 1).succ_ne_zero g = g + psmul (n + 1) n.succ_ne_zero g := + by intros; rfl #align add_semigroup AddSemigroup #align add_semigroup.ext AddSemigroup.ext #align add_semigroup.ext_iff AddSemigroup.ext_iff diff --git a/Mathlib/Tactic/ToAdditive.lean b/Mathlib/Tactic/ToAdditive.lean index 48cbc70e1e682c..dddb0f23f0c6dc 100644 --- a/Mathlib/Tactic/ToAdditive.lean +++ b/Mathlib/Tactic/ToAdditive.lean @@ -721,6 +721,7 @@ def nameDict : String → List String | "finprod" => ["finsum"] | "pow" => ["nsmul"] | "npow" => ["nsmul"] + | "ppow" => ["psmul"] | "zpow" => ["zsmul"] | "monoid" => ["add", "Monoid"] | "submonoid" => ["add", "Submonoid"] From ae1a0062dfdf2118b38fbc89204ffe7e0424683f Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Thu, 29 Jun 2023 00:48:37 -0500 Subject: [PATCH 002/127] try to fix --- .../Algebra/Category/FGModuleCat/Basic.lean | 4 +- Mathlib/Algebra/Group/Defs.lean | 36 +++----- Mathlib/Algebra/Group/Ext.lean | 37 +++++++- Mathlib/Algebra/Group/PPow.lean | 91 +++++++++++++++++++ Mathlib/Algebra/Group/TypeTags.lean | 18 +++- Mathlib/Algebra/Hom/Aut.lean | 2 + Mathlib/Algebra/Jordan/Basic.lean | 2 +- Mathlib/Algebra/Module/GradedModule.lean | 1 + Mathlib/Algebra/Ring/ULift.lean | 18 +++- Mathlib/Data/Num/Lemmas.lean | 27 +++++- Mathlib/Data/Real/Basic.lean | 2 + Mathlib/Data/ZMod/Defs.lean | 16 ++++ Mathlib/LinearAlgebra/LinearPMap.lean | 12 +-- Mathlib/LinearAlgebra/TensorPower.lean | 3 +- Mathlib/NumberTheory/Dioph.lean | 2 + Mathlib/RingTheory/IsTensorProduct.lean | 2 + Mathlib/RingTheory/MatrixAlgebra.lean | 1 + Mathlib/RingTheory/Polynomial/Quotient.lean | 3 +- Mathlib/RingTheory/TensorProduct.lean | 1 + 19 files changed, 230 insertions(+), 48 deletions(-) create mode 100644 Mathlib/Algebra/Group/PPow.lean diff --git a/Mathlib/Algebra/Category/FGModuleCat/Basic.lean b/Mathlib/Algebra/Category/FGModuleCat/Basic.lean index 6124c73289b27e..c86bc4fe2f6654 100644 --- a/Mathlib/Algebra/Category/FGModuleCat/Basic.lean +++ b/Mathlib/Algebra/Category/FGModuleCat/Basic.lean @@ -268,7 +268,7 @@ theorem FGModuleCatEvaluation_apply (f : FGModuleCatDual K V) (x : V) : -- Porting note: extremely slow, was fast in mathlib3. -- I tried many things using `dsimp` and `change`, but couldn't find anything faster than this. -set_option maxHeartbeats 1600000 in +set_option maxHeartbeats 2000000 in private theorem coevaluation_evaluation : letI V' : FGModuleCat K := FGModuleCatDual K V (𝟙 V' ⊗ FGModuleCatCoevaluation K V) ≫ (α_ V' V V').inv ≫ (FGModuleCatEvaluation K V ⊗ 𝟙 V') = @@ -276,7 +276,7 @@ private theorem coevaluation_evaluation : apply contractLeft_assoc_coevaluation K V -- Porting note: extremely slow, was fast in mathlib3. -set_option maxHeartbeats 1600000 in +set_option maxHeartbeats 2000000 in private theorem evaluation_coevaluation : (FGModuleCatCoevaluation K V ⊗ 𝟙 V) ≫ (α_ V (FGModuleCatDual K V) V).hom ≫ (𝟙 V ⊗ FGModuleCatEvaluation K V) = diff --git a/Mathlib/Algebra/Group/Defs.lean b/Mathlib/Algebra/Group/Defs.lean index e76a003ea4345c..706f51cc58550f 100644 --- a/Mathlib/Algebra/Group/Defs.lean +++ b/Mathlib/Algebra/Group/Defs.lean @@ -257,45 +257,39 @@ There are several important design decisions to mention here. -- definitional unfolding of `ppowRec` is blocked, to avoid deep recursion issues. /-- The fundamental power operation in a semigroup. `ppowRec n a = a*a*...*a` n times. Use instead `a ^ n`, which has better definitional behavior. -/ -def ppowRec [Mul M] : ∀ n : ℕ, n ≠ 0 → M → M - | 0, h, _ => (h rfl).elim +def ppowRec [Mul M] : ∀ n : ℕ, 0 < n → M → M + | 0, h, _ => (Nat.ne_of_lt h rfl).elim | 1, _, a => a - | n + 2, _, a => a * ppowRec (n + 1) n.succ_ne_zero a + | n + 2, _, a => a * ppowRec (n + 1) n.succ_pos a /-- The fundamental scalar multipication in an additive semigroup. `psmulRec n a = a+a+...+a` n times. Use instead `a ^ n`, which has better definitional behavior. -/ -def psmulRec [Add M] : ∀ n : ℕ, n ≠ 0 → M → M - | 0, h, _ => (h rfl).elim +def psmulRec [Add M] : ∀ n : ℕ, 0 < n → M → M + | 0, h, _ => (Nat.ne_of_lt h rfl).elim | 1, _, a => a - | n + 2, _, a => a + psmulRec (n + 1) n.succ_ne_zero a + | n + 2, _, a => a + psmulRec (n + 1) n.succ_pos a attribute [to_additive existing] ppowRec /-- A semigroup is a type with an associative `(*)`. -/ -@[ext] class Semigroup (G : Type u) extends Mul G where /-- Multiplication is associative -/ mul_assoc : ∀ a b c : G, a * b * c = a * (b * c) - ppow : ∀ n : ℕ, n ≠ 0 → G → G := ppowRec - ppow_one : ∀ g, ppow 1 Nat.one_ne_zero g = g := by intros; rfl - ppow_succ : ∀ g n, ppow (n + 2) (n + 1).succ_ne_zero g = g * ppow (n + 1) n.succ_ne_zero g := + ppow : ∀ n : ℕ, 0 < n → G → G := ppowRec + ppow_one : ∀ g, ppow 1 Nat.one_pos g = g := by intros; rfl + ppow_succ : ∀ g n, ppow (n + 2) (n + 1).succ_pos g = g * ppow (n + 1) n.succ_pos g := by intros; rfl #align semigroup Semigroup -#align semigroup.ext Semigroup.ext -#align semigroup.ext_iff Semigroup.ext_iff /-- An additive semigroup is a type with an associative `(+)`. -/ -@[ext] class AddSemigroup (G : Type u) extends Add G where /-- Addition is associative -/ add_assoc : ∀ a b c : G, a + b + c = a + (b + c) - psmul : ∀ n : ℕ, n ≠ 0 → G → G := psmulRec - psmul_one : ∀ g, psmul 1 Nat.one_ne_zero g = g := by intros; rfl - psmul_succ : ∀ g n, psmul (n + 2) (n + 1).succ_ne_zero g = g + psmul (n + 1) n.succ_ne_zero g := + psmul : ∀ n : ℕ, 0 < n → G → G := psmulRec + psmul_one : ∀ g, psmul 1 Nat.one_pos g = g := by intros; rfl + psmul_succ : ∀ g n, psmul (n + 2) (n + 1).succ_pos g = g + psmul (n + 1) n.succ_pos g := by intros; rfl #align add_semigroup AddSemigroup -#align add_semigroup.ext AddSemigroup.ext -#align add_semigroup.ext_iff AddSemigroup.ext_iff attribute [to_additive] Semigroup @@ -318,22 +312,16 @@ instance Semigroup.to_isAssociative : IsAssociative G (· * ·) := end Semigroup /-- A commutative semigroup is a type with an associative commutative `(*)`. -/ -@[ext] class CommSemigroup (G : Type u) extends Semigroup G where /-- Multiplication is commutative in a commutative semigroup. -/ mul_comm : ∀ a b : G, a * b = b * a #align comm_semigroup CommSemigroup -#align comm_semigroup.ext_iff CommSemigroup.ext_iff -#align comm_semigroup.ext CommSemigroup.ext /-- A commutative additive semigroup is a type with an associative commutative `(+)`. -/ -@[ext] class AddCommSemigroup (G : Type u) extends AddSemigroup G where /-- Addition is commutative in an additive commutative semigroup. -/ add_comm : ∀ a b : G, a + b = b + a #align add_comm_semigroup AddCommSemigroup -#align add_comm_semigroup.ext AddCommSemigroup.ext -#align add_comm_semigroup.ext_iff AddCommSemigroup.ext_iff attribute [to_additive] CommSemigroup diff --git a/Mathlib/Algebra/Group/Ext.lean b/Mathlib/Algebra/Group/Ext.lean index c140d3e5f3e7ec..89fe900c9a1c4e 100644 --- a/Mathlib/Algebra/Group/Ext.lean +++ b/Mathlib/Algebra/Group/Ext.lean @@ -9,6 +9,7 @@ Authors: Bryan Gin-ge Chen, Yury Kudryashov ! if you have ported upstream changes. -/ import Mathlib.Algebra.Hom.Group +import Mathlib.Algebra.Group.PPow /-! # Extensionality lemmas for monoid and group structures @@ -28,18 +29,50 @@ monoid, group, extensionality universe u +variable [Monoid M] + +@[to_additive (attr := ext)] +theorem Semigroup.ext {M : Type u} ⦃m₁ m₂ : Semigroup M⦄ (h_mul : m₁.mul = m₂.mul) : m₁ = m₂ := by + let f := @MulHom.mk _ _ m₁.toMul m₂.toMul id fun _ _ => congr_fun (congr_fun h_mul _) _ + have : m₁.ppow = m₂.ppow := by + ext n hn x + exact @map_ppow _ M M m₁ m₂ _ f x ⟨n, hn⟩ + rcases m₁ with @⟨@⟨_⟩, _⟩ + rcases m₂ with @⟨@⟨_⟩, _⟩ + congr +#align semigroup.ext Semigroup.extₓ +#noalign semigroup.ext_iff +#align add_semigroup.ext AddSemigroup.extₓ +#noalign add_semigroup.ext_iff + +@[to_additive] +theorem CommSemigroup.toSemigroup_injective {M : Type u} [Semigroup M] : + Function.Injective (@CommSemigroup.toSemigroup M) := by + rintro ⟨⟩ ⟨⟩ h + congr + +@[to_additive (attr := ext)] +theorem CommSemigroup.ext {M : Type _} ⦃m₁ m₂ : CommSemigroup M⦄ (h_mul : m₁.mul = m₂.mul) : + m₁ = m₂ := + CommSemigroup.toSemigroup_injective <| Semigroup.ext h_mul +#align comm_semigroup.ext CommSemigroup.extₓ +#noalign comm_semigroup.ext_iff +#align add_comm_semigroup.ext AddCommSemigroup.extₓ +#noalign add_comm_semigroup.ext_iff + @[to_additive (attr := ext)] theorem Monoid.ext {M : Type u} ⦃m₁ m₂ : Monoid M⦄ (h_mul : m₁.mul = m₂.mul) : m₁ = m₂ := by have : m₁.toMulOneClass = m₂.toMulOneClass := MulOneClass.ext h_mul have h₁ : m₁.one = m₂.one := congr_arg (·.one) (this) + have h₂ : m₁.toSemigroup = m₂.toSemigroup := Semigroup.ext h_mul let f : @MonoidHom M M m₁.toMulOneClass m₂.toMulOneClass := @MonoidHom.mk _ _ (_) _ (@OneHom.mk _ _ (_) _ id h₁) (fun x y => congr_fun (congr_fun h_mul x) y) have : m₁.npow = m₂.npow := by ext n x exact @MonoidHom.map_pow M M m₁ m₂ f x n - rcases m₁ with @⟨@⟨⟨_⟩⟩, ⟨_⟩⟩ - rcases m₂ with @⟨@⟨⟨_⟩⟩, ⟨_⟩⟩ + rcases m₁ with @⟨_, ⟨_⟩⟩ + rcases m₂ with @⟨_, ⟨_⟩⟩ congr #align monoid.ext Monoid.ext #align add_monoid.ext AddMonoid.ext diff --git a/Mathlib/Algebra/Group/PPow.lean b/Mathlib/Algebra/Group/PPow.lean new file mode 100644 index 00000000000000..508ccf88ff869c --- /dev/null +++ b/Mathlib/Algebra/Group/PPow.lean @@ -0,0 +1,91 @@ +import Mathlib.Algebra.GroupPower.Basic +import Mathlib.Data.PNat.Basic + +local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- See issue #2220 + +variable {M : Type _} + +instance Semigroup.instPow [Semigroup M] : Pow M ℕ+ where + pow x n := Semigroup.ppow n n.pos x + +instance AddSemigroup.instSMul [AddSemigroup M] : SMul ℕ+ M where + smul n x := AddSemigroup.psmul n n.pos x + +attribute [to_additive existing AddSemigroup.instSMul] Semigroup.instPow + +section Semigroup + +variable [Semigroup M] + +@[to_additive (attr := simp) one_psmul] +lemma ppow_one (x : M) : x ^ (1 : ℕ+) = x := Semigroup.ppow_one x + +@[to_additive succ_psmul'] +lemma ppow_succ' (x : M) (n : ℕ+) : x ^ (n + 1) = x * x ^ n := + n.recOn (Semigroup.ppow_succ x 0) fun k _ => Semigroup.ppow_succ x k + +@[to_additive succ_psmul] +lemma ppow_succ (x : M) (n : ℕ+) : x ^ (n + 1) = x ^ n * x := + n.recOn (by simp [ppow_succ']) fun k hk => by rw [ppow_succ' x k, ppow_succ', hk, mul_assoc] + +@[to_additive add_psmul] +lemma ppow_add (x : M) (n m : ℕ+) : x ^ (n + m) = x ^ n * x ^ m := + m.recOn (by simp [ppow_succ, add_comm]) fun k hk => by + rw [←add_assoc, ppow_succ, ppow_succ, hk, mul_assoc] + +@[to_additive mul_comm_psmul] +lemma ppow_mul_comm (x : M) (n m : ℕ+) : x ^ n * x ^ m = x ^ m * x ^ n := by + simp only [←ppow_add, add_comm] + +@[to_additive mul_comm_psmul'] +lemma ppow_mul_comm' (x : M) (n : ℕ+) : x ^ n * x = x * x ^ n := by + simpa only [ppow_one] using ppow_mul_comm x n 1 + +@[to_additive mul_psmul] +lemma ppow_mul (x : M) (n m : ℕ+) : x ^ (n * m) = (x ^ n) ^ m := + m.recOn (by simp) fun k hk => by simp [mul_add, ppow_add, hk] + +@[to_additive] +lemma Commute.ppow_left {x y : M} (h : Commute x y) (n : ℕ+) : Commute (x ^ n) y := + n.recOn ((ppow_one x).symm ▸ h) fun k hk => ppow_succ x k ▸ hk.mul_left h + +@[to_additive] +lemma Commute.ppow_right {x y : M} (h : Commute x y) (n : ℕ+) : Commute x (y ^ n) := + (h.symm.ppow_left n).symm + +@[to_additive Commute.psmul_add] +lemma Commute.mul_ppow {x y : M} (h : Commute x y) (n : ℕ+) : (x * y) ^ n = x ^ n * y ^ n := + n.recOn (by simp) fun k hk => by + simp only [ppow_succ, hk, mul_assoc] + rw [←mul_assoc x, ←mul_assoc (y ^ k)] + congr 2 + exact (h.symm.ppow_left k).eq + +end Semigroup + +section CommSemigroup + +variable [CommSemigroup M] + +@[to_additive psmul_add] +lemma mul_ppow (x y : M) (n : ℕ+) : (x * y) ^ n = x ^ n * y ^ n := + (Commute.all x y).mul_ppow n + +variable (M) + +@[to_additive (attr := simps)] +def ppowMulHom (n : ℕ+) : M →ₙ* M where + toFun x := x ^ n + map_mul' := mul_ppow (n := n) + +end CommSemigroup + +-- not marked as `simp` because in a monoid we probably prefer powers with type `ℕ` +@[to_additive (attr := norm_cast)] +lemma npow_val_eq_ppow [Monoid M] (x : M) (n : ℕ+) : x ^ (n : ℕ) = x ^ n := + n.recOn (by simp [pow_one]) fun k hk => by simp [pow_succ, ppow_succ', hk] + +@[to_additive] +lemma map_ppow {F M N : Type _} [Semigroup M] [Semigroup N] [MulHomClass F M N] + (f : F) (x : M) (n : ℕ+) : f (x ^ n) = f x ^ n := + n.recOn (by simp) fun k hk => by simp [ppow_succ, hk] diff --git a/Mathlib/Algebra/Group/TypeTags.lean b/Mathlib/Algebra/Group/TypeTags.lean index 4c00552ed23a2d..cd0920695e4f88 100644 --- a/Mathlib/Algebra/Group/TypeTags.lean +++ b/Mathlib/Algebra/Group/TypeTags.lean @@ -164,11 +164,19 @@ theorem ofMul_mul [Mul α] (x y : α) : ofMul (x * y) = ofMul x + ofMul y := rfl theorem toMul_add [Mul α] (x y : Additive α) : toMul (x + y) = toMul x * toMul y := rfl #align to_mul_add toMul_add -instance Additive.addSemigroup [Semigroup α] : AddSemigroup (Additive α) := - { Additive.add with add_assoc := @mul_assoc α _ } - -instance Multiplicative.semigroup [AddSemigroup α] : Semigroup (Multiplicative α) := - { Multiplicative.mul with mul_assoc := @add_assoc α _ } +instance Additive.addSemigroup [Semigroup α] : AddSemigroup (Additive α) where + toAdd := Additive.add + add_assoc := @mul_assoc α _ + psmul := @Semigroup.ppow α _ + psmul_one := @Semigroup.ppow_one α _ + psmul_succ := @Semigroup.ppow_succ α _ + +instance Multiplicative.semigroup [AddSemigroup α] : Semigroup (Multiplicative α) where + toMul := Multiplicative.mul + mul_assoc := @add_assoc α _ + ppow := @AddSemigroup.psmul α _ + ppow_one := @AddSemigroup.psmul_one α _ + ppow_succ := @AddSemigroup.psmul_succ α _ instance Additive.addCommSemigroup [CommSemigroup α] : AddCommSemigroup (Additive α) := { Additive.addSemigroup with add_comm := @mul_comm α _ } diff --git a/Mathlib/Algebra/Hom/Aut.lean b/Mathlib/Algebra/Hom/Aut.lean index 11bf4d498c1f82..2eb3380ec76338 100644 --- a/Mathlib/Algebra/Hom/Aut.lean +++ b/Mathlib/Algebra/Hom/Aut.lean @@ -55,6 +55,7 @@ instance : Group (MulAut M) := by one := MulEquiv.refl M inv := MulEquiv.symm div := fun g h => MulEquiv.trans h.symm g + ppow := @ppowRec _ ⟨fun g h => MulEquiv.trans h g⟩ npow := @npowRec _ ⟨MulEquiv.refl M⟩ ⟨fun g h => MulEquiv.trans h g⟩ zpow := @zpowRec _ ⟨MulEquiv.refl M⟩ ⟨fun g h => MulEquiv.trans h g⟩ ⟨MulEquiv.symm⟩ .. } <;> @@ -182,6 +183,7 @@ instance group : Group (AddAut A) := by one := AddEquiv.refl A inv := AddEquiv.symm div := fun g h => AddEquiv.trans h.symm g + ppow := @ppowRec _ ⟨fun g h => AddEquiv.trans h g⟩ npow := @npowRec _ ⟨AddEquiv.refl A⟩ ⟨fun g h => AddEquiv.trans h g⟩ zpow := @zpowRec _ ⟨AddEquiv.refl A⟩ ⟨fun g h => AddEquiv.trans h g⟩ ⟨AddEquiv.symm⟩ .. } <;> diff --git a/Mathlib/Algebra/Jordan/Basic.lean b/Mathlib/Algebra/Jordan/Basic.lean index d5ba7c01bf5585..d955d663966be4 100644 --- a/Mathlib/Algebra/Jordan/Basic.lean +++ b/Mathlib/Algebra/Jordan/Basic.lean @@ -211,7 +211,7 @@ private theorem aux1 {a b c : A} : rw [add_lie, add_lie] iterate 15 rw [lie_add] -set_option maxHeartbeats 300000 in +set_option maxHeartbeats 350000 in private theorem aux2 {a b c : A} : ⁅L a, L (a * a)⁆ + ⁅L a, L (b * b)⁆ + ⁅L a, L (c * c)⁆ + ⁅L a, 2 • L (a * b)⁆ + ⁅L a, 2 • L (c * a)⁆ + ⁅L a, 2 • L (b * c)⁆ + diff --git a/Mathlib/Algebra/Module/GradedModule.lean b/Mathlib/Algebra/Module/GradedModule.lean index 017cfae5a56466..719c79758db46a 100644 --- a/Mathlib/Algebra/Module/GradedModule.lean +++ b/Mathlib/Algebra/Module/GradedModule.lean @@ -220,6 +220,7 @@ def isModule [DecidableEq ι] [GradedRing 𝓐] : Module A (⨁ i, 𝓜 i) := smul := fun a b => DirectSum.decompose 𝓐 a • b } #align graded_module.is_module GradedModule.isModule +set_option synthInstance.maxHeartbeats 25000 in /-- `⨁ i, 𝓜 i` and `M` are isomorphic as `A`-modules. "The internal version" and "the external version" are isomorphism as `A`-modules. -/ diff --git a/Mathlib/Algebra/Ring/ULift.lean b/Mathlib/Algebra/Ring/ULift.lean index 7f2286553dd175..32a400fc604ed5 100644 --- a/Mathlib/Algebra/Ring/ULift.lean +++ b/Mathlib/Algebra/Ring/ULift.lean @@ -60,7 +60,9 @@ instance nonUnitalSemiring [NonUnitalSemiring α] : NonUnitalSemiring (ULift α) { zero := (0 : ULift α), add := (· + ·), mul := (· * ·), nsmul := AddMonoid.nsmul, add_assoc, zero_add, add_zero, add_comm, left_distrib, right_distrib, zero_mul, mul_zero, mul_assoc, nsmul_zero := fun _ => AddMonoid.nsmul_zero _, - nsmul_succ := fun _ _ => AddMonoid.nsmul_succ _ _ } + nsmul_succ := fun _ _ => AddMonoid.nsmul_succ _ _, + ppow := Semigroup.ppow, ppow_one := fun _ => Semigroup.ppow_one _, + ppow_succ := fun _ _ => Semigroup.ppow_succ _ _ } #align ulift.non_unital_semiring ULift.nonUnitalSemiring instance semiring [Semiring α] : Semiring (ULift α) := @@ -68,7 +70,9 @@ instance semiring [Semiring α] : Semiring (ULift α) := zero := (0 : ULift α), one := 1, add := (· + ·), mul := (· * ·), nsmul := AddMonoid.nsmul, npow := Monoid.npow, natCast := fun n => ULift.up n, add_comm, left_distrib, right_distrib, zero_mul, mul_zero, mul_assoc, one_mul, mul_one, npow_zero := fun _ => Monoid.npow_zero _, - npow_succ := fun _ _ => Monoid.npow_succ _ _ } + npow_succ := fun _ _ => Monoid.npow_succ _ _, + ppow := Semigroup.ppow, ppow_one := fun _ => Semigroup.ppow_one _, + ppow_succ := fun _ _ => Semigroup.ppow_succ _ _ } #align ulift.semiring ULift.semiring /-- The ring equivalence between `ULift α` and `α`.-/ @@ -85,7 +89,9 @@ instance nonUnitalCommSemiring [NonUnitalCommSemiring α] : NonUnitalCommSemirin { zero := (0 : ULift α), add := (· + ·), mul := (· * ·), nsmul := AddMonoid.nsmul, add_assoc, zero_add, add_zero, add_comm, left_distrib, right_distrib, zero_mul, mul_zero, mul_assoc, mul_comm, nsmul_zero := fun _ => AddMonoid.nsmul_zero _, - nsmul_succ := fun _ _ => AddMonoid.nsmul_succ _ _ } + nsmul_succ := fun _ _ => AddMonoid.nsmul_succ _ _, + ppow := Semigroup.ppow, ppow_one := fun _ => Semigroup.ppow_one _, + ppow_succ := fun _ _ => Semigroup.ppow_succ _ _ } #align ulift.non_unital_comm_semiring ULift.nonUnitalCommSemiring instance commSemiring [CommSemiring α] : CommSemiring (ULift α) := @@ -108,6 +114,8 @@ instance nonUnitalRing [NonUnitalRing α] : NonUnitalRing (ULift α) := { zero := (0 : ULift α), add := (· + ·), mul := (· * ·), sub := Sub.sub, neg := Neg.neg, nsmul := AddMonoid.nsmul, zsmul := SubNegMonoid.zsmul, add_assoc, zero_add, add_zero, add_comm, add_left_neg, left_distrib, right_distrib, zero_mul, mul_zero, mul_assoc, sub_eq_add_neg + ppow := Semigroup.ppow, ppow_one := fun _ => Semigroup.ppow_one _, + ppow_succ := fun _ _ => Semigroup.ppow_succ _ _, nsmul_zero := fun _ => AddMonoid.nsmul_zero _, nsmul_succ := fun _ _ => AddMonoid.nsmul_succ _ _, zsmul_zero' := SubNegMonoid.zsmul_zero', zsmul_succ' := SubNegMonoid.zsmul_succ', @@ -134,6 +142,8 @@ instance ring [Ring α] : Ring (ULift α) := intCast_ofNat := addGroupWithOne.intCast_ofNat, add_assoc, zero_add, add_zero, add_comm, left_distrib, right_distrib, zero_mul, mul_zero, mul_assoc, one_mul, mul_one, sub_eq_add_neg, add_left_neg, nsmul_zero := fun _ => AddMonoid.nsmul_zero _, natCast := fun n => ULift.up n, + ppow := Semigroup.ppow, ppow_one := fun _ => Semigroup.ppow_one _, + ppow_succ := fun _ _ => Semigroup.ppow_succ _ _, intCast := fun n => ULift.up n, nsmul_succ := fun _ _ => AddMonoid.nsmul_succ _ _, natCast_zero := AddMonoidWithOne.natCast_zero, natCast_succ := AddMonoidWithOne.natCast_succ, npow_zero := fun _ => Monoid.npow_zero _, npow_succ := fun _ _ => Monoid.npow_succ _ _, @@ -147,6 +157,8 @@ instance nonUnitalCommRing [NonUnitalCommRing α] : NonUnitalCommRing (ULift α) mul_zero, left_distrib, right_distrib, add_comm, mul_assoc, mul_comm, nsmul_zero := fun _ => AddMonoid.nsmul_zero _, add_left_neg, nsmul_succ := fun _ _ => AddMonoid.nsmul_succ _ _, sub_eq_add_neg, + ppow := Semigroup.ppow, ppow_one := fun _ => Semigroup.ppow_one _, + ppow_succ := fun _ _ => Semigroup.ppow_succ _ _, zsmul_zero' := SubNegMonoid.zsmul_zero', zsmul_succ' := SubNegMonoid.zsmul_succ', zsmul_neg' := SubNegMonoid.zsmul_neg'.. } diff --git a/Mathlib/Data/Num/Lemmas.lean b/Mathlib/Data/Num/Lemmas.lean index 9039db9e248f3e..2cd1d336fd5dcf 100644 --- a/Mathlib/Data/Num/Lemmas.lean +++ b/Mathlib/Data/Num/Lemmas.lean @@ -13,6 +13,7 @@ import Mathlib.Data.Int.CharZero import Mathlib.Data.Nat.GCD.Basic import Mathlib.Data.Nat.PSub import Mathlib.Data.Nat.Size +import Mathlib.Data.PNat.Basic /-! # Properties of the binary representation of integers @@ -131,6 +132,19 @@ theorem mul_to_nat (m) : ∀ n, ((m * n : PosNum) : ℕ) = m * n show (↑(m * p) + ↑(m * p) + ↑m : ℕ) = ↑m * (p + p) + m by rw [mul_to_nat m p, left_distrib] #align pos_num.mul_to_nat PosNum.mul_to_nat +@[norm_cast] +theorem ppowRec_to_nat (m : PosNum) : ∀ n : ℕ, (hn : 0 < n) → ppowRec n hn (m : ℕ) = ppowRec n hn m +| 0, h => (Nat.not_lt_zero 0 h).elim +| 1, _ => rfl +| n + 2, _ => by rw [ppowRec, ppowRec_to_nat m (n + 1)]; norm_cast + +@[norm_cast] +theorem psmulRec_to_nat (m : PosNum) : + ∀ n : ℕ, (hn : 0 < n) → psmulRec n hn (m : ℕ) = psmulRec n hn m +| 0, h => (Nat.not_lt_zero 0 h).elim +| 1, _ => rfl +| n + 2, _ => by rw [psmulRec, psmulRec_to_nat m (n + 1)]; norm_cast + theorem to_nat_pos : ∀ n : PosNum, 0 < (n : ℕ) | 1 => zero_lt_one | bit0 p => @@ -415,6 +429,7 @@ instance commSemiring : CommSemiring Num := by one := 1 add := (· + ·) zero := 0 + ppow := @ppowRec Num ⟨(· * ·)⟩ npow := @npowRec Num ⟨1⟩ ⟨(· * ·)⟩, .. } <;> try { intros; rfl } <;> transfer <;> @@ -591,8 +606,9 @@ example (n : PosNum) (m : PosNum) : n ≤ n + m := by exact Nat.le_add_right _ _ ``` -/ + scoped macro (name := transfer_rw) "transfer_rw" : tactic => `(tactic| - (repeat first | rw [← to_nat_inj] | rw [← lt_to_nat] | rw [← le_to_nat] + (repeat first | rw [← to_nat_inj] | rw [← lt_to_nat] | rw [← le_to_nat] | rw [← psmulRec_to_nat] repeat first | rw [add_to_nat] | rw [mul_to_nat] | rw [cast_one] | rw [cast_zero])) /-- @@ -606,14 +622,19 @@ scoped macro (name := transfer) "transfer" : tactic => `(tactic| (intros; transfer_rw; try simp [add_comm, add_left_comm, mul_comm, mul_left_comm])) instance addCommSemigroup : AddCommSemigroup PosNum := by - refine' { add := (· + ·).. } <;> transfer + refine' { add := (· + ·), psmul := @psmulRec PosNum ⟨(· + ·)⟩.. } <;> transfer; + convert rfl using 1 + norm_cast + + #align pos_num.add_comm_semigroup PosNum.addCommSemigroup instance commMonoid : CommMonoid PosNum := by refine' { mul := (· * ·) one := (1 : PosNum) - npow := @npowRec PosNum ⟨1⟩ ⟨(· * ·)⟩,.. } <;> + ppow := @ppowRec PosNum ⟨(· * ·)⟩ + npow := @npowRec PosNum ⟨1⟩ ⟨(· * ·)⟩ ,.. } <;> try { intros ; rfl } <;> transfer #align pos_num.comm_monoid PosNum.commMonoid diff --git a/Mathlib/Data/Real/Basic.lean b/Mathlib/Data/Real/Basic.lean index 9c970709902038..09d4c96e374a3b 100644 --- a/Mathlib/Data/Real/Basic.lean +++ b/Mathlib/Data/Real/Basic.lean @@ -212,7 +212,9 @@ instance commRing : CommRing ℝ := by add := (· + ·) neg := @Neg.neg ℝ _ sub := @Sub.sub ℝ _ + ppow := @ppowRec ℝ ⟨(· * ·)⟩ npow := @npowRec ℝ ⟨1⟩ ⟨(· * ·)⟩ + psmul := @psmulRec ℝ ⟨(· + ·)⟩ nsmul := @nsmulRec ℝ ⟨0⟩ ⟨(· + ·)⟩ zsmul := @zsmulRec ℝ ⟨0⟩ ⟨(· + ·)⟩ ⟨@Neg.neg ℝ _⟩, .. } diff --git a/Mathlib/Data/ZMod/Defs.lean b/Mathlib/Data/ZMod/Defs.lean index f97ea8276206b2..6187cdb0940385 100644 --- a/Mathlib/Data/ZMod/Defs.lean +++ b/Mathlib/Data/ZMod/Defs.lean @@ -145,6 +145,14 @@ instance commRing (n : ℕ) : CommRing (ZMod n) where nsmul_succ := Nat.casesOn n (inferInstanceAs (CommRing ℤ)).nsmul_succ fun n => (inferInstanceAs (CommRing (Fin n.succ))).nsmul_succ + psmul := Nat.casesOn n + (inferInstanceAs (CommRing ℤ)).psmul fun n => (inferInstanceAs (CommRing (Fin n.succ))).psmul + psmul_one := Nat.casesOn n + (inferInstanceAs (CommRing ℤ)).psmul_one + fun n => (inferInstanceAs (CommRing (Fin n.succ))).psmul_one + psmul_succ := Nat.casesOn n + (inferInstanceAs (CommRing ℤ)).psmul_succ + fun n => (inferInstanceAs (CommRing (Fin n.succ))).psmul_succ -- porting note: `match` didn't work here add_left_neg := Nat.casesOn n (@add_left_neg Int _) fun n => @add_left_neg (Fin n.succ) _ add_comm := Nat.casesOn n (@add_comm Int _) fun n => @add_comm (Fin n.succ) _ @@ -177,6 +185,14 @@ instance commRing (n : ℕ) : CommRing (ZMod n) where npow_succ := Nat.casesOn n (inferInstanceAs (CommRing ℤ)).npow_succ fun n => (inferInstanceAs (CommRing (Fin n.succ))).npow_succ + ppow := Nat.casesOn n + (inferInstanceAs (CommRing ℤ)).ppow fun n => (inferInstanceAs (CommRing (Fin n.succ))).ppow + ppow_one := Nat.casesOn n + (inferInstanceAs (CommRing ℤ)).ppow_one + fun n => (inferInstanceAs (CommRing (Fin n.succ))).ppow_one + ppow_succ := Nat.casesOn n + (inferInstanceAs (CommRing ℤ)).ppow_succ + fun n => (inferInstanceAs (CommRing (Fin n.succ))).ppow_succ #align zmod.comm_ring ZMod.commRing instance inhabited (n : ℕ) : Inhabited (ZMod n) := diff --git a/Mathlib/LinearAlgebra/LinearPMap.lean b/Mathlib/LinearAlgebra/LinearPMap.lean index ff0cc13f58ec9d..0c229b38a76d4f 100644 --- a/Mathlib/LinearAlgebra/LinearPMap.lean +++ b/Mathlib/LinearAlgebra/LinearPMap.lean @@ -472,17 +472,17 @@ theorem add_domain (f g : E →ₗ.[R] F) : (f + g).domain = f.domain ⊓ g.doma theorem add_apply (f g : E →ₗ.[R] F) (x : (f.domain ⊓ g.domain : Submodule R E)) : (f + g) x = f ⟨x, x.prop.1⟩ + g ⟨x, x.prop.2⟩ := rfl -instance instAddSemigroup : AddSemigroup (E →ₗ.[R] F) := - ⟨fun f g h => by +instance instAddSemigroup : AddSemigroup (E →ₗ.[R] F) where + add_assoc := fun f g h => by ext x y hxy · simp only [add_domain, inf_assoc] - · simp only [add_apply, hxy, add_assoc]⟩ + · simp only [add_apply, hxy, add_assoc] -instance instAddCommSemigroup : AddCommSemigroup (E →ₗ.[R] F) := - ⟨fun f g => by +instance instAddCommSemigroup : AddCommSemigroup (E →ₗ.[R] F) where + add_comm := fun f g => by ext x y hxy · simp only [add_domain, inf_comm] - · simp only [add_apply, hxy, add_comm]⟩ + · simp only [add_apply, hxy, add_comm] instance instAddZeroClass : AddZeroClass (E →ₗ.[R] F) := ⟨fun f => by diff --git a/Mathlib/LinearAlgebra/TensorPower.lean b/Mathlib/LinearAlgebra/TensorPower.lean index c4b7f20a7fb3a2..c7e6081a8e75d0 100644 --- a/Mathlib/LinearAlgebra/TensorPower.lean +++ b/Mathlib/LinearAlgebra/TensorPower.lean @@ -259,7 +259,7 @@ theorem algebraMap₀_mul_algebraMap₀ (r s : R) : exact algebraMap₀_mul r (@algebraMap₀ R M _ _ _ s) #align tensor_power.algebra_map₀_mul_algebra_map₀ TensorPower.algebraMap₀_mul_algebraMap₀ -set_option maxHeartbeats 250000 in +set_option maxHeartbeats 300000 in instance gsemiring : DirectSum.GSemiring fun i => (⨂[R]^i) M := { TensorPower.gmonoid with mul_zero := fun a => LinearMap.map_zero _ @@ -273,6 +273,7 @@ instance gsemiring : DirectSum.GSemiring fun i => (⨂[R]^i) M := example : Semiring (⨁ n : ℕ, (⨂[R]^n) M) := by infer_instance +set_option maxHeartbeats 250000 in /-- The tensor powers form a graded algebra. Note that this instance implies `Algebra R (⨁ n : ℕ, ⨂[R]^n M)` via `DirectSum.Algebra`. -/ diff --git a/Mathlib/NumberTheory/Dioph.lean b/Mathlib/NumberTheory/Dioph.lean index 602fdd8cfbd2f6..c0f25c45b77e04 100644 --- a/Mathlib/NumberTheory/Dioph.lean +++ b/Mathlib/NumberTheory/Dioph.lean @@ -204,6 +204,7 @@ instance : AddCommGroup (Poly α) := by zero := 0 zsmul := @zsmulRec _ ⟨(0 : Poly α)⟩ ⟨(· + ·)⟩ ⟨Neg.neg⟩ nsmul := @nsmulRec _ ⟨(0 : Poly α)⟩ ⟨(· + ·)⟩ + psmul := @psmulRec _ ⟨(· + ·)⟩ .. } all_goals intros @@ -231,6 +232,7 @@ instance : CommRing (Poly α) := by mul := (· * ·) one := 1 npow := @npowRec _ ⟨(1 : Poly α)⟩ ⟨(· * ·)⟩ + ppow := @ppowRec _ ⟨(· * ·)⟩ .. } all_goals intros diff --git a/Mathlib/RingTheory/IsTensorProduct.lean b/Mathlib/RingTheory/IsTensorProduct.lean index 4e32544c844f6e..7fa0d4380e4a91 100644 --- a/Mathlib/RingTheory/IsTensorProduct.lean +++ b/Mathlib/RingTheory/IsTensorProduct.lean @@ -418,11 +418,13 @@ variable {R S R'} attribute [local instance] Algebra.TensorProduct.rightAlgebra +set_option maxHeartbeats 350000 in instance TensorProduct.isPushout {R S T : Type _} [CommRing R] [CommRing S] [CommRing T] [Algebra R S] [Algebra R T] : Algebra.IsPushout R S T (TensorProduct R S T) := ⟨TensorProduct.isBaseChange R T S⟩ #align tensor_product.is_pushout TensorProduct.isPushout +set_option maxHeartbeats 350000 in instance TensorProduct.isPushout' {R S T : Type _} [CommRing R] [CommRing S] [CommRing T] [Algebra R S] [Algebra R T] : Algebra.IsPushout R T S (TensorProduct R S T) := Algebra.IsPushout.symm inferInstance diff --git a/Mathlib/RingTheory/MatrixAlgebra.lean b/Mathlib/RingTheory/MatrixAlgebra.lean index 8805e625ab6dca..6aa98633f7c3be 100644 --- a/Mathlib/RingTheory/MatrixAlgebra.lean +++ b/Mathlib/RingTheory/MatrixAlgebra.lean @@ -129,6 +129,7 @@ theorem right_inv (M : Matrix n n A) : (toFunAlgHom R A n) (invFun R A n M) = M split_ifs <;> aesop #align matrix_equiv_tensor.right_inv MatrixEquivTensor.right_inv +set_option synthInstance.maxHeartbeats 30000 in theorem left_inv (M : A ⊗[R] Matrix n n R) : invFun R A n (toFunAlgHom R A n M) = M := by induction' M using TensorProduct.induction_on with a m x y hx hy · simp diff --git a/Mathlib/RingTheory/Polynomial/Quotient.lean b/Mathlib/RingTheory/Polynomial/Quotient.lean index 480646c9e83fd6..2bd4e6bd3d4514 100644 --- a/Mathlib/RingTheory/Polynomial/Quotient.lean +++ b/Mathlib/RingTheory/Polynomial/Quotient.lean @@ -66,7 +66,7 @@ noncomputable def quotientSpanCXSubCAlgEquiv (x y : R) : simp only [Ideal.map_span, Set.image_singleton]; congr 2; exact eval_C #align polynomial.quotient_span_C_X_sub_C_alg_equiv Polynomial.quotientSpanCXSubCAlgEquiv -set_option maxHeartbeats 250000 in +set_option maxHeartbeats 350000 in /-- For a commutative ring $R$, evaluating a polynomial at elements $y(X) \in R[X]$ and $x \in R$ induces an isomorphism of $R$-algebras $R[X, Y] / \langle X - x, Y - y(X) \rangle \cong R$. -/ noncomputable def quotientSpanCXSubCXSubCAlgEquiv {x : R} {y : R[X]} : @@ -209,6 +209,7 @@ theorem quotient_map_C_eq_zero {I : Ideal R} {i : R} (hi : i ∈ I) : exact Ideal.mem_map_of_mem _ hi #align mv_polynomial.quotient_map_C_eq_zero MvPolynomial.quotient_map_C_eq_zero +set_option synthInstance.maxHeartbeats 20100 in theorem eval₂_C_mk_eq_zero {I : Ideal R} {a : MvPolynomial σ R} (ha : a ∈ (Ideal.map (C : R →+* MvPolynomial σ R) I : Ideal (MvPolynomial σ R))) : eval₂Hom (C.comp (Ideal.Quotient.mk I)) X a = 0 := by diff --git a/Mathlib/RingTheory/TensorProduct.lean b/Mathlib/RingTheory/TensorProduct.lean index 4838164037fe07..71ea5622167fb9 100644 --- a/Mathlib/RingTheory/TensorProduct.lean +++ b/Mathlib/RingTheory/TensorProduct.lean @@ -453,6 +453,7 @@ instance : Semiring (A ⊗[R] B) := zero_add := zero_add add_zero := add_zero add_comm := add_comm + psmul_succ := AddSemigroup.psmul_succ nsmul_succ := AddMonoid.nsmul_succ natCast_succ := AddMonoidWithOne.natCast_succ zero_mul := fun a => show mul 0 a = 0 by rw [map_zero, LinearMap.zero_apply] From 9380937956d44e20f4892e9707cf7a418512bd38 Mon Sep 17 00:00:00 2001 From: Christopher Hoskin Date: Tue, 23 Apr 2024 06:00:34 +0100 Subject: [PATCH 003/127] Fix up --- Mathlib/Algebra/Group/Aut.lean | 44 +++++++++-------------- Mathlib/Algebra/Group/Defs.lean | 5 ++- Mathlib/Algebra/Group/Ext.lean | 8 +++-- Mathlib/Algebra/Group/PNatPowAssoc.lean | 2 ++ Mathlib/Algebra/Group/PPow.lean | 10 ++++-- Mathlib/AlgebraicGeometry/Properties.lean | 1 + 6 files changed, 34 insertions(+), 36 deletions(-) diff --git a/Mathlib/Algebra/Group/Aut.lean b/Mathlib/Algebra/Group/Aut.lean index 8abac90115a324..7e1f5afa40fc17 100644 --- a/Mathlib/Algebra/Group/Aut.lean +++ b/Mathlib/Algebra/Group/Aut.lean @@ -46,20 +46,14 @@ variable (M) [Mul M] /-- The group operation on multiplicative automorphisms is defined by `g h => MulEquiv.trans h g`. This means that multiplication agrees with composition, `(g*h)(x) = g (h x)`. -/ -instance : Group (MulAut M) := by - refine' - { mul := fun g h => MulEquiv.trans h g - one := MulEquiv.refl M - inv := MulEquiv.symm - div := fun g h => MulEquiv.trans h.symm g - ppow := @ppowRec _ ⟨fun g h => MulEquiv.trans h g⟩ - npow := @npowRec _ ⟨MulEquiv.refl M⟩ ⟨fun g h => MulEquiv.trans h g⟩ - zpow := @zpowRec _ ⟨MulEquiv.refl M⟩ ⟨fun g h => MulEquiv.trans h g⟩ ⟨MulEquiv.symm⟩ - .. } <;> - intros <;> - ext <;> - try rfl - apply Equiv.left_inv +instance : Group (MulAut M) where + mul g h := MulEquiv.trans h g + one := MulEquiv.refl _ + inv := MulEquiv.symm + mul_assoc _ _ _ := rfl + one_mul _ := rfl + mul_one _ := rfl + mul_left_inv := MulEquiv.self_trans_symm instance : Inhabited (MulAut M) := ⟨1⟩ @@ -174,20 +168,14 @@ variable (A) [Add A] /-- The group operation on additive automorphisms is defined by `g h => AddEquiv.trans h g`. This means that multiplication agrees with composition, `(g*h)(x) = g (h x)`. -/ -instance group : Group (AddAut A) := by - refine' - { mul := fun g h => AddEquiv.trans h g - one := AddEquiv.refl A - inv := AddEquiv.symm - div := fun g h => AddEquiv.trans h.symm g - ppow := @ppowRec _ ⟨fun g h => AddEquiv.trans h g⟩ - npow := @npowRec _ ⟨AddEquiv.refl A⟩ ⟨fun g h => AddEquiv.trans h g⟩ - zpow := @zpowRec _ ⟨AddEquiv.refl A⟩ ⟨fun g h => AddEquiv.trans h g⟩ ⟨AddEquiv.symm⟩ - .. } <;> - intros <;> - ext <;> - try rfl - apply Equiv.left_inv +instance group : Group (AddAut A) where + mul g h := AddEquiv.trans h g + one := AddEquiv.refl _ + inv := AddEquiv.symm + mul_assoc _ _ _ := rfl + one_mul _ := rfl + mul_one _ := rfl + mul_left_inv := AddEquiv.self_trans_symm #align add_aut.group AddAut.group instance : Inhabited (AddAut A) := diff --git a/Mathlib/Algebra/Group/Defs.lean b/Mathlib/Algebra/Group/Defs.lean index cf255bf7a311da..e8f42b66713e18 100644 --- a/Mathlib/Algebra/Group/Defs.lean +++ b/Mathlib/Algebra/Group/Defs.lean @@ -272,14 +272,14 @@ There are several important design decisions to mention here. -- definitional unfolding of `ppowRec` is blocked, to avoid deep recursion issues. /-- The fundamental power operation in a semigroup. `ppowRec n a = a*a*...*a` n times. Use instead `a ^ n`, which has better definitional behavior. -/ -def ppowRec [Mul M] : ∀ n : ℕ, 0 < n → M → M +def ppowRec {M : Type*} [Mul M] : ∀ n : ℕ, 0 < n → M → M | 0, h, _ => (Nat.ne_of_lt h rfl).elim | 1, _, a => a | n + 2, _, a => a * ppowRec (n + 1) n.succ_pos a /-- The fundamental scalar multipication in an additive semigroup. `psmulRec n a = a+a+...+a` n times. Use instead `a ^ n`, which has better definitional behavior. -/ -def psmulRec [Add M] : ∀ n : ℕ, 0 < n → M → M +def psmulRec {M : Type*} [Add M] : ∀ n : ℕ, 0 < n → M → M | 0, h, _ => (Nat.ne_of_lt h rfl).elim | 1, _, a => a | n + 2, _, a => a + psmulRec (n + 1) n.succ_pos a @@ -335,7 +335,6 @@ class CommMagma (G : Type u) extends Mul G where attribute [to_additive] CommMagma /-- A commutative semigroup is a type with an associative commutative `(*)`. -/ -@[ext] class CommSemigroup (G : Type u) extends Semigroup G, CommMagma G where #align comm_semigroup CommSemigroup diff --git a/Mathlib/Algebra/Group/Ext.lean b/Mathlib/Algebra/Group/Ext.lean index e417879abf55bd..788ef998a19026 100644 --- a/Mathlib/Algebra/Group/Ext.lean +++ b/Mathlib/Algebra/Group/Ext.lean @@ -3,7 +3,6 @@ Copyright (c) 2021 Bryan Gin-ge Chen. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Bryan Gin-ge Chen, Yury Kudryashov -/ -import Mathlib.Algebra.Hom.Group import Mathlib.Algebra.Group.PPow import Mathlib.Algebra.Group.Hom.Defs @@ -33,14 +32,14 @@ open Function universe u -variable [Monoid M] +variable {M : Type*} [Monoid M] @[to_additive (attr := ext)] theorem Semigroup.ext {M : Type u} ⦃m₁ m₂ : Semigroup M⦄ (h_mul : m₁.mul = m₂.mul) : m₁ = m₂ := by let f := @MulHom.mk _ _ m₁.toMul m₂.toMul id fun _ _ => congr_fun (congr_fun h_mul _) _ have : m₁.ppow = m₂.ppow := by ext n hn x - exact @map_ppow _ M M m₁ m₂ _ f x ⟨n, hn⟩ + exact @map_ppow _ M M m₁ m₂ _ _ f x ⟨n, hn⟩ rcases m₁ with @⟨@⟨_⟩, _⟩ rcases m₂ with @⟨@⟨_⟩, _⟩ congr @@ -49,12 +48,14 @@ theorem Semigroup.ext {M : Type u} ⦃m₁ m₂ : Semigroup M⦄ (h_mul : m₁.m #align add_semigroup.ext AddSemigroup.extₓ #noalign add_semigroup.ext_iff + @[to_additive] theorem CommSemigroup.toSemigroup_injective {M : Type u} [Semigroup M] : Function.Injective (@CommSemigroup.toSemigroup M) := by rintro ⟨⟩ ⟨⟩ h congr + @[to_additive (attr := ext)] theorem CommSemigroup.ext {M : Type _} ⦃m₁ m₂ : CommSemigroup M⦄ (h_mul : m₁.mul = m₂.mul) : m₁ = m₂ := @@ -64,6 +65,7 @@ theorem CommSemigroup.ext {M : Type _} ⦃m₁ m₂ : CommSemigroup M⦄ (h_mul #align add_comm_semigroup.ext AddCommSemigroup.extₓ #noalign add_comm_semigroup.ext_iff + @[to_additive (attr := ext)] theorem Monoid.ext {M : Type u} ⦃m₁ m₂ : Monoid M⦄ (h_mul : (letI := m₁; HMul.hMul : M → M → M) = (letI := m₂; HMul.hMul : M → M → M)) : diff --git a/Mathlib/Algebra/Group/PNatPowAssoc.lean b/Mathlib/Algebra/Group/PNatPowAssoc.lean index 0139823c743870..2715be8686e796 100644 --- a/Mathlib/Algebra/Group/PNatPowAssoc.lean +++ b/Mathlib/Algebra/Group/PNatPowAssoc.lean @@ -47,6 +47,8 @@ class PNatPowAssoc (M : Type*) [Mul M] [Pow M ℕ+] : Prop where /-- Exponent one is identity. -/ protected ppow_one : ∀ (x : M), x ^ (1 : ℕ+) = x +namespace Mul + section Mul variable [Mul M] [Pow M ℕ+] [PNatPowAssoc M] diff --git a/Mathlib/Algebra/Group/PPow.lean b/Mathlib/Algebra/Group/PPow.lean index 508ccf88ff869c..223b4eccaea645 100644 --- a/Mathlib/Algebra/Group/PPow.lean +++ b/Mathlib/Algebra/Group/PPow.lean @@ -80,12 +80,18 @@ def ppowMulHom (n : ℕ+) : M →ₙ* M where end CommSemigroup +@[to_additive] +theorem pow_mul_comm'' [Monoid M] (a : M) (n : ℕ+) : a ^ n * a = a * a ^ n := by + exact ppow_mul_comm' a n + -- not marked as `simp` because in a monoid we probably prefer powers with type `ℕ` @[to_additive (attr := norm_cast)] lemma npow_val_eq_ppow [Monoid M] (x : M) (n : ℕ+) : x ^ (n : ℕ) = x ^ n := - n.recOn (by simp [pow_one]) fun k hk => by simp [pow_succ, ppow_succ', hk] + n.recOn (by simp [pow_one]) fun k hk => by + simp [pow_succ, ppow_succ', hk] + rw [pow_mul_comm''] @[to_additive] -lemma map_ppow {F M N : Type _} [Semigroup M] [Semigroup N] [MulHomClass F M N] +lemma map_ppow {F M N : Type _} [Semigroup M] [Semigroup N] [FunLike F M N] [MulHomClass F M N] (f : F) (x : M) (n : ℕ+) : f (x ^ n) = f x ^ n := n.recOn (by simp) fun k hk => by simp [ppow_succ, hk] diff --git a/Mathlib/AlgebraicGeometry/Properties.lean b/Mathlib/AlgebraicGeometry/Properties.lean index 368a5b4e534124..ddb1ab80622b16 100644 --- a/Mathlib/AlgebraicGeometry/Properties.lean +++ b/Mathlib/AlgebraicGeometry/Properties.lean @@ -89,6 +89,7 @@ theorem isReducedOfOpenImmersion {X Y : Scheme} (f : X ⟶ Y) [H : IsOpenImmersi Y.presheaf.obj _ ≅ _).symm.commRingCatIsoToRingEquiv.injective #align algebraic_geometry.is_reduced_of_open_immersion AlgebraicGeometry.isReducedOfOpenImmersion +set_option maxHeartbeats 250000 in instance {R : CommRingCat} [H : _root_.IsReduced R] : IsReduced (Scheme.Spec.obj <| op R) := by apply (config := { allowSynthFailures := true }) isReducedOfStalkIsReduced intro x; dsimp From f4a060f61760cd5d39cccb9e9b6c7069a090d75d Mon Sep 17 00:00:00 2001 From: Christopher Hoskin Date: Tue, 23 Apr 2024 06:24:10 +0100 Subject: [PATCH 004/127] Lint --- Mathlib/Algebra/Group/PPow.lean | 16 +++++++++++++--- Mathlib/Data/Num/Lemmas.lean | 8 ++++---- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/Mathlib/Algebra/Group/PPow.lean b/Mathlib/Algebra/Group/PPow.lean index 223b4eccaea645..63473a447c240c 100644 --- a/Mathlib/Algebra/Group/PPow.lean +++ b/Mathlib/Algebra/Group/PPow.lean @@ -1,3 +1,13 @@ +/- +Copyright (c) 2024 Jireh Loreaux. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jireh Loreaux +-/ + +/-! +# TODO : Fill in module docstring +-/ + import Mathlib.Algebra.GroupPower.Basic import Mathlib.Data.PNat.Basic @@ -31,11 +41,11 @@ lemma ppow_succ (x : M) (n : ℕ+) : x ^ (n + 1) = x ^ n * x := @[to_additive add_psmul] lemma ppow_add (x : M) (n m : ℕ+) : x ^ (n + m) = x ^ n * x ^ m := m.recOn (by simp [ppow_succ, add_comm]) fun k hk => by - rw [←add_assoc, ppow_succ, ppow_succ, hk, mul_assoc] + rw [← add_assoc, ppow_succ, ppow_succ, hk, mul_assoc] @[to_additive mul_comm_psmul] lemma ppow_mul_comm (x : M) (n m : ℕ+) : x ^ n * x ^ m = x ^ m * x ^ n := by - simp only [←ppow_add, add_comm] + simp only [← ppow_add, add_comm] @[to_additive mul_comm_psmul'] lemma ppow_mul_comm' (x : M) (n : ℕ+) : x ^ n * x = x * x ^ n := by @@ -57,7 +67,7 @@ lemma Commute.ppow_right {x y : M} (h : Commute x y) (n : ℕ+) : Commute x (y ^ lemma Commute.mul_ppow {x y : M} (h : Commute x y) (n : ℕ+) : (x * y) ^ n = x ^ n * y ^ n := n.recOn (by simp) fun k hk => by simp only [ppow_succ, hk, mul_assoc] - rw [←mul_assoc x, ←mul_assoc (y ^ k)] + rw [← mul_assoc x, ← mul_assoc (y ^ k)] congr 2 exact (h.symm.ppow_left k).eq diff --git a/Mathlib/Data/Num/Lemmas.lean b/Mathlib/Data/Num/Lemmas.lean index b26a3f1f1a94d3..4a9bd1c33e5a73 100644 --- a/Mathlib/Data/Num/Lemmas.lean +++ b/Mathlib/Data/Num/Lemmas.lean @@ -131,9 +131,9 @@ theorem mul_to_nat (m) : ∀ n, ((m * n : PosNum) : ℕ) = m * n @[norm_cast] theorem ppowRec_to_nat (m : PosNum) : ∀ n : ℕ, (hn : 0 < n) → ppowRec n hn (m : ℕ) = ppowRec n hn m -| 0, h => (Nat.not_lt_zero 0 h).elim -| 1, _ => rfl -| n + 2, _ => by rw [ppowRec, ppowRec_to_nat m (n + 1)]; norm_cast + | 0, h => (Nat.not_lt_zero 0 h).elim + | 1, _ => rfl + | n + 2, _ => by rw [ppowRec, ppowRec_to_nat m (n + 1)]; norm_cast @[norm_cast] theorem psmulRec_to_nat (m : PosNum) : @@ -621,7 +621,7 @@ instance commMonoid : CommMonoid PosNum := by one := (1 : PosNum) ppow := @ppowRec PosNum ⟨(· * ·)⟩ npow := @npowRec PosNum ⟨1⟩ ⟨(· * ·)⟩ ,.. } <;> - try { intros ; rfl } <;> + try { intros; rfl } <;> transfer #align pos_num.comm_monoid PosNum.commMonoid From 9dafe98e1506158e124b4cbd3819e966d5b80c01 Mon Sep 17 00:00:00 2001 From: Christopher Hoskin Date: Tue, 23 Apr 2024 06:25:30 +0100 Subject: [PATCH 005/127] Lint --- Mathlib/Algebra/Group/PPow.lean | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Mathlib/Algebra/Group/PPow.lean b/Mathlib/Algebra/Group/PPow.lean index 63473a447c240c..9eb5759d638e65 100644 --- a/Mathlib/Algebra/Group/PPow.lean +++ b/Mathlib/Algebra/Group/PPow.lean @@ -3,14 +3,13 @@ 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.Algebra.GroupPower.Basic +import Mathlib.Data.PNat.Basic /-! # TODO : Fill in module docstring -/ -import Mathlib.Algebra.GroupPower.Basic -import Mathlib.Data.PNat.Basic - local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- See issue #2220 variable {M : Type _} From 85a19cc3f5927966da330ac6fddfe94bac3eb70b Mon Sep 17 00:00:00 2001 From: Christopher Hoskin Date: Tue, 23 Apr 2024 06:31:14 +0100 Subject: [PATCH 006/127] Remove duplicate (additive) ext --- Mathlib/Algebra/Group/Defs.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/Algebra/Group/Defs.lean b/Mathlib/Algebra/Group/Defs.lean index e8f42b66713e18..713a64fe0507ab 100644 --- a/Mathlib/Algebra/Group/Defs.lean +++ b/Mathlib/Algebra/Group/Defs.lean @@ -339,7 +339,6 @@ class CommSemigroup (G : Type u) extends Semigroup G, CommMagma G where #align comm_semigroup CommSemigroup /-- A commutative additive semigroup is a type with an associative commutative `(+)`. -/ -@[ext] class AddCommSemigroup (G : Type u) extends AddSemigroup G, AddCommMagma G where #align add_comm_semigroup AddCommSemigroup From 74b1096d4597b7cb96d645503fb7d6d0ccd77a74 Mon Sep 17 00:00:00 2001 From: Christopher Hoskin Date: Tue, 23 Apr 2024 06:48:19 +0100 Subject: [PATCH 007/127] Import all files --- Mathlib.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib.lean b/Mathlib.lean index 53a0c02fa48df8..60967f897cd365 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -211,6 +211,7 @@ import Mathlib.Algebra.Group.NatPowAssoc import Mathlib.Algebra.Group.Opposite import Mathlib.Algebra.Group.OrderSynonym import Mathlib.Algebra.Group.PNatPowAssoc +import Mathlib.Algebra.Group.PPow import Mathlib.Algebra.Group.Pi.Basic import Mathlib.Algebra.Group.Pi.Lemmas import Mathlib.Algebra.Group.Prod From aad455e4b17a552dc2a6182f8fae4082f6239f21 Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Tue, 23 Apr 2024 13:30:50 -0500 Subject: [PATCH 008/127] remove heartbeat bumps, except one in algebraic geometry --- Mathlib/Algebra/Category/FGModuleCat/Basic.lean | 5 ----- Mathlib/Algebra/Jordan/Basic.lean | 1 - Mathlib/Algebra/Module/GradedModule.lean | 1 - Mathlib/LinearAlgebra/TensorPower.lean | 4 +--- Mathlib/RingTheory/IsTensorProduct.lean | 2 -- Mathlib/RingTheory/MatrixAlgebra.lean | 1 - Mathlib/RingTheory/Polynomial/Quotient.lean | 2 -- 7 files changed, 1 insertion(+), 15 deletions(-) diff --git a/Mathlib/Algebra/Category/FGModuleCat/Basic.lean b/Mathlib/Algebra/Category/FGModuleCat/Basic.lean index 3a71a45f636a8c..db38eafd2c2df0 100644 --- a/Mathlib/Algebra/Category/FGModuleCat/Basic.lean +++ b/Mathlib/Algebra/Category/FGModuleCat/Basic.lean @@ -267,17 +267,12 @@ theorem FGModuleCatEvaluation_apply (f : FGModuleCatDual K V) (x : V) : contractLeft_apply f x #align fgModule.fgModule_evaluation_apply FGModuleCat.FGModuleCatEvaluation_apply --- Porting note: extremely slow, was fast in mathlib3. --- I tried many things using `dsimp` and `change`, but couldn't find anything faster than this. -set_option maxHeartbeats 2000000 in private theorem coevaluation_evaluation : letI V' : FGModuleCat K := FGModuleCatDual K V V' ◁ FGModuleCatCoevaluation K V ≫ (α_ V' V V').inv ≫ FGModuleCatEvaluation K V ▷ V' = (ρ_ V').hom ≫ (λ_ V').inv := by apply contractLeft_assoc_coevaluation K V --- Porting note: extremely slow, was fast in mathlib3. -set_option maxHeartbeats 2000000 in private theorem evaluation_coevaluation : FGModuleCatCoevaluation K V ▷ V ≫ (α_ V (FGModuleCatDual K V) V).hom ≫ V ◁ FGModuleCatEvaluation K V = diff --git a/Mathlib/Algebra/Jordan/Basic.lean b/Mathlib/Algebra/Jordan/Basic.lean index 1ebcb417015625..aa77f422e68604 100644 --- a/Mathlib/Algebra/Jordan/Basic.lean +++ b/Mathlib/Algebra/Jordan/Basic.lean @@ -204,7 +204,6 @@ private theorem aux1 {a b c : A} : rw [add_lie, add_lie] iterate 15 rw [lie_add] -set_option maxHeartbeats 350000 in private theorem aux2 {a b c : A} : ⁅L a, L (a * a)⁆ + ⁅L a, L (b * b)⁆ + ⁅L a, L (c * c)⁆ + ⁅L a, 2 • L (a * b)⁆ + ⁅L a, 2 • L (c * a)⁆ + ⁅L a, 2 • L (b * c)⁆ + diff --git a/Mathlib/Algebra/Module/GradedModule.lean b/Mathlib/Algebra/Module/GradedModule.lean index 1720783246bd12..9ede97fdf9ac1a 100644 --- a/Mathlib/Algebra/Module/GradedModule.lean +++ b/Mathlib/Algebra/Module/GradedModule.lean @@ -216,7 +216,6 @@ def isModule [DecidableEq ιA] [DecidableEq ιM] [GradedRing 𝓐] : Module A ( smul := fun a b => DirectSum.decompose 𝓐 a • b } #align graded_module.is_module GradedModule.isModule -set_option synthInstance.maxHeartbeats 25000 in /-- `⨁ i, 𝓜 i` and `M` are isomorphic as `A`-modules. "The internal version" and "the external version" are isomorphism as `A`-modules. -/ diff --git a/Mathlib/LinearAlgebra/TensorPower.lean b/Mathlib/LinearAlgebra/TensorPower.lean index f7933db1dbe642..f6cf3584423ec6 100644 --- a/Mathlib/LinearAlgebra/TensorPower.lean +++ b/Mathlib/LinearAlgebra/TensorPower.lean @@ -259,8 +259,7 @@ theorem algebraMap₀_mul_algebraMap₀ (r s : R) : exact algebraMap₀_mul r (@algebraMap₀ R M _ _ _ s) #align tensor_power.algebra_map₀_mul_algebra_map₀ TensorPower.algebraMap₀_mul_algebraMap₀ -set_option maxHeartbeats 300000 in -instance gsemiring : DirectSum.GSemiring fun i => (⨂[R]^i) M := +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₂ _ _ @@ -273,7 +272,6 @@ instance gsemiring : DirectSum.GSemiring fun i => (⨂[R]^i) M := example : Semiring (⨁ n : ℕ, ⨂[R]^n M) := by infer_instance -set_option maxHeartbeats 250000 in /-- The tensor powers form a graded algebra. Note that this instance implies `Algebra R (⨁ n : ℕ, ⨂[R]^n M)` via `DirectSum.Algebra`. -/ diff --git a/Mathlib/RingTheory/IsTensorProduct.lean b/Mathlib/RingTheory/IsTensorProduct.lean index c0b1aeb7f18987..34368cbdfa343a 100644 --- a/Mathlib/RingTheory/IsTensorProduct.lean +++ b/Mathlib/RingTheory/IsTensorProduct.lean @@ -401,13 +401,11 @@ variable {R S R'} attribute [local instance] Algebra.TensorProduct.rightAlgebra -set_option maxHeartbeats 350000 in instance TensorProduct.isPushout {R S T : Type*} [CommRing R] [CommRing S] [CommRing T] [Algebra R S] [Algebra R T] : Algebra.IsPushout R S T (TensorProduct R S T) := ⟨TensorProduct.isBaseChange R T S⟩ #align tensor_product.is_pushout TensorProduct.isPushout -set_option maxHeartbeats 350000 in instance TensorProduct.isPushout' {R S T : Type*} [CommRing R] [CommRing S] [CommRing T] [Algebra R S] [Algebra R T] : Algebra.IsPushout R T S (TensorProduct R S T) := Algebra.IsPushout.symm inferInstance diff --git a/Mathlib/RingTheory/MatrixAlgebra.lean b/Mathlib/RingTheory/MatrixAlgebra.lean index c336afe57db2a7..9ee0f65c18a0c7 100644 --- a/Mathlib/RingTheory/MatrixAlgebra.lean +++ b/Mathlib/RingTheory/MatrixAlgebra.lean @@ -121,7 +121,6 @@ theorem right_inv (M : Matrix n n A) : (toFunAlgHom R A n) (invFun R A n M) = M split_ifs <;> aesop #align matrix_equiv_tensor.right_inv MatrixEquivTensor.right_inv -set_option synthInstance.maxHeartbeats 30000 in theorem left_inv (M : A ⊗[R] Matrix n n R) : invFun R A n (toFunAlgHom R A n M) = M := by induction M using TensorProduct.induction_on with | zero => simp diff --git a/Mathlib/RingTheory/Polynomial/Quotient.lean b/Mathlib/RingTheory/Polynomial/Quotient.lean index bd5185e645a6c0..d1bc7e02a23eab 100644 --- a/Mathlib/RingTheory/Polynomial/Quotient.lean +++ b/Mathlib/RingTheory/Polynomial/Quotient.lean @@ -63,7 +63,6 @@ noncomputable def quotientSpanCXSubCAlgEquiv (x y : R) : simp only [Ideal.map_span, Set.image_singleton]; congr 2; exact eval_C #align polynomial.quotient_span_C_X_sub_C_alg_equiv Polynomial.quotientSpanCXSubCAlgEquiv -set_option maxHeartbeats 350000 in /-- For a commutative ring $R$, evaluating a polynomial at elements $y(X) \in R[X]$ and $x \in R$ induces an isomorphism of $R$-algebras $R[X, Y] / \langle X - x, Y - y(X) \rangle \cong R$. -/ noncomputable def quotientSpanCXSubCXSubCAlgEquiv {x : R} {y : R[X]} : @@ -206,7 +205,6 @@ theorem quotient_map_C_eq_zero {I : Ideal R} {i : R} (hi : i ∈ I) : exact Ideal.mem_map_of_mem _ hi #align mv_polynomial.quotient_map_C_eq_zero MvPolynomial.quotient_map_C_eq_zero -set_option synthInstance.maxHeartbeats 20100 in theorem eval₂_C_mk_eq_zero {I : Ideal R} {a : MvPolynomial σ R} (ha : a ∈ (Ideal.map (C : R →+* MvPolynomial σ R) I : Ideal (MvPolynomial σ R))) : eval₂Hom (C.comp (Ideal.Quotient.mk I)) X a = 0 := by From 89bb57823447d0a140547ecaf299449fdc828dab Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Tue, 23 Apr 2024 13:33:39 -0500 Subject: [PATCH 009/127] remove unused arguments --- Mathlib/Algebra/Group/Ext.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Group/Ext.lean b/Mathlib/Algebra/Group/Ext.lean index 788ef998a19026..73af39f4ca2f41 100644 --- a/Mathlib/Algebra/Group/Ext.lean +++ b/Mathlib/Algebra/Group/Ext.lean @@ -50,7 +50,7 @@ theorem Semigroup.ext {M : Type u} ⦃m₁ m₂ : Semigroup M⦄ (h_mul : m₁.m @[to_additive] -theorem CommSemigroup.toSemigroup_injective {M : Type u} [Semigroup M] : +theorem CommSemigroup.toSemigroup_injective {M : Type u} : Function.Injective (@CommSemigroup.toSemigroup M) := by rintro ⟨⟩ ⟨⟩ h congr From 60dbead9301d929b8a37cd1fcd483815e3e6bf2d Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Tue, 23 Apr 2024 13:39:38 -0500 Subject: [PATCH 010/127] add docstrings --- Mathlib/Algebra/Group/Defs.lean | 2 ++ Mathlib/Algebra/Group/PPow.lean | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Group/Defs.lean b/Mathlib/Algebra/Group/Defs.lean index 713a64fe0507ab..15181a2779a199 100644 --- a/Mathlib/Algebra/Group/Defs.lean +++ b/Mathlib/Algebra/Group/Defs.lean @@ -290,6 +290,7 @@ attribute [to_additive existing] ppowRec class Semigroup (G : Type u) extends Mul G where /-- Multiplication is associative -/ protected mul_assoc : ∀ a b c : G, a * b * c = a * (b * c) + /-- Positive integer power operation -/ ppow : ∀ n : ℕ, 0 < n → G → G := ppowRec ppow_one : ∀ g, ppow 1 Nat.one_pos g = g := by intros; rfl ppow_succ : ∀ g n, ppow (n + 2) (n + 1).succ_pos g = g * ppow (n + 1) n.succ_pos g := @@ -300,6 +301,7 @@ class Semigroup (G : Type u) extends Mul G where class AddSemigroup (G : Type u) extends Add G where /-- Addition is associative -/ protected add_assoc : ∀ a b c : G, a + b + c = a + (b + c) + /-- Positive integer scalar multiplication -/ psmul : ∀ n : ℕ, 0 < n → G → G := psmulRec psmul_one : ∀ g, psmul 1 Nat.one_pos g = g := by intros; rfl psmul_succ : ∀ g n, psmul (n + 2) (n + 1).succ_pos g = g + psmul (n + 1) n.succ_pos g := diff --git a/Mathlib/Algebra/Group/PPow.lean b/Mathlib/Algebra/Group/PPow.lean index 9eb5759d638e65..c751c636075b3c 100644 --- a/Mathlib/Algebra/Group/PPow.lean +++ b/Mathlib/Algebra/Group/PPow.lean @@ -82,7 +82,8 @@ lemma mul_ppow (x y : M) (n : ℕ+) : (x * y) ^ n = x ^ n * y ^ n := variable (M) -@[to_additive (attr := simps)] +/-- `(· ^ (n : ℕ+))` as a `MulHom`. -/ +@[to_additive (attr := simps) "`((n : ℕ+) • ·)` as an `AddHom`."] def ppowMulHom (n : ℕ+) : M →ₙ* M where toFun x := x ^ n map_mul' := mul_ppow (n := n) From 76c0d177f332b24cbc90690da9a7e15b17c5c49b Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Mon, 3 Mar 2025 15:05:37 -0600 Subject: [PATCH 011/127] fix to_additive --- Mathlib/Tactic/ToAdditive/Frontend.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/Tactic/ToAdditive/Frontend.lean b/Mathlib/Tactic/ToAdditive/Frontend.lean index c1b1ddefb19afd..1c6a1a1d91e806 100644 --- a/Mathlib/Tactic/ToAdditive/Frontend.lean +++ b/Mathlib/Tactic/ToAdditive/Frontend.lean @@ -953,6 +953,7 @@ def nameDict : String → List String | "finprod" => ["finsum"] | "tprod" => ["tsum"] | "pow" => ["nsmul"] + | "ppow" => ["psmul"] | "npow" => ["nsmul"] | "zpow" => ["zsmul"] | "mabs" => ["abs"] From 09639103c23e8234a23cfe8b920646695f3b6d75 Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Mon, 3 Mar 2025 15:21:12 -0600 Subject: [PATCH 012/127] fix import? --- Mathlib/Algebra/Group/PPow.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Group/PPow.lean b/Mathlib/Algebra/Group/PPow.lean index c751c636075b3c..8722c4ad472bbe 100644 --- a/Mathlib/Algebra/Group/PPow.lean +++ b/Mathlib/Algebra/Group/PPow.lean @@ -3,7 +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.Algebra.GroupPower.Basic +import Mathlib.Algebra.Group.Defs import Mathlib.Data.PNat.Basic /-! From 950dd9faccd763743850c101329e399f68cd0c80 Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Mon, 3 Mar 2025 20:28:52 -0600 Subject: [PATCH 013/127] fix all? --- Mathlib/Algebra/Group/Ext.lean | 20 +++++++------------- Mathlib/Algebra/Group/PNatPowAssoc.lean | 2 -- Mathlib/Algebra/Group/PPow.lean | 4 +--- Mathlib/Algebra/Ring/Ext.lean | 11 ++++++++++- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/Mathlib/Algebra/Group/Ext.lean b/Mathlib/Algebra/Group/Ext.lean index 634179d3e7d321..6cbc46f3da6469 100644 --- a/Mathlib/Algebra/Group/Ext.lean +++ b/Mathlib/Algebra/Group/Ext.lean @@ -3,7 +3,6 @@ Copyright (c) 2021 Bryan Gin-ge Chen. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Bryan Gin-ge Chen, Yury Kudryashov -/ -import Mathlib.Algebra.Group.PPow import Mathlib.Algebra.Group.Hom.Defs /-! @@ -36,18 +35,18 @@ variable {M : Type*} [Monoid M] @[to_additive (attr := ext)] theorem Semigroup.ext {M : Type u} ⦃m₁ m₂ : Semigroup M⦄ (h_mul : m₁.mul = m₂.mul) : m₁ = m₂ := by - let f := @MulHom.mk _ _ m₁.toMul m₂.toMul id fun _ _ => congr_fun (congr_fun h_mul _) _ have : m₁.ppow = m₂.ppow := by ext n hn x - exact @map_ppow _ M M m₁ m₂ _ _ f x ⟨n, hn⟩ + induction n using Nat.strongRecOn with + | ind n ih => + match n with + | 1 => rw [m₁.ppow_one, m₂.ppow_one] + | n + 2 => + rw [m₁.ppow_succ, m₂.ppow_succ, ih _ (n + 1).lt_succ_self n.succ_pos] + exact congr_fun (congr_fun h_mul _) _ rcases m₁ with @⟨@⟨_⟩, _⟩ rcases m₂ with @⟨@⟨_⟩, _⟩ congr -#align semigroup.ext Semigroup.extₓ -#noalign semigroup.ext_iff -#align add_semigroup.ext AddSemigroup.extₓ -#noalign add_semigroup.ext_iff - @[to_additive] theorem CommSemigroup.toSemigroup_injective {M : Type u} : @@ -60,11 +59,6 @@ theorem CommSemigroup.toSemigroup_injective {M : Type u} : theorem CommSemigroup.ext {M : Type _} ⦃m₁ m₂ : CommSemigroup M⦄ (h_mul : m₁.mul = m₂.mul) : m₁ = m₂ := CommSemigroup.toSemigroup_injective <| Semigroup.ext h_mul -#align comm_semigroup.ext CommSemigroup.extₓ -#noalign comm_semigroup.ext_iff -#align add_comm_semigroup.ext AddCommSemigroup.extₓ -#noalign add_comm_semigroup.ext_iff - @[to_additive (attr := ext)] theorem Monoid.ext {M : Type u} ⦃m₁ m₂ : Monoid M⦄ diff --git a/Mathlib/Algebra/Group/PNatPowAssoc.lean b/Mathlib/Algebra/Group/PNatPowAssoc.lean index 93d84343a62727..12929673086a21 100644 --- a/Mathlib/Algebra/Group/PNatPowAssoc.lean +++ b/Mathlib/Algebra/Group/PNatPowAssoc.lean @@ -47,8 +47,6 @@ class PNatPowAssoc (M : Type*) [Mul M] [Pow M ℕ+] : Prop where /-- Exponent one is identity. -/ protected ppow_one : ∀ (x : M), x ^ (1 : ℕ+) = x -namespace Mul - section Mul variable [Mul M] [Pow M ℕ+] [PNatPowAssoc M] diff --git a/Mathlib/Algebra/Group/PPow.lean b/Mathlib/Algebra/Group/PPow.lean index 8722c4ad472bbe..8ab7d3449ef5fe 100644 --- a/Mathlib/Algebra/Group/PPow.lean +++ b/Mathlib/Algebra/Group/PPow.lean @@ -10,9 +10,7 @@ import Mathlib.Data.PNat.Basic # TODO : Fill in module docstring -/ -local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- See issue #2220 - -variable {M : Type _} +variable {M : Type*} instance Semigroup.instPow [Semigroup M] : Pow M ℕ+ where pow x n := Semigroup.ppow n n.pos x diff --git a/Mathlib/Algebra/Ring/Ext.lean b/Mathlib/Algebra/Ring/Ext.lean index 3d7a340d5bff81..2f3b608208cf64 100644 --- a/Mathlib/Algebra/Ring/Ext.lean +++ b/Mathlib/Algebra/Ring/Ext.lean @@ -5,6 +5,7 @@ Authors: Raghuram Sundararajan -/ import Mathlib.Algebra.Ring.Defs import Mathlib.Algebra.Group.Ext +import Mathlib.Tactic.CongrM /-! # Extensionality lemmas for rings and similar structures @@ -77,7 +78,12 @@ namespace NonUnitalSemiring theorem toNonUnitalNonAssocSemiring_injective : Function.Injective (@toNonUnitalNonAssocSemiring R) := by - rintro ⟨⟩ ⟨⟩ _; congr + intro R₁ R₂ h + have h' : R₁.toSemigroup = R₂.toSemigroup := Semigroup.ext congr($(h).mul) + have := congr($(h').ppow) + rcases R₁ with ⟨⟩ + rcases R₂ with ⟨⟩ + congr @[ext] theorem ext ⦃inst₁ inst₂ : NonUnitalSemiring R⦄ (h_add : local_hAdd[R, inst₁] = local_hAdd[R, inst₂]) @@ -187,6 +193,9 @@ namespace NonUnitalRing inst₁ = inst₂ := by have : inst₁.toNonUnitalNonAssocRing = inst₂.toNonUnitalNonAssocRing := by ext : 1 <;> assumption + have : inst₁.toSemigroup = inst₂.toSemigroup := by + ext : 1 <;> assumption + have := congr($(this).ppow) -- Split into fields and prove they are equal using the above. cases inst₁; cases inst₂ congr From fe85b6a0e9ae85abc52842639391f49f7d48da94 Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Mon, 3 Mar 2025 22:15:55 -0600 Subject: [PATCH 014/127] namespace lemmas in `PNatPowAssoc` to avoid conflicts --- Mathlib/Algebra/Group/PNatPowAssoc.lean | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Mathlib/Algebra/Group/PNatPowAssoc.lean b/Mathlib/Algebra/Group/PNatPowAssoc.lean index 12929673086a21..d1886087f0663a 100644 --- a/Mathlib/Algebra/Group/PNatPowAssoc.lean +++ b/Mathlib/Algebra/Group/PNatPowAssoc.lean @@ -43,20 +43,22 @@ variable {M : Type*} /-- A `Prop`-valued mixin for power-associative multiplication in the non-unital setting. -/ class PNatPowAssoc (M : Type*) [Mul M] [Pow M ℕ+] : Prop where /-- Multiplication is power-associative. -/ - protected ppow_add : ∀ (k n : ℕ+) (x : M), x ^ (k + n) = x ^ k * x ^ n + protected ppow_add' : ∀ (k n : ℕ+) (x : M), x ^ (k + n) = x ^ k * x ^ n /-- Exponent one is identity. -/ - protected ppow_one : ∀ (x : M), x ^ (1 : ℕ+) = x + protected ppow_one' : ∀ (x : M), x ^ (1 : ℕ+) = x + +namespace PNatPowAssoc section Mul variable [Mul M] [Pow M ℕ+] [PNatPowAssoc M] theorem ppow_add (k n : ℕ+) (x : M) : x ^ (k + n) = x ^ k * x ^ n := - PNatPowAssoc.ppow_add k n x + PNatPowAssoc.ppow_add' k n x @[simp] theorem ppow_one (x : M) : x ^ (1 : ℕ+) = x := - PNatPowAssoc.ppow_one x + PNatPowAssoc.ppow_one' x theorem ppow_mul_assoc (k m n : ℕ+) (x : M) : (x ^ k * x ^ m) * x ^ n = x ^ k * (x ^ m * x ^ n) := by @@ -78,16 +80,18 @@ end Mul instance Pi.instPNatPowAssoc {ι : Type*} {α : ι → Type*} [∀ i, Mul <| α i] [∀ i, Pow (α i) ℕ+] [∀ i, PNatPowAssoc <| α i] : PNatPowAssoc (∀ i, α i) where - ppow_add _ _ _ := by ext; simp [ppow_add] - ppow_one _ := by ext; simp + ppow_add' _ _ _ := by ext; simp [ppow_add] + ppow_one' _ := by ext; simp instance Prod.instPNatPowAssoc {N : Type*} [Mul M] [Pow M ℕ+] [PNatPowAssoc M] [Mul N] [Pow N ℕ+] [PNatPowAssoc N] : PNatPowAssoc (M × N) where - ppow_add _ _ _ := by ext <;> simp [ppow_add] - ppow_one _ := by ext <;> simp + ppow_add' _ _ _ := by ext <;> simp [ppow_add] + ppow_one' _ := by ext <;> simp theorem ppow_eq_pow [Monoid M] [Pow M ℕ+] [PNatPowAssoc M] (x : M) (n : ℕ+) : x ^ n = x ^ (n : ℕ) := by induction n with | one => rw [ppow_one, PNat.one_coe, pow_one] | succ k hk => rw [ppow_add, ppow_one, PNat.add_coe, pow_add, PNat.one_coe, pow_one, ← hk] + +end PNatPowAssoc From d7d20f7bdcba9f843234f580a39e15599e0624b9 Mon Sep 17 00:00:00 2001 From: Jireh Loreaux Date: Mon, 3 Mar 2025 22:28:05 -0600 Subject: [PATCH 015/127] shake --- Mathlib/Data/Num/Lemmas.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/Data/Num/Lemmas.lean b/Mathlib/Data/Num/Lemmas.lean index 58a7ac707cbba9..061b59fa1788e2 100644 --- a/Mathlib/Data/Num/Lemmas.lean +++ b/Mathlib/Data/Num/Lemmas.lean @@ -9,7 +9,6 @@ import Mathlib.Data.Nat.Bitwise import Mathlib.Data.Nat.PSub import Mathlib.Data.Nat.Size import Mathlib.Data.Num.Bitwise -import Mathlib.Data.PNat.Basic /-! # Properties of the binary representation of integers From 1927358d83a02fcec7a5bf43d7eae946e22e3967 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 18 Jun 2026 15:09:19 -0400 Subject: [PATCH 016/127] Ext.lean --- Mathlib/Algebra/Group/Ext.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Group/Ext.lean b/Mathlib/Algebra/Group/Ext.lean index 2240693477621b..a485b8b474b088 100644 --- a/Mathlib/Algebra/Group/Ext.lean +++ b/Mathlib/Algebra/Group/Ext.lean @@ -71,7 +71,7 @@ theorem Monoid.ext {M : Type u} ⦃m₁ m₂ : Monoid M⦄ have : m₁.toMulOneClass = m₂.toMulOneClass := MulOneClass.ext h_mul have h₁ : m₁.one = m₂.one := congr_arg (·.one) (this) have h₂ : m₁.toSemigroup = m₂.toSemigroup := Semigroup.ext h_mul - let f : @MonoidHom M M m₁.toMulOneClass m₂.toMulOneClass := + let f : @MonoidHom M M m₁.toMulOne m₂.toMulOne := @MonoidHom.mk _ _ (_) _ (@OneHom.mk _ _ (_) _ id h₁) (fun x y => congr_fun (congr_fun h_mul x) y) have : m₁.npow = m₂.npow := by From 972d5d2b379f9e59104fa802f06539ab30272b11 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 18 Jun 2026 15:09:29 -0400 Subject: [PATCH 017/127] mk_all --- Mathlib.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib.lean b/Mathlib.lean index 73d920207c69ad..14712aea3a2de3 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -427,6 +427,7 @@ public import Mathlib.Algebra.Group.Nat.Units public import Mathlib.Algebra.Group.NatPowAssoc public import Mathlib.Algebra.Group.Opposite public import Mathlib.Algebra.Group.PNatPowAssoc +public import Mathlib.Algebra.Group.PPow public import Mathlib.Algebra.Group.PUnit public import Mathlib.Algebra.Group.Pi.Basic public import Mathlib.Algebra.Group.Pi.Lemmas From ea0af546583fed948363511b14c8a79a4d21cc1e Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 18 Jun 2026 15:29:44 -0400 Subject: [PATCH 018/127] fix zmod --- Mathlib/Data/ZMod/Defs.lean | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Mathlib/Data/ZMod/Defs.lean b/Mathlib/Data/ZMod/Defs.lean index a6569495efb164..49613531dff1d2 100644 --- a/Mathlib/Data/ZMod/Defs.lean +++ b/Mathlib/Data/ZMod/Defs.lean @@ -205,16 +205,16 @@ instance commRing (n : ℕ) : CommRing (ZMod n) where ((inferInstance : CommRing ℤ)).nsmul_zero fun n => ((inferInstance : CommRing (Fin n.succ))).nsmul_zero nsmul_succ := Nat.casesOn n - (inferInstanceAs (CommRing ℤ)).nsmul_succ - fun n => (inferInstanceAs (CommRing (Fin n.succ))).nsmul_succ + (inferInstance : CommRing ℤ).nsmul_succ + fun n => (inferInstance : CommRing (Fin n.succ)).nsmul_succ psmul := Nat.casesOn n - (inferInstanceAs (CommRing ℤ)).psmul fun n => (inferInstanceAs (CommRing (Fin n.succ))).psmul + (inferInstance : CommRing ℤ).psmul fun n => (inferInstance : CommRing (Fin n.succ)).psmul psmul_one := Nat.casesOn n - (inferInstanceAs (CommRing ℤ)).psmul_one - fun n => (inferInstanceAs (CommRing (Fin n.succ))).psmul_one + (inferInstance : CommRing ℤ).psmul_one + fun n => (inferInstance: CommRing (Fin n.succ)).psmul_one psmul_succ := Nat.casesOn n - (inferInstanceAs (CommRing ℤ)).psmul_succ - fun n => (inferInstanceAs (CommRing (Fin n.succ))).psmul_succ + (inferInstance : CommRing ℤ).psmul_succ + fun n => (inferInstance : CommRing (Fin n.succ)).psmul_succ neg_add_cancel := Nat.casesOn n (@neg_add_cancel Int _) fun n => @neg_add_cancel (Fin n.succ) _ add_comm := Nat.casesOn n (@add_comm Int _) fun n => @add_comm (Fin n.succ) _ mul := Nat.casesOn n (@Mul.mul Int _) fun n => @Mul.mul (Fin n.succ) _ @@ -241,16 +241,16 @@ instance commRing (n : ℕ) : CommRing (ZMod n) where ((inferInstance : CommRing ℤ)).npow_zero fun n => ((inferInstance : CommRing (Fin n.succ))).npow_zero npow_succ := Nat.casesOn n - (inferInstanceAs (CommRing ℤ)).npow_succ - fun n => (inferInstanceAs (CommRing (Fin n.succ))).npow_succ + (inferInstance : CommRing ℤ).npow_succ + fun n => (inferInstance : CommRing (Fin n.succ)).npow_succ ppow := Nat.casesOn n - (inferInstanceAs (CommRing ℤ)).ppow fun n => (inferInstanceAs (CommRing (Fin n.succ))).ppow + (inferInstance : CommRing ℤ).ppow fun n => (inferInstance : CommRing (Fin n.succ)).ppow ppow_one := Nat.casesOn n - (inferInstanceAs (CommRing ℤ)).ppow_one - fun n => (inferInstanceAs (CommRing (Fin n.succ))).ppow_one + (inferInstance : CommRing ℤ).ppow_one + fun n => (inferInstance : CommRing (Fin n.succ)).ppow_one ppow_succ := Nat.casesOn n - (inferInstanceAs (CommRing ℤ)).ppow_succ - fun n => (inferInstanceAs (CommRing (Fin n.succ))).ppow_succ + (inferInstance : CommRing ℤ).ppow_succ + fun n => (inferInstance : CommRing (Fin n.succ)).ppow_succ instance inhabited (n : ℕ) : Inhabited (ZMod n) := ⟨0⟩ From a3be18be58ba0e9c61668c079affa75c4a6ccd62 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 18 Jun 2026 16:26:31 -0400 Subject: [PATCH 019/127] nonunital center fast_instance hack --- Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean b/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean index 188f76c8320d9d..b7814bc81c0207 100644 --- a/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean +++ b/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean @@ -237,7 +237,7 @@ theorem center_toSubsemigroup : rfl /-- The center is commutative and associative. -/ -instance center.instNonUnitalCommSemiring : NonUnitalCommSemiring (center R) := +instance center.instNonUnitalCommSemiring : NonUnitalCommSemiring (center R) := fast_instance% { Subsemigroup.center.commSemigroup, NonUnitalSubsemiringClass.toNonUnitalNonAssocSemiring (center R) with } From 0b5b15623e93c2b8a25c20cdc5b04c2d2d56bdae Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 18 Jun 2026 16:53:44 -0400 Subject: [PATCH 020/127] cleanup --- Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean b/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean index b7814bc81c0207..51a570b0c829e4 100644 --- a/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean +++ b/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean @@ -237,9 +237,10 @@ theorem center_toSubsemigroup : rfl /-- The center is commutative and associative. -/ -instance center.instNonUnitalCommSemiring : NonUnitalCommSemiring (center R) := fast_instance% - { Subsemigroup.center.commSemigroup, - NonUnitalSubsemiringClass.toNonUnitalNonAssocSemiring (center R) with } +instance center.instNonUnitalCommSemiring : NonUnitalCommSemiring (center R) where + __ := NonUnitalSubsemiringClass.toNonUnitalNonAssocSemiring (center R) + __ := Subsemigroup.center.commSemigroup.toCommMagma + mul_assoc := Subsemigroup.center.commSemigroup.mul_assoc /-- A point-free means of proving membership in the center, for a non-associative ring. @@ -269,11 +270,12 @@ end NonUnitalNonAssocSemiring section NonUnitalSemiring -set_option backward.isDefEq.respectTransparency false in +variable {R : Type*} [NonUnitalSemiring R] + -- no instance diamond, unlike the unital version example {R} [NonUnitalSemiring R] : - (center.instNonUnitalCommSemiring _).toNonUnitalSemiring = - NonUnitalSubsemiringClass.toNonUnitalSemiring (center R) := by + ((center.instNonUnitalCommSemiring _).toNonUnitalSemiring) = + (NonUnitalSubsemiringClass.toNonUnitalSemiring (center R)) := by with_reducible_and_instances rfl theorem mem_center_iff {R} [NonUnitalSemiring R] {z : R} : z ∈ center R ↔ ∀ g, g * z = z * g := by From fe2b39708df32397ea84124ef5b3d240a2d128d0 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 18 Jun 2026 16:58:23 -0400 Subject: [PATCH 021/127] another fix, don't copy data --- Mathlib/RingTheory/NonUnitalSubring/Basic.lean | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Mathlib/RingTheory/NonUnitalSubring/Basic.lean b/Mathlib/RingTheory/NonUnitalSubring/Basic.lean index 2032ab1081b90b..724a93c353173e 100644 --- a/Mathlib/RingTheory/NonUnitalSubring/Basic.lean +++ b/Mathlib/RingTheory/NonUnitalSubring/Basic.lean @@ -357,9 +357,8 @@ theorem center_toNonUnitalSubsemiring : /-- The center is commutative and associative. -/ instance center.instNonUnitalCommRing : NonUnitalCommRing (center R) where - __ : NonUnitalCommSemiring (center R) := - inferInstanceAs <| NonUnitalCommSemiring (NonUnitalSubsemiring.center R) - __ := (inferInstance : NonUnitalNonAssocRing (center R)) + mul_assoc := Subsemigroup.center.commSemigroup.mul_assoc + mul_comm := Subsemigroup.center.commSemigroup.mul_comm variable {R} @@ -378,8 +377,8 @@ section NonUnitalRing variable [NonUnitalRing R] -- no instance diamond, unlike the unital version -example : (center.instNonUnitalCommRing _).toNonUnitalRing = - NonUnitalSubringClass.toNonUnitalRing (center R) := by +example : ((center.instNonUnitalCommRing _).toNonUnitalRing) = + (NonUnitalSubringClass.toNonUnitalRing (center R)) := by with_reducible_and_instances rfl theorem mem_center_iff {z : R} : z ∈ center R ↔ ∀ g, g * z = z * g := Subsemigroup.mem_center_iff From c123b67f6eed31df5f3dae8d5614bf47c99d4daa Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 18 Jun 2026 16:59:44 -0400 Subject: [PATCH 022/127] lints --- Mathlib/Algebra/Group/PPow.lean | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Mathlib/Algebra/Group/PPow.lean b/Mathlib/Algebra/Group/PPow.lean index 8ab7d3449ef5fe..da8deda3a6ec9e 100644 --- a/Mathlib/Algebra/Group/PPow.lean +++ b/Mathlib/Algebra/Group/PPow.lean @@ -37,7 +37,7 @@ lemma ppow_succ (x : M) (n : ℕ+) : x ^ (n + 1) = x ^ n * x := @[to_additive add_psmul] lemma ppow_add (x : M) (n m : ℕ+) : x ^ (n + m) = x ^ n * x ^ m := - m.recOn (by simp [ppow_succ, add_comm]) fun k hk => by + m.recOn (by simp [ppow_succ]) fun k hk => by rw [← add_assoc, ppow_succ, ppow_succ, hk, mul_assoc] @[to_additive mul_comm_psmul] @@ -81,7 +81,8 @@ lemma mul_ppow (x y : M) (n : ℕ+) : (x * y) ^ n = x ^ n * y ^ n := variable (M) /-- `(· ^ (n : ℕ+))` as a `MulHom`. -/ -@[to_additive (attr := simps) "`((n : ℕ+) • ·)` as an `AddHom`."] +@[to_additive (attr := simps) + /-- `((n : ℕ+) • ·)` as an `AddHom`. -/] def ppowMulHom (n : ℕ+) : M →ₙ* M where toFun x := x ^ n map_mul' := mul_ppow (n := n) @@ -96,7 +97,7 @@ theorem pow_mul_comm'' [Monoid M] (a : M) (n : ℕ+) : a ^ n * a = a * a ^ n := @[to_additive (attr := norm_cast)] lemma npow_val_eq_ppow [Monoid M] (x : M) (n : ℕ+) : x ^ (n : ℕ) = x ^ n := n.recOn (by simp [pow_one]) fun k hk => by - simp [pow_succ, ppow_succ', hk] + simp only [PNat.add_coe, PNat.val_ofNat, pow_succ, hk, ppow_succ'] rw [pow_mul_comm''] @[to_additive] From fdde4b140bfe8b80b6fe877ec7082ce83085c24f Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 18 Jun 2026 17:01:49 -0400 Subject: [PATCH 023/127] more proof fix --- Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean b/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean index 49483234759347..113781e935991b 100644 --- a/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean +++ b/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean @@ -1094,8 +1094,10 @@ theorem coe_center : (center R A : Set A) = Set.center A := rfl /-- The center of a non-unital algebra is commutative and associative -/ -instance center.instNonUnitalCommSemiring : NonUnitalCommSemiring (center R A) := - inferInstanceAs <| NonUnitalCommSemiring (NonUnitalSubsemiring.center A) +instance center.instNonUnitalCommSemiring : NonUnitalCommSemiring (center R A) where + mul_assoc := Subsemigroup.center.commSemigroup.mul_assoc + mul_comm := Subsemigroup.center.commSemigroup.mul_comm + -- inferInstanceAs <| NonUnitalCommSemiring (NonUnitalSubsemiring.center A) instance center.instNonUnitalCommRing {A : Type*} [NonUnitalNonAssocRing A] [Module R A] [IsScalarTower R A A] [SMulCommClass R A A] : NonUnitalCommRing (center R A) := From c76c30615a0b6791c2ddcd92e5dfec2f320cf862 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 18 Jun 2026 17:06:03 -0400 Subject: [PATCH 024/127] fix merge --- Mathlib/LinearAlgebra/LinearPMap.lean | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/Mathlib/LinearAlgebra/LinearPMap.lean b/Mathlib/LinearAlgebra/LinearPMap.lean index ff388e84c975aa..b04285522255d7 100644 --- a/Mathlib/LinearAlgebra/LinearPMap.lean +++ b/Mathlib/LinearAlgebra/LinearPMap.lean @@ -431,19 +431,11 @@ theorem add_domain (f g : E →ₛₗ.[σ] F) : (f + g).domain = f.domain ⊓ g. theorem add_apply (f g : E →ₛₗ.[σ] F) (x : (f.domain ⊓ g.domain : Submodule R E)) : (f + g) x = f ⟨x, x.prop.1⟩ + g ⟨x, x.prop.2⟩ := rfl -instance instAddSemigroup : AddSemigroup (E →ₗ.[R] F) where +instance instAddSemigroup : AddSemigroup (E →ₛₗ.[σ] F) where add_assoc := fun f g h => by - fun f g h => by ext x y hxy · simp only [add_domain, inf_assoc] - · simp only [add_apply, hxy, add_assoc] - -instance instAddCommSemigroup : AddCommSemigroup (E →ₗ.[R] F) where - add_comm := fun f g => by - ext x y hxy - · simp only [add_domain, inf_comm] - · simp only [add_apply, hxy, add_comm] - · simp only [add_apply, add_assoc]⟩ + · simp only [add_apply, add_assoc] instance instAddZeroClass : AddZeroClass (E →ₛₗ.[σ] F) where zero_add := fun f => by From 0d6cc7d60054ec2d7e52aa14bf7d3bb1f7873f79 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 09:14:47 -0400 Subject: [PATCH 025/127] factor out Pow instance to help bootstrap --- Mathlib.lean | 3 ++- .../Group/{PPow.lean => PPow/Basic.lean} | 10 +------- Mathlib/Algebra/Group/PPow/Defs.lean | 24 +++++++++++++++++++ 3 files changed, 27 insertions(+), 10 deletions(-) rename Mathlib/Algebra/Group/{PPow.lean => PPow/Basic.lean} (90%) create mode 100644 Mathlib/Algebra/Group/PPow/Defs.lean diff --git a/Mathlib.lean b/Mathlib.lean index 14712aea3a2de3..f6e5f3ea3c021c 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -427,7 +427,8 @@ public import Mathlib.Algebra.Group.Nat.Units public import Mathlib.Algebra.Group.NatPowAssoc public import Mathlib.Algebra.Group.Opposite public import Mathlib.Algebra.Group.PNatPowAssoc -public import Mathlib.Algebra.Group.PPow +public import Mathlib.Algebra.Group.PPow.Basic +public import Mathlib.Algebra.Group.PPow.Defs public import Mathlib.Algebra.Group.PUnit public import Mathlib.Algebra.Group.Pi.Basic public import Mathlib.Algebra.Group.Pi.Lemmas diff --git a/Mathlib/Algebra/Group/PPow.lean b/Mathlib/Algebra/Group/PPow/Basic.lean similarity index 90% rename from Mathlib/Algebra/Group/PPow.lean rename to Mathlib/Algebra/Group/PPow/Basic.lean index da8deda3a6ec9e..0647dd2300eb0c 100644 --- a/Mathlib/Algebra/Group/PPow.lean +++ b/Mathlib/Algebra/Group/PPow/Basic.lean @@ -3,7 +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.Algebra.Group.Defs +import Mathlib.Algebra.Group.PPow.Defs import Mathlib.Data.PNat.Basic /-! @@ -12,14 +12,6 @@ import Mathlib.Data.PNat.Basic variable {M : Type*} -instance Semigroup.instPow [Semigroup M] : Pow M ℕ+ where - pow x n := Semigroup.ppow n n.pos x - -instance AddSemigroup.instSMul [AddSemigroup M] : SMul ℕ+ M where - smul n x := AddSemigroup.psmul n n.pos x - -attribute [to_additive existing AddSemigroup.instSMul] Semigroup.instPow - section Semigroup variable [Semigroup M] diff --git a/Mathlib/Algebra/Group/PPow/Defs.lean b/Mathlib/Algebra/Group/PPow/Defs.lean new file mode 100644 index 00000000000000..4dc589fb6d8fbc --- /dev/null +++ b/Mathlib/Algebra/Group/PPow/Defs.lean @@ -0,0 +1,24 @@ +/- +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.Algebra.Group.Defs +import Mathlib.Data.PNat.Notation + +/-! +# Instances for `ℕ+`-indexed powers on semigroups + +Declared in a separate file to bootstrap the algebra hierarchy without +requiring instances on `ℕ+`, which are usually inferred via inheriting from `ℕ`. +-/ + +variable {M : Type*} + +instance Semigroup.instPow [Semigroup M] : Pow M ℕ+ where + pow x n := Semigroup.ppow n n.property x + +instance AddSemigroup.instSMul [AddSemigroup M] : SMul ℕ+ M where + smul n x := AddSemigroup.psmul n n.property x + +attribute [to_additive existing AddSemigroup.instSMul] Semigroup.instPow From 72ed0340f03f16ebbee6dbb6bc72aaf1092f26c6 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 09:22:14 -0400 Subject: [PATCH 026/127] module system --- Mathlib/Algebra/Group/PPow/Basic.lean | 8 ++++++-- Mathlib/Algebra/Group/PPow/Defs.lean | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Group/PPow/Basic.lean b/Mathlib/Algebra/Group/PPow/Basic.lean index 0647dd2300eb0c..cdb3da9edc069c 100644 --- a/Mathlib/Algebra/Group/PPow/Basic.lean +++ b/Mathlib/Algebra/Group/PPow/Basic.lean @@ -3,13 +3,17 @@ 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.Algebra.Group.PPow.Defs -import Mathlib.Data.PNat.Basic +module + +public import Mathlib.Algebra.Group.PPow.Defs +public import Mathlib.Data.PNat.Basic /-! # TODO : Fill in module docstring -/ +public section + variable {M : Type*} section Semigroup diff --git a/Mathlib/Algebra/Group/PPow/Defs.lean b/Mathlib/Algebra/Group/PPow/Defs.lean index 4dc589fb6d8fbc..ebfe37db0487da 100644 --- a/Mathlib/Algebra/Group/PPow/Defs.lean +++ b/Mathlib/Algebra/Group/PPow/Defs.lean @@ -3,8 +3,10 @@ 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.Algebra.Group.Defs -import Mathlib.Data.PNat.Notation +module + +public import Mathlib.Algebra.Group.Defs +public import Mathlib.Data.PNat.Notation /-! # Instances for `ℕ+`-indexed powers on semigroups @@ -13,6 +15,8 @@ Declared in a separate file to bootstrap the algebra hierarchy without requiring instances on `ℕ+`, which are usually inferred via inheriting from `ℕ`. -/ +public section + variable {M : Type*} instance Semigroup.instPow [Semigroup M] : Pow M ℕ+ where From 81e818cb517ad7be73395a2940c9846be530a347 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 11:53:23 -0400 Subject: [PATCH 027/127] preparatory shuffle --- Mathlib/Algebra/Group/PPow/Defs.lean | 4 ++++ Mathlib/Data/PNat/Defs.lean | 11 ----------- Mathlib/Data/PNat/Notation.lean | 22 ++++++++++++++++++++++ 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/Mathlib/Algebra/Group/PPow/Defs.lean b/Mathlib/Algebra/Group/PPow/Defs.lean index ebfe37db0487da..75612ab6323160 100644 --- a/Mathlib/Algebra/Group/PPow/Defs.lean +++ b/Mathlib/Algebra/Group/PPow/Defs.lean @@ -26,3 +26,7 @@ instance AddSemigroup.instSMul [AddSemigroup M] : SMul ℕ+ M where smul n x := AddSemigroup.psmul n n.property x attribute [to_additive existing AddSemigroup.instSMul] Semigroup.instPow + +@[to_additive (attr := simp)] +lemma ppow_one [Semigroup M] (x : M) : x ^ (1 : ℕ+) = x := + Semigroup.ppow_one _ diff --git a/Mathlib/Data/PNat/Defs.lean b/Mathlib/Data/PNat/Defs.lean index 356d1193020665..699bf0d24c0b2a 100644 --- a/Mathlib/Data/PNat/Defs.lean +++ b/Mathlib/Data/PNat/Defs.lean @@ -23,19 +23,8 @@ Most algebraic facts are deferred to `Data.PNat.Basic`, as they need more import deriving instance LinearOrder for PNat -instance : One ℕ+ := - ⟨⟨1, Nat.zero_lt_one⟩⟩ - -instance (n : ℕ) [NeZero n] : OfNat ℕ+ n := - ⟨⟨n, Nat.pos_of_ne_zero <| NeZero.ne n⟩⟩ - namespace PNat --- Note: similar to Subtype.coe_mk -@[simp] -theorem mk_coe (n h) : (PNat.val (⟨n, h⟩ : ℕ+) : ℕ) = n := - rfl - /-- Predecessor of a `ℕ+`, as a `ℕ`. -/ def natPred (i : ℕ+) : ℕ := i - 1 diff --git a/Mathlib/Data/PNat/Notation.lean b/Mathlib/Data/PNat/Notation.lean index 430c87fddb35f6..4d4b693d3a1a0a 100644 --- a/Mathlib/Data/PNat/Notation.lean +++ b/Mathlib/Data/PNat/Notation.lean @@ -19,6 +19,9 @@ def PNat := { n : ℕ // 0 < n } deriving DecidableEq @[inherit_doc] notation "ℕ+" => PNat +/-- Helper constructor for `ℕ+`. -/ +def PNat.mk (n : ℕ) (h : 0 < n) : ℕ+ := ⟨n, h⟩ + /-- The underlying natural number -/ @[coe] def PNat.val : ℕ+ → ℕ := Subtype.val @@ -28,3 +31,22 @@ instance coePNatNat : Coe ℕ+ ℕ := instance : Repr ℕ+ := ⟨fun n n' => reprPrec n.1 n'⟩ + +instance : One ℕ+ := + ⟨⟨1, Nat.zero_lt_one⟩⟩ + +instance (n : ℕ) [NeZero n] : OfNat ℕ+ n := + ⟨⟨n, Nat.pos_of_ne_zero <| NeZero.ne n⟩⟩ + +@[simp] +lemma mk_one : PNat.mk 1 Nat.zero_lt_one = (1 : ℕ+) := + rfl + +@[simp] +lemma val_one : (1 : ℕ+).val = 1 := + rfl + +-- Note: similar to Subtype.coe_mk +@[simp] +theorem mk_coe (n h) : (PNat.val (⟨n, h⟩ : ℕ+) : ℕ) = n := + rfl From fbafdd9a477bd73af4efae17da46960fe9a83142 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 11:53:46 -0400 Subject: [PATCH 028/127] InjSurj update --- Mathlib/Algebra/Group/InjSurj.lean | 83 +++++++++++++++++++----------- 1 file changed, 54 insertions(+), 29 deletions(-) diff --git a/Mathlib/Algebra/Group/InjSurj.lean b/Mathlib/Algebra/Group/InjSurj.lean index e843f06764b73c..70fa014ac87243 100644 --- a/Mathlib/Algebra/Group/InjSurj.lean +++ b/Mathlib/Algebra/Group/InjSurj.lean @@ -5,7 +5,7 @@ Authors: Johan Commelin -/ module -public import Mathlib.Algebra.Group.Defs +public import Mathlib.Algebra.Group.PPow.Defs public import Mathlib.Logic.Function.Basic public import Mathlib.Tactic.Spread @@ -48,9 +48,17 @@ variable {M₁ : Type*} {M₂ : Type*} [Mul M₁] a semigroup. See note [reducible non-instances]. -/ @[to_additive /-- A type endowed with `+` is an additive semigroup, if it admits an injective map that preserves `+` to an additive semigroup. -/] -protected abbrev semigroup [Semigroup M₂] (f : M₁ → M₂) (hf : Injective f) - (mul : ∀ x y, f (x * y) = f x * f y) : Semigroup M₁ where +protected abbrev semigroup [Pow M₁ ℕ+] [Semigroup M₂] (f : M₁ → M₂) (hf : Injective f) + (mul : ∀ x y, f (x * y) = f x * f y) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) : Semigroup M₁ where mul_assoc := fun x y z => hf <| by rw [mul, mul, mul, mul, mul_assoc] + ppow := fun n hn x => (x ^ (PNat.mk n hn : ℕ+)) + ppow_one := fun x => hf <| by simp [ppow, ppow_one] + ppow_succ := fun n x => hf <| by + rw [ppow, mul, ppow] + change Semigroup.ppow (x + 2) _ _ = _ + rw [Semigroup.ppow_succ] + rfl /-- A type endowed with `*` is a commutative magma, if it admits a surjective map that preserves `*` from a commutative magma. -/ @@ -66,9 +74,10 @@ preserves `*` to a commutative semigroup. See note [reducible non-instances]. - @[to_additive /-- A type endowed with `+` is an additive commutative semigroup,if it admits an injective map that preserves `+` to an additive commutative semigroup. -/] -protected abbrev commSemigroup [CommSemigroup M₂] (f : M₁ → M₂) (hf : Injective f) - (mul : ∀ x y, f (x * y) = f x * f y) : CommSemigroup M₁ where - toSemigroup := hf.semigroup f mul +protected abbrev commSemigroup [Pow M₁ ℕ+] [CommSemigroup M₂] (f : M₁ → M₂) (hf : Injective f) + (mul : ∀ x y, f (x * y) = f x * f y) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) : CommSemigroup M₁ where + toSemigroup := hf.semigroup f mul ppow __ := hf.commMagma f mul /-- A type has left-cancellative multiplication, if it admits an injective map that @@ -100,18 +109,22 @@ protected theorem isCancelMul [Mul M₂] [IsCancelMul M₂] (f : M₁ → M₂) preserves `*` to a left cancel semigroup. See note [reducible non-instances]. -/ @[to_additive /-- A type endowed with `+` is an additive left cancel semigroup, if it admits an injective map that preserves `+` to an additive left cancel semigroup. -/] -protected abbrev leftCancelSemigroup [LeftCancelSemigroup M₂] (f : M₁ → M₂) (hf : Injective f) - (mul : ∀ x y, f (x * y) = f x * f y) : LeftCancelSemigroup M₁ := - { hf.semigroup f mul, hf.isLeftCancelMul f mul with } +protected abbrev leftCancelSemigroup [Pow M₁ ℕ+] [LeftCancelSemigroup M₂] + (f : M₁ → M₂) (hf : Injective f) + (mul : ∀ x y, f (x * y) = f x * f y) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) : LeftCancelSemigroup M₁ := + { hf.semigroup f mul ppow, hf.isLeftCancelMul f mul with } /-- A type endowed with `*` is a right cancel semigroup, if it admits an injective map that preserves `*` to a right cancel semigroup. See note [reducible non-instances]. -/ @[to_additive /-- A type endowed with `+` is an additive right cancel semigroup, if it admits an injective map that preserves `+` to an additive right cancel semigroup. -/] -protected abbrev rightCancelSemigroup [RightCancelSemigroup M₂] (f : M₁ → M₂) (hf : Injective f) - (mul : ∀ x y, f (x * y) = f x * f y) : RightCancelSemigroup M₁ := - { hf.semigroup f mul, hf.isRightCancelMul f mul with } +protected abbrev rightCancelSemigroup [Pow M₁ ℕ+] [RightCancelSemigroup M₂] + (f : M₁ → M₂) (hf : Injective f) + (mul : ∀ x y, f (x * y) = f x * f y) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) : RightCancelSemigroup M₁ := + { hf.semigroup f mul ppow, hf.isRightCancelMul f mul with } variable [One M₁] @@ -125,7 +138,7 @@ protected abbrev mulOneClass [MulOneClass M₂] (f : M₁ → M₂) (hf : Inject one_mul := fun x => hf <| by rw [mul, one, one_mul] mul_one := fun x => hf <| by rw [mul, one, mul_one] -variable [Pow M₁ ℕ] +variable [Pow M₁ ℕ+] [Pow M₁ ℕ] /-- A type endowed with `1` and `*` is a monoid, if it admits an injective map that preserves `1` and `*` to a monoid. See note [reducible non-instances]. -/ @@ -134,8 +147,9 @@ and `*` to a monoid. See note [reducible non-instances]. -/ injective map that preserves `0` and `+` to an additive monoid. See note [reducible non-instances]. -/] protected abbrev monoid [Monoid M₂] (f : M₁ → M₂) (hf : Injective f) (one : f 1 = 1) - (mul : ∀ x y, f (x * y) = f x * f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : Monoid M₁ := - { hf.semigroup f mul, hf.mulOneClass f one mul with + (mul : ∀ x y, f (x * y) = f x * f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : Monoid M₁ := + { hf.semigroup f mul ppow, hf.mulOneClass f one mul with npow := fun n x => x ^ n, npow_zero := fun x => hf <| by rw [npow, one, pow_zero], npow_succ := fun n x => hf <| by rw [npow, pow_succ, mul, npow] } @@ -147,8 +161,9 @@ preserves `1` and `*` to a left cancel monoid. See note [reducible non-instances admits an injective map that preserves `0` and `+` to an additive left cancel monoid. -/] protected abbrev leftCancelMonoid [LeftCancelMonoid M₂] (f : M₁ → M₂) (hf : Injective f) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : LeftCancelMonoid M₁ := - { hf.monoid f one mul npow, hf.leftCancelSemigroup f mul with } + { hf.monoid f one mul ppow npow, hf.leftCancelSemigroup f mul ppow with } /-- A type endowed with `1` and `*` is a right cancel monoid, if it admits an injective map that preserves `1` and `*` to a right cancel monoid. See note [reducible non-instances]. -/ @@ -157,8 +172,9 @@ preserves `1` and `*` to a right cancel monoid. See note [reducible non-instance admits an injective map that preserves `0` and `+` to an additive left cancel monoid. -/] protected abbrev rightCancelMonoid [RightCancelMonoid M₂] (f : M₁ → M₂) (hf : Injective f) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : RightCancelMonoid M₁ := - { hf.monoid f one mul npow, hf.rightCancelSemigroup f mul with } + { hf.monoid f one mul ppow npow, hf.rightCancelSemigroup f mul ppow with } /-- A type endowed with `1` and `*` is a cancel monoid, if it admits an injective map that preserves `1` and `*` to a cancel monoid. See note [reducible non-instances]. -/ @@ -166,9 +182,10 @@ protected abbrev rightCancelMonoid [RightCancelMonoid M₂] (f : M₁ → M₂) /-- A type endowed with `0` and `+` is an additive left cancel monoid,if it admits an injective map that preserves `0` and `+` to an additive left cancel monoid. -/] protected abbrev cancelMonoid [CancelMonoid M₂] (f : M₁ → M₂) (hf : Injective f) (one : f 1 = 1) - (mul : ∀ x y, f (x * y) = f x * f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : + (mul : ∀ x y, f (x * y) = f x * f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : CancelMonoid M₁ := - { hf.leftCancelMonoid f one mul npow, hf.rightCancelMonoid f one mul npow with } + { hf.leftCancelMonoid f one mul ppow npow, hf.rightCancelMonoid f one mul ppow npow with } /-- A type endowed with `1` and `*` is a commutative monoid, if it admits an injective map that preserves `1` and `*` to a commutative monoid. See note [reducible non-instances]. -/ @@ -176,9 +193,10 @@ preserves `1` and `*` to a commutative monoid. See note [reducible non-instance /-- A type endowed with `0` and `+` is an additive commutative monoid, if it admits an injective map that preserves `0` and `+` to an additive commutative monoid. -/] protected abbrev commMonoid [CommMonoid M₂] (f : M₁ → M₂) (hf : Injective f) (one : f 1 = 1) - (mul : ∀ x y, f (x * y) = f x * f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : + (mul : ∀ x y, f (x * y) = f x * f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : CommMonoid M₁ := - { hf.monoid f one mul npow, hf.commSemigroup f mul with } + { hf.monoid f one mul ppow npow, hf.commSemigroup f mul ppow with } /-- A type endowed with `1` and `*` is a cancel commutative monoid if it admits an injective map that preserves `1` and `*` to a cancel commutative monoid. See note [reducible non-instances]. -/ @@ -186,8 +204,9 @@ that preserves `1` and `*` to a cancel commutative monoid. See note [reducible n admits an injective map that preserves `0` and `+` to an additive cancel commutative monoid. -/] protected abbrev cancelCommMonoid [CancelCommMonoid M₂] (f : M₁ → M₂) (hf : Injective f) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : CancelCommMonoid M₁ := - { hf.commMonoid f one mul npow, hf.leftCancelSemigroup f mul with } + { hf.commMonoid f one mul ppow npow, hf.leftCancelSemigroup f mul ppow with } /-- A type has an involutive inversion if it admits a surjective map that preserves `⁻¹` to a type which has an involutive inversion. See note [reducible non-instances] -/ @@ -219,10 +238,11 @@ that preserves `1`, `*`, `⁻¹`, and `/` to a `DivInvMonoid`. See note [reducib a `SubNegMonoid`. This version takes custom `nsmul` and `zsmul` as `[SMul ℕ M₁]` and `[SMul ℤ M₁]` arguments. -/] protected abbrev divInvMonoid [DivInvMonoid M₂] (f : M₁ → M₂) (hf : Injective f) (one : f 1 = 1) - (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) + (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (div : ∀ x y, f (x / y) = f x / f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : DivInvMonoid M₁ := - { hf.monoid f one mul npow with + { hf.monoid f one mul ppow npow with zpow := fun n x => x ^ n, zpow_zero' := fun x => hf <| by rw [zpow, zpow_zero, one], zpow_succ' := fun n x => hf <| by rw [zpow, mul, zpow_natCast, pow_succ, zpow, zpow_natCast], @@ -239,9 +259,10 @@ map that preserves `1`, `*`, `⁻¹`, and `/` to a `DivInvOneMonoid`. See note `[SMul ℤ M₁]` arguments. -/] protected abbrev divInvOneMonoid [DivInvOneMonoid M₂] (f : M₁ → M₂) (hf : Injective f) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (div : ∀ x y, f (x / y) = f x / f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : DivInvOneMonoid M₁ := - { hf.divInvMonoid f one mul inv div npow zpow, hf.invOneClass f one inv with } + { hf.divInvMonoid f one mul inv ppow div npow zpow, hf.invOneClass f one inv with } /-- A type endowed with `1`, `*`, `⁻¹`, and `/` is a `DivisionMonoid` if it admits an injective map that preserves `1`, `*`, `⁻¹`, and `/` to a `DivisionMonoid`. See note [reducible non-instances] -/ @@ -252,9 +273,10 @@ binary `-` to a `SubtractionMonoid`. This version takes custom `nsmul` and `zsmu and `[SMul ℤ M₁]` arguments. -/] protected abbrev divisionMonoid [DivisionMonoid M₂] (f : M₁ → M₂) (hf : Injective f) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (div : ∀ x y, f (x / y) = f x / f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : DivisionMonoid M₁ := - { hf.divInvMonoid f one mul inv div npow zpow, hf.involutiveInv f inv with + { hf.divInvMonoid f one mul inv ppow div npow zpow, hf.involutiveInv f inv with mul_inv_rev := fun x y => hf <| by rw [inv, mul, mul_inv_rev, mul, inv, inv], inv_eq_of_mul := fun x y h => hf <| by rw [inv, inv_eq_of_mul_eq_one_right (by rw [← mul, h, one])] } @@ -269,9 +291,10 @@ and binary `-` to a `SubtractionCommMonoid`. This version takes custom `nsmul` a `[SMul ℕ M₁]` and `[SMul ℤ M₁]` arguments. -/] protected abbrev divisionCommMonoid [DivisionCommMonoid M₂] (f : M₁ → M₂) (hf : Injective f) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (div : ∀ x y, f (x / y) = f x / f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : DivisionCommMonoid M₁ := - { hf.divisionMonoid f one mul inv div npow zpow, hf.commSemigroup f mul with } + { hf.divisionMonoid f one mul inv ppow div npow zpow, hf.commSemigroup f mul ppow with } /-- A type endowed with `1`, `*` and `⁻¹` is a group, if it admits an injective map that preserves `1`, `*` and `⁻¹` to a group. See note [reducible non-instances]. -/ @@ -280,9 +303,10 @@ protected abbrev divisionCommMonoid [DivisionCommMonoid M₂] (f : M₁ → M₂ injective map that preserves `0` and `+` to an additive group. -/] protected abbrev group [Group M₂] (f : M₁ → M₂) (hf : Injective f) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (div : ∀ x y, f (x / y) = f x / f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : Group M₁ := - { hf.divInvMonoid f one mul inv div npow zpow with + { hf.divInvMonoid f one mul inv ppow div npow zpow with inv_mul_cancel := fun x => hf <| by rw [mul, inv, inv_mul_cancel, one] } @@ -293,9 +317,10 @@ preserves `1`, `*` and `⁻¹` to a commutative group. See note [reducible non-i admits an injective map that preserves `0` and `+` to an additive commutative group. -/] protected abbrev commGroup [CommGroup M₂] (f : M₁ → M₂) (hf : Injective f) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (div : ∀ x y, f (x / y) = f x / f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : CommGroup M₁ := - { hf.group f one mul inv div npow zpow, hf.commMonoid f one mul npow with } + { hf.group f one mul inv ppow div npow zpow, hf.commMonoid f one mul ppow npow with } end Injective From 069661c2d0191c2fe079ea13f20904d09c3a3c01 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 13:26:45 -0400 Subject: [PATCH 029/127] InjSurj update --- Mathlib/Algebra/Group/InjSurj.lean | 44 +++++++++++++++++++--------- Mathlib/Algebra/Group/PPow/Defs.lean | 14 +++++++++ 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/Mathlib/Algebra/Group/InjSurj.lean b/Mathlib/Algebra/Group/InjSurj.lean index 70fa014ac87243..ecb8f8eebc0771 100644 --- a/Mathlib/Algebra/Group/InjSurj.lean +++ b/Mathlib/Algebra/Group/InjSurj.lean @@ -338,9 +338,18 @@ semigroup. See note [reducible non-instances]. -/ @[to_additive /-- A type endowed with `+` is an additive semigroup, if it admits a surjective map that preserves `+` from an additive semigroup. -/] -protected abbrev semigroup [Semigroup M₁] (f : M₁ → M₂) (hf : Surjective f) - (mul : ∀ x y, f (x * y) = f x * f y) : Semigroup M₂ where +protected abbrev semigroup [Pow M₂ ℕ+] [Semigroup M₁] (f : M₁ → M₂) (hf : Surjective f) + (mul : ∀ x y, f (x * y) = f x * f y) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) : Semigroup M₂ where mul_assoc := hf.forall₃.2 fun x y z => by simp only [← mul, mul_assoc] + ppow := fun n hn x => x ^ (PNat.mk n hn : ℕ+) + ppow_one := hf.forall.2 fun x => by simp [← ppow] + ppow_succ := hf.forall.2 fun x n => by + rw [← ppow, ← ppow, ← mul] + congr + change Semigroup.ppow (n + 2) _ _ = _ + rw [Semigroup.ppow_succ] + rfl /-- A type endowed with `*` is a commutative semigroup, if it admits a surjective map that preserves `*` from a commutative semigroup. See note [reducible non-instances]. -/ @@ -356,9 +365,10 @@ protected abbrev commMagma [CommMagma M₁] (f : M₁ → M₂) (hf : Surjective @[to_additive /-- A type endowed with `+` is an additive commutative semigroup, if it admits a surjective map that preserves `+` from an additive commutative semigroup. -/] -protected abbrev commSemigroup [CommSemigroup M₁] (f : M₁ → M₂) (hf : Surjective f) - (mul : ∀ x y, f (x * y) = f x * f y) : CommSemigroup M₂ where - toSemigroup := hf.semigroup f mul +protected abbrev commSemigroup [Pow M₂ ℕ+] [CommSemigroup M₁] (f : M₁ → M₂) (hf : Surjective f) + (mul : ∀ x y, f (x * y) = f x * f y) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) : CommSemigroup M₂ where + toSemigroup := hf.semigroup f mul ppow __ := hf.commMagma f mul variable [One M₂] @@ -373,7 +383,7 @@ protected abbrev mulOneClass [MulOneClass M₁] (f : M₁ → M₂) (hf : Surjec one_mul := hf.forall.2 fun x => by rw [← one, ← mul, one_mul] mul_one := hf.forall.2 fun x => by rw [← one, ← mul, mul_one] -variable [Pow M₂ ℕ] +variable [Pow M₂ ℕ+] [Pow M₂ ℕ] /-- A type endowed with `1` and `*` is a monoid, if it admits a surjective map that preserves `1` and `*` to a monoid. See note [reducible non-instances]. -/ @@ -382,8 +392,9 @@ and `*` to a monoid. See note [reducible non-instances]. -/ surjective map that preserves `0` and `+` to an additive monoid. This version takes a custom `nsmul` as a `[SMul ℕ M₂]` argument. -/] protected abbrev monoid [Monoid M₁] (f : M₁ → M₂) (hf : Surjective f) (one : f 1 = 1) - (mul : ∀ x y, f (x * y) = f x * f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : Monoid M₂ := - { hf.semigroup f mul, hf.mulOneClass f one mul with + (mul : ∀ x y, f (x * y) = f x * f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : Monoid M₂ := + { hf.semigroup f mul ppow, hf.mulOneClass f one mul with npow := fun n x => x ^ n, npow_zero := hf.forall.2 fun x => by rw [← npow, pow_zero, ← one], npow_succ := fun n => hf.forall.2 fun x => by @@ -396,9 +407,10 @@ preserves `1` and `*` from a commutative monoid. See note [reducible non-instanc /-- A type endowed with `0` and `+` is an additive commutative monoid, if it admits a surjective map that preserves `0` and `+` to an additive commutative monoid. -/] protected abbrev commMonoid [CommMonoid M₁] (f : M₁ → M₂) (hf : Surjective f) (one : f 1 = 1) - (mul : ∀ x y, f (x * y) = f x * f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : + (mul : ∀ x y, f (x * y) = f x * f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : CommMonoid M₂ := - { hf.monoid f one mul npow, hf.commSemigroup f mul with } + { hf.monoid f one mul ppow npow, hf.commSemigroup f mul ppow with } /-- A type has an involutive inversion if it admits a surjective map that preserves `⁻¹` to a type which has an involutive inversion. See note [reducible non-instances] -/ @@ -419,16 +431,18 @@ that preserves `1`, `*`, `⁻¹`, and `/` to a `DivInvMonoid`. See note [reducib a `SubNegMonoid`. -/] protected abbrev divInvMonoid [DivInvMonoid M₁] (f : M₁ → M₂) (hf : Surjective f) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (div : ∀ x y, f (x / y) = f x / f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : DivInvMonoid M₂ := - { hf.monoid f one mul npow with + { hf.monoid f one mul ppow npow with zpow := fun n x => x ^ n, zpow_zero' := hf.forall.2 fun x => by rw [← zpow, zpow_zero, ← one], zpow_succ' := fun n => hf.forall.2 fun x => by rw [← zpow, ← zpow, zpow_natCast, zpow_natCast, pow_succ, ← mul], zpow_neg' := fun n => hf.forall.2 fun x => by rw [← zpow, ← zpow, zpow_negSucc, zpow_natCast, inv], - div_eq_mul_inv := hf.forall₂.2 fun x y => by rw [← inv, ← mul, ← div, div_eq_mul_inv] } + div_eq_mul_inv := hf.forall₂.2 fun x y => by + rw [← inv, ← mul, ← div, div_eq_mul_inv] } /-- A type endowed with `1`, `*` and `⁻¹` is a group, if it admits a surjective map that preserves `1`, `*` and `⁻¹` to a group. See note [reducible non-instances]. -/ @@ -437,9 +451,10 @@ protected abbrev divInvMonoid [DivInvMonoid M₁] (f : M₁ → M₂) (hf : Surj surjective map that preserves `0` and `+` to an additive group. -/] protected abbrev group [Group M₁] (f : M₁ → M₂) (hf : Surjective f) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (div : ∀ x y, f (x / y) = f x / f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : Group M₂ := - { hf.divInvMonoid f one mul inv div npow zpow with + { hf.divInvMonoid f one mul inv ppow div npow zpow with inv_mul_cancel := hf.forall.2 fun x => by rw [← inv, ← mul, inv_mul_cancel, one] } /-- A type endowed with `1`, `*`, `⁻¹`, and `/` is a commutative group, if it admits a surjective @@ -450,9 +465,10 @@ map that preserves `1`, `*`, `⁻¹`, and `/` from a commutative group. See note admits a surjective map that preserves `0` and `+` to an additive commutative group. -/] protected abbrev commGroup [CommGroup M₁] (f : M₁ → M₂) (hf : Surjective f) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (div : ∀ x y, f (x / y) = f x / f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : CommGroup M₂ := - { hf.group f one mul inv div npow zpow, hf.commMonoid f one mul npow with } + { hf.group f one mul inv ppow div npow zpow, hf.commMonoid f one mul ppow npow with } end Surjective diff --git a/Mathlib/Algebra/Group/PPow/Defs.lean b/Mathlib/Algebra/Group/PPow/Defs.lean index 75612ab6323160..8db3d2a83c3377 100644 --- a/Mathlib/Algebra/Group/PPow/Defs.lean +++ b/Mathlib/Algebra/Group/PPow/Defs.lean @@ -27,6 +27,20 @@ instance AddSemigroup.instSMul [AddSemigroup M] : SMul ℕ+ M where attribute [to_additive existing AddSemigroup.instSMul] Semigroup.instPow +@[to_additive (attr := simp)] +lemma Semigroup.ppow_eq_pow [Semigroup M] (x : M) (n : ℕ+) : + Semigroup.ppow n n.property x = x ^ n := + rfl + @[to_additive (attr := simp)] lemma ppow_one [Semigroup M] (x : M) : x ^ (1 : ℕ+) = x := Semigroup.ppow_one _ + +@[to_additive (attr := simp)] +theorem npow_val_eq_ppow [Monoid M] (n : ℕ+) (x : M) : x ^ n.val = x ^ n := by + rcases n with ⟨_|n, hn⟩ + · contradiction + simp only [mk_coe, ← Semigroup.ppow_eq_pow] + induction n + · simp [Semigroup.ppow_one] + · simp_all [Semigroup.ppow_succ, pow_succ'] From f4d2fae069e64781634bd5f16695f1497aea3c5c Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 15:02:30 -0400 Subject: [PATCH 030/127] InjSurj update --- Mathlib/Algebra/GroupWithZero/InjSurj.lean | 72 +++-- Mathlib/Algebra/Ring/InjSurj.lean | 310 ++++++++++++--------- 2 files changed, 227 insertions(+), 155 deletions(-) diff --git a/Mathlib/Algebra/GroupWithZero/InjSurj.lean b/Mathlib/Algebra/GroupWithZero/InjSurj.lean index f4dcc90064bab7..dfa6aa0471046b 100644 --- a/Mathlib/Algebra/GroupWithZero/InjSurj.lean +++ b/Mathlib/Algebra/GroupWithZero/InjSurj.lean @@ -102,17 +102,19 @@ section SemigroupWithZero /-- Pull back a `SemigroupWithZero` along an injective function. See note [reducible non-instances]. -/ -protected abbrev Function.Injective.semigroupWithZero [Zero M₀'] [Mul M₀'] [SemigroupWithZero M₀] - (f : M₀' → M₀) (hf : Injective f) (zero : f 0 = 0) (mul : ∀ x y, f (x * y) = f x * f y) : +protected abbrev Function.Injective.semigroupWithZero [Zero M₀'] [Mul M₀'] [Pow M₀' ℕ+] + [SemigroupWithZero M₀] (f : M₀' → M₀) (hf : Injective f) (zero : f 0 = 0) + (mul : ∀ x y, f (x * y) = f x * f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) : SemigroupWithZero M₀' := - { hf.mulZeroClass f zero mul, ‹Zero M₀'›, hf.semigroup f mul with } + { hf.mulZeroClass f zero mul, ‹Zero M₀'›, hf.semigroup f mul ppow with } /-- Push forward a `SemigroupWithZero` along a surjective function. See note [reducible non-instances]. -/ protected abbrev Function.Surjective.semigroupWithZero [SemigroupWithZero M₀] [Zero M₀'] [Mul M₀'] - (f : M₀ → M₀') (hf : Surjective f) (zero : f 0 = 0) (mul : ∀ x y, f (x * y) = f x * f y) : + [Pow M₀' ℕ+] (f : M₀ → M₀') (hf : Surjective f) (zero : f 0 = 0) + (mul : ∀ x y, f (x * y) = f x * f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) : SemigroupWithZero M₀' := - { hf.mulZeroClass f zero mul, ‹Zero M₀'›, hf.semigroup f mul with } + { hf.mulZeroClass f zero mul, ‹Zero M₀'›, hf.semigroup f mul ppow with } end SemigroupWithZero @@ -121,34 +123,38 @@ section MonoidWithZero /-- Pull back a `MonoidWithZero` along an injective function. See note [reducible non-instances]. -/ protected abbrev Function.Injective.monoidWithZero [Zero M₀'] [Mul M₀'] [One M₀'] [Pow M₀' ℕ] - [MonoidWithZero M₀] (f : M₀' → M₀) (hf : Injective f) (zero : f 0 = 0) (one : f 1 = 1) - (mul : ∀ x y, f (x * y) = f x * f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : + [Pow M₀' ℕ+] [MonoidWithZero M₀] (f : M₀' → M₀) (hf : Injective f) (zero : f 0 = 0) + (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : MonoidWithZero M₀' := - { hf.monoid f one mul npow, hf.mulZeroClass f zero mul with } + { hf.monoid f one mul ppow npow, hf.mulZeroClass f zero mul with } /-- Push forward a `MonoidWithZero` along a surjective function. See note [reducible non-instances]. -/ protected abbrev Function.Surjective.monoidWithZero [Zero M₀'] [Mul M₀'] [One M₀'] [Pow M₀' ℕ] - [MonoidWithZero M₀] (f : M₀ → M₀') (hf : Surjective f) (zero : f 0 = 0) (one : f 1 = 1) - (mul : ∀ x y, f (x * y) = f x * f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : + [Pow M₀' ℕ+] [MonoidWithZero M₀] (f : M₀ → M₀') (hf : Surjective f) (zero : f 0 = 0) + (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : MonoidWithZero M₀' := - { hf.monoid f one mul npow, hf.mulZeroClass f zero mul with } + { hf.monoid f one mul ppow npow, hf.mulZeroClass f zero mul with } /-- Pull back a `CommMonoidWithZero` along an injective function. See note [reducible non-instances]. -/ protected abbrev Function.Injective.commMonoidWithZero [Zero M₀'] [Mul M₀'] [One M₀'] [Pow M₀' ℕ] - [CommMonoidWithZero M₀] (f : M₀' → M₀) (hf : Injective f) (zero : f 0 = 0) (one : f 1 = 1) - (mul : ∀ x y, f (x * y) = f x * f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : + [Pow M₀' ℕ+] [CommMonoidWithZero M₀] (f : M₀' → M₀) (hf : Injective f) (zero : f 0 = 0) + (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : CommMonoidWithZero M₀' := - { hf.commMonoid f one mul npow, hf.mulZeroClass f zero mul with } + { hf.commMonoid f one mul ppow npow, hf.mulZeroClass f zero mul with } /-- Push forward a `CommMonoidWithZero` along a surjective function. See note [reducible non-instances]. -/ protected abbrev Function.Surjective.commMonoidWithZero [Zero M₀'] [Mul M₀'] [One M₀'] [Pow M₀' ℕ] - [CommMonoidWithZero M₀] (f : M₀ → M₀') (hf : Surjective f) (zero : f 0 = 0) (one : f 1 = 1) - (mul : ∀ x y, f (x * y) = f x * f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : + [Pow M₀' ℕ+] [CommMonoidWithZero M₀] (f : M₀ → M₀') (hf : Surjective f) (zero : f 0 = 0) + (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : CommMonoidWithZero M₀' := - { hf.commMonoid f one mul npow, hf.mulZeroClass f zero mul with } + { hf.commMonoid f one mul ppow npow, hf.mulZeroClass f zero mul with } end MonoidWithZero @@ -159,12 +165,14 @@ variable [GroupWithZero G₀] /-- Pull back a `GroupWithZero` along an injective function. See note [reducible non-instances]. -/ protected abbrev Function.Injective.groupWithZero [Zero G₀'] [Mul G₀'] [One G₀'] [Inv G₀'] [Div G₀'] - [Pow G₀' ℕ] [Pow G₀' ℤ] (f : G₀' → G₀) (hf : Injective f) (zero : f 0 = 0) (one : f 1 = 1) + [Pow G₀' ℕ] [Pow G₀' ℕ+] [Pow G₀' ℤ] (f : G₀' → G₀) (hf : Injective f) (zero : f 0 = 0) + (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) - (div : ∀ x y, f (x / y) = f x / f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) + (div : ∀ x y, f (x / y) = f x / f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : GroupWithZero G₀' := - { hf.monoidWithZero f zero one mul npow, - hf.divInvMonoid f one mul inv div npow zpow, + { hf.monoidWithZero f zero one mul ppow npow, + hf.divInvMonoid f one mul inv ppow div npow zpow, domain_nontrivial f zero one with inv_zero := hf <| by rw [inv, zero, inv_zero], mul_inv_cancel := fun x hx => hf <| by @@ -173,12 +181,15 @@ protected abbrev Function.Injective.groupWithZero [Zero G₀'] [Mul G₀'] [One /-- Push forward a `GroupWithZero` along a surjective function. See note [reducible non-instances]. -/ protected abbrev Function.Surjective.groupWithZero [Zero G₀'] [Mul G₀'] [One G₀'] [Inv G₀'] - [Div G₀'] [Pow G₀' ℕ] [Pow G₀' ℤ] (h01 : (0 : G₀') ≠ 1) (f : G₀ → G₀') (hf : Surjective f) + [Div G₀'] [Pow G₀' ℕ] [Pow G₀' ℕ+] [Pow G₀' ℤ] (h01 : (0 : G₀') ≠ 1) (f : G₀ → G₀') + (hf : Surjective f) (zero : f 0 = 0) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) (div : ∀ x y, f (x / y) = f x / f y) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : GroupWithZero G₀' := - { hf.monoidWithZero f zero one mul npow, hf.divInvMonoid f one mul inv div npow zpow with + { hf.monoidWithZero f zero one mul ppow npow, + hf.divInvMonoid f one mul inv ppow div npow zpow with inv_zero := by rw [← zero, ← inv, inv_zero], mul_inv_cancel := hf.forall.2 fun x hx => by rw [← inv, ← mul, mul_inv_cancel₀ (mt (congr_arg f) fun h ↦ hx (h.trans zero)), one] @@ -193,21 +204,26 @@ variable [CommGroupWithZero G₀] /-- Pull back a `CommGroupWithZero` along an injective function. See note [reducible non-instances]. -/ protected abbrev Function.Injective.commGroupWithZero [Zero G₀'] [Mul G₀'] [One G₀'] [Inv G₀'] - [Div G₀'] [Pow G₀' ℕ] [Pow G₀' ℤ] (f : G₀' → G₀) (hf : Injective f) (zero : f 0 = 0) + [Div G₀'] [Pow G₀' ℕ] [Pow G₀' ℕ+] [Pow G₀' ℤ] (f : G₀' → G₀) (hf : Injective f) + (zero : f 0 = 0) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) - (div : ∀ x y, f (x / y) = f x / f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) + (div : ∀ x y, f (x / y) = f x / f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : CommGroupWithZero G₀' := - { hf.groupWithZero f zero one mul inv div npow zpow, hf.commSemigroup f mul with } + { hf.groupWithZero f zero one mul inv div ppow npow zpow, hf.commSemigroup f mul ppow with } /-- Push forward a `CommGroupWithZero` along a surjective function. See note [reducible non-instances]. -/ @[implicit_reducible] protected def Function.Surjective.commGroupWithZero [Zero G₀'] [Mul G₀'] [One G₀'] [Inv G₀'] - [Div G₀'] [Pow G₀' ℕ] [Pow G₀' ℤ] (h01 : (0 : G₀') ≠ 1) (f : G₀ → G₀') (hf : Surjective f) + [Div G₀'] [Pow G₀' ℕ] [Pow G₀' ℕ+] [Pow G₀' ℤ] (h01 : (0 : G₀') ≠ 1) (f : G₀ → G₀') + (hf : Surjective f) (zero : f 0 = 0) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) (div : ∀ x y, f (x / y) = f x / f y) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : CommGroupWithZero G₀' := - { hf.groupWithZero h01 f zero one mul inv div npow zpow, hf.commSemigroup f mul with } + { hf.groupWithZero h01 f zero one mul inv div ppow npow zpow, + hf.commSemigroup f mul ppow with } end CommGroupWithZero diff --git a/Mathlib/Algebra/Ring/InjSurj.lean b/Mathlib/Algebra/Ring/InjSurj.lean index 139aab361e5d9a..0de8728ae352a9 100644 --- a/Mathlib/Algebra/Ring/InjSurj.lean +++ b/Mathlib/Algebra/Ring/InjSurj.lean @@ -44,8 +44,8 @@ theorem rightDistribClass [Mul R] [Add R] [RightDistribClass R] (add : ∀ x y, (mul : ∀ x y, f (x * y) = f x * f y) : RightDistribClass S where right_distrib x y z := hf <| by simp only [*, right_distrib] -variable [Zero S] [One S] [Neg S] [Sub S] [SMul ℕ S] [SMul ℤ S] - [Pow S ℕ] [NatCast S] [IntCast S] +variable [Zero S] [One S] [Neg S] [Sub S] [SMul ℕ+ S] [SMul ℕ S] [SMul ℤ S] + [Pow S ℕ+] [Pow S ℕ] [NatCast S] [IntCast S] /-- Pullback a `Distrib` instance along an injective function. -/ -- See note [reducible non-instances] @@ -69,9 +69,10 @@ if it admits an injective map that preserves `0`, `1` and `+` to an additive mon See note [reducible non-instances]. -/ protected abbrev addMonoidWithOne [AddMonoidWithOne R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (one : f 1 = 1) - (add : ∀ x y, f (x + y) = f x + f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (add : ∀ x y, f (x + y) = f x + f y) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) : AddMonoidWithOne S := - { hf.addMonoid f zero add (swap nsmul) with + { hf.addMonoid f zero add psmul (swap nsmul) with natCast := Nat.cast, natCast_zero := hf (by rw [natCast, Nat.cast_zero, zero]), natCast_succ := fun n => hf (by rw [natCast, Nat.cast_succ, add, one, natCast]) } @@ -79,24 +80,27 @@ protected abbrev addMonoidWithOne [AddMonoidWithOne R] /-- A type endowed with `0`, `1` and `+` is an additive commutative monoid with one, if it admits an injective map that preserves `0`, `1` and `+` to an additive commutative monoid with one. See note [reducible non-instances]. -/ -protected abbrev addCommMonoidWithOne {S} [Zero S] [One S] [Add S] [SMul ℕ S] [NatCast S] - [AddCommMonoidWithOne R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (one : f 1 = 1) - (add : ∀ x y, f (x + y) = f x + f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) +protected abbrev addCommMonoidWithOne {S} [Zero S] [One S] [Add S] [SMul ℕ+ S] + [SMul ℕ S] [NatCast S] [AddCommMonoidWithOne R] (f : S → R) (hf : Injective f) + (zero : f 0 = 0) (one : f 1 = 1) + (add : ∀ x y, f (x + y) = f x + f y) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) : AddCommMonoidWithOne S where - __ := hf.addMonoidWithOne f zero one add nsmul natCast - __ := hf.addCommMonoid _ zero add (swap nsmul) + __ := hf.addMonoidWithOne f zero one add psmul nsmul natCast + __ := hf.addCommMonoid _ zero add psmul (swap nsmul) /-- A type endowed with `0`, `1` and `+` is an additive group with one, if it admits an injective map that preserves `0`, `1` and `+` to an additive group with one. See note [reducible non-instances]. -/ -protected abbrev addGroupWithOne {S} [Zero S] [One S] [Add S] [SMul ℕ S] [Neg S] [Sub S] +protected abbrev addGroupWithOne {S} [Zero S] [One S] [Add S] [SMul ℕ+ S] [SMul ℕ S] [Neg S] [Sub S] [SMul ℤ S] [NatCast S] [IntCast S] [AddGroupWithOne R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (neg : ∀ x, f (-x) = -f x) - (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : AddGroupWithOne S := - { hf.addGroup f zero add neg sub (swap nsmul) (swap zsmul), - hf.addMonoidWithOne f zero one add nsmul natCast with + { hf.addGroup f zero add neg psmul sub (swap nsmul) (swap zsmul), + hf.addMonoidWithOne f zero one add psmul nsmul natCast with intCast := Int.cast, intCast_ofNat := fun n => hf (by rw [natCast, intCast, Int.cast_natCast]), intCast_negSucc := fun n => hf (by rw [intCast, neg, natCast, Int.cast_negSucc]) } @@ -104,21 +108,24 @@ protected abbrev addGroupWithOne {S} [Zero S] [One S] [Add S] [SMul ℕ S] [Neg /-- A type endowed with `0`, `1` and `+` is an additive commutative group with one, if it admits an injective map that preserves `0`, `1` and `+` to an additive commutative group with one. See note [reducible non-instances]. -/ -protected abbrev addCommGroupWithOne {S} [Zero S] [One S] [Add S] [SMul ℕ S] [Neg S] [Sub S] - [SMul ℤ S] [NatCast S] [IntCast S] [AddCommGroupWithOne R] (f : S → R) (hf : Injective f) +protected abbrev addCommGroupWithOne {S} [Zero S] [One S] [Add S] [SMul ℕ+ S] + [SMul ℕ S] [Neg S] [Sub S] [SMul ℤ S] [NatCast S] [IntCast S] + [AddCommGroupWithOne R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (neg : ∀ x, f (-x) = -f x) - (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : AddCommGroupWithOne S := - { hf.addGroupWithOne f zero one add neg sub nsmul zsmul natCast intCast, - hf.addCommMonoid _ zero add (swap nsmul) with } + { hf.addGroupWithOne f zero one add neg psmul sub nsmul zsmul natCast intCast, + hf.addCommMonoid _ zero add psmul (swap nsmul) with } /-- Pullback a `NonUnitalNonAssocSemiring` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalNonAssocSemiring [NonUnitalNonAssocSemiring R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : NonUnitalNonAssocSemiring S where - toAddCommMonoid := hf.addCommMonoid f zero add (swap nsmul) + toAddCommMonoid := hf.addCommMonoid f zero add psmul (swap nsmul) __ := hf.distrib f add mul __ := hf.mulZeroClass f zero mul @@ -126,155 +133,177 @@ protected abbrev nonUnitalNonAssocSemiring [NonUnitalNonAssocSemiring R] (zero : -- See note [reducible non-instances] protected abbrev nonUnitalSemiring [NonUnitalSemiring R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) - (mul : ∀ x y, f (x * y) = f x * f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : + (mul : ∀ x y, f (x * y) = f x * f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : NonUnitalSemiring S where - toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul nsmul - __ := hf.semigroupWithZero f zero mul + toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul psmul nsmul + __ := hf.semigroupWithZero f zero mul ppow /-- Pullback a `NonAssocSemiring` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev nonAssocSemiring [NonAssocSemiring R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) - (mul : ∀ x y, f (x * y) = f x * f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (mul : ∀ x y, f (x * y) = f x * f y) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) : NonAssocSemiring S where - toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul nsmul + toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul psmul nsmul __ := hf.mulZeroOneClass f zero one mul - __ := hf.addMonoidWithOne f zero one add nsmul natCast + __ := hf.addMonoidWithOne f zero one add psmul nsmul natCast /-- Pullback a `Semiring` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev semiring [Semiring R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) : Semiring S where - toNonUnitalSemiring := hf.nonUnitalSemiring f zero add mul nsmul - __ := hf.nonAssocSemiring f zero one add mul nsmul natCast - __ := hf.monoidWithZero f zero one mul npow + toNonUnitalSemiring := hf.nonUnitalSemiring f zero add mul ppow psmul nsmul + __ := hf.nonAssocSemiring f zero one add mul psmul nsmul natCast + __ := hf.monoidWithZero f zero one mul ppow npow /-- Pullback a `NonUnitalNonAssocRing` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalNonAssocRing [NonUnitalNonAssocRing R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) - (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : NonUnitalNonAssocRing S where - toAddCommGroup := hf.addCommGroup f zero add neg sub (swap nsmul) (swap zsmul) - __ := hf.nonUnitalNonAssocSemiring f zero add mul nsmul + toAddCommGroup := hf.addCommGroup f zero add neg psmul sub (swap nsmul) (swap zsmul) + __ := hf.nonUnitalNonAssocSemiring f zero add mul psmul nsmul /-- Pullback a `NonUnitalRing` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalRing [NonUnitalRing R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : + (neg : ∀ x, f (-x) = -f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : NonUnitalRing S where - toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg sub nsmul zsmul - __ := hf.nonUnitalSemiring f zero add mul nsmul + toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg psmul sub nsmul zsmul + __ := hf.nonUnitalSemiring f zero add mul ppow psmul nsmul /-- Pullback a `NonAssocRing` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev nonAssocRing [NonAssocRing R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) - (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : NonAssocRing S where - toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg sub nsmul zsmul - __ := hf.nonAssocSemiring f zero one add mul nsmul natCast - __ := hf.addCommGroupWithOne f zero one add neg sub nsmul zsmul natCast intCast + toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg psmul sub nsmul zsmul + __ := hf.nonAssocSemiring f zero one add mul psmul nsmul natCast + __ := hf.addCommGroupWithOne f zero one add neg psmul sub nsmul zsmul natCast intCast /-- Pullback a `Ring` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev ring [Ring R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) + (neg : ∀ x, f (-x) = -f x) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : Ring S where - toSemiring := hf.semiring f zero one add mul nsmul npow natCast + toSemiring := hf.semiring f zero one add mul psmul nsmul ppow npow natCast -- zsmul included here explicitly to make sure it's picked correctly by `fast_instance%`. zsmul := fun n x ↦ n • x - __ := hf.addGroupWithOne f zero one add neg sub nsmul zsmul natCast intCast - __ := hf.addCommGroup f zero add neg sub (swap nsmul) (swap zsmul) + __ := hf.addGroupWithOne f zero one add neg psmul sub nsmul zsmul natCast intCast + __ := hf.addCommGroup f zero add neg psmul sub (swap nsmul) (swap zsmul) /-- Pullback a `NonUnitalNonAssocCommSemiring` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalNonAssocCommSemiring [NonUnitalNonAssocCommSemiring R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) - (mul : ∀ x y, f (x * y) = f x * f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : + (mul : ∀ x y, f (x * y) = f x * f y) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : NonUnitalNonAssocCommSemiring S where - toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul nsmul + toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul psmul nsmul __ := hf.commMagma f mul /-- Pullback a `NonUnitalCommSemiring` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalCommSemiring [NonUnitalCommSemiring R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) - (mul : ∀ x y, f (x * y) = f x * f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : + (mul : ∀ x y, f (x * y) = f x * f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : NonUnitalCommSemiring S where - toNonUnitalSemiring := hf.nonUnitalSemiring f zero add mul nsmul - __ := hf.commSemigroup f mul + toNonUnitalSemiring := hf.nonUnitalSemiring f zero add mul ppow psmul nsmul + __ := hf.commSemigroup f mul ppow /-- Pullback a `NonAssocCommSemiring` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev nonAssocCommSemiring [NonAssocCommSemiring R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) - (mul : ∀ x y, f (x * y) = f x * f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (mul : ∀ x y, f (x * y) = f x * f y) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) : NonAssocCommSemiring S where - toNonAssocSemiring := hf.nonAssocSemiring f zero one add mul nsmul natCast + toNonAssocSemiring := hf.nonAssocSemiring f zero one add mul psmul nsmul natCast __ := hf.commMagma f mul /-- Pullback a `CommSemiring` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev commSemiring [CommSemiring R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) - (mul : ∀ x y, f (x * y) = f x * f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (mul : ∀ x y, f (x * y) = f x * f y) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) : CommSemiring S where - toSemiring := hf.semiring f zero one add mul nsmul npow natCast - __ := hf.commSemigroup f mul + toSemiring := hf.semiring f zero one add mul psmul nsmul ppow npow natCast + __ := hf.commSemigroup f mul ppow /-- Pullback a `NonUnitalNonAssocCommRing` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalNonAssocCommRing [NonUnitalNonAssocCommRing R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) - (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : NonUnitalNonAssocCommRing S where - toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg sub nsmul zsmul - __ := hf.nonUnitalNonAssocCommSemiring f zero add mul nsmul + toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg psmul sub nsmul zsmul + __ := hf.nonUnitalNonAssocCommSemiring f zero add mul psmul nsmul /-- Pullback a `NonUnitalCommRing` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalCommRing [NonUnitalCommRing R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) - (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : NonUnitalCommRing S where - toNonUnitalRing := hf.nonUnitalRing f zero add mul neg sub nsmul zsmul - __ := hf.nonUnitalNonAssocCommRing f zero add mul neg sub nsmul zsmul + toNonUnitalRing := hf.nonUnitalRing f zero add mul neg ppow psmul sub nsmul zsmul + __ := hf.nonUnitalNonAssocCommRing f zero add mul neg psmul sub nsmul zsmul /-- Pullback a `NonAssocCommRing` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev nonAssocCommRing [NonAssocCommRing R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) - (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : NonAssocCommRing S where - toNonAssocRing := hf.nonAssocRing f zero one add mul neg sub nsmul zsmul natCast intCast - __ := hf.nonUnitalNonAssocCommRing f zero add mul neg sub nsmul zsmul + toNonAssocRing := hf.nonAssocRing f zero one add mul neg psmul sub nsmul zsmul natCast intCast + __ := hf.nonUnitalNonAssocCommRing f zero add mul neg psmul sub nsmul zsmul /-- Pullback a `CommRing` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev commRing [CommRing R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) - (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : CommRing S where - toRing := hf.ring f zero one add mul neg sub nsmul zsmul npow natCast intCast - __ := hf.commMonoid f one mul npow + toRing := hf.ring f zero one add mul neg psmul sub nsmul zsmul ppow npow natCast intCast + __ := hf.commMonoid f one mul ppow npow end Function.Injective @@ -301,8 +330,8 @@ protected abbrev distrib [Distrib R] (add : ∀ x y, f (x + y) = f x + f y) __ := hf.leftDistribClass f add mul __ := hf.rightDistribClass f add mul -variable [Zero S] [One S] [Neg S] [Sub S] [SMul ℕ S] [SMul ℤ S] - [Pow S ℕ] [NatCast S] [IntCast S] +variable [Zero S] [One S] [Neg S] [Sub S] [SMul ℕ+ S] [SMul ℕ S] [SMul ℤ S] + [Pow S ℕ+] [Pow S ℕ] [NatCast S] [IntCast S] /-- A type endowed with `-` and `*` has distributive negation, if it admits a surjective map that preserves `-` and `*` from a type which has distributive negation. -/ @@ -318,9 +347,10 @@ protected abbrev hasDistribNeg [Mul R] [HasDistribNeg R] map that preserves `0`, `1` and `*` from an additive monoid with one. See note [reducible non-instances]. -/ protected abbrev addMonoidWithOne [AddMonoidWithOne R] (zero : f 0 = 0) (one : f 1 = 1) - (add : ∀ x y, f (x + y) = f x + f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (add : ∀ x y, f (x + y) = f x + f y) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) : AddMonoidWithOne S := - { hf.addMonoid f zero add (swap nsmul) with + { hf.addMonoid f zero add psmul (swap nsmul) with natCast := Nat.cast, natCast_zero := by rw [← natCast, Nat.cast_zero, zero] natCast_succ := fun n => by rw [← natCast, Nat.cast_succ, add, one, natCast] } @@ -329,21 +359,23 @@ protected abbrev addMonoidWithOne [AddMonoidWithOne R] (zero : f 0 = 0) (one : f if it admits a surjective map that preserves `0`, `1` and `*` from an additive monoid with one. See note [reducible non-instances]. -/ protected abbrev addCommMonoidWithOne [AddCommMonoidWithOne R] (zero : f 0 = 0) (one : f 1 = 1) - (add : ∀ x y, f (x + y) = f x + f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (add : ∀ x y, f (x + y) = f x + f y) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) : AddCommMonoidWithOne S where - __ := hf.addMonoidWithOne f zero one add nsmul natCast - __ := hf.addCommMonoid _ zero add (swap nsmul) + __ := hf.addMonoidWithOne f zero one add psmul nsmul natCast + __ := hf.addCommMonoid _ zero add psmul (swap nsmul) /-- A type endowed with `0`, `1`, `+` is an additive group with one, if it admits a surjective map that preserves `0`, `1`, and `+` to an additive group with one. See note [reducible non-instances]. -/ protected abbrev addGroupWithOne [AddGroupWithOne R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (neg : ∀ x, f (-x) = -f x) - (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : AddGroupWithOne S := - { hf.addMonoidWithOne f zero one add nsmul natCast, - hf.addGroup f zero add neg sub (swap nsmul) (swap zsmul) with + { hf.addMonoidWithOne f zero one add psmul nsmul natCast, + hf.addGroup f zero add neg psmul sub (swap nsmul) (swap zsmul) with intCast := Int.cast, intCast_ofNat := fun n => by rw [← intCast, Int.cast_natCast, natCast], intCast_negSucc := fun n => by @@ -354,18 +386,20 @@ surjective map that preserves `0`, `1`, and `+` to an additive commutative group See note [reducible non-instances]. -/ protected abbrev addCommGroupWithOne [AddCommGroupWithOne R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (neg : ∀ x, f (-x) = -f x) - (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : AddCommGroupWithOne S := - { hf.addGroupWithOne f zero one add neg sub nsmul zsmul natCast intCast, - hf.addCommMonoid _ zero add (swap nsmul) with } + { hf.addGroupWithOne f zero one add neg psmul sub nsmul zsmul natCast intCast, + hf.addCommMonoid _ zero add psmul (swap nsmul) with } /-- Pushforward a `NonUnitalNonAssocSemiring` instance along a surjective function. See note [reducible non-instances]. -/ protected abbrev nonUnitalNonAssocSemiring [NonUnitalNonAssocSemiring R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : NonUnitalNonAssocSemiring S where - toAddCommMonoid := hf.addCommMonoid f zero add (swap nsmul) + toAddCommMonoid := hf.addCommMonoid f zero add psmul (swap nsmul) __ := hf.distrib f add mul __ := hf.mulZeroClass f zero mul @@ -373,147 +407,169 @@ protected abbrev nonUnitalNonAssocSemiring [NonUnitalNonAssocSemiring R] (zero : -- See note [reducible non-instances] protected abbrev nonUnitalSemiring [NonUnitalSemiring R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : NonUnitalSemiring S where - toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul nsmul - __ := hf.semigroupWithZero f zero mul + toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul psmul nsmul + __ := hf.semigroupWithZero f zero mul ppow /-- Pushforward a `NonAssocSemiring` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev nonAssocSemiring [NonAssocSemiring R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) : NonAssocSemiring S where - toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul nsmul + toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul psmul nsmul __ := hf.mulZeroOneClass f zero one mul - __ := hf.addMonoidWithOne f zero one add nsmul natCast + __ := hf.addMonoidWithOne f zero one add psmul nsmul natCast /-- Pushforward a `Semiring` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev semiring [Semiring R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) : Semiring S where - toNonUnitalSemiring := hf.nonUnitalSemiring f zero add mul nsmul - __ := hf.nonAssocSemiring f zero one add mul nsmul natCast - __ := hf.monoidWithZero f zero one mul npow + toNonUnitalSemiring := hf.nonUnitalSemiring f zero add mul ppow psmul nsmul + __ := hf.nonAssocSemiring f zero one add mul psmul nsmul natCast + __ := hf.monoidWithZero f zero one mul ppow npow /-- Pushforward a `NonUnitalNonAssocRing` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalNonAssocRing [NonUnitalNonAssocRing R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : + (neg : ∀ x, f (-x) = -f x) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : NonUnitalNonAssocRing S where - toAddCommGroup := hf.addCommGroup f zero add neg sub (swap nsmul) (swap zsmul) - __ := hf.nonUnitalNonAssocSemiring f zero add mul nsmul + toAddCommGroup := hf.addCommGroup f zero add neg psmul sub (swap nsmul) (swap zsmul) + __ := hf.nonUnitalNonAssocSemiring f zero add mul psmul nsmul /-- Pushforward a `NonUnitalRing` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalRing [NonUnitalRing R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : + (neg : ∀ x, f (-x) = -f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : NonUnitalRing S where - toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg sub nsmul zsmul - __ := hf.nonUnitalSemiring f zero add mul nsmul + toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg psmul sub nsmul zsmul + __ := hf.nonUnitalSemiring f zero add mul ppow psmul nsmul /-- Pushforward a `NonAssocRing` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev nonAssocRing [NonAssocRing R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) + (neg : ∀ x, f (-x) = -f x) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : NonAssocRing S where - toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg sub nsmul zsmul - __ := hf.nonAssocSemiring f zero one add mul nsmul natCast - __ := hf.addCommGroupWithOne f zero one add neg sub nsmul zsmul natCast intCast + toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg psmul sub nsmul zsmul + __ := hf.nonAssocSemiring f zero one add mul psmul nsmul natCast + __ := hf.addCommGroupWithOne f zero one add neg psmul sub nsmul zsmul natCast intCast /-- Pushforward a `Ring` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev ring [Ring R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) + (neg : ∀ x, f (-x) = -f x) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : Ring S where - toSemiring := hf.semiring f zero one add mul nsmul npow natCast - __ := hf.addGroupWithOne f zero one add neg sub nsmul zsmul natCast intCast - __ := hf.addCommGroup f zero add neg sub (swap nsmul) (swap zsmul) + toSemiring := hf.semiring f zero one add mul psmul nsmul ppow npow natCast + __ := hf.addGroupWithOne f zero one add neg psmul sub nsmul zsmul natCast intCast + __ := hf.addCommGroup f zero add neg psmul sub (swap nsmul) (swap zsmul) /-- Pushforward a `NonUnitalNonAssocCommSemiring` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalNonAssocCommSemiring [NonUnitalNonAssocCommSemiring R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : NonUnitalNonAssocCommSemiring S where - toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul nsmul + toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul psmul nsmul __ := hf.commMagma f mul /-- Pushforward a `NonUnitalCommSemiring` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalCommSemiring [NonUnitalCommSemiring R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : NonUnitalCommSemiring S where - toNonUnitalSemiring := hf.nonUnitalSemiring f zero add mul nsmul - __ := hf.commSemigroup f mul + toNonUnitalSemiring := hf.nonUnitalSemiring f zero add mul ppow psmul nsmul + __ := hf.commSemigroup f mul ppow /-- Pushforward a `NonAssocCommSemiring` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev nonAssocCommSemiring [NonAssocCommSemiring R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) : NonAssocCommSemiring S where - toNonAssocSemiring := hf.nonAssocSemiring f zero one add mul nsmul natCast + toNonAssocSemiring := hf.nonAssocSemiring f zero one add mul psmul nsmul natCast __ := hf.commMagma f mul /-- Pushforward a `CommSemiring` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev commSemiring [CommSemiring R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) : CommSemiring S where - toSemiring := hf.semiring f zero one add mul nsmul npow natCast - __ := hf.commSemigroup f mul + toSemiring := hf.semiring f zero one add mul psmul nsmul ppow npow natCast + __ := hf.commSemigroup f mul ppow /-- Pushforward a `NonUnitalNonAssocCommRing` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalNonAssocCommRing [NonUnitalNonAssocCommRing R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : NonUnitalNonAssocCommRing S where - toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg sub nsmul zsmul - __ := hf.nonUnitalNonAssocCommSemiring f zero add mul nsmul + toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg psmul sub nsmul zsmul + __ := hf.nonUnitalNonAssocCommSemiring f zero add mul psmul nsmul /-- Pushforward a `NonUnitalCommRing` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalCommRing [NonUnitalCommRing R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : + (neg : ∀ x, f (-x) = -f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : NonUnitalCommRing S where - toNonUnitalRing := hf.nonUnitalRing f zero add mul neg sub nsmul zsmul - __ := hf.nonUnitalNonAssocCommRing f zero add mul neg sub nsmul zsmul + toNonUnitalRing := hf.nonUnitalRing f zero add mul neg ppow psmul sub nsmul zsmul + __ := hf.nonUnitalNonAssocCommRing f zero add mul neg psmul sub nsmul zsmul /-- Pushforward a `NonAssocCommRing` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev nonAssocCommRing [NonAssocCommRing R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) + (neg : ∀ x, f (-x) = -f x) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : NonAssocCommRing S where - toNonAssocRing := hf.nonAssocRing f zero one add mul neg sub nsmul zsmul natCast intCast - __ := hf.nonAssocCommSemiring f zero one add mul nsmul natCast + toNonAssocRing := hf.nonAssocRing f zero one add mul neg psmul sub nsmul zsmul natCast intCast + __ := hf.nonAssocCommSemiring f zero one add mul psmul nsmul natCast /-- Pushforward a `CommRing` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev commRing [CommRing R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) + (neg : ∀ x, f (-x) = -f x) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : CommRing S where - toRing := hf.ring f zero one add mul neg sub nsmul zsmul npow natCast intCast - __ := hf.commMonoid f one mul npow + toRing := hf.ring f zero one add mul neg psmul sub nsmul zsmul ppow npow natCast intCast + __ := hf.commMonoid f one mul ppow npow end Function.Surjective From dc2506b63c6b191a6c4b5efa88cde516e3ccc3e5 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 15:54:21 -0400 Subject: [PATCH 031/127] order lemmas --- .../Algebra/Order/GroupWithZero/Basic.lean | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/Mathlib/Algebra/Order/GroupWithZero/Basic.lean b/Mathlib/Algebra/Order/GroupWithZero/Basic.lean index 9810e9a39dfd9d..a7bbbff77876c3 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Basic.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Basic.lean @@ -5,6 +5,7 @@ Authors: Damiano Testa, Yuyang Zhao -/ module +public import Mathlib.Algebra.Group.PPow.Defs public import Mathlib.Algebra.GroupWithZero.Units.Basic public import Mathlib.Algebra.Notation.Pi.Defs public import Mathlib.Algebra.Order.GroupWithZero.Defs @@ -555,6 +556,23 @@ lemma pow_left_strictMonoOn₀ [MulPosMono M₀] (hn : n ≠ 0) : StrictMonoOn (· ^ n : M₀ → M₀) {a | 0 ≤ a} := fun _a ha _b _ hab ↦ pow_lt_pow_left₀ hab ha hn +@[simp] lemma ppow_pos (ha : 0 < a) (n : ℕ+) : 0 < a ^ n := by + rcases n with ⟨n, h⟩ + rw [← npow_val_eq_ppow, mk_coe] + obtain ⟨n, rfl⟩ := Nat.exists_eq_succ_of_ne_zero h.ne' + exact pow_succ_pos ha n + +@[gcongr, bound] +lemma ppow_lt_ppow_left₀ [MulPosMono M₀] (hab : a < b) (ha : 0 ≤ a) {n : ℕ+} : + a ^ n < b ^ n := by + rw [← npow_val_eq_ppow, ← npow_val_eq_ppow] + exact pow_lt_pow_left₀ hab ha n.prop.ne' + +/-- See also `ppow_left_strictMono₀` -/ +lemma ppow_left_strictMonoOn₀ [MulPosMono M₀] (n : ℕ+) : + StrictMonoOn (· ^ n : M₀ → M₀) {a | 0 ≤ a} := + fun _a ha _b _ hn ↦ ppow_lt_ppow_left₀ hn ha + section ZeroLEOneClass variable [ZeroLEOneClass M₀] @@ -567,15 +585,30 @@ lemma pow_right_strictMono₀ (h : 1 < a) : StrictMono (a ^ ·) := @[gcongr] lemma pow_lt_pow_right₀ (h : 1 < a) (hmn : m < n) : a ^ m < a ^ n := pow_right_strictMono₀ h hmn +lemma ppow_lt_ppow_right₀ (h : 1 < a) {m n : ℕ+} (hmn : m.val < n.val) : a ^ m < a ^ n := by + rw [← npow_val_eq_ppow, ← npow_val_eq_ppow] + exact pow_right_strictMono₀ h hmn + lemma pow_lt_pow_iff_right₀ (h : 1 < a) : a ^ n < a ^ m ↔ n < m := (pow_right_strictMono₀ h).lt_iff_lt +lemma ppow_lt_ppow_iff_right₀ (h : 1 < a) {m n : ℕ+} : a ^ m < a ^ n ↔ m.val < n.val := by + rw [← npow_val_eq_ppow, ← npow_val_eq_ppow] + exact (pow_right_strictMono₀ h).lt_iff_lt + lemma pow_le_pow_iff_right₀ (h : 1 < a) : a ^ n ≤ a ^ m ↔ n ≤ m := (pow_right_strictMono₀ h).le_iff_le +lemma ppow_le_ppow_iff_right₀ (h : 1 < a) {m n : ℕ+} : a ^ m ≤ a ^ n ↔ m.val ≤ n.val := by + rw [← npow_val_eq_ppow, ← npow_val_eq_ppow] + exact (pow_right_strictMono₀ h).le_iff_le + lemma lt_self_pow₀ (h : 1 < a) (hm : 1 < m) : a < a ^ m := by simpa only [pow_one] using pow_lt_pow_right₀ h hm +lemma lt_self_ppow₀ (h : 1 < a) {n : ℕ+} (hn : 1 < n.val) : a < a ^ n := by + simpa only [ppow_one] using ppow_lt_ppow_right₀ (m := 1) (n := n) h hn + end ZeroLEOneClass lemma pow_right_strictAnti₀ (h₀ : 0 < a) (h₁ : a < 1) : StrictAnti (a ^ ·) := @@ -586,15 +619,32 @@ lemma pow_right_strictAnti₀ (h₀ : 0 < a) (h₁ : a < 1) : StrictAnti (a ^ · lemma pow_le_pow_iff_right_of_lt_one₀ (ha₀ : 0 < a) (ha₁ : a < 1) : a ^ m ≤ a ^ n ↔ n ≤ m := (pow_right_strictAnti₀ ha₀ ha₁).le_iff_ge +lemma ppow_le_ppow_iff_right_of_lt_one₀ (ha₀ : 0 < a) (ha₁ : a < 1) {m n : ℕ+} : + a ^ m ≤ a ^ n ↔ n.val ≤ m.val := by + rw [← npow_val_eq_ppow, ← npow_val_eq_ppow] + exact (pow_right_strictAnti₀ ha₀ ha₁).le_iff_ge + lemma pow_lt_pow_iff_right_of_lt_one₀ (h₀ : 0 < a) (h₁ : a < 1) : a ^ m < a ^ n ↔ n < m := (pow_right_strictAnti₀ h₀ h₁).lt_iff_gt +lemma ppow_lt_ppow_iff_right_of_lt_one₀ (h₀ : 0 < a) (h₁ : a < 1) {m n : ℕ+} : + a ^ m < a ^ n ↔ n.val < m.val := by + rw [← npow_val_eq_ppow, ← npow_val_eq_ppow] + exact (pow_right_strictAnti₀ h₀ h₁).lt_iff_gt + lemma pow_lt_pow_right_of_lt_one₀ (h₀ : 0 < a) (h₁ : a < 1) (hmn : m < n) : a ^ n < a ^ m := (pow_lt_pow_iff_right_of_lt_one₀ h₀ h₁).2 hmn +lemma ppow_lt_ppow_right_of_lt_one₀ (h₀ : 0 < a) (h₁ : a < 1) {m n : ℕ+} (hmn : m.val < n.val) : + a ^ n < a ^ m := + (ppow_lt_ppow_iff_right_of_lt_one₀ h₀ h₁).2 hmn + lemma pow_lt_self_of_lt_one₀ (h₀ : 0 < a) (h₁ : a < 1) (hn : 1 < n) : a ^ n < a := by simpa only [pow_one] using pow_lt_pow_right_of_lt_one₀ h₀ h₁ hn +lemma ppow_lt_self_of_lt_one₀ (h₀ : 0 < a) (h₁ : a < 1) {n : ℕ+} (hn : 1 < n.val) : a ^ n < a := by + simpa only [ppow_one] using ppow_lt_ppow_right_of_lt_one₀ (m := 1) (n := n) h₀ h₁ hn + end strict_mono variable [Preorder α] {f g : α → M₀} From 56c665ba77e16d984770d588b6b358b4b0dd0075 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 15:57:00 -0400 Subject: [PATCH 032/127] ring order --- Mathlib/Algebra/Order/Positive/Ring.lean | 38 +++++++++++++++++++----- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/Mathlib/Algebra/Order/Positive/Ring.lean b/Mathlib/Algebra/Order/Positive/Ring.lean index a445ed2d6e8bc0..d9c1787276a1f8 100644 --- a/Mathlib/Algebra/Order/Positive/Ring.lean +++ b/Mathlib/Algebra/Order/Positive/Ring.lean @@ -37,20 +37,36 @@ instance : Add { x : M // 0 < x } := theorem coe_add (x y : { x : M // 0 < x }) : ↑(x + y) = (x + y : M) := rfl +instance : SMul ℕ+ { x : M // 0 < x } := + ⟨fun n x => ⟨n • (x : M), by + rcases n with ⟨n, h⟩ + simp only [← nsmul_val_eq_psmul, mk_coe] + induction n with + | zero => exact absurd h (by decide) + | succ n IH => + rcases n with - | n + · simp [one_nsmul, x.2] + · simpa [succ_nsmul _ (n + 1)] using add_pos (IH (Nat.zero_lt_succ n)) x.2 + ⟩⟩ + +@[simp, norm_cast] +lemma coe_psmul (n : ℕ+) (x : { x : M // 0 < x }) : ↑(n • x) = (n • x : M) := + rfl + instance addSemigroup : AddSemigroup { x : M // 0 < x } := fast_instance% - Subtype.coe_injective.addSemigroup _ coe_add + Subtype.coe_injective.addSemigroup _ coe_add (swap coe_psmul) instance addCommSemigroup {M : Type*} [AddCommMonoid M] [Preorder M] [AddLeftStrictMono M] : AddCommSemigroup { x : M // 0 < x } := fast_instance% - Subtype.coe_injective.addCommSemigroup _ coe_add + Subtype.coe_injective.addCommSemigroup _ coe_add (swap coe_psmul) instance addLeftCancelSemigroup {M : Type*} [AddLeftCancelMonoid M] [Preorder M] [AddLeftStrictMono M] : AddLeftCancelSemigroup { x : M // 0 < x } := fast_instance% - Subtype.coe_injective.addLeftCancelSemigroup _ coe_add + Subtype.coe_injective.addLeftCancelSemigroup _ coe_add (swap coe_psmul) instance addRightCancelSemigroup {M : Type*} [AddRightCancelMonoid M] [Preorder M] [AddLeftStrictMono M] : AddRightCancelSemigroup { x : M // 0 < x } := fast_instance% - Subtype.coe_injective.addRightCancelSemigroup _ coe_add + Subtype.coe_injective.addRightCancelSemigroup _ coe_add (swap coe_psmul) instance addLeftStrictMono : AddLeftStrictMono { x : M // 0 < x } := ⟨fun _ y z hyz => Subtype.coe_lt_coe.1 <| add_lt_add_right (show (y : M) < z from hyz) _⟩ @@ -90,13 +106,19 @@ theorem val_mul (x y : { x : R // 0 < x }) : ↑(x * y) = (x * y : R) := instance : Pow { x : R // 0 < x } ℕ := ⟨fun x n => ⟨(x : R) ^ n, pow_pos x.2 n⟩⟩ -@[simp] +instance : Pow { x : R // 0 < x } ℕ+ := + ⟨fun x n => ⟨(x : R) ^ n, ppow_pos x.2 n⟩⟩ + theorem val_pow (x : { x : R // 0 < x }) (n : ℕ) : ↑(x ^ n) = (x : R) ^ n := rfl +theorem val_ppow (x : { x : R // 0 < x }) (n : ℕ+) : + ↑(x ^ n) = (x : R) ^ n := + rfl + instance : Semigroup { x : R // 0 < x } := fast_instance% - Subtype.coe_injective.semigroup Subtype.val val_mul + Subtype.coe_injective.semigroup Subtype.val val_mul val_ppow instance : Distrib { x : R // 0 < x } := fast_instance% Subtype.coe_injective.distrib _ coe_add val_mul @@ -109,7 +131,7 @@ theorem val_one : ((1 : { x : R // 0 < x }) : R) = 1 := rfl instance : Monoid { x : R // 0 < x } := fast_instance% - Subtype.coe_injective.monoid _ val_one val_mul val_pow + Subtype.coe_injective.monoid _ val_one val_mul val_ppow val_pow end Mul @@ -117,7 +139,7 @@ section mul_comm instance commMonoid [CommSemiring R] [PartialOrder R] [IsStrictOrderedRing R] : CommMonoid { x : R // 0 < x } := fast_instance% - Subtype.coe_injective.commMonoid (M₂ := R) (Subtype.val) val_one val_mul val_pow + Subtype.coe_injective.commMonoid (M₂ := R) (Subtype.val) val_one val_mul val_ppow val_pow instance isOrderedMonoid [CommSemiring R] [PartialOrder R] [IsStrictOrderedRing R] : IsOrderedMonoid { x : R // 0 < x } where From 69c0792cab552b95404cface881248209d52b3d6 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 16:26:20 -0400 Subject: [PATCH 033/127] subsemigroup --- Mathlib/Algebra/Group/PPow/Defs.lean | 7 +++++++ Mathlib/Algebra/Group/Subsemigroup/Defs.lean | 22 ++++++++++++++++++-- Mathlib/Data/PNat/Notation.lean | 2 +- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/Mathlib/Algebra/Group/PPow/Defs.lean b/Mathlib/Algebra/Group/PPow/Defs.lean index 8db3d2a83c3377..4f3e58b8feb90e 100644 --- a/Mathlib/Algebra/Group/PPow/Defs.lean +++ b/Mathlib/Algebra/Group/PPow/Defs.lean @@ -36,6 +36,13 @@ lemma Semigroup.ppow_eq_pow [Semigroup M] (x : M) (n : ℕ+) : lemma ppow_one [Semigroup M] (x : M) : x ^ (1 : ℕ+) = x := Semigroup.ppow_one _ +@[to_additive] +lemma ppow_mk_add_one [Semigroup M] (x : M) {n : ℕ} (hn : n ≠ 0) : + x ^ (PNat.mk (n + 1) (Nat.succ_pos n)) = x * x ^ (PNat.mk n (Nat.pos_of_ne_zero hn)) := by + cases n + · contradiction + · simp [← Semigroup.ppow_eq_pow, PNat.mk, Semigroup.ppow_succ] + @[to_additive (attr := simp)] theorem npow_val_eq_ppow [Monoid M] (n : ℕ+) (x : M) : x ^ n.val = x ^ n := by rcases n with ⟨_|n, hn⟩ diff --git a/Mathlib/Algebra/Group/Subsemigroup/Defs.lean b/Mathlib/Algebra/Group/Subsemigroup/Defs.lean index d36ce7b502a23a..b3536667bd2aec 100644 --- a/Mathlib/Algebra/Group/Subsemigroup/Defs.lean +++ b/Mathlib/Algebra/Group/Subsemigroup/Defs.lean @@ -281,18 +281,36 @@ theorem mk_mul_mk (x y : M) (hx : x ∈ S') (hy : y ∈ S') : theorem mul_def (x y : S') : x * y = ⟨x * y, mul_mem x.2 y.2⟩ := rfl +@[to_additive] +lemma ppow_coe_mem {M A : Type*} [Semigroup M] [SetLike A M] [hA : MulMemClass A M] {S' : A} + (x : S') (n : ℕ+) : (x : M) ^ n ∈ S' := by + rcases n with ⟨n, hn⟩ + obtain ⟨n, rfl⟩ := Nat.exists_eq_succ_of_ne_zero hn.ne' + induction n with + | zero => simp [ppow_one] + | succ n IH => + rw [ppow_mk_add_one _ (Nat.succ_ne_zero _)] + exact mul_mem x.2 (IH Nat.succ_pos') + +-- lower priority so other instances are found first +/-- Iterated multiplication via exponentiation by a `ℕ+` is inherited by a submagma. -/ +@[to_additive /-- An additive submagma of an additive magma inherits an addition. -/] +instance (priority := 900) {M A : Type*} [Semigroup M] [SetLike A M] [hA : MulMemClass A M] + {S' : A} : Pow S' ℕ+ := + ⟨fun x n => ⟨x.1 ^ n, ppow_coe_mem _ _⟩⟩ + /-- A subsemigroup of a semigroup inherits a semigroup structure. -/ @[to_additive /-- An `AddSubsemigroup` of an `AddSemigroup` inherits an `AddSemigroup` structure. -/] instance toSemigroup {M : Type*} [Semigroup M] {A : Type*} [SetLike A M] [MulMemClass A M] (S : A) : Semigroup S := fast_instance% - Subtype.coe_injective.semigroup Subtype.val fun _ _ => rfl + Subtype.coe_injective.semigroup Subtype.val (fun _ _ => rfl) fun _ _ => rfl /-- A subsemigroup of a `CommSemigroup` is a `CommSemigroup`. -/ @[to_additive /-- An `AddSubsemigroup` of an `AddCommSemigroup` is an `AddCommSemigroup`. -/] instance toCommSemigroup {M} [CommSemigroup M] {A : Type*} [SetLike A M] [MulMemClass A M] (S : A) : CommSemigroup S := fast_instance% - Subtype.coe_injective.commSemigroup Subtype.val fun _ _ => rfl + Subtype.coe_injective.commSemigroup Subtype.val (fun _ _ => rfl) fun _ _ => rfl /-- A submagma of a left cancellative magma inherits left cancellation. -/ @[to_additive diff --git a/Mathlib/Data/PNat/Notation.lean b/Mathlib/Data/PNat/Notation.lean index 4d4b693d3a1a0a..642eefc2b42bc1 100644 --- a/Mathlib/Data/PNat/Notation.lean +++ b/Mathlib/Data/PNat/Notation.lean @@ -20,7 +20,7 @@ def PNat := { n : ℕ // 0 < n } deriving DecidableEq notation "ℕ+" => PNat /-- Helper constructor for `ℕ+`. -/ -def PNat.mk (n : ℕ) (h : 0 < n) : ℕ+ := ⟨n, h⟩ +abbrev PNat.mk (n : ℕ) (h : 0 < n) : ℕ+ := ⟨n, h⟩ /-- The underlying natural number -/ @[coe] From f52a35f4cc326a6bcaffaf5665b724a8ce1ed43d Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 16:31:16 -0400 Subject: [PATCH 034/127] ulift --- Mathlib/Algebra/Group/ULift.lean | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Mathlib/Algebra/Group/ULift.lean b/Mathlib/Algebra/Group/ULift.lean index 375f8ee797273c..9c568fa19d069c 100644 --- a/Mathlib/Algebra/Group/ULift.lean +++ b/Mathlib/Algebra/Group/ULift.lean @@ -76,11 +76,11 @@ def _root_.MulEquiv.ulift [Mul α] : ULift α ≃* α := @[to_additive] instance semigroup [Semigroup α] : Semigroup (ULift α) := - (MulEquiv.ulift.injective.semigroup _) fun _ _ => rfl + (MulEquiv.ulift.injective.semigroup _) (fun _ _ => rfl) fun _ _ => rfl @[to_additive] instance commSemigroup [CommSemigroup α] : CommSemigroup (ULift α) := - (Equiv.ulift.injective.commSemigroup _) fun _ _ => rfl + (Equiv.ulift.injective.commSemigroup _) (fun _ _ => rfl) fun _ _ => rfl @[to_additive] instance mulOneClass [MulOneClass α] : MulOneClass (ULift α) := @@ -88,50 +88,50 @@ instance mulOneClass [MulOneClass α] : MulOneClass (ULift α) := @[to_additive] instance monoid [Monoid α] : Monoid (ULift α) := - Equiv.ulift.injective.monoid _ rfl (fun _ _ => rfl) fun _ _ => rfl + Equiv.ulift.injective.monoid _ rfl (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl @[to_additive] instance commMonoid [CommMonoid α] : CommMonoid (ULift α) := - Equiv.ulift.injective.commMonoid _ rfl (fun _ _ => rfl) fun _ _ => rfl + Equiv.ulift.injective.commMonoid _ rfl (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl @[to_additive] instance divInvMonoid [DivInvMonoid α] : DivInvMonoid (ULift α) := Equiv.ulift.injective.divInvMonoid _ rfl (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl @[to_additive] instance group [Group α] : Group (ULift α) := Equiv.ulift.injective.group _ rfl (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl @[to_additive] instance commGroup [CommGroup α] : CommGroup (ULift α) := Equiv.ulift.injective.commGroup _ rfl (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl @[to_additive] instance leftCancelSemigroup [LeftCancelSemigroup α] : LeftCancelSemigroup (ULift α) := - Equiv.ulift.injective.leftCancelSemigroup _ fun _ _ => rfl + Equiv.ulift.injective.leftCancelSemigroup _ (fun _ _ => rfl) fun _ _ => rfl @[to_additive] instance rightCancelSemigroup [RightCancelSemigroup α] : RightCancelSemigroup (ULift α) := - Equiv.ulift.injective.rightCancelSemigroup _ fun _ _ => rfl + Equiv.ulift.injective.rightCancelSemigroup _ (fun _ _ => rfl) fun _ _ => rfl @[to_additive] instance leftCancelMonoid [LeftCancelMonoid α] : LeftCancelMonoid (ULift α) := - Equiv.ulift.injective.leftCancelMonoid _ rfl (fun _ _ => rfl) fun _ _ => rfl + Equiv.ulift.injective.leftCancelMonoid _ rfl (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl @[to_additive] instance rightCancelMonoid [RightCancelMonoid α] : RightCancelMonoid (ULift α) := - Equiv.ulift.injective.rightCancelMonoid _ rfl (fun _ _ => rfl) fun _ _ => rfl + Equiv.ulift.injective.rightCancelMonoid _ rfl (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl @[to_additive] instance cancelMonoid [CancelMonoid α] : CancelMonoid (ULift α) := - Equiv.ulift.injective.cancelMonoid _ rfl (fun _ _ => rfl) fun _ _ => rfl + Equiv.ulift.injective.cancelMonoid _ rfl (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl @[to_additive] instance cancelCommMonoid [CancelCommMonoid α] : CancelCommMonoid (ULift α) := - Equiv.ulift.injective.cancelCommMonoid _ rfl (fun _ _ => rfl) fun _ _ => rfl + Equiv.ulift.injective.cancelCommMonoid _ rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) instance nontrivial [Nontrivial α] : Nontrivial (ULift α) := Equiv.ulift.symm.injective.nontrivial From 7a1d2640dd6c00516692147d483958e3a3206fee Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 16:39:55 -0400 Subject: [PATCH 035/127] transfer --- Mathlib/Algebra/Group/TransferInstance.lean | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Group/TransferInstance.lean b/Mathlib/Algebra/Group/TransferInstance.lean index 41a945e1b28f44..893226d363c8c9 100644 --- a/Mathlib/Algebra/Group/TransferInstance.lean +++ b/Mathlib/Algebra/Group/TransferInstance.lean @@ -105,13 +105,15 @@ lemma mulEquiv_symm_apply (e : α ≃ β) [Mul β] (b : β) : @[to_additive /-- Transfer `add_semigroup` across an `Equiv` -/] protected abbrev semigroup [Semigroup β] : Semigroup α := by let mul := e.mul - apply e.injective.semigroup _; intros; exact e.apply_symm_apply _ + let ppow := e.pow ℕ+ + apply e.injective.semigroup _ <;> intros <;> exact e.apply_symm_apply _ /-- Transfer `CommSemigroup` across an `Equiv` -/ @[to_additive /-- Transfer `AddCommSemigroup` across an `Equiv` -/] protected abbrev commSemigroup [CommSemigroup β] : CommSemigroup α := by let mul := e.mul - apply e.injective.commSemigroup _; intros; exact e.apply_symm_apply _ + let ppow := e.pow ℕ+ + apply e.injective.commSemigroup _ <;> intros <;> exact e.apply_symm_apply _ /-- Transfer `IsLeftCancelMul` across an `Equiv` -/ @[to_additive /-- Transfer `IsLeftCancelAdd` across an `Equiv` -/] @@ -146,6 +148,7 @@ protected abbrev mulOneClass [MulOneClass β] : MulOneClass α := by protected abbrev monoid [Monoid β] : Monoid α := by let one := e.one let mul := e.mul + let ppow := e.pow ℕ+ let pow := e.pow ℕ apply e.injective.monoid _ <;> intros <;> exact e.apply_symm_apply _ @@ -154,6 +157,7 @@ protected abbrev monoid [Monoid β] : Monoid α := by protected abbrev commMonoid [CommMonoid β] : CommMonoid α := by let one := e.one let mul := e.mul + let ppow := e.pow ℕ+ let pow := e.pow ℕ apply e.injective.commMonoid _ <;> intros <;> exact e.apply_symm_apply _ @@ -164,6 +168,7 @@ protected abbrev group [Group β] : Group α := by let mul := e.mul let inv := e.Inv let div := e.div + let ppow := e.pow ℕ+ let npow := e.pow ℕ let zpow := e.pow ℤ apply e.injective.group _ <;> intros <;> exact e.apply_symm_apply _ @@ -175,6 +180,7 @@ protected abbrev commGroup [CommGroup β] : CommGroup α := by let mul := e.mul let inv := e.Inv let div := e.div + let ppow := e.pow ℕ+ let npow := e.pow ℕ let zpow := e.pow ℤ apply e.injective.commGroup _ <;> intros <;> exact e.apply_symm_apply _ From e0661824f583470b8fdb3bcb5f294c2c91b6bd68 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 17:11:08 -0400 Subject: [PATCH 036/127] opposite --- Mathlib/Algebra/Group/Opposite.lean | 57 +++++++++++++++-------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/Mathlib/Algebra/Group/Opposite.lean b/Mathlib/Algebra/Group/Opposite.lean index 68a9347be830d8..beda24ce7b2622 100644 --- a/Mathlib/Algebra/Group/Opposite.lean +++ b/Mathlib/Algebra/Group/Opposite.lean @@ -28,40 +28,40 @@ namespace MulOpposite -/ instance instAddSemigroup [AddSemigroup α] : AddSemigroup αᵐᵒᵖ := - unop_injective.addSemigroup _ fun _ _ => rfl + unop_injective.addSemigroup _ (fun _ _ => rfl) fun _ _ => rfl instance instAddLeftCancelSemigroup [AddLeftCancelSemigroup α] : AddLeftCancelSemigroup αᵐᵒᵖ := - unop_injective.addLeftCancelSemigroup _ fun _ _ => rfl + unop_injective.addLeftCancelSemigroup _ (fun _ _ => rfl) fun _ _ => rfl instance instAddRightCancelSemigroup [AddRightCancelSemigroup α] : AddRightCancelSemigroup αᵐᵒᵖ := - unop_injective.addRightCancelSemigroup _ fun _ _ => rfl + unop_injective.addRightCancelSemigroup _ (fun _ _ => rfl) fun _ _ => rfl instance instAddCommMagma [AddCommMagma α] : AddCommMagma αᵐᵒᵖ := unop_injective.addCommMagma _ fun _ _ => rfl instance instAddCommSemigroup [AddCommSemigroup α] : AddCommSemigroup αᵐᵒᵖ := - unop_injective.addCommSemigroup _ fun _ _ => rfl + unop_injective.addCommSemigroup _ (fun _ _ => rfl) fun _ _ => rfl instance instAddZeroClass [AddZeroClass α] : AddZeroClass αᵐᵒᵖ := unop_injective.addZeroClass _ (by exact rfl) fun _ _ => rfl instance instAddMonoid [AddMonoid α] : AddMonoid αᵐᵒᵖ := - unop_injective.addMonoid _ (by exact rfl) (fun _ _ => rfl) fun _ _ => rfl + unop_injective.addMonoid _ (by exact rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl instance instAddCommMonoid [AddCommMonoid α] : AddCommMonoid αᵐᵒᵖ := - unop_injective.addCommMonoid _ rfl (fun _ _ => rfl) fun _ _ => rfl + unop_injective.addCommMonoid _ rfl (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl instance instSubNegMonoid [SubNegMonoid α] : SubNegMonoid αᵐᵒᵖ := unop_injective.subNegMonoid _ (by exact rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl instance instAddGroup [AddGroup α] : AddGroup αᵐᵒᵖ := unop_injective.addGroup _ (by exact rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl instance instAddCommGroup [AddCommGroup α] : AddCommGroup αᵐᵒᵖ := unop_injective.addCommGroup _ rfl (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl /-! ### Multiplicative structures on `αᵐᵒᵖ` @@ -249,20 +249,6 @@ end MulOpposite namespace AddOpposite -instance instSemigroup [Semigroup α] : Semigroup αᵃᵒᵖ := unop_injective.semigroup _ fun _ _ ↦ rfl - -instance instLeftCancelSemigroup [LeftCancelSemigroup α] : LeftCancelSemigroup αᵃᵒᵖ := - unop_injective.leftCancelSemigroup _ fun _ _ => rfl - -instance instRightCancelSemigroup [RightCancelSemigroup α] : RightCancelSemigroup αᵃᵒᵖ := - unop_injective.rightCancelSemigroup _ fun _ _ => rfl - -instance instCommSemigroup [CommSemigroup α] : CommSemigroup αᵃᵒᵖ := - unop_injective.commSemigroup _ fun _ _ => rfl - -instance instMulOneClass [MulOneClass α] : MulOneClass αᵃᵒᵖ := - unop_injective.mulOneClass _ (by exact rfl) fun _ _ => rfl - instance pow {β} [Pow α β] : Pow αᵃᵒᵖ β where pow a b := op (unop a ^ b) @[simp] @@ -273,23 +259,38 @@ theorem op_pow {β} [Pow α β] (a : α) (b : β) : op (a ^ b) = op a ^ b := theorem unop_pow {β} [Pow α β] (a : αᵃᵒᵖ) (b : β) : unop (a ^ b) = unop a ^ b := rfl +instance instSemigroup [Semigroup α] : Semigroup αᵃᵒᵖ := + unop_injective.semigroup _ (fun _ _ => rfl) fun _ _ ↦ rfl + +instance instLeftCancelSemigroup [LeftCancelSemigroup α] : LeftCancelSemigroup αᵃᵒᵖ := + unop_injective.leftCancelSemigroup _ (fun _ _ => rfl) fun _ _ => rfl + +instance instRightCancelSemigroup [RightCancelSemigroup α] : RightCancelSemigroup αᵃᵒᵖ := + unop_injective.rightCancelSemigroup _ (fun _ _ => rfl) fun _ _ => rfl + +instance instCommSemigroup [CommSemigroup α] : CommSemigroup αᵃᵒᵖ := + unop_injective.commSemigroup _ (fun _ _ => rfl) fun _ _ => rfl + +instance instMulOneClass [MulOneClass α] : MulOneClass αᵃᵒᵖ := + unop_injective.mulOneClass _ (by exact rfl) fun _ _ => rfl + instance instMonoid [Monoid α] : Monoid αᵃᵒᵖ := - unop_injective.monoid _ (by exact rfl) (fun _ _ => rfl) fun _ _ => rfl + unop_injective.monoid _ (by exact rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl instance instCommMonoid [CommMonoid α] : CommMonoid αᵃᵒᵖ := - unop_injective.commMonoid _ (by exact rfl) (fun _ _ => rfl) fun _ _ => rfl + unop_injective.commMonoid _ (by exact rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl instance instDivInvMonoid [DivInvMonoid α] : DivInvMonoid αᵃᵒᵖ := unop_injective.divInvMonoid _ (by exact rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl instance instGroup [Group α] : Group αᵃᵒᵖ := unop_injective.group _ (by exact rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl instance instCommGroup [CommGroup α] : CommGroup αᵃᵒᵖ := unop_injective.commGroup _ (by exact rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl @[to_additive] instance instMulTorsionFree [Monoid α] [IsMulTorsionFree α] : IsMulTorsionFree αᵐᵒᵖ := From 18ce684408fb365f7eceb5e27c696b27ee96cd8f Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 17:17:13 -0400 Subject: [PATCH 037/127] linearorderedcommmonoidwithzero --- Mathlib/Algebra/Order/GroupWithZero/Canonical.lean | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean index 94095610485d23..c9b5723ad6d354 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Canonical.lean @@ -74,17 +74,19 @@ instance (priority := 100) : IsCancelMulZero α where /-- Pullback a `LinearOrderedCommMonoidWithZero` under an injective map. See note [reducible non-instances]. -/ abbrev Function.Injective.linearOrderedCommMonoidWithZero {β : Type*} [Zero β] [Bot β] [One β] - [Mul β] [Pow β ℕ] [LE β] [LT β] [Max β] [Min β] [Ord β] + [Mul β] [Pow β ℕ+] [Pow β ℕ] [LE β] [LT β] [Max β] [Min β] [Ord β] [DecidableEq β] [DecidableLE β] [DecidableLT β] (f : β → α) (hf : Function.Injective f) (zero : f 0 = 0) - (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) + (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) + (ppow : ∀ (x) (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (le : ∀ {x y}, f x ≤ f y ↔ x ≤ y) (lt : ∀ {x y}, f x < f y ↔ x < y) (hsup : ∀ x y, f (x ⊔ y) = max (f x) (f y)) (hinf : ∀ x y, f (x ⊓ y) = min (f x) (f y)) (bot : f ⊥ = ⊥) (compare : ∀ x y, compare (f x) (f y) = compare x y) : LinearOrderedCommMonoidWithZero β where __ := hf.linearOrder f le lt hinf hsup compare - __ := hf.commMonoidWithZero f zero one mul npow + __ := hf.commMonoidWithZero f zero one mul ppow npow __ := Function.Injective.posMulStrictMono f zero mul lt isBot_zero _ := le.1 <| zero ▸ zero_le bot_le _ := le.1 <| bot ▸ bot_le From 5d6858e3e5b6442323ea97f6cf738aa60f6e710c Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 17:50:36 -0400 Subject: [PATCH 038/127] Pi --- Mathlib/Algebra/Group/Pi/Basic.lean | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Group/Pi/Basic.lean b/Mathlib/Algebra/Group/Pi/Basic.lean index 644bea1dc47db9..24d55a181827f9 100644 --- a/Mathlib/Algebra/Group/Pi/Basic.lean +++ b/Mathlib/Algebra/Group/Pi/Basic.lean @@ -5,7 +5,7 @@ Authors: Simon Hudon, Patrick Massot, Eric Wieser -/ module -public import Mathlib.Algebra.Group.Defs +public import Mathlib.Algebra.Group.PPow.Defs public import Mathlib.Algebra.Notation.Pi.Basic public import Mathlib.Data.Sum.Basic public import Mathlib.Logic.Unique @@ -55,6 +55,9 @@ instance commMagma [∀ i, CommMagma (f i)] : CommMagma (∀ i, f i) where @[to_additive] instance semigroup [∀ i, Semigroup (f i)] : Semigroup (∀ i, f i) where mul_assoc := by intros; ext; exact mul_assoc _ _ _ + ppow := fun n hn x i => x i ^ PNat.mk n hn + ppow_one := by intros; ext; exact ppow_one _ + ppow_succ := by intros; ext; exact Semigroup.ppow_succ _ _ @[to_additive] instance commSemigroup [∀ i, CommSemigroup (f i)] : CommSemigroup (∀ i, f i) where From 4bac04ff8ac8edc29cc6d507e8dd88ad57fb8ad4 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 17:56:28 -0400 Subject: [PATCH 039/127] dfinsupp --- Mathlib/Algebra/Group/PPow/Defs.lean | 6 +++++- Mathlib/Data/DFinsupp/Defs.lean | 26 ++++++++++++++++++++------ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/Mathlib/Algebra/Group/PPow/Defs.lean b/Mathlib/Algebra/Group/PPow/Defs.lean index 4f3e58b8feb90e..16c1d57449a1aa 100644 --- a/Mathlib/Algebra/Group/PPow/Defs.lean +++ b/Mathlib/Algebra/Group/PPow/Defs.lean @@ -32,7 +32,11 @@ lemma Semigroup.ppow_eq_pow [Semigroup M] (x : M) (n : ℕ+) : Semigroup.ppow n n.property x = x ^ n := rfl -@[to_additive (attr := simp)] +@[simp] +lemma one_psmul [AddSemigroup M] (x : M) : (1 : ℕ+) • x = x := + AddSemigroup.psmul_one _ + +@[to_additive (attr := simp) existing] lemma ppow_one [Semigroup M] (x : M) : x ^ (1 : ℕ+) = x := Semigroup.ppow_one _ diff --git a/Mathlib/Data/DFinsupp/Defs.lean b/Mathlib/Data/DFinsupp/Defs.lean index feccf9203b85e9..31a0e929b20aa3 100644 --- a/Mathlib/Data/DFinsupp/Defs.lean +++ b/Mathlib/Data/DFinsupp/Defs.lean @@ -208,6 +208,18 @@ instance instIsRightCancelAdd [∀ i, AddZeroClass (β i)] [∀ i, IsRightCancel instance instIsCancelAdd [∀ i, AddZeroClass (β i)] [∀ i, IsCancelAdd (β i)] : IsCancelAdd (Π₀ i, β i) where +/-- Note the general `SMul` instance doesn't apply as `ℕ+` is not distributive +unless `β i`'s addition is commutative. -/ +instance hasPNatScalar [∀ i, AddMonoid (β i)] : SMul ℕ+ (Π₀ i, β i) := + ⟨fun c v => v.mapRange (fun _ => (c • ·)) fun _ => by rw [← nsmul_val_eq_psmul, nsmul_zero]⟩ + +theorem psmul_apply [∀ i, AddMonoid (β i)] (b : ℕ+) (v : Π₀ i, β i) (i : ι) : (b • v) i = b • v i := + rfl + +@[simp, norm_cast] +theorem coe_psmul [∀ i, AddMonoid (β i)] (b : ℕ+) (v : Π₀ i, β i) : ⇑(b • v) = b • ⇑v := + rfl + /-- Note the general `SMul` instance doesn't apply as `ℕ` is not distributive unless `β i`'s addition is commutative. -/ instance hasNatScalar [∀ i, AddMonoid (β i)] : SMul ℕ (Π₀ i, β i) := @@ -221,7 +233,8 @@ theorem coe_nsmul [∀ i, AddMonoid (β i)] (b : ℕ) (v : Π₀ i, β i) : ⇑( rfl instance [∀ i, AddMonoid (β i)] : AddMonoid (Π₀ i, β i) := - DFunLike.coe_injective.addMonoid _ coe_zero coe_add fun _ _ => coe_nsmul _ _ + DFunLike.coe_injective.addMonoid _ coe_zero coe_add (fun _ _ => coe_psmul _ _) + fun _ _ => coe_nsmul _ _ /-- Coercion from a `DFinsupp` to a pi type is an `AddMonoidHom`. -/ def coeFnAddMonoidHom [∀ i, AddZeroClass (β i)] : (Π₀ i, β i) →+ ∀ i, β i where @@ -234,7 +247,8 @@ lemma coeFnAddMonoidHom_apply [∀ i, AddZeroClass (β i)] (v : Π₀ i, β i) : rfl instance addCommMonoid [∀ i, AddCommMonoid (β i)] : AddCommMonoid (Π₀ i, β i) := - fast_instance% DFunLike.coe_injective.addCommMonoid _ coe_zero coe_add fun _ _ => coe_nsmul _ _ + fast_instance% DFunLike.coe_injective.addCommMonoid _ coe_zero coe_add (fun _ _ => coe_psmul _ _) + fun _ _ => coe_nsmul _ _ instance [∀ i, AddGroup (β i)] : Neg (Π₀ i, β i) := ⟨fun f => f.mapRange (fun _ => Neg.neg) fun _ => neg_zero⟩ @@ -267,12 +281,12 @@ theorem coe_zsmul [∀ i, AddGroup (β i)] (b : ℤ) (v : Π₀ i, β i) : ⇑(b rfl instance [∀ i, AddGroup (β i)] : AddGroup (Π₀ i, β i) := - fast_instance% DFunLike.coe_injective.addGroup _ coe_zero coe_add coe_neg coe_sub - (fun _ _ => coe_nsmul _ _) fun _ _ => coe_zsmul _ _ + fast_instance% DFunLike.coe_injective.addGroup _ coe_zero coe_add coe_neg + (fun _ _ => coe_psmul _ _) coe_sub (fun _ _ => coe_nsmul _ _) fun _ _ => coe_zsmul _ _ instance addCommGroup [∀ i, AddCommGroup (β i)] : AddCommGroup (Π₀ i, β i) := - fast_instance% DFunLike.coe_injective.addCommGroup _ coe_zero coe_add coe_neg coe_sub - (fun _ _ => coe_nsmul _ _) fun _ _ => coe_zsmul _ _ + fast_instance% DFunLike.coe_injective.addCommGroup _ coe_zero coe_add coe_neg + (fun _ _ => coe_psmul _ _) coe_sub (fun _ _ => coe_nsmul _ _) fun _ _ => coe_zsmul _ _ end Algebra From 0fadffc485277cfd1cd1304d21d96fd6d06b732b Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 21:28:21 -0400 Subject: [PATCH 040/127] Hom instances --- Mathlib/Algebra/Group/Hom/Instances.lean | 22 ++++++++++++++++++++- Mathlib/Algebra/Group/PPow/Basic.lean | 23 +++++++--------------- Mathlib/Algebra/Group/PPow/Defs.lean | 25 +++++++++++++++++++++++- 3 files changed, 52 insertions(+), 18 deletions(-) diff --git a/Mathlib/Algebra/Group/Hom/Instances.lean b/Mathlib/Algebra/Group/Hom/Instances.lean index 6675d8ec20a9e4..0941d7a7d0f062 100644 --- a/Mathlib/Algebra/Group/Hom/Instances.lean +++ b/Mathlib/Algebra/Group/Hom/Instances.lean @@ -9,6 +9,7 @@ module public import Mathlib.Algebra.Group.Hom.Basic public import Mathlib.Algebra.Group.InjSurj public import Mathlib.Algebra.Group.Pi.Basic +public import Mathlib.Algebra.Group.PPow.Defs public import Mathlib.Tactic.FastInstance /-! @@ -33,11 +34,24 @@ universe uM uN uP uQ variable {M : Type uM} {N : Type uN} {P : Type uP} {Q : Type uQ} @[to_additive] -instance OneHom.instPow [One M] [Monoid N] : Pow (OneHom M N) ℕ where +instance OneHom.instPPow [One M] [Monoid N] : Pow (OneHom M N) ℕ+ where pow f n := { toFun := f ^ n map_one' := by simp } +@[to_additive] +instance OneHom.instPow [One M] [Monoid N] : Pow (OneHom M N) ℕ where + pow f n := + { toFun := f ^ n + map_one' := by simp} + +@[to_additive] +instance MonoidHom.instPPow [MulOneClass M] [CommMonoid N] : Pow (M →* N) ℕ+ where + pow f n := + { toFun := f ^ n + map_one' := by simp + map_mul' x y := by simp [mul_ppow] } + @[to_additive] instance MonoidHom.instPow [MulOneClass M] [CommMonoid N] : Pow (M →* N) ℕ where pow f n := @@ -60,18 +74,21 @@ lemma MonoidHom.pow_apply [MulOneClass M] [CommMonoid N] (f : M →* N) (n : ℕ instance OneHom.instMonoid [One M] [Monoid N] : Monoid (OneHom M N) := fast_instance% DFunLike.coe_injective.monoid DFunLike.coe rfl (fun _ _ => rfl) (fun _ _ => rfl) + fun _ _ => rfl /-- `OneHom M N` is a `CommMonoid` if `N` is commutative. -/ @[to_additive /-- `ZeroHom M N` is an `AddCommMonoid` if `N` is commutative. -/] instance OneHom.instCommMonoid [One M] [CommMonoid N] : CommMonoid (OneHom M N) := fast_instance% DFunLike.coe_injective.commMonoid DFunLike.coe rfl (fun _ _ => rfl) (fun _ _ => rfl) + fun _ _ => rfl /-- `(M →* N)` is a `CommMonoid` if `N` is commutative. -/ @[to_additive /-- `(M →+ N)` is an `AddCommMonoid` if `N` is commutative. -/] instance MonoidHom.instCommMonoid [MulOneClass M] [CommMonoid N] : CommMonoid (M →* N) := fast_instance% DFunLike.coe_injective.commMonoid DFunLike.coe rfl (fun _ _ => rfl) (fun _ _ => rfl) + fun _ _ => rfl @[to_additive] instance OneHom.instZPow [One M] [Group N] : Pow (OneHom M N) ℤ where @@ -102,6 +119,7 @@ instance OneHom.instGroup [One M] [Group N] : Group (OneHom M N) := fast_instance% DFunLike.coe_injective.group DFunLike.coe rfl (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) /-- If `G` is a commutative group, then so is `OneHom M G`. -/ @[to_additive /-- If `G` is an additive commutative group, then so is `ZeroHom M G`. -/] @@ -109,6 +127,7 @@ instance OneHom.instCommGroup [One M] [CommGroup N] : CommGroup (OneHom M N) := fast_instance% DFunLike.coe_injective.commGroup DFunLike.coe rfl (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) /-- If `G` is a commutative group, then `M →* G` is a commutative group too. -/ @[to_additive /-- If `G` is an additive commutative group, then `M →+ G` is an additive commutative @@ -117,6 +136,7 @@ instance MonoidHom.instCommGroup [MulOneClass M] [CommGroup N] : CommGroup (M fast_instance% DFunLike.coe_injective.commGroup DFunLike.coe rfl (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) @[to_additive] instance [One M] [MulOneClass N] [IsLeftCancelMul N] : IsLeftCancelMul (OneHom M N) := diff --git a/Mathlib/Algebra/Group/PPow/Basic.lean b/Mathlib/Algebra/Group/PPow/Basic.lean index cdb3da9edc069c..c658c264496aad 100644 --- a/Mathlib/Algebra/Group/PPow/Basic.lean +++ b/Mathlib/Algebra/Group/PPow/Basic.lean @@ -20,9 +20,6 @@ section Semigroup variable [Semigroup M] -@[to_additive (attr := simp) one_psmul] -lemma ppow_one (x : M) : x ^ (1 : ℕ+) = x := Semigroup.ppow_one x - @[to_additive succ_psmul'] lemma ppow_succ' (x : M) (n : ℕ+) : x ^ (n + 1) = x * x ^ n := n.recOn (Semigroup.ppow_succ x 0) fun k _ => Semigroup.ppow_succ x k @@ -70,19 +67,19 @@ section CommSemigroup variable [CommSemigroup M] -@[to_additive psmul_add] -lemma mul_ppow (x y : M) (n : ℕ+) : (x * y) ^ n = x ^ n * y ^ n := - (Commute.all x y).mul_ppow n - -variable (M) - /-- `(· ^ (n : ℕ+))` as a `MulHom`. -/ -@[to_additive (attr := simps) +@[to_additive /-- `((n : ℕ+) • ·)` as an `AddHom`. -/] def ppowMulHom (n : ℕ+) : M →ₙ* M where toFun x := x ^ n map_mul' := mul_ppow (n := n) +-- unclear why `simps` doesn't work, nor `rfl` +@[to_additive (attr := simp)] +lemma ppowMulHom_apply (n : ℕ+) (x : M) : ppowMulHom n x = x ^ n := by + rw [ppowMulHom] + rfl + end CommSemigroup @[to_additive] @@ -90,12 +87,6 @@ theorem pow_mul_comm'' [Monoid M] (a : M) (n : ℕ+) : a ^ n * a = a * a ^ n := exact ppow_mul_comm' a n -- not marked as `simp` because in a monoid we probably prefer powers with type `ℕ` -@[to_additive (attr := norm_cast)] -lemma npow_val_eq_ppow [Monoid M] (x : M) (n : ℕ+) : x ^ (n : ℕ) = x ^ n := - n.recOn (by simp [pow_one]) fun k hk => by - simp only [PNat.add_coe, PNat.val_ofNat, pow_succ, hk, ppow_succ'] - rw [pow_mul_comm''] - @[to_additive] lemma map_ppow {F M N : Type _} [Semigroup M] [Semigroup N] [FunLike F M N] [MulHomClass F M N] (f : F) (x : M) (n : ℕ+) : f (x ^ n) = f x ^ n := diff --git a/Mathlib/Algebra/Group/PPow/Defs.lean b/Mathlib/Algebra/Group/PPow/Defs.lean index 16c1d57449a1aa..ab8f0b28da8286 100644 --- a/Mathlib/Algebra/Group/PPow/Defs.lean +++ b/Mathlib/Algebra/Group/PPow/Defs.lean @@ -47,7 +47,8 @@ lemma ppow_mk_add_one [Semigroup M] (x : M) {n : ℕ} (hn : n ≠ 0) : · contradiction · simp [← Semigroup.ppow_eq_pow, PNat.mk, Semigroup.ppow_succ] -@[to_additive (attr := simp)] +-- not marked as `simp` because in a monoid we probably prefer powers with type `ℕ` +@[to_additive (attr := norm_cast)] theorem npow_val_eq_ppow [Monoid M] (n : ℕ+) (x : M) : x ^ n.val = x ^ n := by rcases n with ⟨_|n, hn⟩ · contradiction @@ -55,3 +56,25 @@ theorem npow_val_eq_ppow [Monoid M] (n : ℕ+) (x : M) : x ^ n.val = x ^ n := by induction n · simp [Semigroup.ppow_one] · simp_all [Semigroup.ppow_succ, pow_succ'] + +-- This lemma is higher priority than later `smul_zero` so that the `simpNF` is happy +@[to_additive (attr := simp high) psmul_zero] lemma one_ppow [Monoid M] (n : ℕ+) : + (1 : M) ^ n = 1 := by + rw [← npow_val_eq_ppow, one_pow] + +section CommSemigroup + +variable [CommSemigroup M] + +@[to_additive psmul_add] +lemma mul_ppow (x y : M) (n : ℕ+) : (x * y) ^ n = x ^ n * y ^ n := by + rcases n with ⟨_|n, hn⟩ + · contradiction + simp only [mk_coe, ← Semigroup.ppow_eq_pow] + induction n with + | zero => simp [Semigroup.ppow_one] + | succ n IH => + rw [Semigroup.ppow_succ, IH (Nat.succ_pos _), Semigroup.ppow_succ, Semigroup.ppow_succ, + mul_assoc, mul_comm y, ← mul_assoc, ← mul_assoc, mul_comm y, ← mul_assoc] + +end CommSemigroup From c40d8a23bc2398a32ac5cbc45c9734e3d31ce771 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 21:31:32 -0400 Subject: [PATCH 041/127] long file FIXME --- Mathlib/Algebra/Order/GroupWithZero/Basic.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/Algebra/Order/GroupWithZero/Basic.lean b/Mathlib/Algebra/Order/GroupWithZero/Basic.lean index a7bbbff77876c3..f53ce2d86a2ebb 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Basic.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Basic.lean @@ -25,6 +25,7 @@ lemmas that do not immediately follow from the typeclass specifications. -/ public section +set_option linter.style.longFile 1600 -- FIXME open Function From f47f8f6f5c797577627fb65a288ed8bec208fdb9 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 21:33:30 -0400 Subject: [PATCH 042/127] ulift with zero --- Mathlib/Algebra/GroupWithZero/ULift.lean | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/GroupWithZero/ULift.lean b/Mathlib/Algebra/GroupWithZero/ULift.lean index 24f8764b05ce8d..522f04d4ef584d 100644 --- a/Mathlib/Algebra/GroupWithZero/ULift.lean +++ b/Mathlib/Algebra/GroupWithZero/ULift.lean @@ -30,17 +30,18 @@ instance mulZeroOneClass [MulZeroOneClass α] : MulZeroOneClass (ULift α) := Equiv.ulift.injective.mulZeroOneClass _ rfl rfl (by intros; rfl) instance monoidWithZero [MonoidWithZero α] : MonoidWithZero (ULift α) := - Equiv.ulift.injective.monoidWithZero _ rfl rfl (fun _ _ => rfl) fun _ _ => rfl + Equiv.ulift.injective.monoidWithZero _ rfl rfl (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl instance commMonoidWithZero [CommMonoidWithZero α] : CommMonoidWithZero (ULift α) := - Equiv.ulift.injective.commMonoidWithZero _ rfl rfl (fun _ _ => rfl) fun _ _ => rfl + Equiv.ulift.injective.commMonoidWithZero _ rfl rfl (fun _ _ => rfl) (fun _ _ => rfl) + fun _ _ => rfl instance groupWithZero [GroupWithZero α] : GroupWithZero (ULift α) := Equiv.ulift.injective.groupWithZero _ rfl rfl (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl instance commGroupWithZero [CommGroupWithZero α] : CommGroupWithZero (ULift α) := Equiv.ulift.injective.commGroupWithZero _ rfl rfl (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl end ULift From dd63c5c47170fa2435871301a79324ba4ae27a74 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 21:33:51 -0400 Subject: [PATCH 043/127] remove assert_not_exists --- Mathlib/Algebra/Ring/Rat.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Ring/Rat.lean b/Mathlib/Algebra/Ring/Rat.lean index 3e59a33a910445..ea865f9f5c188f 100644 --- a/Mathlib/Algebra/Ring/Rat.lean +++ b/Mathlib/Algebra/Ring/Rat.lean @@ -21,7 +21,7 @@ See note [foundational algebra order theory]. public section -assert_not_exists IsOrderedMonoid Field PNat Nat.gcd_greatest +assert_not_exists IsOrderedMonoid Field Nat.gcd_greatest namespace Rat From 46ec8569c1ec310fba7f65f100fdb780aaa21f20 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 21:42:53 -0400 Subject: [PATCH 044/127] Rat psmul and ppow --- Mathlib/Data/Rat/Defs.lean | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Mathlib/Data/Rat/Defs.lean b/Mathlib/Data/Rat/Defs.lean index 1b3f964e3a1f79..56241e80bb7d29 100644 --- a/Mathlib/Data/Rat/Defs.lean +++ b/Mathlib/Data/Rat/Defs.lean @@ -152,8 +152,15 @@ instance addCommGroup : AddCommGroup ℚ where add_assoc := Rat.add_assoc neg_add_cancel := Rat.neg_add_cancel sub_eq_add_neg := Rat.sub_eq_add_neg + psmul n hn q := n * q nsmul := (· * ·) zsmul := (· * ·) + psmul_one := Rat.one_mul + psmul_succ q n := by + change ((n + 2 : Int) : Rat) * q = q + ((n + 1 : Int) : Rat) * q + rw [Rat.intCast_add, Rat.add_mul, Rat.intCast_add, Rat.add_mul, Rat.add_comm q, Rat.add_assoc, + show (2 : Int) = 1 + 1 by rfl, Rat.intCast_add, Rat.add_mul] + simp nsmul_zero := Rat.zero_mul nsmul_succ n q := by change ((n + 1 : Int) : Rat) * q = _ @@ -182,6 +189,9 @@ instance commMonoid : CommMonoid ℚ where one_mul := Rat.one_mul mul_comm := Rat.mul_comm mul_assoc := Rat.mul_assoc + ppow n hn q := q ^ n + ppow_one := Rat.pow_one + ppow_succ q n := by rw [Rat.pow_succ, Rat.mul_comm] npow n q := q ^ n npow_zero := Rat.pow_zero npow_succ n q := Rat.pow_succ q n From 5c5258356b49e9bacf6babd3ce7e6c37d31e6832 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 21:44:37 -0400 Subject: [PATCH 045/127] Submonoid --- Mathlib/Algebra/Group/Submonoid/Defs.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Group/Submonoid/Defs.lean b/Mathlib/Algebra/Group/Submonoid/Defs.lean index 5773ce82160051..17e33f329c17e1 100644 --- a/Mathlib/Algebra/Group/Submonoid/Defs.lean +++ b/Mathlib/Algebra/Group/Submonoid/Defs.lean @@ -397,14 +397,14 @@ instance (S : A) [IsDedekindFiniteMonoid M] : IsDedekindFiniteMonoid S where @[to_additive /-- An `AddSubmonoid` of an `AddMonoid` inherits an `AddMonoid` structure. -/] instance (priority := 75) toMonoid {M : Type*} [Monoid M] {A : Type*} [SetLike A M] [SubmonoidClass A M] (S : A) : Monoid S := fast_instance% - Subtype.coe_injective.monoid Subtype.val rfl (fun _ _ => rfl) (fun _ _ => rfl) + Subtype.coe_injective.monoid Subtype.val rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) -- Prefer subclasses of `Monoid` over subclasses of `SubmonoidClass`. /-- A submonoid of a `CommMonoid` is a `CommMonoid`. -/ @[to_additive /-- An `AddSubmonoid` of an `AddCommMonoid` is an `AddCommMonoid`. -/] instance (priority := 75) toCommMonoid {M} [CommMonoid M] {A : Type*} [SetLike A M] [SubmonoidClass A M] (S : A) : CommMonoid S := fast_instance% - Subtype.coe_injective.commMonoid Subtype.val rfl (fun _ _ => rfl) fun _ _ => rfl + Subtype.coe_injective.commMonoid Subtype.val rfl (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl /-- The natural monoid hom from a submonoid of monoid `M` to `M`. -/ @[to_additive /-- The natural monoid hom from an `AddSubmonoid` of `AddMonoid` `M` to `M`. -/] From e8fea58254a10e2369efff505822f626828eb208 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 21:48:49 -0400 Subject: [PATCH 046/127] fix order --- Mathlib/Algebra/Group/InjSurj.lean | 14 +++++++------- Mathlib/Algebra/Ring/InjSurj.lean | 14 +++++++------- Mathlib/Data/DFinsupp/Defs.lean | 8 ++++---- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Mathlib/Algebra/Group/InjSurj.lean b/Mathlib/Algebra/Group/InjSurj.lean index ecb8f8eebc0771..c2a48f948a2745 100644 --- a/Mathlib/Algebra/Group/InjSurj.lean +++ b/Mathlib/Algebra/Group/InjSurj.lean @@ -303,9 +303,9 @@ protected abbrev divisionCommMonoid [DivisionCommMonoid M₂] (f : M₁ → M₂ injective map that preserves `0` and `+` to an additive group. -/] protected abbrev group [Group M₂] (f : M₁ → M₂) (hf : Injective f) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) - (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (div : ∀ x y, f (x / y) = f x / f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) - (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : Group M₁ := + (div : ∀ x y, f (x / y) = f x / f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : + Group M₁ := { hf.divInvMonoid f one mul inv ppow div npow zpow with inv_mul_cancel := fun x => hf <| by rw [mul, inv, inv_mul_cancel, one] } @@ -317,10 +317,10 @@ preserves `1`, `*` and `⁻¹` to a commutative group. See note [reducible non-i admits an injective map that preserves `0` and `+` to an additive commutative group. -/] protected abbrev commGroup [CommGroup M₂] (f : M₁ → M₂) (hf : Injective f) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) - (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (div : ∀ x y, f (x / y) = f x / f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) - (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : CommGroup M₁ := - { hf.group f one mul inv ppow div npow zpow, hf.commMonoid f one mul ppow npow with } + (div : ∀ x y, f (x / y) = f x / f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : + CommGroup M₁ := + { hf.group f one mul inv div ppow npow zpow, hf.commMonoid f one mul ppow npow with } end Injective diff --git a/Mathlib/Algebra/Ring/InjSurj.lean b/Mathlib/Algebra/Ring/InjSurj.lean index 0de8728ae352a9..f4fbc77ffb2dbb 100644 --- a/Mathlib/Algebra/Ring/InjSurj.lean +++ b/Mathlib/Algebra/Ring/InjSurj.lean @@ -99,7 +99,7 @@ protected abbrev addGroupWithOne {S} [Zero S] [One S] [Add S] [SMul ℕ+ S] [SMu (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : AddGroupWithOne S := - { hf.addGroup f zero add neg psmul sub (swap nsmul) (swap zsmul), + { hf.addGroup f zero add neg sub psmul (swap nsmul) (swap zsmul), hf.addMonoidWithOne f zero one add psmul nsmul natCast with intCast := Int.cast, intCast_ofNat := fun n => hf (by rw [natCast, intCast, Int.cast_natCast]), @@ -171,7 +171,7 @@ protected abbrev nonUnitalNonAssocRing [NonUnitalNonAssocRing R] (f : S → R) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : NonUnitalNonAssocRing S where - toAddCommGroup := hf.addCommGroup f zero add neg psmul sub (swap nsmul) (swap zsmul) + toAddCommGroup := hf.addCommGroup f zero add neg sub psmul (swap nsmul) (swap zsmul) __ := hf.nonUnitalNonAssocSemiring f zero add mul psmul nsmul /-- Pullback a `NonUnitalRing` instance along an injective function. -/ @@ -203,8 +203,8 @@ protected abbrev nonAssocRing [NonAssocRing R] -- See note [reducible non-instances] protected abbrev ring [Ring R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (neg : ∀ x, f (-x) = -f x) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) + (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : Ring S where @@ -212,7 +212,7 @@ protected abbrev ring [Ring R] (zero : f 0 = 0) -- zsmul included here explicitly to make sure it's picked correctly by `fast_instance%`. zsmul := fun n x ↦ n • x __ := hf.addGroupWithOne f zero one add neg psmul sub nsmul zsmul natCast intCast - __ := hf.addCommGroup f zero add neg psmul sub (swap nsmul) (swap zsmul) + __ := hf.addCommGroup f zero add neg sub psmul (swap nsmul) (swap zsmul) /-- Pullback a `NonUnitalNonAssocCommSemiring` instance along an injective function. -/ -- See note [reducible non-instances] @@ -297,12 +297,12 @@ protected abbrev nonAssocCommRing [NonAssocCommRing R] (f : S → R) protected abbrev commRing [CommRing R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) + (sub : ∀ x y, f (x - y) = f x - f y) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : CommRing S where - toRing := hf.ring f zero one add mul neg psmul sub nsmul zsmul ppow npow natCast intCast + toRing := hf.ring f zero one add mul neg sub psmul nsmul zsmul ppow npow natCast intCast __ := hf.commMonoid f one mul ppow npow end Function.Injective diff --git a/Mathlib/Data/DFinsupp/Defs.lean b/Mathlib/Data/DFinsupp/Defs.lean index 31a0e929b20aa3..240fc1caa29e44 100644 --- a/Mathlib/Data/DFinsupp/Defs.lean +++ b/Mathlib/Data/DFinsupp/Defs.lean @@ -281,12 +281,12 @@ theorem coe_zsmul [∀ i, AddGroup (β i)] (b : ℤ) (v : Π₀ i, β i) : ⇑(b rfl instance [∀ i, AddGroup (β i)] : AddGroup (Π₀ i, β i) := - fast_instance% DFunLike.coe_injective.addGroup _ coe_zero coe_add coe_neg - (fun _ _ => coe_psmul _ _) coe_sub (fun _ _ => coe_nsmul _ _) fun _ _ => coe_zsmul _ _ + fast_instance% DFunLike.coe_injective.addGroup _ coe_zero coe_add coe_neg coe_sub + (fun _ _ => coe_psmul _ _) (fun _ _ => coe_nsmul _ _) fun _ _ => coe_zsmul _ _ instance addCommGroup [∀ i, AddCommGroup (β i)] : AddCommGroup (Π₀ i, β i) := - fast_instance% DFunLike.coe_injective.addCommGroup _ coe_zero coe_add coe_neg - (fun _ _ => coe_psmul _ _) coe_sub (fun _ _ => coe_nsmul _ _) fun _ _ => coe_zsmul _ _ + fast_instance% DFunLike.coe_injective.addCommGroup _ coe_zero coe_add coe_neg coe_sub + (fun _ _ => coe_psmul _ _) (fun _ _ => coe_nsmul _ _) fun _ _ => coe_zsmul _ _ end Algebra From 899d3d156de8e8488ef3c4a84a1873a986dcdc1f Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 22:06:47 -0400 Subject: [PATCH 047/127] group Con --- Mathlib/GroupTheory/Congruence/Defs.lean | 27 ++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/Mathlib/GroupTheory/Congruence/Defs.lean b/Mathlib/GroupTheory/Congruence/Defs.lean index b47a3672e90a92..a5efab5a751438 100644 --- a/Mathlib/GroupTheory/Congruence/Defs.lean +++ b/Mathlib/GroupTheory/Congruence/Defs.lean @@ -6,6 +6,7 @@ Authors: Amelia Livingston module public import Mathlib.Algebra.Group.InjSurj +public import Mathlib.Algebra.Group.PPow.Basic public import Mathlib.Algebra.Group.Units.Defs public import Mathlib.Data.Setoid.Basic public import Mathlib.Tactic.FastInstance @@ -564,6 +565,18 @@ end MulOneClass section Monoids +/-- Multiplicative congruence relations preserve positive natural powers. -/ +@[to_additive /-- Additive congruence relations preserve positive natural scaling. -/] +protected theorem ppow {M : Type*} [Semigroup M] (c : Con M) (n : ℕ+) {w x} (h : c w x) : + c (w ^ n) (x ^ n) := by + induction n + · simpa + · simpa [ppow_succ] using c.mul ‹_› h + +@[to_additive] +instance {M : Type*} [Semigroup M] (c : Con M) : Pow c.Quotient ℕ+ where + pow x n := Quotient.map' (fun x => x ^ n) (fun _ _ => c.ppow n) x + /-- Multiplicative congruence relations preserve natural powers. -/ @[to_additive /-- Additive congruence relations preserve natural scaling. -/] protected theorem pow {M : Type*} [Monoid M] (c : Con M) : @@ -579,7 +592,7 @@ instance {M : Type*} [Monoid M] (c : Con M) : Pow c.Quotient ℕ where @[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 := fast_instance% - Function.Surjective.semigroup _ Quotient.mk''_surjective fun _ _ => rfl + Function.Surjective.semigroup _ Quotient.mk''_surjective (fun _ _ => rfl) fun _ _ => rfl /-- The quotient of a commutative magma by a congruence relation is a commutative magma. -/ @[to_additive /-- The quotient of an `AddCommMagma` by an additive congruence relation is @@ -591,20 +604,21 @@ instance commMagma {M : Type*} [CommMagma M] (c : Con M) : CommMagma c.Quotient @[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.mk''_surjective fun _ _ => rfl + Function.Surjective.commSemigroup _ Quotient.mk''_surjective (fun _ _ => rfl) fun _ _ => rfl /-- 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 := fast_instance% - Function.Surjective.monoid _ Quotient.mk''_surjective rfl (fun _ _ => rfl) fun _ _ => rfl + Function.Surjective.monoid _ Quotient.mk''_surjective rfl (fun _ _ => rfl) (fun _ _ => rfl) + fun _ _ => rfl /-- 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 := fast_instance% fast_instance% Function.Surjective.commMonoid _ Quotient.mk''_surjective rfl - (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl /-- 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`. @@ -676,14 +690,15 @@ instance instZPow : Pow c.Quotient ℤ := an `AddGroup`. -/] instance group : Group c.Quotient := fast_instance% Function.Surjective.group Quotient.mk'' Quotient.mk''_surjective - rfl (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl + rfl (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + fun _ _ => rfl /-- The quotient of a `CommGroup` by a congruence relation is a `CommGroup`. -/ @[to_additive /-- The quotient of an `AddCommGroup` by an additive congruence relation is an `AddCommGroup`. -/] instance commGroup {M : Type*} [CommGroup M] (c : Con M) : CommGroup c.Quotient := fast_instance% Function.Surjective.commGroup _ Quotient.mk''_surjective rfl (fun _ _ => rfl) (fun _ => rfl) - (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl end Groups From 679294d44103a89417041ad8695b15a0b2a6a702 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Mon, 22 Jun 2026 22:06:57 -0400 Subject: [PATCH 048/127] Field --- Mathlib/Algebra/Field/Basic.lean | 42 ++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/Mathlib/Algebra/Field/Basic.lean b/Mathlib/Algebra/Field/Basic.lean index f903c5e449f4b3..bca5483fdaf845 100644 --- a/Mathlib/Algebra/Field/Basic.lean +++ b/Mathlib/Algebra/Field/Basic.lean @@ -224,20 +224,21 @@ noncomputable abbrev Field.ofIsUnitOrEqZero [CommRing R] (h : ∀ a : R, IsUnit end NoncomputableDefs namespace Function.Injective -variable [Zero K] [Add K] [Neg K] [Sub K] [One K] [Mul K] [Inv K] [Div K] [SMul ℕ K] [SMul ℤ K] - [SMul ℚ≥0 K] [SMul ℚ K] [Pow K ℕ] [Pow K ℤ] [NatCast K] [IntCast K] [NNRatCast K] [RatCast K] - (f : K → L) (hf : Injective f) +variable [Zero K] [Add K] [Neg K] [Sub K] [One K] [Mul K] [Inv K] [Div K] [SMul ℕ+ K] [SMul ℕ K] + [SMul ℤ K] [SMul ℚ≥0 K] [SMul ℚ K] [Pow K ℕ+] [Pow K ℕ] [Pow K ℤ] [NatCast K] [IntCast K] + [NNRatCast K] [RatCast K] (f : K → L) (hf : Injective f) /-- Pullback a `DivisionSemiring` along an injective function. -/ -- See note [reducible non-instances] protected abbrev divisionSemiring [DivisionSemiring L] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) (div : ∀ x y, f (x / y) = f x / f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (nnqsmul : ∀ (q : ℚ≥0) (x), f (q • x) = q • f x) + (psmul : ∀ x (n : ℕ+), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (nnqsmul : ∀ (q : ℚ≥0) (x), f (q • x) = q • f x) (ppow : ∀ (x) (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) (nnratCast : ∀ q : ℚ≥0, f q = q) : DivisionSemiring K where - toSemiring := hf.semiring f zero one add mul nsmul npow natCast - __ := hf.groupWithZero f zero one mul inv div npow zpow + toSemiring := hf.semiring f zero one add mul psmul nsmul ppow npow natCast + __ := hf.groupWithZero f zero one mul inv div ppow npow zpow nnratCast_def q := hf <| by rw [nnratCast, NNRat.cast_def, div, natCast, natCast] nnqsmul := (· • ·) nnqsmul_def q a := hf <| by rw [nnqsmul, NNRat.smul_def, mul, nnratCast] @@ -247,15 +248,17 @@ protected abbrev divisionSemiring [DivisionSemiring L] (zero : f 0 = 0) (one : f protected abbrev divisionRing [DivisionRing L] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) - (div : ∀ x y, f (x / y) = f x / f y) + (div : ∀ x y, f (x / y) = f x / f y) (psmul : ∀ x (n : ℕ+), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (nnqsmul : ∀ (q : ℚ≥0) (x), f (q • x) = q • f x) (qsmul : ∀ (q : ℚ) (x), f (q • x) = q • f x) + (ppow : ∀ (x) (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) (nnratCast : ∀ q : ℚ≥0, f q = q) (ratCast : ∀ q : ℚ, f q = q) : DivisionRing K where - toRing := hf.ring f zero one add mul neg sub nsmul zsmul npow natCast intCast - __ := hf.groupWithZero f zero one mul inv div npow zpow - __ := hf.divisionSemiring f zero one add mul inv div nsmul nnqsmul npow zpow natCast nnratCast + toRing := hf.ring f zero one add mul neg sub psmul nsmul zsmul ppow npow natCast intCast + __ := hf.groupWithZero f zero one mul inv div ppow npow zpow + __ := hf.divisionSemiring f zero one add mul inv div psmul nsmul nnqsmul ppow npow zpow natCast + nnratCast ratCast_def q := hf <| by rw [ratCast, div, intCast, natCast, Rat.cast_def] qsmul := (· • ·) qsmul_def q a := hf <| by rw [qsmul, mul, Rat.smul_def, ratCast] @@ -265,28 +268,31 @@ protected abbrev divisionRing [DivisionRing L] (zero : f 0 = 0) (one : f 1 = 1) protected abbrev semifield [Semifield L] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) (div : ∀ x y, f (x / y) = f x / f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (nnqsmul : ∀ (q : ℚ≥0) (x), f (q • x) = q • f x) + (psmul : ∀ x (n : ℕ+), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (nnqsmul : ∀ (q : ℚ≥0) (x), f (q • x) = q • f x) (ppow : ∀ (x) (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) (nnratCast : ∀ q : ℚ≥0, f q = q) : Semifield K where - toCommSemiring := hf.commSemiring f zero one add mul nsmul npow natCast - __ := hf.commGroupWithZero f zero one mul inv div npow zpow - __ := hf.divisionSemiring f zero one add mul inv div nsmul nnqsmul npow zpow natCast nnratCast + toCommSemiring := hf.commSemiring f zero one add mul psmul nsmul ppow npow natCast + __ := hf.commGroupWithZero f zero one mul inv div ppow npow zpow + __ := hf.divisionSemiring f zero one add mul inv div psmul nsmul nnqsmul ppow npow zpow natCast + nnratCast /-- Pullback a `Field` along an injective function. -/ -- See note [reducible non-instances] protected abbrev field [Field L] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) - (div : ∀ x y, f (x / y) = f x / f y) + (div : ∀ x y, f (x / y) = f x / f y) (psmul : ∀ x (n : ℕ+), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (nnqsmul : ∀ (q : ℚ≥0) (x), f (q • x) = q • f x) (qsmul : ∀ (q : ℚ) (x), f (q • x) = q • f x) + (ppow : ∀ (x) (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) (nnratCast : ∀ q : ℚ≥0, f q = q) (ratCast : ∀ q : ℚ, f q = q) : Field K where - toCommRing := hf.commRing f zero one add mul neg sub nsmul zsmul npow natCast intCast - __ := hf.divisionRing f zero one add mul neg sub inv div nsmul zsmul nnqsmul qsmul npow zpow - natCast intCast nnratCast ratCast + toCommRing := hf.commRing f zero one add mul neg sub psmul nsmul zsmul ppow npow natCast intCast + __ := hf.divisionRing f zero one add mul neg sub inv div psmul nsmul zsmul nnqsmul qsmul ppow npow + zpow natCast intCast nnratCast ratCast end Function.Injective From 07a464b98da61103782344ac811f0dc895f74892 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 09:36:27 -0400 Subject: [PATCH 049/127] PNat: move Add and recOn earlier --- Mathlib/Data/PNat/Basic.lean | 24 +----------------------- Mathlib/Data/PNat/Defs.lean | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/Mathlib/Data/PNat/Basic.lean b/Mathlib/Data/PNat/Basic.lean index 285715236d27af..61fb27f756dcf9 100644 --- a/Mathlib/Data/PNat/Basic.lean +++ b/Mathlib/Data/PNat/Basic.lean @@ -21,7 +21,7 @@ that `Data.PNat.Defs` can have very few imports. @[expose] public section -deriving instance Add, Mul, Distrib, AddLeftCancelSemigroup, AddRightCancelSemigroup, +deriving instance Mul, Distrib, AddLeftCancelSemigroup, AddRightCancelSemigroup, AddCommSemigroup, CommMonoid, IsOrderedCancelMonoid, WellFoundedLT, AddLeftMono, AddLeftStrictMono, AddLeftReflectLE, AddLeftReflectLT for PNat @@ -156,28 +156,6 @@ def caseStrongInductionOn {p : ℕ+ → Sort*} (a : ℕ+) (hz : p 1) · exact hz exact hi ⟨k.succ, Nat.succ_pos _⟩ fun m hm => hk _ (Nat.lt_succ_iff.2 hm) -/-- An induction principle for `ℕ+`: it takes values in `Sort*`, so it applies also to Types, -not only to `Prop`. -/ -@[elab_as_elim, induction_eliminator] -def recOn (n : ℕ+) {p : ℕ+ → Sort*} (one : p 1) (succ : ∀ n, p n → p (n + 1)) : p n := by - rcases n with ⟨n, h⟩ - induction n with - | zero => exact absurd h (by decide) - | succ n IH => - rcases n with - | n - · exact one - · exact succ _ (IH n.succ_pos) - -@[simp] -theorem recOn_one {p} (one succ) : @PNat.recOn 1 p one succ = one := - rfl - -@[simp] -theorem recOn_succ (n : ℕ+) {p : ℕ+ → Sort*} (one succ) : - @PNat.recOn (n + 1) p one succ = succ n (@PNat.recOn n p one succ) := by - obtain ⟨n, h⟩ := n - cases n <;> [exact absurd h (by decide); rfl] - @[simp] theorem ofNat_le_ofNat {m n : ℕ} [NeZero m] [NeZero n] : (ofNat(m) : ℕ+) ≤ ofNat(n) ↔ OfNat.ofNat m ≤ OfNat.ofNat n := diff --git a/Mathlib/Data/PNat/Defs.lean b/Mathlib/Data/PNat/Defs.lean index 699bf0d24c0b2a..9a30f1a3714462 100644 --- a/Mathlib/Data/PNat/Defs.lean +++ b/Mathlib/Data/PNat/Defs.lean @@ -213,6 +213,31 @@ theorem div_coe (m k : ℕ+) : def divExact (m k : ℕ+) : ℕ+ := ⟨(div m k).succ, Nat.succ_pos _⟩ +instance : Add ℕ+ := + ⟨fun m n => ⟨(m : ℕ) + (n : ℕ), Nat.add_lt_add m.2 n.2⟩⟩ + +/-- An induction principle for `ℕ+`: it takes values in `Sort*`, so it applies also to Types, +not only to `Prop`. -/ +@[elab_as_elim, induction_eliminator] +def recOn (n : ℕ+) {p : ℕ+ → Sort*} (one : p 1) (succ : ∀ n, p n → p (n + 1)) : p n := by + rcases n with ⟨n, h⟩ + induction n with + | zero => exact absurd h (by decide) + | succ n IH => + rcases n with - | n + · exact one + · exact succ _ (IH n.succ_pos) + +@[simp] +theorem recOn_one {p} (one succ) : @PNat.recOn 1 p one succ = one := + rfl + +@[simp] +theorem recOn_succ (n : ℕ+) {p : ℕ+ → Sort*} (one succ) : + @PNat.recOn (n + 1) p one succ = succ n (@PNat.recOn n p one succ) := by + obtain ⟨n, h⟩ := n + cases n <;> [exact absurd h (by decide); rfl] + end PNat section CanLift From 63da0016adb326d24231f30b992339b055ca025e Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 15:05:51 -0400 Subject: [PATCH 050/127] injsurj fix order --- Mathlib/Algebra/Group/InjSurj.lean | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Mathlib/Algebra/Group/InjSurj.lean b/Mathlib/Algebra/Group/InjSurj.lean index c2a48f948a2745..a6c0ae1432ec56 100644 --- a/Mathlib/Algebra/Group/InjSurj.lean +++ b/Mathlib/Algebra/Group/InjSurj.lean @@ -238,10 +238,10 @@ that preserves `1`, `*`, `⁻¹`, and `/` to a `DivInvMonoid`. See note [reducib a `SubNegMonoid`. This version takes custom `nsmul` and `zsmul` as `[SMul ℕ M₁]` and `[SMul ℤ M₁]` arguments. -/] protected abbrev divInvMonoid [DivInvMonoid M₂] (f : M₁ → M₂) (hf : Injective f) (one : f 1 = 1) - (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) - (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (div : ∀ x y, f (x / y) = f x / f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) - (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : DivInvMonoid M₁ := + (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) + (div : ∀ x y, f (x / y) = f x / f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : + DivInvMonoid M₁ := { hf.monoid f one mul ppow npow with zpow := fun n x => x ^ n, zpow_zero' := fun x => hf <| by rw [zpow, zpow_zero, one], @@ -262,7 +262,7 @@ protected abbrev divInvOneMonoid [DivInvOneMonoid M₂] (f : M₁ → M₂) (hf (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (div : ∀ x y, f (x / y) = f x / f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : DivInvOneMonoid M₁ := - { hf.divInvMonoid f one mul inv ppow div npow zpow, hf.invOneClass f one inv with } + { hf.divInvMonoid f one mul inv div ppow npow zpow, hf.invOneClass f one inv with } /-- A type endowed with `1`, `*`, `⁻¹`, and `/` is a `DivisionMonoid` if it admits an injective map that preserves `1`, `*`, `⁻¹`, and `/` to a `DivisionMonoid`. See note [reducible non-instances] -/ @@ -273,10 +273,10 @@ binary `-` to a `SubtractionMonoid`. This version takes custom `nsmul` and `zsmu and `[SMul ℤ M₁]` arguments. -/] protected abbrev divisionMonoid [DivisionMonoid M₂] (f : M₁ → M₂) (hf : Injective f) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) - (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (div : ∀ x y, f (x / y) = f x / f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) - (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : DivisionMonoid M₁ := - { hf.divInvMonoid f one mul inv ppow div npow zpow, hf.involutiveInv f inv with + (div : ∀ x y, f (x / y) = f x / f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : + DivisionMonoid M₁ := + { hf.divInvMonoid f one mul inv div ppow npow zpow, hf.involutiveInv f inv with mul_inv_rev := fun x y => hf <| by rw [inv, mul, mul_inv_rev, mul, inv, inv], inv_eq_of_mul := fun x y h => hf <| by rw [inv, inv_eq_of_mul_eq_one_right (by rw [← mul, h, one])] } @@ -291,10 +291,10 @@ and binary `-` to a `SubtractionCommMonoid`. This version takes custom `nsmul` a `[SMul ℕ M₁]` and `[SMul ℤ M₁]` arguments. -/] protected abbrev divisionCommMonoid [DivisionCommMonoid M₂] (f : M₁ → M₂) (hf : Injective f) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) - (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (div : ∀ x y, f (x / y) = f x / f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) - (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : DivisionCommMonoid M₁ := - { hf.divisionMonoid f one mul inv ppow div npow zpow, hf.commSemigroup f mul ppow with } + (div : ∀ x y, f (x / y) = f x / f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : + DivisionCommMonoid M₁ := + { hf.divisionMonoid f one mul inv div ppow npow zpow, hf.commSemigroup f mul ppow with } /-- A type endowed with `1`, `*` and `⁻¹` is a group, if it admits an injective map that preserves `1`, `*` and `⁻¹` to a group. See note [reducible non-instances]. -/ @@ -306,7 +306,7 @@ protected abbrev group [Group M₂] (f : M₁ → M₂) (hf : Injective f) (one (div : ∀ x y, f (x / y) = f x / f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : Group M₁ := - { hf.divInvMonoid f one mul inv ppow div npow zpow with + { hf.divInvMonoid f one mul inv div ppow npow zpow with inv_mul_cancel := fun x => hf <| by rw [mul, inv, inv_mul_cancel, one] } From 3a5af0c8549bf43507b3d1b1723f3058645a79f0 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 15:18:45 -0400 Subject: [PATCH 051/127] pointwise finset --- .../Algebra/Group/Pointwise/Finset/Basic.lean | 36 +++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean b/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean index d2652c3e4c35e3..85536baff89d17 100644 --- a/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean +++ b/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean @@ -695,6 +695,14 @@ section Instances variable [DecidableEq α] [DecidableEq β] +/-- Repeated pointwise multiplication (not the same as pointwise repeated multiplication!) of a +`Finset`. See note [pointwise nat action]. -/ +@[to_additive (attr := instance_reducible) +/-- Repeated pointwise addition (not the same as pointwise repeated addition!) of a `Finset`. See +note [pointwise nat action]. -/] +protected def ppow [Mul α] : Pow (Finset α) ℕ+ := + ⟨fun s n => ppowRec n n.prop s⟩ + /-- Repeated pointwise multiplication (not the same as pointwise repeated multiplication!) of a `Finset`. See note [pointwise nat action]. -/ @[to_additive (attr := instance_reducible) @@ -711,13 +719,27 @@ addition/subtraction!) of a `Finset`. See note [pointwise nat action]. -/] protected def zpow [One α] [Mul α] [Inv α] : Pow (Finset α) ℤ := ⟨fun s n => zpowRec npowRec n s⟩ -scoped[Pointwise] attribute [instance] Finset.nsmul Finset.npow Finset.zsmul Finset.zpow +scoped[Pointwise] attribute [instance] Finset.psmul Finset.ppow Finset.nsmul Finset.npow + Finset.zsmul Finset.zpow + +@[to_additive (attr := simp, norm_cast)] +theorem coe_ppow [Semigroup α] (s : Finset α) (n : ℕ+) : ↑(s ^ n) = (s : Set α) ^ n := by + change ↑(ppowRec n n.prop s) = (s : Set α) ^ n + rw [← Semigroup.ppow_eq_pow] + rcases n with ⟨_|n, hn⟩ + · contradiction + simp only [_root_.mk_coe] + induction n with + | zero => rfl + | succ n IH => + rw [ppowRec] + simp [IH Nat.succ_pos', Semigroup.ppow_succ] /-- `Finset α` is a `Semigroup` under pointwise operations if `α` is. -/ @[to_additive (attr := implicit_reducible) /-- `Finset α` is an `AddSemigroup` under pointwise operations if `α` is. -/] protected def semigroup [Semigroup α] : Semigroup (Finset α) := - coe_injective.semigroup _ coe_mul + coe_injective.semigroup _ coe_mul coe_ppow section CommSemigroup @@ -727,7 +749,7 @@ variable [CommSemigroup α] {s t : Finset α} @[to_additive (attr := implicit_reducible) /-- `Finset α` is an `AddCommSemigroup` under pointwise operations if `α` is. -/] protected def commSemigroup : CommSemigroup (Finset α) := - coe_injective.commSemigroup _ coe_mul + coe_injective.commSemigroup _ coe_mul coe_ppow @[to_additive] theorem inter_mul_union_subset : s ∩ t * (s ∪ t) ⊆ s * t := @@ -811,7 +833,7 @@ theorem coe_pow (s : Finset α) (n : ℕ) : ↑(s ^ n) = (s : Set α) ^ n := by @[to_additive (attr := implicit_reducible) /-- `Finset α` is an `AddMonoid` under pointwise operations if `α` is. -/] protected def monoid : Monoid (Finset α) := - coe_injective.monoid _ coe_one coe_mul coe_pow + coe_injective.monoid _ coe_one coe_mul coe_ppow coe_pow scoped[Pointwise] attribute [instance] Finset.monoid Finset.addMonoid @@ -937,7 +959,7 @@ variable [CommMonoid α] @[to_additive (attr := implicit_reducible) /-- `Finset α` is an `AddCommMonoid` under pointwise operations if `α` is. -/] protected def commMonoid : CommMonoid (Finset α) := - coe_injective.commMonoid _ coe_one coe_mul coe_pow + coe_injective.commMonoid _ coe_one coe_mul coe_ppow coe_pow scoped[Pointwise] attribute [instance] Finset.commMonoid Finset.addCommMonoid @@ -962,7 +984,7 @@ protected theorem mul_eq_one_iff : s * t = 1 ↔ ∃ a b, s = {a} ∧ t = {b} @[to_additive (attr := implicit_reducible) /-- `Finset α` is a subtraction monoid under pointwise operations if `α` is. -/] protected def divisionMonoid : DivisionMonoid (Finset α) := - coe_injective.divisionMonoid _ coe_one coe_mul coe_inv coe_div coe_pow coe_zpow + coe_injective.divisionMonoid _ coe_one coe_mul coe_inv coe_div coe_ppow coe_pow coe_zpow scoped[Pointwise] attribute [instance] Finset.divisionMonoid Finset.subtractionMonoid @@ -1017,7 +1039,7 @@ end DivisionMonoid /-- `Finset α` is a commutative subtraction monoid under pointwise operations if `α` is. -/] protected def divisionCommMonoid [DivisionCommMonoid α] : DivisionCommMonoid (Finset α) := - coe_injective.divisionCommMonoid _ coe_one coe_mul coe_inv coe_div coe_pow coe_zpow + coe_injective.divisionCommMonoid _ coe_one coe_mul coe_inv coe_div coe_ppow coe_pow coe_zpow scoped[Pointwise] attribute [instance] Finset.divisionCommMonoid Finset.subtractionCommMonoid section Group From adf97295265fdabb13ce975c980cbf35eb3f1eb8 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 15:27:47 -0400 Subject: [PATCH 052/127] injsurj fix order and formatting --- Mathlib/Algebra/GroupWithZero/InjSurj.lean | 50 +++++++++------------- 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/Mathlib/Algebra/GroupWithZero/InjSurj.lean b/Mathlib/Algebra/GroupWithZero/InjSurj.lean index dfa6aa0471046b..ed799ee1cabd46 100644 --- a/Mathlib/Algebra/GroupWithZero/InjSurj.lean +++ b/Mathlib/Algebra/GroupWithZero/InjSurj.lean @@ -125,35 +125,31 @@ See note [reducible non-instances]. -/ protected abbrev Function.Injective.monoidWithZero [Zero M₀'] [Mul M₀'] [One M₀'] [Pow M₀' ℕ] [Pow M₀' ℕ+] [MonoidWithZero M₀] (f : M₀' → M₀) (hf : Injective f) (zero : f 0 = 0) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : - MonoidWithZero M₀' := + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : MonoidWithZero M₀' := { hf.monoid f one mul ppow npow, hf.mulZeroClass f zero mul with } /-- Push forward a `MonoidWithZero` along a surjective function. See note [reducible non-instances]. -/ protected abbrev Function.Surjective.monoidWithZero [Zero M₀'] [Mul M₀'] [One M₀'] [Pow M₀' ℕ] [Pow M₀' ℕ+] [MonoidWithZero M₀] (f : M₀ → M₀') (hf : Surjective f) (zero : f 0 = 0) - (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) - (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : - MonoidWithZero M₀' := + (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : MonoidWithZero M₀' := { hf.monoid f one mul ppow npow, hf.mulZeroClass f zero mul with } /-- Pull back a `CommMonoidWithZero` along an injective function. See note [reducible non-instances]. -/ protected abbrev Function.Injective.commMonoidWithZero [Zero M₀'] [Mul M₀'] [One M₀'] [Pow M₀' ℕ] [Pow M₀' ℕ+] [CommMonoidWithZero M₀] (f : M₀' → M₀) (hf : Injective f) (zero : f 0 = 0) - (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) - (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : - CommMonoidWithZero M₀' := + (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : CommMonoidWithZero M₀' := { hf.commMonoid f one mul ppow npow, hf.mulZeroClass f zero mul with } /-- Push forward a `CommMonoidWithZero` along a surjective function. See note [reducible non-instances]. -/ protected abbrev Function.Surjective.commMonoidWithZero [Zero M₀'] [Mul M₀'] [One M₀'] [Pow M₀' ℕ] [Pow M₀' ℕ+] [CommMonoidWithZero M₀] (f : M₀ → M₀') (hf : Surjective f) (zero : f 0 = 0) - (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) - (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : - CommMonoidWithZero M₀' := + (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) : CommMonoidWithZero M₀' := { hf.commMonoid f one mul ppow npow, hf.mulZeroClass f zero mul with } end MonoidWithZero @@ -166,13 +162,12 @@ variable [GroupWithZero G₀] See note [reducible non-instances]. -/ protected abbrev Function.Injective.groupWithZero [Zero G₀'] [Mul G₀'] [One G₀'] [Inv G₀'] [Div G₀'] [Pow G₀' ℕ] [Pow G₀' ℕ+] [Pow G₀' ℤ] (f : G₀' → G₀) (hf : Injective f) (zero : f 0 = 0) - (one : f 1 = 1) - (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) + (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) (div : ∀ x y, f (x / y) = f x / f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) - (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : GroupWithZero G₀' := + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : + GroupWithZero G₀' := { hf.monoidWithZero f zero one mul ppow npow, - hf.divInvMonoid f one mul inv ppow div npow zpow, + hf.divInvMonoid f one mul inv div ppow npow zpow, domain_nontrivial f zero one with inv_zero := hf <| by rw [inv, zero, inv_zero], mul_inv_cancel := fun x hx => hf <| by @@ -182,12 +177,10 @@ protected abbrev Function.Injective.groupWithZero [Zero G₀'] [Mul G₀'] [One See note [reducible non-instances]. -/ protected abbrev Function.Surjective.groupWithZero [Zero G₀'] [Mul G₀'] [One G₀'] [Inv G₀'] [Div G₀'] [Pow G₀' ℕ] [Pow G₀' ℕ+] [Pow G₀' ℤ] (h01 : (0 : G₀') ≠ 1) (f : G₀ → G₀') - (hf : Surjective f) - (zero : f 0 = 0) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) + (hf : Surjective f) (zero : f 0 = 0) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) (div : ∀ x y, f (x / y) = f x / f y) - (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : - GroupWithZero G₀' := + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) + (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : GroupWithZero G₀' := { hf.monoidWithZero f zero one mul ppow npow, hf.divInvMonoid f one mul inv ppow div npow zpow with inv_zero := by rw [← zero, ← inv, inv_zero], @@ -205,10 +198,9 @@ variable [CommGroupWithZero G₀] See note [reducible non-instances]. -/ protected abbrev Function.Injective.commGroupWithZero [Zero G₀'] [Mul G₀'] [One G₀'] [Inv G₀'] [Div G₀'] [Pow G₀' ℕ] [Pow G₀' ℕ+] [Pow G₀' ℤ] (f : G₀' → G₀) (hf : Injective f) - (zero : f 0 = 0) - (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) - (div : ∀ x y, f (x / y) = f x / f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) + (zero : f 0 = 0) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) + (inv : ∀ x, f x⁻¹ = (f x)⁻¹) (div : ∀ x y, f (x / y) = f x / f y) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : CommGroupWithZero G₀' := { hf.groupWithZero f zero one mul inv div ppow npow zpow, hf.commSemigroup f mul ppow with } @@ -217,12 +209,10 @@ See note [reducible non-instances]. -/ @[implicit_reducible] protected def Function.Surjective.commGroupWithZero [Zero G₀'] [Mul G₀'] [One G₀'] [Inv G₀'] [Div G₀'] [Pow G₀' ℕ] [Pow G₀' ℕ+] [Pow G₀' ℤ] (h01 : (0 : G₀') ≠ 1) (f : G₀ → G₀') - (hf : Surjective f) - (zero : f 0 = 0) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) + (hf : Surjective f) (zero : f 0 = 0) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) (div : ∀ x y, f (x / y) = f x / f y) - (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : - CommGroupWithZero G₀' := + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) + (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : CommGroupWithZero G₀' := { hf.groupWithZero h01 f zero one mul inv div ppow npow zpow, hf.commSemigroup f mul ppow with } From 6ac546a6c326f6e191ac0835382931372b89af22 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 15:37:04 -0400 Subject: [PATCH 053/127] subgroup --- Mathlib/Algebra/Group/Subgroup/Defs.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Group/Subgroup/Defs.lean b/Mathlib/Algebra/Group/Subgroup/Defs.lean index 81e5bb70d1a79d..3c809255e7a5b6 100644 --- a/Mathlib/Algebra/Group/Subgroup/Defs.lean +++ b/Mathlib/Algebra/Group/Subgroup/Defs.lean @@ -206,7 +206,7 @@ variable (H) @[to_additive /-- An additive subgroup of an `AddGroup` inherits an `AddGroup` structure. -/] instance (priority := 75) toGroup : Group H := fast_instance% Subtype.coe_injective.group _ rfl (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl -- Prefer subclasses of `CommGroup` over subclasses of `SubgroupClass`. /-- A subgroup of a `CommGroup` is a `CommGroup`. -/ @@ -214,7 +214,7 @@ instance (priority := 75) toGroup : Group H := fast_instance% instance (priority := 75) toCommGroup {G : Type*} [CommGroup G] [SetLike S G] [SubgroupClass S G] : CommGroup H := fast_instance% Subtype.coe_injective.commGroup _ rfl (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl /-- The natural group hom from a subgroup of group `G` to `G`. -/ @[to_additive (attr := coe) From 79110fb8d260d689b157047269ca4b13aea088a5 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 15:56:14 -0400 Subject: [PATCH 054/127] ring injsurj arg order and lemma order --- Mathlib/Algebra/Ring/InjSurj.lean | 308 ++++++++++++++---------------- 1 file changed, 141 insertions(+), 167 deletions(-) diff --git a/Mathlib/Algebra/Ring/InjSurj.lean b/Mathlib/Algebra/Ring/InjSurj.lean index f4fbc77ffb2dbb..819cf8d86e3b1b 100644 --- a/Mathlib/Algebra/Ring/InjSurj.lean +++ b/Mathlib/Algebra/Ring/InjSurj.lean @@ -69,10 +69,10 @@ if it admits an injective map that preserves `0`, `1` and `+` to an additive mon See note [reducible non-instances]. -/ protected abbrev addMonoidWithOne [AddMonoidWithOne R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (one : f 1 = 1) - (add : ∀ x y, f (x + y) = f x + f y) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (add : ∀ x y, f (x + y) = f x + f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) : AddMonoidWithOne S := - { hf.addMonoid f zero add psmul (swap nsmul) with + { hf.addMonoid f zero add (swap psmul) (swap nsmul) with natCast := Nat.cast, natCast_zero := hf (by rw [natCast, Nat.cast_zero, zero]), natCast_succ := fun n => hf (by rw [natCast, Nat.cast_succ, add, one, natCast]) } @@ -83,11 +83,11 @@ See note [reducible non-instances]. -/ protected abbrev addCommMonoidWithOne {S} [Zero S] [One S] [Add S] [SMul ℕ+ S] [SMul ℕ S] [NatCast S] [AddCommMonoidWithOne R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (one : f 1 = 1) - (add : ∀ x y, f (x + y) = f x + f y) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (add : ∀ x y, f (x + y) = f x + f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) : AddCommMonoidWithOne S where __ := hf.addMonoidWithOne f zero one add psmul nsmul natCast - __ := hf.addCommMonoid _ zero add psmul (swap nsmul) + __ := hf.addCommMonoid _ zero add (swap psmul) (swap nsmul) /-- A type endowed with `0`, `1` and `+` is an additive group with one, if it admits an injective map that preserves `0`, `1` and `+` to an additive group with one. See note @@ -95,11 +95,10 @@ map that preserves `0`, `1` and `+` to an additive group with one. See note protected abbrev addGroupWithOne {S} [Zero S] [One S] [Add S] [SMul ℕ+ S] [SMul ℕ S] [Neg S] [Sub S] [SMul ℤ S] [NatCast S] [IntCast S] [AddGroupWithOne R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (neg : ∀ x, f (-x) = -f x) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) - (intCast : ∀ n : ℤ, f n = n) : AddGroupWithOne S := - { hf.addGroup f zero add neg sub psmul (swap nsmul) (swap zsmul), + (sub : ∀ x y, f (x - y) = f x - f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) + (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : AddGroupWithOne S := + { hf.addGroup f zero add neg sub (swap psmul) (swap nsmul) (swap zsmul), hf.addMonoidWithOne f zero one add psmul nsmul natCast with intCast := Int.cast, intCast_ofNat := fun n => hf (by rw [natCast, intCast, Int.cast_natCast]), @@ -112,30 +111,28 @@ protected abbrev addCommGroupWithOne {S} [Zero S] [One S] [Add S] [SMul ℕ+ S] [SMul ℕ S] [Neg S] [Sub S] [SMul ℤ S] [NatCast S] [IntCast S] [AddCommGroupWithOne R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (neg : ∀ x, f (-x) = -f x) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) - (intCast : ∀ n : ℤ, f n = n) : AddCommGroupWithOne S := - { hf.addGroupWithOne f zero one add neg psmul sub nsmul zsmul natCast intCast, - hf.addCommMonoid _ zero add psmul (swap nsmul) with } + (sub : ∀ x y, f (x - y) = f x - f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) + (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : AddCommGroupWithOne S := + { hf.addGroupWithOne f zero one add neg sub psmul nsmul zsmul natCast intCast, + hf.addCommMonoid _ zero add (swap psmul) (swap nsmul) with } /-- Pullback a `NonUnitalNonAssocSemiring` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalNonAssocSemiring [NonUnitalNonAssocSemiring R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : NonUnitalNonAssocSemiring S where - toAddCommMonoid := hf.addCommMonoid f zero add psmul (swap nsmul) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : + NonUnitalNonAssocSemiring S where + toAddCommMonoid := hf.addCommMonoid f zero add (swap psmul) (swap nsmul) __ := hf.distrib f add mul __ := hf.mulZeroClass f zero mul /-- Pullback a `NonUnitalSemiring` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalSemiring [NonUnitalSemiring R] - (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) - (mul : ∀ x y, f (x * y) = f x * f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : + (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) : NonUnitalSemiring S where toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul psmul nsmul __ := hf.semigroupWithZero f zero mul ppow @@ -144,9 +141,9 @@ protected abbrev nonUnitalSemiring [NonUnitalSemiring R] -- See note [reducible non-instances] protected abbrev nonAssocSemiring [NonAssocSemiring R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) - (mul : ∀ x y, f (x * y) = f x * f y) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (natCast : ∀ n : ℕ, f n = n) : NonAssocSemiring S where + (mul : ∀ x y, f (x * y) = f x * f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) : + NonAssocSemiring S where toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul psmul nsmul __ := hf.mulZeroOneClass f zero one mul __ := hf.addMonoidWithOne f zero one add psmul nsmul natCast @@ -155,11 +152,10 @@ protected abbrev nonAssocSemiring [NonAssocSemiring R] -- See note [reducible non-instances] protected abbrev semiring [Semiring R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) : Semiring S where - toNonUnitalSemiring := hf.nonUnitalSemiring f zero add mul ppow psmul nsmul + toNonUnitalSemiring := hf.nonUnitalSemiring f zero add mul psmul nsmul ppow __ := hf.nonAssocSemiring f zero one add mul psmul nsmul natCast __ := hf.monoidWithZero f zero one mul ppow npow @@ -168,58 +164,55 @@ protected abbrev semiring [Semiring R] (zero : f 0 = 0) (one : f 1 = 1) protected abbrev nonUnitalNonAssocRing [NonUnitalNonAssocRing R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : NonUnitalNonAssocRing S where - toAddCommGroup := hf.addCommGroup f zero add neg sub psmul (swap nsmul) (swap zsmul) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : + NonUnitalNonAssocRing S where + toAddCommGroup := hf.addCommGroup f zero add neg sub (swap psmul) (swap nsmul) (swap zsmul) __ := hf.nonUnitalNonAssocSemiring f zero add mul psmul nsmul /-- Pullback a `NonUnitalRing` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalRing [NonUnitalRing R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (neg : ∀ x, f (-x) = -f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : + (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) : NonUnitalRing S where toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg psmul sub nsmul zsmul - __ := hf.nonUnitalSemiring f zero add mul ppow psmul nsmul + __ := hf.nonUnitalSemiring f zero add mul psmul nsmul ppow /-- Pullback a `NonAssocRing` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev nonAssocRing [NonAssocRing R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) - (intCast : ∀ n : ℤ, f n = n) : NonAssocRing S where + (sub : ∀ x y, f (x - y) = f x - f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) + (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : NonAssocRing S where toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg psmul sub nsmul zsmul __ := hf.nonAssocSemiring f zero one add mul psmul nsmul natCast - __ := hf.addCommGroupWithOne f zero one add neg psmul sub nsmul zsmul natCast intCast + __ := hf.addCommGroupWithOne f zero one add neg sub psmul nsmul zsmul natCast intCast /-- Pullback a `Ring` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev ring [Ring R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : Ring S where toSemiring := hf.semiring f zero one add mul psmul nsmul ppow npow natCast -- zsmul included here explicitly to make sure it's picked correctly by `fast_instance%`. zsmul := fun n x ↦ n • x - __ := hf.addGroupWithOne f zero one add neg psmul sub nsmul zsmul natCast intCast - __ := hf.addCommGroup f zero add neg sub psmul (swap nsmul) (swap zsmul) + __ := hf.addGroupWithOne f zero one add neg sub psmul nsmul zsmul natCast intCast + __ := hf.addCommGroup f zero add neg sub (swap psmul) (swap nsmul) (swap zsmul) /-- Pullback a `NonUnitalNonAssocCommSemiring` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalNonAssocCommSemiring [NonUnitalNonAssocCommSemiring R] - (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) - (mul : ∀ x y, f (x * y) = f x * f y) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : + (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : NonUnitalNonAssocCommSemiring S where toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul psmul nsmul __ := hf.commMagma f mul @@ -228,18 +221,17 @@ protected abbrev nonUnitalNonAssocCommSemiring [NonUnitalNonAssocCommSemiring R] -- See note [reducible non-instances] protected abbrev nonUnitalCommSemiring [NonUnitalCommSemiring R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) - (mul : ∀ x y, f (x * y) = f x * f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : + (mul : ∀ x y, f (x * y) = f x * f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) : NonUnitalCommSemiring S where - toNonUnitalSemiring := hf.nonUnitalSemiring f zero add mul ppow psmul nsmul + toNonUnitalSemiring := hf.nonUnitalSemiring f zero add mul psmul nsmul ppow __ := hf.commSemigroup f mul ppow /-- Pullback a `NonAssocCommSemiring` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev nonAssocCommSemiring [NonAssocCommSemiring R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) - (mul : ∀ x y, f (x * y) = f x * f y) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) + (mul : ∀ x y, f (x * y) = f x * f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) : NonAssocCommSemiring S where toNonAssocSemiring := hf.nonAssocSemiring f zero one add mul psmul nsmul natCast @@ -249,11 +241,9 @@ protected abbrev nonAssocCommSemiring [NonAssocCommSemiring R] (f : S → R) -- See note [reducible non-instances] protected abbrev commSemiring [CommSemiring R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) - (mul : ∀ x y, f (x * y) = f x * f y) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) : - CommSemiring S where + (mul : ∀ x y, f (x * y) = f x * f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) : CommSemiring S where toSemiring := hf.semiring f zero one add mul psmul nsmul ppow npow natCast __ := hf.commSemigroup f mul ppow @@ -262,9 +252,9 @@ protected abbrev commSemiring [CommSemiring R] protected abbrev nonUnitalNonAssocCommRing [NonUnitalNonAssocCommRing R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : NonUnitalNonAssocCommRing S where + (sub : ∀ x y, f (x - y) = f x - f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : + NonUnitalNonAssocCommRing S where toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg psmul sub nsmul zsmul __ := hf.nonUnitalNonAssocCommSemiring f zero add mul psmul nsmul @@ -273,34 +263,31 @@ protected abbrev nonUnitalNonAssocCommRing [NonUnitalNonAssocCommRing R] (f : S protected abbrev nonUnitalCommRing [NonUnitalCommRing R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) - (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : NonUnitalCommRing S where - toNonUnitalRing := hf.nonUnitalRing f zero add mul neg ppow psmul sub nsmul zsmul - __ := hf.nonUnitalNonAssocCommRing f zero add mul neg psmul sub nsmul zsmul + (sub : ∀ x y, f (x - y) = f x - f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) : NonUnitalCommRing S where + toNonUnitalRing := hf.nonUnitalRing f zero add mul neg sub psmul nsmul zsmul ppow + __ := hf.nonUnitalNonAssocCommRing f zero add mul neg sub psmul nsmul zsmul /-- Pullback a `NonAssocCommRing` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev nonAssocCommRing [NonAssocCommRing R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) + (sub : ∀ x y, f (x - y) = f x - f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : NonAssocCommRing S where - toNonAssocRing := hf.nonAssocRing f zero one add mul neg psmul sub nsmul zsmul natCast intCast - __ := hf.nonUnitalNonAssocCommRing f zero add mul neg psmul sub nsmul zsmul + toNonAssocRing := hf.nonAssocRing f zero one add mul neg sub psmul nsmul zsmul natCast intCast + __ := hf.nonUnitalNonAssocCommRing f zero add mul neg sub psmul nsmul zsmul /-- Pullback a `CommRing` instance along an injective function. -/ -- See note [reducible non-instances] protected abbrev commRing [CommRing R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) - (sub : ∀ x y, f (x - y) = f x - f y) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) + (sub : ∀ x y, f (x - y) = f x - f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : CommRing S where toRing := hf.ring f zero one add mul neg sub psmul nsmul zsmul ppow npow natCast intCast __ := hf.commMonoid f one mul ppow npow @@ -347,10 +334,10 @@ protected abbrev hasDistribNeg [Mul R] [HasDistribNeg R] map that preserves `0`, `1` and `*` from an additive monoid with one. See note [reducible non-instances]. -/ protected abbrev addMonoidWithOne [AddMonoidWithOne R] (zero : f 0 = 0) (one : f 1 = 1) - (add : ∀ x y, f (x + y) = f x + f y) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (natCast : ∀ n : ℕ, f n = n) : AddMonoidWithOne S := - { hf.addMonoid f zero add psmul (swap nsmul) with + (add : ∀ x y, f (x + y) = f x + f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) : + AddMonoidWithOne S := + { hf.addMonoid f zero add (swap psmul) (swap nsmul) with natCast := Nat.cast, natCast_zero := by rw [← natCast, Nat.cast_zero, zero] natCast_succ := fun n => by rw [← natCast, Nat.cast_succ, add, one, natCast] } @@ -359,23 +346,22 @@ protected abbrev addMonoidWithOne [AddMonoidWithOne R] (zero : f 0 = 0) (one : f if it admits a surjective map that preserves `0`, `1` and `*` from an additive monoid with one. See note [reducible non-instances]. -/ protected abbrev addCommMonoidWithOne [AddCommMonoidWithOne R] (zero : f 0 = 0) (one : f 1 = 1) - (add : ∀ x y, f (x + y) = f x + f y) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (natCast : ∀ n : ℕ, f n = n) : AddCommMonoidWithOne S where + (add : ∀ x y, f (x + y) = f x + f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) : + AddCommMonoidWithOne S where __ := hf.addMonoidWithOne f zero one add psmul nsmul natCast - __ := hf.addCommMonoid _ zero add psmul (swap nsmul) + __ := hf.addCommMonoid _ zero add (swap psmul) (swap nsmul) /-- A type endowed with `0`, `1`, `+` is an additive group with one, if it admits a surjective map that preserves `0`, `1`, and `+` to an additive group with one. See note [reducible non-instances]. -/ protected abbrev addGroupWithOne [AddGroupWithOne R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (neg : ∀ x, f (-x) = -f x) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) - (intCast : ∀ n : ℤ, f n = n) : AddGroupWithOne S := + (sub : ∀ x y, f (x - y) = f x - f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) + (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : AddGroupWithOne S := { hf.addMonoidWithOne f zero one add psmul nsmul natCast, - hf.addGroup f zero add neg psmul sub (swap nsmul) (swap zsmul) with + hf.addGroup f zero add neg (swap psmul) sub (swap nsmul) (swap zsmul) with intCast := Int.cast, intCast_ofNat := fun n => by rw [← intCast, Int.cast_natCast, natCast], intCast_negSucc := fun n => by @@ -386,20 +372,19 @@ surjective map that preserves `0`, `1`, and `+` to an additive commutative group See note [reducible non-instances]. -/ protected abbrev addCommGroupWithOne [AddCommGroupWithOne R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (neg : ∀ x, f (-x) = -f x) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) - (intCast : ∀ n : ℤ, f n = n) : AddCommGroupWithOne S := - { hf.addGroupWithOne f zero one add neg psmul sub nsmul zsmul natCast intCast, - hf.addCommMonoid _ zero add psmul (swap nsmul) with } + (sub : ∀ x y, f (x - y) = f x - f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) + (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : AddCommGroupWithOne S := + { hf.addGroupWithOne f zero one add neg sub psmul nsmul zsmul natCast intCast, + hf.addCommMonoid _ zero add (swap psmul) (swap nsmul) with } /-- Pushforward a `NonUnitalNonAssocSemiring` instance along a surjective function. See note [reducible non-instances]. -/ protected abbrev nonUnitalNonAssocSemiring [NonUnitalNonAssocSemiring R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : NonUnitalNonAssocSemiring S where - toAddCommMonoid := hf.addCommMonoid f zero add psmul (swap nsmul) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : + NonUnitalNonAssocSemiring S where + toAddCommMonoid := hf.addCommMonoid f zero add (swap psmul) (swap nsmul) __ := hf.distrib f add mul __ := hf.mulZeroClass f zero mul @@ -407,9 +392,8 @@ protected abbrev nonUnitalNonAssocSemiring [NonUnitalNonAssocSemiring R] (zero : -- See note [reducible non-instances] protected abbrev nonUnitalSemiring [NonUnitalSemiring R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : NonUnitalSemiring S where + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) : NonUnitalSemiring S where toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul psmul nsmul __ := hf.semigroupWithZero f zero mul ppow @@ -417,8 +401,7 @@ protected abbrev nonUnitalSemiring [NonUnitalSemiring R] (zero : f 0 = 0) -- See note [reducible non-instances] protected abbrev nonAssocSemiring [NonAssocSemiring R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) : NonAssocSemiring S where toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul psmul nsmul __ := hf.mulZeroOneClass f zero one mul @@ -428,11 +411,10 @@ protected abbrev nonAssocSemiring [NonAssocSemiring R] (zero : f 0 = 0) (one : f -- See note [reducible non-instances] protected abbrev semiring [Semiring R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) : Semiring S where - toNonUnitalSemiring := hf.nonUnitalSemiring f zero add mul ppow psmul nsmul + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) + (natCast : ∀ n : ℕ, f n = n) : Semiring S where + toNonUnitalSemiring := hf.nonUnitalSemiring f zero add mul psmul nsmul ppow __ := hf.nonAssocSemiring f zero one add mul psmul nsmul natCast __ := hf.monoidWithZero f zero one mul ppow npow @@ -440,56 +422,54 @@ protected abbrev semiring [Semiring R] (zero : f 0 = 0) (one : f 1 = 1) -- See note [reducible non-instances] protected abbrev nonUnitalNonAssocRing [NonUnitalNonAssocRing R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (neg : ∀ x, f (-x) = -f x) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : NonUnitalNonAssocRing S where - toAddCommGroup := hf.addCommGroup f zero add neg psmul sub (swap nsmul) (swap zsmul) + toAddCommGroup := hf.addCommGroup f zero add neg (swap psmul) sub (swap nsmul) (swap zsmul) __ := hf.nonUnitalNonAssocSemiring f zero add mul psmul nsmul /-- Pushforward a `NonUnitalRing` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalRing [NonUnitalRing R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (neg : ∀ x, f (-x) = -f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : + (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) : NonUnitalRing S where - toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg psmul sub nsmul zsmul - __ := hf.nonUnitalSemiring f zero add mul ppow psmul nsmul + toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg sub psmul nsmul zsmul + __ := hf.nonUnitalSemiring f zero add mul psmul nsmul ppow /-- Pushforward a `NonAssocRing` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev nonAssocRing [NonAssocRing R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (neg : ∀ x, f (-x) = -f x) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) - (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : NonAssocRing S where - toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg psmul sub nsmul zsmul + (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) + (intCast : ∀ n : ℤ, f n = n) : NonAssocRing S where + toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg sub psmul nsmul zsmul __ := hf.nonAssocSemiring f zero one add mul psmul nsmul natCast - __ := hf.addCommGroupWithOne f zero one add neg psmul sub nsmul zsmul natCast intCast + __ := hf.addCommGroupWithOne f zero one add neg sub psmul nsmul zsmul natCast intCast /-- Pushforward a `Ring` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev ring [Ring R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) - (mul : ∀ x y, f (x * y) = f x * f y) - (neg : ∀ x, f (-x) = -f x) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) - (intCast : ∀ n : ℤ, f n = n) : Ring S where + (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) + (sub : ∀ x y, f (x - y) = f x - f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) + (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) + (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : Ring S where toSemiring := hf.semiring f zero one add mul psmul nsmul ppow npow natCast - __ := hf.addGroupWithOne f zero one add neg psmul sub nsmul zsmul natCast intCast - __ := hf.addCommGroup f zero add neg psmul sub (swap nsmul) (swap zsmul) + __ := hf.addGroupWithOne f zero one add neg sub psmul nsmul zsmul natCast intCast + __ := hf.addCommGroup f zero add neg (swap psmul) sub (swap nsmul) (swap zsmul) /-- Pushforward a `NonUnitalNonAssocCommSemiring` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalNonAssocCommSemiring [NonUnitalNonAssocCommSemiring R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : NonUnitalNonAssocCommSemiring S where + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : + NonUnitalNonAssocCommSemiring S where toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul psmul nsmul __ := hf.commMagma f mul @@ -497,18 +477,16 @@ protected abbrev nonUnitalNonAssocCommSemiring [NonUnitalNonAssocCommSemiring R] -- See note [reducible non-instances] protected abbrev nonUnitalCommSemiring [NonUnitalCommSemiring R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : NonUnitalCommSemiring S where - toNonUnitalSemiring := hf.nonUnitalSemiring f zero add mul ppow psmul nsmul + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) : NonUnitalCommSemiring S where + toNonUnitalSemiring := hf.nonUnitalSemiring f zero add mul psmul nsmul ppow __ := hf.commSemigroup f mul ppow /-- Pushforward a `NonAssocCommSemiring` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev nonAssocCommSemiring [NonAssocCommSemiring R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) : NonAssocCommSemiring S where toNonAssocSemiring := hf.nonAssocSemiring f zero one add mul psmul nsmul natCast __ := hf.commMagma f mul @@ -517,58 +495,54 @@ protected abbrev nonAssocCommSemiring [NonAssocCommSemiring R] (zero : f 0 = 0) -- See note [reducible non-instances] protected abbrev commSemiring [CommSemiring R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) : CommSemiring S where toSemiring := hf.semiring f zero one add mul psmul nsmul ppow npow natCast __ := hf.commSemigroup f mul ppow /-- Pushforward a `NonUnitalNonAssocCommRing` instance along a surjective function. -/ -- See note [reducible non-instances] -protected abbrev nonUnitalNonAssocCommRing [NonUnitalNonAssocCommRing R] - (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) - (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) +protected abbrev nonUnitalNonAssocCommRing [NonUnitalNonAssocCommRing R] (zero : f 0 = 0) + (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) + (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : NonUnitalNonAssocCommRing S where - toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg psmul sub nsmul zsmul + toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg sub psmul nsmul zsmul __ := hf.nonUnitalNonAssocCommSemiring f zero add mul psmul nsmul /-- Pushforward a `NonUnitalCommRing` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev nonUnitalCommRing [NonUnitalCommRing R] (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (neg : ∀ x, f (-x) = -f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : + (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) : NonUnitalCommRing S where - toNonUnitalRing := hf.nonUnitalRing f zero add mul neg ppow psmul sub nsmul zsmul - __ := hf.nonUnitalNonAssocCommRing f zero add mul neg psmul sub nsmul zsmul + toNonUnitalRing := hf.nonUnitalRing f zero add mul neg sub psmul nsmul zsmul ppow + __ := hf.nonUnitalNonAssocCommRing f zero add mul neg sub psmul nsmul zsmul /-- Pushforward a `NonAssocCommRing` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev nonAssocCommRing [NonAssocCommRing R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (neg : ∀ x, f (-x) = -f x) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (sub : ∀ x y, f (x - y) = f x - f y) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) - (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : NonAssocCommRing S where - toNonAssocRing := hf.nonAssocRing f zero one add mul neg psmul sub nsmul zsmul natCast intCast + (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) + (intCast : ∀ n : ℤ, f n = n) : NonAssocCommRing S where + toNonAssocRing := hf.nonAssocRing f zero one add mul neg sub psmul nsmul zsmul natCast intCast __ := hf.nonAssocCommSemiring f zero one add mul psmul nsmul natCast /-- Pushforward a `CommRing` instance along a surjective function. -/ -- See note [reducible non-instances] protected abbrev commRing [CommRing R] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (neg : ∀ x, f (-x) = -f x) (psmul : ∀ (x) (n : ℕ+), f (n • x) = n • f x) - (sub : ∀ x y, f (x - y) = f x - f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) - (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) - (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : CommRing S where - toRing := hf.ring f zero one add mul neg psmul sub nsmul zsmul ppow npow natCast intCast + (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) + (intCast : ∀ n : ℤ, f n = n) : CommRing S where + toRing := hf.ring f zero one add mul neg sub psmul nsmul zsmul ppow npow natCast intCast __ := hf.commMonoid f one mul ppow npow end Function.Surjective From 1f06ecf54c4eb9b74b00bb85a97e198a1379474f Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 15:58:13 -0400 Subject: [PATCH 055/127] Kleene --- Mathlib/Algebra/Order/Kleene.lean | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/Mathlib/Algebra/Order/Kleene.lean b/Mathlib/Algebra/Order/Kleene.lean index 31cfca05053b33..aaea5fb97946ee 100644 --- a/Mathlib/Algebra/Order/Kleene.lean +++ b/Mathlib/Algebra/Order/Kleene.lean @@ -320,43 +320,46 @@ namespace Function.Injective -- See note [reducible non-instances] /-- Pullback an `IdemSemiring` instance along an injective function. -/ -protected abbrev idemSemiring [IdemSemiring α] [LE β] [LT β] [Zero β] [One β] - [Add β] [Mul β] [Pow β ℕ] [SMul ℕ β] [NatCast β] [Max β] [Bot β] (f : β → α) +protected abbrev idemSemiring [IdemSemiring α] [LE β] [LT β] [Zero β] [One β] [Add β] [Mul β] + [Pow β ℕ+] [Pow β ℕ] [SMul ℕ+ β] [SMul ℕ β] [NatCast β] [Max β] [Bot β] (f : β → α) (hf : Injective f) (le : ∀ {x y}, f x ≤ f y ↔ x ≤ y) (lt : ∀ {x y}, f x < f y ↔ x < y) (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (ppow : ∀ (x) (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) (sup : ∀ a b, f (a ⊔ b) = f a ⊔ f b) (bot : f ⊥ = ⊥) : IdemSemiring β where - __ := hf.semiring f zero one add mul nsmul npow natCast + __ := hf.semiring f zero one add mul psmul nsmul ppow npow natCast __ := hf.semilatticeSup f le lt sup add_eq_sup a b := hf <| by rw [sup, add, add_eq_sup] bot_le a := le.1 <| bot.trans_le bot_le -- See note [reducible non-instances] /-- Pullback an `IdemCommSemiring` instance along an injective function. -/ -protected abbrev idemCommSemiring [IdemCommSemiring α] [LE β] [LT β] [Zero β] [One β] - [Add β] [Mul β] [Pow β ℕ] [SMul ℕ β] [NatCast β] [Max β] [Bot β] (f : β → α) +protected abbrev idemCommSemiring [IdemCommSemiring α] [LE β] [LT β] [Zero β] [One β] [Add β] + [Mul β] [Pow β ℕ+] [Pow β ℕ] [SMul ℕ+ β] [SMul ℕ β] [NatCast β] [Max β] [Bot β] (f : β → α) (hf : Injective f) (le : ∀ {x y}, f x ≤ f y ↔ x ≤ y) (lt : ∀ {x y}, f x < f y ↔ x < y) (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (ppow : ∀ (x) (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) (sup : ∀ a b, f (a ⊔ b) = f a ⊔ f b) (bot : f ⊥ = ⊥) : IdemCommSemiring β where - __ := hf.commSemiring f zero one add mul nsmul npow natCast - __ := hf.idemSemiring f le lt zero one add mul nsmul npow natCast sup bot + __ := hf.commSemiring f zero one add mul psmul nsmul ppow npow natCast + __ := hf.idemSemiring f le lt zero one add mul psmul nsmul ppow npow natCast sup bot -- See note [reducible non-instances] /-- Pullback a `KleeneAlgebra` instance along an injective function. -/ -protected abbrev kleeneAlgebra [KleeneAlgebra α] [LE β] [LT β] [Zero β] [One β] - [Add β] [Mul β] [Pow β ℕ] [SMul ℕ β] [NatCast β] [Max β] [Bot β] [KStar β] (f : β → α) +protected abbrev kleeneAlgebra [KleeneAlgebra α] [LE β] [LT β] [Zero β] [One β] [Add β] [Mul β] + [Pow β ℕ+] [Pow β ℕ] [SMul ℕ+ β] [SMul ℕ β] [NatCast β] [Max β] [Bot β] [KStar β] (f : β → α) (hf : Injective f) (le : ∀ {x y}, f x ≤ f y ↔ x ≤ y) (lt : ∀ {x y}, f x < f y ↔ x < y) (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (ppow : ∀ (x) (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) (sup : ∀ a b, f (a ⊔ b) = f a ⊔ f b) (bot : f ⊥ = ⊥) (kstar : ∀ a, f a∗ = (f a)∗) : KleeneAlgebra β where - __ := hf.idemSemiring f le lt zero one add mul nsmul npow natCast sup bot + __ := hf.idemSemiring f le lt zero one add mul psmul nsmul ppow npow natCast sup bot one_le_kstar a := by rw [← le, one, kstar] exact one_le_kstar From deeb99e688893a3df4a03e4d9f20354d81a63efa Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 16:10:10 -0400 Subject: [PATCH 056/127] finsupp --- Mathlib/Algebra/Group/Finsupp.lean | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Group/Finsupp.lean b/Mathlib/Algebra/Group/Finsupp.lean index a3ddce45119979..39e0a4b9d1b6e3 100644 --- a/Mathlib/Algebra/Group/Finsupp.lean +++ b/Mathlib/Algebra/Group/Finsupp.lean @@ -337,6 +337,10 @@ end AddZeroClass section AddMonoid variable [AddMonoid M] +instance instPNatSMul : SMul ℕ+ (ι →₀ M) where smul n v := v.mapRange (n • ·) (psmul_zero _) + +@[simp, norm_cast] lemma coe_psmul (n : ℕ+) (f : ι →₀ M) : ⇑(n • f) = n • ⇑f := rfl + /-- Note the general `SMul` instance for `Finsupp` doesn't apply as `ℕ` is not distributive unless `F i`'s addition is commutative. -/ instance instNatSMul : SMul ℕ (ι →₀ M) where smul n v := v.mapRange (n • ·) (nsmul_zero _) @@ -346,7 +350,7 @@ instance instNatSMul : SMul ℕ (ι →₀ M) where smul n v := v.mapRange (n lemma nsmul_apply (n : ℕ) (f : ι →₀ M) (x : ι) : (n • f) x = n • f x := rfl instance instAddMonoid : AddMonoid (ι →₀ M) := - fast_instance% DFunLike.coe_injective.addMonoid _ coe_zero coe_add fun _ _ => rfl + fast_instance% DFunLike.coe_injective.addMonoid _ coe_zero coe_add (fun _ _ => rfl) fun _ _ => rfl instance instIsAddTorsionFree [IsAddTorsionFree M] : IsAddTorsionFree (ι →₀ M) := DFunLike.coe_injective.isAddTorsionFree coeFnAddHom @@ -358,7 +362,7 @@ variable [AddCommMonoid M] [AddCommMonoid N] [AddCommMonoid O] instance instAddCommMonoid : AddCommMonoid (ι →₀ M) := fast_instance% DFunLike.coe_injective.addCommMonoid - DFunLike.coe coe_zero coe_add (fun _ _ => rfl) + DFunLike.coe coe_zero coe_add (fun _ _ => rfl) (fun _ _ => rfl) lemma single_add_single_eq_single_add_single {k l m n : ι} {u v : M} (hu : u ≠ 0) (hv : v ≠ 0) : single k u + single l v = single m u + single n v ↔ @@ -458,7 +462,7 @@ instance instIntSMul : SMul ℤ (ι →₀ G) := instance instAddGroup : AddGroup (ι →₀ G) := fast_instance% DFunLike.coe_injective.addGroup DFunLike.coe coe_zero coe_add coe_neg coe_sub - (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl @[simp] lemma support_neg (f : ι →₀ G) : support (-f) = support f := @@ -501,6 +505,6 @@ end AddGroup instance instAddCommGroup [AddCommGroup G] : AddCommGroup (ι →₀ G) := fast_instance% DFunLike.coe_injective.addCommGroup DFunLike.coe coe_zero coe_add coe_neg coe_sub - (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl end Finsupp From 0a9c0ae9e9db5c320fbeb2fec843dc7fd509e310 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 16:52:28 -0400 Subject: [PATCH 057/127] namespacing --- Mathlib/Algebra/Group/PPow/Defs.lean | 2 ++ Mathlib/Algebra/Order/GroupWithZero/Basic.lean | 2 +- Mathlib/Data/PNat/Notation.lean | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Group/PPow/Defs.lean b/Mathlib/Algebra/Group/PPow/Defs.lean index ab8f0b28da8286..ccdf3bedfdb3cc 100644 --- a/Mathlib/Algebra/Group/PPow/Defs.lean +++ b/Mathlib/Algebra/Group/PPow/Defs.lean @@ -17,6 +17,8 @@ requiring instances on `ℕ+`, which are usually inferred via inheriting from ` public section +open PNat + variable {M : Type*} instance Semigroup.instPow [Semigroup M] : Pow M ℕ+ where diff --git a/Mathlib/Algebra/Order/GroupWithZero/Basic.lean b/Mathlib/Algebra/Order/GroupWithZero/Basic.lean index f53ce2d86a2ebb..34f7f229762b97 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Basic.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Basic.lean @@ -559,7 +559,7 @@ lemma pow_left_strictMonoOn₀ [MulPosMono M₀] (hn : n ≠ 0) : @[simp] lemma ppow_pos (ha : 0 < a) (n : ℕ+) : 0 < a ^ n := by rcases n with ⟨n, h⟩ - rw [← npow_val_eq_ppow, mk_coe] + rw [← npow_val_eq_ppow, PNat.mk_coe] obtain ⟨n, rfl⟩ := Nat.exists_eq_succ_of_ne_zero h.ne' exact pow_succ_pos ha n diff --git a/Mathlib/Data/PNat/Notation.lean b/Mathlib/Data/PNat/Notation.lean index 642eefc2b42bc1..53127e023581f8 100644 --- a/Mathlib/Data/PNat/Notation.lean +++ b/Mathlib/Data/PNat/Notation.lean @@ -38,6 +38,8 @@ instance : One ℕ+ := instance (n : ℕ) [NeZero n] : OfNat ℕ+ n := ⟨⟨n, Nat.pos_of_ne_zero <| NeZero.ne n⟩⟩ +namespace PNat + @[simp] lemma mk_one : PNat.mk 1 Nat.zero_lt_one = (1 : ℕ+) := rfl @@ -50,3 +52,5 @@ lemma val_one : (1 : ℕ+).val = 1 := @[simp] theorem mk_coe (n h) : (PNat.val (⟨n, h⟩ : ℕ+) : ℕ) = n := rfl + +end PNat From 7c52096e62d6089fa8b718e27f16dd27a4e703df Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 17:16:29 -0400 Subject: [PATCH 058/127] order lemmas and nonneg instances --- .../Algebra/Order/GroupWithZero/Basic.lean | 16 ++++++++ .../Algebra/Order/Monoid/Unbundled/Pow.lean | 26 ++++++++++++ Mathlib/Algebra/Order/Nonneg/Basic.lean | 41 +++++++++++++++++-- 3 files changed, 80 insertions(+), 3 deletions(-) diff --git a/Mathlib/Algebra/Order/GroupWithZero/Basic.lean b/Mathlib/Algebra/Order/GroupWithZero/Basic.lean index 34f7f229762b97..385616e2ac72b0 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Basic.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Basic.lean @@ -367,6 +367,22 @@ lemma MonotoneOn.mul [PosMulMono M₀] [MulPosMono M₀] {s : Set α} (hf : Mono end MulZero +section SemigroupWithZero +variable [SemigroupWithZero M₀] +variable [Preorder M₀] {a b : M₀} + +@[simp] lemma ppow_nonneg [PosMulMono M₀] (n : ℕ+) (ha : 0 ≤ a) : 0 ≤ a ^ n := by + rcases n with ⟨n, hn⟩ + simp only [← Semigroup.ppow_eq_pow, PNat.mk_coe] + obtain ⟨k, rfl⟩ := Nat.exists_eq_succ_of_ne_zero hn.ne' + induction k with + | zero => simp [Semigroup.ppow_one, ha] + | succ k IH => + rw [Semigroup.ppow_succ] + exact mul_nonneg ha (IH Nat.succ_pos') + +end SemigroupWithZero + section MonoidWithZero variable [MonoidWithZero M₀] diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean index a4dcd4ab0cb008..bc0b9d39407205 100644 --- a/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean @@ -7,6 +7,7 @@ module public import Mathlib.Algebra.Order.Monoid.Unbundled.Basic public import Mathlib.Algebra.Order.Monoid.Unbundled.OrderDual +public import Mathlib.Algebra.Group.PPow.Defs public import Mathlib.Tactic.Lift public import Mathlib.Tactic.Monotonicity.Attr @@ -32,6 +33,28 @@ namespace Left variable [MulLeftMono M] {a : M} +@[to_additive Left.psmul_nonneg] +theorem one_le_ppow_of_le (ha : 1 ≤ a) (n : ℕ+) : 1 ≤ a ^ n := by + rcases n with ⟨n, hn⟩ + simp only [← Semigroup.ppow_eq_pow, PNat.mk_coe] + obtain ⟨k, rfl⟩ := Nat.exists_eq_succ_of_ne_zero hn.ne' + induction k with + | zero => simp [Semigroup.ppow_one, ha] + | succ k IH => + rw [Semigroup.ppow_succ] + exact one_le_mul ha (IH Nat.succ_pos') + +@[to_additive psmul_nonpos] +theorem ppow_le_one_of_le (ha : a ≤ 1) (n : ℕ+) : a ^ n ≤ 1 := one_le_ppow_of_le (M := Mᵒᵈ) ha n + +@[to_additive psmul_neg] +theorem ppow_lt_one_of_lt {a : M} (n : ℕ+) (h : a < 1) : a ^ n < 1 := by + rcases n with ⟨n, hn⟩ + obtain ⟨_|k, rfl⟩ := Nat.exists_eq_succ_of_ne_zero hn.ne' + · simp [h] + · simp only [Nat.succ_eq_add_one, ← Semigroup.ppow_eq_pow, PNat.mk_coe, Semigroup.ppow_succ] + refine mul_lt_one_of_lt_of_le h (ppow_le_one_of_le h.le ⟨k + 1, Nat.succ_pos k⟩) + @[to_additive Left.nsmul_nonneg] theorem one_le_pow_of_le (ha : 1 ≤ a) : ∀ n : ℕ, 1 ≤ a ^ n | 0 => by simp @@ -50,6 +73,9 @@ theorem pow_lt_one_of_lt {a : M} {n : ℕ} (h : a < 1) (hn : n ≠ 0) : a ^ n < end Left +@[to_additive psmul_nonneg] alias one_le_ppow_of_one_le' := Left.one_le_ppow_of_le +@[to_additive psmul_nonpos] alias ppow_le_one' := Left.ppow_le_one_of_le +@[to_additive psmul_neg] alias ppow_lt_one' := Left.ppow_lt_one_of_lt @[to_additive nsmul_nonneg] alias one_le_pow_of_one_le' := Left.one_le_pow_of_le @[to_additive nsmul_nonpos] alias pow_le_one' := Left.pow_le_one_of_le @[to_additive nsmul_neg] alias pow_lt_one' := Left.pow_lt_one_of_lt diff --git a/Mathlib/Algebra/Order/Nonneg/Basic.lean b/Mathlib/Algebra/Order/Nonneg/Basic.lean index f7915045096ce2..67cc1d2625ccab 100644 --- a/Mathlib/Algebra/Order/Nonneg/Basic.lean +++ b/Mathlib/Algebra/Order/Nonneg/Basic.lean @@ -85,6 +85,19 @@ instance [AddZeroClass α] [Preorder α] [AddLeftMono α] [IsRightCancelAdd α] instance [AddZeroClass α] [Preorder α] [AddLeftMono α] [IsCancelAdd α] : IsCancelAdd { x : α // 0 ≤ x } where +instance psmul [AddMonoid α] [Preorder α] [AddLeftMono α] : SMul ℕ+ { x : α // 0 ≤ x } := + ⟨fun n x => ⟨n • (x : α), psmul_nonneg x.prop n⟩⟩ + +@[simp] +theorem psmul_mk [AddMonoid α] [Preorder α] [AddLeftMono α] (n : ℕ+) {x : α} + (hx : 0 ≤ x) : (n • (⟨x, hx⟩ : { x : α // 0 ≤ x })) = ⟨n • x, psmul_nonneg hx n⟩ := + rfl + +@[simp, norm_cast] +protected theorem coe_psmul [AddMonoid α] [Preorder α] [AddLeftMono α] + (n : ℕ+) (a : { x : α // 0 ≤ x }) : ((n • a : { x : α // 0 ≤ x }) : α) = n • (a : α) := + rfl + instance nsmul [AddMonoid α] [Preorder α] [AddLeftMono α] : SMul ℕ { x : α // 0 ≤ x } := ⟨fun n x => ⟨n • (x : α), nsmul_nonneg x.prop n⟩⟩ @@ -140,7 +153,8 @@ section AddMonoid variable [AddMonoid α] [Preorder α] [AddLeftMono α] instance addMonoid : AddMonoid { x : α // 0 ≤ x } := - fast_instance% Subtype.coe_injective.addMonoid _ Nonneg.coe_zero (fun _ _ => rfl) fun _ _ => rfl + fast_instance% Subtype.coe_injective.addMonoid _ Nonneg.coe_zero (fun _ _ => rfl) + (fun _ _ => rfl) fun _ _ => rfl /-- Coercion `{x : α // 0 ≤ x} → α` as an `AddMonoidHom`. -/ @[simps] @@ -163,6 +177,7 @@ variable [AddCommMonoid α] [Preorder α] [AddLeftMono α] instance addCommMonoid : AddCommMonoid { x : α // 0 ≤ x } := fast_instance% Subtype.coe_injective.addCommMonoid _ Nonneg.coe_zero (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) end AddCommMonoid @@ -172,6 +187,7 @@ variable [AddCancelCommMonoid α] [Preorder α] [AddLeftMono α] instance addCancelCommMonoid : AddCancelCommMonoid {x : α // 0 ≤ x} := fast_instance% Subtype.coe_injective.addCancelCommMonoid _ Nonneg.coe_zero (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) end AddCancelCommMonoid @@ -198,6 +214,25 @@ instance addMonoidWithOne : AddMonoidWithOne { x : α // 0 ≤ x } := end AddMonoidWithOne +section PPow + +variable [SemigroupWithZero α] [Preorder α] [PosMulMono α] + +instance ppow : Pow { x : α // 0 ≤ x } ℕ+ where + pow x n := ⟨(x : α) ^ n, ppow_nonneg _ x.2⟩ + +@[simp, norm_cast] +protected theorem coe_ppow (a : { x : α // 0 ≤ x }) (n : ℕ+) : + (↑(a ^ n) : α) = (a : α) ^ n := + rfl + +@[simp] +theorem mk_ppow {x : α} (hx : 0 ≤ x) (n : ℕ+) : + (⟨x, hx⟩ : { x : α // 0 ≤ x }) ^ n = ⟨x ^ n, ppow_nonneg _ hx⟩ := + rfl + +end PPow + section Pow variable [MonoidWithZero α] [Preorder α] [ZeroLEOneClass α] [PosMulMono α] @@ -224,7 +259,7 @@ variable [Semiring α] [PartialOrder α] [ZeroLEOneClass α] instance semiring : Semiring { x : α // 0 ≤ x } := fast_instance% Subtype.coe_injective.semiring _ Nonneg.coe_zero Nonneg.coe_one - (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl instance monoidWithZero : MonoidWithZero { x : α // 0 ≤ x } := by infer_instance @@ -246,7 +281,7 @@ variable [CommSemiring α] [PartialOrder α] [ZeroLEOneClass α] instance commSemiring : CommSemiring { x : α // 0 ≤ x } := fast_instance% Subtype.coe_injective.commSemiring _ Nonneg.coe_zero Nonneg.coe_one - (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl instance commMonoidWithZero : CommMonoidWithZero { x : α // 0 ≤ x } := inferInstance From 085189aa96f599587215a6b6d57cbe77902b86e4 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 17:17:30 -0400 Subject: [PATCH 059/127] remove dupl lemma --- Mathlib/Data/PNat/Defs.lean | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Mathlib/Data/PNat/Defs.lean b/Mathlib/Data/PNat/Defs.lean index 9a30f1a3714462..e187a2bf4a5d5f 100644 --- a/Mathlib/Data/PNat/Defs.lean +++ b/Mathlib/Data/PNat/Defs.lean @@ -132,10 +132,6 @@ instance : Inhabited ℕ+ := ⟨1⟩ -- Some lemmas that rewrite `PNat.mk n h`, for `n` an explicit numeral, into explicit numerals. -@[simp] -theorem mk_one {h} : (⟨1, h⟩ : ℕ+) = (1 : ℕ+) := - rfl - @[norm_cast] theorem one_coe : ((1 : ℕ+) : ℕ) = 1 := rfl From 5e3055fa9207b1b0b8ad78dbd2615f69f486e4c4 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 17:22:05 -0400 Subject: [PATCH 060/127] fix field args --- Mathlib/Algebra/Field/Basic.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Field/Basic.lean b/Mathlib/Algebra/Field/Basic.lean index bca5483fdaf845..d3f23d5551fa38 100644 --- a/Mathlib/Algebra/Field/Basic.lean +++ b/Mathlib/Algebra/Field/Basic.lean @@ -233,7 +233,7 @@ variable [Zero K] [Add K] [Neg K] [Sub K] [One K] [Mul K] [Inv K] [Div K] [SMul protected abbrev divisionSemiring [DivisionSemiring L] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) (div : ∀ x y, f (x / y) = f x / f y) - (psmul : ∀ x (n : ℕ+), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (nnqsmul : ∀ (q : ℚ≥0) (x), f (q • x) = q • f x) (ppow : ∀ (x) (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) (nnratCast : ∀ q : ℚ≥0, f q = q) : DivisionSemiring K where @@ -248,7 +248,7 @@ protected abbrev divisionSemiring [DivisionSemiring L] (zero : f 0 = 0) (one : f protected abbrev divisionRing [DivisionRing L] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) - (div : ∀ x y, f (x / y) = f x / f y) (psmul : ∀ x (n : ℕ+), f (n • x) = n • f x) + (div : ∀ x y, f (x / y) = f x / f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (nnqsmul : ∀ (q : ℚ≥0) (x), f (q • x) = q • f x) (qsmul : ∀ (q : ℚ) (x), f (q • x) = q • f x) (ppow : ∀ (x) (n : ℕ+), f (x ^ n) = f x ^ n) @@ -268,7 +268,7 @@ protected abbrev divisionRing [DivisionRing L] (zero : f 0 = 0) (one : f 1 = 1) protected abbrev semifield [Semifield L] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) (div : ∀ x y, f (x / y) = f x / f y) - (psmul : ∀ x (n : ℕ+), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) + (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (nnqsmul : ∀ (q : ℚ≥0) (x), f (q • x) = q • f x) (ppow : ∀ (x) (n : ℕ+), f (x ^ n) = f x ^ n) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) (natCast : ∀ n : ℕ, f n = n) (nnratCast : ∀ q : ℚ≥0, f q = q) : Semifield K where @@ -282,7 +282,7 @@ protected abbrev semifield [Semifield L] (zero : f 0 = 0) (one : f 1 = 1) protected abbrev field [Field L] (zero : f 0 = 0) (one : f 1 = 1) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) (sub : ∀ x y, f (x - y) = f x - f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) - (div : ∀ x y, f (x / y) = f x / f y) (psmul : ∀ x (n : ℕ+), f (n • x) = n • f x) + (div : ∀ x y, f (x / y) = f x / f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (nnqsmul : ∀ (q : ℚ≥0) (x), f (q • x) = q • f x) (qsmul : ∀ (q : ℚ) (x), f (q • x) = q • f x) (ppow : ∀ (x) (n : ℕ+), f (x ^ n) = f x ^ n) From 61914bf3e9bba5da1176450b9cbf9b2058190fef Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 17:22:27 -0400 Subject: [PATCH 061/127] fix lemma rename --- Mathlib/Algebra/Order/Positive/Ring.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Order/Positive/Ring.lean b/Mathlib/Algebra/Order/Positive/Ring.lean index d9c1787276a1f8..deb979335d0e1c 100644 --- a/Mathlib/Algebra/Order/Positive/Ring.lean +++ b/Mathlib/Algebra/Order/Positive/Ring.lean @@ -40,7 +40,7 @@ theorem coe_add (x y : { x : M // 0 < x }) : ↑(x + y) = (x + y : M) := instance : SMul ℕ+ { x : M // 0 < x } := ⟨fun n x => ⟨n • (x : M), by rcases n with ⟨n, h⟩ - simp only [← nsmul_val_eq_psmul, mk_coe] + simp only [← nsmul_val_eq_psmul, PNat.mk_coe] induction n with | zero => exact absurd h (by decide) | succ n IH => From fd4f64bce7f03118b5ac9ef678f353f64e4a7041 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 17:25:32 -0400 Subject: [PATCH 062/127] nonunitalsubsemiring --- Mathlib/RingTheory/NonUnitalSubsemiring/Defs.lean | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Mathlib/RingTheory/NonUnitalSubsemiring/Defs.lean b/Mathlib/RingTheory/NonUnitalSubsemiring/Defs.lean index d57e4ce0d91024..8d8c4d5a397c19 100644 --- a/Mathlib/RingTheory/NonUnitalSubsemiring/Defs.lean +++ b/Mathlib/RingTheory/NonUnitalSubsemiring/Defs.lean @@ -73,7 +73,7 @@ open AddSubmonoidClass instance (priority := 75) toNonUnitalNonAssocSemiring : NonUnitalNonAssocSemiring s := fast_instance% Subtype.coe_injective.nonUnitalNonAssocSemiring Subtype.val rfl (by simp) (fun _ _ => rfl) - fun _ _ => rfl + (fun _ _ => rfl) fun _ _ => rfl /- Prefer subclasses of `NonUnitalNonAssocCommSemiring` over subclasses of `NonUnitalSubsemiringClass`. -/ @@ -83,7 +83,7 @@ instance (priority := 75) toNonUnitalNonAssocCommSemiring {R} [NonUnitalNonAssoc [SetLike S R] [NonUnitalSubsemiringClass S R] : NonUnitalNonAssocCommSemiring s := fast_instance% Subtype.coe_injective.nonUnitalNonAssocCommSemiring Subtype.val rfl (by simp) (fun _ _ => rfl) - fun _ _ => rfl + (fun _ _ => rfl) fun _ _ => rfl instance noZeroDivisors [NoZeroDivisors R] : NoZeroDivisors s := Subtype.coe_injective.noZeroDivisors Subtype.val rfl fun _ _ => rfl @@ -108,13 +108,14 @@ theorem coe_subtype : (subtype s : s → R) = ((↑) : s → R) := /-- A non-unital subsemiring of a `NonUnitalSemiring` is a `NonUnitalSemiring`. -/ instance toNonUnitalSemiring {R} [NonUnitalSemiring R] [SetLike S R] [NonUnitalSubsemiringClass S R] : NonUnitalSemiring s := fast_instance% - Subtype.coe_injective.nonUnitalSemiring Subtype.val rfl (by simp) (fun _ _ => rfl) fun _ _ => rfl + Subtype.coe_injective.nonUnitalSemiring Subtype.val rfl (by simp) (fun _ _ => rfl) + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl /-- A non-unital subsemiring of a `NonUnitalCommSemiring` is a `NonUnitalCommSemiring`. -/ instance toNonUnitalCommSemiring {R} [NonUnitalCommSemiring R] [SetLike S R] [NonUnitalSubsemiringClass S R] : NonUnitalCommSemiring s := fast_instance% Subtype.coe_injective.nonUnitalCommSemiring Subtype.val rfl (by simp) (fun _ _ => rfl) - fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl /-! Note: currently, there are no ordered versions of non-unital rings. -/ From 94edf05731f1c104d7271989a2da39cdef1371da Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 17:30:33 -0400 Subject: [PATCH 063/127] subsemiring --- Mathlib/Algebra/Ring/Subsemiring/Defs.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Ring/Subsemiring/Defs.lean b/Mathlib/Algebra/Ring/Subsemiring/Defs.lean index 34f225d4096fd6..57682e80e192fb 100644 --- a/Mathlib/Algebra/Ring/Subsemiring/Defs.lean +++ b/Mathlib/Algebra/Ring/Subsemiring/Defs.lean @@ -76,13 +76,13 @@ namespace SubsemiringClass /-- A subsemiring of a `NonAssocSemiring` inherits a `NonAssocSemiring` structure -/ instance (priority := 75) toNonAssocSemiring : NonAssocSemiring s := fast_instance% Subtype.coe_injective.nonAssocSemiring Subtype.val rfl rfl (fun _ _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) fun _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl /-- A subsemiring of a `NonAssocCommSemiring` inherits a `NonAssocCommSemiring` structure -/ instance (priority := 75) toNonAssocCommSemiring {R} [NonAssocCommSemiring R] [SetLike S R] [SubsemiringClass S R] : NonAssocCommSemiring s := fast_instance% Subtype.coe_injective.nonAssocCommSemiring Subtype.val rfl rfl (fun _ _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) fun _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl instance nontrivial [Nontrivial R] : Nontrivial s := nontrivial_of_ne 0 1 fun H => zero_ne_one (congr_arg Subtype.val H) @@ -112,13 +112,13 @@ lemma subtype_injective : instance (priority := 75) toSemiring {R} [Semiring R] [SetLike S R] [SubsemiringClass S R] : Semiring s := fast_instance% Subtype.coe_injective.semiring Subtype.val rfl rfl (fun _ _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl /-- A subsemiring of a `CommSemiring` is a `CommSemiring`. -/ instance toCommSemiring {R} [CommSemiring R] [SetLike S R] [SubsemiringClass S R] : CommSemiring s := fast_instance% Subtype.coe_injective.commSemiring Subtype.val rfl rfl (fun _ _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl end SubsemiringClass From 6277243b282c41150a8ca4533747e6248c91868a Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 17:32:50 -0400 Subject: [PATCH 064/127] nonunitalsubring --- Mathlib/RingTheory/NonUnitalSubring/Defs.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/RingTheory/NonUnitalSubring/Defs.lean b/Mathlib/RingTheory/NonUnitalSubring/Defs.lean index 9db14ca946f22b..48a0294f5b6c69 100644 --- a/Mathlib/RingTheory/NonUnitalSubring/Defs.lean +++ b/Mathlib/RingTheory/NonUnitalSubring/Defs.lean @@ -68,14 +68,14 @@ namespace NonUnitalSubringClass /-- A non-unital subring of a non-unital ring inherits a non-unital ring structure -/ instance (priority := 75) toNonUnitalNonAssocRing : NonUnitalNonAssocRing s := fast_instance% Subtype.val_injective.nonUnitalNonAssocRing _ rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) - (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl -- Prefer subclasses of `NonUnitalRing` over subclasses of `NonUnitalSubringClass`. /-- A non-unital subring of a non-unital ring inherits a non-unital ring structure -/ instance (priority := 75) toNonUnitalRing {R : Type*} [NonUnitalRing R] [SetLike S R] [NonUnitalSubringClass S R] (s : S) : NonUnitalRing s := fast_instance% Subtype.val_injective.nonUnitalRing _ rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) - (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl -- Prefer subclasses of `NonUnitalRing` over subclasses of `NonUnitalSubringClass`. /-- A non-unital subring of a `NonUnitalNonAssocCommRing` is a `NonUnitalNonAssocCommRing`. -/ @@ -83,14 +83,14 @@ instance (priority := 75) toNonUnitalNonAssocCommRing {R} [NonUnitalNonAssocComm [SetLike S R] [NonUnitalSubringClass S R] (s : S) : NonUnitalNonAssocCommRing s := fast_instance% Subtype.val_injective.nonUnitalNonAssocCommRing _ rfl (fun _ _ => rfl) (fun _ _ => rfl) - (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl + (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl -- Prefer subclasses of `NonUnitalRing` over subclasses of `NonUnitalSubringClass`. /-- A non-unital subring of a `NonUnitalCommRing` is a `NonUnitalCommRing`. -/ instance (priority := 75) toNonUnitalCommRing {R} [NonUnitalCommRing R] [SetLike S R] [NonUnitalSubringClass S R] : NonUnitalCommRing s := fast_instance% Subtype.val_injective.nonUnitalCommRing _ rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) - (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl /-- The natural non-unital ring hom from a non-unital subring of a non-unital ring `R` to `R`. -/ def subtype (s : S) : s →ₙ+* R := From c7dd30b0666a0bc3d6c3a680f4c1c1cf2f673bac Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 17:34:23 -0400 Subject: [PATCH 065/127] nonneg semifield -- no coe_ lemmas, it is rfl --- Mathlib/Algebra/Order/Nonneg/Field.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Order/Nonneg/Field.lean b/Mathlib/Algebra/Order/Nonneg/Field.lean index 3e1f5c8136cdfb..dd048c81294b4a 100644 --- a/Mathlib/Algebra/Order/Nonneg/Field.lean +++ b/Mathlib/Algebra/Order/Nonneg/Field.lean @@ -109,8 +109,8 @@ instance instNNRatSMul : SMul ℚ≥0 {x : α // 0 ≤ x} where instance semifield : Semifield { x : α // 0 ≤ x } := fast_instance% Subtype.coe_injective.semifield _ Nonneg.coe_zero Nonneg.coe_one Nonneg.coe_add - Nonneg.coe_mul Nonneg.coe_inv Nonneg.coe_div (fun _ _ => rfl) coe_nnqsmul Nonneg.coe_pow - Nonneg.coe_zpow Nonneg.coe_natCast coe_nnratCast + Nonneg.coe_mul Nonneg.coe_inv Nonneg.coe_div (fun _ _ => rfl) (fun _ _ => rfl) + coe_nnqsmul (fun _ _ => rfl) Nonneg.coe_pow Nonneg.coe_zpow Nonneg.coe_natCast coe_nnratCast end LinearOrderedSemifield From 803dd8e569a8d89357e32f7d644e00c957b422dc Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 17:36:55 -0400 Subject: [PATCH 066/127] subring --- Mathlib/Algebra/Ring/Subring/Defs.lean | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Mathlib/Algebra/Ring/Subring/Defs.lean b/Mathlib/Algebra/Ring/Subring/Defs.lean index f9df568ccb0b4f..7271e255f5f494 100644 --- a/Mathlib/Algebra/Ring/Subring/Defs.lean +++ b/Mathlib/Algebra/Ring/Subring/Defs.lean @@ -100,22 +100,24 @@ instance (priority := 75) toHasIntCast : IntCast s := /-- A subring of a non-unital ring inherits a non-unital ring structure -/ instance (priority := 75) toNonAssocRing (s : S) : NonAssocRing s := fast_instance% Subtype.coe_injective.nonAssocRing Subtype.val 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 _ => rfl) fun _ => rfl -- Prefer subclasses of `Ring` over subclasses of `SubringClass`. /-- A subring of a ring inherits a ring structure -/ instance (priority := 75) toRing {R} [Ring R] [SetLike S R] [SubringClass S R] : Ring s := fast_instance% Subtype.coe_injective.ring Subtype.val 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 _ _ => rfl) + (fun _ _ => rfl) (fun _ => rfl) fun _ => rfl -- Prefer subclasses of `Ring` over subclasses of `SubringClass`. /-- A subring of a `NonAssocCommRing` is a `NonAssocCommRing`. -/ instance (priority := 75) toNonAssocCommRing {R} [NonAssocCommRing R] [SetLike S R] [SubringClass S R] : NonAssocCommRing s := fast_instance% Subtype.coe_injective.nonAssocCommRing Subtype.val 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 _ => rfl) fun _ => rfl -- Prefer subclasses of `Ring` over subclasses of `SubringClass`. /-- A subring of a `CommRing` is a `CommRing`. -/ @@ -123,7 +125,7 @@ instance (priority := 75) toCommRing {R} [CommRing R] [SetLike S R] [SubringClas CommRing s := fast_instance% Subtype.coe_injective.commRing Subtype.val 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 -- Prefer subclasses of `Ring` over subclasses of `SubringClass`. /-- A subring of a domain is a domain. -/ From 6c4fa252a721895477c4415a1ea1785cb3926657 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 17:47:44 -0400 Subject: [PATCH 067/127] reduce imports --- Mathlib/GroupTheory/Congruence/Defs.lean | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Mathlib/GroupTheory/Congruence/Defs.lean b/Mathlib/GroupTheory/Congruence/Defs.lean index a5efab5a751438..3d65aa26d33b80 100644 --- a/Mathlib/GroupTheory/Congruence/Defs.lean +++ b/Mathlib/GroupTheory/Congruence/Defs.lean @@ -6,10 +6,10 @@ Authors: Amelia Livingston module public import Mathlib.Algebra.Group.InjSurj -public import Mathlib.Algebra.Group.PPow.Basic public import Mathlib.Algebra.Group.Units.Defs public import Mathlib.Data.Setoid.Basic public import Mathlib.Tactic.FastInstance +import Mathlib.Algebra.Group.PPow.Defs import Mathlib.Order.GaloisConnection.Basic /-! @@ -569,9 +569,14 @@ section Monoids @[to_additive /-- Additive congruence relations preserve positive natural scaling. -/] protected theorem ppow {M : Type*} [Semigroup M] (c : Con M) (n : ℕ+) {w x} (h : c w x) : c (w ^ n) (x ^ n) := by - induction n - · simpa - · simpa [ppow_succ] using c.mul ‹_› h + rcases n with ⟨n, hn⟩ + simp only [← Semigroup.ppow_eq_pow, PNat.mk_coe] + obtain ⟨k, rfl⟩ := Nat.exists_eq_succ_of_ne_zero hn.ne' + induction k with + | zero => simp [Semigroup.ppow_one, h] + | succ k IH => + rw [Semigroup.ppow_succ, Semigroup.ppow_succ] + exact c.mul h (IH Nat.succ_pos') @[to_additive] instance {M : Type*} [Semigroup M] (c : Con M) : Pow c.Quotient ℕ+ where From c10022294d87c8f3bf554736e1f5c3b8cc50becf Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 18:12:22 -0400 Subject: [PATCH 068/127] ppow_succ' in nasty nat form --- Mathlib/Algebra/Group/Defs.lean | 6 ++++++ Mathlib/Algebra/Group/PPow/Basic.lean | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Group/Defs.lean b/Mathlib/Algebra/Group/Defs.lean index cb94b93605417a..534bf57536dda9 100644 --- a/Mathlib/Algebra/Group/Defs.lean +++ b/Mathlib/Algebra/Group/Defs.lean @@ -229,6 +229,12 @@ variable [Semigroup G] theorem mul_assoc : ∀ a b c : G, a * b * c = a * (b * c) := Semigroup.mul_assoc +@[to_additive Semigroup.succ_psmul'] +lemma Semigroup.ppow_succ' (a : G) : ∀ n : ℕ, + Semigroup.ppow (n + 2) (Nat.succ_pos (n + 1)) a = Semigroup.ppow (n + 1) (Nat.succ_pos n) a * a + | .zero => by rw [Semigroup.ppow_succ, Semigroup.ppow_one] + | .succ n => by rw [Semigroup.ppow_succ _ n, Semigroup.ppow_succ, Semigroup.ppow_succ', mul_assoc] + end Semigroup section IsCommutative diff --git a/Mathlib/Algebra/Group/PPow/Basic.lean b/Mathlib/Algebra/Group/PPow/Basic.lean index c658c264496aad..ccd52e1af528d1 100644 --- a/Mathlib/Algebra/Group/PPow/Basic.lean +++ b/Mathlib/Algebra/Group/PPow/Basic.lean @@ -26,7 +26,7 @@ lemma ppow_succ' (x : M) (n : ℕ+) : x ^ (n + 1) = x * x ^ n := @[to_additive succ_psmul] lemma ppow_succ (x : M) (n : ℕ+) : x ^ (n + 1) = x ^ n * x := - n.recOn (by simp [ppow_succ']) fun k hk => by rw [ppow_succ' x k, ppow_succ', hk, mul_assoc] + n.recOn (Semigroup.ppow_succ' x 0) fun k _ => Semigroup.ppow_succ' x k @[to_additive add_psmul] lemma ppow_add (x : M) (n m : ℕ+) : x ^ (n + m) = x ^ n * x ^ m := From ec8eff0e16131c1663b6ea1146552d5dee0a51fa Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 18:16:56 -0400 Subject: [PATCH 069/127] mul opposite ppow --- Mathlib/Algebra/Group/Opposite.lean | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Mathlib/Algebra/Group/Opposite.lean b/Mathlib/Algebra/Group/Opposite.lean index beda24ce7b2622..e73ef8be7e99e7 100644 --- a/Mathlib/Algebra/Group/Opposite.lean +++ b/Mathlib/Algebra/Group/Opposite.lean @@ -6,6 +6,7 @@ Authors: Kenny Lau module public import Mathlib.Algebra.Group.Commute.Defs +public import Mathlib.Algebra.Group.PPow.Defs public import Mathlib.Algebra.Group.InjSurj public import Mathlib.Algebra.Group.Torsion public import Mathlib.Algebra.Opposites @@ -82,6 +83,9 @@ instance instIsLeftCancelMul [Mul α] [IsRightCancelMul α] : IsLeftCancelMul α @[to_additive] instance instSemigroup [Semigroup α] : Semigroup αᵐᵒᵖ where mul_assoc x y z := unop_injective <| Eq.symm <| mul_assoc (unop z) (unop y) (unop x) + ppow n hn a := op <| a.unop ^ PNat.mk n hn + ppow_one _ := unop_injective <| Semigroup.ppow_one _ + ppow_succ _ _ := unop_injective <| Semigroup.ppow_succ' _ _ @[to_additive] instance instLeftCancelSemigroup [RightCancelSemigroup α] : LeftCancelSemigroup αᵐᵒᵖ where @@ -167,6 +171,15 @@ instance instCommGroup [CommGroup α] : CommGroup αᵐᵒᵖ where toGroup := instGroup __ := instCommSemigroup +section Semigroup +variable [Semigroup α] + +@[to_additive (attr := simp)] lemma op_ppow (x : α) (n : ℕ+) : op (x ^ n) = op x ^ n := rfl + +@[to_additive (attr := simp)] lemma unop_ppow (x : αᵐᵒᵖ) (n : ℕ+) : unop (x ^ n) = unop x ^ n := rfl + +end Semigroup + section Monoid variable [Monoid α] From 2bef2f1db1f174cf517f483b672d1274ee965bb9 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 18:17:03 -0400 Subject: [PATCH 070/127] MulHom.map_ppow --- Mathlib/Algebra/Group/Hom/Defs.lean | 12 +++++++++++- Mathlib/Algebra/Group/PPow/Basic.lean | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Group/Hom/Defs.lean b/Mathlib/Algebra/Group/Hom/Defs.lean index ab1fcb1515dab3..59a91d4c98ae38 100644 --- a/Mathlib/Algebra/Group/Hom/Defs.lean +++ b/Mathlib/Algebra/Group/Hom/Defs.lean @@ -6,7 +6,7 @@ Authors: Patrick Massot, Kevin Buzzard, Kim Morrison, Johan Commelin, Chris Hugh -/ module -public import Mathlib.Algebra.Group.Defs +public import Mathlib.Algebra.Group.PPow.Defs public import Mathlib.Algebra.Notation.Pi.Defs public import Mathlib.Data.FunLike.Basic public import Mathlib.Logic.Function.Iterate @@ -679,6 +679,16 @@ protected theorem MonoidHom.map_one [MulOne M] [MulOne N] (f : M →* N) : f 1 = protected theorem MulHom.map_mul [Mul M] [Mul N] (f : M →ₙ* N) (a b : M) : f (a * b) = f a * f b := f.map_mul' a b +@[to_additive] +protected theorem MulHom.map_ppow {M N : Type*} [Semigroup M] [Semigroup N] (f : M →ₙ* N) (a : M) + (n : ℕ+) : f (a ^ n) = f a ^ n := by + rcases n with ⟨n, hn⟩ + simp only [← Semigroup.ppow_eq_pow, PNat.mk_coe] + obtain ⟨k, rfl⟩ := Nat.exists_eq_succ_of_ne_zero (Nat.pos_iff_ne_zero.1 hn) + induction k with + | zero => simp only [Semigroup.ppow_one] + | succ k IH => simp only [Semigroup.ppow_succ, MulHom.map_mul, IH (Nat.succ_pos _)] + /-- If `f` is a monoid homomorphism then `f (a * b) = f a * f b`. -/ @[to_additive /-- If `f` is an additive monoid homomorphism then `f (a + b) = f a + f b`. -/] protected theorem MonoidHom.map_mul [MulOne M] [MulOne N] (f : M →* N) (a b : M) : diff --git a/Mathlib/Algebra/Group/PPow/Basic.lean b/Mathlib/Algebra/Group/PPow/Basic.lean index ccd52e1af528d1..a8abb95b16bd60 100644 --- a/Mathlib/Algebra/Group/PPow/Basic.lean +++ b/Mathlib/Algebra/Group/PPow/Basic.lean @@ -90,4 +90,4 @@ theorem pow_mul_comm'' [Monoid M] (a : M) (n : ℕ+) : a ^ n * a = a * a ^ n := @[to_additive] lemma map_ppow {F M N : Type _} [Semigroup M] [Semigroup N] [FunLike F M N] [MulHomClass F M N] (f : F) (x : M) (n : ℕ+) : f (x ^ n) = f x ^ n := - n.recOn (by simp) fun k hk => by simp [ppow_succ, hk] + MulHom.map_ppow (MulHomClass.toMulHom f) _ _ From 61c87a99ef23deb05154bd7438611c85336d9cc4 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 18:28:40 -0400 Subject: [PATCH 071/127] coe_ppow --- Mathlib/Algebra/Group/Subgroup/Defs.lean | 4 ++++ Mathlib/Algebra/Group/Subsemigroup/Defs.lean | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/Mathlib/Algebra/Group/Subgroup/Defs.lean b/Mathlib/Algebra/Group/Subgroup/Defs.lean index 3c809255e7a5b6..8b209a2a75b1c0 100644 --- a/Mathlib/Algebra/Group/Subgroup/Defs.lean +++ b/Mathlib/Algebra/Group/Subgroup/Defs.lean @@ -536,6 +536,10 @@ theorem coe_div (x y : H) : (↑(x / y) : G) = ↑x / ↑y := theorem coe_mk (x : G) (hx : x ∈ H) : ((⟨x, hx⟩ : H) : G) = x := rfl +@[to_additive (attr := simp, norm_cast)] +theorem coe_ppow (x : H) (n : ℕ+) : ((x ^ n : H) : G) = (x : G) ^ n := + rfl + @[to_additive (attr := simp, norm_cast)] theorem coe_pow (x : H) (n : ℕ) : ((x ^ n : H) : G) = (x : G) ^ n := rfl diff --git a/Mathlib/Algebra/Group/Subsemigroup/Defs.lean b/Mathlib/Algebra/Group/Subsemigroup/Defs.lean index b3536667bd2aec..30777081061f2e 100644 --- a/Mathlib/Algebra/Group/Subsemigroup/Defs.lean +++ b/Mathlib/Algebra/Group/Subsemigroup/Defs.lean @@ -299,6 +299,11 @@ instance (priority := 900) {M A : Type*} [Semigroup M] [SetLike A M] [hA : MulMe {S' : A} : Pow S' ℕ+ := ⟨fun x n => ⟨x.1 ^ n, ppow_coe_mem _ _⟩⟩ +@[to_additive (attr := simp low, norm_cast)] +theorem coe_ppow {M A : Type*} [Semigroup M] [SetLike A M] [hA : MulMemClass A M] {S' : A} + (x : S') (n : ℕ+) : ((x ^ n : S') : M) = (x : M) ^ n := + rfl + /-- A subsemigroup of a semigroup inherits a semigroup structure. -/ @[to_additive /-- An `AddSubsemigroup` of an `AddSemigroup` inherits an `AddSemigroup` structure. -/] From 1c0237b375ff381a10aa21da11aee7364df1d904 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 18:29:08 -0400 Subject: [PATCH 072/127] star and self adjoint --- Mathlib/Algebra/Star/Basic.lean | 5 +++++ Mathlib/Algebra/Star/SelfAdjoint.lean | 24 +++++++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/Mathlib/Algebra/Star/Basic.lean b/Mathlib/Algebra/Star/Basic.lean index f37f1dc5d07931..4bc6091d87f45f 100644 --- a/Mathlib/Algebra/Star/Basic.lean +++ b/Mathlib/Algebra/Star/Basic.lean @@ -189,6 +189,11 @@ lemma Pi.star_mulSingle {ι : Type*} {R : ι → Type*} [DecidableEq ι] [∀ i, [∀ i, StarMul (R i)] (i : ι) (r : R i) : star (mulSingle i r) = mulSingle i (star r) := by ext; exact apply_mulSingle (fun _ ↦ star) (fun _ ↦ star_one _) .. +@[simp] +theorem star_ppow [Semigroup R] [StarMul R] (x : R) (n : ℕ+) : star (x ^ n) = star x ^ n := + op_injective <| + ((starMulEquiv : R ≃* Rᵐᵒᵖ).toMulHom.map_ppow x n).trans (op_ppow (star x) n).symm + @[simp] theorem star_pow [Monoid R] [StarMul R] (x : R) (n : ℕ) : star (x ^ n) = star x ^ n := op_injective <| diff --git a/Mathlib/Algebra/Star/SelfAdjoint.lean b/Mathlib/Algebra/Star/SelfAdjoint.lean index fce5c46c8fbebe..aad9aee38bbdfe 100644 --- a/Mathlib/Algebra/Star/SelfAdjoint.lean +++ b/Mathlib/Algebra/Star/SelfAdjoint.lean @@ -187,6 +187,16 @@ variable (R) end MulOneClass +section Semigroup + +variable [Semigroup R] [StarMul R] + +@[aesop safe apply] +theorem ppow {x : R} (hx : IsSelfAdjoint x) (n : ℕ+) : IsSelfAdjoint (x ^ n) := by + simp only [isSelfAdjoint_iff, star_ppow, hx.star_eq] + +end Semigroup + section Monoid variable [Monoid R] [StarMul R] @@ -412,6 +422,13 @@ instance : NatCast (selfAdjoint R) where instance : IntCast (selfAdjoint R) where intCast n := ⟨n, .intCast _⟩ +instance : Pow (selfAdjoint R) ℕ+ where + pow x n := ⟨(x : R) ^ n, x.prop.ppow n⟩ + +@[simp, norm_cast] +theorem val_ppow (x : selfAdjoint R) (n : ℕ+) : ↑(x ^ n) = (x : R) ^ n := + rfl + instance : Pow (selfAdjoint R) ℕ where pow x n := ⟨(x : R) ^ n, x.prop.pow n⟩ @@ -441,7 +458,7 @@ variable [CommRing R] [StarRing R] instance : CommRing (selfAdjoint R) := Function.Injective.commRing _ Subtype.coe_injective (selfAdjoint R).coe_zero val_one (selfAdjoint R).coe_add val_mul (selfAdjoint R).coe_neg (selfAdjoint R).coe_sub - (by intros; rfl) (by intros; rfl) val_pow + (by intros; rfl) (by intros; rfl) (fun _ _ => rfl) val_ppow val_pow (fun _ => rfl) fun _ => rfl end CommRing @@ -492,8 +509,9 @@ instance instSMulRat : SMul ℚ (selfAdjoint R) where instance instField : Field (selfAdjoint R) := Subtype.coe_injective.field _ (selfAdjoint R).coe_zero val_one (selfAdjoint R).coe_add val_mul (selfAdjoint R).coe_neg (selfAdjoint R).coe_sub - val_inv val_div (swap (selfAdjoint R).coe_nsmul) (by intros; rfl) val_nnqsmul - val_qsmul val_pow val_zpow (fun _ => rfl) (fun _ => rfl) val_nnratCast val_ratCast + val_inv val_div (swap (selfAdjoint R).coe_psmul) (swap (selfAdjoint R).coe_nsmul) + (by intros; rfl) val_nnqsmul val_qsmul val_ppow val_pow val_zpow (fun _ => rfl) (fun _ => rfl) + val_nnratCast val_ratCast end Field From 15b3a9a383f5bcdff0c86fd57581f3aefb828e8f Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 18:38:13 -0400 Subject: [PATCH 073/127] ringcon --- Mathlib/RingTheory/Congruence/Defs.lean | 39 ++++++++++++++----------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/Mathlib/RingTheory/Congruence/Defs.lean b/Mathlib/RingTheory/Congruence/Defs.lean index 16f78f06af0245..b281e3c7316b1d 100644 --- a/Mathlib/RingTheory/Congruence/Defs.lean +++ b/Mathlib/RingTheory/Congruence/Defs.lean @@ -401,76 +401,81 @@ end Mul instance [NonUnitalNonAssocSemiring R] (c : RingCon R) : NonUnitalNonAssocSemiring c.Quotient := fast_instance% Function.Surjective.nonUnitalNonAssocSemiring _ Quotient.mk''_surjective rfl - (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl instance [NonUnitalNonAssocCommSemiring R] (c : RingCon R) : NonUnitalNonAssocCommSemiring c.Quotient := fast_instance% Function.Surjective.nonUnitalNonAssocCommSemiring _ Quotient.mk''_surjective rfl - (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl instance [NonAssocSemiring R] (c : RingCon R) : NonAssocSemiring c.Quotient := fast_instance% Function.Surjective.nonAssocSemiring _ Quotient.mk''_surjective rfl rfl (fun _ _ => rfl) - (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl instance [NonAssocCommSemiring R] (c : RingCon R) : NonAssocCommSemiring c.Quotient := fast_instance% Function.Surjective.nonAssocCommSemiring _ Quotient.mk''_surjective rfl rfl (fun _ _ => rfl) - (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl instance [NonUnitalSemiring R] (c : RingCon R) : NonUnitalSemiring c.Quotient := fast_instance% Function.Surjective.nonUnitalSemiring _ Quotient.mk''_surjective rfl (fun _ _ => rfl) - (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl instance [NonUnitalCommSemiring R] (c : RingCon R) : NonUnitalCommSemiring c.Quotient := fast_instance% Function.Surjective.nonUnitalCommSemiring _ Quotient.mk''_surjective rfl (fun _ _ => rfl) - (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl instance [Semiring R] (c : RingCon R) : Semiring c.Quotient := fast_instance% - Function.Surjective.semiring _ Quotient.mk''_surjective rfl rfl (fun _ _ => rfl) - (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl + Function.Surjective.semiring _ Quotient.mk''_surjective rfl rfl (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl instance [CommSemiring R] (c : RingCon R) : CommSemiring c.Quotient := fast_instance% Function.Surjective.commSemiring _ Quotient.mk''_surjective rfl rfl (fun _ _ => rfl) - (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + fun _ => rfl instance [NonUnitalNonAssocRing R] (c : RingCon R) : NonUnitalNonAssocRing c.Quotient := fast_instance% Function.Surjective.nonUnitalNonAssocRing _ Quotient.mk''_surjective 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 instance [NonUnitalNonAssocCommRing R] (c : RingCon R) : NonUnitalNonAssocCommRing c.Quotient := fast_instance% Function.Surjective.nonUnitalNonAssocCommRing _ Quotient.mk''_surjective rfl (fun _ _ => rfl) - (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + fun _ _ => rfl instance [NonAssocRing R] (c : RingCon R) : NonAssocRing c.Quotient := fast_instance% Function.Surjective.nonAssocRing _ Quotient.mk''_surjective rfl rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) - (fun _ => rfl) fun _ => rfl + (fun _ _ => rfl) (fun _ => rfl) fun _ => rfl instance [NonAssocCommRing R] (c : RingCon R) : NonAssocCommRing c.Quotient := fast_instance% Function.Surjective.nonAssocCommRing _ Quotient.mk''_surjective rfl rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) - (fun _ => rfl) fun _ => rfl + (fun _ _ => rfl) (fun _ => rfl) fun _ => rfl instance [NonUnitalRing R] (c : RingCon R) : NonUnitalRing c.Quotient := fast_instance% Function.Surjective.nonUnitalRing _ Quotient.mk''_surjective rfl (fun _ _ => rfl) - (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) fun _ _ => rfl instance [NonUnitalCommRing R] (c : RingCon R) : NonUnitalCommRing c.Quotient := fast_instance% Function.Surjective.nonUnitalCommRing _ Quotient.mk''_surjective rfl (fun _ _ => rfl) - (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ _ => rfl + (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) fun _ _ => rfl instance [Ring R] (c : RingCon R) : Ring c.Quotient := fast_instance% Function.Surjective.ring _ Quotient.mk''_surjective rfl rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) - (fun _ _ => rfl) (fun _ => rfl) fun _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) fun _ => rfl instance [CommRing R] (c : RingCon R) : CommRing c.Quotient := fast_instance% Function.Surjective.commRing _ Quotient.mk''_surjective 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 _ => rfl end Algebraic From 51ba3e1d41472d994a424d491d5d7f8d92118488 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Tue, 23 Jun 2026 21:17:32 -0400 Subject: [PATCH 074/127] IsScalarTower --- Mathlib/Algebra/Module/NatInt.lean | 3 +++ Mathlib/GroupTheory/GroupAction/Ring.lean | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/Mathlib/Algebra/Module/NatInt.lean b/Mathlib/Algebra/Module/NatInt.lean index 9daa84aa1c71eb..d5c083d9d42463 100644 --- a/Mathlib/Algebra/Module/NatInt.lean +++ b/Mathlib/Algebra/Module/NatInt.lean @@ -146,6 +146,9 @@ instance AddCommMonoid.nat_isScalarTower : IsScalarTower ℕ R M where | zero => simp only [zero_smul] | succ n ih => simp only [add_smul, one_smul, ih] +instance AddCommMonoid.pnat_isScalarTower : IsScalarTower ℕ+ R M where + smul_assoc _ _ _ := by rw [← nsmul_val_eq_psmul, smul_assoc, nsmul_val_eq_psmul] + end AddCommMonoid theorem map_natCast_smul [AddCommMonoid M] [AddCommMonoid M₂] {F : Type*} [FunLike F M M₂] diff --git a/Mathlib/GroupTheory/GroupAction/Ring.lean b/Mathlib/GroupTheory/GroupAction/Ring.lean index 7c2610e440e2b0..e70cb57e4740c4 100644 --- a/Mathlib/GroupTheory/GroupAction/Ring.lean +++ b/Mathlib/GroupTheory/GroupAction/Ring.lean @@ -36,6 +36,11 @@ instance NonUnitalNonAssocSemiring.nat_isScalarTower [NonUnitalNonAssocSemiring | zero => simp | succ n ih => simp_rw [succ_nsmul, ← ih, smul_eq_mul, add_mul] +/-- Note that `AddCommSemigroup.pnat_isScalarTower` requires stronger assumptions on `R`. -/ +instance NonUnitalNonAssocSemiring.pnat_isScalarTower [NonUnitalNonAssocSemiring R] : + IsScalarTower ℕ+ R R where + smul_assoc _ _ _ := by rw [← nsmul_val_eq_psmul, smul_assoc, nsmul_val_eq_psmul] + /-- Note that `AddCommGroup.int_isScalarTower` requires stronger assumptions on `R`. -/ instance NonUnitalNonAssocRing.int_isScalarTower [NonUnitalNonAssocRing R] : IsScalarTower ℤ R R where From 8a3146a79fb85f2f460ca2709b2b563ca8c29f8b Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 09:34:18 -0400 Subject: [PATCH 075/127] ppow_induction golfs many proofs --- Mathlib/Algebra/Group/Hom/Defs.lean | 9 ++-- Mathlib/Algebra/Group/InjSurj.lean | 11 +---- Mathlib/Algebra/Group/PPow/Defs.lean | 42 ++++++++++++------- .../Algebra/Group/Pointwise/Finset/Basic.lean | 14 ++----- Mathlib/Algebra/Order/CauSeq/Basic.lean | 22 +++++++++- .../Algebra/Order/GroupWithZero/Basic.lean | 11 ++--- .../Algebra/Order/Monoid/Unbundled/Pow.lean | 19 +++------ Mathlib/GroupTheory/Congruence/Defs.lean | 13 +++--- 8 files changed, 71 insertions(+), 70 deletions(-) diff --git a/Mathlib/Algebra/Group/Hom/Defs.lean b/Mathlib/Algebra/Group/Hom/Defs.lean index 59a91d4c98ae38..3eba5485ba2eed 100644 --- a/Mathlib/Algebra/Group/Hom/Defs.lean +++ b/Mathlib/Algebra/Group/Hom/Defs.lean @@ -682,12 +682,9 @@ protected theorem MulHom.map_mul [Mul M] [Mul N] (f : M →ₙ* N) (a b : M) : f @[to_additive] protected theorem MulHom.map_ppow {M N : Type*} [Semigroup M] [Semigroup N] (f : M →ₙ* N) (a : M) (n : ℕ+) : f (a ^ n) = f a ^ n := by - rcases n with ⟨n, hn⟩ - simp only [← Semigroup.ppow_eq_pow, PNat.mk_coe] - obtain ⟨k, rfl⟩ := Nat.exists_eq_succ_of_ne_zero (Nat.pos_iff_ne_zero.1 hn) - induction k with - | zero => simp only [Semigroup.ppow_one] - | succ k IH => simp only [Semigroup.ppow_succ, MulHom.map_mul, IH (Nat.succ_pos _)] + induction n using Semigroup.ppow_induction a + · simp + · simp [ppow_mk_add_one _ (Nat.succ_ne_zero _), *] /-- If `f` is a monoid homomorphism then `f (a * b) = f a * f b`. -/ @[to_additive /-- If `f` is an additive monoid homomorphism then `f (a + b) = f a + f b`. -/] diff --git a/Mathlib/Algebra/Group/InjSurj.lean b/Mathlib/Algebra/Group/InjSurj.lean index a6c0ae1432ec56..a4f28beeac5480 100644 --- a/Mathlib/Algebra/Group/InjSurj.lean +++ b/Mathlib/Algebra/Group/InjSurj.lean @@ -55,10 +55,7 @@ protected abbrev semigroup [Pow M₁ ℕ+] [Semigroup M₂] (f : M₁ → M₂) ppow := fun n hn x => (x ^ (PNat.mk n hn : ℕ+)) ppow_one := fun x => hf <| by simp [ppow, ppow_one] ppow_succ := fun n x => hf <| by - rw [ppow, mul, ppow] - change Semigroup.ppow (x + 2) _ _ = _ - rw [Semigroup.ppow_succ] - rfl + simp [ppow, mul, ← Semigroup.ppow_eq_pow, Semigroup.ppow_succ] /-- A type endowed with `*` is a commutative magma, if it admits a surjective map that preserves `*` from a commutative magma. -/ @@ -345,11 +342,7 @@ protected abbrev semigroup [Pow M₂ ℕ+] [Semigroup M₁] (f : M₁ → M₂) ppow := fun n hn x => x ^ (PNat.mk n hn : ℕ+) ppow_one := hf.forall.2 fun x => by simp [← ppow] ppow_succ := hf.forall.2 fun x n => by - rw [← ppow, ← ppow, ← mul] - congr - change Semigroup.ppow (n + 2) _ _ = _ - rw [Semigroup.ppow_succ] - rfl + simp [← ppow, ← mul, ← Semigroup.ppow_eq_pow, Semigroup.ppow_succ] /-- A type endowed with `*` is a commutative semigroup, if it admits a surjective map that preserves `*` from a commutative semigroup. See note [reducible non-instances]. -/ diff --git a/Mathlib/Algebra/Group/PPow/Defs.lean b/Mathlib/Algebra/Group/PPow/Defs.lean index ccdf3bedfdb3cc..f06a3ccdcce8dd 100644 --- a/Mathlib/Algebra/Group/PPow/Defs.lean +++ b/Mathlib/Algebra/Group/PPow/Defs.lean @@ -42,6 +42,24 @@ lemma one_psmul [AddSemigroup M] (x : M) : (1 : ℕ+) • x = x := lemma ppow_one [Semigroup M] (x : M) : x ^ (1 : ℕ+) = x := Semigroup.ppow_one _ +@[to_additive (attr := elab_as_elim)] +lemma Semigroup.ppow_induction [Semigroup M] {p : ℕ+ → M → Prop} (x : M) (n : ℕ+) + (h1 : p 1 x) (hsucc : ∀ n : ℕ, + p (PNat.mk (n + 1) (Nat.succ_pos n)) (x ^ PNat.mk (n + 1) (Nat.succ_pos n)) → + p (PNat.mk (n + 2) (Nat.succ_pos (n + 1))) + (x * x ^ PNat.mk (n + 1) (Nat.succ_pos n))) : + p n (x ^ n) := by + rcases n with ⟨n, hn⟩ + rcases Nat.exists_eq_succ_of_ne_zero (Nat.ne_of_gt hn) with ⟨k, rfl⟩ + let q : ℕ → Prop := fun k => + p (PNat.mk (k + 1) (Nat.succ_pos k)) (x ^ PNat.mk (k + 1) (Nat.succ_pos k)) + have hq (k : ℕ) : q k := by + induction k with + | zero => simpa [q, PNat.mk] using h1 + | succ k IH => + simpa [q, PNat.mk, ← Semigroup.ppow_eq_pow, Semigroup.ppow_succ] using hsucc k IH + simpa [q, PNat.mk] using hq k + @[to_additive] lemma ppow_mk_add_one [Semigroup M] (x : M) {n : ℕ} (hn : n ≠ 0) : x ^ (PNat.mk (n + 1) (Nat.succ_pos n)) = x * x ^ (PNat.mk n (Nat.pos_of_ne_zero hn)) := by @@ -52,12 +70,11 @@ lemma ppow_mk_add_one [Semigroup M] (x : M) {n : ℕ} (hn : n ≠ 0) : -- not marked as `simp` because in a monoid we probably prefer powers with type `ℕ` @[to_additive (attr := norm_cast)] theorem npow_val_eq_ppow [Monoid M] (n : ℕ+) (x : M) : x ^ n.val = x ^ n := by - rcases n with ⟨_|n, hn⟩ - · contradiction - simp only [mk_coe, ← Semigroup.ppow_eq_pow] - induction n - · simp [Semigroup.ppow_one] - · simp_all [Semigroup.ppow_succ, pow_succ'] + induction n using Semigroup.ppow_induction x with + | h1 => simp + | hsucc n IH => + simp only [mk_coe] at IH + simp [pow_succ' _ (n + 1), IH] -- This lemma is higher priority than later `smul_zero` so that the `simpNF` is happy @[to_additive (attr := simp high) psmul_zero] lemma one_ppow [Monoid M] (n : ℕ+) : @@ -70,13 +87,10 @@ variable [CommSemigroup M] @[to_additive psmul_add] lemma mul_ppow (x y : M) (n : ℕ+) : (x * y) ^ n = x ^ n * y ^ n := by - rcases n with ⟨_|n, hn⟩ - · contradiction - simp only [mk_coe, ← Semigroup.ppow_eq_pow] - induction n with - | zero => simp [Semigroup.ppow_one] - | succ n IH => - rw [Semigroup.ppow_succ, IH (Nat.succ_pos _), Semigroup.ppow_succ, Semigroup.ppow_succ, - mul_assoc, mul_comm y, ← mul_assoc, ← mul_assoc, mul_comm y, ← mul_assoc] + induction n using Semigroup.ppow_induction (x * y) with + | h1 => simp + | hsucc n IH => + rw [ppow_mk_add_one x (Nat.succ_ne_zero n), ppow_mk_add_one y (Nat.succ_ne_zero n), + IH, mul_assoc, mul_comm y, ← mul_assoc, ← mul_assoc, mul_comm y, ← mul_assoc] end CommSemigroup diff --git a/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean b/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean index 85536baff89d17..a471e65118c405 100644 --- a/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean +++ b/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean @@ -724,16 +724,10 @@ scoped[Pointwise] attribute [instance] Finset.psmul Finset.ppow Finset.nsmul Fin @[to_additive (attr := simp, norm_cast)] theorem coe_ppow [Semigroup α] (s : Finset α) (n : ℕ+) : ↑(s ^ n) = (s : Set α) ^ n := by - change ↑(ppowRec n n.prop s) = (s : Set α) ^ n - rw [← Semigroup.ppow_eq_pow] - rcases n with ⟨_|n, hn⟩ - · contradiction - simp only [_root_.mk_coe] - induction n with - | zero => rfl - | succ n IH => - rw [ppowRec] - simp [IH Nat.succ_pos', Semigroup.ppow_succ] + change ↑(ppowRec _ _ s) = (s : Set α) ^ _ + induction n using Semigroup.ppow_induction (s : Set α) + · rfl + · simp_all [ppowRec] /-- `Finset α` is a `Semigroup` under pointwise operations if `α` is. -/ @[to_additive (attr := implicit_reducible) diff --git a/Mathlib/Algebra/Order/CauSeq/Basic.lean b/Mathlib/Algebra/Order/CauSeq/Basic.lean index c3f8165c29f6db..15a53cfcf43485 100644 --- a/Mathlib/Algebra/Order/CauSeq/Basic.lean +++ b/Mathlib/Algebra/Order/CauSeq/Basic.lean @@ -325,7 +325,7 @@ end SMul instance addGroup : AddGroup (CauSeq β abv) := Function.Injective.addGroup Subtype.val Subtype.val_injective rfl coe_add coe_neg coe_sub - (fun _ _ => coe_smul _ _) fun _ _ => coe_smul _ _ + (fun _ _ => coe_smul _ _) (fun _ _ => coe_smul _ _) fun _ _ => coe_smul _ _ instance instNatCast : NatCast (CauSeq β abv) := ⟨fun n => const n⟩ @@ -338,6 +338,7 @@ instance addGroupWithOne : AddGroupWithOne (CauSeq β abv) := (by intros; rfl) (by intros; rfl) (by intros; rfl) + (by intros; rfl) instance : Pow (CauSeq β abv) ℕ := ⟨fun f n => @@ -354,9 +355,26 @@ theorem pow_apply (f : CauSeq β abv) (n i : ℕ) : (f ^ n) i = f i ^ n := theorem const_pow (x : β) (n : ℕ) : const (x ^ n) = const x ^ n := rfl +instance : Pow (CauSeq β abv) ℕ+ := + ⟨fun f n => + (ofEq (ppowRec n n.prop f) fun i => f i ^ n) <| fun i ↦ by + refine Semigroup.ppow_induction (f i) n ?_ ?_ <;> simp +contextual [ppowRec]⟩ + +@[simp, norm_cast] +theorem coe_ppow (f : CauSeq β abv) (n : ℕ+) : ⇑(f ^ n) = (f : ℕ → β) ^ n := + rfl + +@[simp, norm_cast] +theorem ppow_apply (f : CauSeq β abv) (n : ℕ+) (i : ℕ) : (f ^ n) i = f i ^ n := + rfl + +theorem const_ppow (x : β) (n : ℕ+) : const (x ^ n) = const x ^ n := + rfl + instance ring : Ring (CauSeq β abv) := Function.Injective.ring Subtype.val Subtype.val_injective rfl rfl coe_add coe_mul coe_neg coe_sub - (fun _ _ => coe_smul _ _) (fun _ _ => coe_smul _ _) coe_pow (fun _ => rfl) fun _ => rfl + (fun _ _ => coe_smul _ _) (fun _ _ => coe_smul _ _) (fun _ _ => coe_smul _ _) coe_ppow coe_pow + (fun _ => rfl) fun _ => rfl instance {β : Type*} [CommRing β] {abv : β → α} [IsAbsoluteValue abv] : CommRing (CauSeq β abv) := { CauSeq.ring with diff --git a/Mathlib/Algebra/Order/GroupWithZero/Basic.lean b/Mathlib/Algebra/Order/GroupWithZero/Basic.lean index 385616e2ac72b0..b1126cc793c730 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Basic.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Basic.lean @@ -372,14 +372,9 @@ variable [SemigroupWithZero M₀] variable [Preorder M₀] {a b : M₀} @[simp] lemma ppow_nonneg [PosMulMono M₀] (n : ℕ+) (ha : 0 ≤ a) : 0 ≤ a ^ n := by - rcases n with ⟨n, hn⟩ - simp only [← Semigroup.ppow_eq_pow, PNat.mk_coe] - obtain ⟨k, rfl⟩ := Nat.exists_eq_succ_of_ne_zero hn.ne' - induction k with - | zero => simp [Semigroup.ppow_one, ha] - | succ k IH => - rw [Semigroup.ppow_succ] - exact mul_nonneg ha (IH Nat.succ_pos') + induction n using Semigroup.ppow_induction a + · exact ha + · exact mul_nonneg ha ‹_› end SemigroupWithZero diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean index bc0b9d39407205..fd76b3c5a6209f 100644 --- a/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean @@ -35,25 +35,18 @@ variable [MulLeftMono M] {a : M} @[to_additive Left.psmul_nonneg] theorem one_le_ppow_of_le (ha : 1 ≤ a) (n : ℕ+) : 1 ≤ a ^ n := by - rcases n with ⟨n, hn⟩ - simp only [← Semigroup.ppow_eq_pow, PNat.mk_coe] - obtain ⟨k, rfl⟩ := Nat.exists_eq_succ_of_ne_zero hn.ne' - induction k with - | zero => simp [Semigroup.ppow_one, ha] - | succ k IH => - rw [Semigroup.ppow_succ] - exact one_le_mul ha (IH Nat.succ_pos') + induction n using Semigroup.ppow_induction a + · exact ha + · exact one_le_mul ha ‹_› @[to_additive psmul_nonpos] theorem ppow_le_one_of_le (ha : a ≤ 1) (n : ℕ+) : a ^ n ≤ 1 := one_le_ppow_of_le (M := Mᵒᵈ) ha n @[to_additive psmul_neg] theorem ppow_lt_one_of_lt {a : M} (n : ℕ+) (h : a < 1) : a ^ n < 1 := by - rcases n with ⟨n, hn⟩ - obtain ⟨_|k, rfl⟩ := Nat.exists_eq_succ_of_ne_zero hn.ne' - · simp [h] - · simp only [Nat.succ_eq_add_one, ← Semigroup.ppow_eq_pow, PNat.mk_coe, Semigroup.ppow_succ] - refine mul_lt_one_of_lt_of_le h (ppow_le_one_of_le h.le ⟨k + 1, Nat.succ_pos k⟩) + induction n using Semigroup.ppow_induction a + · exact h + · exact mul_lt_one_of_lt_of_le h (ppow_le_one_of_le h.le _) @[to_additive Left.nsmul_nonneg] theorem one_le_pow_of_le (ha : 1 ≤ a) : ∀ n : ℕ, 1 ≤ a ^ n diff --git a/Mathlib/GroupTheory/Congruence/Defs.lean b/Mathlib/GroupTheory/Congruence/Defs.lean index 3d65aa26d33b80..308caa78c4a661 100644 --- a/Mathlib/GroupTheory/Congruence/Defs.lean +++ b/Mathlib/GroupTheory/Congruence/Defs.lean @@ -569,14 +569,11 @@ section Monoids @[to_additive /-- Additive congruence relations preserve positive natural scaling. -/] protected theorem ppow {M : Type*} [Semigroup M] (c : Con M) (n : ℕ+) {w x} (h : c w x) : c (w ^ n) (x ^ n) := by - rcases n with ⟨n, hn⟩ - simp only [← Semigroup.ppow_eq_pow, PNat.mk_coe] - obtain ⟨k, rfl⟩ := Nat.exists_eq_succ_of_ne_zero hn.ne' - induction k with - | zero => simp [Semigroup.ppow_one, h] - | succ k IH => - rw [Semigroup.ppow_succ, Semigroup.ppow_succ] - exact c.mul h (IH Nat.succ_pos') + induction n using Semigroup.ppow_induction w generalizing x with + | h1 => simp [h] + | hsucc n IH => + rw [ppow_mk_add_one x (Nat.succ_ne_zero _)] + exact c.mul h (IH h) @[to_additive] instance {M : Type*} [Semigroup M] (c : Con M) : Pow c.Quotient ℕ+ where From 936021e433fbbb63980df9ed73a8907e0c22a7e9 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 09:43:22 -0400 Subject: [PATCH 076/127] autoparam for easier rws --- Mathlib/Algebra/Group/Hom/Defs.lean | 2 +- Mathlib/Algebra/Group/PPow/Defs.lean | 4 ++-- Mathlib/Algebra/Group/Subsemigroup/Defs.lean | 2 +- Mathlib/GroupTheory/Congruence/Defs.lean | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Mathlib/Algebra/Group/Hom/Defs.lean b/Mathlib/Algebra/Group/Hom/Defs.lean index 3eba5485ba2eed..b1f162b64a7402 100644 --- a/Mathlib/Algebra/Group/Hom/Defs.lean +++ b/Mathlib/Algebra/Group/Hom/Defs.lean @@ -684,7 +684,7 @@ protected theorem MulHom.map_ppow {M N : Type*} [Semigroup M] [Semigroup N] (f : (n : ℕ+) : f (a ^ n) = f a ^ n := by induction n using Semigroup.ppow_induction a · simp - · simp [ppow_mk_add_one _ (Nat.succ_ne_zero _), *] + · simp [ppow_mk_add_one, *] /-- If `f` is a monoid homomorphism then `f (a * b) = f a * f b`. -/ @[to_additive /-- If `f` is an additive monoid homomorphism then `f (a + b) = f a + f b`. -/] diff --git a/Mathlib/Algebra/Group/PPow/Defs.lean b/Mathlib/Algebra/Group/PPow/Defs.lean index f06a3ccdcce8dd..96c4eeb44b71b3 100644 --- a/Mathlib/Algebra/Group/PPow/Defs.lean +++ b/Mathlib/Algebra/Group/PPow/Defs.lean @@ -61,7 +61,7 @@ lemma Semigroup.ppow_induction [Semigroup M] {p : ℕ+ → M → Prop} (x : M) ( simpa [q, PNat.mk] using hq k @[to_additive] -lemma ppow_mk_add_one [Semigroup M] (x : M) {n : ℕ} (hn : n ≠ 0) : +lemma ppow_mk_add_one [Semigroup M] (x : M) {n : ℕ} (hn : n ≠ 0 := by exact Nat.succ_ne_zero _) : x ^ (PNat.mk (n + 1) (Nat.succ_pos n)) = x * x ^ (PNat.mk n (Nat.pos_of_ne_zero hn)) := by cases n · contradiction @@ -90,7 +90,7 @@ lemma mul_ppow (x y : M) (n : ℕ+) : (x * y) ^ n = x ^ n * y ^ n := by induction n using Semigroup.ppow_induction (x * y) with | h1 => simp | hsucc n IH => - rw [ppow_mk_add_one x (Nat.succ_ne_zero n), ppow_mk_add_one y (Nat.succ_ne_zero n), + rw [ppow_mk_add_one x, ppow_mk_add_one y, IH, mul_assoc, mul_comm y, ← mul_assoc, ← mul_assoc, mul_comm y, ← mul_assoc] end CommSemigroup diff --git a/Mathlib/Algebra/Group/Subsemigroup/Defs.lean b/Mathlib/Algebra/Group/Subsemigroup/Defs.lean index 30777081061f2e..b5fa3852f0855c 100644 --- a/Mathlib/Algebra/Group/Subsemigroup/Defs.lean +++ b/Mathlib/Algebra/Group/Subsemigroup/Defs.lean @@ -289,7 +289,7 @@ lemma ppow_coe_mem {M A : Type*} [Semigroup M] [SetLike A M] [hA : MulMemClass A induction n with | zero => simp [ppow_one] | succ n IH => - rw [ppow_mk_add_one _ (Nat.succ_ne_zero _)] + rw [ppow_mk_add_one] exact mul_mem x.2 (IH Nat.succ_pos') -- lower priority so other instances are found first diff --git a/Mathlib/GroupTheory/Congruence/Defs.lean b/Mathlib/GroupTheory/Congruence/Defs.lean index 308caa78c4a661..cad00d04c56751 100644 --- a/Mathlib/GroupTheory/Congruence/Defs.lean +++ b/Mathlib/GroupTheory/Congruence/Defs.lean @@ -572,7 +572,7 @@ protected theorem ppow {M : Type*} [Semigroup M] (c : Con M) (n : ℕ+) {w x} (h induction n using Semigroup.ppow_induction w generalizing x with | h1 => simp [h] | hsucc n IH => - rw [ppow_mk_add_one x (Nat.succ_ne_zero _)] + rw [ppow_mk_add_one x] exact c.mul h (IH h) @[to_additive] From 215fe31362929e5cc07386fa19cfe9f9c15d257e Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 09:59:07 -0400 Subject: [PATCH 077/127] distribsmul and smulcomm instances, fixes linearmap --- Mathlib/Algebra/Group/Hom/Defs.lean | 2 +- Mathlib/Algebra/GroupWithZero/Action/Defs.lean | 9 +++++++++ Mathlib/Algebra/Module/LinearMap/Defs.lean | 6 +++--- Mathlib/Algebra/Module/NatInt.lean | 4 ++++ 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Group/Hom/Defs.lean b/Mathlib/Algebra/Group/Hom/Defs.lean index b1f162b64a7402..eaef2e8f82bc39 100644 --- a/Mathlib/Algebra/Group/Hom/Defs.lean +++ b/Mathlib/Algebra/Group/Hom/Defs.lean @@ -679,7 +679,7 @@ protected theorem MonoidHom.map_one [MulOne M] [MulOne N] (f : M →* N) : f 1 = protected theorem MulHom.map_mul [Mul M] [Mul N] (f : M →ₙ* N) (a b : M) : f (a * b) = f a * f b := f.map_mul' a b -@[to_additive] +@[to_additive (reorder := a n)] protected theorem MulHom.map_ppow {M N : Type*} [Semigroup M] [Semigroup N] (f : M →ₙ* N) (a : M) (n : ℕ+) : f (a ^ n) = f a ^ n := by induction n using Semigroup.ppow_induction a diff --git a/Mathlib/Algebra/GroupWithZero/Action/Defs.lean b/Mathlib/Algebra/GroupWithZero/Action/Defs.lean index a190d119283050..eb8af108e44eae 100644 --- a/Mathlib/Algebra/GroupWithZero/Action/Defs.lean +++ b/Mathlib/Algebra/GroupWithZero/Action/Defs.lean @@ -320,10 +320,19 @@ abbrev DistribSMul.compFun (f : N → M) : DistribSMul N A := def DistribSMul.toAddMonoidHom (x : M) : A →+ A := { SMulZeroClass.toZeroHom A x with toFun := (x • ·), map_add' := smul_add x } +instance AddMonoid.pnat_smulCommClass {M A : Type*} [AddMonoid A] [DistribSMul M A] : + SMulCommClass ℕ+ M A where + smul_comm n x y := ((DistribSMul.toAddMonoidHom A x).map_psmul n y).symm + instance AddMonoid.nat_smulCommClass {M A : Type*} [AddMonoid A] [DistribSMul M A] : SMulCommClass ℕ M A where smul_comm n x y := ((DistribSMul.toAddMonoidHom A x).map_nsmul n y).symm +-- `SMulCommClass.symm` is not registered as an instance, as it would cause a loop +instance AddMonoid.pnat_smulCommClass' {M A : Type*} [AddMonoid A] [DistribSMul M A] : + SMulCommClass M ℕ+ A := + .symm _ _ _ + -- `SMulCommClass.symm` is not registered as an instance, as it would cause a loop instance AddMonoid.nat_smulCommClass' {M A : Type*} [AddMonoid A] [DistribSMul M A] : SMulCommClass M ℕ A := diff --git a/Mathlib/Algebra/Module/LinearMap/Defs.lean b/Mathlib/Algebra/Module/LinearMap/Defs.lean index 8286654704bb3a..f0a613ebc68d28 100644 --- a/Mathlib/Algebra/Module/LinearMap/Defs.lean +++ b/Mathlib/Algebra/Module/LinearMap/Defs.lean @@ -844,11 +844,11 @@ theorem comp_add (f g : M →ₛₗ[σ₁₂] M₂) (h : M₂ →ₛₗ[σ₂₃ -- The `AddMonoid` instance exists to help speedup unification instance addMonoid : AddMonoid (M →ₛₗ[σ₁₂] M₂) := fast_instance% - DFunLike.coe_injective.addMonoid _ rfl (fun _ _ ↦ rfl) fun _ _ ↦ rfl + DFunLike.coe_injective.addMonoid _ rfl (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) fun _ _ ↦ rfl /-- The type of linear maps is an additive monoid. -/ instance addCommMonoid : AddCommMonoid (M →ₛₗ[σ₁₂] M₂) := fast_instance% - DFunLike.coe_injective.addCommMonoid _ rfl (fun _ _ ↦ rfl) fun _ _ ↦ rfl + DFunLike.coe_injective.addCommMonoid _ rfl (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) fun _ _ ↦ rfl /-- The negation of a linear map is linear. -/ instance : Neg (M →ₛₗ[σ₁₂] N₂) := @@ -893,7 +893,7 @@ theorem comp_sub (f g : M →ₛₗ[σ₁₂] N₂) (h : N₂ →ₛₗ[σ₂₃ /-- The type of linear maps is an additive group. -/ instance addCommGroup : AddCommGroup (M →ₛₗ[σ₁₂] N₂) := fast_instance% DFunLike.coe_injective.addCommGroup _ rfl (fun _ _ ↦ rfl) (fun _ ↦ rfl) (fun _ _ ↦ rfl) - (fun _ _ ↦ rfl) fun _ _ ↦ rfl + (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) fun _ _ ↦ rfl /-- Evaluation of a `σ₁₂`-linear map at a fixed `a`, as an `AddMonoidHom`. -/ @[simps] diff --git a/Mathlib/Algebra/Module/NatInt.lean b/Mathlib/Algebra/Module/NatInt.lean index d5c083d9d42463..c13abc34e7d47e 100644 --- a/Mathlib/Algebra/Module/NatInt.lean +++ b/Mathlib/Algebra/Module/NatInt.lean @@ -57,6 +57,10 @@ section AddCommMonoid variable [AddCommMonoid M] +instance AddCommMonoid.toPNatDistribSMul : DistribSMul ℕ+ M where + smul_add n a b := psmul_add a b n + smul_zero := psmul_zero + instance AddCommMonoid.toNatModule : Module ℕ M where smul_add n a b := nsmul_add a b n smul_zero := nsmul_zero From a53868edb92529c479a4f073654e98b362e99a56 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 10:11:08 -0400 Subject: [PATCH 078/127] causeq completion --- Mathlib/Algebra/Order/CauSeq/Basic.lean | 8 ++++++++ Mathlib/Algebra/Order/CauSeq/Completion.lean | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/Mathlib/Algebra/Order/CauSeq/Basic.lean b/Mathlib/Algebra/Order/CauSeq/Basic.lean index 15a53cfcf43485..12b09b570334a8 100644 --- a/Mathlib/Algebra/Order/CauSeq/Basic.lean +++ b/Mathlib/Algebra/Order/CauSeq/Basic.lean @@ -371,6 +371,11 @@ theorem ppow_apply (f : CauSeq β abv) (n : ℕ+) (i : ℕ) : (f ^ n) i = f i ^ theorem const_ppow (x : β) (n : ℕ+) : const (x ^ n) = const x ^ n := rfl +@[norm_cast] +theorem npow_val_eq_ppow (f : CauSeq β abv) (n : ℕ+) : f ^ n.val = f ^ n := by + ext + simp [← _root_.npow_val_eq_ppow] + instance ring : Ring (CauSeq β abv) := Function.Injective.ring Subtype.val Subtype.val_injective rfl rfl coe_add coe_mul coe_neg coe_sub (fun _ _ => coe_smul _ _) (fun _ _ => coe_smul _ _) (fun _ _ => coe_smul _ _) coe_ppow coe_pow @@ -522,6 +527,9 @@ theorem pow_equiv_pow {f1 f2 : CauSeq β abv} (hf : f1 ≈ f2) (n : ℕ) : f1 ^ | zero => simp only [pow_zero, Setoid.refl] | succ n ih => simpa only [pow_succ'] using mul_equiv_mul hf ih +theorem ppow_equiv_ppow {f1 f2 : CauSeq β abv} (hf : f1 ≈ f2) (n : ℕ+) : f1 ^ n ≈ f2 ^ n := by + simp [← npow_val_eq_ppow, pow_equiv_pow hf n.val] + end Ring section IsDomain diff --git a/Mathlib/Algebra/Order/CauSeq/Completion.lean b/Mathlib/Algebra/Order/CauSeq/Completion.lean index 9d8794438abc3f..d203dea3ee36ac 100644 --- a/Mathlib/Algebra/Order/CauSeq/Completion.lean +++ b/Mathlib/Algebra/Order/CauSeq/Completion.lean @@ -106,6 +106,9 @@ theorem mk_smul {γ : Type*} [SMul γ β] [IsScalarTower γ β β] (c : γ) (f : c • mk f = mk (c • f) := rfl +instance : Pow (Cauchy abv) ℕ+ := + ⟨fun x n => Quotient.map (· ^ n) (fun _ _ hf => ppow_equiv_ppow hf _) x⟩ + instance : Pow (Cauchy abv) ℕ := ⟨fun x n => Quotient.map (· ^ n) (fun _ _ hf => pow_equiv_pow hf _) x⟩ @@ -145,6 +148,7 @@ instance Cauchy.ring : Ring (Cauchy abv) := fast_instance% Function.Surjective.ring mk Quotient.mk'_surjective rfl rfl (fun _ _ => (mk_add _ _).symm) (fun _ _ => (mk_mul _ _).symm) (fun _ => (mk_neg _).symm) (fun _ _ => (mk_sub _ _).symm) (fun _ _ => (mk_smul _ _).symm) (fun _ _ => (mk_smul _ _).symm) + (fun _ _ => (mk_smul _ _).symm) (fun _ _ => rfl) (fun _ _ => (mk_pow _ _).symm) (fun _ => rfl) fun _ => rfl /-- `CauSeq.Completion.ofRat` as a `RingHom` -/ @@ -173,6 +177,7 @@ instance Cauchy.commRing : CommRing (Cauchy abv) := fast_instance% Function.Surjective.commRing mk Quotient.mk'_surjective rfl rfl (fun _ _ => (mk_add _ _).symm) (fun _ _ => (mk_mul _ _).symm) (fun _ => (mk_neg _).symm) (fun _ _ => (mk_sub _ _).symm) (fun _ _ => (mk_smul _ _).symm) (fun _ _ => (mk_smul _ _).symm) + (fun _ _ => (mk_smul _ _).symm) (fun _ _ => rfl) (fun _ _ => (mk_pow _ _).symm) (fun _ => rfl) fun _ => rfl end From 3dce82219610ad086d829ab3993ce85143e2d315 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 10:42:53 -0400 Subject: [PATCH 079/127] explain diamond --- .../NonUnitalSubsemiring/Basic.lean | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean b/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean index 51a570b0c829e4..33875110bd4b4f 100644 --- a/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean +++ b/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean @@ -223,10 +223,10 @@ variable (R) /-- The center of a semiring `R` is the set of elements that commute and associate with everything in `R` -/ -def center : NonUnitalSubsemiring R := - { Subsemigroup.center R with - zero_mem' := Set.zero_mem_center - add_mem' := Set.add_mem_center } +def center : NonUnitalSubsemiring R where + __ := Subsemigroup.center R + zero_mem' := Set.zero_mem_center + add_mem' := Set.add_mem_center theorem coe_center : ↑(center R) = Set.center R := rfl @@ -272,10 +272,22 @@ section NonUnitalSemiring variable {R : Type*} [NonUnitalSemiring R] +-- The issue is, once `R` becomes associative, then it inherits a pnat pow ... +example {R} [NonUnitalSemiring R] (x : center R) (n : ℕ+) : + (NonUnitalSubsemiringClass.toNonUnitalSemiring (center R)).toSemigroup.ppow n n.prop x = + x ^ n := + rfl + +-- But the underlying center (subsemigroup) uses the pnat pow from the smaller semigroup instance +example {R} [NonUnitalSemiring R] (x : center R) (n : ℕ+) : + ((center.instNonUnitalCommSemiring _).toNonUnitalSemiring).toSemigroup.ppow n n.prop x = + x ^ n := + rfl + -- no instance diamond, unlike the unital version example {R} [NonUnitalSemiring R] : - ((center.instNonUnitalCommSemiring _).toNonUnitalSemiring) = - (NonUnitalSubsemiringClass.toNonUnitalSemiring (center R)) := by + ((center.instNonUnitalCommSemiring _).toNonUnitalSemiring).toSemigroup.ppow = + (NonUnitalSubsemiringClass.toNonUnitalSemiring (center R)).toSemigroup.ppow := by with_reducible_and_instances rfl theorem mem_center_iff {R} [NonUnitalSemiring R] {z : R} : z ∈ center R ↔ ∀ g, g * z = z * g := by From 5300a3130ef41e8c12201ef82c4f847d579e71f1 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 10:48:20 -0400 Subject: [PATCH 080/127] ring transfer --- Mathlib/Algebra/Ring/TransferInstance.lean | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Mathlib/Algebra/Ring/TransferInstance.lean b/Mathlib/Algebra/Ring/TransferInstance.lean index dd9da001db04e6..4c392b696664b1 100644 --- a/Mathlib/Algebra/Ring/TransferInstance.lean +++ b/Mathlib/Algebra/Ring/TransferInstance.lean @@ -53,6 +53,7 @@ protected abbrev nonUnitalNonAssocSemiring [NonUnitalNonAssocSemiring β] : let zero := e.zero let add := e.add let mul := e.mul + let psmul := e.smul ℕ+ let nsmul := e.smul ℕ apply e.injective.nonUnitalNonAssocSemiring _ <;> intros <;> exact e.apply_symm_apply _ @@ -61,7 +62,9 @@ protected abbrev nonUnitalSemiring [NonUnitalSemiring β] : NonUnitalSemiring α let zero := e.zero let add := e.add let mul := e.mul + let psmul := e.smul ℕ+ let nsmul := e.smul ℕ + let ppow := e.pow ℕ+ apply e.injective.nonUnitalSemiring _ <;> intros <;> exact e.apply_symm_apply _ /-- Transfer `AddMonoidWithOne` across an `Equiv` -/ @@ -90,6 +93,7 @@ protected abbrev nonAssocSemiring [NonAssocSemiring β] : NonAssocSemiring α := protected abbrev semiring [Semiring β] : Semiring α := by let mul := e.mul let add_monoid_with_one := e.addMonoidWithOne + let ppow := e.pow ℕ+ let npow := e.pow ℕ apply e.injective.semiring _ <;> intros <;> exact e.apply_symm_apply _ @@ -98,13 +102,16 @@ protected abbrev nonUnitalCommSemiring [NonUnitalCommSemiring β] : NonUnitalCom let zero := e.zero let add := e.add let mul := e.mul + let psmul := e.smul ℕ+ let nsmul := e.smul ℕ + let ppow := e.pow ℕ+ apply e.injective.nonUnitalCommSemiring _ <;> intros <;> exact e.apply_symm_apply _ /-- Transfer `CommSemiring` across an `Equiv` -/ protected abbrev commSemiring [CommSemiring β] : CommSemiring α := by let mul := e.mul let add_monoid_with_one := e.addMonoidWithOne + let ppow := e.pow ℕ+ let npow := e.pow ℕ apply e.injective.commSemiring _ <;> intros <;> exact e.apply_symm_apply _ @@ -115,6 +122,7 @@ protected abbrev nonUnitalNonAssocRing [NonUnitalNonAssocRing β] : NonUnitalNon let mul := e.mul let neg := e.Neg let sub := e.sub + let psmul := e.smul ℕ+ let nsmul := e.smul ℕ let zsmul := e.smul ℤ apply e.injective.nonUnitalNonAssocRing _ <;> intros <;> exact e.apply_symm_apply _ @@ -126,8 +134,10 @@ protected abbrev nonUnitalRing [NonUnitalRing β] : NonUnitalRing α := by let mul := e.mul let neg := e.Neg let sub := e.sub + let psmul := e.smul ℕ+ let nsmul := e.smul ℕ let zsmul := e.smul ℤ + let ppow := e.pow ℕ+ apply e.injective.nonUnitalRing _ <;> intros <;> exact e.apply_symm_apply _ /-- Transfer `NonAssocRing` across an `Equiv` -/ @@ -140,6 +150,7 @@ protected abbrev nonAssocRing [NonAssocRing β] : NonAssocRing α := by protected abbrev ring [Ring β] : Ring α := by let mul := e.mul let add_group_with_one := e.addGroupWithOne + let ppow := e.pow ℕ+ let npow := e.pow ℕ apply e.injective.ring _ <;> intros <;> exact e.apply_symm_apply _ @@ -150,14 +161,17 @@ protected abbrev nonUnitalCommRing [NonUnitalCommRing β] : NonUnitalCommRing α let mul := e.mul let neg := e.Neg let sub := e.sub + let psmul := e.smul ℕ+ let nsmul := e.smul ℕ let zsmul := e.smul ℤ + let ppow := e.pow ℕ+ apply e.injective.nonUnitalCommRing _ <;> intros <;> exact e.apply_symm_apply _ /-- Transfer `CommRing` across an `Equiv` -/ protected abbrev commRing [CommRing β] : CommRing α := by let mul := e.mul let add_group_with_one := e.addGroupWithOne + let ppow := e.pow ℕ+ let npow := e.pow ℕ apply e.injective.commRing _ <;> intros <;> exact e.apply_symm_apply _ From 5eba48a1eca13ea7d4aabcee69b39e41df1bb3fc Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 11:36:37 -0400 Subject: [PATCH 081/127] hack diamond for nonunital center with instance prio --- .../Algebra/Algebra/NonUnitalSubalgebra.lean | 15 +++++++++---- .../RingTheory/NonUnitalSubring/Basic.lean | 10 +++++++-- .../NonUnitalSubsemiring/Basic.lean | 21 +++++++------------ 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean b/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean index 113781e935991b..3f64373733e6c5 100644 --- a/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean +++ b/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean @@ -1094,10 +1094,10 @@ theorem coe_center : (center R A : Set A) = Set.center A := rfl /-- The center of a non-unital algebra is commutative and associative -/ -instance center.instNonUnitalCommSemiring : NonUnitalCommSemiring (center R A) where +instance (priority := 75) center.instNonUnitalCommSemiring : + NonUnitalCommSemiring (center R A) where mul_assoc := Subsemigroup.center.commSemigroup.mul_assoc mul_comm := Subsemigroup.center.commSemigroup.mul_comm - -- inferInstanceAs <| NonUnitalCommSemiring (NonUnitalSubsemiring.center A) instance center.instNonUnitalCommRing {A : Type*} [NonUnitalNonAssocRing A] [Module R A] [IsScalarTower R A A] [SMulCommClass R A A] : NonUnitalCommRing (center R A) := @@ -1123,8 +1123,15 @@ end NonUnitalNonAssocSemiring variable (R A : Type*) [CommSemiring R] [NonUnitalSemiring A] [Module R A] [IsScalarTower R A A] [SMulCommClass R A A] --- no instance diamond, as the `npow` field isn't present in the non-unital case. -example : center.instNonUnitalCommSemiring.toNonUnitalSemiring = +/-- When the ambient algebra is associative, use the inherited subsemiring structure so that +positive powers agree definitionally with the ambient powers. -/ +instance center.instNonUnitalCommSemiringOfNonUnitalSemiring : + NonUnitalCommSemiring (center R A) where + __ := NonUnitalSubsemiringClass.toNonUnitalSemiring (center R A) + mul_comm := Subsemigroup.center.commSemigroup.mul_comm + +-- no instance diamond +example : (inferInstance : NonUnitalCommSemiring (center R A)).toNonUnitalSemiring = NonUnitalSubsemiringClass.toNonUnitalSemiring (center R A) := by with_reducible_and_instances rfl diff --git a/Mathlib/RingTheory/NonUnitalSubring/Basic.lean b/Mathlib/RingTheory/NonUnitalSubring/Basic.lean index 724a93c353173e..24c9764087d076 100644 --- a/Mathlib/RingTheory/NonUnitalSubring/Basic.lean +++ b/Mathlib/RingTheory/NonUnitalSubring/Basic.lean @@ -356,7 +356,7 @@ theorem center_toNonUnitalSubsemiring : rfl /-- The center is commutative and associative. -/ -instance center.instNonUnitalCommRing : NonUnitalCommRing (center R) where +instance (priority := 75) center.instNonUnitalCommRing : NonUnitalCommRing (center R) where mul_assoc := Subsemigroup.center.commSemigroup.mul_assoc mul_comm := Subsemigroup.center.commSemigroup.mul_comm @@ -376,8 +376,14 @@ end NonUnitalNonAssocRing section NonUnitalRing variable [NonUnitalRing R] +/-- When the ambient ring is associative, use the inherited subring structure so that positive +powers agree definitionally with the ambient powers. -/ +instance center.instNonUnitalCommRingOfNonUnitalRing : NonUnitalCommRing (center R) where + __ := NonUnitalSubringClass.toNonUnitalRing (center R) + mul_comm := Subsemigroup.center.commSemigroup.mul_comm + -- no instance diamond, unlike the unital version -example : ((center.instNonUnitalCommRing _).toNonUnitalRing) = +example : ((inferInstance : NonUnitalCommRing (center R)).toNonUnitalRing) = (NonUnitalSubringClass.toNonUnitalRing (center R)) := by with_reducible_and_instances rfl diff --git a/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean b/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean index 33875110bd4b4f..169acfdcea9591 100644 --- a/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean +++ b/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean @@ -237,7 +237,7 @@ theorem center_toSubsemigroup : rfl /-- The center is commutative and associative. -/ -instance center.instNonUnitalCommSemiring : NonUnitalCommSemiring (center R) where +instance (priority := 75) center.instNonUnitalCommSemiring : NonUnitalCommSemiring (center R) where __ := NonUnitalSubsemiringClass.toNonUnitalNonAssocSemiring (center R) __ := Subsemigroup.center.commSemigroup.toCommMagma mul_assoc := Subsemigroup.center.commSemigroup.mul_assoc @@ -272,21 +272,16 @@ section NonUnitalSemiring variable {R : Type*} [NonUnitalSemiring R] --- The issue is, once `R` becomes associative, then it inherits a pnat pow ... -example {R} [NonUnitalSemiring R] (x : center R) (n : ℕ+) : - (NonUnitalSubsemiringClass.toNonUnitalSemiring (center R)).toSemigroup.ppow n n.prop x = - x ^ n := - rfl - --- But the underlying center (subsemigroup) uses the pnat pow from the smaller semigroup instance -example {R} [NonUnitalSemiring R] (x : center R) (n : ℕ+) : - ((center.instNonUnitalCommSemiring _).toNonUnitalSemiring).toSemigroup.ppow n n.prop x = - x ^ n := - rfl +/-- When the ambient semiring is associative, use the inherited subsemiring structure so that +positive powers agree definitionally with the ambient powers. -/ +instance center.instNonUnitalCommSemiringOfNonUnitalSemiring : + NonUnitalCommSemiring (center R) where + __ := NonUnitalSubsemiringClass.toNonUnitalSemiring (center R) + mul_comm := Subsemigroup.center.commSemigroup.mul_comm -- no instance diamond, unlike the unital version example {R} [NonUnitalSemiring R] : - ((center.instNonUnitalCommSemiring _).toNonUnitalSemiring).toSemigroup.ppow = + ((inferInstance : NonUnitalCommSemiring (center R)).toNonUnitalSemiring).toSemigroup.ppow = (NonUnitalSubsemiringClass.toNonUnitalSemiring (center R)).toSemigroup.ppow := by with_reducible_and_instances rfl From 6b1d395f06470e6a13988f219c3dd31749c03213 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 11:40:11 -0400 Subject: [PATCH 082/127] FunLike with more IsPowApply --- Mathlib/Algebra/Group/InjSurj.lean | 6 +-- Mathlib/Data/FunLike/Group.lean | 77 ++++++++++++++++-------------- 2 files changed, 45 insertions(+), 38 deletions(-) diff --git a/Mathlib/Algebra/Group/InjSurj.lean b/Mathlib/Algebra/Group/InjSurj.lean index a4f28beeac5480..e043f23597ff2b 100644 --- a/Mathlib/Algebra/Group/InjSurj.lean +++ b/Mathlib/Algebra/Group/InjSurj.lean @@ -256,9 +256,9 @@ map that preserves `1`, `*`, `⁻¹`, and `/` to a `DivInvOneMonoid`. See note `[SMul ℤ M₁]` arguments. -/] protected abbrev divInvOneMonoid [DivInvOneMonoid M₂] (f : M₁ → M₂) (hf : Injective f) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) (inv : ∀ x, f x⁻¹ = (f x)⁻¹) - (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) - (div : ∀ x y, f (x / y) = f x / f y) (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) - (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : DivInvOneMonoid M₁ := + (div : ∀ x y, f (x / y) = f x / f y) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) + (npow : ∀ (x) (n : ℕ), f (x ^ n) = f x ^ n) (zpow : ∀ (x) (n : ℤ), f (x ^ n) = f x ^ n) : + DivInvOneMonoid M₁ := { hf.divInvMonoid f one mul inv div ppow npow zpow, hf.invOneClass f one inv with } /-- A type endowed with `1`, `*`, `⁻¹`, and `/` is a `DivisionMonoid` if it admits an injective map diff --git a/Mathlib/Data/FunLike/Group.lean b/Mathlib/Data/FunLike/Group.lean index 9b4f97249c71df..9d89b87141c1a4 100644 --- a/Mathlib/Data/FunLike/Group.lean +++ b/Mathlib/Data/FunLike/Group.lean @@ -93,16 +93,17 @@ variable [Mul F] /-- A `FunLike` type that satisfies `(f * g) x = f x * g x` is a semigroup if `β` is a semigroup. -/ @[to_additive /-- A `FunLike` type that satisfies `(f + g) x = f x + g x` is an additive semigroup if `β` is an additive semigroup. -/] -protected abbrev semigroup [Semigroup β] [IsMulApply F α β] : Semigroup F := - DFunLike.coe_injective.semigroup (fun (f : F) ↦ (f : α → β)) coe_mul +protected abbrev semigroup [Semigroup β] [Pow F ℕ+] [IsMulApply F α β] [IsPowApply ℕ+ F α β] : + Semigroup F := + DFunLike.coe_injective.semigroup (fun (f : F) ↦ (f : α → β)) coe_mul coe_pow /-- A `FunLike` type that satisfies `(f * g) x = f x * g x` is a commutative semigroup if `β` is a commutative semigroup. -/ @[to_additive /-- A `FunLike` type that satisfies `(f + g) x = f x + g x` is a commatative additive semigroup if `β` is a commatative additive semigroup. -/] -protected abbrev commSemigroup [CommSemigroup β] [IsMulApply F α β] : - CommSemigroup F := - DFunLike.coe_injective.commSemigroup (fun (f : F) ↦ (f : α → β)) coe_mul +protected abbrev commSemigroup [CommSemigroup β] [Pow F ℕ+] [IsMulApply F α β] + [IsPowApply ℕ+ F α β] : CommSemigroup F := + DFunLike.coe_injective.commSemigroup (fun (f : F) ↦ (f : α → β)) coe_mul coe_pow /-- A `FunLike` type that satisfies `(f * g) x = f x * g x` has left cancellative multiplication if `β` has left cancellative multiplication. -/ @@ -132,17 +133,18 @@ protected theorem isCancelMul [Mul β] [IsCancelMul β] [IsMulApply F α β] : left cancel semigroup. -/ @[to_additive /-- A `FunLike` type that satisfies `(f + g) x = f x + g x` is a left cancel additive semigroup if `β` is a left cancel additive semigroup. -/] -protected abbrev leftCancelSemigroup [LeftCancelSemigroup β] [IsMulApply F α β] : +protected abbrev leftCancelSemigroup [LeftCancelSemigroup β] [IsMulApply F α β] [Pow F ℕ+] + [IsPowApply ℕ+ F α β] : LeftCancelSemigroup F := - DFunLike.coe_injective.leftCancelSemigroup (fun (f : F) ↦ (f : α → β)) coe_mul + DFunLike.coe_injective.leftCancelSemigroup (fun (f : F) ↦ (f : α → β)) coe_mul coe_pow /-- A `FunLike` type that satisfies `(f * g) x = f x * g x` is a right cancel semigroup if `β` is a right cancel semigroup. -/ @[to_additive /-- A `FunLike` type that satisfies `(f + g) x = f x + g x` is a right cancel additive semigroup if `β` is a right cancel additive semigroup. -/] -protected abbrev rightCancelSemigroup [RightCancelSemigroup β] [IsMulApply F α β] : - RightCancelSemigroup F := - DFunLike.coe_injective.rightCancelSemigroup (fun (f : F) ↦ (f : α → β)) coe_mul +protected abbrev rightCancelSemigroup [RightCancelSemigroup β] [IsMulApply F α β] [Pow F ℕ+] + [IsPowApply ℕ+ F α β] : RightCancelSemigroup F := + DFunLike.coe_injective.rightCancelSemigroup (fun (f : F) ↦ (f : α → β)) coe_mul coe_pow variable [One F] @@ -153,23 +155,24 @@ protected abbrev mulOneClass [MulOneClass β] [IsOneApply F α β] [IsMulApply F MulOneClass F := DFunLike.coe_injective.mulOneClass (fun (f : F) ↦ (f : α → β)) coe_one coe_mul -variable [Pow F ℕ] +variable [Pow F ℕ+] [Pow F ℕ] /-- A `FunLike` type that satisfies `(f * g) x = f x * g x`, `1 x = 1`, and `(f ^ n) x = f x ^ n` is a monoid if `β` is a monoid. -/ @[to_additive /-- A `FunLike` type that satisfies `(f + g) x = f x + g x`, `0 x = 0`, and `(n • f) x = n • f x` is an additive monoid if `β` is an additive monoid. -/] -protected abbrev monoid [Monoid β] [IsOneApply F α β] [IsMulApply F α β] [IsPowApply ℕ F α β] : - Monoid F := - DFunLike.coe_injective.monoid (fun (f : F) ↦ (f : α → β)) coe_one coe_mul coe_pow +protected abbrev monoid [Monoid β] [IsOneApply F α β] [IsMulApply F α β] [IsPowApply ℕ+ F α β] + [IsPowApply ℕ F α β] : Monoid F := + DFunLike.coe_injective.monoid (fun (f : F) ↦ (f : α → β)) coe_one coe_mul coe_pow coe_pow /-- A `FunLike` type that satisfies `(f * g) x = f x * g x`, `1 x = 1`, and `(f ^ n) x = f x ^ n` is a left cancel monoid if `β` is a left cancel monoid. -/ @[to_additive /-- A `FunLike` type that satisfies `(f + g) x = f x + g x`, `0 x = 0`, and `(n • f) x = n • f x` is a left cancel additive monoid if `β` is a left cancel additive monoid. -/] protected abbrev leftCancelMonoid [LeftCancelMonoid β] [IsOneApply F α β] [IsMulApply F α β] - [IsPowApply ℕ F α β] : LeftCancelMonoid F := + [IsPowApply ℕ+ F α β] [IsPowApply ℕ F α β] : LeftCancelMonoid F := DFunLike.coe_injective.leftCancelMonoid (fun (f : F) ↦ (f : α → β)) coe_one coe_mul coe_pow + coe_pow /-- A `FunLike` type that satisfies `(f * g) x = f x * g x`, `1 x = 1`, and `(f ^ n) x = f x ^ n` is a right cancel monoid if `β` is a right cancel monoid. -/ @@ -177,24 +180,27 @@ is a right cancel monoid if `β` is a right cancel monoid. -/ `(n • f) x = n • f x` is a right cancel additive monoid if `β` is a right cancel additive monoid. -/] protected abbrev rightCancelMonoid [RightCancelMonoid β] [IsOneApply F α β] [IsMulApply F α β] - [IsPowApply ℕ F α β] : RightCancelMonoid F := + [IsPowApply ℕ+ F α β] [IsPowApply ℕ F α β] : RightCancelMonoid F := DFunLike.coe_injective.rightCancelMonoid (fun (f : F) ↦ (f : α → β)) coe_one coe_mul coe_pow + coe_pow /-- A `FunLike` type that satisfies `(f * g) x = f x * g x`, `1 x = 1`, and `(f ^ n) x = f x ^ n` is a cancel monoid if `β` is a cancel monoid. -/ @[to_additive /-- A `FunLike` type that satisfies `(f + g) x = f x + g x`, `0 x = 0`, and `(n • f) x = n • f x` is a cancel additive monoid if `β` is a cancel additive monoid. -/] protected abbrev cancelMonoid [CancelMonoid β] [IsOneApply F α β] [IsMulApply F α β] - [IsPowApply ℕ F α β] : CancelMonoid F := + [IsPowApply ℕ+ F α β] [IsPowApply ℕ F α β] : CancelMonoid F := DFunLike.coe_injective.cancelMonoid (fun (f : F) ↦ (f : α → β)) coe_one coe_mul coe_pow + coe_pow /-- A `FunLike` type that satisfies `(f * g) x = f x * g x`, `1 x = 1`, and `(f ^ n) x = f x ^ n` is a commutative monoid if `β` is a commutative monoid. -/ @[to_additive /-- A `FunLike` type that satisfies `(f + g) x = f x + g x`, `0 x = 0`, and `(n • f) x = n • f x` is a commutative additive monoid if `β` is a commutative additive monoid. -/] protected abbrev commMonoid [CommMonoid β] [IsOneApply F α β] [IsMulApply F α β] - [IsPowApply ℕ F α β] : CommMonoid F := + [IsPowApply ℕ+ F α β] [IsPowApply ℕ F α β] : CommMonoid F := DFunLike.coe_injective.commMonoid (fun (f : F) ↦ (f : α → β)) coe_one coe_mul coe_pow + coe_pow /-- A `FunLike` type that satisfies `(f * g) x = f x * g x`, `1 x = 1`, and `(f ^ n) x = f x ^ n` is a cancel commutative monoid if `β` is a cancel commutative monoid. -/ @@ -202,8 +208,9 @@ is a cancel commutative monoid if `β` is a cancel commutative monoid. -/ `(n • f) x = n • f x` is a cancel commutative additive monoid if `β` is a cancel commutative additive monoid. -/] protected abbrev cancelCommMonoid [CancelCommMonoid β] [IsOneApply F α β] [IsMulApply F α β] - [IsPowApply ℕ F α β] : CancelCommMonoid F := + [IsPowApply ℕ+ F α β] [IsPowApply ℕ F α β] : CancelCommMonoid F := DFunLike.coe_injective.cancelCommMonoid (fun (f : F) ↦ (f : α → β)) coe_one coe_mul coe_pow + coe_pow variable [Inv F] @@ -226,53 +233,53 @@ variable [Div F] [Pow F ℤ] /-- A `FunLike` type is a `DivInvMonoid` if `β` is a `DivInvMonoid`. -/ @[to_additive subNegMonoid /-- A `FunLike` type is a `SubNegMonoid` if `β` is a `SubNegMonoid`. -/] protected abbrev divInvMonoid [DivInvMonoid β] [IsOneApply F α β] [IsMulApply F α β] - [IsInvApply F α β] [IsDivApply F α β] [IsPowApply ℕ F α β] [IsPowApply ℤ F α β] : - DivInvMonoid F := + [IsInvApply F α β] [IsDivApply F α β] [IsPowApply ℕ+ F α β] [IsPowApply ℕ F α β] + [IsPowApply ℤ F α β] : DivInvMonoid F := DFunLike.coe_injective.divInvMonoid (fun (f : F) ↦ (f : α → β)) coe_one coe_mul coe_inv coe_div - coe_pow coe_pow + coe_pow coe_pow coe_pow /-- A `FunLike` type is a `DivInvOneMonoid` if `β` is a `DivInvOneMonoid`. -/ @[to_additive /-- A `FunLike` type is a `SubNegOneMonoid` if `β` is a `SubNegOneMonoid`. -/] protected abbrev divInvOneMonoid [DivInvOneMonoid β] [IsOneApply F α β] [IsMulApply F α β] - [IsInvApply F α β] [IsDivApply F α β] [IsPowApply ℕ F α β] [IsPowApply ℤ F α β] : - DivInvOneMonoid F := + [IsInvApply F α β] [IsDivApply F α β] [IsPowApply ℕ+ F α β] [IsPowApply ℕ F α β] + [IsPowApply ℤ F α β] : DivInvOneMonoid F := DFunLike.coe_injective.divInvOneMonoid (fun (f : F) ↦ (f : α → β)) coe_one coe_mul - coe_inv coe_div coe_pow coe_pow + coe_inv coe_div coe_pow coe_pow coe_pow /-- A `FunLike` type is a division monoid if `β` is a division monoid. -/ @[to_additive /-- A `FunLike` type is a subtraction monoid if `β` is a subtraction monoid. -/] protected abbrev divisionMonoid [DivisionMonoid β] [IsOneApply F α β] [IsMulApply F α β] - [IsInvApply F α β] [IsDivApply F α β] [IsPowApply ℕ F α β] [IsPowApply ℤ F α β] : - DivisionMonoid F := + [IsInvApply F α β] [IsDivApply F α β] [IsPowApply ℕ+ F α β] [IsPowApply ℕ F α β] + [IsPowApply ℤ F α β] : DivisionMonoid F := DFunLike.coe_injective.divisionMonoid (fun (f : F) ↦ (f : α → β)) coe_one coe_mul - coe_inv coe_div coe_pow coe_pow + coe_inv coe_div coe_pow coe_pow coe_pow /-- A `FunLike` type is a division commutative monoid if `β` is a division commutative monoid. -/ @[to_additive subtractionCommMonoid /-- A `FunLike` type is a subtraction commutative monoid if `β` is a subtraction commutative monoid. -/] protected abbrev divisionCommMonoid [DivisionCommMonoid β] [IsOneApply F α β] [IsMulApply F α β] - [IsInvApply F α β] [IsDivApply F α β] [IsPowApply ℕ F α β] [IsPowApply ℤ F α β] : - DivisionCommMonoid F := + [IsInvApply F α β] [IsDivApply F α β] [IsPowApply ℕ+ F α β] [IsPowApply ℕ F α β] + [IsPowApply ℤ F α β] : DivisionCommMonoid F := DFunLike.coe_injective.divisionCommMonoid (fun (f : F) ↦ (f : α → β)) coe_one coe_mul coe_inv - coe_div coe_pow coe_pow + coe_div coe_pow coe_pow coe_pow /-- A `FunLike` type is a group if `β` is a group. -/ @[to_additive /-- A `FunLike` type is an additive group if `β` is an additive group. -/] protected abbrev group [Group β] [IsOneApply F α β] [IsMulApply F α β] [IsInvApply F α β] - [IsDivApply F α β] [IsPowApply ℕ F α β] [IsPowApply ℤ F α β] : + [IsDivApply F α β] [IsPowApply ℕ+ F α β] [IsPowApply ℕ F α β] [IsPowApply ℤ F α β] : Group F := DFunLike.coe_injective.group (fun (f : F) ↦ (f : α → β)) coe_one coe_mul coe_inv coe_div coe_pow - coe_pow + coe_pow coe_pow /-- A `FunLike` type is a commutative group if `β` is a commutative group. -/ @[to_additive /-- A `FunLike` type is an additive commutative group if `β` is an additive commutative group. -/] protected abbrev commGroup [CommGroup β] [IsOneApply F α β] [IsMulApply F α β] [IsInvApply F α β] - [IsDivApply F α β] [IsPowApply ℕ F α β] [IsPowApply ℤ F α β] : + [IsDivApply F α β] [IsPowApply ℕ+ F α β] [IsPowApply ℕ F α β] [IsPowApply ℤ F α β] : CommGroup F := DFunLike.coe_injective.commGroup (fun (f : F) ↦ (f : α → β)) coe_one coe_mul coe_inv coe_div - coe_pow coe_pow + coe_pow coe_pow coe_pow end GroupInstances From 16664f6da1ddf591019f7ae04bf835791799fbe1 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 11:59:23 -0400 Subject: [PATCH 083/127] Ixx instances --- .../Algebra/Order/GroupWithZero/Basic.lean | 19 +++++++- .../Algebra/Order/Interval/Set/Instances.lean | 48 +++++++++++++++---- 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/Mathlib/Algebra/Order/GroupWithZero/Basic.lean b/Mathlib/Algebra/Order/GroupWithZero/Basic.lean index b1126cc793c730..b8037233d1b020 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Basic.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Basic.lean @@ -371,7 +371,7 @@ section SemigroupWithZero variable [SemigroupWithZero M₀] variable [Preorder M₀] {a b : M₀} -@[simp] lemma ppow_nonneg [PosMulMono M₀] (n : ℕ+) (ha : 0 ≤ a) : 0 ≤ a ^ n := by +@[simp] lemma ppow_nonneg [PosMulMono M₀] (ha : 0 ≤ a) (n : ℕ+) : 0 ≤ a ^ n := by induction n using Semigroup.ppow_induction a · exact ha · exact mul_nonneg ha ‹_› @@ -403,6 +403,12 @@ lemma pow_right_anti₀ [PosMulMono M₀] (ha₀ : 0 ≤ a) (ha₁ : a ≤ 1) : gcongr exact pow_nonneg ha₀ n +-- not `Antitone` because no order on `ℕ+` here +lemma ppow_right_anti₀ [PosMulMono M₀] (ha₀ : 0 ≤ a) (ha₁ : a ≤ 1) ⦃m n : ℕ+⦄ (hm : m.val ≤ n.val) : + a ^ n ≤ a ^ m := by + rw [← npow_val_eq_ppow, ← npow_val_eq_ppow] + exact pow_right_anti₀ ha₀ ha₁ hm + lemma pow_le_pow_of_le_one [PosMulMono M₀] (ha₀ : 0 ≤ a) (ha₁ : a ≤ 1) {m n : ℕ} (hmn : m ≤ n) : a ^ n ≤ a ^ m := pow_right_anti₀ ha₀ ha₁ hmn @@ -412,6 +418,13 @@ lemma pow_le_of_le_one [PosMulMono M₀] (h₀ : 0 ≤ a) (h₁ : a ≤ 1) (hn : lemma sq_le [PosMulMono M₀] (h₀ : 0 ≤ a) (h₁ : a ≤ 1) : a ^ 2 ≤ a := pow_le_of_le_one h₀ h₁ two_ne_zero +lemma ppow_le_one₀ [PosMulMono M₀] {n : ℕ+} (ha₀ : 0 ≤ a) (ha₁ : a ≤ 1) : a ^ n ≤ 1 := by + induction n using Semigroup.ppow_induction a with + | h1 => exact ha₁ + | hsucc n IH => + refine mul_le_of_mul_le_of_nonneg_left ?_ IH ha₀ + simp [ha₁] + lemma pow_le_one₀ [PosMulMono M₀] {n : ℕ} (ha₀ : 0 ≤ a) (ha₁ : a ≤ 1) : a ^ n ≤ 1 := pow_zero a ▸ pow_right_anti₀ ha₀ ha₁ (Nat.zero_le n) @@ -446,6 +459,10 @@ lemma pow_lt_one₀ [PosMulMono M₀] (h₀ : 0 ≤ a) (h₁ : a < 1) : ∀ {n : | n + 1, _ => by rw [pow_succ']; exact mul_lt_one_of_nonneg_of_lt_one_left h₀ h₁ (pow_le_one₀ h₀ h₁.le) +lemma ppow_lt_one₀ [PosMulMono M₀] (h₀ : 0 ≤ a) (h₁ : a < 1) (n : ℕ+) : a ^ n < 1 := by + rw [← npow_val_eq_ppow] + exact pow_lt_one₀ h₀ h₁ n.prop.ne' + lemma pow_right_mono₀ [ZeroLEOneClass M₀] [PosMulMono M₀] (h : 1 ≤ a) : Monotone (a ^ ·) := monotone_nat_of_le_succ fun n => by rw [pow_succ]; exact le_mul_of_one_le_right (pow_nonneg (zero_le_one.trans h) _) h diff --git a/Mathlib/Algebra/Order/Interval/Set/Instances.lean b/Mathlib/Algebra/Order/Interval/Set/Instances.lean index 71bba2fbd9b2bb..9ebf5ea32e601d 100644 --- a/Mathlib/Algebra/Order/Interval/Set/Instances.lean +++ b/Mathlib/Algebra/Order/Interval/Set/Instances.lean @@ -115,6 +115,9 @@ theorem le_one {t : Icc (0 : R) 1} : t ≤ 1 := instance instMul : Mul (Icc (0 : R) 1) where mul p q := ⟨p * q, ⟨mul_nonneg p.2.1 q.2.1, mul_le_one₀ p.2.2 q.2.1 q.2.2⟩⟩ +instance instPPow : Pow (Icc (0 : R) 1) ℕ+ where + pow p n := ⟨p.1 ^ n, ⟨ppow_nonneg p.2.1 n, ppow_le_one₀ p.2.1 p.2.2⟩⟩ + instance instPow : Pow (Icc (0 : R) 1) ℕ where pow p n := ⟨p.1 ^ n, ⟨pow_nonneg p.2.1 n, pow_le_one₀ p.2.1 p.2.2⟩⟩ @@ -122,6 +125,10 @@ instance instPow : Pow (Icc (0 : R) 1) ℕ where theorem coe_mul (x y : Icc (0 : R) 1) : ↑(x * y) = (x * y : R) := rfl +@[simp, norm_cast] +theorem coe_ppow (x : Icc (0 : R) 1) (n : ℕ+) : ↑(x ^ n) = ((x : R) ^ n) := + rfl + @[simp, norm_cast] theorem coe_pow (x : Icc (0 : R) 1) (n : ℕ) : ↑(x ^ n) = ((x : R) ^ n) := rfl @@ -133,11 +140,11 @@ theorem mul_le_right {x y : Icc (0 : R) 1} : x * y ≤ y := (mul_le_mul_of_nonneg_right x.2.2 y.2.1).trans_eq (one_mul _) instance instMonoidWithZero : MonoidWithZero (Icc (0 : R) 1) := fast_instance% - Subtype.coe_injective.monoidWithZero _ coe_zero coe_one coe_mul coe_pow + Subtype.coe_injective.monoidWithZero _ coe_zero coe_one coe_mul coe_ppow coe_pow instance instCommMonoidWithZero {R : Type*} [CommSemiring R] [PartialOrder R] [IsOrderedRing R] : CommMonoidWithZero (Icc (0 : R) 1) := fast_instance% - Subtype.coe_injective.commMonoidWithZero _ coe_zero coe_one coe_mul coe_pow + Subtype.coe_injective.commMonoidWithZero _ coe_zero coe_one coe_mul coe_ppow coe_pow instance instIsCancelMulZero {R : Type*} [Ring R] [PartialOrder R] [IsOrderedRing R] [NoZeroDivisors R] : @@ -207,16 +214,23 @@ instance instMul : Mul (Ico (0 : R) 1) where mul p q := ⟨p * q, ⟨mul_nonneg p.2.1 q.2.1, mul_lt_one_of_nonneg_of_lt_one_right p.2.2.le q.2.1 q.2.2⟩⟩ +instance instPPow : Pow (Ico (0 : R) 1) ℕ+ where + pow p n := ⟨p.1 ^ n, ⟨ppow_nonneg p.2.1 n, ppow_lt_one₀ p.2.1 p.2.2 n⟩⟩ + @[simp, norm_cast] theorem coe_mul (x y : Ico (0 : R) 1) : ↑(x * y) = (x * y : R) := rfl +@[simp, norm_cast] +theorem coe_ppow (x : Ico (0 : R) 1) (n : ℕ+) : ↑(x ^ n) = ((x : R) ^ n) := + rfl + instance instSemigroup : Semigroup (Ico (0 : R) 1) := fast_instance% - Subtype.coe_injective.semigroup _ coe_mul + Subtype.coe_injective.semigroup _ coe_mul coe_ppow instance instCommSemigroup {R : Type*} [CommSemiring R] [PartialOrder R] [IsOrderedRing R] : CommSemigroup (Ico (0 : R) 1) := fast_instance% - Subtype.coe_injective.commSemigroup _ coe_mul + Subtype.coe_injective.commSemigroup _ coe_mul coe_ppow /-- The coercion from `Set.Ico 0 1` as a `MulHom`. -/ @[simps] @@ -268,6 +282,9 @@ theorem le_one {t : Ioc (0 : R) 1} : t ≤ 1 := instance instMul : Mul (Ioc (0 : R) 1) where mul p q := ⟨p.1 * q.1, ⟨mul_pos p.2.1 q.2.1, mul_le_one₀ p.2.2 (le_of_lt q.2.1) q.2.2⟩⟩ +instance instPPow : Pow (Ioc (0 : R) 1) ℕ+ where + pow p n := ⟨p.1 ^ n, ⟨ppow_pos p.2.1 n, ppow_le_one₀ (le_of_lt p.2.1) p.2.2⟩⟩ + instance instPow : Pow (Ioc (0 : R) 1) ℕ where pow p n := ⟨p.1 ^ n, ⟨pow_pos p.2.1 n, pow_le_one₀ (le_of_lt p.2.1) p.2.2⟩⟩ @@ -275,23 +292,27 @@ instance instPow : Pow (Ioc (0 : R) 1) ℕ where theorem coe_mul (x y : Ioc (0 : R) 1) : ↑(x * y) = (x * y : R) := rfl +@[simp, norm_cast] +theorem coe_ppow (x : Ioc (0 : R) 1) (n : ℕ+) : ↑(x ^ n) = ((x : R) ^ n) := + rfl + @[simp, norm_cast] theorem coe_pow (x : Ioc (0 : R) 1) (n : ℕ) : ↑(x ^ n) = ((x : R) ^ n) := rfl instance instSemigroup : Semigroup (Ioc (0 : R) 1) := fast_instance% - Subtype.coe_injective.semigroup _ coe_mul + Subtype.coe_injective.semigroup _ coe_mul coe_ppow instance instMonoid : Monoid (Ioc (0 : R) 1) := fast_instance% - Subtype.coe_injective.monoid _ coe_one coe_mul coe_pow + Subtype.coe_injective.monoid _ coe_one coe_mul coe_ppow coe_pow instance instCommSemigroup {R : Type*} [CommSemiring R] [PartialOrder R] [IsStrictOrderedRing R] : CommSemigroup (Ioc (0 : R) 1) := fast_instance% - Subtype.coe_injective.commSemigroup _ coe_mul + Subtype.coe_injective.commSemigroup _ coe_mul coe_ppow instance instCommMonoid {R : Type*} [CommSemiring R] [PartialOrder R] [IsStrictOrderedRing R] : CommMonoid (Ioc (0 : R) 1) := fast_instance% - Subtype.coe_injective.commMonoid _ coe_one coe_mul coe_pow + Subtype.coe_injective.commMonoid _ coe_one coe_mul coe_ppow coe_pow instance instCancelMonoid {R : Type*} [Ring R] [PartialOrder R] [IsStrictOrderedRing R] [IsDomain R] : CancelMonoid (Ioc (0 : R) 1) := @@ -332,16 +353,23 @@ instance instMul : Mul (Ioo (0 : R) 1) where mul p q := ⟨p.1 * q.1, ⟨mul_pos p.2.1 q.2.1, mul_lt_one_of_nonneg_of_lt_one_right p.2.2.le q.2.1.le q.2.2⟩⟩ +instance instPPow : Pow (Ioo (0 : R) 1) ℕ+ where + pow p n := ⟨p.1 ^ n, ⟨ppow_pos p.2.1 n, ppow_lt_one₀ (le_of_lt p.2.1) p.2.2 n⟩⟩ + @[simp, norm_cast] theorem coe_mul (x y : Ioo (0 : R) 1) : ↑(x * y) = (x * y : R) := rfl +@[simp, norm_cast] +theorem coe_ppow (x : Ioo (0 : R) 1) (n : ℕ+) : ↑(x ^ n) = ((x : R) ^ n) := + rfl + instance instSemigroup : Semigroup (Ioo (0 : R) 1) := fast_instance% - Subtype.coe_injective.semigroup _ coe_mul + Subtype.coe_injective.semigroup _ coe_mul coe_ppow instance instCommSemigroup {R : Type*} [CommSemiring R] [PartialOrder R] [IsStrictOrderedRing R] : CommSemigroup (Ioo (0 : R) 1) := fast_instance% - Subtype.coe_injective.commSemigroup _ coe_mul + Subtype.coe_injective.commSemigroup _ coe_mul coe_ppow /-- The coercion from `Set.Ioo 0 1` as a `MulHom`. -/ @[simps] From 5a7ef0cdd942e97fed6f57d664cfbb08e0c70d3e Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 12:15:48 -0400 Subject: [PATCH 084/127] transferinstance --- Mathlib/Algebra/GroupWithZero/TransferInstance.lean | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mathlib/Algebra/GroupWithZero/TransferInstance.lean b/Mathlib/Algebra/GroupWithZero/TransferInstance.lean index 06c18605d6a46e..a9e10a060aae1d 100644 --- a/Mathlib/Algebra/GroupWithZero/TransferInstance.lean +++ b/Mathlib/Algebra/GroupWithZero/TransferInstance.lean @@ -30,6 +30,7 @@ variable (e : α ≃ β) protected abbrev semigroupWithZero [SemigroupWithZero β] : SemigroupWithZero α := by let mul := e.mul let zero := e.zero + let ppow := e.pow ℕ+ apply e.injective.semigroupWithZero _ <;> intros <;> exact e.apply_symm_apply _ /-- Transfer `MulZeroClass` across an `Equiv` -/ @@ -48,6 +49,7 @@ protected abbrev mulZeroOneClass [MulZeroOneClass β] : MulZeroOneClass α := by /-- Transfer `MonoidWithZero` across an `Equiv` -/ protected abbrev monoidWithZero [MonoidWithZero β] : MonoidWithZero α := by let _ := e.mulZeroOneClass + let _ := e.pow ℕ+ let _ := e.pow ℕ apply e.injective.monoidWithZero _ <;> intros <;> exact e.apply_symm_apply _ From 03a77855a55f6ebab0c130c50a90999a81398816 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 12:15:53 -0400 Subject: [PATCH 085/127] formatting --- Mathlib/Data/Num/Lemmas.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/Data/Num/Lemmas.lean b/Mathlib/Data/Num/Lemmas.lean index b5ffaa3f24b859..19651eccb5a47c 100644 --- a/Mathlib/Data/Num/Lemmas.lean +++ b/Mathlib/Data/Num/Lemmas.lean @@ -523,7 +523,6 @@ example (n : PosNum) (m : PosNum) : n ≤ n + m := by exact Nat.le_add_right _ _ ``` -/ - scoped macro (name := transfer_rw) "transfer_rw" : tactic => `(tactic| (repeat first | rw [← to_nat_inj] | rw [← lt_to_nat] | rw [← le_to_nat] | rw [← psmulRec_to_nat] repeat first | rw [add_to_nat] | rw [mul_to_nat] | rw [cast_one] | rw [cast_zero])) From 9d371f8a7a84eca4dc8ed2a81a17b1590e02057a Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 12:16:54 -0400 Subject: [PATCH 086/127] subfield --- Mathlib/Algebra/Field/Subfield/Defs.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Field/Subfield/Defs.lean b/Mathlib/Algebra/Field/Subfield/Defs.lean index 39d027bfa4c262..cdaba4614f5171 100644 --- a/Mathlib/Algebra/Field/Subfield/Defs.lean +++ b/Mathlib/Algebra/Field/Subfield/Defs.lean @@ -110,8 +110,8 @@ instance (priority := 75) toDivisionRing (s : S) : DivisionRing s := fast_instan Subtype.coe_injective.divisionRing ((↑) : s → K) rfl rfl (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) - (fun _ _ ↦ rfl) (coe_nnqsmul _) (coe_qsmul _) (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) - (fun _ ↦ rfl) (fun _ ↦ rfl) (fun _ ↦ rfl) (fun _ ↦ rfl) + (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) (coe_nnqsmul _) (coe_qsmul _) (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) + (fun _ _ ↦ rfl) (fun _ ↦ rfl) (fun _ ↦ rfl) (fun _ ↦ rfl) (fun _ ↦ rfl) -- Prefer subclasses of `Field` over subclasses of `SubfieldClass`. /-- A subfield of a field inherits a field structure -/ @@ -120,8 +120,8 @@ instance (priority := 75) toField {K} [Field K] [SetLike S K] [SubfieldClass S K Subtype.coe_injective.field ((↑) : s → K) rfl rfl (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) - (coe_nnqsmul _) (coe_qsmul _) (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ ↦ rfl) - (fun _ ↦ rfl) (fun _ ↦ rfl) (fun _ ↦ rfl) + (fun _ _ ↦ rfl) (coe_nnqsmul _) (coe_qsmul _) (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) + (fun _ _ ↦ rfl) (fun _ ↦ rfl) (fun _ ↦ rfl) (fun _ ↦ rfl) (fun _ ↦ rfl) end SubfieldClass From 61b5b56d200ac847b8f2b45f69653e45a76cf2e1 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 16:08:24 -0400 Subject: [PATCH 087/127] ppowRec on the right, matches core npowRec, and match axiom arg order --- Mathlib/Algebra/Group/Defs.lean | 18 +++++++----- Mathlib/Algebra/Group/InjSurj.lean | 2 +- Mathlib/Algebra/Group/PPow/Basic.lean | 16 +++++----- Mathlib/Algebra/Group/PPow/Defs.lean | 29 +++++++++++++++---- Mathlib/Algebra/Group/Subsemigroup/Defs.lean | 2 +- .../Algebra/Order/GroupWithZero/Basic.lean | 4 +-- .../Algebra/Order/Monoid/Unbundled/Pow.lean | 4 +-- Mathlib/Algebra/Order/Nonneg/Basic.lean | 4 +-- Mathlib/Data/Rat/Defs.lean | 6 ++-- Mathlib/GroupTheory/Congruence/Defs.lean | 2 +- 10 files changed, 54 insertions(+), 33 deletions(-) diff --git a/Mathlib/Algebra/Group/Defs.lean b/Mathlib/Algebra/Group/Defs.lean index 534bf57536dda9..d23cd53b89d58e 100644 --- a/Mathlib/Algebra/Group/Defs.lean +++ b/Mathlib/Algebra/Group/Defs.lean @@ -188,14 +188,14 @@ Use instead `a ^ n`, which has better definitional behavior. -/ def ppowRec {M : Type*} [Mul M] : ∀ n : ℕ, 0 < n → M → M | 0, h, _ => (Nat.ne_of_lt h rfl).elim | 1, _, a => a - | n + 2, _, a => a * ppowRec (n + 1) n.succ_pos a + | n + 2, _, a => ppowRec (n + 1) n.succ_pos a * a /-- The fundamental scalar multipication in an additive semigroup. `psmulRec n a = a+a+...+a` n times. Use instead `a ^ n`, which has better definitional behavior. -/ def psmulRec {M : Type*} [Add M] : ∀ n : ℕ, 0 < n → M → M | 0, h, _ => (Nat.ne_of_lt h rfl).elim | 1, _, a => a - | n + 2, _, a => a + psmulRec (n + 1) n.succ_pos a + | n + 2, _, a => psmulRec (n + 1) n.succ_pos a + a attribute [to_additive existing] ppowRec @@ -206,7 +206,7 @@ class Semigroup (G : Type u) extends Mul G where /-- Positive integer power operation -/ ppow : ∀ n : ℕ, 0 < n → G → G := ppowRec ppow_one : ∀ g, ppow 1 Nat.one_pos g = g := by intros; rfl - ppow_succ : ∀ g n, ppow (n + 2) (n + 1).succ_pos g = g * ppow (n + 1) n.succ_pos g := + ppow_succ : ∀ n g, ppow (n + 2) (n + 1).succ_pos g = ppow (n + 1) n.succ_pos g * g := by intros; rfl /-- An additive semigroup is a type with an associative `(+)`. -/ @@ -216,7 +216,7 @@ class AddSemigroup (G : Type u) extends Add G where /-- Positive integer scalar multiplication -/ psmul : ∀ n : ℕ, 0 < n → G → G := psmulRec psmul_one : ∀ g, psmul 1 Nat.one_pos g = g := by intros; rfl - psmul_succ : ∀ g n, psmul (n + 2) (n + 1).succ_pos g = g + psmul (n + 1) n.succ_pos g := + psmul_succ : ∀ n g, psmul (n + 2) (n + 1).succ_pos g = psmul (n + 1) n.succ_pos g + g := by intros; rfl attribute [to_additive] Semigroup @@ -230,10 +230,12 @@ theorem mul_assoc : ∀ a b c : G, a * b * c = a * (b * c) := Semigroup.mul_assoc @[to_additive Semigroup.succ_psmul'] -lemma Semigroup.ppow_succ' (a : G) : ∀ n : ℕ, - Semigroup.ppow (n + 2) (Nat.succ_pos (n + 1)) a = Semigroup.ppow (n + 1) (Nat.succ_pos n) a * a - | .zero => by rw [Semigroup.ppow_succ, Semigroup.ppow_one] - | .succ n => by rw [Semigroup.ppow_succ _ n, Semigroup.ppow_succ, Semigroup.ppow_succ', mul_assoc] +lemma Semigroup.ppow_succ' (n : ℕ) (a : G) : + Semigroup.ppow (n + 2) (Nat.succ_pos (n + 1)) a = + a * Semigroup.ppow (n + 1) (Nat.succ_pos n) a := by + induction n with + | zero => rw [Semigroup.ppow_succ, Semigroup.ppow_one] + | succ n IH => rw [Semigroup.ppow_succ n, Semigroup.ppow_succ, IH, mul_assoc] end Semigroup diff --git a/Mathlib/Algebra/Group/InjSurj.lean b/Mathlib/Algebra/Group/InjSurj.lean index e043f23597ff2b..b6288cb6690aa2 100644 --- a/Mathlib/Algebra/Group/InjSurj.lean +++ b/Mathlib/Algebra/Group/InjSurj.lean @@ -341,7 +341,7 @@ protected abbrev semigroup [Pow M₂ ℕ+] [Semigroup M₁] (f : M₁ → M₂) mul_assoc := hf.forall₃.2 fun x y z => by simp only [← mul, mul_assoc] ppow := fun n hn x => x ^ (PNat.mk n hn : ℕ+) ppow_one := hf.forall.2 fun x => by simp [← ppow] - ppow_succ := hf.forall.2 fun x n => by + ppow_succ n := hf.forall.2 fun n => by simp [← ppow, ← mul, ← Semigroup.ppow_eq_pow, Semigroup.ppow_succ] /-- A type endowed with `*` is a commutative semigroup, if it admits a surjective map that preserves diff --git a/Mathlib/Algebra/Group/PPow/Basic.lean b/Mathlib/Algebra/Group/PPow/Basic.lean index a8abb95b16bd60..7af6898da3cb7b 100644 --- a/Mathlib/Algebra/Group/PPow/Basic.lean +++ b/Mathlib/Algebra/Group/PPow/Basic.lean @@ -20,28 +20,28 @@ section Semigroup variable [Semigroup M] -@[to_additive succ_psmul'] +@[to_additive (reorder := x n) succ_psmul'] lemma ppow_succ' (x : M) (n : ℕ+) : x ^ (n + 1) = x * x ^ n := - n.recOn (Semigroup.ppow_succ x 0) fun k _ => Semigroup.ppow_succ x k + n.recOn (Semigroup.ppow_succ' 0 x) fun k _ => Semigroup.ppow_succ' k x -@[to_additive succ_psmul] +@[to_additive (reorder := x n) succ_psmul] lemma ppow_succ (x : M) (n : ℕ+) : x ^ (n + 1) = x ^ n * x := - n.recOn (Semigroup.ppow_succ' x 0) fun k _ => Semigroup.ppow_succ' x k + n.recOn (Semigroup.ppow_succ 0 x) fun k _ => Semigroup.ppow_succ k x -@[to_additive add_psmul] +@[to_additive (reorder := n x m) add_psmul] lemma ppow_add (x : M) (n m : ℕ+) : x ^ (n + m) = x ^ n * x ^ m := m.recOn (by simp [ppow_succ]) fun k hk => by rw [← add_assoc, ppow_succ, ppow_succ, hk, mul_assoc] -@[to_additive mul_comm_psmul] +@[to_additive (reorder := n x m) mul_comm_psmul] lemma ppow_mul_comm (x : M) (n m : ℕ+) : x ^ n * x ^ m = x ^ m * x ^ n := by simp only [← ppow_add, add_comm] -@[to_additive mul_comm_psmul'] +@[to_additive (reorder := n x) rmul_comm_psmul'] lemma ppow_mul_comm' (x : M) (n : ℕ+) : x ^ n * x = x * x ^ n := by simpa only [ppow_one] using ppow_mul_comm x n 1 -@[to_additive mul_psmul] +@[to_additive (reorder := n x m) mul_psmul] lemma ppow_mul (x : M) (n m : ℕ+) : x ^ (n * m) = (x ^ n) ^ m := m.recOn (by simp) fun k hk => by simp [mul_add, ppow_add, hk] diff --git a/Mathlib/Algebra/Group/PPow/Defs.lean b/Mathlib/Algebra/Group/PPow/Defs.lean index 96c4eeb44b71b3..9c02a220fbe654 100644 --- a/Mathlib/Algebra/Group/PPow/Defs.lean +++ b/Mathlib/Algebra/Group/PPow/Defs.lean @@ -47,7 +47,7 @@ lemma Semigroup.ppow_induction [Semigroup M] {p : ℕ+ → M → Prop} (x : M) ( (h1 : p 1 x) (hsucc : ∀ n : ℕ, p (PNat.mk (n + 1) (Nat.succ_pos n)) (x ^ PNat.mk (n + 1) (Nat.succ_pos n)) → p (PNat.mk (n + 2) (Nat.succ_pos (n + 1))) - (x * x ^ PNat.mk (n + 1) (Nat.succ_pos n))) : + (x ^ PNat.mk (n + 1) (Nat.succ_pos n) * x)) : p n (x ^ n) := by rcases n with ⟨n, hn⟩ rcases Nat.exists_eq_succ_of_ne_zero (Nat.ne_of_gt hn) with ⟨k, rfl⟩ @@ -62,11 +62,30 @@ lemma Semigroup.ppow_induction [Semigroup M] {p : ℕ+ → M → Prop} (x : M) ( @[to_additive] lemma ppow_mk_add_one [Semigroup M] (x : M) {n : ℕ} (hn : n ≠ 0 := by exact Nat.succ_ne_zero _) : - x ^ (PNat.mk (n + 1) (Nat.succ_pos n)) = x * x ^ (PNat.mk n (Nat.pos_of_ne_zero hn)) := by + x ^ (PNat.mk (n + 1) (Nat.succ_pos n)) = x ^ (PNat.mk n (Nat.pos_of_ne_zero hn)) * x := by cases n · contradiction · simp [← Semigroup.ppow_eq_pow, PNat.mk, Semigroup.ppow_succ] +@[to_additive] +lemma ppow_mk_add_one' [Semigroup M] (x : M) {n : ℕ} (hn : n ≠ 0 := by exact Nat.succ_ne_zero _) : + x ^ (PNat.mk (n + 1) (Nat.succ_pos n)) = x * x ^ (PNat.mk n (Nat.pos_of_ne_zero hn)) := by + cases n + · contradiction + · simp [← Semigroup.ppow_eq_pow, PNat.mk, Semigroup.ppow_succ'] + +@[to_additive (attr := elab_as_elim)] +lemma Semigroup.ppow_induction' [Semigroup M] {p : ℕ+ → M → Prop} (x : M) (n : ℕ+) + (h1 : p 1 x) (hsucc : ∀ n : ℕ, + p (PNat.mk (n + 1) (Nat.succ_pos n)) (x ^ PNat.mk (n + 1) (Nat.succ_pos n)) → + p (PNat.mk (n + 2) (Nat.succ_pos (n + 1))) + (x * x ^ PNat.mk (n + 1) (Nat.succ_pos n))) : + p n (x ^ n) := by + induction n using Semigroup.ppow_induction x + · exact h1 + · rw [← ppow_mk_add_one, ppow_mk_add_one'] + exact hsucc _ ‹_› + -- not marked as `simp` because in a monoid we probably prefer powers with type `ℕ` @[to_additive (attr := norm_cast)] theorem npow_val_eq_ppow [Monoid M] (n : ℕ+) (x : M) : x ^ n.val = x ^ n := by @@ -74,7 +93,7 @@ theorem npow_val_eq_ppow [Monoid M] (n : ℕ+) (x : M) : x ^ n.val = x ^ n := by | h1 => simp | hsucc n IH => simp only [mk_coe] at IH - simp [pow_succ' _ (n + 1), IH] + simp [pow_succ _ (n + 1), IH] -- This lemma is higher priority than later `smul_zero` so that the `simpNF` is happy @[to_additive (attr := simp high) psmul_zero] lemma one_ppow [Monoid M] (n : ℕ+) : @@ -90,7 +109,7 @@ lemma mul_ppow (x y : M) (n : ℕ+) : (x * y) ^ n = x ^ n * y ^ n := by induction n using Semigroup.ppow_induction (x * y) with | h1 => simp | hsucc n IH => - rw [ppow_mk_add_one x, ppow_mk_add_one y, - IH, mul_assoc, mul_comm y, ← mul_assoc, ← mul_assoc, mul_comm y, ← mul_assoc] + rw [ppow_mk_add_one x, ppow_mk_add_one y, IH, ← mul_assoc, mul_assoc _ _ x, mul_comm _ x, + ← mul_assoc, ← mul_assoc] end CommSemigroup diff --git a/Mathlib/Algebra/Group/Subsemigroup/Defs.lean b/Mathlib/Algebra/Group/Subsemigroup/Defs.lean index b5fa3852f0855c..c93c52673989b6 100644 --- a/Mathlib/Algebra/Group/Subsemigroup/Defs.lean +++ b/Mathlib/Algebra/Group/Subsemigroup/Defs.lean @@ -290,7 +290,7 @@ lemma ppow_coe_mem {M A : Type*} [Semigroup M] [SetLike A M] [hA : MulMemClass A | zero => simp [ppow_one] | succ n IH => rw [ppow_mk_add_one] - exact mul_mem x.2 (IH Nat.succ_pos') + exact mul_mem (IH Nat.succ_pos') x.2 -- lower priority so other instances are found first /-- Iterated multiplication via exponentiation by a `ℕ+` is inherited by a submagma. -/ diff --git a/Mathlib/Algebra/Order/GroupWithZero/Basic.lean b/Mathlib/Algebra/Order/GroupWithZero/Basic.lean index b8037233d1b020..4c0e1ec30fb472 100644 --- a/Mathlib/Algebra/Order/GroupWithZero/Basic.lean +++ b/Mathlib/Algebra/Order/GroupWithZero/Basic.lean @@ -374,7 +374,7 @@ variable [Preorder M₀] {a b : M₀} @[simp] lemma ppow_nonneg [PosMulMono M₀] (ha : 0 ≤ a) (n : ℕ+) : 0 ≤ a ^ n := by induction n using Semigroup.ppow_induction a · exact ha - · exact mul_nonneg ha ‹_› + · exact mul_nonneg ‹_› ha end SemigroupWithZero @@ -419,7 +419,7 @@ lemma sq_le [PosMulMono M₀] (h₀ : 0 ≤ a) (h₁ : a ≤ 1) : a ^ 2 ≤ a := pow_le_of_le_one h₀ h₁ two_ne_zero lemma ppow_le_one₀ [PosMulMono M₀] {n : ℕ+} (ha₀ : 0 ≤ a) (ha₁ : a ≤ 1) : a ^ n ≤ 1 := by - induction n using Semigroup.ppow_induction a with + induction n using Semigroup.ppow_induction' a with | h1 => exact ha₁ | hsucc n IH => refine mul_le_of_mul_le_of_nonneg_left ?_ IH ha₀ diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean index fd76b3c5a6209f..b226d0fcce3369 100644 --- a/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean @@ -37,14 +37,14 @@ variable [MulLeftMono M] {a : M} theorem one_le_ppow_of_le (ha : 1 ≤ a) (n : ℕ+) : 1 ≤ a ^ n := by induction n using Semigroup.ppow_induction a · exact ha - · exact one_le_mul ha ‹_› + · exact one_le_mul ‹_› ha @[to_additive psmul_nonpos] theorem ppow_le_one_of_le (ha : a ≤ 1) (n : ℕ+) : a ^ n ≤ 1 := one_le_ppow_of_le (M := Mᵒᵈ) ha n @[to_additive psmul_neg] theorem ppow_lt_one_of_lt {a : M} (n : ℕ+) (h : a < 1) : a ^ n < 1 := by - induction n using Semigroup.ppow_induction a + induction n using Semigroup.ppow_induction' a · exact h · exact mul_lt_one_of_lt_of_le h (ppow_le_one_of_le h.le _) diff --git a/Mathlib/Algebra/Order/Nonneg/Basic.lean b/Mathlib/Algebra/Order/Nonneg/Basic.lean index 67cc1d2625ccab..bad6bcf208b955 100644 --- a/Mathlib/Algebra/Order/Nonneg/Basic.lean +++ b/Mathlib/Algebra/Order/Nonneg/Basic.lean @@ -219,7 +219,7 @@ section PPow variable [SemigroupWithZero α] [Preorder α] [PosMulMono α] instance ppow : Pow { x : α // 0 ≤ x } ℕ+ where - pow x n := ⟨(x : α) ^ n, ppow_nonneg _ x.2⟩ + pow x n := ⟨(x : α) ^ n, ppow_nonneg x.2 _⟩ @[simp, norm_cast] protected theorem coe_ppow (a : { x : α // 0 ≤ x }) (n : ℕ+) : @@ -228,7 +228,7 @@ protected theorem coe_ppow (a : { x : α // 0 ≤ x }) (n : ℕ+) : @[simp] theorem mk_ppow {x : α} (hx : 0 ≤ x) (n : ℕ+) : - (⟨x, hx⟩ : { x : α // 0 ≤ x }) ^ n = ⟨x ^ n, ppow_nonneg _ hx⟩ := + (⟨x, hx⟩ : { x : α // 0 ≤ x }) ^ n = ⟨x ^ n, ppow_nonneg hx _⟩ := rfl end PPow diff --git a/Mathlib/Data/Rat/Defs.lean b/Mathlib/Data/Rat/Defs.lean index 56241e80bb7d29..aaa6980f7cc5f9 100644 --- a/Mathlib/Data/Rat/Defs.lean +++ b/Mathlib/Data/Rat/Defs.lean @@ -156,9 +156,9 @@ instance addCommGroup : AddCommGroup ℚ where nsmul := (· * ·) zsmul := (· * ·) psmul_one := Rat.one_mul - psmul_succ q n := by - change ((n + 2 : Int) : Rat) * q = q + ((n + 1 : Int) : Rat) * q - rw [Rat.intCast_add, Rat.add_mul, Rat.intCast_add, Rat.add_mul, Rat.add_comm q, Rat.add_assoc, + psmul_succ n q := by + change ((n + 2 : Int) : Rat) * q = ((n + 1 : Int) : Rat) * q + q + rw [Rat.intCast_add, Rat.add_mul, Rat.intCast_add, Rat.add_mul, Rat.add_assoc, show (2 : Int) = 1 + 1 by rfl, Rat.intCast_add, Rat.add_mul] simp nsmul_zero := Rat.zero_mul diff --git a/Mathlib/GroupTheory/Congruence/Defs.lean b/Mathlib/GroupTheory/Congruence/Defs.lean index cad00d04c56751..a842619086a1ed 100644 --- a/Mathlib/GroupTheory/Congruence/Defs.lean +++ b/Mathlib/GroupTheory/Congruence/Defs.lean @@ -573,7 +573,7 @@ protected theorem ppow {M : Type*} [Semigroup M] (c : Con M) (n : ℕ+) {w x} (h | h1 => simp [h] | hsucc n IH => rw [ppow_mk_add_one x] - exact c.mul h (IH h) + exact c.mul (IH h) h @[to_additive] instance {M : Type*} [Semigroup M] (c : Con M) : Pow c.Quotient ℕ+ where From c324489965814c79880f715b399c4f44a4432a91 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 16:47:32 -0400 Subject: [PATCH 088/127] twosided ideal --- Mathlib/RingTheory/TwoSidedIdeal/Basic.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/RingTheory/TwoSidedIdeal/Basic.lean b/Mathlib/RingTheory/TwoSidedIdeal/Basic.lean index 543ded7a05f1ee..038b0f71d246c7 100644 --- a/Mathlib/RingTheory/TwoSidedIdeal/Basic.lean +++ b/Mathlib/RingTheory/TwoSidedIdeal/Basic.lean @@ -198,6 +198,7 @@ instance : SMul ℤ I where smul n x := ⟨n • x.1, I.zsmul_mem n x.2⟩ instance addCommGroup : AddCommGroup I := Function.Injective.addCommGroup _ Subtype.coe_injective rfl (fun _ _ ↦ rfl) (fun _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) + (fun _ _ ↦ rfl) /-- The coercion into the ring as a `AddMonoidHom` -/ @[simps] From 426ed234902bbf139cb1b80daf0ee962291ee7cc Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 18:38:19 -0400 Subject: [PATCH 089/127] Submodule --- Mathlib/Algebra/Algebra/Operations.lean | 19 +++++++++++++++++++ Mathlib/Algebra/Ring/Submonoid/Pointwise.lean | 12 ++++++++++++ 2 files changed, 31 insertions(+) diff --git a/Mathlib/Algebra/Algebra/Operations.lean b/Mathlib/Algebra/Algebra/Operations.lean index 54267e7ffb5618..281a7822f0e2b2 100644 --- a/Mathlib/Algebra/Algebra/Operations.lean +++ b/Mathlib/Algebra/Algebra/Operations.lean @@ -300,9 +300,28 @@ theorem iSup_mul (s : ι → Submodule R A) (t : Submodule R A) : (⨆ i, s i) * theorem mul_iSup (t : Submodule R A) (s : ι → Submodule R A) : (t * ⨆ i, s i) = ⨆ i, t * s i := smul_iSup +instance : Pow (Submodule R A) ℕ+ where + pow s n := ppowRec n n.prop s -- as opposed to `s.toAddSubmonoid ^ n` + +@[simp] +protected theorem ppow_zero : M ^ (1 : ℕ+) = M := rfl + +protected theorem ppow_succ {n : ℕ+} : M ^ (n + 1) = M ^ n * M := by + rcases n with ⟨_|n, hn⟩ + · contradiction + · rfl + +private protected theorem ppow_mk_add_two (n : ℕ) : + M ^ (PNat.mk (n + 2) (Nat.succ_pos _)) = M ^ (PNat.mk (n + 1) (Nat.succ_pos _)) * M := + rfl + /-- Sub-`R`-modules of an `R`-module form an idempotent semiring. -/ instance : NonUnitalSemiring (Submodule R A) where __ := toAddSubmonoid_injective.semigroup _ mul_toAddSubmonoid + (fun x n => by + induction n using Semigroup.ppow_induction x.toAddSubmonoid with + | h1 => simp + | hsucc n IH => rw [Submodule.ppow_mk_add_two, mul_toAddSubmonoid, IH]) zero_mul := bot_mul mul_zero := mul_bot left_distrib := mul_sup diff --git a/Mathlib/Algebra/Ring/Submonoid/Pointwise.lean b/Mathlib/Algebra/Ring/Submonoid/Pointwise.lean index b40650b7b053b3..17160cbab6a2be 100644 --- a/Mathlib/Algebra/Ring/Submonoid/Pointwise.lean +++ b/Mathlib/Algebra/Ring/Submonoid/Pointwise.lean @@ -262,6 +262,18 @@ protected def semigroup : Semigroup (AddSubmonoid R) where scoped[Pointwise] attribute [instance] AddSubmonoid.semigroup +lemma closure_ppow (s : Set R) (n : ℕ+) : closure s ^ n = closure (s ^ n) := by + induction n using Semigroup.ppow_induction s with + | h1 => rw [ppow_one] + | hsucc n IH => rw [ppow_mk_add_one, IH, closure_mul_closure] + +lemma ppow_eq_closure_ppow_set (s : AddSubmonoid R) (n : ℕ+) : + s ^ n = closure ((s : Set R) ^ n) := by + rw [← closure_ppow, closure_eq] + +lemma ppow_subset_ppow {s : AddSubmonoid R} {n : ℕ+} : (↑s : Set R) ^ n ⊆ ↑(s ^ n) := + (ppow_eq_closure_ppow_set s n).symm ▸ subset_closure + end NonUnitalSemiring section Semiring From b93631474a96a941cdcbe696befaf7562495782a Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 21:35:04 -0400 Subject: [PATCH 090/127] GMonoid --- Mathlib/Algebra/GradedMonoid.lean | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/GradedMonoid.lean b/Mathlib/Algebra/GradedMonoid.lean index e979eb59e8d2e8..6aa079160217c9 100644 --- a/Mathlib/Algebra/GradedMonoid.lean +++ b/Mathlib/Algebra/GradedMonoid.lean @@ -200,7 +200,7 @@ theorem gnpowRec_zero (a : GradedMonoid A) : GradedMonoid.mk _ (gnpowRec 0 a.snd @[simp] theorem gnpowRec_succ (n : ℕ) (a : GradedMonoid A) : - (GradedMonoid.mk _ <| gnpowRec n.succ a.snd) = ⟨_, gnpowRec n a.snd⟩ * a := + (GradedMonoid.mk _ <| gnpowRec n.succ a.snd) = (GradedMonoid.mk _ <| gnpowRec n a.snd) * a := Sigma.ext (succ_nsmul _ _) (heq_of_cast_eq _ rfl).symm end GMonoid @@ -229,11 +229,14 @@ class GMonoid [AddMonoid ι] extends GMul A, GOne A where /-- Successor powers behave as expected -/ gnpow_succ' : ∀ (n : ℕ) (a : GradedMonoid A), - (GradedMonoid.mk _ <| gnpow n.succ a.snd) = ⟨_, gnpow n a.snd⟩ * a := by + (GradedMonoid.mk _ <| gnpow n.succ a.snd) = (GradedMonoid.mk _ <| gnpow n a.snd) * a := by apply_gmonoid_gnpowRec_succ_tac /-- `GMonoid` implies a `Monoid (GradedMonoid A)`. -/ instance GMonoid.toMonoid [AddMonoid ι] [GMonoid A] : Monoid (GradedMonoid A) where + ppow n hn a := GradedMonoid.mk _ (GMonoid.gnpow n a.snd) + ppow_one a := by simp [GMonoid.gnpow_succ', GMonoid.gnpow_zero', GMonoid.one_mul] + ppow_succ n a := GMonoid.gnpow_succ' (n + 1) a npow n a := GradedMonoid.mk _ (GMonoid.gnpow n a.snd) npow_zero a := GMonoid.gnpow_zero' a npow_succ n a := GMonoid.gnpow_succ' n a @@ -316,6 +319,9 @@ section Monoid variable [AddMonoid ι] [GMonoid A] +instance : Pow (A 0) ℕ+ where + pow x n := @Eq.rec ι (n.val • (0 : ι)) (fun a _ => A a) (GMonoid.gnpow n.val x) 0 (nsmul_zero n) + instance : NatPow (A 0) where pow x n := @Eq.rec ι (n • (0 : ι)) (fun a _ => A a) (GMonoid.gnpow n x) 0 (nsmul_zero n) @@ -324,9 +330,14 @@ variable {A} in theorem mk_zero_pow (a : A 0) (n : ℕ) : mk _ (a ^ n) = mk _ a ^ n := Sigma.ext (nsmul_zero n).symm <| eqRec_heq _ _ +variable {A} in +@[simp] +theorem mk_zero_ppow (a : A 0) (n : ℕ+) : mk _ (a ^ n) = mk _ a ^ n := + Sigma.ext (nsmul_zero n).symm <| eqRec_heq _ _ + /-- The `Monoid` structure derived from `GMonoid A`. -/ instance (priority := 900) GradeZero.monoid : Monoid (A 0) := - Function.Injective.monoid (mk 0) sigma_mk_injective rfl mk_zero_smul mk_zero_pow + Function.Injective.monoid (mk 0) sigma_mk_injective rfl mk_zero_smul mk_zero_ppow mk_zero_pow end Monoid @@ -336,7 +347,7 @@ variable [AddCommMonoid ι] [GCommMonoid A] /-- The `CommMonoid` structure derived from `GCommMonoid A`. -/ instance (priority := 900) GradeZero.commMonoid : CommMonoid (A 0) := - Function.Injective.commMonoid (mk 0) sigma_mk_injective rfl mk_zero_smul mk_zero_pow + Function.Injective.commMonoid (mk 0) sigma_mk_injective rfl mk_zero_smul mk_zero_ppow mk_zero_pow end Monoid From 8686c4f8c4132a862808df4a942cf5682b0533c0 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 21:52:53 -0400 Subject: [PATCH 091/127] Bitvec --- Mathlib/Data/BitVec.lean | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Mathlib/Data/BitVec.lean b/Mathlib/Data/BitVec.lean index c76df5a6a66593..2a1ba9fb25c3f1 100644 --- a/Mathlib/Data/BitVec.lean +++ b/Mathlib/Data/BitVec.lean @@ -61,21 +61,35 @@ theorem toFin_injective {n : Nat} : Function.Injective (toFin : BitVec n → _) open Fin.NatCast +instance : SMul ℕ+ (BitVec w) where + smul n x := n.val • x + lemma toFin_nsmul (n : ℕ) (x : BitVec w) : toFin (n • x) = n • x.toFin := toFin_mul _ _ |>.trans <| by open scoped Fin.CommRing in simp only [natCast_eq_ofNat, toFin_ofNat, Fin.ofNat_eq_cast, nsmul_eq_mul] +lemma toFin_psmul (n : ℕ+) (x : BitVec w) : toFin (n • x) = n • x.toFin := by + rw [← nsmul_val_eq_psmul] + exact toFin_nsmul n.val x + lemma toFin_zsmul (z : ℤ) (x : BitVec w) : toFin (z • x) = z • x.toFin := toFin_mul _ _ |>.trans <| by open scoped Fin.CommRing in simp only [zsmul_eq_mul, toFin_intCast] +instance : Pow (BitVec w) ℕ+ where + pow x n := x ^ n.val + lemma toFin_pow (x : BitVec w) (n : ℕ) : toFin (x ^ n) = x.toFin ^ n := by induction n with | zero => simp | succ n ih => simp [ih, BitVec.pow_succ] +lemma toFin_ppow (x : BitVec w) (n : ℕ+) : toFin (x ^ n) = x.toFin ^ n := by + rw [← npow_val_eq_ppow] + exact toFin_pow x n.val + /-! ## Ring -/ @@ -90,7 +104,9 @@ instance : CommSemiring (BitVec w) := toFin_one toFin_add toFin_mul + toFin_psmul toFin_nsmul + toFin_ppow toFin_pow toFin_natCast -- The statement in the new API would be: `n#(k.succ) = ((n / 2)#k).concat (n % 2 != 0)` @@ -99,7 +115,7 @@ instance : CommRing (BitVec w) := open Fin.CommRing in 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 + toFin_psmul toFin_nsmul toFin_zsmul toFin_ppow toFin_pow toFin_natCast toFin_intCast /-- The ring `BitVec m` is isomorphic to `Fin (2 ^ m)`. -/ @[simps] From c66b6a61e4a38a49bf6753df7f9d7c4a5bee1059 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 22:00:16 -0400 Subject: [PATCH 092/127] Filter/Gem --- Mathlib/Order/Filter/Germ/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Order/Filter/Germ/Basic.lean b/Mathlib/Order/Filter/Germ/Basic.lean index dd0aa8723d3e62..f4eb00b5260394 100644 --- a/Mathlib/Order/Filter/Germ/Basic.lean +++ b/Mathlib/Order/Filter/Germ/Basic.lean @@ -407,7 +407,7 @@ theorem const_pow [Pow G M] (a : G) (n : M) : (↑(a ^ n) : Germ l G) = (↑a : @[to_additive] instance instMonoid [Monoid M] : Monoid (Germ l M) := { Function.Surjective.monoid ofFun Quot.mk_surjective rfl - (fun _ _ => by rfl) fun _ _ => by rfl with + (fun _ _ => by rfl) (fun _ _ => by rfl) fun _ _ => by rfl with toSemigroup := instSemigroup toOne := instOne npow := fun n a => a ^ n } From 3386b997e7efb81558b126631a7029c873b7c08a Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 22:07:27 -0400 Subject: [PATCH 093/127] fix arg order --- Mathlib/Algebra/Ring/InjSurj.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Ring/InjSurj.lean b/Mathlib/Algebra/Ring/InjSurj.lean index 819cf8d86e3b1b..b27b2f981beb2a 100644 --- a/Mathlib/Algebra/Ring/InjSurj.lean +++ b/Mathlib/Algebra/Ring/InjSurj.lean @@ -164,7 +164,7 @@ protected abbrev semiring [Semiring R] (zero : f 0 = 0) (one : f 1 = 1) protected abbrev nonUnitalNonAssocRing [NonUnitalNonAssocRing R] (f : S → R) (hf : Injective f) (zero : f 0 = 0) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) (neg : ∀ x, f (-x) = -f x) - (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (sub : ∀ x y, f (x - y) = f x - f y) + (sub : ∀ x y, f (x - y) = f x - f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : NonUnitalNonAssocRing S where toAddCommGroup := hf.addCommGroup f zero add neg sub (swap psmul) (swap nsmul) (swap zsmul) @@ -178,7 +178,7 @@ protected abbrev nonUnitalRing [NonUnitalRing R] (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (ppow : ∀ x (n : ℕ+), f (x ^ n) = f x ^ n) : NonUnitalRing S where - toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg psmul sub nsmul zsmul + toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg sub psmul nsmul zsmul __ := hf.nonUnitalSemiring f zero add mul psmul nsmul ppow /-- Pullback a `NonAssocRing` instance along an injective function. -/ @@ -189,7 +189,7 @@ protected abbrev nonAssocRing [NonAssocRing R] (sub : ∀ x y, f (x - y) = f x - f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) (natCast : ∀ n : ℕ, f n = n) (intCast : ∀ n : ℤ, f n = n) : NonAssocRing S where - toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg psmul sub nsmul zsmul + toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg sub psmul nsmul zsmul __ := hf.nonAssocSemiring f zero one add mul psmul nsmul natCast __ := hf.addCommGroupWithOne f zero one add neg sub psmul nsmul zsmul natCast intCast @@ -255,7 +255,7 @@ protected abbrev nonUnitalNonAssocCommRing [NonUnitalNonAssocCommRing R] (f : S (sub : ∀ x y, f (x - y) = f x - f y) (psmul : ∀ (n : ℕ+) (x), f (n • x) = n • f x) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (n : ℤ) (x), f (n • x) = n • f x) : NonUnitalNonAssocCommRing S where - toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg psmul sub nsmul zsmul + toNonUnitalNonAssocRing := hf.nonUnitalNonAssocRing f zero add mul neg sub psmul nsmul zsmul __ := hf.nonUnitalNonAssocCommSemiring f zero add mul psmul nsmul /-- Pullback a `NonUnitalCommRing` instance along an injective function. -/ From 2abd6d9709154eb8493defce8d563c419f2dd99d Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 22:18:38 -0400 Subject: [PATCH 094/127] finsupp pointwise --- Mathlib/Algebra/GroupWithZero/Basic.lean | 9 +++++++++ Mathlib/Data/Finsupp/Pointwise.lean | 21 ++++++++++++++------- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/Mathlib/Algebra/GroupWithZero/Basic.lean b/Mathlib/Algebra/GroupWithZero/Basic.lean index a6ce83d77a3f5c..beb44064bdec01 100644 --- a/Mathlib/Algebra/GroupWithZero/Basic.lean +++ b/Mathlib/Algebra/GroupWithZero/Basic.lean @@ -6,6 +6,7 @@ Authors: Johan Commelin module public import Mathlib.Algebra.Group.Basic +public import Mathlib.Algebra.Group.PPow.Defs public import Mathlib.Algebra.GroupWithZero.NeZero public import Mathlib.Logic.Unique public import Mathlib.Tactic.Conv @@ -212,6 +213,14 @@ lemma exists_isNilpotent_of_not_isReduced {R : Type*} [Zero R] [Pow R ℕ] (h : end Nilpotent +section SemigroupWithZero +variable {S₀ : Type*} [SemigroupWithZero S₀] + +@[simp] lemma zero_ppow (n : ℕ+) : (0 : S₀) ^ n = 0 := by + induction n using Semigroup.ppow_induction (0 : S₀) <;> simp + +end SemigroupWithZero + section MonoidWithZero variable [MonoidWithZero M₀] {a : M₀} {n : ℕ} diff --git a/Mathlib/Data/Finsupp/Pointwise.lean b/Mathlib/Data/Finsupp/Pointwise.lean index 0fb88d8fbe9e11..ca1cb0a2f99203 100644 --- a/Mathlib/Data/Finsupp/Pointwise.lean +++ b/Mathlib/Data/Finsupp/Pointwise.lean @@ -71,29 +71,36 @@ instance : MulZeroClass (α →₀ β) := end +instance [SemigroupWithZero β] : Pow (α →₀ β) ℕ+ where + pow g n := Finsupp.ofSupportFinite (fun a ↦ g a ^ n) + (Set.Finite.subset g.hasFiniteSupport (by simp; grind [zero_ppow])) + instance [SemigroupWithZero β] : SemigroupWithZero (α →₀ β) := - DFunLike.coe_injective.semigroupWithZero _ coe_zero coe_mul + DFunLike.coe_injective.semigroupWithZero _ coe_zero coe_mul fun _ _ ↦ rfl instance [NonUnitalNonAssocSemiring β] : NonUnitalNonAssocSemiring (α →₀ β) := - DFunLike.coe_injective.nonUnitalNonAssocSemiring _ coe_zero coe_add coe_mul fun _ _ ↦ rfl + DFunLike.coe_injective.nonUnitalNonAssocSemiring _ coe_zero coe_add coe_mul (fun _ _ ↦ rfl) + fun _ _ ↦ rfl instance [NonUnitalSemiring β] : NonUnitalSemiring (α →₀ β) := - DFunLike.coe_injective.nonUnitalSemiring _ coe_zero coe_add coe_mul fun _ _ ↦ rfl + DFunLike.coe_injective.nonUnitalSemiring _ coe_zero coe_add coe_mul (fun _ _ ↦ rfl) + (fun _ _ ↦ rfl) fun _ _ ↦ rfl instance [NonUnitalCommSemiring β] : NonUnitalCommSemiring (α →₀ β) := - DFunLike.coe_injective.nonUnitalCommSemiring _ coe_zero coe_add coe_mul fun _ _ ↦ rfl + DFunLike.coe_injective.nonUnitalCommSemiring _ coe_zero coe_add coe_mul (fun _ _ ↦ rfl) + (fun _ _ ↦ rfl) fun _ _ ↦ rfl instance [NonUnitalNonAssocRing β] : NonUnitalNonAssocRing (α →₀ β) := DFunLike.coe_injective.nonUnitalNonAssocRing _ coe_zero coe_add coe_mul coe_neg coe_sub - (fun _ _ ↦ rfl) fun _ _ ↦ rfl + (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) fun _ _ ↦ rfl instance [NonUnitalRing β] : NonUnitalRing (α →₀ β) := DFunLike.coe_injective.nonUnitalRing _ coe_zero coe_add coe_mul coe_neg coe_sub (fun _ _ ↦ rfl) - fun _ _ ↦ rfl + (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) fun _ _ ↦ rfl instance [NonUnitalCommRing β] : NonUnitalCommRing (α →₀ β) := DFunLike.coe_injective.nonUnitalCommRing _ coe_zero coe_add coe_mul coe_neg coe_sub - (fun _ _ ↦ rfl) fun _ _ ↦ rfl + (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) fun _ _ ↦ rfl lemma pointwise_smul_support_finite [Zero γ] [SMulZeroClass β γ] (f : α → β) (g : α →₀ γ) : (fun x ↦ f x • g x).support.Finite := From e2f186bc088b0e65e17669fa1cf4daccba8c0eb7 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 22:29:30 -0400 Subject: [PATCH 095/127] fix additive renaming --- Mathlib/Algebra/Group/PPow/Defs.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Group/PPow/Defs.lean b/Mathlib/Algebra/Group/PPow/Defs.lean index 9c02a220fbe654..67e43a6844385a 100644 --- a/Mathlib/Algebra/Group/PPow/Defs.lean +++ b/Mathlib/Algebra/Group/PPow/Defs.lean @@ -60,14 +60,14 @@ lemma Semigroup.ppow_induction [Semigroup M] {p : ℕ+ → M → Prop} (x : M) ( simpa [q, PNat.mk, ← Semigroup.ppow_eq_pow, Semigroup.ppow_succ] using hsucc k IH simpa [q, PNat.mk] using hq k -@[to_additive] +@[to_additive psmul_mk_add_one] lemma ppow_mk_add_one [Semigroup M] (x : M) {n : ℕ} (hn : n ≠ 0 := by exact Nat.succ_ne_zero _) : x ^ (PNat.mk (n + 1) (Nat.succ_pos n)) = x ^ (PNat.mk n (Nat.pos_of_ne_zero hn)) * x := by cases n · contradiction · simp [← Semigroup.ppow_eq_pow, PNat.mk, Semigroup.ppow_succ] -@[to_additive] +@[to_additive psmul_mk_add_one'] lemma ppow_mk_add_one' [Semigroup M] (x : M) {n : ℕ} (hn : n ≠ 0 := by exact Nat.succ_ne_zero _) : x ^ (PNat.mk (n + 1) (Nat.succ_pos n)) = x * x ^ (PNat.mk n (Nat.pos_of_ne_zero hn)) := by cases n From 945f8884f324b9cb37d8092f1359abe38d7a49a8 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Wed, 24 Jun 2026 22:29:40 -0400 Subject: [PATCH 096/127] PositiveLinearMap --- .../Order/Module/PositiveLinearMap.lean | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Order/Module/PositiveLinearMap.lean b/Mathlib/Algebra/Order/Module/PositiveLinearMap.lean index e32de62a976895..201b5a543e53dc 100644 --- a/Mathlib/Algebra/Order/Module/PositiveLinearMap.lean +++ b/Mathlib/Algebra/Order/Module/PositiveLinearMap.lean @@ -163,6 +163,22 @@ lemma add_apply (f g : E₁ →ₚ[R] E₂) (x : E₁) : (f + g) x = f x + g x := by rfl +instance : SMul ℕ+ (E₁ →ₚ[R] E₂) where + smul n f := .mk (n • f.toLinearMap) fun x y h ↦ by + induction n using AddSemigroup.psmul_induction f.toLinearMap with + | h1 => exact OrderHomClass.mono f h + | hsucc n IH => exact add_le_add IH (OrderHomClass.mono f h) + +@[simp] +lemma toLinearMap_psmul (f : E₁ →ₚ[R] E₂) (n : ℕ+) : + (n • f).toLinearMap = n • f.toLinearMap := + rfl + +@[simp] +lemma psmul_apply (f : E₁ →ₚ[R] E₂) (n : ℕ+) (x : E₁) : + (n • f) x = n • (f x) := + rfl + instance : SMul ℕ (E₁ →ₚ[R] E₂) where smul n f := .mk (n • f.toLinearMap) fun x y h ↦ by induction n with @@ -181,7 +197,7 @@ lemma nsmul_apply (f : E₁ →ₚ[R] E₂) (n : ℕ) (x : E₁) : instance : AddCommMonoid (E₁ →ₚ[R] E₂) := toLinearMap_injective.addCommMonoid _ toLinearMap_zero toLinearMap_add - toLinearMap_nsmul + toLinearMap_psmul toLinearMap_nsmul end general From 0b08c6b9153dee415eace99560850eff047b8a8a Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 25 Jun 2026 09:54:43 -0400 Subject: [PATCH 097/127] funlike ring --- Mathlib/Data/FunLike/Ring.lean | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Mathlib/Data/FunLike/Ring.lean b/Mathlib/Data/FunLike/Ring.lean index 935248a211142f..bfe28d6b5857e9 100644 --- a/Mathlib/Data/FunLike/Ring.lean +++ b/Mathlib/Data/FunLike/Ring.lean @@ -41,7 +41,8 @@ section Semiring variable [FunLike F α α] [Zero F] [One F] [Mul F] [Add F] [AddCommMonoid α] [IsZeroApply F α α] [IsAddApply F α α] [IsOneApplyEqSelf F α] [IsMulApplyEqComp F α] - [SMul ℕ F] [IsSMulApply ℕ F α α] [AddMonoidHomClass F α α] [NatCast F] [IsNatCastApply F α] + [SMul ℕ+ F] [IsSMulApply ℕ+ F α α] [SMul ℕ F] [IsSMulApply ℕ F α α] [AddMonoidHomClass F α α] + [NatCast F] [IsNatCastApply F α] /-- A `FunLike` type with `(f + g) x = f x + g x` and `(f * g) x = f (g x)` is a `Semiring` if `α` is a `Semiring`. -/ @@ -61,7 +62,7 @@ variable [FunLike F α α] [Zero F] [One F] [Mul F] [Add F] [Neg F] [Sub F] [AddCommGroup α] [IsZeroApply F α α] [IsAddApply F α α] [IsOneApplyEqSelf F α] [IsMulApplyEqComp F α] [IsNegApply F α α] [IsSubApply F α α] - [SMul ℕ F] [IsSMulApply ℕ F α α] + [SMul ℕ+ F] [IsSMulApply ℕ+ F α α] [SMul ℕ F] [IsSMulApply ℕ F α α] [SMul ℤ F] [IsSMulApply ℤ F α α] [AddMonoidHomClass F α α] [NatCast F] [IsNatCastApply F α] [IntCast F] [IsIntCastApply F α] From 891729050a9e7995ffc5e71fc7f9d56f70aeb4b7 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 25 Jun 2026 10:00:44 -0400 Subject: [PATCH 098/127] field transfer instance --- Mathlib/Algebra/Field/TransferInstance.lean | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mathlib/Algebra/Field/TransferInstance.lean b/Mathlib/Algebra/Field/TransferInstance.lean index 37f6c86000b5af..4b5e11548e0721 100644 --- a/Mathlib/Algebra/Field/TransferInstance.lean +++ b/Mathlib/Algebra/Field/TransferInstance.lean @@ -33,6 +33,7 @@ protected abbrev divisionRing [DivisionRing β] : DivisionRing α := by let inv := e.Inv let div := e.div let mul := e.mul + let ppow := e.pow ℕ+ let npow := e.pow ℕ let zpow := e.pow ℤ let nnratCast := e.nnratCast @@ -48,6 +49,7 @@ protected abbrev field [Field β] : Field α := by let inv := e.Inv let div := e.div let mul := e.mul + let ppow := e.pow ℕ+ let npow := e.pow ℕ let zpow := e.pow ℤ let nnratCast := e.nnratCast From 9adad85e10266c69ae46a56698c0200075295758 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 25 Jun 2026 10:54:08 -0400 Subject: [PATCH 099/127] UpperLower --- Mathlib/Algebra/Order/UpperLower.lean | 28 +++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Order/UpperLower.lean b/Mathlib/Algebra/Order/UpperLower.lean index 73864388c338df..3dad1059e32d57 100644 --- a/Mathlib/Algebra/Order/UpperLower.lean +++ b/Mathlib/Algebra/Order/UpperLower.lean @@ -94,6 +94,14 @@ theorem IsLowerSet.div_left {α : Type*} [CommGroup α] [PartialOrder α] [IsOrd @[to_additive] theorem IsLowerSet.div_right (hs : IsLowerSet s) : IsLowerSet (s / t) := hs.toDual.div_right +@[to_additive] +theorem IsUpperSet.ppow (hs : IsUpperSet s) (n : ℕ+) : IsUpperSet (s ^ n) := + Semigroup.ppow_induction s n hs fun _ _ ↦ hs.mul_left + +@[to_additive] +theorem IsLowerSet.ppow (hs : IsLowerSet s) (n : ℕ+) : IsLowerSet (s ^ n) := + Semigroup.ppow_induction s n hs fun _ _ ↦ hs.mul_left + namespace UpperSet @[to_additive] @@ -112,6 +120,10 @@ instance : Div (UpperSet α) := instance : SMul α (UpperSet α) := ⟨fun a s ↦ ⟨(a • ·) '' s, s.2.smul⟩⟩ +@[to_additive] +instance : Pow (UpperSet α) ℕ+ := + ⟨fun s n ↦ ⟨s ^ n, s.2.ppow _⟩⟩ + omit [IsOrderedMonoid α] in @[to_additive (attr := simp, norm_cast)] theorem coe_one : ((1 : UpperSet α) : Set α) = Set.Ici 1 := @@ -125,6 +137,10 @@ theorem coe_mul (s t : UpperSet α) : (↑(s * t) : Set α) = s * t := theorem coe_div (s t : UpperSet α) : (↑(s / t) : Set α) = s / t := rfl +@[to_additive (attr := simp, norm_cast)] +theorem coe_ppow (s : UpperSet α) (n : ℕ+) : (↑(s ^ n) : Set α) = s ^ n := + rfl + omit [IsOrderedMonoid α] in @[to_additive (attr := simp)] theorem Ici_one : Ici (1 : α) = 1 := @@ -136,7 +152,7 @@ instance : MulAction α (UpperSet α) := @[to_additive] instance commSemigroup : CommSemigroup (UpperSet α) := - { (SetLike.coe_injective.commSemigroup _ coe_mul : CommSemigroup (UpperSet α)) with } + { (SetLike.coe_injective.commSemigroup _ coe_mul coe_ppow : CommSemigroup (UpperSet α)) with } @[to_additive] private theorem one_mul (s : UpperSet α) : 1 * s = s := @@ -173,6 +189,10 @@ instance : Div (LowerSet α) := instance : SMul α (LowerSet α) := ⟨fun a s ↦ ⟨(a • ·) '' s, s.2.smul⟩⟩ +@[to_additive] +instance : Pow (LowerSet α) ℕ+ := + ⟨fun s n ↦ ⟨s ^ n, s.2.ppow _⟩⟩ + @[to_additive (attr := simp, norm_cast)] theorem coe_mul (s t : LowerSet α) : (↑(s * t) : Set α) = s * t := rfl @@ -181,6 +201,10 @@ theorem coe_mul (s t : LowerSet α) : (↑(s * t) : Set α) = s * t := theorem coe_div (s t : LowerSet α) : (↑(s / t) : Set α) = s / t := rfl +@[to_additive (attr := simp, norm_cast)] +theorem coe_ppow (s : LowerSet α) (n : ℕ+) : (↑(s ^ n) : Set α) = s ^ n := + rfl + omit [IsOrderedMonoid α] in @[to_additive (attr := simp)] theorem Iic_one : Iic (1 : α) = 1 := @@ -192,7 +216,7 @@ instance : MulAction α (LowerSet α) := @[to_additive] instance commSemigroup : CommSemigroup (LowerSet α) := - { (SetLike.coe_injective.commSemigroup _ coe_mul : CommSemigroup (LowerSet α)) with } + { (SetLike.coe_injective.commSemigroup _ coe_mul coe_ppow : CommSemigroup (LowerSet α)) with } @[to_additive] private theorem one_mul (s : LowerSet α) : 1 * s = s := From 42efe1ea741e5ffc725cc4384671e21d30d709d9 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 25 Jun 2026 11:21:14 -0400 Subject: [PATCH 100/127] UInt --- Mathlib/Data/UInt.lean | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/Mathlib/Data/UInt.lean b/Mathlib/Data/UInt.lean index 14225b9611b9a5..13e8e804fa8cf0 100644 --- a/Mathlib/Data/UInt.lean +++ b/Mathlib/Data/UInt.lean @@ -44,6 +44,20 @@ run_cmd nsmul_eq_mul, BitVec.natCast_eq_ofNat] rfl + instance : SMul ℕ+ $typeName := ⟨fun n a ↦ n.val • a⟩ + + open $typeName (toBitVec_nsmul) in + protected theorem toBitVec_psmul (n : ℕ+) (a : $typeName) : + (n • a).toBitVec = n • a.toBitVec := + toBitVec_nsmul n.val a + + instance : Pow $typeName ℕ+ := ⟨fun a n ↦ a ^ n.val⟩ + + open $typeName (toBitVec_pow) in + protected theorem toBitVec_ppow (a : $typeName) (n : ℕ+) : + (a ^ n).toBitVec = a.toBitVec ^ n := + toBitVec_pow a n.val + attribute [local instance] natCast intCast @[simp, int_toBitVec] @@ -88,33 +102,35 @@ run_cmd open $typeName (eq_of_toBitVec_eq) in lemma toBitVec_injective : Function.Injective toBitVec := @eq_of_toBitVec_eq - open $typeName (toBitVec_one toBitVec_mul toBitVec_pow) in + open $typeName (toBitVec_one toBitVec_mul toBitVec_ppow toBitVec_pow) in instance instCommMonoid : CommMonoid $typeName := Function.Injective.commMonoid toBitVec toBitVec_injective - toBitVec_one (fun _ _ => toBitVec_mul) (fun _ _ => toBitVec_pow _ _) + toBitVec_one (fun _ _ => toBitVec_mul) (fun _ _ => toBitVec_ppow _ _) + (fun _ _ => toBitVec_pow _ _) open $typeName ( - toBitVec_zero toBitVec_add toBitVec_mul toBitVec_neg toBitVec_sub toBitVec_nsmul - toBitVec_zsmul) in + toBitVec_zero toBitVec_add toBitVec_mul toBitVec_neg toBitVec_sub + toBitVec_psmul toBitVec_nsmul toBitVec_zsmul toBitVec_ppow) in instance instNonUnitalCommRing : NonUnitalCommRing $typeName := Function.Injective.nonUnitalCommRing toBitVec toBitVec_injective toBitVec_zero (fun _ _ => toBitVec_add) (fun _ _ => toBitVec_mul) (fun _ => toBitVec_neg) - (fun _ _ => toBitVec_sub) + (fun _ _ => toBitVec_sub) (fun _ _ => toBitVec_psmul _ _) (fun _ _ => toBitVec_nsmul _ _) (fun _ _ => toBitVec_zsmul _ _) + (fun _ _ => toBitVec_ppow _ _) attribute [local instance] intCast natCast open $typeName ( - toBitVec_zero toBitVec_one toBitVec_add toBitVec_mul toBitVec_neg - toBitVec_sub toBitVec_nsmul toBitVec_zsmul toBitVec_pow + toBitVec_zero toBitVec_one toBitVec_add toBitVec_mul toBitVec_neg toBitVec_sub + toBitVec_psmul toBitVec_nsmul toBitVec_zsmul toBitVec_ppow toBitVec_pow toBitVec_natCast toBitVec_intCast) in -- `noncomputable` should not be necessary but triggers some codegen assertion noncomputable local instance instCommRing : CommRing $typeName := Function.Injective.commRing toBitVec toBitVec_injective toBitVec_zero toBitVec_one (fun _ _ => toBitVec_add) (fun _ _ => toBitVec_mul) - (fun _ => toBitVec_neg) (fun _ _ => toBitVec_sub) + (fun _ => toBitVec_neg) (fun _ _ => toBitVec_sub) (fun _ _ => toBitVec_psmul _ _) (fun _ _ => toBitVec_nsmul _ _) (fun _ _ => toBitVec_zsmul _ _) - (fun _ _ => toBitVec_pow _ _) + (fun _ _ => toBitVec_ppow _ _) (fun _ _ => toBitVec_pow _ _) toBitVec_natCast toBitVec_intCast namespace CommRing From 2a226d592978bd1bcd25bddd842e69cbac5f571c Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 25 Jun 2026 11:38:12 -0400 Subject: [PATCH 101/127] fix prod diamond --- Mathlib/Algebra/Group/Prod.lean | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mathlib/Algebra/Group/Prod.lean b/Mathlib/Algebra/Group/Prod.lean index 7c8bf82d187fa0..2b5d2b9cced898 100644 --- a/Mathlib/Algebra/Group/Prod.lean +++ b/Mathlib/Algebra/Group/Prod.lean @@ -75,6 +75,9 @@ instance commMagma [CommMagma M] [CommMagma N] : CommMagma (M × N) where @[to_additive] instance instSemigroup [Semigroup M] [Semigroup N] : Semigroup (M × N) where + ppow := fun n hn a => ⟨Semigroup.ppow n hn a.1, Semigroup.ppow n hn a.2⟩ + ppow_one _ := Prod.ext (Semigroup.ppow_one _) (Semigroup.ppow_one _) + ppow_succ _ _ := Prod.ext (Semigroup.ppow_succ _ _) (Semigroup.ppow_succ _ _) mul_assoc _ _ _ := by ext <;> exact mul_assoc .. @[to_additive] From 5534581f62ccc8fbd8d8135b5403da14d42951e5 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 25 Jun 2026 11:44:07 -0400 Subject: [PATCH 102/127] order interval algebra --- Mathlib/Algebra/Order/Interval/Basic.lean | 17 ++++++++++++++--- Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean | 9 +++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Mathlib/Algebra/Order/Interval/Basic.lean b/Mathlib/Algebra/Order/Interval/Basic.lean index 620b79a1c6fa82..eb02b822c49041 100644 --- a/Mathlib/Algebra/Order/Interval/Basic.lean +++ b/Mathlib/Algebra/Order/Interval/Basic.lean @@ -186,6 +186,11 @@ end Mul section Pow +@[to_additive] +instance NonemptyInterval.instPPow [Semigroup α] [Preorder α] [MulLeftMono α] [MulRightMono α] : + Pow (NonemptyInterval α) ℕ+ := + ⟨fun s n => ⟨s.toProd ^ n, ppow_le_ppow_left' s.fst_le_snd _⟩⟩ + variable [Monoid α] [Preorder α] @[to_additive] @@ -198,7 +203,11 @@ namespace NonemptyInterval variable [MulLeftMono α] [MulRightMono α] variable (s : NonemptyInterval α) (a : α) (n : ℕ) -@[to_additive (attr := simp) toProd_nsmul] +@[to_additive (reorder := s n) (attr := simp) toProd_psmul] +theorem toProd_ppow (n : ℕ+) : (s ^ n).toProd = s.toProd ^ n := + rfl + +@[to_additive (reorder := s n) (attr := simp) toProd_nsmul] theorem toProd_pow : (s ^ n).toProd = s.toProd ^ n := rfl @@ -223,7 +232,8 @@ namespace NonemptyInterval @[to_additive] instance commMonoid [CommMonoid α] [Preorder α] [IsOrderedMonoid α] : CommMonoid (NonemptyInterval α) := - fast_instance% NonemptyInterval.toProd_injective.commMonoid _ toProd_one toProd_mul toProd_pow + fast_instance% NonemptyInterval.toProd_injective.commMonoid _ toProd_one toProd_mul + toProd_ppow toProd_pow end NonemptyInterval @@ -298,7 +308,8 @@ namespace NonemptyInterval instance [CommSemiring α] [PartialOrder α] [CanonicallyOrderedAdd α] : CommSemiring (NonemptyInterval α) := fast_instance% NonemptyInterval.toProd_injective.commSemiring _ - toProd_zero toProd_one toProd_add toProd_mul (swap toProd_nsmul) toProd_pow (fun _ => rfl) + toProd_zero toProd_one toProd_add toProd_mul toProd_psmul toProd_nsmul + toProd_ppow toProd_pow (fun _ => rfl) end NonemptyInterval diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean index b226d0fcce3369..6202cd6df43ec9 100644 --- a/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean +++ b/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean @@ -175,6 +175,15 @@ section CovariantLESwap variable [Preorder β] [MulLeftMono M] [MulRightMono M] +@[to_additive (attr := mono, gcongr) psmul_le_psmul_right] +theorem ppow_le_ppow_left' {M : Type*} [Semigroup M] [Preorder M] [MulLeftMono M] [MulRightMono M] + {a b : M} (hab : a ≤ b) (i : ℕ+) : a ^ i ≤ b ^ i := by + induction i using Semigroup.ppow_induction a generalizing b with + | h1 => simp [hab] + | hsucc i IH => + rw [ppow_mk_add_one b] + exact mul_le_mul' (IH hab) hab + @[to_additive (attr := mono, gcongr) nsmul_le_nsmul_right] theorem pow_le_pow_left' {a b : M} (hab : a ≤ b) : ∀ i : ℕ, a ^ i ≤ b ^ i | 0 => by simp From 463f31d11539dff03bf310a680f9cc95884da769 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 25 Jun 2026 12:55:52 -0400 Subject: [PATCH 103/127] CentroidHom --- Mathlib/Algebra/Ring/CentroidHom.lean | 45 ++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/Mathlib/Algebra/Ring/CentroidHom.lean b/Mathlib/Algebra/Ring/CentroidHom.lean index 40144449bb936c..c51e08edd59dbc 100644 --- a/Mathlib/Algebra/Ring/CentroidHom.lean +++ b/Mathlib/Algebra/Ring/CentroidHom.lean @@ -246,6 +246,10 @@ instance instSMul : SMul M (CentroidHom α) where change n • f (a * b) = n • f a * b rw [map_mul_right f, ← smul_mul_assoc] } +-- separate because `ℕ+` is not a `Monoid` +instance instPSMul : SMul ℕ+ (CentroidHom α) where + smul n f := n.val • f + instance [SMul M N] [IsScalarTower M N α] : IsScalarTower M N (CentroidHom α) where smul_assoc _ _ _ := ext fun _ => smul_assoc _ _ _ @@ -258,6 +262,28 @@ instance [DistribMulAction Mᵐᵒᵖ α] [IsCentralScalar M α] : IsCentralScal instance isScalarTowerRight : IsScalarTower M (CentroidHom α) (CentroidHom α) where smul_assoc _ _ _ := rfl +instance hasPPow : Pow (CentroidHom α) ℕ+ := + ⟨fun f n ↦ + { toAddMonoidHom := (f.toEnd ^ n : AddMonoid.End α) + map_mul_left' := fun a b ↦ by + induction n using Semigroup.ppow_induction f.toEnd generalizing b with + | h1 => exact f.map_mul_left' _ _ + | hsucc n IH => + have : f.toEnd (a * b) = a * f.toEnd b := f.map_mul_left' a b + refine (congr_fun (AddMonoid.End.coe_mul _ + (f.toEnd ^ PNat.mk (n + 1) (Nat.succ_pos n)) f.toEnd) (a * b)).trans ?_ + simp only [Function.comp_apply, this] + exact IH (f.toEnd b) + map_mul_right' := fun a b ↦ by + induction n using Semigroup.ppow_induction f.toEnd generalizing a with + | h1 => exact f.map_mul_right' _ _ + | hsucc n IH => + have h a b : f.toEnd (a * b) = f.toEnd a * b := f.map_mul_right' a b + refine (congr_fun (AddMonoid.End.coe_mul _ + (f.toEnd ^ PNat.mk (n + 1) (Nat.succ_pos n)) f.toEnd) (a * b)).trans ?_ + simp only [Function.comp_apply, h] + exact IH (f.toEnd a)}⟩ + instance hasNPowNat : Pow (CentroidHom α) ℕ := ⟨fun f n ↦ { toAddMonoidHom := (f.toEnd ^ n : AddMonoid.End α) @@ -327,8 +353,13 @@ theorem toEnd_add (x y : CentroidHom α) : (x + y).toEnd = x.toEnd + y.toEnd := theorem toEnd_smul (m : M) (x : CentroidHom α) : (m • x).toEnd = m • x.toEnd := rfl +theorem toEnd_psmul (n : ℕ+) (x : CentroidHom α) : (n • x).toEnd = n • x.toEnd := by + rw [← nsmul_val_eq_psmul] + exact toEnd_smul n.val x + instance : AddCommMonoid (CentroidHom α) := - coe_toAddMonoidHom_injective.addCommMonoid _ toEnd_zero toEnd_add (swap toEnd_smul) + coe_toAddMonoidHom_injective.addCommMonoid _ toEnd_zero toEnd_add (swap toEnd_psmul) + (swap toEnd_smul) instance : NatCast (CentroidHom α) where natCast n := n • (1 : CentroidHom α) @@ -347,6 +378,10 @@ theorem toEnd_one : (1 : CentroidHom α).toEnd = 1 := theorem toEnd_mul (x y : CentroidHom α) : (x * y).toEnd = x.toEnd * y.toEnd := rfl +@[simp] +theorem toEnd_ppow (x : CentroidHom α) (n : ℕ+) : (x ^ n).toEnd = x.toEnd ^ n := + rfl + @[simp] theorem toEnd_pow (x : CentroidHom α) (n : ℕ) : (x ^ n).toEnd = x.toEnd ^ n := rfl @@ -357,8 +392,8 @@ theorem toEnd_natCast (n : ℕ) : (n : CentroidHom α).toEnd = ↑n := -- cf `add_monoid.End.semiring` instance : Semiring (CentroidHom α) := - toEnd_injective.semiring _ toEnd_zero toEnd_one toEnd_add toEnd_mul toEnd_smul toEnd_pow - toEnd_natCast + toEnd_injective.semiring _ toEnd_zero toEnd_one toEnd_add toEnd_mul toEnd_psmul toEnd_smul + toEnd_ppow toEnd_pow toEnd_natCast variable (α) in /-- `CentroidHom.toEnd` as a `RingHom`. -/ @@ -571,7 +606,7 @@ theorem toEnd_sub (x y : CentroidHom α) : (x - y).toEnd = x.toEnd - y.toEnd := instance : AddCommGroup (CentroidHom α) := toEnd_injective.addCommGroup _ - toEnd_zero toEnd_add toEnd_neg toEnd_sub (swap toEnd_smul) (swap toEnd_smul) + toEnd_zero toEnd_add toEnd_neg toEnd_sub (swap toEnd_psmul) (swap toEnd_smul) (swap toEnd_smul) @[simp, norm_cast] theorem coe_neg (f : CentroidHom α) : ⇑(-f) = -f := @@ -595,7 +630,7 @@ theorem toEnd_intCast (z : ℤ) : (z : CentroidHom α).toEnd = ↑z := instance instRing : Ring (CentroidHom α) := toEnd_injective.ring _ toEnd_zero toEnd_one toEnd_add toEnd_mul toEnd_neg toEnd_sub - toEnd_smul toEnd_smul toEnd_pow toEnd_natCast toEnd_intCast + toEnd_psmul toEnd_smul toEnd_smul toEnd_ppow toEnd_pow toEnd_natCast toEnd_intCast end NonUnitalNonAssocRing From b277caa16a67aa7d1d608b2a1f9dc339d6e39a68 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 25 Jun 2026 13:15:47 -0400 Subject: [PATCH 104/127] ppow_mem for MulMemClass --- Mathlib/Algebra/Group/Subsemigroup/Defs.lean | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Mathlib/Algebra/Group/Subsemigroup/Defs.lean b/Mathlib/Algebra/Group/Subsemigroup/Defs.lean index c93c52673989b6..5daf0de735ce1f 100644 --- a/Mathlib/Algebra/Group/Subsemigroup/Defs.lean +++ b/Mathlib/Algebra/Group/Subsemigroup/Defs.lean @@ -92,6 +92,13 @@ structure AddSubsemigroup (M : Type*) [Add M] where attribute [to_additive AddSubsemigroup] Subsemigroup +@[to_additive (attr := aesop 90% (rule_sets := [SetLike]))] +theorem ppow_mem {S A} [Semigroup S] [SetLike A S] [MulMemClass A S] {U : A} {x : S} + (hx : x ∈ U) (n : ℕ+) : x ^ n ∈ U := by + induction n using Semigroup.ppow_induction x + · exact hx + · exact MulMemClass.mul_mem ‹_› hx + namespace Subsemigroup @[to_additive] From 8f61589b4e502130dfd1c03060b92d11417c9b36 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 25 Jun 2026 13:19:14 -0400 Subject: [PATCH 105/127] restricted products --- .../Algebra/RestrictedProduct/Basic.lean | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Mathlib/Topology/Algebra/RestrictedProduct/Basic.lean b/Mathlib/Topology/Algebra/RestrictedProduct/Basic.lean index 46ec97c30dc377..975ad3c6351334 100644 --- a/Mathlib/Topology/Algebra/RestrictedProduct/Basic.lean +++ b/Mathlib/Topology/Algebra/RestrictedProduct/Basic.lean @@ -241,11 +241,21 @@ lemma div_apply [Π i, DivInvMonoid (R i)] [∀ i, SubgroupClass (S i) (R i)] (x y : Πʳ i, [R i, B i]_[𝓕]) (i : ι) : (x / y) i = x i / y i := rfl +@[to_additive] +instance instPPow [Π i, Semigroup (R i)] [∀ i, MulMemClass (S i) (R i)] : + Pow (Πʳ i, [R i, B i]_[𝓕]) ℕ+ where + pow x n := ⟨fun i ↦ x i ^ n, x.2.mono fun _ hi ↦ ppow_mem hi n⟩ + @[to_additive] instance instPow [Π i, Monoid (R i)] [∀ i, SubmonoidClass (S i) (R i)] : Pow (Πʳ i, [R i, B i]_[𝓕]) ℕ where pow x n := ⟨fun i ↦ x i ^ n, x.2.mono fun _ hi ↦ pow_mem hi n⟩ +@[to_additive] +lemma ppow_apply [Π i, Semigroup (R i)] [∀ i, MulMemClass (S i) (R i)] + (x : Πʳ i, [R i, B i]_[𝓕]) (n : ℕ+) (i : ι) : (x ^ n) i = x i ^ n := + rfl + @[to_additive] lemma pow_apply [Π i, Monoid (R i)] [∀ i, SubmonoidClass (S i) (R i)] (x : Πʳ i, [R i, B i]_[𝓕]) (n : ℕ) (i : ι) : (x ^ n) i = x i ^ n := @@ -254,12 +264,12 @@ lemma pow_apply [Π i, Monoid (R i)] [∀ i, SubmonoidClass (S i) (R i)] @[to_additive] instance [Π i, Monoid (R i)] [∀ i, SubmonoidClass (S i) (R i)] : Monoid (Πʳ i, [R i, B i]_[𝓕]) := - DFunLike.coe_injective.monoid _ rfl (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) + DFunLike.coe_injective.monoid _ rfl (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) @[to_additive] instance [Π i, CommMonoid (R i)] [∀ i, SubmonoidClass (S i) (R i)] : CommMonoid (Πʳ i, [R i, B i]_[𝓕]) := - DFunLike.coe_injective.commMonoid _ rfl (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) + DFunLike.coe_injective.commMonoid _ rfl (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) @[to_additive] instance instZPow [Π i, DivInvMonoid (R i)] [∀ i, SubgroupClass (S i) (R i)] : @@ -279,13 +289,13 @@ instance [Π i, AddMonoidWithOne (R i)] [∀ i, AddSubmonoidWithOneClass (S i) ( instance [Π i, Group (R i)] [∀ i, SubgroupClass (S i) (R i)] : Group (Πʳ i, [R i, B i]_[𝓕]) := DFunLike.coe_injective.group _ rfl (fun _ _ ↦ rfl) (fun _ ↦ rfl) (fun _ _ ↦ rfl) - (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) + (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) @[to_additive] instance [Π i, CommGroup (R i)] [∀ i, SubgroupClass (S i) (R i)] : CommGroup (Πʳ i, [R i, B i]_[𝓕]) := DFunLike.coe_injective.commGroup _ rfl (fun _ _ ↦ rfl) (fun _ ↦ rfl) (fun _ _ ↦ rfl) - (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) + (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) instance [Π i, Ring (R i)] [∀ i, SubringClass (S i) (R i)] : IntCast (Πʳ i, [R i, B i]_[𝓕]) where @@ -294,7 +304,8 @@ instance [Π i, Ring (R i)] [∀ i, SubringClass (S i) (R i)] : instance [Π i, Ring (R i)] [∀ i, SubringClass (S i) (R i)] : Ring (Πʳ i, [R i, B i]_[𝓕]) := DFunLike.coe_injective.ring _ 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 _ _ ↦ rfl) + (fun _ _ ↦ rfl) (fun _ ↦ rfl) (fun _ ↦ rfl) instance [Π i, CommRing (R i)] [∀ i, SubringClass (S i) (R i)] : CommRing (Πʳ i, [R i, B i]_[𝓕]) where From a5a1db63cba6c7f3410809300e53499d6f880133 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 25 Jun 2026 13:34:46 -0400 Subject: [PATCH 106/127] HahnSeries --- Mathlib/RingTheory/HahnSeries/Addition.lean | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Mathlib/RingTheory/HahnSeries/Addition.lean b/Mathlib/RingTheory/HahnSeries/Addition.lean index 3980046d3b6e78..a9737142b0fa8f 100644 --- a/Mathlib/RingTheory/HahnSeries/Addition.lean +++ b/Mathlib/RingTheory/HahnSeries/Addition.lean @@ -118,11 +118,19 @@ theorem coeff_add {x y : R⟦Γ⟧} {a : Γ} : (x + y).coeff a = x.coeff a + y.c classical ext : 1; exact Pi.single_add (f := fun _ => R) a r s +-- can't infer this otherwise, since `ℕ+` has no `Zero` instance, so can't be `SMulZeroClass` +instance instPSMul : SMul ℕ+ R⟦Γ⟧ where + smul n x := n.val • x + +theorem coeff_nsmul {x : R⟦Γ⟧} {n : ℕ} : (n • x).coeff = n • x.coeff := rfl + +theorem coeff_psmul {x : R⟦Γ⟧} {n : ℕ+} : (n • x).coeff = n • x.coeff := by + rw [← nsmul_val_eq_psmul] + rfl + instance : AddMonoid R⟦Γ⟧ := fast_instance% coeff_injective.addMonoid _ - coeff_zero' coeff_add' (fun _ _ => coeff_smul' _ _) - -theorem coeff_nsmul {x : R⟦Γ⟧} {n : ℕ} : (n • x).coeff = n • x.coeff := coeff_smul' _ _ + coeff_zero' coeff_add' (fun _ _ ↦ coeff_psmul) (fun _ _ ↦ coeff_nsmul) @[simp] protected lemma map_add [AddMonoid S] (f : R →+ S) {x y : R⟦Γ⟧} : @@ -365,7 +373,7 @@ theorem coeff_sub {x y : R⟦Γ⟧} {a : Γ} : (x - y).coeff a = x.coeff a - y.c instance : AddGroup R⟦Γ⟧ := fast_instance% coeff_injective.addGroup _ coeff_zero' coeff_add' coeff_neg' coeff_sub' - (fun _ _ => coeff_smul' _ _) (fun _ _ => coeff_smul' _ _) + (fun _ _ => coeff_psmul) (fun _ _ => coeff_nsmul) (fun _ _ => rfl) @[simp] theorem single_sub (a : Γ) (r s : R) : single a (r - s) = single a r - single a s := From 87c605f943d7ec898ca27c5df17791a2e6104f1a Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Thu, 25 Jun 2026 13:44:08 -0400 Subject: [PATCH 107/127] fix Function.End diamond, unloack AddConstMap --- Mathlib/Algebra/AddConstMap/Basic.lean | 8 +++++++- Mathlib/Algebra/Group/End.lean | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Mathlib/Algebra/AddConstMap/Basic.lean b/Mathlib/Algebra/AddConstMap/Basic.lean index 4e52663a049314..5b4160def698c1 100644 --- a/Mathlib/Algebra/AddConstMap/Basic.lean +++ b/Mathlib/Algebra/AddConstMap/Basic.lean @@ -387,11 +387,15 @@ instance {K : Type*} [AddMonoid K] [AddAction K H] [VAddAssocClass K H H] : instance : Mul (G →+c[a, a] G) := ⟨comp⟩ instance : One (G →+c[a, a] G) := ⟨.id⟩ +instance : Pow (G →+c[a, a] G) ℕ+ where + pow f n := ⟨f^[n], Commute.iterate_left (AddConstMapClass.semiconj f) _⟩ + instance : Pow (G →+c[a, a] G) ℕ where pow f n := ⟨f^[n], Commute.iterate_left (AddConstMapClass.semiconj f) _⟩ instance : Monoid (G →+c[a, a] G) := - DFunLike.coe_injective.monoid (M₂ := Function.End G) _ rfl (fun _ _ ↦ rfl) fun _ _ ↦ rfl + DFunLike.coe_injective.monoid (M₂ := Function.End G) _ rfl (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) + fun _ _ ↦ rfl theorem mul_def (f g : G →+c[a, a] G) : f * g = f.comp g := rfl @[simp, push_cast] theorem coe_mul (f g : G →+c[a, a] G) : ⇑(f * g) = f ∘ g := rfl @@ -401,6 +405,8 @@ theorem one_def : (1 : G →+c[a, a] G) = .id := rfl @[simp, push_cast] theorem coe_pow (f : G →+c[a, a] G) (n : ℕ) : ⇑(f ^ n) = f^[n] := rfl +theorem ppow_apply (f : G →+c[a, a] G) (n : ℕ+) (x : G) : (f ^ n) x = f^[n] x := rfl + theorem pow_apply (f : G →+c[a, a] G) (n : ℕ) (x : G) : (f ^ n) x = f^[n] x := rfl /-- Coercion to functions as a monoid homomorphism to `Function.End G`. -/ diff --git a/Mathlib/Algebra/Group/End.lean b/Mathlib/Algebra/Group/End.lean index 9c3dabedf1513b..d4617d793c5f70 100644 --- a/Mathlib/Algebra/Group/End.lean +++ b/Mathlib/Algebra/Group/End.lean @@ -54,6 +54,8 @@ instance : Monoid (Function.End α) where mul_assoc _ _ _ := rfl mul_one _ := rfl one_mul _ := rfl + ppow n _ f := f^[n] + ppow_succ _ _ := Function.iterate_succ _ _ npow n f := f^[n] npow_succ _ _ := Function.iterate_succ _ _ From 15016a8b80a6e55701edcc08b644f5b3975214ce Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 12:22:15 -0400 Subject: [PATCH 108/127] solve Pi diamond by different reducibility on PNat --- Mathlib/Data/PNat/Basic.lean | 2 +- Mathlib/Data/PNat/Notation.lean | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Mathlib/Data/PNat/Basic.lean b/Mathlib/Data/PNat/Basic.lean index 61fb27f756dcf9..de6940d01896dd 100644 --- a/Mathlib/Data/PNat/Basic.lean +++ b/Mathlib/Data/PNat/Basic.lean @@ -298,7 +298,7 @@ theorem dvd_iff {k m : ℕ+} : k ∣ m ↔ (k : ℕ) ∣ (m : ℕ) := by rintro rfl simp only [mul_zero, ne_zero] at h use ⟨n.succ, n.succ_pos⟩ - rw [← coe_inj, h, mul_coe, mk_coe] + rw [← coe_inj, h, mul_coe, mk_coe _ k.prop] theorem dvd_iff' {k m : ℕ+} : k ∣ m ↔ mod m k = k := by rw [dvd_iff] diff --git a/Mathlib/Data/PNat/Notation.lean b/Mathlib/Data/PNat/Notation.lean index 53127e023581f8..19d77ead280c20 100644 --- a/Mathlib/Data/PNat/Notation.lean +++ b/Mathlib/Data/PNat/Notation.lean @@ -14,6 +14,7 @@ public import Mathlib.Data.Nat.Notation /-- `ℕ+` is the type of positive natural numbers. It is defined as a subtype, and the VM representation of `ℕ+` is the same as `ℕ` because the proof is not stored. -/ +@[instance_reducible] def PNat := { n : ℕ // 0 < n } deriving DecidableEq @[inherit_doc] @@ -22,9 +23,17 @@ notation "ℕ+" => PNat /-- Helper constructor for `ℕ+`. -/ abbrev PNat.mk (n : ℕ) (h : 0 < n) : ℕ+ := ⟨n, h⟩ +-- Assert that eta-rfl works; if `PNat.mk` was a `def`, it would not. +example (n : ℕ+) : n = PNat.mk n.val n.property := by + with_reducible_and_instances rfl + /-- The underlying natural number -/ @[coe] -def PNat.val : ℕ+ → ℕ := Subtype.val +abbrev PNat.val : ℕ+ → ℕ := Subtype.val + +-- Assert that eta-rfl works; if `PNat.val` was a `def`, it would not. +example (n : ℕ+) : n = PNat.mk (PNat.val n) n.property := by + with_reducible_and_instances rfl instance coePNatNat : Coe ℕ+ ℕ := ⟨PNat.val⟩ From 058a5e2574005e9a2e4bd41050019ec3637d1404 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 13:09:15 -0400 Subject: [PATCH 109/127] SMulZeroClass with PNat Need to find where to put SemigroupAction --- Mathlib/Algebra/Module/NatInt.lean | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Mathlib/Algebra/Module/NatInt.lean b/Mathlib/Algebra/Module/NatInt.lean index c13abc34e7d47e..55604d3e8c8e7c 100644 --- a/Mathlib/Algebra/Module/NatInt.lean +++ b/Mathlib/Algebra/Module/NatInt.lean @@ -45,6 +45,11 @@ instance [AddMonoid M] : SMulWithZero ℕ M where smul_zero := nsmul_zero zero_smul := zero_nsmul +-- Ideally we would also have `SemigroupAction ℕ+ M` but no `Semigroup ℕ+` available here + +instance [AddMonoid M] : SMulZeroClass ℕ+ M where + smul_zero := psmul_zero + instance [SubtractionMonoid M] : MulAction ℤ M where one_smul := one_zsmul mul_smul _ _ _ := mul_zsmul .. From ea8be61b14410516e47713bc230975cd53f1c02a Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 13:16:53 -0400 Subject: [PATCH 110/127] IncidenceAlgebra --- .../Combinatorics/Enumerative/IncidenceAlgebra.lean | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Mathlib/Combinatorics/Enumerative/IncidenceAlgebra.lean b/Mathlib/Combinatorics/Enumerative/IncidenceAlgebra.lean index 0522e1ad32621b..44bd9ededf0e8b 100644 --- a/Mathlib/Combinatorics/Enumerative/IncidenceAlgebra.lean +++ b/Mathlib/Combinatorics/Enumerative/IncidenceAlgebra.lean @@ -155,11 +155,15 @@ lemma constSMul_apply (c : M) (f : IncidenceAlgebra 𝕜 α) (a b : α) : (c • end Smul +instance instPSMul {𝕜 : Type*} [AddMonoid 𝕜] [LE α] : SMul ℕ+ (IncidenceAlgebra 𝕜 α) where + smul n f := + ⟨n • ⇑f, fun a b hab ↦ by simp_rw [Pi.smul_apply, apply_eq_zero_of_not_le hab, smul_zero n] ⟩ + instance instAddMonoid [AddMonoid 𝕜] [LE α] : AddMonoid (IncidenceAlgebra 𝕜 α) := - DFunLike.coe_injective.addMonoid _ coe_zero coe_add fun _ _ ↦ rfl + DFunLike.coe_injective.addMonoid _ coe_zero coe_add (fun _ _ ↦ rfl) fun _ _ ↦ rfl instance instAddCommMonoid [AddCommMonoid 𝕜] [LE α] : AddCommMonoid (IncidenceAlgebra 𝕜 α) := - DFunLike.coe_injective.addCommMonoid _ coe_zero coe_add fun _ _ ↦ rfl + DFunLike.coe_injective.addCommMonoid _ coe_zero coe_add (fun _ _ ↦ rfl) fun _ _ ↦ rfl section AddGroup variable [AddGroup 𝕜] [LE α] @@ -176,13 +180,14 @@ lemma neg_apply (f : IncidenceAlgebra 𝕜 α) (a b : α) : (-f) a b = -f a b := lemma sub_apply (f g : IncidenceAlgebra 𝕜 α) (a b : α) : (f - g) a b = f a b - g a b := rfl instance instAddGroup : AddGroup (IncidenceAlgebra 𝕜 α) := - DFunLike.coe_injective.addGroup _ coe_zero coe_add coe_neg coe_sub (fun _ _ ↦ rfl) fun _ _ ↦ rfl + DFunLike.coe_injective.addGroup _ coe_zero coe_add coe_neg coe_sub (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) + fun _ _ ↦ rfl end AddGroup instance instAddCommGroup [AddCommGroup 𝕜] [LE α] : AddCommGroup (IncidenceAlgebra 𝕜 α) := DFunLike.coe_injective.addCommGroup _ coe_zero coe_add coe_neg coe_sub (fun _ _ ↦ rfl) - fun _ _ ↦ rfl + (fun _ _ ↦ rfl) fun _ _ ↦ rfl section One variable [Preorder α] [DecidableEq α] [Zero 𝕜] [One 𝕜] From 612014a97625e65f5d55b56c9b3ae0cc3701ae9b Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 13:27:34 -0400 Subject: [PATCH 111/127] NNReal --- Mathlib/Data/NNReal/Defs.lean | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mathlib/Data/NNReal/Defs.lean b/Mathlib/Data/NNReal/Defs.lean index d1a46797c16806..c186f0c90d27d2 100644 --- a/Mathlib/Data/NNReal/Defs.lean +++ b/Mathlib/Data/NNReal/Defs.lean @@ -113,7 +113,8 @@ it needs to be reducible(-with-instances). noncomputable instance : Semifield ℝ≥0 := fast_instance% Function.Injective.semifield toReal Subtype.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 _ _ => rfl) (fun _ _ => rfl) + (fun _ => rfl) (fun _ => rfl) instance : IsOrderedRing ℝ≥0 := Nonneg.isOrderedRing From 68111df4dbc71308662ab7a03d418f9728db8718 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 13:36:44 -0400 Subject: [PATCH 112/127] Lie --- Mathlib/Algebra/Lie/Basic.lean | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Lie/Basic.lean b/Mathlib/Algebra/Lie/Basic.lean index e90318b3481721..8e68e9a1351816 100644 --- a/Mathlib/Algebra/Lie/Basic.lean +++ b/Mathlib/Algebra/Lie/Basic.lean @@ -201,6 +201,14 @@ theorem sub_lie : ⁅x - y, m⁆ = ⁅x, m⁆ - ⁅y, m⁆ := by simp [sub_eq_ad @[simp] theorem lie_sub : ⁅x, m - n⁆ = ⁅x, m⁆ - ⁅x, n⁆ := by simp [sub_eq_add_neg] +@[simp] +theorem psmul_lie (n : ℕ+) : ⁅n • x, m⁆ = n • ⁅x, m⁆ := + AddHom.map_psmul { toFun := fun x : L => ⁅x, m⁆, map_add' := fun _ _ => add_lie _ _ _ } _ _ + +@[simp] +theorem lie_psmul (n : ℕ+) : ⁅x, n • m⁆ = n • ⁅x, m⁆ := + AddHom.map_psmul { toFun := fun m : M => ⁅x, m⁆, map_add' := fun _ _ => lie_add _ _ _ } _ _ + @[simp] theorem nsmul_lie (n : ℕ) : ⁅n • x, m⁆ = n • ⁅x, m⁆ := AddMonoidHom.map_nsmul @@ -817,6 +825,16 @@ theorem coe_neg (f : M →ₗ⁅R,L⁆ N) : ⇑(-f) = -f := theorem neg_apply (f : M →ₗ⁅R,L⁆ N) (m : M) : (-f) m = -f m := rfl +instance hasPSMul : SMul ℕ+ (M →ₗ⁅R,L⁆ N) where + smul n f := { n • (f : M →ₗ[R] N) with map_lie' := by simp } + +@[norm_cast, simp] +theorem coe_psmul (n : ℕ+) (f : M →ₗ⁅R,L⁆ N) : ⇑(n • f) = n • (⇑f) := + rfl + +theorem psmul_apply (n : ℕ+) (f : M →ₗ⁅R,L⁆ N) (m : M) : (n • f) m = n • f m := + rfl + instance hasNSMul : SMul ℕ (M →ₗ⁅R,L⁆ N) where smul n f := { n • (f : M →ₗ[R] N) with map_lie' := by simp } @@ -838,8 +856,8 @@ theorem zsmul_apply (z : ℤ) (f : M →ₗ⁅R,L⁆ N) (m : M) : (z • f) m = rfl instance : AddCommGroup (M →ₗ⁅R,L⁆ N) := - coe_injective.addCommGroup _ coe_zero coe_add coe_neg coe_sub (fun _ _ => coe_nsmul _ _) - (fun _ _ => coe_zsmul _ _) + coe_injective.addCommGroup _ coe_zero coe_add coe_neg coe_sub (fun _ _ => rfl) + (fun _ _ => coe_nsmul _ _) (fun _ _ => coe_zsmul _ _) variable [LieAlgebra R L] [LieModule R L N] From 1fceae8542ffe584fa2f5d86ab13668db95796df Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 13:41:22 -0400 Subject: [PATCH 113/127] move map_ppow --- Mathlib/Algebra/Group/Hom/Defs.lean | 6 ++++++ Mathlib/Algebra/Group/PPow/Basic.lean | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Mathlib/Algebra/Group/Hom/Defs.lean b/Mathlib/Algebra/Group/Hom/Defs.lean index eaef2e8f82bc39..4317b727dcdc33 100644 --- a/Mathlib/Algebra/Group/Hom/Defs.lean +++ b/Mathlib/Algebra/Group/Hom/Defs.lean @@ -686,6 +686,12 @@ protected theorem MulHom.map_ppow {M N : Type*} [Semigroup M] [Semigroup N] (f : · simp · simp [ppow_mk_add_one, *] +-- not marked as `simp` because in a monoid we probably prefer powers with type `ℕ` +@[to_additive (reorder := x n)] +lemma map_ppow {F M N : Type _} [Semigroup M] [Semigroup N] [FunLike F M N] [MulHomClass F M N] + (f : F) (x : M) (n : ℕ+) : f (x ^ n) = f x ^ n := + MulHom.map_ppow (MulHomClass.toMulHom f) _ _ + /-- If `f` is a monoid homomorphism then `f (a * b) = f a * f b`. -/ @[to_additive /-- If `f` is an additive monoid homomorphism then `f (a + b) = f a + f b`. -/] protected theorem MonoidHom.map_mul [MulOne M] [MulOne N] (f : M →* N) (a b : M) : diff --git a/Mathlib/Algebra/Group/PPow/Basic.lean b/Mathlib/Algebra/Group/PPow/Basic.lean index 7af6898da3cb7b..dcdb1aecda1fc6 100644 --- a/Mathlib/Algebra/Group/PPow/Basic.lean +++ b/Mathlib/Algebra/Group/PPow/Basic.lean @@ -85,9 +85,3 @@ end CommSemigroup @[to_additive] theorem pow_mul_comm'' [Monoid M] (a : M) (n : ℕ+) : a ^ n * a = a * a ^ n := by exact ppow_mul_comm' a n - --- not marked as `simp` because in a monoid we probably prefer powers with type `ℕ` -@[to_additive] -lemma map_ppow {F M N : Type _} [Semigroup M] [Semigroup N] [FunLike F M N] [MulHomClass F M N] - (f : F) (x : M) (n : ℕ+) : f (x ^ n) = f x ^ n := - MulHom.map_ppow (MulHomClass.toMulHom f) _ _ From 6dd5f5c9244d2618dc01c823a0fc4a4e32ee1105 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 13:56:47 -0400 Subject: [PATCH 114/127] DirectSum ring instance --- Mathlib/Algebra/DirectSum/Ring.lean | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Mathlib/Algebra/DirectSum/Ring.lean b/Mathlib/Algebra/DirectSum/Ring.lean index 3f887f3139cf5c..9f8bfa03a376ff 100644 --- a/Mathlib/Algebra/DirectSum/Ring.lean +++ b/Mathlib/Algebra/DirectSum/Ring.lean @@ -398,7 +398,7 @@ of a `GNonUnitalNonAssocSemiring`. -/ scoped instance (priority := 900) : NonUnitalNonAssocSemiring (A 0) := Function.Injective.nonUnitalNonAssocSemiring (of A 0) DFinsupp.single_injective (of A 0).map_zero - (of A 0).map_add (of_zero_mul A) (map_nsmul _) + (of A 0).map_add (of_zero_mul A) (map_psmul _) (map_nsmul _) /-- The `SMulWithZero` structure on the grade zero part of a `GNonUnitalNonAssocSemiring`. -/ @@ -414,6 +414,10 @@ section Semiring variable [∀ i, AddCommMonoid (A i)] [AddMonoid ι] [GSemiring A] @[simp] +theorem of_zero_ppow (a : A 0) (n : ℕ+) : + of A 0 (a ^ n) = of A 0 a ^ n := by + induction n using Semigroup.ppow_induction a <;> simp [*, ppow_mk_add_one] + theorem of_zero_pow (a : A 0) : ∀ n : ℕ, of A 0 (a ^ n) = of A 0 a ^ n | 0 => by rw [pow_zero, pow_zero, DirectSum.of_zero_one] -- Porting note: Lean doesn't think this terminates if we only use `of_zero_pow` alone @@ -437,7 +441,8 @@ theorem of_zero_ofNat (n : ℕ) [n.AtLeastTwo] : of A 0 ofNat(n) = ofNat(n) := /-- The `Semiring` structure derived from `GSemiring A`. -/ scoped instance (priority := 900) : Semiring (A 0) := Function.Injective.semiring (of A 0) DFinsupp.single_injective (of A 0).map_zero (of_zero_one A) - (of A 0).map_add (of_zero_mul A) (fun _ _ ↦ (of A 0).map_nsmul _ _) + (of A 0).map_add (of_zero_mul A) (fun _ _ ↦ (of A 0).map_psmul _ _) + (fun _ _ ↦ (of A 0).map_nsmul _ _) (fun _ _ => of_zero_ppow _ _ _) (fun _ _ => of_zero_pow _ _ _) (of_natCast A) /-- `of A 0` is a `RingHom`, using the `DirectSum.GradeZero.semiring` structure. -/ @@ -462,7 +467,8 @@ variable [∀ i, AddCommMonoid (A i)] [AddCommMonoid ι] [GCommSemiring A] /-- The `CommSemiring` structure derived from `GCommSemiring A`. -/ scoped instance (priority := 900) : CommSemiring (A 0) := Function.Injective.commSemiring (of A 0) DFinsupp.single_injective (of A 0).map_zero - (of_zero_one A) (of A 0).map_add (of_zero_mul A) (fun _ _ ↦ map_nsmul _ _ _) + (of_zero_one A) (of A 0).map_add (of_zero_mul A) (fun _ _ ↦ map_psmul _ _ _) + (fun _ _ ↦ map_nsmul _ _ _) (fun _ _ => of_zero_ppow _ _ _) (fun _ _ => of_zero_pow _ _ _) (of_natCast A) end CommSemiring @@ -474,8 +480,8 @@ variable [∀ i, AddCommGroup (A i)] [AddZeroClass ι] [GNonUnitalNonAssocSemiri /-- The `NonUnitalNonAssocRing` derived from `GNonUnitalNonAssocSemiring A`. -/ scoped instance (priority := 900) : NonUnitalNonAssocRing (A 0) := Function.Injective.nonUnitalNonAssocRing (of A 0) DFinsupp.single_injective (of A 0).map_zero - (of A 0).map_add (of_zero_mul A) (of A 0).map_neg (of A 0).map_sub (fun _ _ ↦ map_nsmul _ _ _) - (fun _ _ ↦ map_zsmul _ _ _) + (of A 0).map_add (of_zero_mul A) (of A 0).map_neg (of A 0).map_sub (fun _ _ ↦ map_psmul _ _ _) + (fun _ _ ↦ map_nsmul _ _ _) (fun _ _ ↦ map_zsmul _ _ _) end Ring @@ -494,8 +500,9 @@ theorem of_intCast (n : ℤ) : of A 0 n = n := by /-- The `Ring` derived from `GSemiring A`. -/ scoped instance (priority := 900) : Ring (A 0) := Function.Injective.ring (of A 0) DFinsupp.single_injective (of A 0).map_zero (of_zero_one A) - (of A 0).map_add (of_zero_mul A) (of A 0).map_neg (of A 0).map_sub (fun _ _ ↦ map_nsmul _ _ _) - (fun _ _ ↦ map_zsmul _ _ _) (fun _ _ => of_zero_pow _ _ _) (of_natCast A) (of_intCast A) + (of A 0).map_add (of_zero_mul A) (of A 0).map_neg (of A 0).map_sub (fun _ _ ↦ map_psmul _ _ _) + (fun _ _ ↦ map_nsmul _ _ _) (fun _ _ ↦ map_zsmul _ _ _) (fun _ _ => of_zero_ppow _ _ _) + (fun _ _ => of_zero_pow _ _ _) (of_natCast A) (of_intCast A) end Ring @@ -506,8 +513,9 @@ variable [∀ i, AddCommGroup (A i)] [AddCommMonoid ι] [GCommRing A] /-- The `CommRing` derived from `GCommSemiring A`. -/ scoped instance (priority := 900) : CommRing (A 0) := Function.Injective.commRing (of A 0) DFinsupp.single_injective (of A 0).map_zero (of_zero_one A) - (of A 0).map_add (of_zero_mul A) (of A 0).map_neg (of A 0).map_sub (fun _ _ ↦ map_nsmul _ _ _) - (fun _ _ ↦ map_zsmul _ _ _) (fun _ _ => of_zero_pow _ _ _) (of_natCast A) (of_intCast A) + (of A 0).map_add (of_zero_mul A) (of A 0).map_neg (of A 0).map_sub (fun _ _ ↦ map_psmul _ _ _) + (fun _ _ ↦ map_nsmul _ _ _) (fun _ _ ↦ map_zsmul _ _ _) (fun _ _ => of_zero_ppow _ _ _) + (fun _ _ => of_zero_pow _ _ _) (of_natCast A) (of_intCast A) end CommRing From 07703de94276b17e044888770d6a3f0942a0683b Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 14:03:47 -0400 Subject: [PATCH 115/127] semimodule cat --- Mathlib/Algebra/Category/ModuleCat/Semi.lean | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Mathlib/Algebra/Category/ModuleCat/Semi.lean b/Mathlib/Algebra/Category/ModuleCat/Semi.lean index 9fea6dca48d399..202440956e0f44 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Semi.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Semi.lean @@ -295,6 +295,11 @@ instance : Zero (M ⟶ N) where @[simp] lemma hom_zero : (0 : M ⟶ N).hom = 0 := rfl +instance : SMul ℕ+ (M ⟶ N) where + smul n f := ⟨n • f.hom⟩ + +@[simp] lemma hom_psmul (n : ℕ+) (f : M ⟶ N) : (n • f).hom = n • f.hom := rfl + instance : SMul ℕ (M ⟶ N) where smul n f := ⟨n • f.hom⟩ @@ -306,6 +311,7 @@ alias hom_zsmul := hom_nsmul instance : AddCommMonoid (M ⟶ N) := Function.Injective.addCommMonoid Hom.hom hom_injective rfl (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) @[simp] lemma hom_sum {ι : Type*} (f : ι → (M ⟶ N)) (s : Finset ι) : (∑ i ∈ s, f i).hom = ∑ i ∈ s, (f i).hom := From 849ff7fbc1738fb6b8ed423a952ebbf7ddd42949 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 14:14:16 -0400 Subject: [PATCH 116/127] Polynomial with some removal of args --- Mathlib/Algebra/Polynomial/Basic.lean | 28 +++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/Mathlib/Algebra/Polynomial/Basic.lean b/Mathlib/Algebra/Polynomial/Basic.lean index bedc15cd7f6966..da2df3218041d3 100644 --- a/Mathlib/Algebra/Polynomial/Basic.lean +++ b/Mathlib/Algebra/Polynomial/Basic.lean @@ -138,6 +138,8 @@ instance smulZeroClass {S : Type*} [SMulZeroClass S R] : SMulZeroClass S R[X] wh -- to avoid a bug in the `ring` tactic instance (priority := 1) pow : Pow R[X] ℕ where pow p n := npowRec n p +instance (priority := 1) ppow : Pow R[X] ℕ+ where pow p n := ppowRec n n.property p + @[simp] theorem ofFinsupp_zero : (⟨0⟩ : R[X]) = 0 := rfl @@ -180,6 +182,12 @@ theorem ofFinsupp_pow (a) (n : ℕ) : (⟨a ^ n⟩ : R[X]) = ⟨a⟩ ^ n := by | zero => simp [npowRec] | succ n n_ih => simp [npowRec, n_ih, pow_succ] +@[simp] +theorem ofFinsupp_ppow (a) (n : ℕ+) : (⟨a ^ n⟩ : R[X]) = ⟨a⟩ ^ n := by + induction n using Semigroup.ppow_induction a <;> + · try simp only [ofFinsupp_mul, *] + rfl + @[simp] theorem toFinsupp_zero : (0 : R[X]).toFinsupp = 0 := rfl @@ -206,6 +214,10 @@ theorem toFinsupp_sub {R : Type u} [Ring R] (a b : R[X]) : theorem toFinsupp_mul (a b : R[X]) : (a * b).toFinsupp = a.toFinsupp * b.toFinsupp := (rfl) +@[simp] +theorem toFinsupp_psmul (a : ℕ+) (b : R[X]) : (a • b).toFinsupp = a • b.toFinsupp := + rfl + @[simp] theorem toFinsupp_nsmul (a : ℕ) (b : R[X]) : (a • b).toFinsupp = a • b.toFinsupp := rfl @@ -215,6 +227,10 @@ theorem toFinsupp_smul {S : Type*} [SMulZeroClass S R] (a : S) (b : R[X]) : (a • b).toFinsupp = a • b.toFinsupp := rfl +@[simp] +theorem toFinsupp_ppow (a : R[X]) (n : ℕ+) : (a ^ n).toFinsupp = a.toFinsupp ^ n := by + rw [← ofFinsupp_ppow] + @[simp] theorem toFinsupp_pow (a : R[X]) (n : ℕ) : (a ^ n).toFinsupp = a.toFinsupp ^ n := by rw [← ofFinsupp_pow] @@ -268,8 +284,8 @@ theorem toFinsupp_ofNat (n : ℕ) [n.AtLeastTwo] : (ofNat(n) : R[X]).toFinsupp = instance semiring : Semiring R[X] := fast_instance% Function.Injective.semiring toFinsupp toFinsupp_injective toFinsupp_zero - toFinsupp_one toFinsupp_add toFinsupp_mul (fun _ _ ↦ toFinsupp_nsmul _ _) toFinsupp_pow - fun _ ↦ rfl + toFinsupp_one toFinsupp_add toFinsupp_mul toFinsupp_psmul toFinsupp_nsmul toFinsupp_ppow + toFinsupp_pow fun _ ↦ rfl instance distribSMul {S} [DistribSMul S R] : DistribSMul S R[X] := fast_instance% Function.Injective.distribSMul ⟨⟨toFinsupp, toFinsupp_zero⟩, toFinsupp_add⟩ @@ -1094,8 +1110,8 @@ section CommSemiring variable [CommSemiring R] instance commSemiring : CommSemiring R[X] := - fast_instance% { Function.Injective.commSemigroup toFinsupp toFinsupp_injective toFinsupp_mul with - toSemiring := Polynomial.semiring } + fast_instance% { Function.Injective.commSemigroup toFinsupp toFinsupp_injective toFinsupp_mul + toFinsupp_ppow with toSemiring := Polynomial.semiring } end CommSemiring @@ -1127,8 +1143,8 @@ theorem toFinsupp_intCast (z : ℤ) : (z : R[X]).toFinsupp = z := rfl instance ring : Ring R[X] := fast_instance% Function.Injective.ring toFinsupp toFinsupp_injective (toFinsupp_zero (R := R)) toFinsupp_one toFinsupp_add - toFinsupp_mul toFinsupp_neg toFinsupp_sub (fun _ _ ↦ toFinsupp_nsmul _ _) - (fun _ _ ↦ toFinsupp_zsmul _ _) toFinsupp_pow (fun _ ↦ rfl) fun _ ↦ rfl + toFinsupp_mul toFinsupp_neg toFinsupp_sub toFinsupp_psmul toFinsupp_nsmul + toFinsupp_zsmul toFinsupp_ppow toFinsupp_pow (fun _ ↦ rfl) fun _ ↦ rfl set_option backward.isDefEq.respectTransparency false in @[simp] From 6fdc5802987a973ce291f323e9a6674ee03ca14f Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 14:21:39 -0400 Subject: [PATCH 117/127] LocallyFinsupp --- Mathlib/Topology/LocallyFinsupp.lean | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Mathlib/Topology/LocallyFinsupp.lean b/Mathlib/Topology/LocallyFinsupp.lean index cab3d2bf990d59..7ed1cb643e4fd3 100644 --- a/Mathlib/Topology/LocallyFinsupp.lean +++ b/Mathlib/Topology/LocallyFinsupp.lean @@ -323,6 +323,9 @@ instance [AddMonoid Y] : Zero (locallyFinsuppWithin U Y) where instance [AddMonoid Y] : Add (locallyFinsuppWithin U Y) where add D₁ D₂ := mk_of_mem_addSubmonoid (D₁ + D₂) <| add_mem D₁.memAddSubmonoid D₂.memAddSubmonoid +instance [AddMonoid Y] : SMul ℕ+ (locallyFinsuppWithin U Y) where + smul n D := mk_of_mem_addSubmonoid (n • D) <| psmul_mem D.memAddSubmonoid n + instance [AddMonoid Y] : SMul ℕ (locallyFinsuppWithin U Y) where smul n D := mk_of_mem_addSubmonoid (n • D) <| nsmul_mem D.memAddSubmonoid n @@ -352,6 +355,8 @@ instance [AddGroup Y] : SMul ℤ (locallyFinsuppWithin U Y) where (↑(-D) : X → Y) = -(D : X → Y) := rfl @[simp] lemma coe_sub [AddGroup Y] (D₁ D₂ : locallyFinsuppWithin U Y) : (↑(D₁ - D₂) : X → Y) = D₁ - D₂ := rfl +@[simp] lemma coe_psmul [AddMonoid Y] (D : locallyFinsuppWithin U Y) (n : ℕ+) : + (↑(n • D) : X → Y) = n • (D : X → Y) := rfl @[simp] lemma coe_nsmul [AddMonoid Y] (D : locallyFinsuppWithin U Y) (n : ℕ) : (↑(n • D) : X → Y) = n • (D : X → Y) := rfl @[simp] lemma coe_zsmul [AddGroup Y] (D : locallyFinsuppWithin U Y) (n : ℤ) : @@ -359,11 +364,11 @@ instance [AddGroup Y] : SMul ℤ (locallyFinsuppWithin U Y) where instance [AddMonoid Y] : AddMonoid (locallyFinsuppWithin U Y) := Injective.addMonoid (M₁ := locallyFinsuppWithin U Y) (M₂ := X → Y) - _ coe_injective coe_zero coe_add coe_nsmul + _ coe_injective coe_zero coe_add (fun _ _ ↦ rfl) coe_nsmul instance [AddCommMonoid Y] : AddCommMonoid (locallyFinsuppWithin U Y) := Injective.addCommMonoid (M₁ := locallyFinsuppWithin U Y) (M₂ := X → Y) - _ coe_injective coe_zero coe_add coe_nsmul + _ coe_injective coe_zero coe_add coe_psmul coe_nsmul @[simp] lemma coe_sum [AddCommMonoid Y] {ι : Type*} {s : Finset ι} {F : ι → locallyFinsuppWithin U Y} : @@ -385,7 +390,7 @@ instance [AddCommMonoid Y] : AddCommMonoid (locallyFinsuppWithin U Y) := instance [AddGroup Y] : AddGroup (locallyFinsuppWithin U Y) := Injective.addGroup (M₁ := locallyFinsuppWithin U Y) (M₂ := X → Y) - _ coe_injective coe_zero coe_add coe_neg coe_sub coe_nsmul coe_zsmul + _ coe_injective coe_zero coe_add coe_neg coe_sub coe_psmul coe_nsmul coe_zsmul /-- Simplifier lemma: Support does not change when replacing a function with locally finite support by @@ -396,7 +401,7 @@ its negative. instance [AddCommGroup Y] : AddCommGroup (locallyFinsuppWithin U Y) := Injective.addCommGroup (M₁ := locallyFinsuppWithin U Y) (M₂ := X → Y) - _ coe_injective coe_zero coe_add coe_neg coe_sub coe_nsmul coe_zsmul + _ coe_injective coe_zero coe_add coe_neg coe_sub coe_psmul coe_nsmul coe_zsmul instance [LE Y] [Zero Y] : LE (locallyFinsuppWithin U Y) where le := fun D₁ D₂ ↦ (D₁ : X → Y) ≤ D₂ From f1ad31a09ace7c7c85438b71838df3e0714db3f3 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 14:34:14 -0400 Subject: [PATCH 118/127] AffineMap --- Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean b/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean index 1c0f189998dbf7..b69f47646a9d86 100644 --- a/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean +++ b/Mathlib/LinearAlgebra/AffineSpace/AffineMap.lean @@ -218,10 +218,18 @@ instance mulAction : MulAction R (P1 →ᵃ[k] V2) where one_smul _ := ext fun _ => one_smul _ _ mul_smul _ _ _ := ext fun _ => mul_smul _ _ _ +-- no SemigroupAction because no `Semigroup ℕ+` here +instance smulPNat : SMul ℕ+ (P1 →ᵃ[k] V2) where + smul n f := ⟨n • ⇑f, n • f.linear, fun p v => by simp⟩ + @[simp, norm_cast] theorem coe_smul (c : R) (f : P1 →ᵃ[k] V2) : ⇑(c • f) = c • ⇑f := rfl +@[simp, norm_cast] +theorem coe_psmul (c : ℕ+) (f : P1 →ᵃ[k] V2) : ⇑(c • f) = c • ⇑f := + rfl + @[simp] theorem smul_linear (t : R) (f : P1 →ᵃ[k] V2) : (t • f).linear = t • f.linear := rfl @@ -277,8 +285,8 @@ theorem neg_linear (f : P1 →ᵃ[k] V2) : (-f).linear = -f.linear := /-- The set of affine maps to a vector space is an additive commutative group. -/ instance : AddCommGroup (P1 →ᵃ[k] V2) := - coeFn_injective.addCommGroup _ coe_zero coe_add coe_neg coe_sub (fun _ _ => coe_smul _ _) - fun _ _ => coe_smul _ _ + coeFn_injective.addCommGroup _ coe_zero coe_add coe_neg coe_sub (fun _ _ => rfl) + (fun _ _ => coe_smul _ _) fun _ _ => coe_smul _ _ /-- The space of affine maps from `P1` to `P2` is an affine space over the space of affine maps from `P1` to the vector space `V2` corresponding to `P2`. -/ From 592e042e5f473d7e38942e7af9b91ebf485d2845 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 14:35:38 -0400 Subject: [PATCH 119/127] Preadditive --- Mathlib/Algebra/Category/Grp/Preadditive.lean | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Mathlib/Algebra/Category/Grp/Preadditive.lean b/Mathlib/Algebra/Category/Grp/Preadditive.lean index ccedfff6c22775..1610b5b25647b2 100644 --- a/Mathlib/Algebra/Category/Grp/Preadditive.lean +++ b/Mathlib/Algebra/Category/Grp/Preadditive.lean @@ -36,6 +36,11 @@ instance : Zero (M ⟶ N) where @[simp] lemma hom_zero : (0 : M ⟶ N).hom = 0 := rfl +instance : SMul ℕ+ (M ⟶ N) where + smul n f := ofHom (n • f.hom) + +@[simp] lemma hom_psmul (n : ℕ+) (f : M ⟶ N) : (n • f).hom = n • f.hom := rfl + instance : SMul ℕ (M ⟶ N) where smul n f := ofHom (n • f.hom) @@ -59,6 +64,7 @@ instance : SMul ℤ (M ⟶ N) where instance (P Q : AddCommGrpCat) : AddCommGroup (P ⟶ Q) := Function.Injective.addCommGroup (Hom.hom) ConcreteCategory.hom_injective rfl (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) instance : Preadditive AddCommGrpCat where From 6e2b13e6c013adfb7700b1b019d6854fd50c3c2c Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 14:41:43 -0400 Subject: [PATCH 120/127] skewalgebra --- Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean b/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean index ca290e8eb3c320..3c81768e6ee12d 100644 --- a/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean +++ b/Mathlib/Algebra/SkewMonoidAlgebra/Basic.lean @@ -142,7 +142,7 @@ instance [Subsingleton k] : Unique (SkewMonoidAlgebra k G) := instance : AddMonoid (SkewMonoidAlgebra k G) where __ := toFinsupp_injective.addMonoid _ toFinsupp_zero toFinsupp_add - (fun _ _ ↦ toFinsupp_smul _ _) + (fun _ _ ↦ toFinsupp_smul _ _) (fun _ _ ↦ toFinsupp_smul _ _) section Support @@ -347,7 +347,7 @@ variable [AddCommMonoid k] instance : AddCommMonoid (SkewMonoidAlgebra k G) where __ := toFinsupp_injective.addCommMonoid _ toFinsupp_zero toFinsupp_add - (fun _ _ ↦ toFinsupp_smul _ _) + (fun _ _ ↦ toFinsupp_smul _ _) (fun _ _ ↦ toFinsupp_smul _ _) section sum From 6a02a8e5d3fbddc2b02baef1b33432a091d5ffcf Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 14:46:22 -0400 Subject: [PATCH 121/127] locallyconstant rings --- Mathlib/Topology/LocallyConstant/Algebra.lean | 62 +++++++++++-------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/Mathlib/Topology/LocallyConstant/Algebra.lean b/Mathlib/Topology/LocallyConstant/Algebra.lean index 1259a89a1fe068..8e593fd881c6a2 100644 --- a/Mathlib/Topology/LocallyConstant/Algebra.lean +++ b/Mathlib/Topology/LocallyConstant/Algebra.lean @@ -118,17 +118,6 @@ theorem coe_div [Div Y] (f g : LocallyConstant X Y) : ⇑(f / g) = f / g := theorem div_apply [Div Y] (f g : LocallyConstant X Y) (x : X) : (f / g) x = f x / g x := rfl -@[to_additive] -instance [Semigroup Y] : Semigroup (LocallyConstant X Y) := - Function.Injective.semigroup DFunLike.coe DFunLike.coe_injective fun _ _ => rfl - -instance [SemigroupWithZero Y] : SemigroupWithZero (LocallyConstant X Y) := - Function.Injective.semigroupWithZero DFunLike.coe DFunLike.coe_injective rfl fun _ _ => rfl - -@[to_additive] -instance [CommSemigroup Y] : CommSemigroup (LocallyConstant X Y) := - Function.Injective.commSemigroup DFunLike.coe DFunLike.coe_injective fun _ _ => rfl - variable {α R : Type*} @[to_additive] @@ -147,9 +136,23 @@ theorem smul_apply [SMul R Y] (r : R) (f : LocallyConstant X Y) (x : X) : (r • instance [Pow Y α] : Pow (LocallyConstant X Y) α where pow f n := f.map (· ^ n) +@[to_additive] +instance [Semigroup Y] : Semigroup (LocallyConstant X Y) := + Function.Injective.semigroup DFunLike.coe DFunLike.coe_injective (fun _ _ => rfl) fun _ _ => rfl + +instance [SemigroupWithZero Y] : SemigroupWithZero (LocallyConstant X Y) := + Function.Injective.semigroupWithZero DFunLike.coe DFunLike.coe_injective rfl + (fun _ _ => rfl) fun _ _ => rfl + +@[to_additive] +instance [CommSemigroup Y] : CommSemigroup (LocallyConstant X Y) := + Function.Injective.commSemigroup DFunLike.coe DFunLike.coe_injective (fun _ _ => rfl) + fun _ _ => rfl + @[to_additive] instance [Monoid Y] : Monoid (LocallyConstant X Y) := - Function.Injective.monoid DFunLike.coe DFunLike.coe_injective rfl (fun _ _ => rfl) fun _ _ => rfl + Function.Injective.monoid DFunLike.coe DFunLike.coe_injective rfl (fun _ _ => rfl) + (fun _ _ => rfl) fun _ _ => rfl instance [NatCast Y] : NatCast (LocallyConstant X Y) where natCast n := const X n @@ -159,37 +162,37 @@ instance [IntCast Y] : IntCast (LocallyConstant X Y) where instance [AddMonoidWithOne Y] : AddMonoidWithOne (LocallyConstant X Y) := Function.Injective.addMonoidWithOne DFunLike.coe DFunLike.coe_injective rfl rfl (fun _ _ => rfl) - (fun _ _ => rfl) fun _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl @[to_additive] instance [CommMonoid Y] : CommMonoid (LocallyConstant X Y) := Function.Injective.commMonoid DFunLike.coe DFunLike.coe_injective rfl (fun _ _ => rfl) - fun _ _ => rfl + (fun _ _ => rfl) fun _ _ => rfl @[to_additive] instance [Group Y] : Group (LocallyConstant X Y) := Function.Injective.group DFunLike.coe DFunLike.coe_injective rfl (fun _ _ => rfl) - (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) @[to_additive] instance [CommGroup Y] : CommGroup (LocallyConstant X Y) := Function.Injective.commGroup DFunLike.coe DFunLike.coe_injective rfl (fun _ _ => rfl) - (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) instance [Distrib Y] : Distrib (LocallyConstant X Y) := Function.Injective.distrib DFunLike.coe DFunLike.coe_injective (fun _ _ => rfl) fun _ _ => rfl instance [NonUnitalNonAssocSemiring Y] : NonUnitalNonAssocSemiring (LocallyConstant X Y) := Function.Injective.nonUnitalNonAssocSemiring DFunLike.coe DFunLike.coe_injective rfl - (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) instance [NonUnitalSemiring Y] : NonUnitalSemiring (LocallyConstant X Y) := Function.Injective.nonUnitalSemiring DFunLike.coe DFunLike.coe_injective rfl - (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) instance [NonAssocSemiring Y] : NonAssocSemiring (LocallyConstant X Y) := Function.Injective.nonAssocSemiring DFunLike.coe DFunLike.coe_injective rfl rfl - (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl /-- The constant-function embedding, as a ring hom. -/ @[simps] @@ -197,43 +200,48 @@ def constRingHom [NonAssocSemiring Y] : Y →+* LocallyConstant X Y := { constMonoidHom, constAddMonoidHom with toFun := const X } instance [Semiring Y] : Semiring (LocallyConstant X Y) := - Function.Injective.semiring DFunLike.coe DFunLike.coe_injective rfl rfl - (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl + Function.Injective.semiring DFunLike.coe DFunLike.coe_injective rfl rfl (fun _ _ => rfl) + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + fun _ => rfl instance [NonUnitalCommSemiring Y] : NonUnitalCommSemiring (LocallyConstant X Y) := Function.Injective.nonUnitalCommSemiring DFunLike.coe DFunLike.coe_injective rfl - (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) instance [CommSemiring Y] : CommSemiring (LocallyConstant X Y) := - Function.Injective.commSemiring DFunLike.coe DFunLike.coe_injective rfl rfl - (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) fun _ => rfl + Function.Injective.commSemiring DFunLike.coe DFunLike.coe_injective rfl rfl (fun _ _ => rfl) + (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + fun _ => rfl instance [NonUnitalNonAssocRing Y] : NonUnitalNonAssocRing (LocallyConstant X Y) := Function.Injective.nonUnitalNonAssocRing DFunLike.coe DFunLike.coe_injective rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) instance [NonUnitalRing Y] : NonUnitalRing (LocallyConstant X Y) := Function.Injective.nonUnitalRing DFunLike.coe DFunLike.coe_injective rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) (fun _ _ => rfl) instance [NonAssocRing Y] : NonAssocRing (LocallyConstant X Y) := Function.Injective.nonAssocRing DFunLike.coe DFunLike.coe_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) instance [Ring Y] : Ring (LocallyConstant X Y) := Function.Injective.ring DFunLike.coe DFunLike.coe_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 _ => rfl instance [NonUnitalCommRing Y] : NonUnitalCommRing (LocallyConstant X Y) := Function.Injective.nonUnitalCommRing DFunLike.coe DFunLike.coe_injective rfl (fun _ _ => rfl) (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) (fun _ _ => rfl) instance [CommRing Y] : CommRing (LocallyConstant X Y) := Function.Injective.commRing DFunLike.coe DFunLike.coe_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 _ => rfl variable {R : Type*} From 2a1442f21dfa14dfe5893b237caea5f58dae2910 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 15:57:00 -0400 Subject: [PATCH 122/127] Limits, work around non-linear smul --- Mathlib/CategoryTheory/Action/Limits.lean | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Action/Limits.lean b/Mathlib/CategoryTheory/Action/Limits.lean index e7292b1df44536..c4b7cd6c123855 100644 --- a/Mathlib/CategoryTheory/Action/Limits.lean +++ b/Mathlib/CategoryTheory/Action/Limits.lean @@ -317,6 +317,10 @@ instance : Sub (X ⟶ Y) where instance : SMul ℕ (X ⟶ Y) where smul n f := ⟨n • f.hom, by simp [f.comm]⟩ +-- because no `Linear ℕ+ V` possible +instance : SMul ℕ+ (X ⟶ Y) where + smul n f := n.val • f + instance : SMul ℤ (X ⟶ Y) where smul n f := ⟨n • f.hom, by simp [f.comm]⟩ @@ -324,12 +328,15 @@ instance : SMul ℤ (X ⟶ Y) where @[simp] lemma neg_hom (f : X ⟶ Y) : (-f).hom = -f.hom := rfl @[simp] lemma sub_hom (f g : X ⟶ Y) : (f - g).hom = f.hom - g.hom := rfl @[simp] lemma nsmul_hom (n : ℕ) (f : X ⟶ Y) : (n • f).hom = n • f.hom := rfl +@[simp] lemma psmul_hom (n : ℕ+) (f : X ⟶ Y) : (n • f).hom = n • f.hom := by + rw [← nsmul_val_eq_psmul] + rfl @[simp] lemma zsmul_hom (n : ℤ) (f : X ⟶ Y) : (n • f).hom = n • f.hom := rfl instance : Preadditive (Action V G) where homGroup X Y := hom_injective.addCommGroup (M₂ := X.V ⟶ Y.V) _ zero_hom add_hom neg_hom sub_hom - (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) + (Function.swap psmul_hom) (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) add_comp := by intros; ext; exact Preadditive.add_comp _ _ _ _ _ _ comp_add := by intros; ext; exact Preadditive.comp_add _ _ _ _ _ _ From 5059a7ac4f042e69b2546c5e2134176291fa33f4 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 16:16:02 -0400 Subject: [PATCH 123/127] better preadditive fix, unlocks homology --- Mathlib/Algebra/Homology/Additive.lean | 10 ++++++++++ Mathlib/CategoryTheory/Action/Limits.lean | 9 +++------ Mathlib/CategoryTheory/Preadditive/Basic.lean | 6 ++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/Mathlib/Algebra/Homology/Additive.lean b/Mathlib/Algebra/Homology/Additive.lean index 86ab7ca1703cef..cb405c9f0a95c3 100644 --- a/Mathlib/Algebra/Homology/Additive.lean +++ b/Mathlib/Algebra/Homology/Additive.lean @@ -45,6 +45,11 @@ instance : Neg (C ⟶ D) := instance : Sub (C ⟶ D) := ⟨fun f g => { f := fun i => f.f i - g.f i }⟩ +instance hasPNatScalar : SMul ℕ+ (C ⟶ D) := + ⟨fun n f => + { f := fun i => n • f.f i + comm' := fun i j _ => by simp [Preadditive.psmul_comp, Preadditive.comp_psmul] }⟩ + instance hasNatScalar : SMul ℕ (C ⟶ D) := ⟨fun n f => { f := fun i => n • f.f i @@ -71,6 +76,10 @@ theorem neg_f_apply (f : C ⟶ D) (i : ι) : (-f).f i = -f.f i := theorem sub_f_apply (f g : C ⟶ D) (i : ι) : (f - g).f i = f.f i - g.f i := rfl +@[simp] +theorem psmul_f_apply (n : ℕ+) (f : C ⟶ D) (i : ι) : (n • f).f i = n • f.f i := + rfl + @[simp] theorem nsmul_f_apply (n : ℕ) (f : C ⟶ D) (i : ι) : (n • f).f i = n • f.f i := rfl @@ -82,6 +91,7 @@ theorem zsmul_f_apply (n : ℤ) (f : C ⟶ D) (i : ι) : (n • f).f i = n • f instance : AddCommGroup (C ⟶ D) := Function.Injective.addCommGroup Hom.f HomologicalComplex.hom_f_injective (by cat_disch) (by cat_disch) (by cat_disch) (by cat_disch) (by cat_disch) (by cat_disch) + (by cat_disch) instance : Preadditive (HomologicalComplex V c) where diff --git a/Mathlib/CategoryTheory/Action/Limits.lean b/Mathlib/CategoryTheory/Action/Limits.lean index c4b7cd6c123855..3029a26368b0d4 100644 --- a/Mathlib/CategoryTheory/Action/Limits.lean +++ b/Mathlib/CategoryTheory/Action/Limits.lean @@ -317,9 +317,8 @@ instance : Sub (X ⟶ Y) where instance : SMul ℕ (X ⟶ Y) where smul n f := ⟨n • f.hom, by simp [f.comm]⟩ --- because no `Linear ℕ+ V` possible instance : SMul ℕ+ (X ⟶ Y) where - smul n f := n.val • f + smul n f := ⟨n • f.hom, by simp [Preadditive.psmul_comp, Preadditive.comp_psmul, f.comm]⟩ instance : SMul ℤ (X ⟶ Y) where smul n f := ⟨n • f.hom, by simp [f.comm]⟩ @@ -328,15 +327,13 @@ instance : SMul ℤ (X ⟶ Y) where @[simp] lemma neg_hom (f : X ⟶ Y) : (-f).hom = -f.hom := rfl @[simp] lemma sub_hom (f g : X ⟶ Y) : (f - g).hom = f.hom - g.hom := rfl @[simp] lemma nsmul_hom (n : ℕ) (f : X ⟶ Y) : (n • f).hom = n • f.hom := rfl -@[simp] lemma psmul_hom (n : ℕ+) (f : X ⟶ Y) : (n • f).hom = n • f.hom := by - rw [← nsmul_val_eq_psmul] - rfl +@[simp] lemma psmul_hom (n : ℕ+) (f : X ⟶ Y) : (n • f).hom = n • f.hom := rfl @[simp] lemma zsmul_hom (n : ℤ) (f : X ⟶ Y) : (n • f).hom = n • f.hom := rfl instance : Preadditive (Action V G) where homGroup X Y := hom_injective.addCommGroup (M₂ := X.V ⟶ Y.V) _ zero_hom add_hom neg_hom sub_hom - (Function.swap psmul_hom) (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) + (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) add_comp := by intros; ext; exact Preadditive.add_comp _ _ _ _ _ _ comp_add := by intros; ext; exact Preadditive.comp_add _ _ _ _ _ _ diff --git a/Mathlib/CategoryTheory/Preadditive/Basic.lean b/Mathlib/CategoryTheory/Preadditive/Basic.lean index 3c7219c2fa171c..590a01a24d28b6 100644 --- a/Mathlib/CategoryTheory/Preadditive/Basic.lean +++ b/Mathlib/CategoryTheory/Preadditive/Basic.lean @@ -164,6 +164,12 @@ theorem comp_neg : f ≫ (-g) = -f ≫ g := @[reassoc] theorem neg_comp_neg : (-f) ≫ (-g) = f ≫ g := by simp +theorem psmul_comp (n : ℕ+) : (n • f) ≫ g = n • f ≫ g := + map_psmul (rightComp P g) n f + +theorem comp_psmul (n : ℕ+) : f ≫ (n • g) = n • f ≫ g := + map_psmul (leftComp R f) n g + theorem nsmul_comp (n : ℕ) : (n • f) ≫ g = n • f ≫ g := map_nsmul (rightComp P g) n f From ba3ec32763efeca164a3fc2e0b7e57f13df8d917 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 16:46:47 -0400 Subject: [PATCH 124/127] convolutoin bialg --- Mathlib/RingTheory/Bialgebra/Convolution.lean | 56 ++++++++++++++++++- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/Mathlib/RingTheory/Bialgebra/Convolution.lean b/Mathlib/RingTheory/Bialgebra/Convolution.lean index 008da3aa3cef4d..02a5b307948cbc 100644 --- a/Mathlib/RingTheory/Bialgebra/Convolution.lean +++ b/Mathlib/RingTheory/Bialgebra/Convolution.lean @@ -43,6 +43,8 @@ instance : One (WithConv <| C →ₐ[R] A) where instance : Mul (WithConv <| C →ₐ[R] A) where mul f g := toConv <| .comp (lmul' R) <| .comp (map f.ofConv g.ofConv) <| comulAlgHom R C +instance : Pow (WithConv <| C →ₐ[R] A) ℕ+ := ⟨fun f n ↦ ppowRec n n.property f⟩ + instance : Pow (WithConv <| C →ₐ[R] A) ℕ := ⟨fun f n ↦ npowRec n f⟩ lemma convOne_def : 1 = toConv ((Algebra.ofId R A).comp (counitAlgHom R C)) := rfl @@ -50,6 +52,11 @@ lemma convOne_def : 1 = toConv ((Algebra.ofId R A).comp (counitAlgHom R C)) := r lemma convMul_def (f g : WithConv <| C →ₐ[R] A) : f * g = toConv (.comp (lmul' R) <| .comp (map f.ofConv g.ofConv) <| comulAlgHom R C) := rfl +private lemma convPPow_succ_mk (f : WithConv <| C →ₐ[R] A) : + ∀ (n : ℕ) (hn : 0 < n), f ^ (PNat.mk (n + 1) Nat.succ_pos') = (f ^ PNat.mk n hn) * f + | 1, _ => rfl + | _ + 2, _ => rfl + private lemma convPow_succ (f : WithConv <| C →ₐ[R] A) (n : ℕ) : f ^ (n + 1) = (f ^ n) * f := rfl @[simp] @@ -70,6 +77,18 @@ lemma toLinearMap_convMul (f g : WithConv <| C →ₐ[R] A) : toConv (f * g).ofConv.toLinearMap = toConv f.ofConv.toLinearMap * toConv g.ofConv.toLinearMap := rfl +@[simp] +lemma toLinearMap_convPPow (f : WithConv <| C →ₐ[R] A) (n : ℕ+) : + toConv (f ^ n).ofConv.toLinearMap = toConv f.ofConv.toLinearMap ^ n := by + rcases n with ⟨_|n, hn⟩ + · contradiction + rw [← show PNat.mk (n + 1) (Nat.succ_pos') = ⟨n + 1, hn⟩ from rfl] + induction n with + | zero => rfl + | succ n IH => + rw [convPPow_succ_mk f _ Nat.succ_pos', toLinearMap_convMul, ppow_mk_add_one (n := n + 1), + IH Nat.succ_pos'] + @[simp] lemma toLinearMap_convPow (f : WithConv <| C →ₐ[R] A) : ∀ n : ℕ, toConv (f ^ n).ofConv.toLinearMap = toConv f.ofConv.toLinearMap ^ n @@ -90,13 +109,13 @@ lemma comp_convMul_distrib [Algebra R B] (h : A →ₐ[R] B) (f g : WithConv <| instance : Monoid (WithConv <| C →ₐ[R] A) := fast_instance% (toConv_injective.comp <| toLinearMap_injective.comp ofConv_injective).monoid _ - toLinearMap_convOne toLinearMap_convMul toLinearMap_convPow + toLinearMap_convOne toLinearMap_convMul toLinearMap_convPPow toLinearMap_convPow variable [IsCocomm R C] instance : CommMonoid (WithConv <| C →ₐ[R] A) := fast_instance% (toConv_injective.comp <| toLinearMap_injective.comp ofConv_injective).commMonoid _ - toLinearMap_convOne toLinearMap_convMul toLinearMap_convPow + toLinearMap_convOne toLinearMap_convMul toLinearMap_convPPow toLinearMap_convPow end AlgHom @@ -122,6 +141,8 @@ variable [IsCocomm R C] instance : Mul (WithConv <| C →ₐc[R] A) where mul f g := toConv <| .comp (mulBialgHom R A) <| .comp (map f.ofConv g.ofConv) <| comulBialgHom R C +instance : Pow (WithConv <| C →ₐc[R] A) ℕ+ := ⟨fun f n ↦ ppowRec n n.property f⟩ + instance : Pow (WithConv <| C →ₐc[R] A) ℕ := ⟨fun f n ↦ npowRec n f⟩ lemma convMul_def (f g : WithConv <| C →ₐc[R] A) : @@ -129,6 +150,11 @@ lemma convMul_def (f g : WithConv <| C →ₐc[R] A) : toConv (.comp (mulBialgHom R A) <| .comp (map f.ofConv g.ofConv) <| comulBialgHom R C) := rfl +private lemma convPPow_succ_mk (f : WithConv <| C →ₐc[R] A) : + ∀ (n : ℕ) (hn : 0 < n), f ^ (PNat.mk (n + 1) Nat.succ_pos') = (f ^ PNat.mk n hn) * f + | 1, _ => rfl + | _ + 2, _ => rfl + private lemma convPow_succ (f : WithConv <| C →ₐc[R] A) (n : ℕ) : f ^ (n + 1) = (f ^ n) * f := rfl -- TODO: Make simp once `SemilinearMapClass.semilinearMap` is not simp nf anymore. @@ -142,6 +168,18 @@ lemma toAlgHom_convMul (f g : WithConv <| C →ₐc[R] A) : toConv (f * g).ofConv.toAlgHom = toConv f.ofConv.toAlgHom * toConv g.ofConv.toAlgHom := rfl +@[simp] +lemma toLinearMap_convPPow (f : WithConv <| C →ₐc[R] A) (n : ℕ+) : + toConv (f ^ n).ofConv.toLinearMap = toConv f.ofConv.toLinearMap ^ n := by + rcases n with ⟨_|n, hn⟩ + · contradiction + rw [← show PNat.mk (n + 1) (Nat.succ_pos') = ⟨n + 1, hn⟩ from rfl] + induction n with + | zero => rfl + | succ n IH => + rw [convPPow_succ_mk f _ Nat.succ_pos', toLinearMap_convMul, ppow_mk_add_one (n := n + 1), + IH Nat.succ_pos'] + -- TODO: Make simp once `SemilinearMapClass.semilinearMap` is not simp nf anymore. -- @[simp] lemma toLinearMap_convPow (f : WithConv <| C →ₐc[R] A) : @@ -149,6 +187,18 @@ lemma toLinearMap_convPow (f : WithConv <| C →ₐc[R] A) : | 0 => rfl | n + 1 => by simp only [convPow_succ, pow_succ, toLinearMap_convMul, toLinearMap_convPow] +@[simp] +lemma toAlgHom_convPPow (f : WithConv <| C →ₐc[R] A) (n : ℕ+) : + toConv (f ^ n).ofConv.toAlgHom = toConv f.ofConv.toAlgHom ^ n := by + rcases n with ⟨_|n, hn⟩ + · contradiction + rw [← show PNat.mk (n + 1) (Nat.succ_pos') = ⟨n + 1, hn⟩ from rfl] + induction n with + | zero => rfl + | succ n IH => + rw [convPPow_succ_mk f _ Nat.succ_pos', toAlgHom_convMul, ppow_mk_add_one (n := n + 1), + IH Nat.succ_pos'] + @[simp] lemma toAlgHom_convPow (f : WithConv <| C →ₐc[R] A) : ∀ n, toConv (f ^ n).ofConv.toAlgHom = toConv f.ofConv.toAlgHom ^ n @@ -157,6 +207,6 @@ lemma toAlgHom_convPow (f : WithConv <| C →ₐc[R] A) : instance : CommMonoid (WithConv <| C →ₐc[R] A) := fast_instance% (toConv_injective.comp <| coe_linearMap_injective.comp ofConv_injective).commMonoid _ - toLinearMap_convOne toLinearMap_convMul toLinearMap_convPow + toLinearMap_convOne toLinearMap_convMul toLinearMap_convPPow toLinearMap_convPow end BialgHom From 94fd6569794782446834a929336bd3d5d4b8d164 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 19:24:18 -0400 Subject: [PATCH 125/127] fix Perm instance which fixes diamond for AddConstEquiv --- Mathlib/Algebra/AddConstMap/Equiv.lean | 5 ++++- Mathlib/Algebra/Group/End.lean | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Mathlib/Algebra/AddConstMap/Equiv.lean b/Mathlib/Algebra/AddConstMap/Equiv.lean index cb710dcb956f05..c1d23bf3179e46 100644 --- a/Mathlib/Algebra/AddConstMap/Equiv.lean +++ b/Mathlib/Algebra/AddConstMap/Equiv.lean @@ -116,6 +116,9 @@ instance instMul : Mul (G ≃+c[a, a] G) := ⟨fun f g ↦ g.trans f⟩ instance instInv : Inv (G ≃+c[a, a] G) := ⟨.symm⟩ instance instDiv : Div (G ≃+c[a, a] G) := ⟨fun f g ↦ f * g⁻¹⟩ +instance instPowPNat : Pow (G ≃+c[a, a] G) ℕ+ where + pow e n := ⟨e^n, (e.toAddConstMap^n).map_add_const'⟩ + instance instPowNat : Pow (G ≃+c[a, a] G) ℕ where pow e n := ⟨e^n, (e.toAddConstMap^n).map_add_const'⟩ @@ -127,7 +130,7 @@ instance instPowInt : Pow (G ≃+c[a, a] G) ℤ where instance instGroup : Group (G ≃+c[a, a] G) := toEquiv_injective.group _ rfl (fun _ _ ↦ rfl) (fun _ ↦ rfl) (fun _ _ ↦ rfl) (fun _ _ ↦ rfl) - fun _ _ ↦ rfl + (fun _ _ ↦ rfl) fun _ _ ↦ rfl /-- Projection from `G ≃+c[a, a] G` to permutations `G ≃ G`, as a monoid homomorphism. -/ @[simps! apply] diff --git a/Mathlib/Algebra/Group/End.lean b/Mathlib/Algebra/Group/End.lean index d4617d793c5f70..dd23572e33577a 100644 --- a/Mathlib/Algebra/Group/End.lean +++ b/Mathlib/Algebra/Group/End.lean @@ -78,6 +78,8 @@ instance permGroup : Group (Perm α) where one_mul := trans_refl mul_one := refl_trans inv_mul_cancel := self_trans_symm + ppow n hn f := f ^ n + ppow_succ _ _ := coe_fn_injective <| Function.iterate_succ _ _ npow n f := f ^ n npow_succ _ _ := coe_fn_injective <| Function.iterate_succ _ _ zpow := zpowRec fun n f ↦ f ^ n From 78d8b36155216cef46500de4efca2a3474a22eb1 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 19:28:52 -0400 Subject: [PATCH 126/127] avoid diamond --- Mathlib/Algebra/Star/NonUnitalSubalgebra.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean b/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean index 4ff88552ac4834..9253ca37d5d0d3 100644 --- a/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean +++ b/Mathlib/Algebra/Star/NonUnitalSubalgebra.lean @@ -1159,8 +1159,8 @@ theorem center_eq_top (A : Type*) [StarRing R] [NonUnitalCommSemiring A] [StarRi variable {R A} -instance instNonUnitalCommSemiring : NonUnitalCommSemiring (center R A) := - fast_instance% NonUnitalSubalgebra.center.instNonUnitalCommSemiring +instance instNonUnitalCommSemiring : NonUnitalCommSemiring (center R A) where + mul_comm := Subsemigroup.center.commSemigroup.mul_comm instance instNonUnitalCommRing {A : Type*} [NonUnitalRing A] [StarRing A] [Module R A] [IsScalarTower R A A] [SMulCommClass R A A] : NonUnitalCommRing (center R A) := From b0d5f86b4f6d469222c78990151d171fb243e802 Mon Sep 17 00:00:00 2001 From: Yakov Pechersky Date: Fri, 26 Jun 2026 19:52:25 -0400 Subject: [PATCH 127/127] ModuleCat --- Mathlib/Algebra/Category/ModuleCat/Basic.lean | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Mathlib/Algebra/Category/ModuleCat/Basic.lean b/Mathlib/Algebra/Category/ModuleCat/Basic.lean index 4c29f9d53dd76d..c7ec5d5e316504 100644 --- a/Mathlib/Algebra/Category/ModuleCat/Basic.lean +++ b/Mathlib/Algebra/Category/ModuleCat/Basic.lean @@ -326,6 +326,13 @@ instance : Zero (M ⟶ N) where @[simp] lemma hom_zero : (0 : M ⟶ N).hom = 0 := rfl +set_option backward.privateInPublic true in +set_option backward.privateInPublic.warn false in +instance : SMul ℕ+ (M ⟶ N) where + smul n f := ⟨n • f.hom⟩ + +@[simp] lemma hom_psmul (n : ℕ+) (f : M ⟶ N) : (n • f).hom = n • f.hom := rfl + set_option backward.privateInPublic true in set_option backward.privateInPublic.warn false in instance : SMul ℕ (M ⟶ N) where @@ -357,6 +364,7 @@ instance : SMul ℤ (M ⟶ N) where instance : AddCommGroup (M ⟶ N) := Function.Injective.addCommGroup (Hom.hom) hom_injective rfl (fun _ _ => rfl) (fun _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) (fun _ _ => rfl) + (fun _ _ => rfl) @[simp] lemma hom_sum {ι : Type*} (f : ι → (M ⟶ N)) (s : Finset ι) : (∑ i ∈ s, f i).hom = ∑ i ∈ s, (f i).hom :=