Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 5ac79a6

Browse files
committed
feat(algebra/lie/tensor_product): prove lie_submodule.lie_ideal_oper_eq_tensor_map_range (#7313)
The lemma `coe_lift_lie_eq_lift_coe` also introduced here is an unrelated change but is a stronger form of `lift_lie_apply` that is worth having. See also this [Zulip remark](https://leanprover.zulipchat.com/#narrow/stream/113488-general/topic/.60linear_map.2Erange_eq_map.60.20vs.20.60submodule.2Emap_top.60/near/235845192) concerning the proposed library note.
1 parent 35b9d9c commit 5ac79a6

File tree

11 files changed

+209
-48
lines changed

11 files changed

+209
-48
lines changed

src/algebra/lie/abelian.lean

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,12 +199,17 @@ def maximal_trivial_linear_map_equiv_lie_module_hom :
199199
((maximal_trivial_linear_map_equiv_lie_module_hom f) : M → N) = f :=
200200
by { ext, refl, }
201201

202-
@[simp] lemma coe_maximal_trivial_linear_map_equiv_lie_module_hom_apply
202+
@[simp] lemma coe_maximal_trivial_linear_map_equiv_lie_module_hom_symm
203+
(f : M →ₗ⁅R,L⁆ N) :
204+
((maximal_trivial_linear_map_equiv_lie_module_hom.symm f) : M → N) = f :=
205+
rfl
206+
207+
@[simp] lemma coe_linear_map_maximal_trivial_linear_map_equiv_lie_module_hom
203208
(f : maximal_trivial_submodule R L (M →ₗ[R] N)) :
204209
((maximal_trivial_linear_map_equiv_lie_module_hom f) : M →ₗ[R] N) = (f : M →ₗ[R] N) :=
205210
by { ext, refl, }
206211

207-
@[simp] lemma coe_maximal_trivial_linear_map_equiv_lie_module_hom_symm_apply
212+
@[simp] lemma coe_linear_map_maximal_trivial_linear_map_equiv_lie_module_hom_symm
208213
(f : M →ₗ⁅R,L⁆ N) :
209214
((maximal_trivial_linear_map_equiv_lie_module_hom.symm f) : M →ₗ[R] N) = (f : M →ₗ[R] N) :=
210215
rfl

src/algebra/lie/basic.lean

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -253,12 +253,18 @@ def comp (f : L₂ →ₗ⁅R⁆ L₃) (g : L₁ →ₗ⁅R⁆ L₂) : L₁ →
253253
{ map_lie' := λ x y, by { change f (g ⁅x, y⁆) = ⁅f (g x), f (g y)⁆, rw [map_lie, map_lie], },
254254
..linear_map.comp f.to_linear_map g.to_linear_map }
255255

256-
@[simp] lemma comp_apply (f : L₂ →ₗ⁅R⁆ L₃) (g : L₁ →ₗ⁅R⁆ L₂) (x : L₁) :
256+
lemma comp_apply (f : L₂ →ₗ⁅R⁆ L₃) (g : L₁ →ₗ⁅R⁆ L₂) (x : L₁) :
257257
f.comp g x = f (g x) := rfl
258258

259-
@[norm_cast]
260-
lemma comp_coe (f : L₂ →ₗ⁅R⁆ L₃) (g : L₁ →ₗ⁅R⁆ L₂) :
261-
(f : L₂ → L₃) ∘ (g : L₁ → L₂) = f.comp g := rfl
259+
@[norm_cast, simp]
260+
lemma coe_comp (f : L₂ →ₗ⁅R⁆ L₃) (g : L₁ →ₗ⁅R⁆ L₂) :
261+
(f.comp g : L₁ → L₃) = f ∘ g :=
262+
rfl
263+
264+
@[norm_cast, simp]
265+
lemma coe_linear_map_comp (f : L₂ →ₗ⁅R⁆ L₃) (g : L₁ →ₗ⁅R⁆ L₂) :
266+
(f.comp g : L₁ →ₗ[R] L₃) = (f : L₂ →ₗ[R] L₃).comp (g : L₁ →ₗ[R] L₂) :=
267+
rfl
262268

263269
/-- The inverse of a bijective morphism is a morphism. -/
264270
def inverse (f : L₁ →ₗ⁅R⁆ L₂) (g : L₂ → L₁)
@@ -445,11 +451,16 @@ def comp (f : N →ₗ⁅R,L⁆ P) (g : M →ₗ⁅R,L⁆ N) : M →ₗ⁅R,L⁆
445451
{ map_lie' := λ x m, by { change f (g ⁅x, m⁆) = ⁅x, f (g m)⁆, rw [map_lie, map_lie], },
446452
..linear_map.comp f.to_linear_map g.to_linear_map }
447453

448-
@[simp] lemma comp_apply (f : N →ₗ⁅R,L⁆ P) (g : M →ₗ⁅R,L⁆ N) (m : M) :
454+
lemma comp_apply (f : N →ₗ⁅R,L⁆ P) (g : M →ₗ⁅R,L⁆ N) (m : M) :
449455
f.comp g m = f (g m) := rfl
450456

451-
@[norm_cast] lemma comp_coe (f : N →ₗ⁅R,L⁆ P) (g : M →ₗ⁅R,L⁆ N) :
452-
(f : N → P) ∘ (g : M → N) = f.comp g := rfl
457+
@[norm_cast, simp] lemma coe_comp (f : N →ₗ⁅R,L⁆ P) (g : M →ₗ⁅R,L⁆ N) :
458+
(f.comp g : M → P) = f ∘ g :=
459+
rfl
460+
461+
@[norm_cast, simp] lemma coe_linear_map_comp (f : N →ₗ⁅R,L⁆ P) (g : M →ₗ⁅R,L⁆ N) :
462+
(f.comp g : M →ₗ[R] P) = (f : N →ₗ[R] P).comp (g : M →ₗ[R] N) :=
463+
rfl
453464

454465
/-- The inverse of a bijective morphism of Lie modules is a morphism of Lie modules. -/
455466
def inverse (f : M →ₗ⁅R,L⁆ N) (g : N → M)

src/algebra/lie/ideal_operations.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ instance has_bracket : has_bracket (lie_ideal R L) (lie_submodule R L M) :=
5050
lemma lie_ideal_oper_eq_span :
5151
⁅I, N⁆ = lie_span R L { m | ∃ (x : I) (n : N), ⁅(x : L), (n : M)⁆ = m } := rfl
5252

53+
/-- See also `lie_submodule.lie_ideal_oper_eq_tensor_map_range`. -/
5354
lemma lie_ideal_oper_eq_linear_span :
5455
(↑⁅I, N⁆ : submodule R M) = submodule.span R { m | ∃ (x : I) (n : N), ⁅(x : L), (n : M)⁆ = m } :=
5556
begin

src/algebra/lie/of_associative.lean

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@ variables (R : Type u) (L : Type v) (M : Type w)
103103
variables [comm_ring R] [lie_ring L] [lie_algebra R L] [add_comm_group M] [module R M]
104104
variables [lie_ring_module L M] [lie_module R L M]
105105

106-
/-- A Lie module yields a Lie algebra morphism into the linear endomorphisms of the module. -/
106+
/-- A Lie module yields a Lie algebra morphism into the linear endomorphisms of the module.
107+
108+
See also `lie_module.to_module_hom`. -/
107109
@[simps] def lie_module.to_endomorphism : L →ₗ⁅R⁆ module.End R M :=
108110
{ to_fun := λ x,
109111
{ to_fun := λ m, ⁅x, m⁆,

src/algebra/lie/submodule.lean

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,15 @@ begin
8989
{ rw h, },
9090
end
9191

92+
/-- Copy of a lie_submodule with a new `carrier` equal to the old one. Useful to fix definitional
93+
equalities. -/
94+
protected def copy (s : set M) (hs : s = ↑N) : lie_submodule R L M :=
95+
{ carrier := s,
96+
zero_mem' := hs.symm ▸ N.zero_mem',
97+
add_mem' := hs.symm ▸ N.add_mem',
98+
smul_mem' := hs.symm ▸ N.smul_mem',
99+
lie_mem := hs.symm ▸ N.lie_mem, }
100+
92101
instance : lie_ring_module L N :=
93102
{ bracket := λ (x : L) (m : N), ⟨⁅x, m.val⁆, N.lie_mem m.property⟩,
94103
add_lie := by { intros x y m, apply set_coe.ext, apply add_lie, },
@@ -416,6 +425,10 @@ lemma map_le_iff_le_comap {f : M →ₗ⁅R,L⁆ M'} {N : lie_submodule R L M} {
416425
lemma gc_map_comap (f : M →ₗ⁅R,L⁆ M') : galois_connection (map f) (comap f) :=
417426
λ N N', map_le_iff_le_comap
418427

428+
@[simp] lemma mem_map (f : M →ₗ⁅R,L⁆ M') (N : lie_submodule R L M) (m' : M') :
429+
m' ∈ N.map f ↔ ∃ m, m ∈ N ∧ f m = m' :=
430+
submodule.mem_map
431+
419432
end lie_submodule
420433

421434
namespace lie_ideal
@@ -719,6 +732,31 @@ end lie_ideal
719732

720733
end lie_submodule_map_and_comap
721734

735+
namespace lie_module_hom
736+
737+
variables {R : Type u} {L : Type v} {M : Type w} {N : Type w₁}
738+
variables [comm_ring R] [lie_ring L] [lie_algebra R L]
739+
variables [add_comm_group M] [module R M] [lie_ring_module L M] [lie_module R L M]
740+
variables [add_comm_group N] [module R N] [lie_ring_module L N] [lie_module R L N]
741+
variables (f : M →ₗ⁅R,L⁆ N)
742+
743+
/-- The range of a morphism of Lie modules `f : M → N` is a Lie submodule of `N`.
744+
See Note [range copy pattern]. -/
745+
def range : lie_submodule R L N :=
746+
(lie_submodule.map f ⊤).copy (set.range f) set.image_univ.symm
747+
748+
@[simp] lemma coe_range : (f.range : set N) = set.range f := rfl
749+
750+
@[simp] lemma coe_submodule_range : (f.range : submodule R N) = (f : M →ₗ[R] N).range := rfl
751+
752+
@[simp] lemma mem_range (n : N) : n ∈ f.range ↔ ∃ m, f m = n :=
753+
iff.rfl
754+
755+
lemma map_top : lie_submodule.map f ⊤ = f.range :=
756+
by { ext, simp, }
757+
758+
end lie_module_hom
759+
722760
section top_equiv_self
723761

724762
variables {R : Type u} {L : Type v}

src/algebra/lie/tensor_product.lean

Lines changed: 106 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,24 @@ Tensor products of Lie modules carry natural Lie module structures.
1515
lie module, tensor product, universal property
1616
-/
1717

18-
universes u v w w₁ w₂
18+
universes u v w w₁ w₂ w₃
19+
20+
variables {R : Type u} [comm_ring R]
1921

2022
namespace tensor_product
2123

2224
open_locale tensor_product
2325

24-
variables {R : Type u} [comm_ring R]
25-
2626
namespace lie_module
2727

2828
open lie_module
2929

30-
variables {L : Type v} {M : Type w} {N : Type w₁} {P : Type w₂}
30+
variables {L : Type v} {M : Type w} {N : Type w₁} {P : Type w₂} {Q : Type w₃}
3131
variables [lie_ring L] [lie_algebra R L]
3232
variables [add_comm_group M] [module R M] [lie_ring_module L M] [lie_module R L M]
3333
variables [add_comm_group N] [module R N] [lie_ring_module L N] [lie_module R L N]
3434
variables [add_comm_group P] [module R P] [lie_ring_module L P] [lie_module R L P]
35+
variables [add_comm_group Q] [module R Q] [lie_ring_module L Q] [lie_module R L Q]
3536

3637
/-- It is useful to define the bracket via this auxiliary function so that we have a type-theoretic
3738
expression of the fact that `L` acts by linear endomorphisms. It simplifies the proofs in
@@ -66,19 +67,19 @@ instance lie_module : lie_module R L (M ⊗[R] N) :=
6667
linear_map.ltensor_smul, lie_hom.map_smul, linear_map.add_apply], },
6768
lie_smul := λ c x, linear_map.map_smul _ c, }
6869

69-
@[simp] lemma lie_tensor_right (x : L) (m : M) (n : N) :
70+
@[simp] lemma lie_tmul_right (x : L) (m : M) (n : N) :
7071
⁅x, m ⊗ₜ[R] n⁆ = ⁅x, m⁆ ⊗ₜ n + m ⊗ₜ ⁅x, n⁆ :=
7172
show has_bracket_aux x (m ⊗ₜ[R] n) = _,
7273
by simp only [has_bracket_aux, linear_map.rtensor_tmul, to_endomorphism_apply_apply,
7374
linear_map.add_apply, linear_map.ltensor_tmul]
7475

75-
variables (R L M N P)
76+
variables (R L M N P Q)
7677

7778
/-- The universal property for tensor product of modules of a Lie algebra: the `R`-linear
7879
tensor-hom adjunction is equivariant with respect to the `L` action. -/
7980
def lift : (M →ₗ[R] N →ₗ[R] P) ≃ₗ⁅R,L⁆ (M ⊗[R] N →ₗ[R] P) :=
8081
{ map_lie' := λ x f, by
81-
{ ext m n, simp only [mk_apply, linear_map.compr₂_apply, lie_tensor_right, linear_map.sub_apply,
82+
{ ext m n, simp only [mk_apply, linear_map.compr₂_apply, lie_tmul_right, linear_map.sub_apply,
8283
lift.equiv_apply, linear_equiv.to_fun_eq_coe, lie_hom.lie_apply, linear_map.map_add],
8384
abel, },
8485
..tensor_product.lift.equiv R M N P }
@@ -96,14 +97,106 @@ def lift_lie : (M →ₗ⁅R,L⁆ N →ₗ[R] P) ≃ₗ[R] (M ⊗[R] N →ₗ⁅
9697
↑(maximal_trivial_equiv (lift R L M N P))).trans
9798
maximal_trivial_linear_map_equiv_lie_module_hom
9899

99-
@[simp] lemma lift_lie_apply (f : M →ₗ⁅R,L⁆ N →ₗ[R] P) (m : M) (n : N) :
100+
@[simp] lemma coe_lift_lie_eq_lift_coe (f : M →ₗ⁅R,L⁆ N →ₗ[R] P) :
101+
⇑(lift_lie R L M N P f) = lift R L M N P f :=
102+
begin
103+
suffices : (lift_lie R L M N P f : M ⊗[R] N →ₗ[R] P) = lift R L M N P f,
104+
{ rw [← this, lie_module_hom.coe_to_linear_map], },
105+
ext m n,
106+
simp only [lift_lie, linear_equiv.trans_apply, lie_module_equiv.coe_to_linear_equiv,
107+
coe_linear_map_maximal_trivial_linear_map_equiv_lie_module_hom, coe_maximal_trivial_equiv_apply,
108+
coe_linear_map_maximal_trivial_linear_map_equiv_lie_module_hom_symm],
109+
end
110+
111+
lemma lift_lie_apply (f : M →ₗ⁅R,L⁆ N →ₗ[R] P) (m : M) (n : N) :
100112
lift_lie R L M N P f (m ⊗ₜ n) = f m n :=
101-
by simp only [lift_lie, linear_equiv.trans_apply, lie_module_hom.coe_to_linear_map,
102-
coe_maximal_trivial_linear_map_equiv_lie_module_hom,
103-
lie_module_equiv.coe_to_linear_equiv, coe_fn_coe_base,
104-
coe_maximal_trivial_linear_map_equiv_lie_module_hom_symm_apply,
105-
coe_maximal_trivial_equiv_apply, lift_apply]
113+
by simp only [coe_lift_lie_eq_lift_coe, lie_module_hom.coe_to_linear_map, lift_apply]
114+
115+
variables {R L M N P Q}
116+
117+
/-- A pair of Lie module morphisms `f : M → P` and `g : N → Q`, induce a Lie module morphism:
118+
`M ⊗ N → P ⊗ Q`. -/
119+
def map (f : M →ₗ⁅R,L⁆ P) (g : N →ₗ⁅R,L⁆ Q) : M ⊗[R] N →ₗ⁅R,L⁆ P ⊗[R] Q :=
120+
{ map_lie' := λ x t, by
121+
{ simp only [linear_map.to_fun_eq_coe],
122+
apply t.induction_on,
123+
{ simp only [linear_map.map_zero, lie_zero], },
124+
{ intros m n, simp only [lie_module_hom.coe_to_linear_map, lie_tmul_right,
125+
lie_module_hom.map_lie, map_tmul, linear_map.map_add], },
126+
{ intros t₁ t₂ ht₁ ht₂, simp only [ht₁, ht₂, lie_add, linear_map.map_add], }, },
127+
.. map (f : M →ₗ[R] P) (g : N →ₗ[R] Q), }
128+
129+
@[simp] lemma coe_linear_map_map (f : M →ₗ⁅R,L⁆ P) (g : N →ₗ⁅R,L⁆ Q) :
130+
(map f g : M ⊗[R] N →ₗ[R] P ⊗[R] Q) = tensor_product.map (f : M →ₗ[R] P) (g : N →ₗ[R] Q) :=
131+
rfl
132+
133+
@[simp] lemma map_tmul (f : M →ₗ⁅R,L⁆ P) (g : N →ₗ⁅R,L⁆ Q) (m : M) (n : N) :
134+
map f g (m ⊗ₜ n) = (f m) ⊗ₜ (g n) :=
135+
map_tmul f g m n
136+
137+
/-- Given Lie submodules `M' ⊆ M` and `N' ⊆ N`, this is the natural map: `M' ⊗ N' → M ⊗ N`. -/
138+
def map_incl (M' : lie_submodule R L M) (N' : lie_submodule R L N) :
139+
M' ⊗[R] N' →ₗ⁅R,L⁆ M ⊗[R] N :=
140+
map M'.incl N'.incl
141+
142+
@[simp] lemma map_incl_def (M' : lie_submodule R L M) (N' : lie_submodule R L N) :
143+
map_incl M' N' = map M'.incl N'.incl :=
144+
rfl
106145

107146
end lie_module
108147

109148
end tensor_product
149+
150+
namespace lie_module
151+
152+
open_locale tensor_product
153+
154+
variables (R) (L : Type v) (M : Type w)
155+
variables [lie_ring L] [lie_algebra R L]
156+
variables [add_comm_group M] [module R M] [lie_ring_module L M] [lie_module R L M]
157+
158+
/-- The action of the Lie algebra on one of its modules, regarded as a morphism of Lie modules. -/
159+
def to_module_hom : L ⊗[R] M →ₗ⁅R,L⁆ M :=
160+
tensor_product.lie_module.lift_lie R L L M M
161+
{ map_lie' := λ x m, by { ext n, simp [lie_ring.of_associative_ring_bracket], },
162+
..(to_endomorphism R L M : L →ₗ[R] M →ₗ[R] M), }
163+
164+
@[simp] lemma to_module_hom_apply (x : L) (m : M) :
165+
to_module_hom R L M (x ⊗ₜ m) = ⁅x, m⁆ :=
166+
by simp only [to_module_hom, tensor_product.lie_module.lift_lie_apply, to_endomorphism_apply_apply,
167+
lie_hom.coe_to_linear_map, lie_module_hom.coe_mk, linear_map.to_fun_eq_coe]
168+
169+
end lie_module
170+
171+
namespace lie_submodule
172+
173+
open_locale tensor_product
174+
175+
open tensor_product.lie_module
176+
open lie_module
177+
178+
variables {L : Type v} {M : Type w}
179+
variables [lie_ring L] [lie_algebra R L]
180+
variables [add_comm_group M] [module R M] [lie_ring_module L M] [lie_module R L M]
181+
variables (I : lie_ideal R L) (N : lie_submodule R L M)
182+
183+
/-- A useful alternative characterisation of Lie ideal operations on Lie submodules.
184+
185+
Given a Lie ideal `I ⊆ L` and a Lie submodule `N ⊆ M`, by tensoring the inclusion maps and then
186+
applying the action of `L` on `M`, we obtain morphism of Lie modules `f : I ⊗ N → L ⊗ M → M`.
187+
188+
This lemma states that `⁅I, N⁆ = range f`. -/
189+
lemma lie_ideal_oper_eq_tensor_map_range :
190+
⁅I, N⁆ = ((to_module_hom R L M).comp (map_incl I N : ↥I ⊗ ↥N →ₗ⁅R,L⁆ L ⊗ M)).range :=
191+
begin
192+
rw [← coe_to_submodule_eq_iff, lie_ideal_oper_eq_linear_span, lie_module_hom.coe_submodule_range,
193+
lie_module_hom.coe_linear_map_comp, linear_map.range_comp, map_incl_def, coe_linear_map_map,
194+
tensor_product.map_range_eq_span_tmul, submodule.map_span],
195+
congr, ext m, split,
196+
{ rintros ⟨⟨x, hx⟩, ⟨n, hn⟩, rfl⟩, use x ⊗ₜ n, split,
197+
{ use [⟨x, hx⟩, ⟨n, hn⟩], simp, },
198+
{ simp, }, },
199+
{ rintros ⟨t, ⟨⟨x, hx⟩, ⟨n, hn⟩, rfl⟩, h⟩, rw ← h, use [⟨x, hx⟩, ⟨n, hn⟩], simp, },
200+
end
201+
202+
end lie_submodule

src/field_theory/subfield.lean

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -286,13 +286,10 @@ variables (g : L →+* M) (f : K →+* L)
286286

287287
/-! # range -/
288288

289-
/-- The range of a ring homomorphism, as a subfield of the target. -/
289+
/-- The range of a ring homomorphism, as a subfield of the target. See Note [range copy pattern]. -/
290290
def field_range : subfield L :=
291291
((⊤ : subfield K).map f).copy (set.range f) set.image_univ.symm
292292

293-
/-- Note that `ring_hom.field_range` is deliberately defined in a way that makes this true by `rfl`,
294-
as this means the types `↥(set.range f)` and `↥f.field_range` are interchangeable without proof
295-
obligations. -/
296293
@[simp] lemma coe_field_range : (f.field_range : set L) = set.range f := rfl
297294

298295
@[simp] lemma mem_field_range {f : K →+* L} {y : L} : y ∈ f.field_range ↔ ∃ x, f x = y := iff.rfl

src/group_theory/submonoid/operations.lean

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -512,24 +512,47 @@ namespace monoid_hom
512512

513513
open submonoid
514514

515-
/-- The range of a monoid homomorphism is a submonoid. -/
515+
/-- For many categories (monoids, modules, rings, ...) the set-theoretic image of a morphism `f` is
516+
a subobject of the codomain. When this is the case, it is useful to define the range of a morphism
517+
in such a way that the underlying carrier set of the range subobject is definitionally
518+
`set.range f`. In particular this means that the types `↥(set.range f)` and `↥f.range` are
519+
interchangeable without proof obligations.
520+
521+
A convenient candidate definition for range which is mathematically correct is `map ⊤ f`, just as
522+
`set.range` could have been defined as `f '' set.univ`. However, this lacks the desired definitional
523+
convenience, in that it both does not match `set.range`, and that it introduces a redudant `x ∈ ⊤`
524+
term which clutters proofs. In such a case one may resort to the `copy`
525+
pattern. A `copy` function converts the definitional problem for the carrier set of a subobject
526+
into a one-off propositional proof obligation which one discharges while writing the definition of
527+
the definitionally convenient range (the parameter `hs` in the example below).
528+
529+
A good example is the case of a morphism of monoids. A convenient definition for
530+
`monoid_hom.mrange` would be `(⊤ : submonoid M).map f`. However since this lacks the required
531+
definitional convenience, we first define `submonoid.copy` as follows:
532+
```lean
533+
protected def copy (S : submonoid M) (s : set M) (hs : s = S) : submonoid M :=
534+
{ carrier := s,
535+
one_mem' := hs.symm ▸ S.one_mem',
536+
mul_mem' := hs.symm ▸ S.mul_mem' }
537+
```
538+
and then finally define:
539+
```lean
540+
def mrange (f : M →* N) : submonoid N :=
541+
((⊤ : submonoid M).map f).copy (set.range f) set.image_univ.symm
542+
```
543+
-/
544+
library_note "range copy pattern"
545+
546+
/-- The range of a monoid homomorphism is a submonoid. See Note [range copy pattern]. -/
516547
@[to_additive "The range of an `add_monoid_hom` is an `add_submonoid`."]
517548
def mrange (f : M →* N) : submonoid N :=
518549
((⊤ : submonoid M).map f).copy (set.range f) set.image_univ.symm
519550

520-
/-- Note that `monoid_hom.mrange` is deliberately defined in a way that makes this true by `rfl`,
521-
as this means the types `↥(set.range f)` and `↥f.mrange` are interchangeable without proof
522-
obligations. -/
523551
@[simp, to_additive]
524552
lemma coe_mrange (f : M →* N) :
525553
(f.mrange : set N) = set.range f :=
526554
rfl
527555

528-
/-- Note that `add_monoid_hom.mrange` is deliberately defined in a way that makes this true by
529-
`rfl`, as this means the types `↥(set.range f)` and `↥f.mrange` are interchangeable without proof
530-
obligations. -/
531-
add_decl_doc add_monoid_hom.coe_mrange
532-
533556
@[simp, to_additive] lemma mem_mrange {f : M →* N} {y : N} :
534557
y ∈ f.mrange ↔ ∃ x, f x = y :=
535558
iff.rfl

src/linear_algebra/basic.lean

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,13 +1378,10 @@ theorem comap_cod_restrict (p : submodule R M) (f : M₂ →ₗ[R] M) (hf p') :
13781378
submodule.comap (cod_restrict p f hf) p' = submodule.comap f (map p.subtype p') :=
13791379
submodule.ext $ λ x, ⟨λ h, ⟨⟨_, hf x⟩, h, rfl⟩, by rintro ⟨⟨_, _⟩, h, ⟨⟩⟩; exact h⟩
13801380

1381-
/-- The range of a linear map `f : M → M₂` is a submodule of `M₂`. -/
1381+
/-- The range of a linear map `f : M → M₂` is a submodule of `M₂`. See Note [range copy pattern]. -/
13821382
def range (f : M →ₗ[R] M₂) : submodule R M₂ :=
13831383
(map f ⊤).copy (set.range f) set.image_univ.symm
13841384

1385-
/-- Note that `linear_map.range` is deliberately defined in a way that makes this true by `rfl`,
1386-
as this means the types `↥(set.range f)` and `↥f.mrange` are interchangeable without proof
1387-
obligations. -/
13881385
theorem range_coe (f : M →ₗ[R] M₂) : (range f : set M₂) = set.range f := rfl
13891386

13901387
@[simp] theorem mem_range {f : M →ₗ[R] M₂} {x} : x ∈ range f ↔ ∃ y, f y = x :=

0 commit comments

Comments
 (0)