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

Commit 20b49fb

Browse files
committed
feat(linear_algebra/tensor_product): allow different semirings in linear_map.flip (#6414)
This also means the `map_*₂` lemmas are more generally applicable to linear_maps over different rings, such as `linear_map.prod_equiv.to_linear_map`. To avoid breakage, this leaves `mk₂ R` for when R is commutative, and introduces `mk₂' R S` for when two different rings are wanted.
1 parent 47b62ea commit 20b49fb

File tree

1 file changed

+75
-38
lines changed

1 file changed

+75
-38
lines changed

src/linear_algebra/tensor_product.lean

Lines changed: 75 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -34,77 +34,112 @@ bilinear, tensor, tensor product
3434

3535
namespace linear_map
3636

37-
variables {R : Type*} [comm_semiring R]
38-
variables {M : Type*} {N : Type*} {P : Type*} {Q : Type*} {S : Type*}
37+
section semiring
3938

40-
variables [add_comm_monoid M] [add_comm_monoid N] [add_comm_monoid P] [add_comm_monoid Q]
41-
[add_comm_monoid S]
42-
variables [semimodule R M] [semimodule R N] [semimodule R P] [semimodule R Q] [semimodule R S]
39+
variables {R : Type*} [semiring R] {S : Type*} [semiring S]
40+
variables {M : Type*} {N : Type*} {P : Type*}
41+
variables {M' : Type*} {N' : Type*} {P' : Type*}
42+
43+
variables [add_comm_monoid M] [add_comm_monoid N] [add_comm_monoid P]
44+
variables [add_comm_group M'] [add_comm_group N'] [add_comm_group P']
45+
variables [semimodule R M] [semimodule S N] [semimodule R P] [semimodule S P]
46+
variables [semimodule R M'] [semimodule S N'] [semimodule R P'] [semimodule S P']
47+
variables [smul_comm_class S R P] [smul_comm_class S R P']
4348
include R
4449

45-
variables (R)
46-
/-- Create a bilinear map from a function that is linear in each component. -/
47-
def mk₂ (f : M → N → P)
50+
variables (R S)
51+
/-- Create a bilinear map from a function that is linear in each component.
52+
See `mk₂` for the special case where both arguments come from modules over the same ring. -/
53+
def mk₂' (f : M → N → P)
4854
(H1 : ∀ m₁ m₂ n, f (m₁ + m₂) n = f m₁ n + f m₂ n)
4955
(H2 : ∀ (c:R) m n, f (c • m) n = c • f m n)
5056
(H3 : ∀ m n₁ n₂, f m (n₁ + n₂) = f m n₁ + f m n₂)
51-
(H4 : ∀ (c:R) m n, f m (c • n) = c • f m n) : M →ₗ N →ₗ P :=
57+
(H4 : ∀ (c:S) m n, f m (c • n) = c • f m n) : M →ₗ[R] N →ₗ[S] P :=
5258
⟨λ m, ⟨f m, H3 m, λ c, H4 c m⟩,
5359
λ m₁ m₂, linear_map.ext $ H1 m₁ m₂,
5460
λ c m, linear_map.ext $ H2 c m⟩
55-
variables {R}
61+
variables {R S}
5662

57-
@[simp] theorem mk₂_apply
63+
@[simp] theorem mk₂'_apply
5864
(f : M → N → P) {H1 H2 H3 H4} (m : M) (n : N) :
59-
(mk₂ R f H1 H2 H3 H4 : M →ₗ[R] N →ₗ P) m n = f m n := rfl
65+
(mk₂' R S f H1 H2 H3 H4 : M →ₗ[R] N →ₗ[S] P) m n = f m n := rfl
6066

61-
theorem ext₂ {f g : M →ₗ[R] N →ₗ[R] P}
67+
theorem ext₂ {f g : M →ₗ[R] N →ₗ[S] P}
6268
(H : ∀ m n, f m n = g m n) : f = g :=
6369
linear_map.ext (λ m, linear_map.ext $ λ n, H m n)
6470

71+
section
72+
73+
local attribute [instance] smul_comm_class.symm
74+
6575
/-- Given a linear map from `M` to linear maps from `N` to `P`, i.e., a bilinear map from `M × N` to
6676
`P`, change the order of variables and get a linear map from `N` to linear maps from `M` to `P`. -/
67-
def flip (f : M →ₗ[R] N →ₗ[R] P) : N →ₗ M →ₗ P :=
68-
mk₂ R (λ n m, f m n)
77+
def flip (f : M →ₗ[R] N →ₗ[S] P) : N →ₗ[S] M →ₗ[R] P :=
78+
mk₂' S R (λ n m, f m n)
6979
(λ n₁ n₂ m, (f m).map_add _ _)
7080
(λ c n m, (f m).map_smul _ _)
7181
(λ n m₁ m₂, by rw f.map_add; refl)
7282
(λ c n m, by rw f.map_smul; refl)
7383

74-
variable (f : M →ₗ[R] N →ₗ[R] P)
84+
end
7585

76-
@[simp] theorem flip_apply (m : M) (n : N) : flip f n m = f m n := rfl
86+
@[simp] theorem flip_apply (f : M →ₗ[R] N →ₗ[S] P) (m : M) (n : N) : flip f n m = f m n := rfl
7787

7888
variables {R}
79-
theorem flip_inj {f g : M →ₗ[R] N →ₗ P} (H : flip f = flip g) : f = g :=
89+
theorem flip_inj {f g : M →ₗ[R] N →ₗ[S] P} (H : flip f = flip g) : f = g :=
8090
ext₂ $ λ m n, show flip f n m = flip g n m, by rw H
8191

92+
theorem map_zero₂ (f : M →ₗ[R] N →ₗ[S] P) (y) : f 0 y = 0 :=
93+
(flip f y).map_zero
94+
95+
theorem map_neg₂ (f : M' →ₗ[R] N →ₗ[S] P') (x y) : f (-x) y = -f x y :=
96+
(flip f y).map_neg _
97+
98+
theorem map_sub₂ (f : M' →ₗ[R] N →ₗ[S] P') (x y z) : f (x - y) z = f x z - f y z :=
99+
(flip f z).map_sub _ _
100+
101+
theorem map_add₂ (f : M →ₗ[R] N →ₗ[S] P) (x₁ x₂ y) : f (x₁ + x₂) y = f x₁ y + f x₂ y :=
102+
(flip f y).map_add _ _
103+
104+
theorem map_smul₂ (f : M →ₗ[R] N →ₗ[S] P) (r : R) (x y) : f (r • x) y = r • f x y :=
105+
(flip f y).map_smul _ _
106+
107+
end semiring
108+
109+
section comm_semiring
110+
111+
variables {R : Type*} [comm_semiring R]
112+
variables {M : Type*} {N : Type*} {P : Type*} {Q : Type*}
113+
114+
variables [add_comm_monoid M] [add_comm_monoid N] [add_comm_monoid P] [add_comm_monoid Q]
115+
variables [semimodule R M] [semimodule R N] [semimodule R P] [semimodule R Q]
116+
117+
variables (R)
118+
119+
/-- Create a bilinear map from a function that is linear in each component.
120+
121+
This is a shorthand for `mk₂'` for the common case when `R = S`. -/
122+
def mk₂ (f : M → N → P)
123+
(H1 : ∀ m₁ m₂ n, f (m₁ + m₂) n = f m₁ n + f m₂ n)
124+
(H2 : ∀ (c:R) m n, f (c • m) n = c • f m n)
125+
(H3 : ∀ m n₁ n₂, f m (n₁ + n₂) = f m n₁ + f m n₂)
126+
(H4 : ∀ (c:R) m n, f m (c • n) = c • f m n) : M →ₗ[R] N →ₗ[R] P :=
127+
mk₂' R R f H1 H2 H3 H4
128+
129+
@[simp] theorem mk₂_apply
130+
(f : M → N → P) {H1 H2 H3 H4} (m : M) (n : N) :
131+
(mk₂ R f H1 H2 H3 H4 : M →ₗ[R] N →ₗ[R] P) m n = f m n := rfl
132+
82133
variables (R M N P)
83134
/-- Given a linear map from `M` to linear maps from `N` to `P`, i.e., a bilinear map `M → N → P`,
84135
change the order of variables and get a linear map from `N` to linear maps from `M` to `P`. -/
85-
def lflip : (M →ₗ[R] N →ₗ P) →ₗ[R] N →ₗ M →ₗ P :=
136+
def lflip : (M →ₗ[R] N →ₗ[R] P) →ₗ[R] N →ₗ[R] M →ₗ[R] P :=
86137
⟨flip, λ _ _, rfl, λ _ _, rfl⟩
87138
variables {R M N P}
88139

89-
@[simp] theorem lflip_apply (m : M) (n : N) : lflip R M N P f n m = f m n := rfl
90-
91-
theorem map_zero₂ (y) : f 0 y = 0 := (flip f y).map_zero
92-
93-
theorem map_neg₂ {R : Type*} [comm_semiring R] {M N P : Type*}
94-
[add_comm_group M] [add_comm_monoid N] [add_comm_group P]
95-
[semimodule R M] [semimodule R N] [semimodule R P] (f : M →ₗ[R] N →ₗ[R] P) (x y) :
96-
f (-x) y = -f x y :=
97-
(flip f y).map_neg _
98-
99-
theorem map_sub₂ {R : Type*} [comm_semiring R] {M N P : Type*}
100-
[add_comm_group M] [add_comm_monoid N] [add_comm_group P]
101-
[semimodule R M] [semimodule R N] [semimodule R P] (f : M →ₗ[R] N →ₗ[R] P) (x y z) :
102-
f (x - y) z = f x z - f y z :=
103-
(flip f z).map_sub _ _
104-
105-
theorem map_add₂ (x₁ x₂ y) : f (x₁ + x₂) y = f x₁ y + f x₂ y := (flip f y).map_add _ _
140+
variables (f : M →ₗ[R] N →ₗ[R] P)
106141

107-
theorem map_smul₂ (r:R) (x y) : f (r • x) y = r • f x y := (flip f y).map_smul _ _
142+
@[simp] theorem lflip_apply (m : M) (n : N) : lflip R M N P f n m = f m n := rfl
108143

109144
variables (R P)
110145
/-- Composing a linear map `M → N` and a linear map `N → P` to form a linear map `M → P`. -/
@@ -121,7 +156,7 @@ variables (R M N P)
121156
def llcomp : (N →ₗ[R] P) →ₗ[R] (M →ₗ[R] N) →ₗ M →ₗ P :=
122157
flip ⟨lcomp R P,
123158
λ f f', ext₂ $ λ g x, g.map_add _ _,
124-
λ c f, ext₂ $ λ g x, g.map_smul _ _⟩
159+
λ (c : R) f, ext₂ $ λ g x, g.map_smul _ _⟩
125160
variables {R M N P}
126161

127162
section
@@ -153,6 +188,8 @@ variables {R M}
153188

154189
@[simp] theorem lsmul_apply (r : R) (m : M) : lsmul R M r m = r • m := rfl
155190

191+
end comm_semiring
192+
156193
end linear_map
157194

158195
section semiring

0 commit comments

Comments
 (0)