# Ticket #7980: trac_7980-multiple-realizations-nt.patch

File trac_7980-multiple-realizations-nt.patch, 62.0 KB (added by nthiery, 9 years ago)
• ## doc/en/reference/categories.rst

# HG changeset patch
# User Nicolas M. Thiery <nthiery@users.sf.net>
# Date 1331915772 -3600
# Node ID ce7273e0b8b822267857e5eb8f219fd4c25b8687
#7980: Implement generic support for parents with (multiple) realizations
* * *
TODO:

- Use bindable classes
- seealso w.r.t. SEEALSO
- Bases ou Realizations dans l'exemple?

diff --git a/doc/en/reference/categories.rst b/doc/en/reference/categories.rst
 a Functorial constructions sage/categories/subobjects sage/categories/isomorphic_objects sage/categories/realizations sage/categories/with_realizations Categories ========== Examples of parents using categories sage/categories/examples/semigroups sage/categories/examples/semigroups_cython sage/categories/examples/sets_cat sage/categories/examples/with_realizations Miscellaneous =============
• ## sage/categories/all.py

diff --git a/sage/categories/all.py b/sage/categories/all.py
 a from category import    is_Category, Category, HomCategory, AbstractCategory from category import    is_Category, Category, HomCategory from category_types import( Elements, from morphism import Morphism, is_Morphi from basic import * from realizations import Realizations from g_sets import GSets from pointed_sets import PointedSets
• ## sage/categories/category.py

diff --git a/sage/categories/category.py b/sage/categories/category.py
 a A parent P is in a category C if #                  http://www.gnu.org/licenses/ #***************************************************************************** from sage.misc.abstract_method import abstract_methods_of_class from sage.misc.abstract_method import abstract_method, abstract_methods_of_class from sage.misc.lazy_attribute import lazy_attribute from sage.misc.cachefunc import cached_method, cached_function #from sage.misc.misc import attrcall class Category(UniqueRepresentation, Sag """ return category_graph([self]) @abstract_method def super_categories(self): """ Returns the immediate super categories of self EXAMPLES:: sage: Groups().super_categories() [Category of monoids] sage: Objects().super_categories() [] """ @cached_method def _all_super_categories_raw(self): """ class Category(UniqueRepresentation, Sag EXAMPLES:: sage: C = GradedHopfAlgebrasWithBasis(QQ).abstract_category(); C Category of abstract graded hopf algebras with basis over Rational Field sage: C = Rings(); C Category of rings sage: C.all_super_categories() [Category of abstract graded hopf algebras with basis over Rational Field, Category of graded hopf algebras over Rational Field, Category of graded bialgebras over Rational Field, Category of graded algebras over Rational Field, Category of graded coalgebras over Rational Field, Category of graded modules over Rational Field, Category of hopf algebras over Rational Field, Category of bialgebras over Rational Field, Category of algebras over Rational Field, ...] [Category of rings, Category of rngs, Category of commutative additive groups, Category of semirings, Category of commutative additive monoids, Category of commutative additive semigroups, Category of additive magmas, Category of monoids, Category of semigroups, Category of magmas, Category of sets, Category of sets with partial maps, Category of objects] sage: C.all_super_categories(proper = True) [Category of rngs, Category of commutative additive groups, Category of semirings, Category of commutative additive monoids, Category of commutative additive semigroups, Category of additive magmas, Category of monoids, Category of semigroups, Category of magmas, Category of sets, Category of sets with partial maps, Category of objects] """ done = set() linear_extension = [] class Category(UniqueRepresentation, Sag except AttributeError: return Category.join((category.hom_category() for category in self.super_categories())) def abstract_category(self): r""" An abstract parent is a parent which models an abstract algebraic structure which has several concrete representations. This returns a mostly technical category which provides support tools for handling the different representation, and in particular the coercions between them. It can be manually specified by defining a class AbstractCategory as a member of this category. Typically, FiniteDimensionalModulesWithBasis(QQ).abstract_category() will be in charge, whenever a coercion \phi: A\mapsto B is registered, to register \phi^{-1} as coercion B \mapsto A if there is none defined yet. This is the analog of the *WithSeveralBases categories in MuPAD-Combinat. TODO: find a better name! The hierarchy of all abstract categories is built in parallel to that of their base categories, optimizing away those categories which do not have an AbstractCategory. Design question: currently self.abstract_category() is a subcategory of self by default. Is this desirable? For example, Algebras(QQ).abstract_category() should definitely be a subcategory of Algebras(QQ). On the other hand, AlgebrasWithBasis(QQ).abstract_category() should be a subcategory of Algebras(QQ), but not of AlgebrasWithBasis(QQ). This is because AlgebrasWithBasis(QQ) is specifying something about the concrete representation. EXAMPLES:: sage: Semigroups().abstract_category() Category of semigroups sage: C = GradedHopfAlgebrasWithBasis(QQ).abstract_category(); C Category of abstract graded hopf algebras with basis over Rational Field sage: C.all_super_categories() [Category of abstract graded hopf algebras with basis over Rational Field, Category of graded hopf algebras over Rational Field, Category of graded bialgebras over Rational Field, Category of graded algebras over Rational Field, Category of graded coalgebras over Rational Field, Category of graded modules over Rational Field, Category of hopf algebras over Rational Field, Category of bialgebras over Rational Field, Category of algebras over Rational Field, ...] """ if hasattr(self, "AbstractCategory"): return self.AbstractCategory(self) else: return Category.join(([self]+[category.abstract_category() for category in self.super_categories()])) def example(self, *args, **keywords): """ Returns an object in this category. Most of the time, this is a parent. def category_graph(categories = None): import sage.categories.all if categories is None: import all abstract_classes_for_categories = [Category, HomCategory, AbstractCategory] abstract_classes_for_categories = [Category, HomCategory] categories = [ cat.an_instance() for cat in sage.categories.all.__dict__.values() if isinstance(cat, type) and issubclass(cat, Category) and cat not in abstract_classes_for_categories ] cats = set() for category in categories: class HomCategory(Category): ############################################################# # Categories of abstract parents ############################################################# class AbstractCategory(Category): """ An abstract base class for all categories of abstract parents See Category.abstract_category. Caveat: specifications subject to change shortly. """ def __init__(self, category, name=None): """ Initializes this AbstractCategory INPUT: - category -- the category of which this category forms the abstract category. - name -- An optional name for this category. TESTS:: sage: C = sage.categories.category.AbstractCategory(Sets()) sage: C Category of abstract sets sage: TestSuite(C).run() """ Category.__init__(self, name) self.base_category = category def _repr_(self): """ String representation. EXAMPLES:: sage: C = GradedHopfAlgebrasWithBasis(QQ).abstract_category(); C #indirect doctest Category of abstract graded hopf algebras with basis over Rational Field """ s = repr(self.base_category) return s[:11]+" abstract"+s[11:] #    def construction(self): #        return (attrcall("abstract_category"), self.base_category) @cached_method def super_categories(self): """ Returns the immediate super categories, as per :meth:Category.super_categories. EXAMPLES:: sage: C = GradedHopfAlgebrasWithBasis(QQ).abstract_category() sage: C.super_categories() [Category of graded hopf algebras over Rational Field] """ return Category.join(self.extra_super_categories() + [category.abstract_category() for category in self.base_category.super_categories()], as_list=True) @cached_method def extra_super_categories(self): """ The super categories of self that are not derived from the inheritance diagram of the base category, as a list. EXAMPLES:: sage: C = GradedHopfAlgebrasWithBasis(QQ).abstract_category() sage: C.extra_super_categories() [Category of graded hopf algebras with basis over Rational Field] """ return [self.base_category] ############################################################# # Join of several categories #############################################################
• ## new file sage/categories/examples/with_realizations.py

diff --git a/sage/categories/examples/with_realizations.py b/sage/categories/examples/with_realizations.py
new file mode 100644
 - r""" Examples of parents endowed with multiple realizations """ #***************************************************************************** #  Copyright (C) 2008-2009 Nicolas M. Thiery # #  Distributed under the terms of the GNU General Public License (GPL) #                  http://www.gnu.org/licenses/ #***************************************************************************** from sage.misc.cachefunc import cached_method from sage.categories.all import Rings, Algebras, AlgebrasWithBasis from sage.categories.realizations import Category_realization_of_parent from sage.structure.unique_representation import UniqueRepresentation from sage.structure.parent import Parent from sage.sets.set import Set from sage.combinat.free_module import CombinatorialFreeModule from sage.combinat.subset import Subsets class SubsetAlgebra(UniqueRepresentation, Parent): r""" An example of parent endowed with several realizations We consider an algebra A(S) whose bases are indexed by the subsets s of a given set S. We consider three natural basis of this algebra: F, In, and Out. In the first basis, the product is given by the union of the indexing sets. That is, for any s, t\subset S .. MATH:: F_s F_t  = F_{s\cup t} The In basis and Out basis are defined respectively by: .. MATH:: In_s  = \sum_{t\subset s} F_t \qquad\text{and}\qquad F_s   = \sum_{t\supset s} Out_t Each such basis gives a realization of A, where the elements are represented by their expansion in this basis. This parent, and its code, demonstrate how to implement this algebra and its three realizations, with coercions and mixed arithmetic between them. .. SEEALSO:: - :func:Sets().WithRealizations  EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field The three bases of A:: sage: F   = A.F()  ; F The subset algebra of {1, 2, 3} over Rational Field on the fundamental basis sage: In  = A.In() ; In The subset algebra of {1, 2, 3} over Rational Field on the in basis sage: Out = A.Out(); Out The subset algebra of {1, 2, 3} over Rational Field on the out basis sage: F.basis().list() [F[{}], F[{1}], F[{2}], F[{3}], F[{1, 2}], F[{1, 3}], F[{2, 3}], F[{1, 2, 3}]] Some conversions:: sage: F(In.from_set(2,3)) F[{}] + F[{2}] + F[{3}] + F[{2, 3}] sage: In(F.from_set(2,3)) In[{}] - In[{2}] - In[{3}] + In[{2, 3}] sage: Out(F.from_set(3)) Out[{3}] + Out[{1, 3}] + Out[{2, 3}] + Out[{1, 2, 3}] sage: F(Out.from_set(3)) F[{3}] - F[{1, 3}] - F[{2, 3}] + F[{1, 2, 3}] sage: Out(In.from_set(2,3)) Out[{}] + Out[{1}] + 2*Out[{2}] + 2*Out[{3}] + 2*Out[{1, 2}] + 2*Out[{1, 3}] + 4*Out[{2, 3}] + 4*Out[{1, 2, 3}] We can now mix expressions:: sage: (1 + Out.from_set(1)) * In.from_set(2,3) Out[{}] + 2*Out[{1}] + 2*Out[{2}] + 2*Out[{3}] + 2*Out[{1, 2}] + 2*Out[{1, 3}] + 4*Out[{2, 3}] + 4*Out[{1, 2, 3}] """ def __init__(self, R, S): r""" EXAMPLES:: sage: from sage.categories.examples.with_realizations import SubsetAlgebra sage: A = SubsetAlgebra(QQ, Set((1,2,3))); A The subset algebra of {1, 2, 3} over Rational Field sage: Sets().WithRealizations().example() is A True sage: TestSuite(A).run() """ assert(R in Rings()) self._base = R # Won't be needed when CategoryObject won't override anymore base_ring self._S = S Parent.__init__(self, category = Algebras(R).WithRealizations()) # Could possibly go in Monoids.WithRealizations.ParentMethods def one(self): r""" EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: A.one() F[{}] sage: A.one() is A.F().one() True """ return self.F().one() # Could possibly go in CommutativeAdditiveMonoids.WithRealizations.ParentMethods def zero(self): r""" EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: A.zero() 0 sage: A.zero() is A.F().zero() True """ return self.F().zero() # Could be inherited from ParentWithBase? def base_ring(self): r""" EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: A.base_ring() Rational Field """ return self._base def base_set(self): r""" EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: A.base_set() {1, 2, 3} """ return self._S def indices(self): r""" EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: A.indices() Subsets of {1, 2, 3} """ return Subsets(self._S) def indices_cmp(self, x, y): r""" A comparison function on sets which gives a linear extension of the inclusion order. INPUT: - x, y -- sets EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: sorted(A.indices(), A.indices_cmp) [{}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}] """ s = cmp(len(x), len(y)) if s != 0: return s return cmp(list(x), list(y)) def supsets(self, set): r""" INPUT: - set -- a subset of the base set S of self Returns all the subsets of S containing set EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: A.supsets(Set((2,))) [{1, 2, 3}, {2, 3}, {1, 2}, {2}] """ S = self.base_set() return list(S.difference(s) for s in Subsets(S.difference(set))) def _repr_(self): r""" EXAMPLES:: sage: Sets().WithRealizations().example()   # indirect doctest The subset algebra of {1, 2, 3} over Rational Field """ return "The subset algebra of %s over %s"%(self.base_set(), self.base_ring()) # Eventually it will be possible to put the class directly here if desired def F(self): """ Returns the fundamental basis of self EXAMPLES:: sage: Sets().WithRealizations().example().F() The subset algebra of {1, 2, 3} over Rational Field on the fundamental basis """ return Fundamental(self) def In(self): """ Returns the in basis of self EXAMPLES:: sage: Sets().WithRealizations().example().In() The subset algebra of {1, 2, 3} over Rational Field on the in basis """ return In(self) def Out(self): """ Returns the out basis of self EXAMPLES:: sage: Sets().WithRealizations().example().Out() The subset algebra of {1, 2, 3} over Rational Field on the out basis """ return Out(self) def __init_extra__(self): r""" Initializes the bases and change of bases of self TESTS:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: F, In, Out = A.realizations() sage: type(F.coerce_map_from(In)) sage: type(In.coerce_map_from(F)) sage: type(F.coerce_map_from(Out)) sage: type(Out.coerce_map_from(F)) sage: In.coerce_map_from(Out) Composite map: From: The subset algebra of {1, 2, 3} over Rational Field on the out basis To:   The subset algebra of {1, 2, 3} over Rational Field on the in basis Defn:   Generic morphism: From: The subset algebra of {1, 2, 3} over Rational Field on the out basis To:   The subset algebra of {1, 2, 3} over Rational Field on the fundamental basis then Generic morphism: From: The subset algebra of {1, 2, 3} over Rational Field on the fundamental basis To:   The subset algebra of {1, 2, 3} over Rational Field on the in basis sage: Out.coerce_map_from(In) Composite map: From: The subset algebra of {1, 2, 3} over Rational Field on the in basis To:   The subset algebra of {1, 2, 3} over Rational Field on the out basis Defn:   Generic morphism: From: The subset algebra of {1, 2, 3} over Rational Field on the in basis To:   The subset algebra of {1, 2, 3} over Rational Field on the fundamental basis then Generic morphism: From: The subset algebra of {1, 2, 3} over Rational Field on the fundamental basis To:   The subset algebra of {1, 2, 3} over Rational Field on the out basis """ category   = self.Realizations() F   = self.F() In  = self.In() Out = self.Out() In_to_F = In.module_morphism(F.sum_of_monomials * Subsets, codomain = F, category = category, triangular = 'upper', unitriangular = True, cmp = self.indices_cmp) In_to_F   .register_as_coercion() (~In_to_F).register_as_coercion() F_to_Out = F.module_morphism(Out.sum_of_monomials * self.supsets, codomain = Out, category = category, triangular = 'lower', unitriangular = True, cmp = self.indices_cmp) F_to_Out   .register_as_coercion() (~F_to_Out).register_as_coercion() # Alternatively, this category can be defined elsewhere, with just a link class Realizations(Category_realization_of_parent): r""" The category of the realizations of the subset algebra """ def super_categories(self): r""" EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: C = A.Realizations(); C The category of realizations of The subset algebra of {1, 2, 3} over Rational Field sage: C.super_categories() [Join of Category of algebras over Rational Field and Category of realizations of sets, Category of algebras with basis over Rational Field] """ R = self.base().base_ring() return [Algebras(R).Realizations(), AlgebrasWithBasis(R)] class ParentMethods: def from_set(self, *args): r""" Construct the monomial indexed by the set containing the elements passed as arguments. EXAMPLES:: sage: In = Sets().WithRealizations().example().In(); In The subset algebra of {1, 2, 3} over Rational Field on the in basis sage: In.from_set(2,3) In[{2, 3}] .. TODO:: rename to __getitem__ once Parent.__getitem__ won't be anymore in the way:: sage: In[2,3]     # todo: not implemented In[{2, 3}] """ return self.monomial(Set(args)) # This could go in some super category VectorSpaces().Realizations() def _repr_(self): r""" EXAMPLES:: sage: Sets().WithRealizations().example().In()  # indirect doctest The subset algebra of {1, 2, 3} over Rational Field on the in basis """ return "%s %s"%(self.realization_of(), "on the %s basis"%(self._realization_name())) @cached_method def one(self): r""" Returns the unit of this algebra. This default implementation takes the unit in the fundamental basis, and coerces it in self. EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: In = A.In(); Out = A.Out() sage: In.one() In[{}] sage: Out.one() Out[{}] + Out[{1}] + Out[{2}] + Out[{3}] + Out[{1, 2}] + Out[{1, 3}] + Out[{2, 3}] + Out[{1, 2, 3}] """ return self(self.realization_of().F().one()) class Fundamental(CombinatorialFreeModule): r""" The class for the parent modeling the fundamental basis of the Subset Algebra INPUT: - A -- a parent with realization in :class:SubsetAlgebra """ def __init__(self, A): r""" EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: F = A.F(); F The subset algebra of {1, 2, 3} over Rational Field on the fundamental basis sage: TestSuite(F).run() """ CombinatorialFreeModule.__init__(self, A.base_ring(), A.indices(), category=A.Realizations(), prefix='F', monomial_cmp=A.indices_cmp) def product_on_basis(self, left, right): r""" Product of basis elements, as per :meth:AlgebrasWithBasis.ParentMethods.product_on_basis. INPUT: - left, right -- sets indexing basis elements EXAMPLES:: sage: F = Sets().WithRealizations().example().F(); F The subset algebra of {1, 2, 3} over Rational Field on the fundamental basis sage: S = F.basis().keys(); S Subsets of {1, 2, 3} sage: F.product_on_basis(S([]), S([])) F[{}] sage: F.product_on_basis(S({1}), S({3})) F[{1, 3}] sage: F.product_on_basis(S({1,2}), S({2,3})) F[{1, 2, 3}] """ return self.monomial( left.union(right)  ) def one_basis(self): r""" Returns the index of the basis element which is equal to '1'. EXAMPLES:: sage: F = Sets().WithRealizations().example().F(); F The subset algebra of {1, 2, 3} over Rational Field on the fundamental basis sage: F.one_basis() {} sage: F.one() F[{}] """ return Set([]) one = AlgebrasWithBasis.ParentMethods.one class In(CombinatorialFreeModule): r""" The class for the parent modeling the In basis of the Subset Algebra INPUT: - A -- a parent with realization in :class:SubsetAlgebra """ def __init__(self, A): r""" EXAMPLES:: sage: In = Sets().WithRealizations().example().In(); In The subset algebra of {1, 2, 3} over Rational Field on the in basis sage: TestSuite(In).run() """ CombinatorialFreeModule.__init__(self, A.base_ring(), A.indices(), category=A.Realizations(), prefix='In', monomial_cmp=A.indices_cmp) # This won't be needed any more once #8878 will be closed def product(self, x, y): r""" Returns the product of x by y .. SEEALSO:: :meth:Magmas.ParentMethods.product EXAMPLES:: sage: In = Sets().WithRealizations().example().In(); In The subset algebra of {1, 2, 3} over Rational Field on the in basis sage: x = In.an_element() sage: y = In.an_element() sage: In.product(x, y) -21*In[{}] - 2*In[{1}] + 19*In[{2}] + 53*In[{1, 2}] .. TODO:: this method won't be needed once :trac:8878 will be closed """ F = self.realization_of().F() return self(F(x) * F(y)) class Out(CombinatorialFreeModule): r""" The class for the parent modeling the Out basis of the Subset Algebra INPUT: - A -- a parent with realization in :class:SubsetAlgebra """ def __init__(self, A): r""" EXAMPLES:: sage: Out = Sets().WithRealizations().example().Out(); Out The subset algebra of {1, 2, 3} over Rational Field on the out basis sage: TestSuite(Out).run() """ CombinatorialFreeModule.__init__(self, A.base_ring(), A.indices(), category=A.Realizations(), prefix='Out', monomial_cmp=A.indices_cmp) def product(self, x, y): r""" Returns the product of x by y .. SEEALSO:: :meth:Magmas.ParentMethods.product EXAMPLES:: sage: Out = Sets().WithRealizations().example().Out(); Out The subset algebra of {1, 2, 3} over Rational Field on the out basis sage: x = Out.an_element() sage: y = Out.an_element() sage: Out.product(x, y) Out[{}] + 4*Out[{1}] + 9*Out[{2}] + Out[{1, 2}] .. TODO:: this method won't be needed once :trac:8878 will be closed """ F = self.realization_of().F() return self(F(x) * F(y))

diff --git a/sage/categories/graded_hopf_algebras_with_basis.py b/sage/categories/graded_hopf_algebras_with_basis.py
• ## new file sage/categories/realizations.py

diff --git a/sage/categories/realizations.py b/sage/categories/realizations.py
new file mode 100644
 - """ Realizations Covariant Functorial Construction .. SEEALSO:: - :func:Sets().WithRealizations  for an introduction to *realizations* and *with realizations*. - :mod:sage.categories.covariant_functorial_construction for an introduction to covariant functorial constructions. - :mod:sage.categories.examples.with_realizations for an example. """ #***************************************************************************** #  Copyright (C) 2010-2012 Nicolas M. Thiery # #  Distributed under the terms of the GNU General Public License (GPL) #                  http://www.gnu.org/licenses/ #***************************************************************************** from sage.categories.category import Category from sage.categories.category_types import Category_over_base from sage.categories.covariant_functorial_construction import RegressiveCovariantConstructionCategory class RealizationsCategory(RegressiveCovariantConstructionCategory): """ An abstract base class for all categories of realizations category Relization are implemented as :class:~sage.categories.covariant_functorial_construction.RegressiveCovariantConstructionCategory. See there for the documentation of how the various bindings such as Sets().Realizations() and P.Realizations(), where P is a parent, work. .. SEEALSO:: :func:Sets().WithRealizations  TESTS:: sage: Sets().Realizations sage: Sets().Realizations() Category of realizations of sets sage: Sets().Realizations().super_categories() [Category of sets] sage: Groups().Realizations().super_categories() [Category of groups, Category of realizations of sets] """ _functor_category = "Realizations" def Realizations(self): """ Return the category of realizations of the parent self or of objects of the category self INPUT: - self -- a parent or a concrete category .. NOTE:: this *function* is actually inserted as a *method* in the class :class:~sage.categories.category.Category (see :meth:~sage.categories.category.Category.Realizations). It is defined here for code locality reasons. EXAMPLES: The category of realizations of some algebra:: sage: Algebras(QQ).Realizations() Join of Category of algebras over Rational Field and Category of realizations of sets The category of realizations of a given algebra:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: A.Realizations() The category of realizations of The subset algebra of {1, 2, 3} over Rational Field sage: C = GradedHopfAlgebrasWithBasis(QQ).Realizations(); C Join of Category of graded hopf algebras with basis over Rational Field and Category of realizations of sets sage: C.super_categories() [Category of graded hopf algebras with basis over Rational Field, Category of realizations of sets] sage: TestSuite(C).run() .. SEEALSO:: - :func:Sets().WithRealizations  - :class:ClasscallMetaclass .. TODO:: Add an optional argument to allow for:: sage: Realizations(A, category = Blahs()) # todo: not implemented """ if isinstance(self, Category): return RealizationsCategory.category_of(self) else: return getattr(self.__class__, "Realizations")(self) Category.Realizations = Realizations class Category_realization_of_parent(Category_over_base): """ An abstract base class for categories of all realizations of a given parent INPUT: - parent_with_realization -- a parent .. SEEALSO:: :func:Sets().WithRealizations  EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field The role of this base class is to implement some technical goodies, like the binding A.Realizations() when a subclass Realizations is implemented as a nested class in A (see the :mod:code of the example ):: sage: C = A.Realizations(); C The category of realizations of The subset algebra of {1, 2, 3} over Rational Field as well as the name for that category. TESTS:: sage: TestSuite(C).run() """ @staticmethod def __classget__(cls, parent, owner): r""" Implements class binding EXAMPLES: Let A be an algebra with several realizations:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field This implements a hack allowing A.Realizations() to call A.__class__.Realizations(A) to construct the category of realizations of A:: sage: A.Realizations() The category of realizations of The subset algebra of {1, 2, 3} over Rational Field sage: A.__class__.Realizations(A) The category of realizations of The subset algebra of {1, 2, 3} over Rational Field As an intermediate step, this binds the method :func:sage.categories.realizations.Realizations to A so that introspection plays nicely:: sage: A.Realizations .. SEEALSO:: - :class:ClasscallMetaclass - :class:Sets.WithRealizations """ if parent is None: return cls # From within a module, is there a shortcut to oneself? import sage.categories.realizations return Realizations.__get__(parent, sage.categories.realizations) def __init__(self, parent_with_realization): """ TESTS:: sage: from sage.categories.realizations import Category_realization_of_parent sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: C = A.Realizations(); C The category of realizations of The subset algebra of {1, 2, 3} over Rational Field sage: isinstance(C, Category_realization_of_parent) True sage: C.parent_with_realization The subset algebra of {1, 2, 3} over Rational Field sage: TestSuite(C).run() """ Category_over_base.__init__(self, parent_with_realization) self.parent_with_realization = parent_with_realization def _get_name(self): """ Return a human readable string specifying which kind of bases this category is for It is obtained by splitting and lower casing the last part of the class name. EXAMPLES:: sage: from sage.categories.realizations import Category_realization_of_parent sage: class MultiplicativeBasesOnPrimitiveElements(Category_realization_of_parent): ...       pass sage: Sym = SymmetricFunctions(QQ); Sym.rename("Sym") sage: MultiplicativeBasesOnPrimitiveElements(Sym)._get_name() 'multiplicative bases on primitive elements' """ import re return re.sub(".[A-Z]", lambda s: s.group()[0]+" "+s.group()[1], self.__class__.__name__.split(".")[-1]).lower() def _repr_(self): """ EXAMPLES:: sage: from sage.categories.realizations import Category_realization_of_parent sage: class MultiplicativeBasesOnPrimitiveElements(Category_realization_of_parent): ...       pass ... sage: Sym = SymmetricFunctions(QQ); Sym.rename("Sym") sage: MultiplicativeBasesOnPrimitiveElements(Sym)     # indirect doctest The category of multiplicative bases on primitive elements of Sym """ return "The category of %s of %s"%(self._get_name(), self.base())
• ## sage/categories/sets_cat.py

diff --git a/sage/categories/sets_cat.py b/sage/categories/sets_cat.py
 a from sage.categories.subobjects import from sage.categories.isomorphic_objects   import IsomorphicObjectsCategory from sage.categories.algebra_functor import AlgebrasCategory from sage.categories.cartesian_product import cartesian_product, CartesianProductsCategory from sage.categories.realizations import RealizationsCategory, Category_realization_of_parent from sage.categories.with_realizations import WithRealizationsCategory lazy_import('sage.sets.cartesian_product', 'CartesianProduct') class Sets(Category_singleton): """ from sage.categories.modules_with_basis import ModulesWithBasis return [ModulesWithBasis(self.base_ring())] class WithRealizations(WithRealizationsCategory): def extra_super_categories(self): """ A set with multiple realizations is a facade parent EXAMPLES:: sage: Sets().WithRealizations().extra_super_categories() [Category of facade sets] sage: Sets().WithRealizations().super_categories() [Category of facade sets] """ return [Sets().Facades()] def example(self, base_ring = None, set = None): r""" Returns an example of set with multiple realizations, as per :meth:Category.example. EXAMPLES:: sage: Sets().WithRealizations().example() The subset algebra of {1, 2, 3} over Rational Field sage: Sets().WithRealizations().example(ZZ, Set([1,2])) The subset algebra of {1, 2} over Integer Ring """ from sage.rings.rational_field import QQ from sage.sets.set import Set if base_ring is None: base_ring = QQ if set is None: set = Set([1,2,3]) from sage.categories.examples.with_realizations import SubsetAlgebra return SubsetAlgebra(base_ring, set) class ParentMethods: def _test_with_realizations(self, **options): r""" Test that this parent with realizations is properly implemented INPUT:: - options -- any keyword arguments accepted by :meth:_tester. EXAMPLES:: sage: A = Sets().WithRealizations().example() sage: A._test_with_realizations() See the documentation for :class:TestSuite for more information. """ tester = self._tester(**options) for R in self.realizations(): tester.assert_(R in self.Realizations()) # Could check that there are coerce maps between any two realizations @lazy_attribute def _realizations(self): """ This lazily initializes the attribute _realizations the first time it is needed. TESTS:: sage: class MyParent(Parent): ...      pass sage: P = MyParent(category = Sets().WithRealizations()) sage: P._realizations [] """ return [] def _register_realization(self, realization): """ EXAMPLES:: sage: A = Sets().WithRealizations().example(QQ[x]); A The subset algebra of {1, 2, 3} over Univariate Polynomial Ring in x over Rational Field sage: class ANewRealizationOfA(CombinatorialFreeModule): ...       pass sage: R = ANewRealizationOfA(A.base_ring(), A.F().basis().keys(), category = A.Realizations()) sage: R in A.realizations()  # indirect doctest True Note: the test above uses QQ[x] to not interfer with other tests """ assert realization.realization_of() is self self._realizations.append(realization) def realizations(self): """ Returns all the realizations of self that self is aware of. EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: A.realizations() [The subset algebra of {1, 2, 3} over Rational Field on the fundamental basis, The subset algebra of {1, 2, 3} over Rational Field on the in basis, The subset algebra of {1, 2, 3} over Rational Field on the out basis] .. note:: Constructing a parent P in the category A.Realizations() automatically adds P to this list by calling A._register_realization(A) """ return self._realizations facade_for = realizations """ Returns the parents self is a facade for, that is the realizations of self EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: A.facade_for() [The subset algebra of {1, 2, 3} over Rational Field on the fundamental basis, The subset algebra of {1, 2, 3} over Rational Field on the in basis, The subset algebra of {1, 2, 3} over Rational Field on the out basis] sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: f = A.F().an_element(); f F[{}] + 2*F[{1}] + 3*F[{2}] + F[{1, 2}] sage: i = A.In().an_element(); i In[{}] + 2*In[{1}] + 3*In[{2}] + In[{1, 2}] sage: o = A.Out().an_element(); o Out[{}] + 2*Out[{1}] + 3*Out[{2}] + Out[{1, 2}] sage: f in A, i in A, o in A (True, True, True) """ # Do we really want this feature? class Realizations(Category_realization_of_parent): def super_categories(self): """ EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: A.Realizations().super_categories() [Join of Category of algebras over Rational Field and Category of realizations of sets, Category of algebras with basis over Rational Field] """ return [Sets().Realizations()] def _an_element_(self): """ Returns an element of some realization of self EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: A.an_element()        # indirect doctest F[{}] + 2*F[{1}] + 3*F[{2}] + F[{1, 2}] """ return self.realizations()[0].an_element() # TODO: maybe this could be taken care of by Sets.Facades()? def __contains__(self, x): r""" Test whether x is in self, that is if it is an element of some realization of self. EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: A.an_element() in A True sage: A.In().an_element() in A True sage: A.F().an_element() in A True sage: A.Out().an_element() in A True sage: 1 in A True sage: QQ['x'].an_element() in A False """ return any(x in realization for realization in self.realizations()) class Realizations(RealizationsCategory): class ParentMethods: def __init_extra__(self): """ Registers self as a realization of self.realization_of TESTS:: sage: A = Sets().WithRealizations().example() sage: A.realizations()    # indirect doctest [The subset algebra of {1, 2, 3} over Rational Field on the fundamental basis, The subset algebra of {1, 2, 3} over Rational Field on the in basis, The subset algebra of {1, 2, 3} over Rational Field on the out basis] """ self.realization_of()._register_realization(self) @cached_method def realization_of(self): """ Returns the parent this is a realization of EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: In = A.In(); In The subset algebra of {1, 2, 3} over Rational Field on the in basis sage: In.realization_of() The subset algebra of {1, 2, 3} over Rational Field """ for category in self.categories(): if isinstance(category, Category_realization_of_parent): return category.base() def _realization_name(self): """ Returns the name of this realization In this default implementation, this is guessed from the name of its class. EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: In = A.In(); In The subset algebra of {1, 2, 3} over Rational Field on the in basis sage: In._realization_name() 'in' FIXME: Do we want In instead? """ # The __base__ gets rid of the with_category return self.__class__.__base__.__name__.lower() def _repr_(self): """ EXAMPLES:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field sage: In = A.In(); In The subset algebra of {1, 2, 3} over Rational Field on the in basis In the example above, :meth:repr was overriden by the category A.Realizations(). We now add a new (fake) realization which is not in A.Realizations() to actually exercise this method:: sage: from sage.categories.realizations import Realizations sage: class Blah(Parent): ...       pass sage: P = Blah(category = Sets.WithRealizations.ParentMethods.Realizations(A)) sage: P     # indirect doctest The subset algebra of {1, 2, 3} over Rational Field in the realization blah """ return "%s in the realization %s"%(self.realization_of(), self._realization_name())
• ## new file sage/categories/with_realizations.py

diff --git a/sage/categories/with_realizations.py b/sage/categories/with_realizations.py
new file mode 100644
 - """ With Realizations Covariant Functorial Construction .. SEEALSO:: - :func:Sets().WithRealizations  for an introduction to *realizations* and *with realizations*. - :mod:sage.categories.covariant_functorial_construction for an introduction to covariant functorial constructions. """ #***************************************************************************** #  Copyright (C) 2010-2012 Nicolas M. Thiery # #  Distributed under the terms of the GNU General Public License (GPL) #                  http://www.gnu.org/licenses/ #***************************************************************************** from sage.categories.category import Category from sage.categories.covariant_functorial_construction import RegressiveCovariantConstructionCategory def WithRealizations(self): """ Returns the category of parents in self endowed with multiple realizations INPUT: - self -- a category .. SEEALSO:: - the documentation and code (:mod:sage.categories.examples.with_realizations) of Sets().WithRealizations().example() for more on how to use and implement a parent with several realizations. - :mod:sage.categories.realizations .. NOTE:: this *function* is actually inserted as a *method* in the class :class:~sage.categories.category.Category (see :meth:~sage.categories.category.Category.WithRealizations). It is defined here for code locality reasons. EXAMPLES:: sage: Sets().WithRealizations() Category of sets with realizations .. RUBRIC:: Parent with realizations Let us now explain the concept of realizations. A *parent with realizations* is a facade parent (see :class:Sets.Facades) admitting multiple concrete realizations where its elements are represented. Consider for example an algebra A which admits several natural bases:: sage: A = Sets().WithRealizations().example(); A The subset algebra of {1, 2, 3} over Rational Field For each such basis B one implements a parent P_B which realizes A with its elements represented by expanding them on the basis B:: sage: A.F() The subset algebra of {1, 2, 3} over Rational Field on the fundamental basis sage: A.Out() The subset algebra of {1, 2, 3} over Rational Field on the out basis sage: A.In() The subset algebra of {1, 2, 3} over Rational Field on the in basis sage: A.an_element() F[{}] + 2*F[{1}] + 3*F[{2}] + F[{1, 2}] If B and B' are two bases, then the change of basis from B to B' is implemented by a canonical coercion between P_B and P_{B'}:: sage: F = A.F(); In = A.In(); Out = A.Out() sage: i = In.an_element(); i In[{}] + 2*In[{1}] + 3*In[{2}] + In[{1, 2}] sage: F(i) 7*F[{}] + 3*F[{1}] + 4*F[{2}] + F[{1, 2}] sage: F.coerce_map_from(Out) Generic morphism: From: The subset algebra of {1, 2, 3} over Rational Field on the out basis To:   The subset algebra of {1, 2, 3} over Rational Field on the fundamental basis allowing for mixed arithmetic:: sage: (1 + Out.from_set(1)) * In.from_set(2,3) Out[{}] + 2*Out[{1}] + 2*Out[{2}] + 2*Out[{3}] + 2*Out[{1, 2}] + 2*Out[{1, 3}] + 4*Out[{2, 3}] + 4*Out[{1, 2, 3}] In our example, there are three realizations:: sage: A.realizations() [The subset algebra of {1, 2, 3} over Rational Field on the fundamental basis, The subset algebra of {1, 2, 3} over Rational Field on the in basis, The subset algebra of {1, 2, 3} over Rational Field on the out basis] The set of all realizations of A, together with the coercion morphisms is a category (whose class inherits from :class:~sage.categories.realizations.Category_realization_of_parent):: sage: A.Realizations() The category of realizations of The subset algebra of {1, 2, 3} over Rational Field The various parent realizing A belong to this category:: sage: A.F() in A.Realizations() True A itself is in the category of algebras with realizations:: sage: A in Algebras(QQ).WithRealizations() True The (mostly technical) WithRealizations categories are the analogs of the *WithSeveralBases categories in MuPAD-Combinat. They provide support tools for handling the different realizations and the morphisms between them. Typically, FiniteDimensionalVectorSpaces(QQ).WithRealizations() will eventually be in charge, whenever a coercion \phi: A\mapsto B is registered, to register \phi^{-1} as coercion B \mapsto A if there is none defined yet. To achieve this, FiniteDimensionalVectorSpaces would provide a nested class WithRealizations implementing the appropriate logic. WithRealizations is a :mod:regressive covariant functorial construction . On our example, this simply means that A is automatically in the category of rings with realizations (covariance):: sage: A in Rings().WithRealizations() True and in the category of algebras (regressiveness):: sage: A in Algebras(QQ) True .. NOTE:: For C a category, C.WithRealizations() in fact calls sage.categories.with_realizations.Realizations(C). The later is responsible for building the hierarchy of the categories with realizations in parallel to that of their base categories, optimizing away those categories that do not provide a WithRealizations nested class. See :mod:sage.categories.covariant_functorial_construction for the technical details. .. NOTE:: Design question: currently WithRealizations is a regressive construction. That is self.WithRealizations() is a subcategory of self by default:: sage: Algebras(QQ).WithRealizations().super_categories() [Category of algebras over Rational Field, Category of sets with realizations] Is this always desirable? For example, AlgebrasWithBasis(QQ).WithRealizations() should certainly be a subcategory of Algebras(QQ), but not of AlgebrasWithBasis(QQ). This is because AlgebrasWithBasis(QQ) is specifying something about the concrete realization. TESTS:: sage: Semigroups().WithRealizations() Join of Category of semigroups and Category of sets with realizations sage: C = GradedHopfAlgebrasWithBasis(QQ).WithRealizations(); C Category of graded hopf algebras with basis over Rational Field with realizations sage: C.super_categories() [Category of graded hopf algebras over Rational Field] sage: C.all_super_categories() [Category of graded hopf algebras with basis over Rational Field with realizations, Category of graded hopf algebras over Rational Field, Category of graded bialgebras over Rational Field, Category of graded algebras over Rational Field, Category of graded coalgebras over Rational Field, Category of graded modules over Rational Field, Category of hopf algebras over Rational Field, Category of bialgebras over Rational Field, Category of algebras over Rational Field, ...] sage: TestSuite(Semigroups().WithRealizations()).run() """ return WithRealizationsCategory.category_of(self) Category.WithRealizations = WithRealizations class WithRealizationsCategory(RegressiveCovariantConstructionCategory): """ An abstract base class for all categories of parents with multiple realizations. .. SEEALSO:: :func:Sets().WithRealizations  The role of this base class is to implement some technical goodies, such as the name for that category. """ _functor_category = "WithRealizations" def _repr_(self): """ String representation. EXAMPLES:: sage: C = GradedHopfAlgebrasWithBasis(QQ).WithRealizations(); C #indirect doctest Category of graded hopf algebras with basis over Rational Field with realizations """ s = repr(self.base_category()) return s+" with realizations"
• ## sage/combinat/sf/sf.py

diff --git a/sage/combinat/sf/sf.py b/sage/combinat/sf/sf.py
 a class SymmetricFunctions(UniqueRepresent Sym is the unique free commutative graded connected algebra, with one generator in each degree:: sage: Sym.category() Category of abstract graded hopf algebras with basis over Rational Field Category of graded hopf algebras with basis over Rational Field with realizations We use the Sage standard renaming idiom to get shorter outputs:: class SymmetricFunctions(UniqueRepresent """ assert(R in Rings()) self._base = R # Won't be needed when CategoryObject won't override anymore base_ring Parent.__init__(self, category = GradedHopfAlgebrasWithBasis(R).abstract_category()) Parent.__init__(self, category = GradedHopfAlgebrasWithBasis(R).WithRealizations()) def _repr_(self): # could be taken care of by the category """