|
| 1 | +/- |
| 2 | +Copyright (c) 2022 Eric Wieser. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Eric Wieser, Jujian Zhang |
| 5 | +-/ |
| 6 | +import algebra.direct_sum.module |
| 7 | +import algebra.module.submodule.basic |
| 8 | + |
| 9 | +/-! |
| 10 | +# Decompositions of additive monoids, groups, and modules into direct sums |
| 11 | +
|
| 12 | +## Main definitions |
| 13 | +
|
| 14 | +* `direct_sum.decomposition ℳ`: A typeclass to provide a constructive decomposition from |
| 15 | + an additive monoid `M` into a family of additive submonoids `ℳ` |
| 16 | +* `direct_sum.decompose ℳ`: The canonical equivalence provided by the above typeclass |
| 17 | +
|
| 18 | +
|
| 19 | +## Main statements |
| 20 | +
|
| 21 | +* `direct_sum.decomposition.is_internal`: The link to `direct_sum.is_internal`. |
| 22 | +
|
| 23 | +## Implementation details |
| 24 | +
|
| 25 | +As we want to talk about different types of decomposition (additive monoids, modules, rings, ...), |
| 26 | +we choose to avoid heavily bundling `direct_sum.decompose`, instead making copies for the |
| 27 | +`add_equiv`, `linear_equiv`, etc. This means we have to repeat statements that follow from these |
| 28 | +bundled homs, but means we don't have to repeat statements for different types of decomposition. |
| 29 | +-/ |
| 30 | + |
| 31 | + |
| 32 | +variables {ι R M σ : Type*} |
| 33 | +open_locale direct_sum big_operators |
| 34 | +namespace direct_sum |
| 35 | + |
| 36 | +section add_comm_monoid |
| 37 | +variables [decidable_eq ι] [add_comm_monoid M] |
| 38 | +variables [set_like σ M] [add_submonoid_class σ M] (ℳ : ι → σ) |
| 39 | + |
| 40 | +/-- A decomposition is an equivalence between an additive monoid `M` and a direct sum of additive |
| 41 | +submonoids `ℳ i` of that `M`, such that the "recomposition" is canonical. This definition also |
| 42 | +works for additive groups and modules. |
| 43 | +
|
| 44 | +This is a version of `direct_sum.is_internal` which comes with a constructive inverse to the |
| 45 | +canonical "recomposition" rather than just a proof that the "recomposition" is bijective. -/ |
| 46 | +class decomposition := |
| 47 | +(decompose' : M → ⨁ i, ℳ i) |
| 48 | +(left_inv : function.left_inverse (direct_sum.coe_add_monoid_hom ℳ) decompose' ) |
| 49 | +(right_inv : function.right_inverse (direct_sum.coe_add_monoid_hom ℳ) decompose') |
| 50 | + |
| 51 | +include M |
| 52 | + |
| 53 | +/-- `direct_sum.decomposition` instances, while carrying data, are always equal. -/ |
| 54 | +instance : subsingleton (decomposition ℳ) := |
| 55 | +⟨λ x y, begin |
| 56 | + cases x with x xl xr, |
| 57 | + cases y with y yl yr, |
| 58 | + congr', |
| 59 | + exact function.left_inverse.eq_right_inverse xr yl, |
| 60 | +end⟩ |
| 61 | + |
| 62 | +variables [decomposition ℳ] |
| 63 | + |
| 64 | +protected lemma decomposition.is_internal : direct_sum.is_internal ℳ := |
| 65 | +⟨decomposition.right_inv.injective, decomposition.left_inv.surjective⟩ |
| 66 | + |
| 67 | +/-- If `M` is graded by `ι` with degree `i` component `ℳ i`, then it is isomorphic as |
| 68 | +to a direct sum of components. This is the canonical spelling of the `decompose'` field. -/ |
| 69 | +def decompose : M ≃ ⨁ i, ℳ i := |
| 70 | +{ to_fun := decomposition.decompose', |
| 71 | + inv_fun := direct_sum.coe_add_monoid_hom ℳ, |
| 72 | + left_inv := decomposition.left_inv, |
| 73 | + right_inv := decomposition.right_inv } |
| 74 | + |
| 75 | +@[simp] lemma decomposition.decompose'_eq : decomposition.decompose' = decompose ℳ := rfl |
| 76 | + |
| 77 | +@[simp] lemma decompose_symm_of {i : ι} (x : ℳ i) : |
| 78 | + (decompose ℳ).symm (direct_sum.of _ i x) = x := |
| 79 | +direct_sum.coe_add_monoid_hom_of ℳ _ _ |
| 80 | + |
| 81 | +@[simp] lemma decompose_coe {i : ι} (x : ℳ i) : |
| 82 | + decompose ℳ (x : M) = direct_sum.of _ i x := |
| 83 | +by rw [←decompose_symm_of, equiv.apply_symm_apply] |
| 84 | + |
| 85 | +lemma decompose_of_mem {x : M} {i : ι} (hx : x ∈ ℳ i) : |
| 86 | + decompose ℳ x = direct_sum.of (λ i, ℳ i) i ⟨x, hx⟩ := |
| 87 | +decompose_coe _ ⟨x, hx⟩ |
| 88 | + |
| 89 | +lemma decompose_of_mem_same {x : M} {i : ι} (hx : x ∈ ℳ i) : |
| 90 | + (decompose ℳ x i : M) = x := |
| 91 | +by rw [decompose_of_mem _ hx, direct_sum.of_eq_same, subtype.coe_mk] |
| 92 | + |
| 93 | +lemma decompose_of_mem_ne {x : M} {i j : ι} (hx : x ∈ ℳ i) (hij : i ≠ j): |
| 94 | + (decompose ℳ x j : M) = 0 := |
| 95 | +by rw [decompose_of_mem _ hx, direct_sum.of_eq_of_ne _ _ _ _ hij, |
| 96 | + add_submonoid_class.coe_zero] |
| 97 | + |
| 98 | +/-- If `M` is graded by `ι` with degree `i` component `ℳ i`, then it is isomorphic as |
| 99 | +an additive monoid to a direct sum of components. -/ |
| 100 | +@[simps {fully_applied := ff}] |
| 101 | +def decompose_add_equiv : M ≃+ ⨁ i, ℳ i := add_equiv.symm |
| 102 | +{ map_add' := map_add (direct_sum.coe_add_monoid_hom ℳ), |
| 103 | + ..(decompose ℳ).symm } |
| 104 | + |
| 105 | +@[simp] lemma decompose_zero : decompose ℳ (0 : M) = 0 := map_zero (decompose_add_equiv ℳ) |
| 106 | +@[simp] lemma decompose_symm_zero : (decompose ℳ).symm 0 = (0 : M) := |
| 107 | +map_zero (decompose_add_equiv ℳ).symm |
| 108 | + |
| 109 | +@[simp] lemma decompose_add (x y : M) : decompose ℳ (x + y) = decompose ℳ x + decompose ℳ y := |
| 110 | +map_add (decompose_add_equiv ℳ) x y |
| 111 | +@[simp] lemma decompose_symm_add (x y : ⨁ i, ℳ i) : |
| 112 | + (decompose ℳ).symm (x + y) = (decompose ℳ).symm x + (decompose ℳ).symm y := |
| 113 | +map_add (decompose_add_equiv ℳ).symm x y |
| 114 | + |
| 115 | +@[simp] lemma decompose_sum {ι'} (s : finset ι') (f : ι' → M) : |
| 116 | + decompose ℳ (∑ i in s, f i) = ∑ i in s, decompose ℳ (f i) := |
| 117 | +map_sum (decompose_add_equiv ℳ) f s |
| 118 | +@[simp] lemma decompose_symm_sum {ι'} (s : finset ι') (f : ι' → ⨁ i, ℳ i) : |
| 119 | + (decompose ℳ).symm (∑ i in s, f i) = ∑ i in s, (decompose ℳ).symm (f i) := |
| 120 | +map_sum (decompose_add_equiv ℳ).symm f s |
| 121 | + |
| 122 | +lemma sum_support_decompose [Π i (x : ℳ i), decidable (x ≠ 0)] (r : M) : |
| 123 | + ∑ i in (decompose ℳ r).support, (decompose ℳ r i : M) = r := |
| 124 | +begin |
| 125 | + conv_rhs { rw [←(decompose ℳ).symm_apply_apply r, |
| 126 | + ←sum_support_of (λ i, (ℳ i)) (decompose ℳ r)] }, |
| 127 | + rw [decompose_symm_sum], |
| 128 | + simp_rw decompose_symm_of, |
| 129 | +end |
| 130 | + |
| 131 | +end add_comm_monoid |
| 132 | + |
| 133 | +/-- The `-` in the statements below doesn't resolve without this line. |
| 134 | +
|
| 135 | +This seems to a be a problem of synthesized vs inferred typeclasses disagreeing. If we replace |
| 136 | +the statement of `decompose_neg` with `@eq (⨁ i, ℳ i) (decompose ℳ (-x)) (-decompose ℳ x)` |
| 137 | +instead of `decompose ℳ (-x) = -decompose ℳ x`, which forces the typeclasses needed by `⨁ i, ℳ i` to |
| 138 | +be found by unification rather than synthesis, then everything works fine without this instance. -/ |
| 139 | +instance add_comm_group_set_like [add_comm_group M] [set_like σ M] [add_subgroup_class σ M] |
| 140 | + (ℳ : ι → σ) : add_comm_group (⨁ i, ℳ i) := by apply_instance |
| 141 | + |
| 142 | +section add_comm_group |
| 143 | +variables [decidable_eq ι] [add_comm_group M] |
| 144 | +variables [set_like σ M] [add_subgroup_class σ M] (ℳ : ι → σ) |
| 145 | +variables [decomposition ℳ] |
| 146 | +include M |
| 147 | + |
| 148 | +@[simp] lemma decompose_neg (x : M) : decompose ℳ (-x) = -decompose ℳ x := |
| 149 | +map_neg (decompose_add_equiv ℳ) x |
| 150 | +@[simp] lemma decompose_symm_neg (x : ⨁ i, ℳ i) : |
| 151 | + (decompose ℳ).symm (-x) = -(decompose ℳ).symm x := |
| 152 | +map_neg (decompose_add_equiv ℳ).symm x |
| 153 | + |
| 154 | +@[simp] lemma decompose_sub (x y : M) : decompose ℳ (x - y) = decompose ℳ x - decompose ℳ y := |
| 155 | +map_sub (decompose_add_equiv ℳ) x y |
| 156 | +@[simp] lemma decompose_symm_sub (x y : ⨁ i, ℳ i) : |
| 157 | + (decompose ℳ).symm (x - y) = (decompose ℳ).symm x - (decompose ℳ).symm y := |
| 158 | +map_sub (decompose_add_equiv ℳ).symm x y |
| 159 | + |
| 160 | +end add_comm_group |
| 161 | + |
| 162 | +section module |
| 163 | +variables [decidable_eq ι] [semiring R] [add_comm_monoid M] [module R M] |
| 164 | +variables (ℳ : ι → submodule R M) |
| 165 | +variables [decomposition ℳ] |
| 166 | +include M |
| 167 | + |
| 168 | +/-- If `M` is graded by `ι` with degree `i` component `ℳ i`, then it is isomorphic as |
| 169 | +a module to a direct sum of components. -/ |
| 170 | +@[simps {fully_applied := ff}] |
| 171 | +def decompose_linear_equiv : M ≃ₗ[R] ⨁ i, ℳ i := linear_equiv.symm |
| 172 | +{ map_smul' := map_smul (direct_sum.coe_linear_map ℳ), |
| 173 | + ..(decompose_add_equiv ℳ).symm } |
| 174 | + |
| 175 | +@[simp] lemma decompose_smul (r : R) (x : M) : decompose ℳ (r • x) = r • decompose ℳ x := |
| 176 | +map_smul (decompose_linear_equiv ℳ) r x |
| 177 | + |
| 178 | +end module |
| 179 | + |
| 180 | +end direct_sum |
0 commit comments