Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Free abelian monoids
AUTHORS:
- David Kohel (2005-09)
Sage supports free abelian monoids on any prescribed finite number `n\geq 0` of generators. Use the ``FreeAbelianMonoid`` function to create a free abelian monoid, and the ``gen`` and ``gens`` functions to obtain the corresponding generators. You can print the generators as arbitrary strings using the optional ``names`` argument to the ``FreeAbelianMonoid`` function.
EXAMPLE 1: It is possible to create an abelian monoid in zero or more variables; the syntax T(1) creates the monoid identity element even in the rank zero case.
::
sage: T = FreeAbelianMonoid(0, '') sage: T Free abelian monoid on 0 generators () sage: T.gens() () sage: T(1) 1
EXAMPLE 2: A free abelian monoid uses a multiplicative representation of elements, but the underlying representation is lists of integer exponents.
::
sage: F = FreeAbelianMonoid(5,names='a,b,c,d,e') sage: (a,b,c,d,e) = F.gens() sage: a*b^2*e*d a*b^2*d*e sage: x = b^2*e*d*a^7 sage: x a^7*b^2*d*e sage: x.list() [7, 2, 0, 1, 1] """ #***************************************************************************** # Copyright (C) 2005 David Kohel <kohel@maths.usyd.edu> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ #***************************************************************************** from __future__ import absolute_import from six import integer_types
from sage.misc.cachefunc import cached_method from sage.structure.category_object import normalize_names from sage.structure.parent import Parent from sage.categories.monoids import Monoids from .free_abelian_monoid_element import FreeAbelianMonoidElement from sage.rings.integer import Integer from sage.rings.all import ZZ
from sage.structure.factory import UniqueFactory from sage.misc.decorators import rename_keyword
class FreeAbelianMonoidFactory(UniqueFactory): """ Create the free abelian monoid in `n` generators.
INPUT:
- ``n`` - integer
- ``names`` - names of generators
OUTPUT: free abelian monoid
EXAMPLES::
sage: FreeAbelianMonoid(0, '') Free abelian monoid on 0 generators () sage: F = FreeAbelianMonoid(5,names = list("abcde")) sage: F Free abelian monoid on 5 generators (a, b, c, d, e) sage: F(1) 1 sage: (a, b, c, d, e) = F.gens() sage: mul([ a, b, a, c, b, d, c, d ], F(1)) a^2*b^2*c^2*d^2 sage: a**2 * b**3 * a**2 * b**4 a^4*b^7
::
sage: loads(dumps(F)) is F True """ def create_key(self, n, names): def create_object(self, version, key):
FreeAbelianMonoid_factory = FreeAbelianMonoidFactory("sage.monoids.free_abelian_monoid.FreeAbelianMonoid_factory")
@rename_keyword(deprecation=15289, n="index_set") def FreeAbelianMonoid(index_set=None, names=None, **kwds): """ Return a free abelian monoid on `n` generators or with the generators indexed by a set `I`.
We construct free abelian monoids by specifing either:
- the number of generators and/or the names of the generators - the indexing set for the generators (this ignores the other two inputs)
INPUT:
- ``index_set`` -- an indexing set for the generators; if an integer, then this becomes `\{0, 1, \ldots, n-1\}`
- ``names`` -- names of generators
OUTPUT:
A free abelian monoid.
EXAMPLES::
sage: F.<a,b,c,d,e> = FreeAbelianMonoid(); F Free abelian monoid on 5 generators (a, b, c, d, e) sage: FreeAbelianMonoid(index_set=ZZ) Free abelian monoid indexed by Integer Ring """ names, index_set = index_set, names
index_set = names.count(',') else:
names = normalize_names(len(names), names)
raise ValueError("names must be specified")
def is_FreeAbelianMonoid(x): """ Return True if `x` is a free abelian monoid.
EXAMPLES::
sage: from sage.monoids.free_abelian_monoid import is_FreeAbelianMonoid sage: is_FreeAbelianMonoid(5) False sage: is_FreeAbelianMonoid(FreeAbelianMonoid(7,'a')) True sage: is_FreeAbelianMonoid(FreeMonoid(7,'a')) False sage: is_FreeAbelianMonoid(FreeMonoid(0,'')) False """
class FreeAbelianMonoid_class(Parent): """ Free abelian monoid on `n` generators. """ Element = FreeAbelianMonoidElement
def __init__(self, n, names): """ Initialize ``self``.
EXAMPLES::
sage: F = FreeAbelianMonoid(6,'b') sage: TestSuite(F).run() """ raise TypeError("n (=%s) must be an integer"%n) raise ValueError("n (=%s) must be nonnegative"%n)
def __repr__(self):
def __call__(self, x): """ Create an element of this abelian monoid from `x`.
EXAMPLES::
sage: F = FreeAbelianMonoid(10,'x') sage: F(F.gen(2)) x2 sage: F(1) 1 """
def __contains__(self, x): """ Return True if `x` is an element of this abelian monoid.
EXAMPLES::
sage: F = FreeAbelianMonoid(10,'b') sage: F.gen(2)*F.gen(3) in F True
Note that a monoid on `9` generators is not considered a submonoid of one on `10` generators.
::
sage: FreeAbelianMonoid(9,'c').gen(2) in F False
However, multiple calls to the monoid constructor do *not* return multiple distinct monoids.
::
sage: FreeAbelianMonoid(10,'b').gen(2) in F True """
def gen(self, i=0): """ The `i`-th generator of the abelian monoid.
EXAMPLES::
sage: F = FreeAbelianMonoid(5,'a') sage: F.gen(0) a0 sage: F.gen(2) a2 """ raise IndexError("Argument i (= %s) must be between 0 and %s."%(i, n-1))
@cached_method def gens(self): """ Return the generators of ``self``.
EXAMPLES::
sage: F = FreeAbelianMonoid(5,'a') sage: F.gens() (a0, a1, a2, a3, a4) """
def ngens(self): """ The number of free generators of the abelian monoid.
EXAMPLES::
sage: F = FreeAbelianMonoid(3000, 'a') sage: F.ngens() 3000 """
def cardinality(self): r""" Return the cardinality of ``self``, which is `\infty`.
EXAMPLES::
sage: F = FreeAbelianMonoid(3000, 'a') sage: F.cardinality() +Infinity """ from sage.rings.all import ZZ return ZZ.one()
|