Example #1
0
 def super_categories(self):
     from sage.categories.objects import Objects
     """
    The right thing to return would be 'Objects()', but that doesn't have Subquotients and CartesianProducts.
    Likewise, 'Sets()' doesn't have TensorProducts... which we're changing below
    """
     return [
         Objects(),
     ]
Example #2
0
def retrieve_structure_of_gap_handle(self):
    """
    Return the category corresponding to the properties and categories
    of the handled gap object.

    EXAMPLES::

        sage: import mygap
        sage: F = libgap.FreeGroup(3)
        sage: mygap.retrieve_structure_of_gap_handle(F)
        (Category of groups, <class 'mygap.GAPParent'>)

        sage: mygap.retrieve_structure_of_gap_handle(F.Iterator())
        (Category of objects, <class 'mygap.GAPIterator'>)

        sage: from mygap import mygap
        sage: mygap.FiniteField(3) in Fields().Finite().Enumerated().GAP()
        True

        sage: mygap.eval("Integers") in Rings().Commutative().GAP().Infinite()
        True
        sage: mygap.eval("Integers").category()
        Join of Category of commutative rings and Category of g a p monoids and Category of commutative g a p magmas and Category of finite dimensional g a p modules with basis over rings and Category of infinite g a p sets

        sage: mygap.eval("PositiveIntegers").category()
        Category of infinite commutative associative unital additive commutative additive associative distributive g a p magmas and additive magmas
        sage: mygap.eval("Cyclotomics") in Fields().Infinite().GAP()
        True
    """
    structure = Structure(GAPObject, Objects())
    gap_categories = [str(cat) for cat in self.CategoriesOfObject()]
    for cat in gap_categories:
        if cat in gap_category_to_structure:
            gap_category_to_structure[cat](structure)
    properties = set(str(prop) for prop in self.KnownPropertiesOfObject())
    true_properties = set(
        str(prop) for prop in self.KnownTruePropertiesOfObject())
    for prop in properties:
        if prop in true_properties:
            if prop in gap_category_to_structure:
                gap_category_to_structure[prop](structure)
        else:
            if prop in false_properties_to_structure:
                false_properties_to_structure[prop](structure)

    # Special cases that can't yet be handled by the infrastructure
    # - We don't have the LDistributive and RDistributive
    #   axioms, and the current infrastructure does not allow to make a
    #   "and" on two axioms "IsLDistributive": "Distributive"
    if "IsLDistributive" in true_properties and "IsRDistributive" in true_properties:
        # Work around: C._with_axiom("Distributive") does not work
        structure.category = structure.category.Distributive()
    if "IsMagmaWithInversesIfNonzero" in gap_categories and structure.category.is_subcategory(
            Rings()):
        structure.category = structure.category.Division()
    return structure
Example #3
0
def category(x):
    """
    Return the category of ``x``.

    EXAMPLES::

        sage: V = VectorSpace(QQ,3)
        sage: category(V)
        Category of finite dimensional vector spaces with basis over
         (number fields and quotient fields and metric spaces)
    """
    try:
        return x.category()
    except AttributeError:
        from sage.categories.objects import Objects
        return Objects()
Example #4
0
def transform_category(category,
                       subcategory_mapping, axiom_mapping,
                       initial_category=None):
    r"""
    Transform ``category`` to a new category according to the given
    mappings.

    INPUT:

    - ``category`` -- a category.

    - ``subcategory_mapping`` -- a list (or other iterable) of triples
      ``(from, to, mandatory)``, where

      - ``from`` and ``to`` are categories and
      - ``mandatory`` is a boolean.

    - ``axiom_mapping`` -- a list (or other iterable) of triples
      ``(from, to, mandatory)``, where

      - ``from`` and ``to`` are strings describing axioms and
      - ``mandatory`` is a boolean.

    - ``initial_category`` -- (default: ``None``) a category. When
      transforming the given category, this ``initial_category`` is
      used as a starting point of the result. This means the resulting
      category will be a subcategory of ``initial_category``.
      If ``initial_category`` is ``None``, then the
      :class:`category of objects <sage.categories.objects.Objects>`
      is used.

    OUTPUT:

    A category.

    .. NOTE::

        Consider a subcategory mapping ``(from, to, mandatory)``. If
        ``category`` is a subcategory of ``from``, then the
        returned category will be a subcategory of ``to``. Otherwise and
        if ``mandatory`` is set, then an error is raised.

        Consider an axiom mapping ``(from, to, mandatory)``. If
        ``category`` is has axiom ``from``, then the
        returned category will have axiom ``to``. Otherwise and
        if ``mandatory`` is set, then an error is raised.

    EXAMPLES::

        sage: from sage.rings.asymptotic.misc import transform_category
        sage: from sage.categories.additive_semigroups import AdditiveSemigroups
        sage: from sage.categories.additive_monoids import AdditiveMonoids
        sage: from sage.categories.additive_groups import AdditiveGroups
        sage: S = [
        ....:     (Sets(), Sets(), True),
        ....:     (Posets(), Posets(), False),
        ....:     (AdditiveMagmas(), Magmas(), False)]
        sage: A = [
        ....:     ('AdditiveAssociative', 'Associative', False),
        ....:     ('AdditiveUnital', 'Unital', False),
        ....:     ('AdditiveInverse', 'Inverse', False),
        ....:     ('AdditiveCommutative', 'Commutative', False)]
        sage: transform_category(Objects(), S, A)
        Traceback (most recent call last):
        ...
        ValueError: Category of objects is not
        a subcategory of Category of sets.
        sage: transform_category(Sets(), S, A)
        Category of sets
        sage: transform_category(Posets(), S, A)
        Category of posets
        sage: transform_category(AdditiveSemigroups(), S, A)
        Category of semigroups
        sage: transform_category(AdditiveMonoids(), S, A)
        Category of monoids
        sage: transform_category(AdditiveGroups(), S, A)
        Category of groups
        sage: transform_category(AdditiveGroups().AdditiveCommutative(), S, A)
        Category of commutative groups

    ::

        sage: transform_category(AdditiveGroups().AdditiveCommutative(), S, A,
        ....:     initial_category=Posets())
        Join of Category of commutative groups
            and Category of posets

    ::

        sage: transform_category(ZZ.category(), S, A)
        Category of commutative groups
        sage: transform_category(QQ.category(), S, A)
        Category of commutative groups
        sage: transform_category(SR.category(), S, A)
        Category of commutative groups
        sage: transform_category(Fields(), S, A)
        Category of commutative groups
        sage: transform_category(ZZ['t'].category(), S, A)
        Category of commutative groups

    ::

        sage: A[-1] = ('Commutative', 'AdditiveCommutative', True)
        sage: transform_category(Groups(), S, A)
        Traceback (most recent call last):
        ...
        ValueError: Category of groups does not have
        axiom Commutative.
    """
    if initial_category is None:
        from sage.categories.objects import Objects
        result = Objects()
    else:
        result = initial_category

    for A, B, mandatory in subcategory_mapping:
        if category.is_subcategory(A):
            result &= B
        elif mandatory:
            raise ValueError('%s is not a subcategory of %s.' %
                             (category, A))

    axioms = category.axioms()
    for A, B, mandatory in axiom_mapping:
        if A in axioms:
            result = result._with_axiom(B)
        elif mandatory:
            raise ValueError('%s does not have axiom %s.' %
                             (category, A))

    return result
Example #5
0
def Sequence(x,
             universe=None,
             check=True,
             immutable=False,
             cr=False,
             cr_str=None,
             use_sage_types=False):
    """
    A mutable list of elements with a common guaranteed universe,
    which can be set immutable.

    A universe is either an object that supports coercion (e.g., a
    parent), or a category.

    INPUT:

    - ``x`` - a list or tuple instance

    - ``universe`` - (default: None) the universe of elements; if None
      determined using canonical coercions and the entire list of
      elements.  If list is empty, is category Objects() of all
      objects.

    - ``check`` -- (default: True) whether to coerce the elements of x
      into the universe

    - ``immutable`` - (default: True) whether or not this sequence is
      immutable

    - ``cr`` - (default: False) if True, then print a carriage return
      after each comma when printing this sequence.

    - ``cr_str`` - (default: False) if True, then print a carriage return
      after each comma when calling ``str()`` on this sequence.

    - ``use_sage_types`` -- (default: False) if True, coerce the
       built-in Python numerical types int, float, complex to the
       corresponding Sage types (this makes functions like vector()
       more flexible)

    OUTPUT:

    - a sequence

    EXAMPLES::

        sage: v = Sequence(range(10))
        sage: v.universe()
        <type 'int'>
        sage: v
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    We can request that the built-in Python numerical types be coerced
    to Sage objects::

        sage: v = Sequence(range(10), use_sage_types=True)
        sage: v.universe()
        Integer Ring
        sage: v
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    You can also use seq for "Sequence", which is identical to using
    Sequence::

        sage: v = seq([1,2,1/1]); v
        [1, 2, 1]
        sage: v.universe()
        Rational Field

    Note that assignment coerces if possible,::

        sage: v = Sequence(range(10), ZZ)
        sage: a = QQ(5)
        sage: v[3] = a
        sage: parent(v[3])
        Integer Ring
        sage: parent(a)
        Rational Field
        sage: v[3] = 2/3
        Traceback (most recent call last):
        ...
        TypeError: no conversion of this rational to integer

    Sequences can be used absolutely anywhere lists or tuples can be used::

        sage: isinstance(v, list)
        True

    Sequence can be immutable, so entries can't be changed::

        sage: v = Sequence([1,2,3], immutable=True)
        sage: v.is_immutable()
        True
        sage: v[0] = 5
        Traceback (most recent call last):
        ...
        ValueError: object is immutable; please change a copy instead.

    Only immutable sequences are hashable (unlike Python lists),
    though the hashing is potentially slow, since it first involves
    conversion of the sequence to a tuple, and returning the hash of
    that.::

        sage: v = Sequence(range(10), ZZ, immutable=True)
        sage: hash(v) == hash(tuple(range(10)))
        True


    If you really know what you are doing, you can circumvent the type
    checking (for an efficiency gain)::

        sage: list.__setitem__(v, int(1), 2/3)        # bad circumvention
        sage: v
        [0, 2/3, 2, 3, 4, 5, 6, 7, 8, 9]
        sage: list.__setitem__(v, int(1), int(2))     # not so bad circumvention

    You can make a sequence with a new universe from an old sequence.::

        sage: w = Sequence(v, QQ)
        sage: w
        [0, 2, 2, 3, 4, 5, 6, 7, 8, 9]
        sage: w.universe()
        Rational Field
        sage: w[1] = 2/3
        sage: w
        [0, 2/3, 2, 3, 4, 5, 6, 7, 8, 9]

    The default universe for any sequence, if no compatible parent structure
    can be found, is the universe of all Sage objects.

    This example illustrates how every element of a list is taken into account
    when constructing a sequence.::

        sage: v = Sequence([1,7,6,GF(5)(3)]); v
        [1, 2, 1, 3]
        sage: v.universe()
        Finite Field of size 5

    TESTS::

        sage: Sequence(["a"], universe=ZZ)
        Traceback (most recent call last):
        ...
        TypeError: unable to convert a to an element of Integer Ring
    """
    from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal

    if isinstance(x, Sequence_generic) and universe is None:
        universe = x.universe()
        x = list(x)

    if isinstance(x, MPolynomialIdeal) and universe is None:
        universe = x.ring()
        x = x.gens()

    if universe is None:
        orig_x = x
        x = list(
            x)  # make a copy even if x is a list, we're going to change it

        if len(x) == 0:
            from sage.categories.objects import Objects
            universe = Objects()
        else:
            import sage.structure.element
            if use_sage_types:
                # convert any Python built-in numerical types to Sage objects
                x = [sage.structure.coerce.py_scalar_to_element(e) for e in x]
            # start the pairwise coercion
            for i in range(len(x) - 1):
                try:
                    x[i], x[i + 1] = sage.structure.element.canonical_coercion(
                        x[i], x[i + 1])
                except TypeError:
                    from sage.categories.objects import Objects
                    universe = Objects()
                    x = list(orig_x)
                    check = False  # no point
                    break
            if universe is None:  # no type errors raised.
                universe = sage.structure.element.parent(x[len(x) - 1])

    from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
    from sage.rings.polynomial.pbori.pbori import BooleanMonomialMonoid
    from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing
    from sage.rings.quotient_ring import is_QuotientRing

    if is_MPolynomialRing(universe) or isinstance(
            universe, BooleanMonomialMonoid) or (is_QuotientRing(universe)
                                                 and is_MPolynomialRing(
                                                     universe.cover_ring())):
        return PolynomialSequence(x,
                                  universe,
                                  immutable=immutable,
                                  cr=cr,
                                  cr_str=cr_str)
    else:
        return Sequence_generic(x, universe, check, immutable, cr, cr_str,
                                use_sage_types)
Example #6
0
    def super_categories(self):
        from sage.categories.objects import Objects

        return [Objects()]