Ticket #11943: trac11943_mro_for_all_super_categories_lazy_hook.patch

File trac11943_mro_for_all_super_categories_lazy_hook.patch, 84.2 KB (added by nthiery, 7 years ago)

Order the super categories of a category according to Python's mro. Internally replace (all_)super_categories by lazy attributes, to prevent a regression. Use _subcategory_hook_

  • doc/en/reference/misc.rst

    # HG changeset patch
    # User Simon King <simon.king@uni-jena.de>
    # Date 1319403311 -7200
    # Node ID 67948c416f8b9ef23a0c97fda5f76772678f05aa
    # Parent  9c42ea6598c003a4f88b1ae727a0f5436650fd59
    #11943: Order the super categories of a category according to Python's method resolution order
    Introduce lazy-attribute versions of super_categories and all_super_categories, for
    getting a speed-up. Allow to use a shortpath in is_subcategory, by using _subcategory_hook_.
    Use subclass check on parent classes to determine subcategories.
    
    diff --git a/doc/en/reference/misc.rst b/doc/en/reference/misc.rst
    a b Miscellaneous 
    88
    99   sage/misc/abstract_method
    1010   sage/misc/cachefunc
     11   sage/misc/c3
    1112   sage/misc/decorators
    1213   sage/misc/classgraph
    1314   sage/misc/dev_tools
  • module_list.py

    diff --git a/module_list.py b/module_list.py
    a b ext_modules = [ 
    10581058    Extension('sage.misc.cython_c',
    10591059              sources = ['sage/misc/cython_c.pyx']),
    10601060
     1061    Extension('sage.misc.c3',
     1062              sources = ['sage/misc/c3.pyx']),
     1063
    10611064    Extension('sage.misc.derivative',
    10621065              sources = ['sage/misc/derivative.pyx']),
    10631066
  • sage/categories/additive_magmas.py

    diff --git a/sage/categories/additive_magmas.py b/sage/categories/additive_magmas.py
    a b class AdditiveMagmas(Category_singleton) 
    3535
    3636    """
    3737
    38     @cached_method
    3938    def super_categories(self):
    4039        """
    4140        EXAMPLES::
  • sage/categories/affine_weyl_groups.py

    diff --git a/sage/categories/affine_weyl_groups.py b/sage/categories/affine_weyl_groups.py
    a b class AffineWeylGroups(Category_singleto 
    4444        sage: TestSuite(C).run()
    4545    """
    4646
    47     @cached_method
    4847    def super_categories(self):
    4948        r"""
    5049        EXAMPLES::
  • sage/categories/algebra_ideals.py

    diff --git a/sage/categories/algebra_ideals.py b/sage/categories/algebra_ideals.py
    a b AlgebraIdeals 
    1212
    1313from sage.misc.cachefunc import cached_method
    1414from category_types import Category_ideal
     15from algebra_modules import AlgebraModules
     16from commutative_algebras import CommutativeAlgebras
    1517
    1618class AlgebraIdeals(Category_ideal):
    1719    """
    class AlgebraIdeals(Category_ideal): 
    5860        """
    5961        return self.ambient()
    6062
    61     @cached_method
    6263    def super_categories(self):
    6364        """
     65        The category of algebra modules should be a super category of this category.
     66
     67        However, since algebra modules are currently only available over commutative rings,
     68        we have to omit it if our ring is non-commutative.
     69
    6470        EXAMPLES::
    6571
    6672            sage: AlgebraIdeals(QQ[x]).super_categories()
    6773            [Category of algebra modules over Univariate Polynomial Ring in x over Rational Field]
     74            sage: C = AlgebraIdeals(FreeAlgebra(QQ,2,'a,b'))
     75            sage: C.super_categories()
     76            []
     77
    6878        """
    69         from algebra_modules import AlgebraModules
    7079        R = self.algebra()
    71         return [AlgebraModules(R)]
     80        try:
     81            if R.is_commutative():
     82                return [AlgebraModules(R)]
     83        except (AttributeError,NotImplementedError):
     84            pass
     85        return []
  • sage/categories/algebra_modules.py

    diff --git a/sage/categories/algebra_modules.py b/sage/categories/algebra_modules.py
    a b Algebra modules 
    1212
    1313from sage.misc.cachefunc import cached_method
    1414from category_types import Category_module
     15from modules import Modules
    1516
    1617class AlgebraModules(Category_module):
    1718    """
    class AlgebraModules(Category_module): 
    7778        """
    7879        return self.base_ring()
    7980
    80     @cached_method
    8181    def super_categories(self):
    8282        """
    8383        EXAMPLES::
    class AlgebraModules(Category_module): 
    8686            [Category of modules over Univariate Polynomial Ring in x over Rational Field]
    8787        """
    8888        R = self.algebra()
    89         from modules import Modules
    9089        return [Modules(R)]
  • sage/categories/algebras.py

    diff --git a/sage/categories/algebras.py b/sage/categories/algebras.py
    a b from sage.categories.dual import DualObj 
    2323from sage.categories.tensor import TensorProductsCategory, tensor
    2424from sage.categories.morphism import SetMorphism
    2525from sage.categories.rings import Rings
     26from sage.categories.modules import Modules
    2627from sage.misc.cachefunc import cached_method
    2728from sage.structure.sage_object import have_same_parent
    2829
    class Algebras(Category_over_base_ring): 
    6667        from sage.rings.ring import Algebra
    6768        return isinstance(x, Algebra) and x.base_ring() == self.base_ring()
    6869
    69     @cached_method
    7070    def super_categories(self):
    7171        """
    7272        EXAMPLES::
    class Algebras(Category_over_base_ring): 
    7575            [Category of rings, Category of modules over Integer Ring]
    7676        """
    7777        R = self.base_ring()
    78         from sage.categories.rings import Rings
    79         from sage.categories.modules import Modules
    8078        return [Rings(), Modules(R)]
    8179
    8280    class ParentMethods: # (Algebra):  # Eventually, the content of Algebra should be moved here
  • sage/categories/bialgebras.py

    diff --git a/sage/categories/bialgebras.py b/sage/categories/bialgebras.py
    a b class Bialgebras(Category_over_base_ring 
    2929        sage: TestSuite(Bialgebras(ZZ)).run()
    3030    """
    3131
    32     @cached_method
    3332    def super_categories(self):
    3433        """
    3534        EXAMPLES::
  • sage/categories/bimodules.py

    diff --git a/sage/categories/bimodules.py b/sage/categories/bimodules.py
    a b Bimodules 
    1313
    1414from sage.categories.category import Category
    1515from sage.misc.cachefunc import cached_method
     16from sage.categories.left_modules import LeftModules
     17from sage.categories.right_modules import RightModules
     18
    1619from sage.categories.rings import Rings
    1720_Rings = Rings()
    1821
    class Bimodules(Category): 
    103106        from sage.misc.latex import latex
    104107        return "{%s}_{%s}_{%s}"%(Category._latex_(self), latex(self._left_base_ring), latex(self._right_base_ring))
    105108
    106     @cached_method
    107109    def super_categories(self):
    108110        """
    109111        EXAMPLES::
    class Bimodules(Category): 
    113115        """
    114116        R = self.left_base_ring()
    115117        S = self.right_base_ring()
    116         from sage.categories.left_modules import LeftModules
    117         from sage.categories.right_modules import RightModules
    118118        return [LeftModules(R), RightModules(S)]
    119119
    120120    class ParentMethods:
  • sage/categories/cartesian_product.py

    diff --git a/sage/categories/cartesian_product.py b/sage/categories/cartesian_product.py
    a b class CartesianProductsCategory(Covarian 
    145145        """
    146146        return self
    147147
    148     def base(self):
     148    def base_ring(self):
    149149        """
    150         The base of a cartesian product is the base (usually a ring) of the underlying category.
     150        The base ring of a cartesian product is the base ring of the underlying category.
    151151
    152152        EXAMPLES::
    153153
    154             sage: Algebras(ZZ).CartesianProducts().base()
     154            sage: Algebras(ZZ).CartesianProducts().base_ring()
    155155            Integer Ring
    156156        """
    157         return self.base_category().base()
     157        return self.base_category().base_ring()
    158158
    159159# This is Category.CartesianProducts
    160160def CartesianProducts(self):
  • sage/categories/category.py

    diff --git a/sage/categories/category.py b/sage/categories/category.py
    a b A parent ``P`` is in a category ``C`` if 
    9898from sage.misc.abstract_method import abstract_method, abstract_methods_of_class
    9999from sage.misc.lazy_attribute import lazy_attribute
    100100from sage.misc.cachefunc import cached_method, cached_function
     101from sage.misc.c3 import C3_algorithm, C3_algorithm_set
    101102#from sage.misc.misc import attrcall
    102103
    103104from sage.structure.sage_object import SageObject
    def _join(categories, as_list): 
    135136
    136137    # Ensure associativity by flattening JoinCategory's
    137138    # Invariant: the super categories of a JoinCategory are not JoinCategories themselves
    138     categories = sum( (tuple(category.super_categories()) if isinstance(category, JoinCategory) else (category,)
     139    categories = sum( (tuple(category._super_categories) if isinstance(category, JoinCategory) else (category,)
    139140                       for category in categories), ())
    140141
    141142    # remove redundant categories which are super categories of others
    class Category(UniqueRepresentation, Sag 
    228229        sage: from sage.categories.all import Category
    229230        sage: from sage.misc.lazy_attribute import lazy_attribute
    230231        sage: class As (Category):
    231         ...       @cached_method
    232232        ...       def super_categories(self):
    233233        ...           return []
    234234        ...
    class Category(UniqueRepresentation, Sag 
    238238        ...           f = fA
    239239        ...
    240240        sage: class Bs (Category):
    241         ...       @cached_method
    242241        ...       def super_categories(self):
    243242        ...           return [As()]
    244243        ...
    class Category(UniqueRepresentation, Sag 
    247246        ...               return "B"
    248247        ...
    249248        sage: class Cs (Category):
    250         ...       @cached_method
    251249        ...       def super_categories(self):
    252250        ...           return [As()]
    253251        ...
    class Category(UniqueRepresentation, Sag 
    257255        ...           f = fC
    258256        ...
    259257        sage: class Ds (Category):
    260         ...       @cached_method
    261258        ...       def super_categories(self):
    262259        ...           return [Bs(),Cs()]
    263260        ...
    class Category(UniqueRepresentation, Sag 
    275272        True
    276273
    277274    We construct a parent in the category Ds() (that is an instance of
    278     Ds().parent_class, and check that it has access to all the
     275    Ds().parent_class), and check that it has access to all the
    279276    methods provided by all the categories, with the appropriate
    280277    inheritance order.
    281278    ::
    class Category(UniqueRepresentation, Sag 
    426423        EXAMPLES::
    427424
    428425            sage: class SemiprimitiveRings(Category):
    429             ...       @cached_method
    430426            ...       def super_categories(self):
    431427            ...           return [Rings()]
    432428            ...
    class Category(UniqueRepresentation, Sag 
    610606#         """
    611607#         return hash(self.__category) # Any reason not to use id?
    612608
     609    def _subcategory_hook_(self, C):
     610        """
     611        Quick subcategory check.
     612
     613        INPUT:
     614
     615        ``C`` - a category
     616
     617        OUTPUT:
     618
     619        - True, if ``C`` is a subcategory of ``self``.
     620        - False, if ``C`` is not a subcategory of ``self``.
     621        - ``NotImplemented``, if a quick check was not enough to determine
     622          whether ``C`` is a subcategory of ``self`` or not.
     623
     624        NOTE:
     625
     626        This default implementation tests whether the parent class
     627        of ``C`` is a subclass of the parent class of ``self``.
     628        Currently (as of trac ticket #11900) this is a complete
     629        subcategory test. But this will change with trac ticket #11935.
     630
     631        The aim of this method is to offer a framework to add
     632        a cheap test for subcategories. When doing
     633        ``C.is_subcategory(self)`` (note the reverse order of
     634        ``self`` and ``C``), this method is usually called first.
     635        Only if it returns ``NotImplemented``,
     636        :meth:`is_subcategory` will determine the list of super
     637        categories of ``C``.
     638
     639        It is not needed to deal with the case that ``C`` is
     640        ``self``, because this is the first test that is done
     641        in :meth:`is_subcategory`.
     642
     643        OUTPUT:
     644
     645        - ``True``, if it is certain that ``C`` is a subcategory
     646          of self.
     647        - ``False``, if it is certain that ``C`` is no subcategory
     648          of self.
     649        - ``NotImplemented``, if the question whether ``C`` is
     650          a subcategory of self shall be answered by studying the
     651          list of super-categories of ``C``.
     652
     653        EXAMPLE::
     654
     655            sage: Rings()._subcategory_hook_(Rings())
     656            True
     657        """
     658        # return True if C is a proper sub-category of self;
     659        # It is not needed to consider the case "C is self".
     660        # return False if C is clearly not a sub-category
     661        # of self.
     662        # return NotImplemented otherwise.
     663        return issubclass(C.parent_class, self.parent_class)
     664
    613665    def __contains__(self, x):
    614666        """
    615667        Membership testing
    class Category(UniqueRepresentation, Sag 
    807859             Category of sets with partial maps,
    808860             Category of objects]
    809861        """
    810         done = set()
    811         linear_extension = []
    812         for cat in reversed(self._all_super_categories_raw()):
    813             if not cat in done:
    814                 done.add(cat)
    815                 linear_extension.append(cat)
    816         linear_extension.reverse()
     862        return C3_algorithm(self,'_super_categories','_all_super_categories',False)
     863
     864    @lazy_attribute
     865    def _all_super_categories_proper(self):
     866        r"""
     867        All proper super categories of this category.
     868
     869        NOTE:
     870
     871        By trac ticket #11943, the order of super categories
     872        is determined by the C3 algorithm.
     873
     874        EXAMPLES::
     875
     876            sage: C = GradedHopfAlgebrasWithBasis(QQ).abstract_category(); C
     877            Category of abstract graded hopf algebras with basis over Rational Field
     878            sage: C._all_super_categories_proper
     879            [Category of graded hopf algebras over Rational Field,
     880             Category of graded bialgebras over Rational Field,
     881             Category of graded algebras over Rational Field,
     882             Category of graded coalgebras over Rational Field,
     883             Category of graded modules over Rational Field,
     884             Category of hopf algebras over Rational Field,
     885             Category of bialgebras over Rational Field,
     886             Category of algebras over Rational Field,
     887             ...]
     888        """
     889        return C3_algorithm(self,'_super_categories','_all_super_categories',True)
     890
     891    @lazy_attribute
     892    def _set_of_super_categories(self):
     893        """
     894        The frozen set of all proper super categories of this category.
     895
     896        NOTE:
     897
     898        This is used for a speed-up in category containment tests.
     899
     900        TEST::
     901
     902            sage: C = HopfAlgebrasWithBasis(GF(7))
     903            sage: C._set_of_super_categories == frozenset(C._all_super_categories_proper)
     904            True
     905        """
     906        try:
     907            return frozenset(self.__dict__['_all_super_categories_proper'])
     908        except KeyError:
     909            return frozenset(C3_algorithm_set(self,'_super_categories','_all_super_categories',True))
     910
     911    def all_super_categories(self, proper=False):
     912        """
     913        Returns the list of all super categories of this category.
     914
     915        NOTE:
     916
     917        By trac ticket #11943, the order of super categories
     918        is determined by the :func:`~sage.misc.c3.C3_algorithm`.
     919
     920        INPUT:
     921
     922         - ``proper``: a boolean; defaults to False.  Whether to exclude this category.       
     923
     924        NOTE:
     925
     926        This method exists for convenience. However, the developers
     927        are advised to use the lazy attribute ``_all_super_categories``
     928        or ``_all_super_categories_proper`` when asking for the super
     929        categories - simply because a lazy attribute is much faster
     930        than any method.
     931
     932        EXAMPLE::
     933
     934            sage: Sets().all_super_categories()
     935            [Category of sets, Category of sets with partial maps, Category of objects]
     936            sage: Sets().all_super_categories(proper=True)
     937            [Category of sets with partial maps, Category of objects]
     938            sage: Sets().all_super_categories() is Sets()._all_super_categories
     939            True
     940            sage: Sets().all_super_categories(proper=True) is Sets()._all_super_categories_proper
     941            True
     942
     943        """
    817944        if proper:
    818             return linear_extension
    819         else:
    820             return [self] + linear_extension
     945            return self._all_super_categories_proper
     946        return self._all_super_categories
     947
     948    @lazy_attribute
     949    def _super_categories(self):
     950        """
     951        Returns the immediate super categories of this category.
     952
     953        NOTE:
     954
     955        For implementing this lazy attribute, you must provide
     956        a method :meth:`super_categories`. However, the developers
     957        are advised to use the lazy attribute ``_super_categories``
     958        when asking for the super categories - simply because a
     959        lazy attribute is much faster than any method.
     960        """
     961        return self.super_categories()
     962
     963    def super_categories(self):
     964        """
     965        Implement this method to provide the *immediate* super categories.
     966
     967        NOTE:
     968
     969        The order of immediate super categories matters in exactly the
     970        same way as the order of base classes of a Python class
     971        matters. In fact, by trac ticket #11943, the category
     972        framework of Sage uses the same algorithm for determining the
     973        order on the list of *all* super categories that Python is
     974        using for the method resolution order of new style classes.
     975
     976        NOTE:
     977
     978        In order to avoid overhead, the developers are advised to use
     979        the lazy attribute ``_super_categories``. While
     980        ``super_categories()`` must be provided, but it should not be
     981        called, for the sake of speed.
     982        """
     983        raise NotImplementedError
     984
     985    def _test_category_graph(self, **options):
     986        """
     987        Verify that Python's method resolution coincides with the category graph.
     988
     989        NOTE:
     990
     991        By trac ticket #11943, the list of categories returned by :meth:`all_super_categories`
     992        is supposed to correspond to the method resolution order of the parent or element
     993        classes. This method verifies it.
     994
     995        TODO:
     996
     997        Currently, it won't work for hom categories.
     998
     999        EXAMPLE::
     1000
     1001            sage: C = HopfAlgebrasWithBasis(QQ)
     1002            sage: C.parent_class.mro() == [X.parent_class for X in C._all_super_categories] + [object]
     1003            True
     1004            sage: C.element_class.mro() == [X.element_class for X in C._all_super_categories] + [object]
     1005            True
     1006            sage: TestSuite(C).run()    # indirect doctest
     1007
     1008        """
     1009        tester = self._tester(**options)
     1010        tester.assert_(self.parent_class.mro() == [C.parent_class for C in self._all_super_categories] + [object])
     1011        tester.assert_(self.element_class.mro() == [C.element_class for C in self._all_super_categories] + [object])
    8211012
    8221013#    def construction(self):
    8231014#        return (self.__class__,)
    class Category(UniqueRepresentation, Sag 
    8611052        # super categories, but not on the base (except when the super categories depend
    8621053        # on the base). When that is done, calling the cached function will be needed again.
    8631054        #return dynamic_class("%s.parent_class"%self.__class__.__name__,
    864         #                     tuple(cat.parent_class for cat in self.super_categories()),
     1055        #                     tuple(cat.parent_class for cat in self.super_categories),
    8651056        #                     self.ParentMethods,
    8661057        #                     reduction = (getattr, (self, "parent_class")))
    8671058        return dynamic_class_internal.f("%s.parent_class"%self.__class__.__name__,
    868                              tuple(cat.parent_class for cat in self.super_categories()),
     1059                             tuple(cat.parent_class for cat in self._super_categories),
    8691060                             self.ParentMethods,
    8701061                             reduction = (getattr, (self, "parent_class")))
    8711062
    class Category(UniqueRepresentation, Sag 
    8921083        # super categories, but not on the base (except when the super categories depend
    8931084        # on the base). When that is done, calling the cached function will be needed again.
    8941085        #return dynamic_class("%s.element_class"%self.__class__.__name__,
    895         #                     (cat.element_class for cat in self.super_categories()),
     1086        #                     (cat.element_class for cat in self.super_categories),
    8961087        #                     self.ElementMethods,
    8971088        #                     reduction = (getattr, (self, "element_class"))
    8981089        #                     )
    8991090        return dynamic_class_internal.f("%s.element_class"%self.__class__.__name__,
    900                              tuple(cat.element_class for cat in self.super_categories()),
     1091                             tuple(cat.element_class for cat in self._super_categories),
    9011092                             self.ElementMethods,
    9021093                             reduction = (getattr, (self, "element_class")))
    9031094
    class Category(UniqueRepresentation, Sag 
    9161107
    9171108
    9181109    # Operations on the lattice of categories
    919     @cached_method
    9201110    def is_subcategory(self, c):
    9211111        """
    9221112        Returns True if self is naturally embedded as a subcategory of c.
    class Category(UniqueRepresentation, Sag 
    9611151        """
    9621152        if c is self:
    9631153            return True
    964         assert(isinstance(c, Category))
    965         if isinstance(c, JoinCategory):
    966             return all(self.is_subcategory(x) for x in c.super_categories())
    967         if isinstance(self, JoinCategory):
    968             for cat in self.super_categories():
    969                 if cat.is_subcategory(c):
    970                     return True
    971             return False
    972         try:
    973             cbase = c.base()
    974         except (AttributeError, TypeError, NotImplementedError):
    975             cbase = None
    976         if cbase is not None:
    977             try:
    978                 selfbase = self.base()
    979             except (AttributeError, TypeError, NotImplementedError):
    980                 selfbase = None
    981             if selfbase is not cbase:
    982                 return False
    983         return c in self.all_super_categories()
     1154        subcat_hook = c._subcategory_hook_(self)
     1155        if subcat_hook is NotImplemented:
     1156            return c in self._set_of_super_categories
     1157        return subcat_hook
    9841158
    9851159    def or_subcategory(self, category = None):
    9861160        """
    class Category(UniqueRepresentation, Sag 
    10401214        if isinstance(c, Category):
    10411215            return self.is_subcategory(c)
    10421216        else:
    1043             return any(isinstance(cat, c) for cat in self.all_super_categories())
     1217            return any(isinstance(cat, c) for cat in self._all_super_categories)
    10441218
    10451219    @cached_method
    10461220    def _meet_(self, other):
    class Category(UniqueRepresentation, Sag 
    10971271            # %time L = EllipticCurve('960d1').prove_BSD()
    10981272            return self
    10991273        else:
    1100             return Category.join(self._meet_(sup) for sup in other.super_categories())
     1274            return Category.join(self._meet_(sup) for sup in other._super_categories)
    11011275
    11021276    @staticmethod
    11031277    def meet(categories):
    class Category(UniqueRepresentation, Sag 
    11451319            Join of Category of groups and Category of commutative additive monoids
    11461320            sage: J.super_categories()
    11471321            [Category of groups, Category of commutative additive monoids]
    1148             sage: J.all_super_categories(proper = True)
     1322            sage: J.all_super_categories(proper=True)
    11491323            [Category of groups,
    11501324             Category of monoids,
    11511325             Category of semigroups,
    class Category(UniqueRepresentation, Sag 
    12341408        try: #if hasattr(self, "HomCategory"):
    12351409            return self.HomCategory(self)
    12361410        except AttributeError:
    1237             return Category.join((category.hom_category() for category in self.super_categories()))
     1411            return Category.join((category.hom_category() for category in self._super_categories))
    12381412
    12391413    def example(self, *args, **keywords):
    12401414        """
    def category_graph(categories = None): 
    13441518        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 ]
    13451519    cats = set()
    13461520    for category in categories:
    1347         for cat in category.all_super_categories():
     1521        for cat in category._all_super_categories:
    13481522            cats.add(cat)
    13491523
    13501524    categories = cats
    def category_graph(categories = None): 
    13521526    for cat in categories:
    13531527        g.add_vertex(cat._repr_object_names())
    13541528        for source in categories:
    1355             for target in source.super_categories():
     1529            for target in source._super_categories:
    13561530                g.add_edge([source._repr_object_names(), target._repr_object_names()])
    13571531    return g
    13581532
    class HomCategory(Category): 
    13641538    """
    13651539    An abstract base class for all categories of homsets
    13661540
    1367     The hierarchy of homset categories is built in parallel to that of
    1368     their base categories (which is plain wrong!!!)
     1541    .. todo::
     1542
     1543        Get a consistent hierarchy of homset categories. Currently, it
     1544        is built in parallel to that of their base categories (which
     1545        is plain wrong!!!)
    13691546
    13701547    """
    13711548    def __init__(self, category, name=None):
    class HomCategory(Category): 
    13761553         - ``category`` -- the category whose Homsets are the objects of this category.
    13771554         - ``name`` -- An optional name for this category.
    13781555
    1379         EXAMPLES::
     1556        EXAMPLES:
     1557
     1558        We need to skip one test, since the hierarchy of hom categories isn't
     1559        consistent yet::
    13801560
    13811561            sage: C = sage.categories.category.HomCategory(Rings()); C
    13821562            Category of hom sets in Category of rings
    1383             sage: TestSuite(C).run()
     1563            sage: TestSuite(C).run(skip=['_test_category_graph'])
    13841564        """
    13851565        Category.__init__(self, name)
    13861566        self.base_category = category
    class HomCategory(Category): 
    14081588
    14091589        """
    14101590        from sage.categories.category_types import Category_over_base
    1411         for C in self.all_super_categories():
     1591        for C in self._all_super_categories_proper:
    14121592            if isinstance(C,Category_over_base):
    14131593                return C.base()
    14141594        raise AttributeError, "This hom category has no base"
    14151595
    1416     @cached_method
    14171596    def super_categories(self):
    14181597        """
    14191598        Returns the immediate super categories, as per :meth:`Category.super_categories`.
    class HomCategory(Category): 
    14251604        """
    14261605        return Category.join(self.extra_super_categories() +
    14271606                             [category.hom_category()
    1428                               for category in self.base_category.super_categories()],
     1607                              for category in self.base_category._super_categories],
    14291608                             as_list=True)
    14301609    @cached_method
    14311610    def extra_super_categories(self):
    class JoinCategory(Category): 
    14571636        Join of Category of groups and Category of commutative additive monoids
    14581637        sage: J.super_categories()
    14591638        [Category of groups, Category of commutative additive monoids]
    1460         sage: J.all_super_categories(proper = True)
     1639        sage: J.all_super_categories(proper=True)
    14611640        [Category of groups, Category of monoids, Category of semigroups, Category of magmas, Category of commutative additive monoids, Category of commutative additive semigroups, Category of additive magmas, Category of sets, Category of sets with partial maps, Category of objects]
    14621641    """
    14631642
    class JoinCategory(Category): 
    14791658            sage: C = JoinCategory((Groups(), CommutativeAdditiveMonoids())); C
    14801659            Join of Category of groups and Category of commutative additive monoids
    14811660            sage: TestSuite(C).run()
     1661
    14821662        """
    14831663        assert(len(super_categories) >= 2)
    14841664        assert(all(not isinstance(category, JoinCategory) for category in super_categories))
    class JoinCategory(Category): 
    15001680        """
    15011681        return self._super_categories
    15021682
     1683    def _subcategory_hook_(self, C):
     1684        """
     1685        Tells whether this join category contains another category as a subcategory.
     1686
     1687        INPUT:
     1688
     1689        ``C`` -- a category.
     1690
     1691        OUTPUT:
     1692
     1693        Whether ``C`` is sub-category of self or not.
     1694
     1695        NOTE:
     1696
     1697        ``C`` is sub-category of this join category if and only if it is sub-category
     1698        for all super categories of this join category.
     1699
     1700        EXAMPLE::
     1701
     1702            sage: QQ['x'].category().is_subcategory(Category.join([Rings(), VectorSpaces(QQ)]))  # indirect doctest
     1703            True
     1704
     1705        """
     1706        for X in self._super_categories:
     1707            if not C.is_subcategory(X):
     1708                return False
     1709        return True
     1710
    15031711    def _repr_(self):
    15041712        """
    15051713        Print representation.
    class JoinCategory(Category): 
    15161724            sage: Category.join((Sets().Facades(), Groups()))
    15171725            Category of facade groups
    15181726        """
    1519         categories = self.super_categories()
     1727        categories = self._super_categories
    15201728        from sets_cat import Sets
    15211729        if len(categories) == 2 and Sets().Facades() in categories:
    15221730            categories = list(categories)
    15231731            categories.remove(Sets().Facades())
    15241732            return "Category of facade %s"%(categories[0]._repr_object_names())
    1525         return "Join of %s"%(" and ".join(str(cat) for cat in self.super_categories()))
     1733        return "Join of %s"%(" and ".join(str(cat) for cat in categories))
  • sage/categories/category_types.py

    diff --git a/sage/categories/category_types.py b/sage/categories/category_types.py
    a b This is placed in a separate file from c 
    1717from sage.misc.cachefunc import cached_method
    1818from sage.misc.latex import latex
    1919from category import Category
    20 from sage.categories.rings import Rings
    21 _Rings = Rings()
     20from objects import Objects
    2221
    2322####################################################################
    2423#   Different types of categories
    class Elements(Category): 
    7675        """
    7776        return self.__object(x)
    7877
    79     @cached_method
    8078    def super_categories(self):
    8179        """
    8280        EXAMPLES::
    class Elements(Category): 
    8886
    8987        check that this is what we want.
    9088        """
    91         from objects import Objects
    9289        return [Objects()]
    9390
    9491    def object(self):
    class Sequences(Category): 
    153150        from sage.rings.rational_field import QQ
    154151        return cls(QQ)
    155152
    156     @cached_method
    157153    def super_categories(self):
    158154        """
    159155        EXAMPLES::
    class Sequences(Category): 
    161157            sage: Sequences(ZZ).super_categories()
    162158            [Category of objects]
    163159        """
    164         from objects import Objects
    165160        return [Objects()]  # Almost FiniteEnumeratedSets() except for possible repetitions
    166161
    167162    def _call_(self, x):
    class Category_over_base(Category): 
    208203        Category.__init__(self, name)
    209204        self.__base = base
    210205
    211 
    212206    @classmethod
    213207    def an_instance(cls):
    214208        """
    class Category_over_base(Category): 
    260254#############################################################
    261255# Category of objects over some base ring
    262256#############################################################
     257class AbelianCategory(Category):
     258    def is_abelian(self):
     259        return True
     260
    263261class Category_over_base_ring(Category_over_base):
    264262    def __init__(self, base, name=None):
    265         assert base in _Rings, "base must be a ring"
     263        from sage.categories.rings import Rings
     264        assert base in Rings(), "base must be a ring"
    266265        Category_over_base.__init__(self, base, name)
    267266        self.__base = base
    268267
    class Category_over_base_ring(Category_o 
    273272        """
    274273        return self.base()
    275274
    276 class AbelianCategory(Category):
    277     def is_abelian(self):
    278         return True
    279 
    280275#############################################################
    281276# Category of objects in some ambient object
    282277#############################################################
    class SimplicialComplexes(Category): 
    358353        sage: TestSuite(SimplicialComplexes()).run()
    359354    """
    360355
    361     @cached_method
    362356    def super_categories(self):
    363357        """
    364358        EXAMPLES::
    class SimplicialComplexes(Category): 
    366360            sage: SimplicialComplexes().super_categories()
    367361            [Category of objects]
    368362        """
    369         from objects import Objects
    370363        return [Objects()] # anything better?
    371364
    372365#############################################################
    class ChainComplexes(Category_module): 
    389382        sage: TestSuite(ChainComplexes(RationalField())).run()
    390383    """
    391384
    392     @cached_method
    393385    def super_categories(self):
    394386        """
    395387        EXAMPLES::
    class ChainComplexes(Category_module): 
    397389            sage: ChainComplexes(Integers(9)).super_categories()
    398390            [Category of objects]
    399391        """
    400         from objects import Objects
    401392        return [Objects()] # anything better?
  • sage/categories/classical_crystals.py

    diff --git a/sage/categories/classical_crystals.py b/sage/categories/classical_crystals.py
    a b class ClassicalCrystals(Category_singlet 
    5555        running ._test_stembridge_local_axioms() . . . pass
    5656    """
    5757
    58     @cached_method
    5958    def super_categories(self):
    6059        r"""
    6160        EXAMPLES::
  • sage/categories/coalgebras.py

    diff --git a/sage/categories/coalgebras.py b/sage/categories/coalgebras.py
    a b class Coalgebras(Category_over_base_ring 
    4545
    4646        sage: TestSuite(Coalgebras(ZZ)).run()
    4747    """
    48     @cached_method
    4948    def super_categories(self):
    5049        """
    5150        EXAMPLES::
  • sage/categories/commutative_additive_groups.py

    diff --git a/sage/categories/commutative_additive_groups.py b/sage/categories/commutative_additive_groups.py
    a b class CommutativeAdditiveGroups(AbelianC 
    3232        sage: TestSuite(CommutativeAdditiveGroups()).run()
    3333    """
    3434
    35     @cached_method
    3635    def super_categories(self):
    3736        """
    3837        EXAMPLES::
  • sage/categories/commutative_additive_monoids.py

    diff --git a/sage/categories/commutative_additive_monoids.py b/sage/categories/commutative_additive_monoids.py
    a b class CommutativeAdditiveMonoids(Categor 
    3535        sage: TestSuite(CommutativeAdditiveMonoids()).run()
    3636    """
    3737
    38     @cached_method
    3938    def super_categories(self):
    4039        """
    4140        EXAMPLES::
  • sage/categories/commutative_additive_semigroups.py

    diff --git a/sage/categories/commutative_additive_semigroups.py b/sage/categories/commutative_additive_semigroups.py
    a b class CommutativeAdditiveSemigroups(Cate 
    3636
    3737    """
    3838
    39     @cached_method
    4039    def super_categories(self):
    4140        """
    4241        EXAMPLES::
  • sage/categories/commutative_algebra_ideals.py

    diff --git a/sage/categories/commutative_algebra_ideals.py b/sage/categories/commutative_algebra_ideals.py
    a b Commutative algebra ideals 
    1212
    1313from sage.misc.cachefunc import cached_method
    1414from category_types import Category_ideal, Category_in_ambient
     15from algebra_ideals import AlgebraIdeals
    1516
    1617class CommutativeAlgebraIdeals(Category_ideal):
    1718    """
    class CommutativeAlgebraIdeals(Category_ 
    6667        """
    6768        return self.ambient()
    6869
    69     @cached_method
    7070    def super_categories(self):
    7171        """
    7272        EXAMPLES::
    class CommutativeAlgebraIdeals(Category_ 
    7474            sage: CommutativeAlgebraIdeals(QQ[x]).super_categories()
    7575            [Category of algebra ideals in Univariate Polynomial Ring in x over Rational Field]
    7676        """
    77         from algebra_ideals import AlgebraIdeals
    7877        R = self.algebra()
    7978        return [AlgebraIdeals(R)]
  • sage/categories/commutative_ring_ideals.py

    diff --git a/sage/categories/commutative_ring_ideals.py b/sage/categories/commutative_ring_ideals.py
    a b Commutative ring ideals 
    1313from sage.misc.cachefunc import cached_method
    1414from category_types import Category_ideal
    1515from sage.categories.commutative_rings import CommutativeRings
     16from ring_ideals import RingIdeals
    1617
    1718class CommutativeRingIdeals(Category_ideal):
    1819    """
    class CommutativeRingIdeals(Category_ide 
    4546            raise TypeError, "R (=%s) must be a commutative ring"%R
    4647        Category_ideal.__init__(self, R)
    4748
    48     @cached_method
    4949    def super_categories(self):
    5050        """
    5151        EXAMPLES::
    class CommutativeRingIdeals(Category_ide 
    5353            sage: CommutativeRingIdeals(ZZ).super_categories()
    5454            [Category of ring ideals in Integer Ring]
    5555        """
    56         from ring_ideals import RingIdeals
    5756        R = self.ring()
    5857        return [RingIdeals(R)]
  • sage/categories/covariant_functorial_construction.py

    diff --git a/sage/categories/covariant_functorial_construction.py b/sage/categories/covariant_functorial_construction.py
    a b class CovariantConstructionCategory(Cate 
    354354            sage: sage.categories.algebra_functor.AlgebrasCategory.default_super_categories(FiniteMonoids(), QQ)
    355355            Category of monoid algebras over Rational Field
    356356        """
    357         return Category.join([getattr(cat, cls._functor_category)(*args) for cat in category.super_categories()])
     357        return Category.join([getattr(cat, cls._functor_category)(*args) for cat in category._super_categories])
    358358
     359    def is_subcategory(self, C):
     360        if C is self:
     361            return True
     362        for X in self._super_categories:
     363            if X.is_subcategory(C):
     364                return True
     365        return False
    359366
    360367    def __init__(self, category, *args):
    361368        """
    class CovariantConstructionCategory(Cate 
    409416        """
    410417        return []
    411418
    412     @cached_method
    413419    def super_categories(self):
    414420        """
    415421        Returns the super categories of a construction category
  • sage/categories/coxeter_groups.py

    diff --git a/sage/categories/coxeter_groups.py b/sage/categories/coxeter_groups.py
    a b class CoxeterGroups(Category_singleton): 
    9797        running ._test_some_elements() . . . pass
    9898    """
    9999
    100     @cached_method
    101100    def super_categories(self):
    102101        """
    103102        EXAMPLES::
  • sage/categories/crystals.py

    diff --git a/sage/categories/crystals.py b/sage/categories/crystals.py
    a b class Crystals(Category_singleton): 
    8282        running ._test_stembridge_local_axioms() . . . pass
    8383    """
    8484
    85     @cached_method
    8685    def super_categories(self):
    8786        r"""
    8887        EXAMPLES::
  • sage/categories/division_rings.py

    diff --git a/sage/categories/division_rings.py b/sage/categories/division_rings.py
    a b class DivisionRings(Category_singleton): 
    3131        sage: TestSuite(DivisionRings()).run()
    3232    """
    3333
    34     @cached_method
    3534    def super_categories(self):
    3635        """
    3736        EXAMPLES::
  • sage/categories/domains.py

    diff --git a/sage/categories/domains.py b/sage/categories/domains.py
    a b class Domains(Category_singleton): 
    3232        sage: TestSuite(Domains()).run()
    3333    """
    3434
    35     @cached_method
    3635    def super_categories(self):
    3736        """
    3837        EXAMPLES::
  • sage/categories/enumerated_sets.py

    diff --git a/sage/categories/enumerated_sets.py b/sage/categories/enumerated_sets.py
    a b class EnumeratedSets(Category_singleton) 
    8585        sage: TestSuite(C).run()
    8686    """
    8787
    88     @cached_method
    8988    def super_categories(self):
    9089        """
    9190        EXAMPLES::
  • sage/categories/euclidean_domains.py

    diff --git a/sage/categories/euclidean_domains.py b/sage/categories/euclidean_domains.py
    a b class EuclideanDomains(Category_singleto 
    3131        sage: TestSuite(EuclideanDomains()).run()
    3232    """
    3333
    34     @cached_method
    3534    def super_categories(self):
    3635        """
    3736        EXAMPLES::
  • sage/categories/fields.py

    diff --git a/sage/categories/fields.py b/sage/categories/fields.py
    a b Fields 
    1313
    1414from sage.categories.category import Category
    1515from sage.categories.category_singleton import Category_singleton, Category_contains_method_by_parent_class
     16from sage.categories.euclidean_domains import EuclideanDomains
     17from sage.categories.unique_factorization_domains import UniqueFactorizationDomains
     18from sage.categories.division_rings import DivisionRings
     19
    1620from sage.misc.cachefunc import cached_method
    1721from sage.misc.lazy_attribute import lazy_class_attribute
    1822from sage.rings.field import is_Field
    class Fields(Category_singleton): 
    4347        sage: TestSuite(Fields()).run()
    4448    """
    4549
    46     @cached_method
    4750    def super_categories(self):
    4851        """
    4952        EXAMPLES::
    class Fields(Category_singleton): 
    5255            [Category of euclidean domains, Category of unique factorization domains, Category of division rings]
    5356
    5457        """
    55         from sage.categories.basic import EuclideanDomains, UniqueFactorizationDomains, DivisionRings
    5658        return [EuclideanDomains(), UniqueFactorizationDomains(), DivisionRings()]
    5759
    5860    def __contains__(self, x):
  • sage/categories/finite_groups.py

    diff --git a/sage/categories/finite_groups.py b/sage/categories/finite_groups.py
    a b class FiniteGroups(Category): 
    3131        sage: C = FiniteGroups()
    3232        sage: TestSuite(C).run(verbose = True)
    3333        running ._test_category() . . . pass
     34        running ._test_category_graph() . . . pass
    3435        running ._test_not_implemented_methods() . . . pass
    3536        running ._test_pickling() . . . pass
    3637
  • sage/categories/finite_permutation_groups.py

    diff --git a/sage/categories/finite_permutation_groups.py b/sage/categories/finite_permutation_groups.py
    a b class FinitePermutationGroups(Category): 
    3333        sage: C = FinitePermutationGroups()
    3434        sage: TestSuite(C).run(verbose = True)
    3535        running ._test_category() . . . pass
     36        running ._test_category_graph() . . . pass
    3637        running ._test_not_implemented_methods() . . . pass
    3738        running ._test_pickling() . . . pass
    3839
  • sage/categories/finite_semigroups.py

    diff --git a/sage/categories/finite_semigroups.py b/sage/categories/finite_semigroups.py
    a b class FiniteSemigroups(Category): 
    4444        sage: C = FiniteSemigroups()
    4545        sage: TestSuite(C).run(verbose = True)
    4646        running ._test_category() . . . pass
     47        running ._test_category_graph() . . . pass
    4748        running ._test_not_implemented_methods() . . . pass
    4849        running ._test_pickling() . . . pass
    4950
  • sage/categories/g_sets.py

    diff --git a/sage/categories/g_sets.py b/sage/categories/g_sets.py
    a b G-Sets 
    1212
    1313from sage.categories.category import Category
    1414from sage.misc.cachefunc import cached_method
     15from sets_cat import Sets
    1516
    1617#############################################################
    1718# GSets
    class GSets(Category): 
    5152    #def construction(self):
    5253    #    return (self.__class__, self.__G)
    5354
    54     @cached_method
    5555    def super_categories(self):
    5656        """
    5757        EXAMPLES::
    class GSets(Category): 
    5959            sage: GSets(SymmetricGroup(8)).super_categories()
    6060            [Category of sets]
    6161        """
    62         from sets_cat import Sets
    6362        return [Sets()]
    6463
    6564    @classmethod
  • sage/categories/gcd_domains.py

    diff --git a/sage/categories/gcd_domains.py b/sage/categories/gcd_domains.py
    a b Gcd domains 
    1111from sage.categories.category import Category
    1212from sage.categories.category_singleton import Category_singleton
    1313from sage.misc.cachefunc import cached_method
     14from sage.categories.integral_domains import IntegralDomains
    1415
    1516class GcdDomains(Category_singleton):
    1617    """
    class GcdDomains(Category_singleton): 
    3031        sage: TestSuite(GcdDomains()).run()
    3132    """
    3233
    33     @cached_method
    3434    def super_categories(self):
    3535        """
    3636        EXAMPLES::
    class GcdDomains(Category_singleton): 
    3838            sage: GcdDomains().super_categories()
    3939            [Category of integral domains]
    4040        """
    41         from sage.categories.integral_domains import IntegralDomains
    4241        return [IntegralDomains()]
    4342
    4443    class ParentMethods:
  • sage/categories/groupoid.py

    diff --git a/sage/categories/groupoid.py b/sage/categories/groupoid.py
    a b Groupoid 
    1212
    1313from sage.categories.category import Category
    1414from sage.misc.cachefunc import cached_method
     15from sets_cat import Sets
    1516
    1617class Groupoid(Category):
    1718    """
    class Groupoid(Category): 
    5758    #def construction(self):
    5859    #    return (self.__class__, self.__G)
    5960
    60     @cached_method
    6161    def super_categories(self):
    6262        """
    6363        EXAMPLES::
    class Groupoid(Category): 
    6565            sage: Groupoid(DihedralGroup(3)).super_categories()
    6666            [Category of sets]
    6767        """
    68         from sets_cat import Sets
    6968        return [Sets()] # ???
    7069
    7170    @classmethod
  • sage/categories/groups.py

    diff --git a/sage/categories/groups.py b/sage/categories/groups.py
    a b class Groups(Category_singleton): 
    3434        sage: TestSuite(Groups()).run()
    3535    """
    3636
    37     @cached_method
    3837    def super_categories(self):
    3938        """
    4039        EXAMPLES::
    class Groups(Category_singleton): 
    344343                [Category of hopf algebras with basis over Rational Field, Category of monoid algebras over Rational Field]
    345344
    346345                sage: Groups().example().algebra(ZZ).categories()
    347                 [Category of group algebras over Integer Ring, Category of hopf algebras with basis over Integer Ring, Category of bialgebras with basis over Integer Ring, Category of coalgebras with basis over Integer Ring, Category of hopf algebras over Integer Ring, Category of bialgebras over Integer Ring, Category of coalgebras over Integer Ring, Category of monoid algebras over Integer Ring, Category of semigroup algebras over Integer Ring, Category of algebras with basis over Integer Ring, Category of algebras over Integer Ring, Category of rings, Category of rngs, Category of semirings, Category of monoids, Category of semigroups, Category of magmas, Category of set algebras over Integer Ring, Category of modules with basis over Integer Ring, Category of modules over Integer Ring, Category of bimodules over Integer Ring on the left and Integer Ring on the right, Category of left modules over Integer Ring, Category of right modules over Integer Ring, Category of commutative additive groups, Category of commutative additive monoids, Category of commutative additive semigroups, Category of additive magmas, Category of sets, Category of sets with partial maps, Category of objects]
     346                [Category of group algebras over Integer Ring,
     347                 Category of hopf algebras with basis over Integer Ring,
     348                 Category of bialgebras with basis over Integer Ring,
     349                 Category of monoid algebras over Integer Ring,
     350                 Category of semigroup algebras over Integer Ring,
     351                 Category of algebras with basis over Integer Ring,
     352                 Category of coalgebras with basis over Integer Ring,
     353                 Category of set algebras over Integer Ring,
     354                 Category of modules with basis over Integer Ring,
     355                 Category of hopf algebras over Integer Ring,
     356                 Category of bialgebras over Integer Ring,
     357                 Category of algebras over Integer Ring,
     358                 Category of rings,
     359                 Category of rngs,
     360                 Category of coalgebras over Integer Ring,
     361                 Category of modules over Integer Ring,
     362                 Category of bimodules over Integer Ring on the left and Integer Ring on the right,
     363                 Category of left modules over Integer Ring,
     364                 Category of right modules over Integer Ring,
     365                 Category of commutative additive groups,
     366                 Category of semirings,
     367                 Category of commutative additive monoids,
     368                 Category of commutative additive semigroups,
     369                 Category of additive magmas,
     370                 Category of monoids,
     371                 Category of semigroups,
     372                 Category of magmas,
     373                 Category of sets,
     374                 Category of sets with partial maps,
     375                 Category of objects]
    348376            """
    349377            from sage.categories.hopf_algebras_with_basis import HopfAlgebrasWithBasis
    350378            return [HopfAlgebrasWithBasis(self.base_ring())]
  • sage/categories/hecke_modules.py

    diff --git a/sage/categories/hecke_modules.py b/sage/categories/hecke_modules.py
    a b Hecke modules 
    1313from sage.categories.category_types import Category_module
    1414from sage.misc.cachefunc import cached_method
    1515from sage.categories.category import HomCategory
     16from sage.categories.all import ModulesWithBasis
    1617
    1718class HeckeModules(Category_module):
    1819    r"""
    class HeckeModules(Category_module): 
    7374            raise TypeError, "R (=%s) must be a commutative ring"%R
    7475        Category_module.__init__(self, R, "Hecke modules")
    7576
    76     @cached_method
    7777    def super_categories(self):
    7878        """
    7979        EXAMPLES::
    class HeckeModules(Category_module): 
    8181            sage: HeckeModules(QQ).super_categories()
    8282            [Category of modules with basis over Rational Field]
    8383        """
    84         from sage.categories.all import ModulesWithBasis
    8584        R = self.base_ring()
    8685        return [ModulesWithBasis(R)]
    8786
  • sage/categories/highest_weight_crystals.py

    diff --git a/sage/categories/highest_weight_crystals.py b/sage/categories/highest_weight_crystals.py
    a b class HighestWeightCrystals(Category_sin 
    5858        running ._test_stembridge_local_axioms() . . . pass
    5959    """
    6060
    61     @cached_method
    6261    def super_categories(self):
    6362        r"""
    6463        EXAMPLES::
  • sage/categories/hopf_algebras.py

    diff --git a/sage/categories/hopf_algebras.py b/sage/categories/hopf_algebras.py
    a b class HopfAlgebras(Category_over_base_ri 
    3232        sage: TestSuite(HopfAlgebras(ZZ)).run()
    3333    """
    3434
    35     @cached_method
    3635    def super_categories(self):
    3736        """
    3837        EXAMPLES::
  • sage/categories/integral_domains.py

    diff --git a/sage/categories/integral_domains.py b/sage/categories/integral_domains.py
    a b Integral domains 
    1111from sage.categories.category import Category
    1212from sage.categories.category_singleton import Category_singleton
    1313from sage.misc.cachefunc import cached_method
     14from sage.categories.commutative_rings import CommutativeRings
     15from sage.categories.domains import Domains
    1416
    1517class IntegralDomains(Category_singleton):
    1618    """
    class IntegralDomains(Category_singleton 
    2931        sage: TestSuite(IntegralDomains()).run()
    3032    """
    3133
    32     @cached_method
    3334    def super_categories(self):
    3435        """
    3536        EXAMPLES::
    class IntegralDomains(Category_singleton 
    3738            sage: IntegralDomains().super_categories()
    3839            [Category of commutative rings, Category of domains]
    3940        """
    40         from sage.categories.basic import CommutativeRings, Domains
    4141        return [CommutativeRings(), Domains()]
    4242
    4343    class ParentMethods:
  • sage/categories/left_modules.py

    diff --git a/sage/categories/left_modules.py b/sage/categories/left_modules.py
    a b Left modules 
    1010
    1111from category_types import Category_over_base_ring
    1212from sage.misc.cachefunc import cached_method
     13from sage.categories.commutative_additive_groups import CommutativeAdditiveGroups
    1314
    1415#?class LeftModules(Category_over_base_rng):
    1516class LeftModules(Category_over_base_ring):
    class LeftModules(Category_over_base_rin 
    3031        sage: TestSuite(LeftModules(ZZ)).run()
    3132    """
    3233
    33     @cached_method
    3434    def super_categories(self):
    3535        """
    3636        EXAMPLES::
    class LeftModules(Category_over_base_rin 
    3838            sage: LeftModules(QQ).super_categories()
    3939            [Category of commutative additive groups]
    4040        """
    41         from sage.categories.commutative_additive_groups import CommutativeAdditiveGroups
    4241        return [CommutativeAdditiveGroups()]
    4342
    4443    class ParentMethods:
  • sage/categories/magmas.py

    diff --git a/sage/categories/magmas.py b/sage/categories/magmas.py
    a b class Magmas(Category_singleton): 
    3636        sage: C = Magmas()
    3737        sage: TestSuite(C).run(verbose=True)
    3838        running ._test_category() . . . pass
     39        running ._test_category_graph() . . . pass
    3940        running ._test_not_implemented_methods() . . . pass
    4041        running ._test_pickling() . . . pass
    4142
    4243    """
    43     @cached_method
    4444    def super_categories(self):
    4545        """
    4646        EXAMPLES::
  • sage/categories/matrix_algebras.py

    diff --git a/sage/categories/matrix_algebras.py b/sage/categories/matrix_algebras.py
    a b Matrix algebras 
    1212
    1313from category_types import Category_over_base_ring
    1414from sage.misc.cachefunc import cached_method
     15from algebras import Algebras
    1516
    1617class MatrixAlgebras(Category_over_base_ring):
    1718    """
    class MatrixAlgebras(Category_over_base_ 
    2728        sage: TestSuite(MatrixAlgebras(ZZ)).run()
    2829    """
    2930
    30     @cached_method
    3131    def super_categories(self):
    3232        """
    3333        EXAMPLES::
    class MatrixAlgebras(Category_over_base_ 
    3535            sage: MatrixAlgebras(QQ).super_categories()
    3636            [Category of algebras over Rational Field]
    3737        """
    38         from algebras import Algebras
    3938        R = self.base_ring()
    4039        return [Algebras(R)]
  • sage/categories/modular_abelian_varieties.py

    diff --git a/sage/categories/modular_abelian_varieties.py b/sage/categories/modular_abelian_varieties.py
    a b Modular abelian varieties 
    1212
    1313from category_types import Category_over_base
    1414from sage.misc.cachefunc import cached_method
     15from sets_cat import Sets
    1516
    1617class ModularAbelianVarieties(Category_over_base):
    1718    """
    class ModularAbelianVarieties(Category_o 
    4950        """
    5051        return self.base()
    5152
    52     @cached_method
    5353    def super_categories(self):
    5454        """
    5555        EXAMPLES::
    class ModularAbelianVarieties(Category_o 
    5757            sage: ModularAbelianVarieties(QQ).super_categories()
    5858            [Category of sets]
    5959        """
    60         from sets_cat import Sets
    6160        return [Sets()] # FIXME
  • sage/categories/modules.py

    diff --git a/sage/categories/modules.py b/sage/categories/modules.py
    a b Modules 
    1414from sage.categories.category import HomCategory
    1515from category_types import Category_module
    1616from sage.misc.cachefunc import cached_method
     17from sage.categories.bimodules import Bimodules
    1718from sage.categories.fields import Fields
    1819_Fields = Fields()
    1920from vector_spaces import VectorSpaces
    class Modules(Category_module): 
    120121        result._reduction[2]['dispatch'] = False
    121122        return result
    122123
    123     @cached_method
    124124    def super_categories(self):
    125125        """
    126126        EXAMPLES::
    class Modules(Category_module): 
    136136            [Category of modules over Rational Field]
    137137        """
    138138        R = self.base_ring()
    139         from sage.categories.bimodules import Bimodules
    140139        return [Bimodules(R,R)]
    141140
    142141    class ParentMethods:
  • sage/categories/monoids.py

    diff --git a/sage/categories/monoids.py b/sage/categories/monoids.py
    a b class Monoids(Category_singleton): 
    4646        sage: TestSuite(C).run()
    4747
    4848    """
    49     @cached_method
    5049    def super_categories(self):
    5150        """
    5251        Returns a list of the immediate super categories of ``self``.
  • sage/categories/number_fields.py

    diff --git a/sage/categories/number_fields.py b/sage/categories/number_fields.py
    a b class NumberFields(Category_singleton): 
    5555        sage: TestSuite(NumberFields()).run()
    5656    """
    5757
    58     @cached_method
    5958    def super_categories(self):
    6059        """
    6160        EXAMPLES::
  • sage/categories/objects.py

    diff --git a/sage/categories/objects.py b/sage/categories/objects.py
    a b class Objects(Category): 
    3838        sage: TestSuite(Objects()).run()
    3939    """
    4040
    41     @cached_method
    4241    def super_categories(self):
    4342        """
    4443        EXAMPLES::
  • sage/categories/partially_ordered_monoids.py

    diff --git a/sage/categories/partially_ordered_monoids.py b/sage/categories/partially_ordered_monoids.py
    a b class PartiallyOrderedMonoids(Category_s 
    3333        sage: TestSuite(PartiallyOrderedMonoids()).run()
    3434    """
    3535
    36     @cached_method
    3736    def super_categories(self):
    3837        """
    3938        EXAMPLES::
  • sage/categories/pointed_sets.py

    diff --git a/sage/categories/pointed_sets.py b/sage/categories/pointed_sets.py
    a b Pointed sets 
    1313from sage.categories.category import Category
    1414from sage.categories.category_singleton import Category_singleton
    1515from sage.misc.cachefunc import cached_method
     16from sets_cat import Sets
    1617
    1718class PointedSets(Category_singleton):
    1819    """
    class PointedSets(Category_singleton): 
    3132    #    import sage.sets.all
    3233    #    return sage.sets.all.Set(X, pt)
    3334
    34     @cached_method
    3535    def super_categories(self):
    3636        """
    3737        EXAMPLES::
    class PointedSets(Category_singleton): 
    3939            sage: PointedSets().super_categories()
    4040            [Category of sets]
    4141        """
    42         from sets_cat import Sets
    4342        return [Sets()] # ???
  • sage/categories/primer.py

    diff --git a/sage/categories/primer.py b/sage/categories/primer.py
    a b Functorial constructions 
    546546     Category of algebras over Rational Field,
    547547     Category of rings,
    548548     Category of rngs,
    549      Category of semirings,
    550549     Category of vector spaces over Rational Field,
    551550     Category of modules over Rational Field,
    552551     Category of bimodules over Rational Field on the left and Rational Field on the right,
    553552     Category of left modules over Rational Field,
    554553     Category of right modules over Rational Field,
    555554     Category of commutative additive groups,
     555     Category of semirings,
    556556     Category of commutative additive monoids,
    557557     Category of commutative additive semigroups,
    558558     Category of additive magmas,
    Wrapup: 
    613613Writing a new category
    614614----------------------
    615615
    616 Each category should come with a good example, in sage.categories.examples.
     616Each category `C` **must** be provided with a method ``C.super_categories()``
     617and *can* be provided with a method ``C._subcategory_hook_(D)``. Also, it
     618may be needed to insert `C` into the output of the ``super_categories()`` method
     619of some other category. This determines the position of `C` in the category graph.
    617620
    618 The order between super categories should not be mathematically
    619 relevant (otherwise this usually means the category hierarchy is
    620 wrong). On the other hand, it should be consistent, to help Python
    621 build the method resolution order for the generated classes (it always
    622 respects inheritance, and tries to respect the order of the bases).
     621A category *may* provide methods that can be used by all its objects,
     622respectively by all elements of its objects.
    623623
    624 The current convention is to order them lexicographically w.r.t. the
    625 following criterions:
     624Each category *should* come with a good example, in sage.categories.examples.
     625
     626Inserting the new category into the category graph
     627..................................................
     628
     629``C.super_categories()``  must return a list of categories, namely
     630the *immediate* super categories of `C`. The generic method
     631``C.all_super_categories()`` will recursively determine the list
     632of *all* super categories of `C`, by using the so-called C3 algorithm,
     633that is also used for the method resolution order of new-style classes
     634in Python (see trac ticket #11943).
     635
     636Of course, if you know that your new category `C` is immediate
     637super category of an existing category `D`, then you should modify
     638`D`'s ``super_categories`` method so that `C` is included.
     639
     640Although the order between super categories should not be mathematically
     641relevant, the order *is* relevant for inheritance of methods. Namely,
     642a category can provide methods for all its objects and for the elements
     643for all its objects. If `P` is an object in the category `C` and if
     644`C_1` and `C_2` are both super categories of `C` defining some method
     645``foo``, then `P` will use `C_1`'s version of ``foo`` only if `C_1`
     646appears in ``C.all_super_categories()`` before `C_2`.
     647
     648Also, the C3 algorithm will only be able to determine a consistent order
     649on the list of all super categories if the orders on the different lists
     650of *immediate* super categories is sane. See :func:`sage.misc.c3.C3_algorithm`
     651and :meth:`sage.categories.category.Category.all_super_categories` for examples.
     652
     653It is thus useful to follow certain conventions when ordering the
     654immediate super categories. The current convention is to order them
     655lexicographically w.r.t. the following criteria:
    626656
    627657 - Graded... or Finite dimensional... first
    628658 - ...WithBasis first
    This gives the following order:: 
    652682     Category of algebras over Rational Field,
    653683     Category of rings,
    654684     Category of rngs,
    655      Category of semirings,
    656      Category of monoids,
    657      Category of semigroups,
    658      Category of magmas,
    659685     Category of coalgebras over Rational Field,
    660686     Category of vector spaces over Rational Field,
    661687     Category of modules over Rational Field,
    This gives the following order:: 
    663689     Category of left modules over Rational Field,
    664690     Category of right modules over Rational Field,
    665691     Category of commutative additive groups,
     692     Category of semirings,
    666693     Category of commutative additive monoids,
    667694     Category of commutative additive semigroups,
    668695     Category of additive magmas,
     696     Category of monoids,
     697     Category of semigroups,
     698     Category of magmas,
    669699     Category of sets,
    670700     Category of sets with partial maps,
    671701     Category of objects]
    672702
    673 Todo: any better convention? Maybe we should further specify that subcategories of Modules() go first?
     703When in doubt, ``C.is_subcategory(D)`` returns True if and only
     704if `D` appears in ``C.all_super_categories()``. However,
     705creating the list of all super categories is an expensive
     706operation that can sometimes be avoided. For example, if
     707both `C` and `D` are categories defined over a base, but the
     708bases differ, then they can not be subcategories of each other.
     709
     710If such a short-path is known, one can implement a method
     711``_subcategory_hook_``. ``C.is_subcategory(D)`` first calls
     712``D._subcategory_hook_(C)``. If this returns ``NotImplemented``, then
     713``C.is_subcategory(D)`` tries to find ``D`` in
     714``C.all_super_categories()``. Otherwise, ``C.is_subcategory(D)``
     715returns the result of ``D._subcategory_hook_(C)``.
     716
     717By default, ``D._subcategory_hook_(C)`` tests
     718``issubclass(C.parent_class,D.parent_class)``, which is very often
     719giving the right answer::
     720
     721    sage: Rings()._subcategory_hook_(Algebras(QQ))
     722    True
     723    sage: HopfAlgebras(QQ)._subcategory_hook_(Algebras(QQ))
     724    False
     725    sage: Algebras(QQ)._subcategory_hook_(HopfAlgebras(QQ))
     726    True
     727
     728Methods for objects and elements
     729................................
     730
     731Different objects of the same category share some algebraic features, and
     732very often these features can be encoded in a method, in a generic way.
     733For example, for every commutative additive monoid, it makes sense to ask
     734for the sum of a list of elements. Sage's category framework allows to
     735provide a generic implementation for all objects of a category.
     736
     737If you want to provide your new category with generic methods for objects
     738(or elements of objects), then you simply add an attribute called
     739``ParentMethods`` (or ``ElementMethods``) carrying a class. The methods
     740of that class will automatically become methods of the objects (or the
     741elements). For instance::
     742
     743    sage: P.<x,y> = ZZ[]
     744    sage: P.sum([x,y,1])
     745    x + y + 1
     746    sage: P.sum.__module__
     747    'sage.categories.commutative_additive_monoids'
     748    sage: P.sum.__func__ is CommutativeAdditiveMonoids().ParentMethods.sum.__func__
     749    True
     750
     751We recommend to study the code of one example::
     752
     753    sage: C = CommutativeAdditiveMonoids()
     754    sage: C??                               # not tested
    674755
    675756Caveats
    676757-------
  • sage/categories/principal_ideal_domains.py

    diff --git a/sage/categories/principal_ideal_domains.py b/sage/categories/principal_ideal_domains.py
    a b Principal ideal domains 
    1111from sage.categories.category import Category
    1212from sage.categories.category_singleton import Category_singleton
    1313from sage.misc.cachefunc import cached_method
     14from sage.categories.unique_factorization_domains import UniqueFactorizationDomains
    1415
    1516class PrincipalIdealDomains(Category_singleton):
    1617    """
    class PrincipalIdealDomains(Category_sin 
    3637        sage: TestSuite(PrincipalIdealDomains()).run()
    3738    """
    3839
    39     @cached_method
    4040    def super_categories(self):
    4141        """
    4242        EXAMPLES::
    class PrincipalIdealDomains(Category_sin 
    4444            sage: PrincipalIdealDomains().super_categories()
    4545            [Category of unique factorization domains]
    4646        """
    47         from sage.categories.basic import UniqueFactorizationDomains
    4847        return [UniqueFactorizationDomains()]
    4948
    5049    class ParentMethods:
  • sage/categories/quotient_fields.py

    diff --git a/sage/categories/quotient_fields.py b/sage/categories/quotient_fields.py
    a b from sage.categories.category import Cat 
    1212from sage.categories.category_singleton import Category_singleton
    1313from sage.misc.cachefunc import cached_method
    1414from sage.misc.abstract_method import abstract_method
     15from sage.categories.fields import Fields
    1516
    1617class QuotientFields(Category_singleton):
    1718    """
    class QuotientFields(Category_singleton) 
    2930        sage: TestSuite(QuotientFields()).run()
    3031    """
    3132
    32     @cached_method
    3333    def super_categories(self):
    3434        """
    3535        EXAMPLES::
    class QuotientFields(Category_singleton) 
    3737            sage: QuotientFields().super_categories()
    3838            [Category of fields]
    3939        """
    40         from sage.categories.fields import Fields
    4140        return [Fields()]
    4241
    4342    class ParentMethods:
  • sage/categories/right_modules.py

    diff --git a/sage/categories/right_modules.py b/sage/categories/right_modules.py
    a b Right modules 
    1010
    1111from category_types import Category_over_base_ring
    1212from sage.misc.cachefunc import cached_method
     13from sage.categories.commutative_additive_groups import CommutativeAdditiveGroups
    1314
    1415##?class RightModules(Category_over_base_rng):
    1516class RightModules(Category_over_base_ring):
    class RightModules(Category_over_base_ri 
    3031        sage: TestSuite(RightModules(ZZ)).run()
    3132    """
    3233
    33     @cached_method
    3434    def super_categories(self):
    3535        """
    3636        EXAMPLES::
    class RightModules(Category_over_base_ri 
    3838            sage: RightModules(QQ).super_categories()
    3939            [Category of commutative additive groups]
    4040        """
    41         from sage.categories.commutative_additive_groups import CommutativeAdditiveGroups
    4241        return [CommutativeAdditiveGroups()]
    4342
    4443    class ParentMethods:
  • sage/categories/ring_ideals.py

    diff --git a/sage/categories/ring_ideals.py b/sage/categories/ring_ideals.py
    a b Ring ideals 
    1212
    1313from category_types import Category_ideal
    1414from sage.misc.cachefunc import cached_method
     15from modules import Modules
    1516from sage.categories.rings import Rings
    1617_Rings = Rings()
    1718
    class RingIdeals(Category_ideal): 
    5758            raise TypeError, "R (=%s) must be a ring"%R
    5859        Category_ideal.__init__(self, R)
    5960
    60     @cached_method
    6161    def super_categories(self):
    6262        """
    6363        EXAMPLES::
    class RingIdeals(Category_ideal): 
    6767            sage: RingIdeals(QQ).super_categories()
    6868            [Category of vector spaces over Rational Field]
    6969        """
    70         from modules import Modules
    7170        R = self.ring()
    7271        return [Modules(R)]
  • sage/categories/rings.py

    diff --git a/sage/categories/rings.py b/sage/categories/rings.py
    a b Rings 
    1111#                  http://www.gnu.org/licenses/
    1212#******************************************************************************
    1313
     14from sage.categories.rngs import Rngs
     15from sage.categories.semirings import Semirings
    1416from sage.categories.category import Category
    1517from sage.categories.category_singleton import Category_singleton
    1618from category import HomCategory
    class Rings(Category_singleton): 
    4244       in the category ``Algebras(P)``.
    4345    """
    4446
    45     @cached_method
    4647    def super_categories(self):
    4748        """
    4849        EXAMPLES::
    class Rings(Category_singleton): 
    5051            sage: Rings().super_categories()
    5152            [Category of rngs, Category of semirings]
    5253        """
    53         from sage.categories.rngs import Rngs
    54         from sage.categories.semirings import Semirings
    5554        return [Rngs(), Semirings()]
    5655
    5756    class ParentMethods:
  • sage/categories/rngs.py

    diff --git a/sage/categories/rngs.py b/sage/categories/rngs.py
    a b Rngs 
    1111from sage.categories.category import Category
    1212from sage.categories.category_singleton import Category_singleton
    1313from sage.misc.cachefunc import cached_method
     14from commutative_additive_groups import CommutativeAdditiveGroups
     15from semigroups import Semigroups
    1416
    1517class Rngs(Category_singleton):
    1618    """
    class Rngs(Category_singleton): 
    3133        sage: TestSuite(Rngs()).run()
    3234    """
    3335
    34     @cached_method
    3536    def super_categories(self):
    3637        """
    3738        EXAMPLES::
    class Rngs(Category_singleton): 
    3940            sage: Rngs().super_categories()
    4041            [Category of commutative additive groups, Category of semigroups]
    4142        """
    42         from commutative_additive_groups import CommutativeAdditiveGroups
    43         from semigroups import Semigroups
    4443        return [CommutativeAdditiveGroups(), Semigroups()]
    4544
    4645    class ParentMethods:
  • sage/categories/schemes.py

    diff --git a/sage/categories/schemes.py b/sage/categories/schemes.py
    a b Schemes 
    1313from sage.categories.category import Category, HomCategory
    1414from sage.categories.category_types import Category_over_base
    1515from sage.misc.cachefunc import cached_method
     16from sets_cat import Sets
    1617
    1718def Schemes(X=None):
    1819    """
    class Schemes_abstract(Category): 
    5758        """
    5859        Category.__init__(self, "Schemes")
    5960
    60     @cached_method
    6161    def super_categories(self):
    6262        """
    6363        EXAMPLES::
    class Schemes_abstract(Category): 
    6565            sage: Schemes().super_categories()
    6666            [Category of sets]
    6767        """
    68         from sets_cat import Sets
    6968        return [Sets()]
    7069
    7170    def _call_(self, x):
    class Schemes_over_base(Category_over_ba 
    203202        """
    204203        return self.base()
    205204
    206     @cached_method
    207205    def super_categories(self):
    208206        """
    209207        EXAMPLES::
  • sage/categories/semigroups.py

    diff --git a/sage/categories/semigroups.py b/sage/categories/semigroups.py
    a b class Semigroups(Category_singleton): 
    4242        sage: C = Semigroups()
    4343        sage: TestSuite(C).run(verbose=True)
    4444        running ._test_category() . . . pass
     45        running ._test_category_graph() . . . pass
    4546        running ._test_not_implemented_methods() . . . pass
    4647        running ._test_pickling() . . . pass
    4748
    4849    """
    49     @cached_method
    5050    def super_categories(self):
    5151        """
    5252        EXAMPLES::
  • sage/categories/semirings.py

    diff --git a/sage/categories/semirings.py b/sage/categories/semirings.py
    a b Semirings 
    1010
    1111from sage.categories.category import Category
    1212from sage.categories.category_singleton import Category_singleton
     13from sage.categories.commutative_additive_monoids import CommutativeAdditiveMonoids
     14from sage.categories.monoids import Monoids
    1315from sage.misc.cachefunc import cached_method
    1416
    1517class Semirings(Category_singleton):
    class Semirings(Category_singleton): 
    3638        sage: TestSuite(Semirings()).run()
    3739    """
    3840
    39     @cached_method
    4041    def super_categories(self):
    4142        """
    4243        EXAMPLES::
    class Semirings(Category_singleton): 
    4445            sage: Semirings().super_categories()
    4546            [Category of commutative additive monoids, Category of monoids]
    4647        """
    47         from sage.categories.commutative_additive_monoids import CommutativeAdditiveMonoids
    48         from sage.categories.monoids import Monoids
    4948        return [CommutativeAdditiveMonoids(), Monoids()]
    5049
    5150    class ParentMethods:
  • sage/categories/sets_cat.py

    diff --git a/sage/categories/sets_cat.py b/sage/categories/sets_cat.py
    a b class Sets(Category_singleton): 
    157157
    158158    """
    159159
    160     @cached_method
    161160    def super_categories(self):
    162161        r"""
    163162        We include SetsWithPartialMaps between Sets and Objects so that we
  • sage/categories/sets_with_partial_maps.py

    diff --git a/sage/categories/sets_with_partial_maps.py b/sage/categories/sets_with_partial_maps.py
    a b SetsWithPartialMaps 
    1313from sage.categories.category import Category, HomCategory
    1414from sage.categories.category_singleton import Category_singleton
    1515from sage.misc.cachefunc import cached_method
     16from objects import Objects
    1617
    1718class SetsWithPartialMaps(Category_singleton):
    1819    """
    class SetsWithPartialMaps(Category_singl 
    4142    #    import sage.sets.all
    4243    #    return sage.sets.all.Set(X, pt)
    4344
    44     @cached_method
    4545    def super_categories(self):
    4646        """
    4747        EXAMPLES::
    class SetsWithPartialMaps(Category_singl 
    4949            sage: SetsWithPartialMaps().super_categories()
    5050            [Category of objects]
    5151        """
    52         from objects import Objects
    5352        return [Objects()]
    5453
    5554    class HomCategory(HomCategory):
  • sage/categories/unique_factorization_domains.py

    diff --git a/sage/categories/unique_factorization_domains.py b/sage/categories/unique_factorization_domains.py
    a b Unique factorization domains 
    1111from sage.categories.category import Category
    1212from sage.categories.category_singleton import Category_singleton
    1313from sage.misc.cachefunc import cached_method
     14from sage.categories.gcd_domains import GcdDomains
    1415
    1516class UniqueFactorizationDomains(Category_singleton):
    1617    """
    class UniqueFactorizationDomains(Categor 
    3031        sage: TestSuite(UniqueFactorizationDomains()).run()
    3132    """
    3233
    33     @cached_method
    3434    def super_categories(self):
    3535        """
    3636        EXAMPLES::
    class UniqueFactorizationDomains(Categor 
    3838            sage: UniqueFactorizationDomains().super_categories()
    3939            [Category of gcd domains]
    4040        """
    41         from sage.categories.gcd_domains import GcdDomains
    4241        return [GcdDomains()]
    4342
    4443    class ParentMethods:
  • sage/categories/vector_spaces.py

    diff --git a/sage/categories/vector_spaces.py b/sage/categories/vector_spaces.py
    a b class VectorSpaces(Category_module): 
    110110        """
    111111        return self.base_ring()
    112112
    113     @cached_method
    114113    def super_categories(self):
    115114        """
    116115        EXAMPLES::
  • sage/categories/weyl_groups.py

    diff --git a/sage/categories/weyl_groups.py b/sage/categories/weyl_groups.py
    a b class WeylGroups(Category_singleton): 
    4949        sage: TestSuite(C).run()
    5050    """
    5151
    52     @cached_method
    5352    def super_categories(self):
    5453        r"""
    5554        EXAMPLES::
  • new file sage/misc/c3.pyx

    diff --git a/sage/misc/c3.pyx b/sage/misc/c3.pyx
    new file mode 100644
    - +  
     1"""
     2The C3 algorithm
     3
     4The C3 algorithm is used as method resolution order for new style
     5classes in Python. The implementation here is used to order the list
     6of super categories of a category.
     7
     8AUTHOR:
     9
     10- Simon King (2011-11): initial version.
     11"""
     12
     13include "../ext/python.pxi"
     14
     15cpdef list C3_algorithm(object start, str bases, str attribute, bint proper):
     16    """
     17    The C3 algorithm.
     18
     19    NOTE:
     20
     21    This implementation is used to order the list of super categories of a
     22    category; see :meth:`~sage.categories.category.Category.all_super_categories`.
     23    By consequence, the list of super categories exactly corresponds to the
     24    method resolution order of the parent or element class of a category.
     25    This is because Python uses the same algorithm (of course in a different
     26    implementation) as method resolution order for new style classes.
     27   
     28    INPUT:
     29
     30    - ``start`` (object): The returned list is built upon data
     31      provided by certain attributes of ``start``.
     32    - ``bases`` (string): The name of an attribute of ``start``
     33      providing a list of objects.
     34    - ``attribute`` (string): The name of an attribute of the
     35      objects provided in ``getattr(start,bases)``. That attribute
     36      is supposed to provide a list.
     37
     38    ASSUMPTIONS:
     39
     40    Our implementation of the algorithm only works on lists of
     41    objects that compare equal if and only if they are identical.
     42
     43    OUTPUT:
     44
     45    A list, the result of the C3 algorithm applied to the list
     46    ``[getattr(X,attribute) for X in getattr(start,bases)]``.
     47
     48    EXAMPLES:
     49
     50    We start with an example of categories with an inconsistent
     51    base classes of a new class::
     52
     53        sage: class X(Category):
     54        ...    def super_categories(self):
     55        ...        return [Objects()]
     56        sage: class X(Category):
     57        ...    def super_categories(self):
     58        ...        return [Objects()]
     59        sage: class Y(Category):
     60        ...    def super_categories(self):
     61        ...        return [Objects()]
     62        sage: class A(Category):
     63        ...    def super_categories(self):
     64        ...        return [X(),Y()]
     65        sage: class B(Category):
     66        ...    def super_categories(self):
     67        ...        return [Y(),X()]
     68        sage: class Foo(Category):
     69        ...    def super_categories(self):
     70        ...       return [A(),B()]
     71        sage: F = Foo()
     72
     73    Python is not able to create a consistent method resolution order
     74    for the parent class::
     75
     76        sage: F.parent_class
     77        Traceback (most recent call last):
     78        ...
     79        TypeError: Cannot create a consistent method resolution
     80        order (MRO) for bases X.parent_class, Y.parent_class
     81
     82    Since the C3 algorithm is used for determining the list of
     83    all super categories (by trac ticket #11943), a similar error
     84    arises here::
     85
     86        sage: F.all_super_categories()
     87        Traceback (most recent call last):
     88        ...
     89        ValueError: Can not merge the items Category of x, Category of y.
     90
     91    Next, we demonstrate how our implementation of the C3 algorithm
     92    is used to compute the list of all super categories::
     93
     94        sage: C = Category.join([HopfAlgebrasWithBasis(QQ), FiniteEnumeratedSets()])
     95        sage: from sage.misc.c3 import C3_algorithm
     96        sage: C3_algorithm(C,'_super_categories','_all_super_categories',True)==C._all_super_categories_proper
     97        True
     98        sage: C3_algorithm(C,'_super_categories','_all_super_categories',False)==C._all_super_categories
     99        True
     100
     101    By trac ticket #11943, the following consistency tests are part
     102    of the test suites of categories (except for hom categories)::
     103
     104        sage: C.parent_class.mro() == [x.parent_class for x in C.all_super_categories()]+[object]
     105        True
     106        sage: C.element_class.mro() == [x.element_class for x in C.all_super_categories()]+[object]
     107        True
     108
     109    """
     110    # The lists in the arguments are reverted,
     111    # so that we can do pop() in lieue of pop(0).
     112    # In addition, containedness in the tail is tested using lists.
     113    cdef list out
     114    if proper:
     115        out = []
     116    else:
     117        out = [start]
     118    cdef list args = getattr(start,bases)
     119    if not args:
     120        return out
     121    cdef list curr_tail, tmp_tail
     122    cdef set curr_set, tmp_set
     123    cdef object curr_obj
     124    cdef bint next_item_found
     125    cdef list heads = []
     126    cdef list tails = []
     127    cdef list tailsets = []
     128    for curr_obj in args:
     129        curr_tail = getattr(curr_obj, attribute)
     130        heads.append(curr_tail[0])
     131        tmp_tail = PyList_GetSlice(curr_tail,1,PyList_GET_SIZE(curr_tail))
     132        PyList_Reverse(tmp_tail)
     133        tails.append(tmp_tail)
     134        tailsets.append(set(tmp_tail))
     135    cdef int i,j, lenargs
     136    lenargs = len(heads)
     137    for i from 0<=i<lenargs:
     138        curr_tail = <list>PyList_GET_ITEM(tails,i)
     139        if curr_tail is None:
     140            continue
     141        curr_set = <set>PyList_GET_ITEM(tailsets,i)
     142        O = <object>PyList_GET_ITEM(heads,i)
     143        next_item_found=True
     144        for j from 0<=j<i:
     145            tmp_tail = <list>PyList_GET_ITEM(tails,j)
     146            if tmp_tail is None:
     147                continue
     148            tmp_set = <set>PyList_GET_ITEM(tailsets,j)
     149            X = <object>PyList_GET_ITEM(heads,j)
     150            if X is O:
     151                try:
     152                    X = tmp_tail.pop()
     153                    heads[j] = X
     154                    tmp_set.remove(X)
     155                except IndexError:
     156                    tails[j] = None
     157            elif O in tmp_set:
     158                next_item_found=False
     159                break
     160        if next_item_found:
     161            for j from i<j<lenargs:
     162                tmp_tail = <list>PyList_GET_ITEM(tails,j)
     163                if tmp_tail is None:
     164                    continue
     165                tmp_set = <set>PyList_GET_ITEM(tailsets,j)
     166                X = <object>PyList_GET_ITEM(heads,j)
     167                if X is O:
     168                    try:
     169                        X = tmp_tail.pop()
     170                        heads[j] = X
     171                        tmp_set.remove(X)
     172                    except IndexError:
     173                        tails[j] = None
     174                elif O in tmp_set:
     175                    next_item_found=False
     176                    break
     177        if next_item_found:
     178            out.append(O)
     179            try:
     180                O = curr_tail.pop()
     181                heads[i] = O
     182                curr_set.remove(O)
     183            except IndexError:
     184                tails[i] = None
     185           
     186            i = -1
     187    # Either we need to raise an error, or the list is done.
     188    if tails.count(None)<lenargs:
     189        raise ValueError, "Can not merge the items %s."%', '.join([repr(heads[i]) for i,t in enumerate(tails) if t is not None])
     190    return out
     191
     192cpdef frozenset C3_algorithm_set(object start, str bases, str attribute, bint proper):
     193    """
     194    Return the result of :func:`C3_algorithm` as a frozen set.
     195
     196    EXAMPLE:
     197
     198        This function is used internally for creating the set of all
     199        super categories of a category. Since a containment test is
     200        much faster for sets than for lists, this provides some
     201        speed-up for the category framework. See trac ticket #11943::
     202
     203            sage: Rings()._set_of_super_categories
     204            frozenset([...])
     205            sage: Rings()._set_of_super_categories == frozenset(Rings().all_super_categories(proper=True))
     206            True
     207
     208    """
     209    return frozenset(C3_algorithm(start,bases,attribute,proper))