Ticket #9065: trac_9065-facade_parents-nt.patch

File trac_9065-facade_parents-nt.patch, 43.5 KB (added by nthiery, 11 years ago)
  • doc/en/reference/categories.rst

    # HG changeset patch
    # User Nicolas M. Thiery <nthiery@users.sf.net>
    # Date 1303731849 14400
    # Node ID 1524f3d5d5ee1817fcb0248149b9aa96da655ca6
    # Parent  c3de87f579f9c13167590912ad45d088b70e8721
    #9065: Add support for facade parents
    
    diff --git a/doc/en/reference/categories.rst b/doc/en/reference/categories.rst
    a b Categories 
    123123   sage/categories/vector_spaces
    124124   sage/categories/weyl_groups
    125125
     126Technical Categories
     127====================
     128
     129.. toctree::
     130   :maxdepth: 2
     131
     132   sage/categories/facade_sets
     133
    126134Examples of parents using categories
    127135=====================================
    128136
  • sage/categories/category.py

    diff --git a/sage/categories/category.py b/sage/categories/category.py
    a b class JoinCategory(Category): 
    13631363
    13641364        EXAMPLES::
    13651365
    1366             sage: J = Category.join((Groups(), CommutativeAdditiveMonoids())); J #indirect doctest
     1366            sage: Category.join((Groups(), CommutativeAdditiveMonoids())) #indirect doctest
    13671367            Join of Category of groups and Category of commutative additive monoids
     1368
     1369        TODO: find a better place to implement this representation improvement:
     1370
     1371            sage: Category.join((Groups(), Sets().Facades()))
     1372            Category of facade groups
     1373            sage: Category.join((Sets().Facades(), Groups()))
     1374            Category of facade groups
    13681375        """
     1376        categories = self.super_categories()
     1377        from sets_cat import Sets
     1378        if len(categories) == 2 and Sets().Facades() in categories:
     1379            categories = list(categories)
     1380            categories.remove(Sets().Facades())
     1381            return "Category of facade %s"%(categories[0]._repr_object_names())
    13691382        return "Join of %s"%(" and ".join(str(cat) for cat in self.super_categories()))
  • 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 
    7272            tester = self._tester(**options)
    7373            zero = self.zero()
    7474            # TODO: also call is_zero once it will work
    75             tester.assert_(zero.parent() == self)
     75            tester.assert_(self.is_parent_of(zero))
    7676            for x in tester.some_elements():
    7777                tester.assert_(x + zero == x)
    7878            # Check that zero is immutable by asking its hash:
  • sage/categories/enumerated_sets.py

    diff --git a/sage/categories/enumerated_sets.py b/sage/categories/enumerated_sets.py
    a b class EnumeratedSets(Category): 
    110110            sage: S = EnumeratedSets()([1, 2, 3]); S
    111111            {1, 2, 3}
    112112            sage: S.category()
    113             Category of finite enumerated sets
     113            Category of facade finite enumerated sets
    114114
    115115            sage: S = EnumeratedSets()((1, 2, 3)); S
    116116            {1, 2, 3}
    class EnumeratedSets(Category): 
    119119            sage: S = EnumeratedSets()(Set([1, 2, 3])); S
    120120            {1, 2, 3}
    121121            sage: S.category()
    122             Category of finite enumerated sets
     122            Category of facade finite enumerated sets
    123123        """
    124124        import sage.sets.set
    125125        if isinstance(X, (tuple, list, set, sage.sets.set.Set_object_enumerated)):
  • new file sage/categories/examples/facade_sets.py

    diff --git a/sage/categories/examples/facade_sets.py b/sage/categories/examples/facade_sets.py
    new file mode 100644
    - +  
     1r"""
     2Example of facade set
     3"""
     4#*****************************************************************************
     5#  Copyright (C) 2010 Nicolas M. Thiery <nthiery at users.sf.net>
     6#
     7#  Distributed under the terms of the GNU General Public License (GPL)
     8#                  http://www.gnu.org/licenses/
     9#*****************************************************************************
     10
     11from sage.categories.sets_cat import Sets
     12from sage.categories.monoids import Monoids
     13from sage.structure.parent import Parent
     14from sage.structure.unique_representation import UniqueRepresentation
     15from sage.rings.integer_ring import ZZ
     16from sage.rings.infinity import infinity
     17from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
     18
     19class PositiveIntegerMonoid(UniqueRepresentation, Parent):
     20    r"""
     21
     22    An example of a facade parent: the positive integers viewed as a
     23    multiplicative monoid
     24
     25    This class illustrates a minimal implementation of a facade parent
     26    which models a subset of a set.
     27
     28    EXAMPLES::
     29
     30        sage: S = Sets().Facades().example(); S
     31        An example of facade set: the monoid of positive integers
     32
     33    TESTS::
     34
     35        sage: TestSuite(S).run(verbose = True)
     36        running ._test_an_element() . . . pass
     37        running ._test_associativity() . . . pass
     38        running ._test_category() . . . pass
     39        running ._test_elements() . . .
     40          Running the test suite of self.an_element()
     41          running ._test_category() . . . pass
     42          running ._test_eq() . . . pass
     43          running ._test_not_implemented_methods() . . . pass
     44          running ._test_pickling() . . . pass
     45          pass
     46        running ._test_elements_eq() . . . pass
     47        running ._test_eq() . . . pass
     48        running ._test_not_implemented_methods() . . . pass
     49        running ._test_one() . . . pass
     50        running ._test_pickling() . . . pass
     51        running ._test_prod() . . . pass
     52        running ._test_some_elements() . . . pass
     53    """
     54    def __init__(self):
     55        r"""
     56        EXAMPLES::
     57
     58            sage: from sage.categories.examples.facade_sets import PositiveIntegerMonoid
     59            sage: S = PositiveIntegerMonoid(); S
     60            An example of facade set: the monoid of positive integers
     61
     62        TESTS::
     63
     64            sage: TestSuite(S).run()
     65
     66        """
     67        Parent.__init__(self, facade = ZZ, category = Monoids())
     68
     69    def _repr_(self):
     70        r"""
     71
     72        EXAMPLES::
     73
     74            sage: S = Sets().Facades().example()   # indirect doctest
     75
     76        """
     77        return "An example of facade set: the monoid of positive integers"
     78
     79    def _element_constructor_(self, object):
     80        r"""
     81        Construction of elements
     82
     83        Since ``self`` is a strict subset of the parent it is a facade
     84        for, it is mandatory to override this method. This method
     85        indirectly influences membership testing (see
     86        :meth:`Parent.__contains__`).
     87
     88        EXAMPLES::
     89
     90            sage: S = Sets().Facades().example(); S
     91            An example of facade set: the monoid of positive integers
     92            sage: S(1)
     93            1
     94            sage: S(int(1))
     95            1
     96            sage: S(2/1)
     97            2
     98            sage: (parent(S(1)) == ZZ, parent(S(int(1))) == ZZ, parent(S(2/1)))
     99            (True, True, Integer Ring)
     100            sage: S(1), S(int(1)), S(2/1)
     101            (1, 1, 2)
     102            sage: 1 in S
     103            True
     104            sage: 2/1 in S, int(1) in S
     105            (True, True)
     106            sage: -1 in S, 1/2 in S
     107            (False, False)
     108        """
     109        object = ZZ(object)
     110        if object > ZZ(0):
     111            return object
     112        else:
     113            raise ValueError, "%s should be positive"
     114
     115class IntegersCompletion(UniqueRepresentation, Parent):
     116    r"""
     117    An example of a facade parent: the set of integers completed with
     118    `+-\infty`
     119
     120    This class illustrates a minimal implementation of a facade parent
     121    that models the union of several other parents.
     122
     123    EXAMPLES::
     124
     125        sage: S = Sets().Facades().example("union"); S
     126        An example of a facade set: the integers completed by +-infinity
     127
     128    TESTS::
     129
     130        sage: TestSuite(S).run(verbose = True)
     131        running ._test_an_element() . . . pass
     132        running ._test_category() . . . pass
     133        running ._test_elements() . . .
     134          Running the test suite of self.an_element()
     135          running ._test_category() . . . pass
     136          running ._test_eq() . . . pass
     137          running ._test_not_implemented_methods() . . . pass
     138          running ._test_pickling() . . . pass
     139          pass
     140        running ._test_elements_eq() . . . pass
     141        running ._test_eq() . . . pass
     142        running ._test_not_implemented_methods() . . . pass
     143        running ._test_pickling() . . . pass
     144        running ._test_some_elements() . . . pass
     145    """
     146    def __init__(self):
     147        r"""
     148        EXAMPLES::
     149
     150            sage: from sage.categories.examples.facade_sets import IntegersCompletion
     151            sage: S = IntegersCompletion(); S
     152            An example of a facade set: the integers completed by +-infinity
     153
     154        TESTS::
     155
     156            sage: TestSuite(S).run()
     157
     158        """
     159        # We can't use InfinityRing, because this ring contains 3
     160        # elements besides +-infinity. We can't use Set either for the
     161        # moment, because Set([1,2])(1) raises an error
     162        Parent.__init__(self, facade = (ZZ, FiniteEnumeratedSet([-infinity, +infinity])), category = Sets())
     163
     164    def _repr_(self):
     165        r"""
     166
     167        EXAMPLES::
     168
     169            sage: S = Sets().Facades().example()   # indirect doctest
     170
     171        """
     172        return "An example of a facade set: the integers completed by +-infinity"
     173
  • sage/categories/examples/finite_enumerated_sets.py

    diff --git a/sage/categories/examples/finite_enumerated_sets.py b/sage/categories/examples/finite_enumerated_sets.py
    a b from sage.structure.element_wrapper impo 
    1313from sage.categories.enumerated_sets import EnumeratedSets
    1414from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
    1515from sage.rings.integer import Integer
     16from sage.rings.integer_ring import IntegerRing
    1617from sage.functions.other import sqrt
    1718
    1819class Example(UniqueRepresentation, Parent):
    class Example(UniqueRepresentation, Pare 
    3839    return consistent results::
    3940
    4041        sage: TestSuite(C).run(verbose = True)
    41         running ._test_an_element() . . .
    42           The set doesn't seems to implement __call__; skipping test of construction idempotency
    43          pass
     42        running ._test_an_element() . . . pass
    4443        running ._test_category() . . . pass
    4544        running ._test_elements() . . .
    4645          Running the test suite of self.an_element()
    class Example(UniqueRepresentation, Pare 
    6766            sage: C
    6867            An example of a finite enumerated set: {1,2,3}
    6968            sage: C.category()
    70             Category of finite enumerated sets
     69            Category of facade finite enumerated sets
    7170            sage: TestSuite(C).run()
    7271        """
    7372        self._set = map(Integer, [1,2,3])
    74         Parent.__init__(self, category = FiniteEnumeratedSets())
     73        Parent.__init__(self, facade = IntegerRing(), category = FiniteEnumeratedSets())
    7574
    7675    def _repr_(self):
    7776        """
    class IsomorphicObjectOfFiniteEnumerated 
    114113            sage: C
    115114            The image by some isomorphism of An example of a finite enumerated set: {1,2,3}
    116115            sage: C.category()
    117             Category of isomorphic objects of finite enumerated sets
     116            Category of facade isomorphic objects of finite enumerated sets
    118117            sage: TestSuite(C).run()
    119118        """
    120119        self._ambient = ambient
    121         Parent.__init__(self, category = FiniteEnumeratedSets().IsomorphicObjects())
     120        Parent.__init__(self, facade = IntegerRing(), category = FiniteEnumeratedSets().IsomorphicObjects())
    122121
    123122    def ambient(self):
    124123        """
  • sage/categories/examples/sets_cat.py

    diff --git a/sage/categories/examples/sets_cat.py b/sage/categories/examples/sets_cat.py
    a b class PrimeNumbers(UniqueRepresentation, 
    7676        """
    7777        TESTS::
    7878
    79             sage: from sage.categories.examples.sets_cat import PrimeNumbers_Facade
    80             sage: P = PrimeNumbers_Facade()
     79            sage: from sage.categories.examples.sets_cat import PrimeNumbers
     80            sage: P = PrimeNumbers()
    8181            sage: P.category()
    82             Category of sets
     82            Category of facade sets
     83            sage: P is Sets().example()
     84            True
    8385        """
    84         Parent.__init__(self, category = Sets())
     86        Parent.__init__(self, facade = IntegerRing(), category = Sets())
    8587
    8688    def _repr_(self):
    8789        """
    class PrimeNumbers_Facade(PrimeNumbers_A 
    628630        running ._test_some_elements() . . . pass
    629631    """
    630632
     633    def __init__(self):
     634        """
     635        TESTS::
     636
     637            sage: P = Sets().example("inherits")
     638        """
     639        Parent.__init__(self, facade = IntegerRing(), category = Sets())
     640
    631641    def _repr_(self):
    632642        """
    633643        TESTS::
  • new file sage/categories/facade_sets.py

    diff --git a/sage/categories/facade_sets.py b/sage/categories/facade_sets.py
    new file mode 100644
    - +  
     1r"""
     2Facade Sets
     3"""
     4#*****************************************************************************
     5#  Copyright (C) 2010 Nicolas M. Thiery <nthiery at users.sf.net>
     6#
     7#  Distributed under the terms of the GNU General Public License (GPL)
     8#                  http://www.gnu.org/licenses/
     9#******************************************************************************
     10
     11from sage.misc.cachefunc import cached_method
     12from sage.categories.category import Category
     13
     14class FacadeSets(Category):
     15    r"""
     16    The category of facade sets
     17
     18    A *facade set* is a parent ``P`` whose elements actually belong to
     19    some other parent::
     20
     21        sage: P = Sets().example(); P
     22        Set of prime numbers (basic implementation)
     23        sage: p = Sets().example().an_element(); p
     24        47
     25        sage: p in P
     26        True
     27        sage: p.parent()
     28        Integer Ring
     29
     30    Typical use cases include modeling a subset of an existing
     31    parent::
     32
     33        sage: Sets().Facades().example()
     34        An example of facade set: the monoid of positive integers
     35
     36    or the union of several parents::
     37
     38        sage: Sets().Facades().example("union")
     39        An example of a facade set: the integers completed by +-infinity
     40
     41    or endowing a parent with more (or less!) structure::
     42
     43        sage: ... # todo: not implemented
     44        The positive integers endowed with divisibility order
     45
     46    Let us consider one of the examples above in detail: the partially ordered
     47    set `P` of positive integers w.r.t. divisibility order. There are two
     48    options for representing its elements:
     49
     50     1. as plain integers
     51     2. as integers, modified to be aware that their parent is `P`
     52
     53    The advantage of 1. is that one needs not to do conversions back and
     54    forth between `P` and `\ZZ`. The disadvantage is that this
     55    introduces an ambiguity when writing `2 < 3`::
     56
     57        sage: 2 < 3
     58        True
     59
     60    To raise this ambiguity, one needs to explicitely specify the order
     61    as in `2 <_P 3`::
     62
     63        sage: P.le(2,3) # todo: not implemented
     64        False
     65
     66    In short `P` being a facade parent is one of the programmatic
     67    counterpart (with e.g. coercions) of the usual mathematical idiom:
     68    "for ease of notation, we identify an element of `P` with the
     69    corresponding integer". Too many identifications lead to
     70    confusion; the lack thereof leads to heavy, if not obfuscated,
     71    notations. Finding the right balance is an art, and even though
     72    there are common guidelines, it is ultimately up to the writer to
     73    choose which identifications to do. This is no different in code.
     74
     75    .. seealso::
     76
     77       ::
     78
     79        sage: Sets().example("facade")
     80        Set of prime numbers (facade implementation)
     81        sage: Sets().example("inherits")
     82        Set of prime numbers
     83        sage: Sets().example("wrapper")
     84        Set of prime numbers (wrapper implementation)
     85
     86    .. rubric:: Specifications
     87
     88    A parent which is a facade must either:
     89
     90    - call :meth:`Parent.__init__` using the ``facade`` parameter to
     91      specify a parent, or tuple thereof.
     92    - overload the method :meth:`~FacadeSets.ParentMethods.facade_for`.
     93
     94    .. note:: the concept of facade parents was originally introduced
     95       in the computer algebra system MuPAD.
     96    """
     97
     98    @cached_method
     99    def super_categories(self):
     100        r"""
     101        Returns the super categories of ``self``, as per
     102        :meth:`Category.super_categories`.
     103
     104        EXAMPLES::
     105
     106            sage: Sets().Facades().super_categories()
     107            [Category of sets]
     108        """
     109        from sage.categories.sets_cat import Sets
     110        return [Sets()]
     111
     112    def example(self, choice='subset'):
     113        r"""
     114        Returns an example of facade set, as per
     115        :meth:`Category.example()
     116        <sage.categories.category.Category.example>`.
     117
     118        INPUT:
     119
     120        - ``choice`` -- 'union' or 'subset' (default: 'subset').
     121
     122        EXAMPLES::
     123
     124            sage: Sets().Facades().example()
     125            An example of facade set: the monoid of positive integers
     126            sage: Sets().Facades().example(choice='union')
     127            An example of a facade set: the integers completed by +-infinity
     128            sage: Sets().Facades().example(choice='subset')
     129            An example of facade set: the monoid of positive integers
     130        """
     131        import sage.categories.examples.facade_sets as examples
     132        if choice == "union":
     133            return examples.IntegersCompletion()
     134        elif choice == 'subset':
     135            return examples.PositiveIntegerMonoid()
     136        else:
     137            raise TypeError, "choice should be 'union' or 'subset'"
     138
     139    class ParentMethods:
     140
     141        def _element_constructor_(self, element):
     142            """
     143            Coerce ``element`` into ``self``
     144
     145            INPUT:
     146
     147            - ``element`` -- any object
     148
     149            This default implementation returns ``element`` if
     150            ``self`` is a facade for ``parent(element)`. Otherwise it
     151            attempts in turn to coerce ``element`` into each parent
     152            ``self`` is a facade for.
     153
     154            This implementation is only valid for a facade parent
     155            which models the full union of the parents it is a facade
     156            for. Other facade parents should redefine
     157            :meth:`element_constructor` appropriately.
     158
     159            EXAMPLES::
     160
     161                sage: S = Sets().Facades().example("union"); S
     162                An example of a facade set: the integers completed by +-infinity
     163                sage: S(1)
     164                1
     165                sage: S(1/2)
     166                Traceback (most recent call last):
     167                ...
     168                ValueError: Can't coerce `1/2` in any parent `An example of a facade set: the integers completed by +-infinity` is a facade for
     169                sage: S(2/1)
     170                2
     171                sage: S(2/1).parent()
     172                Integer Ring
     173                sage: S(int(1))
     174                1
     175                sage: S(int(1)).parent()
     176                Integer Ring
     177
     178            Facade parents that model strict subsets should redefine
     179            :meth:`element_constructor`::
     180
     181                sage: S = Sets().Facades().example(); S
     182                An example of facade set: the monoid of positive integers
     183                sage: S(-1)
     184                Traceback (most recent call last):
     185                ...
     186                ValueError: %s should be positive
     187            """
     188            if self.is_parent_of(element):
     189                return element
     190            else:
     191                parents = self.facade_for()
     192                if parents is True:
     193                    return NotImplementedError
     194                for parent in self.facade_for():
     195                    try:
     196                        return parent(element)
     197                    except:
     198                        pass
     199            raise ValueError, "Can't coerce `%s` in any parent `%s` is a facade for"%(element, self)
     200
     201        def facade_for(self):
     202            """
     203            Returns all the parents this set is a facade for
     204
     205            This default implementation assumes that ``self`` has
     206            an attribute ``_facade_for``, typically initialized by
     207            :meth:`Parent.__init__`.
     208
     209            EXAMPLES::
     210
     211                sage: S = Sets().Facades().example(); S
     212                An example of facade set: the monoid of positive integers
     213                sage: S.facade_for()
     214                (Integer Ring,)
     215            """
     216            return self._facade_for
     217
     218        def is_parent_of(self, element):
     219            """
     220            Returns whether ``self`` is the parent of ``element``
     221
     222            INPUT:
     223
     224            - ``element`` -- any object
     225
     226            Since ``self`` is a facade domain, this actually tests
     227            whether the parent of ``element`` is any of the parent
     228            ``self`` is a facade for.
     229
     230            EXAMPLES::
     231
     232                sage: S = Sets().Facades().example(); S
     233                An example of facade set: the monoid of positive integers
     234                sage: S.is_parent_of(1)
     235                True
     236                sage: S.is_parent_of(1/2)
     237                False
     238
     239            This method differs from :meth:`__contains__` in two
     240            ways.  First, this does not take into account the fact
     241            that ``self`` may be a strict subset of the parent(s)
     242            it is a facade for::
     243
     244                sage: -1 in S, S.is_parent_of(-1)
     245                (False, True)
     246
     247            Furthermore, there is no coercion attempted::
     248
     249                sage: int(1) in S, S.is_parent_of(int(1))
     250                (True, False)
     251
     252            .. warning::
     253
     254               this implementation does not handle facade parents of facade
     255               parents. Is this a feature we want generically?
     256            """
     257            parents = self.facade_for()
     258            if parents is True:
     259                return True
     260            from sage.structure.element import parent
     261            return parent(element) in parents
     262
     263        def __contains__(self, element):
     264            """
     265            Membership testing
     266
     267            Returns whether ``element`` is in one of the parents
     268            ``self`` is a facade for.
     269
     270            .. warning:: this default implementation is currently
     271            overriden by :meth:`Parent.__contains__`.
     272
     273            EXAMPLES::
     274
     275                sage: S = Sets().Facades().example("union"); S
     276                An example of a facade set: the integers completed by +-infinity
     277                sage: 1 in S, -5 in S, oo in S, -oo in S, int(1) in S, 2/1 in S
     278                (True, True, True, True, True, True)
     279                sage: 1/2 in S, "bla" in S
     280                (False, False)
     281            """
     282            return any(element in parent for parent in self.facade_for())
     283
     284        def _an_element_(self):
     285            """
     286            Try to return an element of ``self``, as per
     287            :meth:`Sets.ParentMethods.an_element`.
     288
     289            For each parent ``self`` is a facade for, this default
     290            implementation tries the method ``an_element`` until it finds an
     291            element in ``self``. If none is found raise a
     292            ``NotImplementedError``.
     293
     294            EXAMPLES::
     295
     296                sage: S = Sets().Facades().example(); S
     297                An example of facade set: the monoid of positive integers
     298                sage: S.an_element()
     299                1
     300            """
     301            for parent in self.facade_for():
     302                x = parent.an_element()
     303                if x in self:
     304                    return x
     305            raise NotImplementedError
     306
     307
  • sage/categories/monoids.py

    diff --git a/sage/categories/monoids.py b/sage/categories/monoids.py
    a b class Monoids(Category): 
    120120            """
    121121            tester = self._tester(**options)
    122122            one = self.one()
    123             tester.assert_(one.parent() == self)
     123            tester.assert_(self.is_parent_of(one))
    124124            for x in tester.some_elements():
    125125                tester.assert_(x * one == x)
    126126                tester.assert_(one * x == x)
  • sage/categories/sets_cat.py

    diff --git a/sage/categories/sets_cat.py b/sage/categories/sets_cat.py
    a b Sets 
    1111#                  http://www.gnu.org/licenses/
    1212#******************************************************************************
    1313
    14 from sage.misc.lazy_import import lazy_import
     14from sage.misc.lazy_import import lazy_import, LazyImport
    1515from sage.misc.cachefunc import cached_method
    1616from sage.misc.sage_unittest import TestSuite
    1717from sage.misc.abstract_method import abstract_method
    from sage.categories.cartesian_product i 
    2929
    3030lazy_import('sage.sets.cartesian_product', 'CartesianProduct')
    3131
    32 
    3332class EmptySetError(ValueError):
    3433    """
    3534    Exception raised when some operation can't be performed on the empty set.
    class Sets(Category): 
    198197              sage: S = Sets()([1, 2, 3]); S.category()
    199198              Category of sets
    200199              sage: S = Sets()([1, 2, 3], True); S.category()
    201               Category of finite enumerated sets
     200              Category of facade finite enumerated sets
    202201        """
    203202        import sage.sets.all
    204203        if enumerated_set_if_possible:
    class Sets(Category): 
    306305            """
    307306            return self.element_class(parent = self, *args, **keywords)
    308307
     308        def is_parent_of(self, element):
     309            """
     310            Returns whether ``self`` is the parent of ``element``
     311
     312            INPUT:
     313             - ``element`` -- any object
     314
     315            EXAMPLES::
     316
     317                sage: S = ZZ
     318                sage: S.is_parent_of(1)
     319                True
     320                sage: S.is_parent_of(2/1)
     321                False
     322
     323            This method differs from :meth:`__contains__` because it
     324            does not attempt any coercion::
     325
     326                sage: 2/1 in S, S.is_parent_of(2/1)
     327                (True, False)
     328                sage: int(1) in S, S.is_parent_of(int(1))
     329                (True, False)
     330            """
     331            from sage.structure.element import parent
     332            return parent(element) == self
     333
    309334        @abstract_method
    310335        def __contains__(self, x):
    311336            """
    class Sets(Category): 
    377402            except EmptySetError:
    378403                return
    379404            tester.assertTrue(an_element in self, "self.an_element() is not in self")
    380 
    381             try:
    382                 element_parent = an_element.parent()
    383             except AttributeError:
    384                 tester.info("\n  self.an_element doesn't have any parent")
    385                 element_parent = None
    386 
    387             if element_parent is self:
     405#            tester.assertTrue(self.is_parent_of(an_element), "self is not the parent of self.an_element()")
     406#            tester.assertEqual(self(an_element), an_element, "element construction is not idempotent")
     407            if self.is_parent_of(an_element):
    388408                tester.assertEqual(self(an_element), an_element, "element construction is not idempotent")
    389409            else: # Allows self(an_element) to fails for facade parent.
    390410                try:
    class Sets(Category): 
    699719    class HomCategory(HomCategory):
    700720        pass
    701721
     722    Facades = LazyImport('sage.categories.facade_sets', 'FacadeSets')
     723
    702724    class Subquotients(SubquotientsCategory):
    703725        """
    704726        A category for subquotients of sets
  • sage/combinat/backtrack.py

    diff --git a/sage/combinat/backtrack.py b/sage/combinat/backtrack.py
    a b class SearchForest(Parent): 
    376376            An enumerated set with a forest structure
    377377    """
    378378    def __init__(self, roots = None, children = None, post_process = None,
    379                  algorithm = 'depth', category=None):
     379                 algorithm = 'depth', facade = None, category=None):
    380380        r"""
    381381        TESTS::
    382382
    class SearchForest(Parent): 
    391391        if post_process is not None:
    392392            self.post_process = post_process
    393393        self._algorithm = algorithm
    394         Parent.__init__(self, category = EnumeratedSets().or_subcategory(category))
     394        Parent.__init__(self, facade = facade, category = EnumeratedSets().or_subcategory(category))
    395395
    396396    def _repr_(self):
    397397        r"""
    class PositiveIntegerSemigroup(UniqueRep 
    661661        sage: from sage.combinat.backtrack import PositiveIntegerSemigroup
    662662        sage: PP = PositiveIntegerSemigroup()
    663663        sage: PP.category()
    664         Join of Category of infinite enumerated sets and Category of commutative additive semigroups and Category of monoids
     664        Join of Category of infinite enumerated sets and Category of commutative additive semigroups and Category of monoids and Category of facade sets
    665665        sage: PP.cardinality()
    666666        +Infinity
    667667        sage: PP.one()
    668668        1
    669669        sage: PP.an_element()
    670670        1
    671         sage: list(PP.some_elements())
     671        sage: some_elements = list(PP.some_elements()); some_elements
    672672        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
    673673
    674674    TESTS::
    675675
    676676        sage: from sage.combinat.backtrack import PositiveIntegerSemigroup
    677677        sage: PP = PositiveIntegerSemigroup()
    678         sage: # TODO: remove the skip; see #9065
    679         sage: TestSuite(PP).run(skip='_test_one')  # long time
     678        sage: TestSuite(PP).run(elements=some_elements)
     679        sage: TestSuite(PP).run()  # long time
    680680    """
    681681    def __init__(self):
    682682        r"""
    class PositiveIntegerSemigroup(UniqueRep 
    685685            sage: from sage.combinat.backtrack import PositiveIntegerSemigroup
    686686            sage: PP = PositiveIntegerSemigroup()
    687687        """
    688         SearchForest.__init__(self, category=(InfiniteEnumeratedSets(), CommutativeAdditiveSemigroups(), Monoids()))
     688        SearchForest.__init__(self, facade = ZZ, category=(InfiniteEnumeratedSets(), CommutativeAdditiveSemigroups(), Monoids()))
    689689
    690690    def roots(self):
    691691        r"""
  • sage/rings/semirings/non_negative_integer_semiring.py

    diff --git a/sage/rings/semirings/non_negative_integer_semiring.py b/sage/rings/semirings/non_negative_integer_semiring.py
    a b class NonNegativeIntegerSemiring(NonNega 
    2626        sage: NonNegativeIntegerSemiring()
    2727        Non negative integer semiring
    2828
    29     For convenience, ``NN`` is a chortcut for
     29    For convenience, ``NN`` is a shortcut for
    3030    ``NonNegativeIntegerSemiring()``::
    3131
    3232        sage: NN is NonNegativeIntegerSemiring()
    3333        True
    3434
    3535        sage: NN.category()
    36         Join of Category of semirings and Category of infinite enumerated sets
     36        Join of Category of semirings and Category of infinite enumerated sets and Category of facade sets
    3737
    3838    Here is a piece of the Cayley graph for the multiplicative structure::
    3939
    class NonNegativeIntegerSemiring(NonNega 
    5858        sage: x+3
    5959        18
    6060
    61     TESTS::
    62 
    63         sage: # TODO : remove this skip, see #9065
    64         sage: TestSuite(NN).run(skip=["_test_one","_test_zero"])
    6561    """
    6662    def __init__(self):
    6763        r"""
    6864        TESTS::
    6965
    70             sage: NonNegativeIntegerSemiring()
     66            sage: NN = NonNegativeIntegerSemiring(); NN
    7167            Non negative integer semiring
    72             sage: NonNegativeIntegerSemiring().category().super_categories()
    73             [Category of semirings, Category of infinite enumerated sets]
     68            sage: NN.category()
     69            Join of Category of semirings and Category of infinite enumerated sets and Category of facade sets
     70            sage: TestSuite(NN).run()
    7471        """
    7572        NonNegativeIntegers.__init__(self, category=(Semirings(), InfiniteEnumeratedSets()) )
    7673
  • sage/sets/finite_enumerated_set.py

    diff --git a/sage/sets/finite_enumerated_set.py b/sage/sets/finite_enumerated_set.py
    a b class FiniteEnumeratedSet(UniqueRepresen 
    5050        sage: S.first()
    5151        1
    5252        sage: S.category()
    53         Category of finite enumerated sets
     53        Category of facade finite enumerated sets
    5454        sage: TestSuite(S).run()
    5555
    5656    Note that being and enumerated set, the result depends on the order::
    class FiniteEnumeratedSet(UniqueRepresen 
    107107        TESTS::
    108108
    109109            sage: S = FiniteEnumeratedSet([1,2,3])
    110             sage: S == loads(dumps(S))
    111             True
     110            sage: TestSuite(S).run()
    112111        """
    113112        self._elements = elements
    114         Parent.__init__(self, category = FiniteEnumeratedSets())
     113        Parent.__init__(self, facade = True, category = FiniteEnumeratedSets())
    115114
    116     def __repr__(self):
     115    def _repr_(self):
    117116        """
    118117        TESTS::
    119118
    class FiniteEnumeratedSet(UniqueRepresen 
    141140            False
    142141            sage: ZZ in S
    143142            False
     143
     144            sage: S.is_parent_of(2)
     145            True
     146            sage: S.is_parent_of(4)
     147            False
    144148        """
    145149        return x in self._elements
     150    is_parent_of = __contains__
    146151
    147152    def list(self):
    148153        """
  • sage/sets/integer_range.py

    diff --git a/sage/sets/integer_range.py b/sage/sets/integer_range.py
    a b AUTHORS: 
    1616from sage.structure.parent import Parent
    1717from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets
    1818from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
    19 from sage.categories.sets_cat import EmptySetError
    2019from sage.structure.unique_representation import UniqueRepresentation
    2120from sage.rings.integer import Integer
     21from sage.rings.integer_ring import IntegerRing
    2222from sage.rings.infinity import Infinity, MinusInfinity, PlusInfinity
    2323
    2424class IntegerRange(UniqueRepresentation, Parent):
    class IntegerRange(UniqueRepresentation, 
    6565        sage: list(I)
    6666        [2, 7, 12, 17, 22, 27, 32, 37, 42, 47, 52, 57, 62, 67, 72, 77, 82, 87, 92, 97]
    6767        sage: I.category()
    68         Category of finite enumerated sets
     68        Category of facade finite enumerated sets
    6969        sage: I[1].parent()
    7070        Integer Ring
    7171
    class IntegerRange(UniqueRepresentation, 
    8989        sage: I = IntegerRange(54,Infinity,3); I
    9090        {54, 57, ..}
    9191        sage: I.category()
    92         Category of infinite enumerated sets
     92        Category of facade infinite enumerated sets
    9393        sage: p = iter(I)
    9494        sage: (p.next(), p.next(), p.next(), p.next(), p.next(), p.next())
    9595        (54, 57, 60, 63, 66, 69)
    class IntegerRange(UniqueRepresentation, 
    9797        sage: I = IntegerRange(54,-Infinity,-3); I
    9898        {54, 51, ..}
    9999        sage: I.category()
    100         Category of infinite enumerated sets
     100        Category of facade infinite enumerated sets
    101101        sage: p = iter(I)
    102102        sage: (p.next(), p.next(), p.next(), p.next(), p.next(), p.next())
    103103        (54, 51, 48, 45, 42, 39)
    class IntegerRange(UniqueRepresentation, 
    111111        sage: I = IntegerRange(-Infinity,Infinity,37,-12); I
    112112        Integer progression containing -12 with increment 37 and bounded with -Infinity and +Infinity
    113113        sage: I.category()
    114         Category of infinite enumerated sets
     114        Category of facade infinite enumerated sets
    115115        sage: -12 in I
    116116        True
    117117        sage: -15 in I
    class IntegerRangeEmpty(IntegerRange, Fi 
    285285            sage: I = IntegerRangeEmpty(); I
    286286            {}
    287287            sage: I.category()
    288             Category of finite enumerated sets
     288            Category of facade finite enumerated sets
    289289            sage: TestSuite(I).run()
    290290            sage: I(0)
    291291            Traceback (most recent call last):
    class IntegerRangeFinite(IntegerRange): 
    307307
    308308            sage: I = IntegerRange(123,12,-4)
    309309            sage: I.category()
    310             Category of finite enumerated sets
     310            Category of facade finite enumerated sets
    311311            sage: TestSuite(I).run()
    312312        """
    313313        self._begin = begin
    314314        self._end = end
    315315        self._step = step
    316         Parent.__init__(self, category = FiniteEnumeratedSets())
     316        Parent.__init__(self, facade = IntegerRing(), category = FiniteEnumeratedSets())
    317317
    318318    def __contains__(self, elt):
    319319        r"""
    class IntegerRangeInfinite(IntegerRange) 
    450450
    451451            sage: I = IntegerRange(-57,Infinity,8)
    452452            sage: I.category()
    453             Category of infinite enumerated sets
     453            Category of facade infinite enumerated sets
    454454            sage: TestSuite(I).run()
    455455        """
    456456        assert isinstance(begin, Integer)
    457457        self._begin = begin
    458458        self._step = step
    459         Parent.__init__(self, category = InfiniteEnumeratedSets())
     459        Parent.__init__(self, facade = IntegerRing(), category = InfiniteEnumeratedSets())
    460460
    461461    def _repr_(self):
    462462        r"""
    class IntegerRangeFromMiddle(IntegerRang 
    551551            sage: from sage.sets.integer_range import IntegerRangeFromMiddle
    552552            sage: I = IntegerRangeFromMiddle(-100,100,10,0)
    553553            sage: I.category()
    554             Category of finite enumerated sets
     554            Category of facade finite enumerated sets
    555555            sage: TestSuite(I).run()
    556556            sage: I = IntegerRangeFromMiddle(Infinity,-Infinity,-37,0)
    557557            sage: I.category()
    558             Category of infinite enumerated sets
     558            Category of facade infinite enumerated sets
    559559            sage: TestSuite(I).run()
    560560
    561561            sage: IntegerRange(0, 5, 1, -3)
    class IntegerRangeFromMiddle(IntegerRang 
    571571
    572572        if (begin != Infinity and begin != -Infinity) and \
    573573             (end != Infinity and end != -Infinity):
    574             Parent.__init__(self, category = FiniteEnumeratedSets())
     574            Parent.__init__(self, facade = IntegerRing(), category = FiniteEnumeratedSets())
    575575        else:
    576             Parent.__init__(self, category = InfiniteEnumeratedSets())
     576            Parent.__init__(self, facade = IntegerRing(), category = InfiniteEnumeratedSets())
    577577
    578578    def __repr__(self):
    579579        r"""
  • sage/sets/non_negative_integers.py

    diff --git a/sage/sets/non_negative_integers.py b/sage/sets/non_negative_integers.py
    a b class NonNegativeIntegers(UniqueRepresen 
    7676            sage: NN
    7777            Non negative integers
    7878            sage: NN.category()
    79             Category of infinite enumerated sets
     79            Category of facade infinite enumerated sets
    8080            sage: TestSuite(NN).run()
    8181        """
    82         Parent.__init__(self, category = InfiniteEnumeratedSets().or_subcategory(category) )
     82        from sage.rings.integer_ring import ZZ
     83        Parent.__init__(self, facade = ZZ, category = InfiniteEnumeratedSets().or_subcategory(category) )
    8384
    8485    def _repr_(self):
    8586        """
  • sage/sets/positive_integers.py

    diff --git a/sage/sets/positive_integers.py b/sage/sets/positive_integers.py
    a b class PositiveIntegers(IntegerRangeInfin 
    5353
    5454            sage: PP = PositiveIntegers()
    5555            sage: PP.category()
    56             Category of infinite enumerated sets
     56            Category of facade infinite enumerated sets
    5757        """
    5858        IntegerRangeInfinite.__init__(self, Integer(1), Integer(1))
    5959
    60     def __repr__(self):
     60    def _repr_(self):
    6161        r"""
    6262        EXAMPLES::
    6363
  • sage/sets/primes.py

    diff --git a/sage/sets/primes.py b/sage/sets/primes.py
    a b class Primes(Set_generic, UniqueRepresen 
    7777
    7878        TESTS::
    7979
     80            sage: P.category()
     81            Category of facade infinite enumerated sets
    8082            sage: TestSuite(P).run()
     83
     84            sage: Q.category()
     85            Category of facade infinite enumerated sets
    8186            sage: TestSuite(Q).run()
    8287
    8388        The set of primes can be compared to various things,
    class Primes(Set_generic, UniqueRepresen 
    104109            sage: cmp('foo', Primes()) != cmp(Primes(), 'foo')
    105110            True
    106111        """
    107         super(Primes, self).__init__(category = InfiniteEnumeratedSets())
     112        super(Primes, self).__init__(facade = ZZ, category = InfiniteEnumeratedSets())
    108113        self.__proof = proof
    109114
    110115    def _repr_(self):
  • sage/structure/parent.pyx

    diff --git a/sage/structure/parent.pyx b/sage/structure/parent.pyx
    a b cdef class Parent(category_object.Catego 
    403403
    404404    """
    405405   
    406     def __init__(self, base=None, *, category=None, element_constructor=None, gens=None, names=None, normalize=True, **kwds):
     406    def __init__(self, base=None, *, category=None, element_constructor=None,
     407                 gens=None, names=None, normalize=True, facade=None, **kwds):
    407408        """
    408409
    409410        category: a category or list/tuple of categories
    cdef class Parent(category_object.Catego 
    420421        - base -- An algebraic structure considered to be the "base"
    421422          of this parent (e.g. the base field for a vector space).
    422423
    423         - category -- The category in which this parent lies.  Since
    424           categories support more general super-categories, this
    425           should be the most specific category possible.
     424        - category -- The category in which this parent lies (or list
     425          or tuple thereof).  Since categories support more general
     426          super-categories, this should be the most specific category
     427          possible.
    426428
    427429        - element_constructor -- A class or function that creates
    428430          elements of this Parent given appropriate input (can also be
    cdef class Parent(category_object.Catego 
    432434          later with ``_populate_generators_``)
    433435
    434436        - names -- Names of generators.
    435        
     437
    436438        - normalize -- Whether to standardize the names (remove punctuation, etc)
     439
     440        - ``facade`` -- a parent, or tuple thereof, or ``True``
     441
     442        If ``facade`` is specified, then ``Sets().Facades()`` is added
     443        to the categories of the parent. Furthermore, if ``facade`` is
     444        not ``True``, the internal attribute _facade_for is set
     445        accordingly for use by :meth:`Sets.Facades.ParentMethods.facade_for`.
    437446        """
    438447
    439448        # TODO: in the long run, we want to get rid of the element_constructor = argument
    cdef class Parent(category_object.Catego 
    441450        # Then, all the element_constructor logic should be moved to init_coerce.
    442451
    443452        CategoryObject.__init__(self, base = base)
     453        if facade is not None and facade is not False:
     454            if isinstance(facade, Parent):
     455                facade = (facade,)
     456            if facade is not True:
     457                assert isinstance(facade, tuple)
     458                self._facade_for = facade
     459            from sage.categories.sets_cat import Sets
     460            if category is None:
     461                category = Sets().Facades()
     462            else:
     463                category = Category.join((category, Sets().Facades()))
    444464        # Setting the categories is currently done in a separate
    445465        # method to let some subclasses (like ParentsWithBase)
    446466        # call it without calling the full constructor
    cdef class Parent(category_object.Catego 
    22172237
    22182238            sage: S = FiniteEnumeratedSet([1,2,3])
    22192239            sage: S.category()
    2220             Category of finite enumerated sets
     2240            Category of facade finite enumerated sets
    22212241            sage: super(Parent, S)._an_element_
    22222242            Cached version of <function _an_element_from_iterator at ...>
    22232243            sage: S._an_element_()