Skip to content

Commit

Permalink
refactor(algebra/direct_sum): rework internally-graded objects (#10127)
Browse files Browse the repository at this point in the history
This is a replacement for the `graded_ring.core` typeclass in #10115, which is called `set_like.graded_monoid` here. The advantage of this approach is that we can use the same typeclass for graded semirings, graded rings, and graded algebras.

Largely, this change replaces a bunch of `def`s with `instances`, by bundling up the arguments to those defs to a new typeclass. This seems to make life easier for the few global `gmonoid` instance we already provide for direct sums of submodules, suggesting this API change is a useful one.

In principle the new `[set_like.graded_monoid A]` typeclass is useless, as the same effect can be achieved with `[set_like.has_graded_one A] [set_like.has_graded_mul A]`; pragmatically though this is painfully verbose, and probably results in larger term sizes. We can always remove it later if it causes problems.



Co-authored-by: Jujian Zhang <jujian.zhang1998@outlook.com>
  • Loading branch information
eric-wieser and jjaassoonn committed Nov 3, 2021
1 parent 6433c1c commit fed57b5
Show file tree
Hide file tree
Showing 6 changed files with 251 additions and 225 deletions.
31 changes: 0 additions & 31 deletions src/algebra/direct_sum/algebra.lean
Expand Up @@ -23,11 +23,6 @@ where all `A i` are `R`-modules. This is the extra structure needed to promote `
submodules.
* `direct_sum.to_algebra` extends `direct_sum.to_semiring` to produce an `alg_hom`.
## Direct sums of subobjects
Additionally, this module provides the instance `direct_sum.galgebra.of_submodules` which promotes
any instance constructed with `direct_sum.gmonoid.of_submodules` to an `R`-algebra.
-/

universes uι uR uA uB
Expand Down Expand Up @@ -93,32 +88,6 @@ lemma algebra_map_apply (r : R) :
lemma algebra_map_to_add_monoid_hom :
↑(algebra_map R (⨁ i, A i)) = (direct_sum.of A 0).comp (galgebra.to_fun : R →+ A 0) := rfl

section
-- for `simps`
local attribute [simp] linear_map.cod_restrict

/-- A `direct_sum.gmonoid` instance produced by `direct_sum.gmonoid.of_submodules` is automatically
a `direct_sum.galgebra`. -/
@[simps to_fun_apply {simp_rhs := tt}]
instance galgebra.of_submodules
(carriers : ι → submodule R B)
(one_mem : (1 : B) ∈ carriers 0)
(mul_mem : ∀ ⦃i j⦄ (gi : carriers i) (gj : carriers j), (gi * gj : B) ∈ carriers (i + j)) :
by haveI : gsemiring (λ i, carriers i) := gsemiring.of_submodules carriers one_mem mul_mem; exact
galgebra R (λ i, carriers i) :=
by exact {
to_fun := begin
refine ((algebra.linear_map R B).cod_restrict (carriers 0) $ λ r, _).to_add_monoid_hom,
exact submodule.one_le.mpr one_mem (submodule.algebra_map_mem _),
end,
map_one := subtype.ext $ by exact (algebra_map R B).map_one,
map_mul := λ x y, sigma.subtype_ext (add_zero 0).symm $ (algebra_map R B).map_mul _ _,
commutes := λ r ⟨i, xi⟩,
sigma.subtype_ext ((zero_add i).trans (add_zero i).symm) $ algebra.commutes _ _,
smul_def := λ r ⟨i, xi⟩, sigma.subtype_ext (zero_add i).symm $ algebra.smul_def _ _ }

end

/-- A family of `linear_map`s preserving `direct_sum.ghas_one.one` and `direct_sum.ghas_mul.mul`
describes an `alg_hom` on `⨁ i, A i`. This is a stronger version of `direct_sum.to_semiring`.
Expand Down
163 changes: 163 additions & 0 deletions src/algebra/direct_sum/internal.lean
@@ -0,0 +1,163 @@
/-
Copyright (c) 2021 Eric Wieser. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Eric Wieser, Kevin Buzzard, Jujian Zhang
-/

import algebra.direct_sum.algebra

/-!
# Internally graded rings and algebras
This module provides `gsemiring` and `gcomm_semiring` instances for a collection of subobjects `A`
when a `set_like.graded_monoid` instance is available:
* on `add_submonoid R`s: `add_submonoid.gsemiring`, `add_submonoid.gcomm_semiring`.
* on `add_subgroup R`s: `add_subgroup.gsemiring`, `add_subgroup.gcomm_semiring`.
* on `submodule S R`s: `submodule.gsemiring`, `submodule.gcomm_semiring`.
With these instances in place, it provides the bundled canonical maps out of a direct sum of
subobjects into their carrier type:
* `direct_sum.add_submonoid_coe_ring_hom` (a `ring_hom` version of `direct_sum.add_submonoid_coe`)
* `direct_sum.add_subgroup_coe_ring_hom` (a `ring_hom` version of `direct_sum.add_subgroup_coe`)
* `direct_sum.submodule_coe_alg_hom` (an `alg_hom` version of `direct_sum.submodule_coe`)
Strictly the definitions in this file are not sufficient to fully define an "internal" direct sum;
to represent this case, `(h : direct_sum.submodule_is_internal A) [set_like.graded_monoid A]` is
needed. In the future there will likely be a data-carrying, constructive, typeclass version of
`direct_sum.submodule_is_internal` for providing an explicit decomposition function.
When `complete_lattice.independent (set.range A)` (a weaker condition than
`direct_sum.submodule_is_internal A`), these provide a grading of `⨆ i, A i`, and the
mapping `⨁ i, A i →+ ⨆ i, A i` can be obtained as
`direct_sum.to_monoid (λ i, add_submonoid.inclusion $ le_supr A i)`.
## tags
internally graded ring
-/

open_locale direct_sum

variables {ι : Type*} {S R : Type*} [decidable_eq ι]

/-! #### From `add_submonoid`s -/

namespace add_submonoid

/-- Build a `gsemiring` instance for a collection of `add_submonoid`s. -/
instance gsemiring [add_monoid ι] [semiring R]
(A : ι → add_submonoid R) [set_like.graded_monoid A] :
direct_sum.gsemiring (λ i, A i) :=
{ mul_zero := λ i j _, subtype.ext (mul_zero _),
zero_mul := λ i j _, subtype.ext (zero_mul _),
mul_add := λ i j _ _ _, subtype.ext (mul_add _ _ _),
add_mul := λ i j _ _ _, subtype.ext (add_mul _ _ _),
..set_like.gmonoid A }

/-- Build a `gcomm_semiring` instance for a collection of `add_submonoid`s. -/
instance gcomm_semiring [add_comm_monoid ι] [comm_semiring R]
(A : ι → add_submonoid R) [set_like.graded_monoid A] :
direct_sum.gcomm_semiring (λ i, A i) :=
{ ..set_like.gcomm_monoid A,
..add_submonoid.gsemiring A, }

end add_submonoid

/-- The canonical ring isomorphism between `⨁ i, A i` and `R`-/
def direct_sum.submonoid_coe_ring_hom [add_monoid ι] [semiring R]
(A : ι → add_submonoid R) [h : set_like.graded_monoid A] : (⨁ i, A i) →+* R :=
direct_sum.to_semiring (λ i, (A i).subtype) rfl (λ _ _ _ _, rfl)

/-- The canonical ring isomorphism between `⨁ i, A i` and `R`-/
@[simp] lemma direct_sum.submonoid_coe_ring_hom_of [add_monoid ι] [semiring R]
(A : ι → add_submonoid R) [h : set_like.graded_monoid A] (i : ι) (x : A i) :
direct_sum.submonoid_coe_ring_hom A (direct_sum.of (λ i, A i) i x) = x :=
direct_sum.to_semiring_of _ _ _ _ _

/-! #### From `add_subgroup`s -/

namespace add_subgroup

/-- Build a `gsemiring` instance for a collection of `add_subgroup`s. -/
instance gsemiring [add_monoid ι] [ring R]
(A : ι → add_subgroup R) [h : set_like.graded_monoid A] :
direct_sum.gsemiring (λ i, A i) :=
have i' : set_like.graded_monoid (λ i, (A i).to_add_submonoid) := {..h},
by exactI add_submonoid.gsemiring (λ i, (A i).to_add_submonoid)

/-- Build a `gcomm_semiring` instance for a collection of `add_subgroup`s. -/
instance gcomm_semiring [add_comm_group ι] [comm_ring R]
(A : ι → add_subgroup R) [h : set_like.graded_monoid A] :
direct_sum.gsemiring (λ i, A i) :=
have i' : set_like.graded_monoid (λ i, (A i).to_add_submonoid) := {..h},
by exactI add_submonoid.gsemiring (λ i, (A i).to_add_submonoid)

end add_subgroup

/-- The canonical ring isomorphism between `⨁ i, A i` and `R`. -/
def direct_sum.subgroup_coe_ring_hom [add_monoid ι] [ring R]
(A : ι → add_subgroup R) [set_like.graded_monoid A] : (⨁ i, A i) →+* R :=
direct_sum.to_semiring (λ i, (A i).subtype) rfl (λ _ _ _ _, rfl)

@[simp] lemma direct_sum.subgroup_coe_ring_hom_of [add_monoid ι] [ring R]
(A : ι → add_subgroup R) [set_like.graded_monoid A] (i : ι) (x : A i) :
direct_sum.subgroup_coe_ring_hom A (direct_sum.of (λ i, A i) i x) = x :=
direct_sum.to_semiring_of _ _ _ _ _

/-! #### From `submodules`s -/

namespace submodule

/-- Build a `gsemiring` instance for a collection of `submodule`s. -/
instance gsemiring [add_monoid ι]
[comm_semiring S] [semiring R] [algebra S R]
(A : ι → submodule S R) [h : set_like.graded_monoid A] :
direct_sum.gsemiring (λ i, A i) :=
have i' : set_like.graded_monoid (λ i, (A i).to_add_submonoid) := {..h},
by exactI add_submonoid.gsemiring (λ i, (A i).to_add_submonoid)

/-- Build a `gsemiring` instance for a collection of `submodule`s. -/
instance gcomm_semiring [add_comm_monoid ι]
[comm_semiring S] [comm_semiring R] [algebra S R]
(A : ι → submodule S R) [h : set_like.graded_monoid A] :
direct_sum.gcomm_semiring (λ i, A i) :=
have i' : set_like.graded_monoid (λ i, (A i).to_add_submonoid) := {..h},
by exactI add_submonoid.gcomm_semiring (λ i, (A i).to_add_submonoid)

/-- Build a `galgebra` instance for a collection of `submodule`s. -/
instance galgebra [add_monoid ι]
[comm_semiring S] [semiring R] [algebra S R]
(A : ι → submodule S R) [h : set_like.graded_monoid A] :
direct_sum.galgebra S (λ i, A i) :=
{ to_fun := begin
refine ((algebra.linear_map S R).cod_restrict (A 0) $ λ r, _).to_add_monoid_hom,
exact submodule.one_le.mpr set_like.has_graded_one.one_mem (submodule.algebra_map_mem _),
end,
map_one := subtype.ext $ by exact (algebra_map S R).map_one,
map_mul := λ x y, sigma.subtype_ext (add_zero 0).symm $ (algebra_map S R).map_mul _ _,
commutes := λ r ⟨i, xi⟩,
sigma.subtype_ext ((zero_add i).trans (add_zero i).symm) $ algebra.commutes _ _,
smul_def := λ r ⟨i, xi⟩, sigma.subtype_ext (zero_add i).symm $ algebra.smul_def _ _ }

/-- A direct sum of powers of a submodule of an algebra has a multiplicative structure. -/
instance nat_power_graded_monoid
[comm_semiring S] [semiring R] [algebra S R] (p : submodule S R) :
set_like.graded_monoid (λ i : ℕ, p ^ i) :=
{ one_mem := by { rw [←one_le, pow_zero], exact le_rfl },
mul_mem := λ i j p q hp hq, by { rw pow_add, exact submodule.mul_mem_mul hp hq } }

end submodule

/-- The canonical algebra isomorphism between `⨁ i, A i` and `R`. -/
def direct_sum.submodule_coe_alg_hom [add_monoid ι]
[comm_semiring S] [semiring R] [algebra S R]
(A : ι → submodule S R) [h : set_like.graded_monoid A] : (⨁ i, A i) →ₐ[S] R :=
direct_sum.to_algebra S _ (λ i, (A i).subtype) rfl (λ _ _ _ _, rfl) (λ _, rfl)

@[simp] lemma direct_sum.submodule_coe_alg_hom_of [add_monoid ι]
[comm_semiring S] [semiring R] [algebra S R]
(A : ι → submodule S R) [h : set_like.graded_monoid A] (i : ι) (x : A i) :
direct_sum.submodule_coe_alg_hom A (direct_sum.of (λ i, A i) i x) = x :=
direct_sum.to_semiring_of _ rfl (λ _ _ _ _, rfl) _ _
112 changes: 1 addition & 111 deletions src/algebra/direct_sum/ring.lean
Expand Up @@ -20,7 +20,7 @@ additively-graded ring. The typeclasses are:
* `direct_sum.gsemiring A`
* `direct_sum.gcomm_semiring A`
Respectively, these imbue the direct sum `⨁ i, A i` with:
Respectively, these imbue the external direct sum `⨁ i, A i` with:
* `direct_sum.non_unital_non_assoc_semiring`
* `direct_sum.semiring`, `direct_sum.ring`
Expand Down Expand Up @@ -103,95 +103,6 @@ class gcomm_semiring [add_comm_monoid ι] [Π i, add_comm_monoid (A i)] extends

end defs

/-! ### Shorthands for creating the above typeclasses -/

section shorthands

variables {R : Type*}

/-! #### From `add_submonoid`s -/

/-- Build a `gsemiring` instance for a collection of `add_submonoid`s.
See note [reducible non-instances]. -/
@[reducible]
def gsemiring.of_add_submonoids [semiring R] [add_monoid ι]
(carriers : ι → add_submonoid R)
(one_mem : (1 : R) ∈ carriers 0)
(mul_mem : ∀ ⦃i j⦄ (gi : carriers i) (gj : carriers j), (gi * gj : R) ∈ carriers (i + j)) :
gsemiring (λ i, carriers i) :=
{ mul_zero := λ i j _, subtype.ext (mul_zero _),
zero_mul := λ i j _, subtype.ext (zero_mul _),
mul_add := λ i j _ _ _, subtype.ext (mul_add _ _ _),
add_mul := λ i j _ _ _, subtype.ext (add_mul _ _ _),
..graded_monoid.gmonoid.of_subobjects carriers one_mem mul_mem }

/-- Build a `gcomm_semiring` instance for a collection of `add_submonoid`s.
See note [reducible non-instances]. -/
@[reducible]
def gcomm_semiring.of_add_submonoids [comm_semiring R] [add_comm_monoid ι]
(carriers : ι → add_submonoid R)
(one_mem : (1 : R) ∈ carriers 0)
(mul_mem : ∀ ⦃i j⦄ (gi : carriers i) (gj : carriers j), (gi * gj : R) ∈ carriers (i + j)) :
gcomm_semiring (λ i, carriers i) :=
{ ..graded_monoid.gcomm_monoid.of_subobjects carriers one_mem mul_mem,
..gsemiring.of_add_submonoids carriers one_mem mul_mem}

/-! #### From `add_subgroup`s -/

/-- Build a `gsemiring` instance for a collection of `add_subgroup`s.
See note [reducible non-instances]. -/
@[reducible]
def gsemiring.of_add_subgroups [ring R] [add_monoid ι]
(carriers : ι → add_subgroup R)
(one_mem : (1 : R) ∈ carriers 0)
(mul_mem : ∀ ⦃i j⦄ (gi : carriers i) (gj : carriers j), (gi * gj : R) ∈ carriers (i + j)) :
gsemiring (λ i, carriers i) :=
gsemiring.of_add_submonoids (λ i, (carriers i).to_add_submonoid) one_mem mul_mem

/-- Build a `gcomm_semiring` instance for a collection of `add_subgroup`s.
See note [reducible non-instances]. -/
@[reducible]
def gcomm_semiring.of_add_subgroups [comm_ring R] [add_comm_monoid ι]
(carriers : ι → add_subgroup R)
(one_mem : (1 : R) ∈ carriers 0)
(mul_mem : ∀ ⦃i j⦄ (gi : carriers i) (gj : carriers j), (gi * gj : R) ∈ carriers (i + j)) :
gcomm_semiring (λ i, carriers i) :=
gcomm_semiring.of_add_submonoids (λ i, (carriers i).to_add_submonoid) one_mem mul_mem

/-! #### From `submodules`s -/

variables {A : Type*}

/-- Build a `gsemiring` instance for a collection of `submodules`s.
See note [reducible non-instances]. -/
@[reducible]
def gsemiring.of_submodules
[comm_semiring R] [semiring A] [algebra R A] [add_monoid ι]
(carriers : ι → submodule R A)
(one_mem : (1 : A) ∈ carriers 0)
(mul_mem : ∀ ⦃i j⦄ (gi : carriers i) (gj : carriers j), (gi * gj : A) ∈ carriers (i + j)) :
gsemiring (λ i, carriers i) :=
gsemiring.of_add_submonoids (λ i, (carriers i).to_add_submonoid) one_mem mul_mem

/-- Build a `gcomm_semiring` instance for a collection of `submodules`s.
See note [reducible non-instances]. -/
@[reducible]
def gcomm_semiring.of_submodules
[comm_semiring R] [comm_semiring A] [algebra R A] [add_comm_monoid ι]
(carriers : ι → submodule R A)
(one_mem : (1 : A) ∈ carriers 0)
(mul_mem : ∀ ⦃i j⦄ (gi : carriers i) (gj : carriers j), (gi * gj : A) ∈ carriers (i + j)) :
gcomm_semiring (λ i, carriers i) :=
gcomm_semiring.of_add_submonoids (λ i, (carriers i).to_add_submonoid) one_mem mul_mem

end shorthands

lemma of_eq_of_graded_monoid_eq {A : ι → Type*} [Π (i : ι), add_comm_monoid (A i)]
{i j : ι} {a : A i} {b : A j} (h : graded_monoid.mk i a = graded_monoid.mk j b) :
direct_sum.of A i a = direct_sum.of A j b :=
Expand Down Expand Up @@ -595,24 +506,3 @@ instance comm_semiring.direct_sum_gcomm_semiring {R : Type*} [add_comm_monoid ι
{ ..comm_monoid.gcomm_monoid ι, ..semiring.direct_sum_gsemiring ι }

end uniform

namespace submodule

variables {R A : Type*} [comm_semiring R]

/-- A direct sum of powers of a submodule of an algebra has a multiplicative structure. -/
instance nat_power_direct_sum_gsemiring [semiring A] [algebra R A] (S : submodule R A) :
direct_sum.gsemiring (λ i : ℕ, ↥(S ^ i)) :=
direct_sum.gsemiring.of_submodules _
(by { rw [←one_le, pow_zero], exact le_rfl })
(λ i j p q, by { rw pow_add, exact submodule.mul_mem_mul p.prop q.prop })

/-- A direct sum of powers of a submodule of a commutative algebra has a commutative multiplicative
structure. -/
instance nat_power_direct_sum_gcomm_semiring [comm_semiring A] [algebra R A] (S : submodule R A) :
direct_sum.gcomm_semiring (λ i : ℕ, ↥(S ^ i)) :=
direct_sum.gcomm_semiring.of_submodules _
(by { rw [←one_le, pow_zero], exact le_rfl })
(λ i j p q, by { rw pow_add, exact submodule.mul_mem_mul p.prop q.prop })

end submodule

0 comments on commit fed57b5

Please sign in to comment.