diff --git a/src/sage/categories/tensor.py b/src/sage/categories/tensor.py index 01208e6217e..c36eb11a5ff 100644 --- a/src/sage/categories/tensor.py +++ b/src/sage/categories/tensor.py @@ -13,10 +13,11 @@ # **************************************************************************** from sage.categories.covariant_functorial_construction import CovariantFunctorialConstruction, CovariantConstructionCategory +from sage.categories.pushout import MultivariateConstructionFunctor from sage.typeset.unicode_characters import unicode_otimes -class TensorProductFunctor(CovariantFunctorialConstruction): +class TensorProductFunctor(CovariantFunctorialConstruction, MultivariateConstructionFunctor): """ A singleton class for the tensor functor. @@ -51,7 +52,24 @@ class TensorProductFunctor(CovariantFunctorialConstruction): _functor_category = "TensorProducts" symbol = " # " unicode_symbol = f" {unicode_otimes} " + def __init__(self, category=None): + r""" + Constructor. See :class:`TensorProductFunctor` for details. + TESTS:: + + sage: from sage.categories.tensor import TensorProductFunctor + sage: TensorProductFunctor() + The tensor functorial construction + """ + CovariantFunctorialConstruction.__init__(self) + self._forced_category = category + from sage.categories.rings import Rings + if self._forced_category is not None: + codomain = self._forced_category + else: + codomain = Rings() + MultivariateConstructionFunctor.__init__(self, Rings(), codomain) tensor = TensorProductFunctor() diff --git a/src/sage/combinat/free_module.py b/src/sage/combinat/free_module.py index 8a97fbdc796..0988afb29cf 100644 --- a/src/sage/combinat/free_module.py +++ b/src/sage/combinat/free_module.py @@ -503,10 +503,13 @@ def change_ring(self, R): return self construction = self.construction() if construction is not None: - functor, _ = construction + functor, args = construction from sage.categories.pushout import VectorFunctor + from sage.categories.tensor import TensorProductFunctor if isinstance(functor, VectorFunctor): return functor(R) + if isinstance(functor, TensorProductFunctor): + return functor([f.change_ring(R) for f in args]) raise NotImplementedError('the method change_ring() has not yet been implemented') # For backwards compatibility @@ -1259,8 +1262,8 @@ class CombinatorialFreeModule_Tensor(CombinatorialFreeModule): Category of tensor products of finite dimensional modules with basis over Integer Ring - sage: T.construction() # todo: not implemented - [tensor, ] + sage: T.construction() + (The tensor functorial construction, (F, G)) T is a free module, with same base ring as F and G:: @@ -1347,7 +1350,8 @@ def __classcall_private__(cls, modules, **options): assert (all(module in ModulesWithBasis(R)) for module in modules) # should check the base ring # flatten the list of modules so that tensor(A, tensor(B,C)) gets rewritten into tensor(A, B, C) - modules = sum([module._sets if isinstance(module, CombinatorialFreeModule_Tensor) else (module,) for module in modules], ()) + modules = sum([module._sets if isinstance(module, CombinatorialFreeModule_Tensor) else (module,) + for module in modules], ()) if all('FiniteDimensional' in M.category().axioms() for M in modules): options['category'] = options['category'].FiniteDimensional() return super(CombinatorialFreeModule.Tensor, cls).__classcall__(cls, modules, **options)