11/-
22Copyright (c) 2020 Scott Morrison. All rights reserved.
33Released under Apache 2.0 license as described in the file LICENSE.
4- Authors: Scott Morrison, Johan Commelin
4+ Authors: Scott Morrison, Johan Commelin, Eric Wieser
55-/
66import Mathlib.LinearAlgebra.TensorProduct
77import Mathlib.Algebra.Algebra.Tower
@@ -14,8 +14,11 @@ import Mathlib.Algebra.Algebra.Tower
1414When `M` is both an `R`-module and an `A`-module, and `Algebra R A`, then many of the morphisms
1515preserve the actions by `A`.
1616
17- This file provides more general versions of the definitions already in
18- `LinearAlgebra/TensorProduct`.
17+ The `Module` instance itself is provided elsewhere as `TensorProduct.leftModule`. This file provides
18+ more general versions of the definitions already in `LinearAlgebra/TensorProduct`.
19+
20+ In this file, we use the convention that `M`, `N`, `P`, `Q` are all `R`-modules, but only `M` and
21+ `P` are simultaneously `A`-modules.
1922
2023## Main definitions
2124
@@ -25,7 +28,14 @@ This file provides more general versions of the definitions already in
2528 * `TensorProduct.AlgebraTensorModule.lift`
2629 * `TensorProduct.AlgebraTensorModule.lift.equiv`
2730 * `TensorProduct.AlgebraTensorModule.mk`
31+ * `TensorProduct.AlgebraTensorModule.map`
32+ * `TensorProduct.AlgebraTensorModule.mapBilinear`
33+ * `TensorProduct.AlgebraTensorModule.congr`
34+ * `TensorProduct.AlgebraTensorModule.homTensorHomMap`
2835 * `TensorProduct.AlgebraTensorModule.assoc`
36+ * `TensorProduct.AlgebraTensorModule.leftComm`
37+ * `TensorProduct.AlgebraTensorModule.rightComm`
38+ * `TensorProduct.AlgebraTensorModule.tensorTensorTensorComm`
2939
3040 ## Implementation notes
3141
@@ -38,20 +48,26 @@ namespace TensorProduct
3848
3949namespace AlgebraTensorModule
4050
41- variable {R A M N P : Type _}
51+ universe uR uA uB uM uN uP uQ
52+ variable {R : Type uR} {A : Type uA} {B : Type uB}
53+ variable {M : Type uM} {N : Type uN} {P : Type uP} {Q : Type uQ}
4254
4355open LinearMap
4456open Algebra (lsmul)
4557
4658section Semiring
4759
48- variable [CommSemiring R] [Semiring A] [Algebra R A]
60+ variable [CommSemiring R] [Semiring A] [Semiring B] [ Algebra R A] [Algebra R B ]
4961
50- variable [AddCommMonoid M] [Module R M] [Module A M] [IsScalarTower R A M]
62+ variable [AddCommMonoid M] [Module R M] [Module A M] [Module B M]
63+ variable [IsScalarTower R A M] [IsScalarTower R B M] [SMulCommClass A B M]
5164
5265variable [AddCommMonoid N] [Module R N]
5366
54- variable [AddCommMonoid P] [Module R P] [Module A P] [IsScalarTower R A P]
67+ variable [AddCommMonoid P] [Module R P] [Module A P] [Module B P]
68+ variable [IsScalarTower R A P] [IsScalarTower R B P] [SMulCommClass A B P]
69+
70+ variable [AddCommMonoid Q] [Module R Q]
5571
5672theorem smul_eq_lsmul_rTensor (a : A) (x : M ⊗[R] N) : a • x = (lsmul R R M a).rTensor N x :=
5773 rfl
@@ -89,18 +105,6 @@ theorem ext {g h : M ⊗[R] N →ₗ[A] P} (H : ∀ x y, g (x ⊗ₜ y) = h (x
89105 curry_injective <| LinearMap.ext₂ H
90106#align tensor_product.algebra_tensor_module.ext TensorProduct.AlgebraTensorModule.ext
91107
92- end Semiring
93-
94- section CommSemiring
95-
96- variable [CommSemiring R] [CommSemiring A] [Algebra R A]
97-
98- variable [AddCommMonoid M] [Module R M] [Module A M] [IsScalarTower R A M]
99-
100- variable [AddCommMonoid N] [Module R N]
101-
102- variable [AddCommMonoid P] [Module R P] [Module A P] [IsScalarTower R A P]
103-
104108/-- Heterobasic version of `TensorProduct.lift`:
105109
106110Constructing a linear map `M ⊗[R] N →[A] P` given a bilinear map `M →[A] N →[R] P` with the
@@ -131,41 +135,44 @@ theorem lift_tmul (f : M →ₗ[A] N →ₗ[R] P) (x : M) (y : N) : lift f (x
131135 rfl
132136#align tensor_product.algebra_tensor_module.lift_tmul TensorProduct.AlgebraTensorModule.lift_tmul
133137
134- variable (R A M N P)
138+ variable (R A B M N P Q )
135139
136140/-- Heterobasic version of `TensorProduct.uncurry`:
137141
138142Linearly constructing a linear map `M ⊗[R] N →[A] P` given a bilinear map `M →[A] N →[R] P`
139143with the property that its composition with the canonical bilinear map `M →[A] N →[R] M ⊗[R] N` is
140144the given bilinear map `M →[A] N →[R] P`. -/
141145@[simps]
142- def uncurry : (M →ₗ[A] N →ₗ[R] P) →ₗ[A ] M ⊗[R] N →ₗ[A] P where
146+ def uncurry : (M →ₗ[A] N →ₗ[R] P) →ₗ[B ] M ⊗[R] N →ₗ[A] P where
143147 toFun := lift
144148 map_add' _ _ := ext fun x y => by simp only [lift_tmul, add_apply]
145149 map_smul' _ _ := ext fun x y => by simp only [lift_tmul, smul_apply, RingHom.id_apply]
146- #align tensor_product.algebra_tensor_module.uncurry TensorProduct.AlgebraTensorModule.uncurry
150+ -- porting note: new `B` argument
151+ #align tensor_product.algebra_tensor_module.uncurry TensorProduct.AlgebraTensorModule.uncurryₓ
147152
148153/-- Heterobasic version of `TensorProduct.lcurry`:
149154
150155Given a linear map `M ⊗[R] N →[A] P`, compose it with the canonical
151156bilinear map `M →[A] N →[R] M ⊗[R] N` to form a bilinear map `M →[A] N →[R] P`. -/
152157@[simps]
153- def lcurry : (M ⊗[R] N →ₗ[A] P) →ₗ[A ] M →ₗ[A] N →ₗ[R] P where
158+ def lcurry : (M ⊗[R] N →ₗ[A] P) →ₗ[B ] M →ₗ[A] N →ₗ[R] P where
154159 toFun := curry
155160 map_add' _ _ := rfl
156161 map_smul' _ _ := rfl
157- #align tensor_product.algebra_tensor_module.lcurry TensorProduct.AlgebraTensorModule.lcurry
162+ -- porting note: new `B` argument
163+ #align tensor_product.algebra_tensor_module.lcurry TensorProduct.AlgebraTensorModule.lcurryₓ
158164
159165/-- Heterobasic version of `TensorProduct.lift.equiv`:
160166
161167A linear equivalence constructing a linear map `M ⊗[R] N →[A] P` given a
162168bilinear map `M →[A] N →[R] P` with the property that its composition with the
163169canonical bilinear map `M →[A] N →[R] M ⊗[R] N` is the given bilinear map `M →[A] N →[R] P`. -/
164- def lift.equiv : (M →ₗ[A] N →ₗ[R] P) ≃ₗ[A ] M ⊗[R] N →ₗ[A] P :=
165- LinearEquiv.ofLinear (uncurry R A M N P) (lcurry R A M N P)
170+ def lift.equiv : (M →ₗ[A] N →ₗ[R] P) ≃ₗ[B ] M ⊗[R] N →ₗ[A] P :=
171+ LinearEquiv.ofLinear (uncurry R A B M N P) (lcurry R A B M N P)
166172 (LinearMap.ext fun _ => ext fun x y => lift_tmul _ x y)
167173 (LinearMap.ext fun f => LinearMap.ext fun x => LinearMap.ext fun y => lift_tmul f x y)
168- #align tensor_product.algebra_tensor_module.lift.equiv TensorProduct.AlgebraTensorModule.lift.equiv
174+ -- porting note: new `B` argument
175+ #align tensor_product.algebra_tensor_module.lift.equiv TensorProduct.AlgebraTensorModule.lift.equivₓ
169176
170177/-- Heterobasic version of `TensorProduct.mk`:
171178
@@ -176,27 +183,208 @@ nonrec def mk : M →ₗ[A] N →ₗ[R] M ⊗[R] N :=
176183#align tensor_product.algebra_tensor_module.mk TensorProduct.AlgebraTensorModule.mk
177184#align tensor_product.algebra_tensor_module.mk_apply TensorProduct.AlgebraTensorModule.mk_apply
178185
186+ variable {R A B M N P Q}
187+
188+ /-- Heterobasic version of `TensorProduct.map` -/
189+ def map (f : M →ₗ[A] P) (g : N →ₗ[R] Q) : M ⊗[R] N →ₗ[A] P ⊗[R] Q :=
190+ lift <|
191+ { toFun := fun h => h ∘ₗ g,
192+ map_add' := fun h₁ h₂ => LinearMap.add_comp g h₂ h₁,
193+ map_smul' := fun c h => LinearMap.smul_comp c h g } ∘ₗ mk R A P Q ∘ₗ f
194+
195+ @[simp] theorem map_tmul (f : M →ₗ[A] P) (g : N →ₗ[R] Q) (m : M) (n : N) :
196+ map f g (m ⊗ₜ n) = f m ⊗ₜ g n :=
197+ rfl
198+
199+ theorem map_add_left (f₁ f₂ : M →ₗ[A] P) (g : N →ₗ[R] Q) :
200+ map (f₁ + f₂) g = map f₁ g + map f₂ g := by
201+ ext
202+ simp_rw [curry_apply, TensorProduct.curry_apply, restrictScalars_apply, add_apply, map_tmul,
203+ add_apply, add_tmul]
204+
205+ theorem map_add_right (f : M →ₗ[A] P) (g₁ g₂ : N →ₗ[R] Q) :
206+ map f (g₁ + g₂) = map f g₁ + map f g₂ := by
207+ ext
208+ simp_rw [curry_apply, TensorProduct.curry_apply, restrictScalars_apply, add_apply, map_tmul,
209+ add_apply, tmul_add]
210+
211+ theorem map_smul_right (r : R) (f : M →ₗ[A] P) (g : N →ₗ[R] Q) : map f (r • g) = r • map f g := by
212+ ext
213+ simp_rw [curry_apply, TensorProduct.curry_apply, restrictScalars_apply, smul_apply, map_tmul,
214+ smul_apply, tmul_smul]
215+
216+ theorem map_smul_left (b : B) (f : M →ₗ[A] P) (g : N →ₗ[R] Q) : map (b • f) g = b • map f g := by
217+ ext
218+ simp_rw [curry_apply, TensorProduct.curry_apply, restrictScalars_apply, smul_apply, map_tmul,
219+ smul_apply, smul_tmul']
220+
221+ variable (R A B M N P Q)
222+
223+ /-- Heterobasic version of `TensorProduct.map_bilinear` -/
224+ def mapBilinear : (M →ₗ[A] P) →ₗ[B] (N →ₗ[R] Q) →ₗ[R] (M ⊗[R] N →ₗ[A] P ⊗[R] Q) :=
225+ LinearMap.mk₂' _ _ map map_add_left map_smul_left map_add_right map_smul_right
226+
227+ variable {R A B M N P Q}
228+
229+ @[simp]
230+ theorem mapBilinear_apply (f : M →ₗ[A] P) (g : N →ₗ[R] Q) :
231+ mapBilinear R A B M N P Q f g = map f g :=
232+ rfl
233+
234+ variable (R A B M N P Q)
235+
236+ /-- Heterobasic version of `TensorProduct.homTensorHomMap` -/
237+ def homTensorHomMap : ((M →ₗ[A] P) ⊗[R] (N →ₗ[R] Q)) →ₗ[B] (M ⊗[R] N →ₗ[A] P ⊗[R] Q) :=
238+ lift <| mapBilinear R A B M N P Q
239+
240+ variable {R A B M N P Q}
241+
242+ @[simp] theorem homTensorHomMap_apply (f : M →ₗ[A] P) (g : N →ₗ[R] Q) :
243+ homTensorHomMap R A B M N P Q (f ⊗ₜ g) = map f g :=
244+ rfl
245+
246+ /-- Heterobasic version of `TensorProduct.congr` -/
247+ def congr (f : M ≃ₗ[A] P) (g : N ≃ₗ[R] Q) : (M ⊗[R] N) ≃ₗ[A] (P ⊗[R] Q) :=
248+ LinearEquiv.ofLinear (map f g) (map f.symm g.symm)
249+ (ext fun _m _n => congr_arg₂ (· ⊗ₜ ·) (f.apply_symm_apply _) (g.apply_symm_apply _))
250+ (ext fun _m _n => congr_arg₂ (· ⊗ₜ ·) (f.symm_apply_apply _) (g.symm_apply_apply _))
251+
252+ @[simp] theorem congr_tmul (f : M ≃ₗ[A] P) (g : N ≃ₗ[R] Q) (m : M) (n : N) :
253+ congr f g (m ⊗ₜ n) = f m ⊗ₜ g n :=
254+ rfl
255+
256+ @[simp] theorem congr_symm_tmul (f : M ≃ₗ[A] P) (g : N ≃ₗ[R] Q) (p : P) (q : Q) :
257+ (congr f g).symm (p ⊗ₜ q) = f.symm p ⊗ₜ g.symm q :=
258+ rfl
259+
260+ end Semiring
261+
262+ section CommSemiring
263+
264+ variable [CommSemiring R] [CommSemiring A] [Semiring B] [Algebra R A] [Algebra R B]
265+
266+ variable [AddCommMonoid M] [Module R M] [Module A M] [Module B M]
267+ variable [IsScalarTower R A M] [IsScalarTower R B M] [SMulCommClass A B M]
268+
269+ variable [AddCommMonoid N] [Module R N]
270+
271+ variable [AddCommMonoid P] [Module R P] [Module A P] [Module B P]
272+ variable [IsScalarTower R A P] [IsScalarTower R B P] [SMulCommClass A B P]
273+
274+ variable [AddCommMonoid Q] [Module R Q]
275+
276+ variable (R A B M N P Q)
277+
179278attribute [local ext high] TensorProduct.ext
180279
280+ section assoc
281+ variable [Algebra A B] [IsScalarTower A B M]
282+
181283/-- Heterobasic version of `TensorProduct.assoc`:
182284
183- Linear equivalence between `(M ⊗[A] N) ⊗[R] P` and `M ⊗[A] (N ⊗[R] P)`. -/
184- def assoc : (M ⊗[A] P) ⊗[R] N ≃ₗ[A] M ⊗[A] P ⊗[R] N :=
285+ Linear equivalence between `(M ⊗[A] N) ⊗[R] P` and `M ⊗[A] (N ⊗[R] P)`.
286+
287+ Note this is especially useful with `A = R` (where it is a "more linear" version of
288+ `TensorProduct.assoc`), or with `B = A`. -/
289+ def assoc : (M ⊗[A] P) ⊗[R] Q ≃ₗ[B] M ⊗[A] (P ⊗[R] Q) :=
185290 LinearEquiv.ofLinear
186- (lift <|
187- TensorProduct.uncurry A _ _ _ <| comp (lcurry R A _ _ _) <| TensorProduct.mk A M (P ⊗[R] N))
188- (TensorProduct.uncurry A _ _ _ <|
189- comp (uncurry R A _ _ _) <| by
190- apply TensorProduct.curry
191- exact mk R A _ _)
192- (by
193- ext
194- rfl)
195- (by
196- ext
197- -- porting note: was `simp only [...]`
198- rfl)
199- #align tensor_product.algebra_tensor_module.assoc TensorProduct.AlgebraTensorModule.assoc
291+ (lift <| lift <| lcurry R A B P Q _ ∘ₗ mk A B M (P ⊗[R] Q))
292+ (lift <| uncurry R A B P Q _ ∘ₗ curry (mk R B _ Q))
293+ (by ext; rfl)
294+ (by ext; rfl)
295+ -- porting note: new `B` argument
296+ #align tensor_product.algebra_tensor_module.assoc TensorProduct.AlgebraTensorModule.assocₓ
297+
298+ variable {M P N Q}
299+
300+ @[simp]
301+ theorem assoc_tmul (m : M) (p : P) (q : Q) :
302+ assoc R A B M P Q ((m ⊗ₜ p) ⊗ₜ q) = m ⊗ₜ (p ⊗ₜ q) :=
303+ rfl
304+
305+ @[simp]
306+ theorem assoc_symm_tmul (m : M) (p : P) (q : Q) :
307+ (assoc R A B M P Q).symm (m ⊗ₜ (p ⊗ₜ q)) = (m ⊗ₜ p) ⊗ₜ q :=
308+ rfl
309+
310+ end assoc
311+
312+ section leftComm
313+
314+ /-- Heterobasic version of `TensorProduct.leftComm` -/
315+ def leftComm : M ⊗[A] (P ⊗[R] Q) ≃ₗ[A] P ⊗[A] (M ⊗[R] Q) :=
316+ let e₁ := (assoc R A A M P Q).symm
317+ let e₂ := congr (TensorProduct.comm A M P) (1 : Q ≃ₗ[R] Q)
318+ let e₃ := assoc R A A P M Q
319+ e₁ ≪≫ₗ e₂ ≪≫ₗ e₃
320+
321+ variable {M N P Q}
322+
323+ @[simp]
324+ theorem leftComm_tmul (m : M) (p : P) (q : Q) :
325+ leftComm R A M P Q (m ⊗ₜ (p ⊗ₜ q)) = p ⊗ₜ (m ⊗ₜ q) :=
326+ rfl
327+
328+ @[simp]
329+ theorem leftComm_symm_tmul (m : M) (p : P) (q : Q):
330+ (leftComm R A M P Q).symm (p ⊗ₜ (m ⊗ₜ q)) = m ⊗ₜ (p ⊗ₜ q) :=
331+ rfl
332+
333+ end leftComm
334+
335+ section rightComm
336+
337+ /-- A tensor product analogue of `mul_right_comm`. -/
338+ def rightComm : (M ⊗[A] P) ⊗[R] Q ≃ₗ[A] (M ⊗[R] Q) ⊗[A] P :=
339+ LinearEquiv.ofLinear
340+ (lift <| TensorProduct.lift <| LinearMap.flip <|
341+ lcurry R A A M Q ((M ⊗[R] Q) ⊗[A] P) ∘ₗ (mk A A (M ⊗[R] Q) P).flip)
342+ (TensorProduct.lift <| lift <| LinearMap.flip <|
343+ (TensorProduct.lcurry A M P ((M ⊗[A] P) ⊗[R] Q)).restrictScalars R
344+ ∘ₗ (mk R A (M ⊗[A] P) Q).flip)
345+ -- explicit `Eq.refl`s here help with performance, but also make it clear that the `ext` are
346+ -- letting us prove the result as an equality of pure tensors.
347+ (TensorProduct.ext <| ext <| fun m q => LinearMap.ext <| fun p => Eq.refl <|
348+ (m ⊗ₜ[R] q) ⊗ₜ[A] p)
349+ (curry_injective <| TensorProduct.ext' <| fun m p => LinearMap.ext <| fun q => Eq.refl <|
350+ (m ⊗ₜ[A] p) ⊗ₜ[R] q)
351+
352+ variable {M N P Q}
353+
354+ @[simp]
355+ theorem rightComm_tmul (m : M) (p : P) (q : Q) :
356+ rightComm R A M P Q ((m ⊗ₜ p) ⊗ₜ q) = (m ⊗ₜ q) ⊗ₜ p :=
357+ rfl
358+
359+ @[simp]
360+ theorem rightComm_symm_tmul (m : M) (p : P) (q : Q):
361+ (rightComm R A M P Q).symm ((m ⊗ₜ q) ⊗ₜ p) = (m ⊗ₜ p) ⊗ₜ q :=
362+ rfl
363+
364+ end rightComm
365+
366+ section tensorTensorTensorComm
367+
368+ /-- Heterobasic version of `tensorTensorTensorComm`. -/
369+ def tensorTensorTensorComm :
370+ (M ⊗[R] N) ⊗[A] (P ⊗[R] Q) ≃ₗ[A] (M ⊗[A] P) ⊗[R] (N ⊗[R] Q) :=
371+ (assoc R A A (M ⊗[R] N) P Q).symm
372+ ≪≫ₗ congr (rightComm R A M P N).symm (1 : Q ≃ₗ[R] Q)
373+ ≪≫ₗ assoc R _ _ (M ⊗[A] P) N Q
374+
375+ variable {M N P Q}
376+
377+ @[simp]
378+ theorem tensorTensorTensorComm_tmul (m : M) (n : N) (p : P) (q : Q) :
379+ tensorTensorTensorComm R A M N P Q ((m ⊗ₜ n) ⊗ₜ (p ⊗ₜ q)) = (m ⊗ₜ p) ⊗ₜ (n ⊗ₜ q) :=
380+ rfl
381+
382+ @[simp]
383+ theorem tensorTensorTensorComm_symm_tmul (m : M) (p : P) (q : Q):
384+ (tensorTensorTensorComm R A M N P Q).symm ((m ⊗ₜ p) ⊗ₜ (n ⊗ₜ q)) = (m ⊗ₜ n) ⊗ₜ (p ⊗ₜ q) :=
385+ rfl
386+
387+ end tensorTensorTensorComm
200388
201389end CommSemiring
202390
0 commit comments