diff --git a/Mathlib.lean b/Mathlib.lean index 73d920207c69ad..f6e5f3ea3c021c 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -427,6 +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.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/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/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/Algebra/NonUnitalSubalgebra.lean b/Mathlib/Algebra/Algebra/NonUnitalSubalgebra.lean index 49483234759347..3f64373733e6c5 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 (priority := 75) center.instNonUnitalCommSemiring : + NonUnitalCommSemiring (center R A) where + mul_assoc := Subsemigroup.center.commSemigroup.mul_assoc + mul_comm := Subsemigroup.center.commSemigroup.mul_comm instance center.instNonUnitalCommRing {A : Type*} [NonUnitalNonAssocRing A] [Module R A] [IsScalarTower R A A] [SMulCommClass R A A] : NonUnitalCommRing (center R A) := @@ -1121,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/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/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 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 := 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 := 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 diff --git a/Mathlib/Algebra/Field/Basic.lean b/Mathlib/Algebra/Field/Basic.lean index f903c5e449f4b3..d3f23d5551fa38 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 : ∀ (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 - 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 : ∀ (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) (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 : ∀ (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 - 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 : ∀ (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) (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 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 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 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 diff --git a/Mathlib/Algebra/Group/Defs.lean b/Mathlib/Algebra/Group/Defs.lean index 8da0e62370f626..d23cd53b89d58e 100644 --- a/Mathlib/Algebra/Group/Defs.lean +++ b/Mathlib/Algebra/Group/Defs.lean @@ -171,17 +171,53 @@ 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 {M : Type*} [Mul M] : ∀ n : ℕ, 0 < n → M → M + | 0, h, _ => (Nat.ne_of_lt h rfl).elim + | 1, _, a => 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 => psmulRec (n + 1) n.succ_pos a + 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 -/ 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 : ∀ 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 `(+)`. -/ -@[ext] 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 : ∀ 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 @@ -193,6 +229,14 @@ 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' (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 section IsCommutative @@ -243,11 +287,9 @@ 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 /-- A commutative additive semigroup is a type with an associative commutative `(+)`. -/ -@[ext] class AddCommSemigroup (G : Type u) extends AddSemigroup G, AddCommMagma G where attribute [to_additive] CommSemigroup diff --git a/Mathlib/Algebra/Group/End.lean b/Mathlib/Algebra/Group/End.lean index 9c3dabedf1513b..dd23572e33577a 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 _ _ @@ -76,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 diff --git a/Mathlib/Algebra/Group/Ext.lean b/Mathlib/Algebra/Group/Ext.lean index 3874fa32780c75..a485b8b474b088 100644 --- a/Mathlib/Algebra/Group/Ext.lean +++ b/Mathlib/Algebra/Group/Ext.lean @@ -35,19 +35,50 @@ open Function universe u +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 + have : m₁.ppow = m₂.ppow := by + ext n hn x + 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 + +@[to_additive] +theorem CommSemigroup.toSemigroup_injective {M : Type u} : + 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 + @[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)) : 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₁.one = m₂.one := congr_arg (·.one) (this) + have h₂ : m₁.toSemigroup = m₂.toSemigroup := Semigroup.ext h_mul 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 ext n x exact @MonoidHom.map_pow M M m₁ m₂ f x n - rcases m₁ with @⟨@⟨⟨_⟩⟩, ⟨_⟩⟩ + rcases m₁ with @⟨_, ⟨_⟩⟩ + rcases m₂ with @⟨_, ⟨_⟩⟩ congr @[to_additive] 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 diff --git a/Mathlib/Algebra/Group/Hom/Defs.lean b/Mathlib/Algebra/Group/Hom/Defs.lean index ab1fcb1515dab3..4317b727dcdc33 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,19 @@ 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 (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 + · 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/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/InjSurj.lean b/Mathlib/Algebra/Group/InjSurj.lean index e843f06764b73c..b6288cb6690aa2 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,14 @@ 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 + 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. -/ @@ -66,9 +71,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 +106,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 +135,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 +144,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 +158,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 +169,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 +179,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 +190,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 +201,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] -/ @@ -220,9 +236,10 @@ a `SubNegMonoid`. This version takes custom `nsmul` and `zsmul` as `[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)⁻¹) - (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 + (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], zpow_succ' := fun n x => hf <| by rw [zpow, mul, zpow_natCast, pow_succ, zpow, zpow_natCast], @@ -239,9 +256,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)⁻¹) - (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 } + (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 that preserves `1`, `*`, `⁻¹`, and `/` to a `DivisionMonoid`. See note [reducible non-instances] -/ @@ -252,9 +270,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)⁻¹) - (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 + (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])] } @@ -269,9 +288,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)⁻¹) - (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 } + (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]. -/ @@ -280,9 +300,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)⁻¹) - (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 + (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 div ppow npow zpow with inv_mul_cancel := fun x => hf <| by rw [mul, inv, inv_mul_cancel, one] } @@ -293,9 +314,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)⁻¹) - (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 } + (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 @@ -313,9 +335,14 @@ 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 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 `*` from a commutative semigroup. See note [reducible non-instances]. -/ @@ -331,9 +358,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₂] @@ -348,7 +376,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]. -/ @@ -357,8 +385,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 @@ -371,9 +400,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] -/ @@ -394,16 +424,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]. -/ @@ -412,9 +444,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 @@ -425,9 +458,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/Opposite.lean b/Mathlib/Algebra/Group/Opposite.lean index 68a9347be830d8..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 @@ -28,40 +29,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 `αᵐᵒᵖ` @@ -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 α] @@ -249,20 +262,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 +272,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 αᵐᵒᵖ := diff --git a/Mathlib/Algebra/Group/PNatPowAssoc.lean b/Mathlib/Algebra/Group/PNatPowAssoc.lean index 116cc74e8c76df..4c66f7e96bf5e4 100644 --- a/Mathlib/Algebra/Group/PNatPowAssoc.lean +++ b/Mathlib/Algebra/Group/PNatPowAssoc.lean @@ -46,20 +46,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 @@ -81,16 +83,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 diff --git a/Mathlib/Algebra/Group/PPow/Basic.lean b/Mathlib/Algebra/Group/PPow/Basic.lean new file mode 100644 index 00000000000000..dcdb1aecda1fc6 --- /dev/null +++ b/Mathlib/Algebra/Group/PPow/Basic.lean @@ -0,0 +1,87 @@ +/- +Copyright (c) 2024 Jireh Loreaux. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jireh Loreaux +-/ +module + +public import Mathlib.Algebra.Group.PPow.Defs +public import Mathlib.Data.PNat.Basic + +/-! +# TODO : Fill in module docstring +-/ + +public section + +variable {M : Type*} + +section Semigroup + +variable [Semigroup M] + +@[to_additive (reorder := x n) succ_psmul'] +lemma ppow_succ' (x : M) (n : ℕ+) : x ^ (n + 1) = x * x ^ n := + n.recOn (Semigroup.ppow_succ' 0 x) fun k _ => Semigroup.ppow_succ' k x + +@[to_additive (reorder := x n) succ_psmul] +lemma ppow_succ (x : M) (n : ℕ+) : x ^ (n + 1) = x ^ n * x := + n.recOn (Semigroup.ppow_succ 0 x) fun k _ => Semigroup.ppow_succ k x + +@[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 (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 (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 (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] + +@[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] + +/-- `(· ^ (n : ℕ+))` as a `MulHom`. -/ +@[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] +theorem pow_mul_comm'' [Monoid M] (a : M) (n : ℕ+) : a ^ n * a = a * a ^ n := by + exact ppow_mul_comm' a n diff --git a/Mathlib/Algebra/Group/PPow/Defs.lean b/Mathlib/Algebra/Group/PPow/Defs.lean new file mode 100644 index 00000000000000..67e43a6844385a --- /dev/null +++ b/Mathlib/Algebra/Group/PPow/Defs.lean @@ -0,0 +1,115 @@ +/- +Copyright (c) 2024 Jireh Loreaux. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Jireh Loreaux +-/ +module + +public import Mathlib.Algebra.Group.Defs +public 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 `ℕ`. +-/ + +public section + +open PNat + +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 + +@[to_additive (attr := simp)] +lemma Semigroup.ppow_eq_pow [Semigroup M] (x : M) (n : ℕ+) : + Semigroup.ppow n n.property x = x ^ n := + rfl + +@[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 _ + +@[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 ^ 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⟩ + 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 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 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 + · 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 + 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 : ℕ+) : + (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 + 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_assoc _ _ x, mul_comm _ x, + ← mul_assoc, ← mul_assoc] + +end CommSemigroup 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 diff --git a/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean b/Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean index d2652c3e4c35e3..a471e65118c405 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,21 @@ 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 _ _ 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) /-- `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 +743,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 +827,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 +953,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 +978,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 +1033,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 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] diff --git a/Mathlib/Algebra/Group/Subgroup/Defs.lean b/Mathlib/Algebra/Group/Subgroup/Defs.lean index 81e5bb70d1a79d..8b209a2a75b1c0 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) @@ -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/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`. -/] diff --git a/Mathlib/Algebra/Group/Subsemigroup/Defs.lean b/Mathlib/Algebra/Group/Subsemigroup/Defs.lean index d36ce7b502a23a..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] @@ -281,18 +288,41 @@ 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] + 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. -/ +@[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 _ _⟩⟩ + +@[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. -/] 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/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 _ diff --git a/Mathlib/Algebra/Group/TypeTags/Basic.lean b/Mathlib/Algebra/Group/TypeTags/Basic.lean index 07c87018aaf344..be51e2ca06ff0a 100644 --- a/Mathlib/Algebra/Group/TypeTags/Basic.lean +++ b/Mathlib/Algebra/Group/TypeTags/Basic.lean @@ -168,11 +168,19 @@ theorem ofMul_mul [Mul α] (x y : α) : ofMul (x * y) = ofMul x + ofMul y := rfl @[simp] theorem toMul_add [Mul α] (x y : Additive α) : (x + y).toMul = x.toMul * y.toMul := rfl -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/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 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/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/Algebra/GroupWithZero/InjSurj.lean b/Mathlib/Algebra/GroupWithZero/InjSurj.lean index f4dcc90064bab7..ed799ee1cabd46 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,34 @@ 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) : - MonoidWithZero M₀' := - { hf.monoid f one mul npow, hf.mulZeroClass f zero mul with } + [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 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) : - MonoidWithZero M₀' := - { hf.monoid f one mul npow, hf.mulZeroClass f zero mul with } + [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 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) : - CommMonoidWithZero M₀' := - { hf.commMonoid f one mul npow, hf.mulZeroClass f zero mul with } + [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 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) : - CommMonoidWithZero M₀' := - { hf.commMonoid f one mul npow, hf.mulZeroClass f zero mul with } + [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 ppow npow, hf.mulZeroClass f zero mul with } end MonoidWithZero @@ -159,12 +161,13 @@ 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) - (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) - (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, + [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) (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 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 @@ -173,12 +176,13 @@ 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) - (zero : f 0 = 0) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) + [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) - (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 + (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], 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 +197,23 @@ 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) - (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 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) (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) - (zero : f 0 = 0) (one : f 1 = 1) (mul : ∀ x y, f (x * y) = f x * f y) + [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) - (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 } + (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 } end CommGroupWithZero 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 _ 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 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/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] 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 9daa84aa1c71eb..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 .. @@ -57,6 +62,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 @@ -146,6 +155,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/Algebra/Order/CauSeq/Basic.lean b/Mathlib/Algebra/Order/CauSeq/Basic.lean index c3f8165c29f6db..12b09b570334a8 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,31 @@ 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 + +@[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 _ _) 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 @@ -504,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 diff --git a/Mathlib/Algebra/Order/GroupWithZero/Basic.lean b/Mathlib/Algebra/Order/GroupWithZero/Basic.lean index 9810e9a39dfd9d..4c0e1ec30fb472 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 @@ -24,6 +25,7 @@ lemmas that do not immediately follow from the typeclass specifications. -/ public section +set_option linter.style.longFile 1600 -- FIXME open Function @@ -365,6 +367,17 @@ 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₀] (ha : 0 ≤ a) (n : ℕ+) : 0 ≤ a ^ n := by + induction n using Semigroup.ppow_induction a + · exact ha + · exact mul_nonneg ‹_› ha + +end SemigroupWithZero + section MonoidWithZero variable [MonoidWithZero M₀] @@ -390,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 @@ -399,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) @@ -433,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 @@ -555,6 +585,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, PNat.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 +614,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 +648,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₀} 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 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/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] 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 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 diff --git a/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean b/Mathlib/Algebra/Order/Monoid/Unbundled/Pow.lean index a4dcd4ab0cb008..6202cd6df43ec9 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,21 @@ 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 + 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 + 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 | 0 => by simp @@ -50,6 +66,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 @@ -156,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 diff --git a/Mathlib/Algebra/Order/Nonneg/Basic.lean b/Mathlib/Algebra/Order/Nonneg/Basic.lean index f7915045096ce2..bad6bcf208b955 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 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 diff --git a/Mathlib/Algebra/Order/Positive/Ring.lean b/Mathlib/Algebra/Order/Positive/Ring.lean index a445ed2d6e8bc0..deb979335d0e1c 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, PNat.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 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 := 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] 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 diff --git a/Mathlib/Algebra/Ring/Ext.lean b/Mathlib/Algebra/Ring/Ext.lean index b024fdbee9ac42..7620a33e7a9b9b 100644 --- a/Mathlib/Algebra/Ring/Ext.lean +++ b/Mathlib/Algebra/Ring/Ext.lean @@ -7,6 +7,7 @@ module public import Mathlib.Algebra.Ring.Defs public import Mathlib.Algebra.Group.Ext +public import Mathlib.Tactic.CongrM /-! # Extensionality lemmas for rings and similar structures @@ -81,7 +82,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₂]) @@ -190,6 +196,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 diff --git a/Mathlib/Algebra/Ring/InjSurj.lean b/Mathlib/Algebra/Ring/InjSurj.lean index 139aab361e5d9a..b27b2f981beb2a 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 : ∀ (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 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]) } @@ -79,24 +80,26 @@ 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 : ∀ (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 nsmul natCast - __ := hf.addCommMonoid _ zero add (swap nsmul) + __ := hf.addMonoidWithOne f zero one add psmul nsmul natCast + __ := 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 [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) - (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 + (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]), intCast_negSucc := fun n => hf (by rw [intCast, neg, natCast, Int.cast_negSucc]) } @@ -104,177 +107,190 @@ 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) - (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 } + (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) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : NonUnitalNonAssocSemiring S where - toAddCommMonoid := hf.addCommMonoid f zero add (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) (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 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) - (natCast : ∀ n : ℕ, f n = n) : NonAssocSemiring S where - toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul nsmul + (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 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 : ∀ (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 nsmul - __ := hf.nonAssocSemiring f zero one add mul nsmul natCast - __ := hf.monoidWithZero f zero one mul npow + 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 /-- 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) - (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 + (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) + __ := 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) : + (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 sub nsmul zsmul - __ := hf.nonUnitalSemiring f zero add mul nsmul + 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. -/ -- 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) (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 + (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 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) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) (zsmul : ∀ (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 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 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) (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 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) (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 nsmul - __ := hf.commSemigroup f mul + 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) (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) (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) - (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 + (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 /-- 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) - (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 + (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 sub psmul 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) - (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 + (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) - (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 sub nsmul zsmul natCast intCast - __ := hf.nonUnitalNonAssocCommRing f zero add mul neg 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) (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) + (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 nsmul zsmul npow natCast intCast - __ := hf.commMonoid f one mul npow + 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 @@ -301,8 +317,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 +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) (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (natCast : ∀ n : ℕ, f n = n) : AddMonoidWithOne S := - { hf.addMonoid f zero add (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] } @@ -329,21 +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) (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) + (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 (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) - (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 + (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 (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 @@ -354,18 +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) - (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 } + (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) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : NonUnitalNonAssocSemiring S where - toAddCommMonoid := hf.addCommMonoid f zero add (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 @@ -373,147 +392,158 @@ 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) : NonUnitalSemiring S where - toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul nsmul - __ := hf.semigroupWithZero f zero mul + (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 /-- 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) - (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 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) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) - (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 + (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 /-- 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) : + (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 nsmul) (swap zsmul) - __ := hf.nonUnitalNonAssocSemiring f zero add mul nsmul + 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) (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) : + (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 sub nsmul zsmul - __ := hf.nonUnitalSemiring f zero add mul 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) (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 + (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 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) (sub : ∀ 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) - (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) + (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 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) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : NonUnitalNonAssocCommSemiring S where - toNonUnitalNonAssocSemiring := hf.nonUnitalNonAssocSemiring f zero add mul nsmul + (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 /-- 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) - (nsmul : ∀ (n : ℕ) (x), f (n • x) = n • f x) : NonUnitalCommSemiring S where - toNonUnitalSemiring := hf.nonUnitalSemiring f zero add mul nsmul - __ := hf.commSemigroup f mul + (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) - (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 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 : ∀ (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 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) - (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 sub nsmul zsmul - __ := hf.nonUnitalNonAssocCommSemiring f zero add mul nsmul + 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) (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) : + (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 nsmul zsmul - __ := hf.nonUnitalNonAssocCommRing f zero add mul neg 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) (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 + (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) (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) - (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 + (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 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 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 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. -/ 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 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 _ 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 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/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) := 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 diff --git a/Mathlib/CategoryTheory/Action/Limits.lean b/Mathlib/CategoryTheory/Action/Limits.lean index e7292b1df44536..3029a26368b0d4 100644 --- a/Mathlib/CategoryTheory/Action/Limits.lean +++ b/Mathlib/CategoryTheory/Action/Limits.lean @@ -317,6 +317,9 @@ instance : Sub (X ⟶ Y) where instance : SMul ℕ (X ⟶ Y) where smul n f := ⟨n • f.hom, by simp [f.comm]⟩ +instance : SMul ℕ+ (X ⟶ Y) where + 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]⟩ @@ -324,12 +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 := 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) + (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 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 𝕜] 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] diff --git a/Mathlib/Data/DFinsupp/Defs.lean b/Mathlib/Data/DFinsupp/Defs.lean index feccf9203b85e9..240fc1caa29e44 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⟩ @@ -268,11 +282,11 @@ theorem coe_zsmul [∀ i, AddGroup (β i)] (b : ℤ) (v : Π₀ i, β i) : ⇑(b 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 _ _ + (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 coe_sub - (fun _ _ => coe_nsmul _ _) fun _ _ => coe_zsmul _ _ + (fun _ _ => coe_psmul _ _) (fun _ _ => coe_nsmul _ _) fun _ _ => coe_zsmul _ _ end Algebra 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 := 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 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 α] 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 diff --git a/Mathlib/Data/Num/Lemmas.lean b/Mathlib/Data/Num/Lemmas.lean index 9a921aa540033f..19651eccb5a47c 100644 --- a/Mathlib/Data/Num/Lemmas.lean +++ b/Mathlib/Data/Num/Lemmas.lean @@ -109,6 +109,19 @@ theorem mul_to_nat (m) : ∀ n, ((m * n : PosNum) : ℕ) = m * n (add_to_nat (bit0 (m * p)) m).trans <| show (↑(m * p) + ↑(m * p) + ↑m : ℕ) = ↑m * (p + p) + m by rw [mul_to_nat m p, left_distrib] +@[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 => Nat.zero_lt_one | bit0 p => @@ -359,6 +372,7 @@ instance commSemiring : CommSemiring Num where __ := Num.addMonoid __ := Num.addMonoidWithOne npow := @npowRec Num ⟨1⟩ ⟨(· * ·)⟩ + ppow := @ppowRec Num ⟨(· * ·)⟩ mul_zero _ := by rw [← to_nat_inj, mul_to_nat, cast_zero, mul_zero] zero_mul _ := by rw [← to_nat_inj, mul_to_nat, cast_zero, zero_mul] mul_one _ := by rw [← to_nat_inj, mul_to_nat, cast_one, mul_one] @@ -510,7 +524,7 @@ example (n : PosNum) (m : PosNum) : n ≤ n + m := by ``` -/ 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])) /-- @@ -526,9 +540,11 @@ scoped macro (name := transfer) "transfer" : tactic => `(tactic| instance addCommSemigroup : AddCommSemigroup PosNum where add_assoc := by transfer add_comm := by transfer + psmul := @psmulRec PosNum ⟨(· + ·)⟩ instance commMonoid : CommMonoid PosNum where npow := @npowRec PosNum ⟨1⟩ ⟨(· * ·)⟩ + ppow := @ppowRec PosNum ⟨(· * ·)⟩ mul_assoc := by transfer one_mul := by transfer mul_one := by transfer diff --git a/Mathlib/Data/PNat/Basic.lean b/Mathlib/Data/PNat/Basic.lean index 285715236d27af..de6940d01896dd 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 := @@ -320,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/Defs.lean b/Mathlib/Data/PNat/Defs.lean index 356d1193020665..e187a2bf4a5d5f 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 @@ -143,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 @@ -224,6 +209,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 diff --git a/Mathlib/Data/PNat/Notation.lean b/Mathlib/Data/PNat/Notation.lean index 430c87fddb35f6..19d77ead280c20 100644 --- a/Mathlib/Data/PNat/Notation.lean +++ b/Mathlib/Data/PNat/Notation.lean @@ -14,17 +14,52 @@ 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] 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⟩ 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⟩⟩ + +namespace PNat + +@[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 + +end PNat diff --git a/Mathlib/Data/Rat/Defs.lean b/Mathlib/Data/Rat/Defs.lean index 1b3f964e3a1f79..aaa6980f7cc5f9 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 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 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 diff --git a/Mathlib/Data/Real/Basic.lean b/Mathlib/Data/Real/Basic.lean index e632e98c8667f5..b90ff642f2a8dd 100644 --- a/Mathlib/Data/Real/Basic.lean +++ b/Mathlib/Data/Real/Basic.lean @@ -188,6 +188,8 @@ instance commRing : CommRing ℝ where natCast n := ⟨n⟩ intCast z := ⟨z⟩ npow := @npowRec ℝ ⟨1⟩ ⟨(· * ·)⟩ + ppow := @ppowRec ℝ ⟨(· * ·)⟩ + psmul := @psmulRec ℝ ⟨(· + ·)⟩ nsmul := @nsmulRec ℝ ⟨0⟩ ⟨(· + ·)⟩ zsmul := @zsmulRec ℝ ⟨0⟩ ⟨(· + ·)⟩ ⟨@Neg.neg ℝ _⟩ (@nsmulRec ℝ ⟨0⟩ ⟨(· + ·)⟩) add_zero a := by apply ext_cauchy; simp [cauchy_add, cauchy_zero] 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 diff --git a/Mathlib/Data/ZMod/Defs.lean b/Mathlib/Data/ZMod/Defs.lean index e1b9832a88d149..49613531dff1d2 100644 --- a/Mathlib/Data/ZMod/Defs.lean +++ b/Mathlib/Data/ZMod/Defs.lean @@ -205,8 +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 - ((inferInstance : CommRing ℤ)).nsmul_succ - fun n => ((inferInstance : CommRing (Fin n.succ))).nsmul_succ + (inferInstance : CommRing ℤ).nsmul_succ + fun n => (inferInstance : CommRing (Fin n.succ)).nsmul_succ + psmul := Nat.casesOn n + (inferInstance : CommRing ℤ).psmul fun n => (inferInstance : CommRing (Fin n.succ)).psmul + psmul_one := Nat.casesOn n + (inferInstance : CommRing ℤ).psmul_one + fun n => (inferInstance: CommRing (Fin n.succ)).psmul_one + psmul_succ := Nat.casesOn n + (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) _ @@ -233,8 +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 - ((inferInstance : CommRing ℤ)).npow_succ - fun n => ((inferInstance : CommRing (Fin n.succ))).npow_succ + (inferInstance : CommRing ℤ).npow_succ + fun n => (inferInstance : CommRing (Fin n.succ)).npow_succ + ppow := Nat.casesOn n + (inferInstance : CommRing ℤ).ppow fun n => (inferInstance : CommRing (Fin n.succ)).ppow + ppow_one := Nat.casesOn n + (inferInstance : CommRing ℤ).ppow_one + fun n => (inferInstance : CommRing (Fin n.succ)).ppow_one + ppow_succ := Nat.casesOn n + (inferInstance : CommRing ℤ).ppow_succ + fun n => (inferInstance : CommRing (Fin n.succ)).ppow_succ instance inhabited (n : ℕ) : Inhabited (ZMod n) := ⟨0⟩ diff --git a/Mathlib/GroupTheory/Congruence/Defs.lean b/Mathlib/GroupTheory/Congruence/Defs.lean index b47a3672e90a92..a842619086a1ed 100644 --- a/Mathlib/GroupTheory/Congruence/Defs.lean +++ b/Mathlib/GroupTheory/Congruence/Defs.lean @@ -9,6 +9,7 @@ public import Mathlib.Algebra.Group.InjSurj 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 /-! @@ -564,6 +565,20 @@ 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 using Semigroup.ppow_induction w generalizing x with + | h1 => simp [h] + | hsucc n IH => + rw [ppow_mk_add_one x] + exact c.mul (IH h) 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 +594,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 +606,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 +692,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 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 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`. -/ diff --git a/Mathlib/LinearAlgebra/LinearPMap.lean b/Mathlib/LinearAlgebra/LinearPMap.lean index 236586e4664d36..b04285522255d7 100644 --- a/Mathlib/LinearAlgebra/LinearPMap.lean +++ b/Mathlib/LinearAlgebra/LinearPMap.lean @@ -431,11 +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 →ₛₗ.[σ] F) := - ⟨fun f g h => by +instance instAddSemigroup : AddSemigroup (E →ₛₗ.[σ] F) where + add_assoc := fun f g h => by ext x y hxy · simp only [add_domain, inf_assoc] - · simp only [add_apply, add_assoc]⟩ + · simp only [add_apply, add_assoc] instance instAddZeroClass : AddZeroClass (E →ₛₗ.[σ] F) where zero_add := fun f => by diff --git a/Mathlib/NumberTheory/Dioph.lean b/Mathlib/NumberTheory/Dioph.lean index 585cda8b56ae2d..a02f896040848a 100644 --- a/Mathlib/NumberTheory/Dioph.lean +++ b/Mathlib/NumberTheory/Dioph.lean @@ -169,6 +169,11 @@ theorem mul_apply (f g : Poly α) (x : α → ℕ) : (f * g) x = f x * g x := rf instance (α : Type*) : Inhabited (Poly α) := ⟨0⟩ instance : AddCommGroup (Poly α) where + add := ((· + ·) : Poly α → Poly α → Poly α) + neg := (Neg.neg : Poly α → Poly α) + sub := Sub.sub + zero := 0 + psmul := @psmulRec _ ⟨(· + ·)⟩ nsmul := @nsmulRec _ ⟨(0 : Poly α)⟩ ⟨(· + ·)⟩ zsmul := @zsmulRec _ ⟨(0 : Poly α)⟩ ⟨(· + ·)⟩ ⟨Neg.neg⟩ (@nsmulRec _ ⟨(0 : Poly α)⟩ ⟨(· + ·)⟩) add_zero _ := by ext; simp_rw [add_apply, zero_apply, add_zero] @@ -185,6 +190,7 @@ instance : CommRing (Poly α) where __ := (inferInstance : AddCommGroup (Poly α)) __ := (inferInstance : AddGroupWithOne (Poly α)) npow := @npowRec _ ⟨(1 : Poly α)⟩ ⟨(· * ·)⟩ + ppow := @ppowRec _ ⟨(· * ·)⟩ mul_zero _ := by ext; rw [mul_apply, zero_apply, mul_zero] zero_mul _ := by ext; rw [mul_apply, zero_apply, zero_mul] mul_one _ := by ext; rw [mul_apply, one_apply, mul_one] 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 } 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 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 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 := diff --git a/Mathlib/RingTheory/NonUnitalSubring/Basic.lean b/Mathlib/RingTheory/NonUnitalSubring/Basic.lean index 2032ab1081b90b..24c9764087d076 100644 --- a/Mathlib/RingTheory/NonUnitalSubring/Basic.lean +++ b/Mathlib/RingTheory/NonUnitalSubring/Basic.lean @@ -356,10 +356,9 @@ theorem center_toNonUnitalSubsemiring : rfl /-- 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)) +instance (priority := 75) center.instNonUnitalCommRing : NonUnitalCommRing (center R) where + mul_assoc := Subsemigroup.center.commSemigroup.mul_assoc + mul_comm := Subsemigroup.center.commSemigroup.mul_comm variable {R} @@ -377,9 +376,15 @@ 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 = - NonUnitalSubringClass.toNonUnitalRing (center R) := by +example : ((inferInstance : NonUnitalCommRing (center R)).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 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 := diff --git a/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean b/Mathlib/RingTheory/NonUnitalSubsemiring/Basic.lean index 188f76c8320d9d..169acfdcea9591 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 @@ -237,9 +237,10 @@ theorem center_toSubsemigroup : rfl /-- The center is commutative and associative. -/ -instance center.instNonUnitalCommSemiring : NonUnitalCommSemiring (center R) := - { Subsemigroup.center.commSemigroup, - NonUnitalSubsemiringClass.toNonUnitalNonAssocSemiring (center R) with } +instance (priority := 75) 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,19 @@ end NonUnitalNonAssocSemiring section NonUnitalSemiring -set_option backward.isDefEq.respectTransparency false in +variable {R : Type*} [NonUnitalSemiring R] + +/-- 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 = - NonUnitalSubsemiringClass.toNonUnitalSemiring (center R) := by + ((inferInstance : NonUnitalCommSemiring (center R)).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 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. -/ 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] diff --git a/Mathlib/Tactic/Translate/ToAdditive.lean b/Mathlib/Tactic/Translate/ToAdditive.lean index 0ce40eceb1fac7..49937d4bc3d833 100644 --- a/Mathlib/Tactic/Translate/ToAdditive.lean +++ b/Mathlib/Tactic/Translate/ToAdditive.lean @@ -301,6 +301,7 @@ def nameDict : Std.HashMap String (List String) := .ofList [ ("tprod", ["TSum"]), ("pow", ["NSMul"]), ("npow", ["NSMul"]), + ("ppow", ["PSMul"]), ("zpow", ["ZSMul"]), ("mabs", ["Abs"]), ("monoid", ["Add", "Monoid"]), 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 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*} 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₂