Path: blob/master/src/sage/monoids/free_abelian_monoid.py
8815 views
r"""1Free abelian monoids23AUTHORS:45- David Kohel (2005-09)67Sage supports free abelian monoids on any prescribed finite number8`n\geq 0` of generators. Use the9``FreeAbelianMonoid`` function to create a free abelian10monoid, and the ``gen`` and ``gens``11functions to obtain the corresponding generators. You can print the12generators as arbitrary strings using the optional13``names`` argument to the14``FreeAbelianMonoid`` function.1516EXAMPLE 1: It is possible to create an abelian monoid in zero or17more variables; the syntax T(1) creates the monoid identity18element even in the rank zero case.1920::2122sage: T = FreeAbelianMonoid(0, '')23sage: T24Free abelian monoid on 0 generators ()25sage: T.gens()26()27sage: T(1)2812930EXAMPLE 2: A free abelian monoid uses a multiplicative31representation of elements, but the underlying representation is32lists of integer exponents.3334::3536sage: F = FreeAbelianMonoid(5,names='a,b,c,d,e')37sage: (a,b,c,d,e) = F.gens()38sage: a*b^2*e*d39a*b^2*d*e40sage: x = b^2*e*d*a^741sage: x42a^7*b^2*d*e43sage: x.list()44[7, 2, 0, 1, 1]45"""4647#*****************************************************************************48# Copyright (C) 2005 David Kohel <[email protected]>49#50# Distributed under the terms of the GNU General Public License (GPL):51#52# http://www.gnu.org/licenses/53#*****************************************************************************545556from sage.structure.parent_gens import ParentWithGens, normalize_names57from free_abelian_monoid_element import FreeAbelianMonoidElement58from sage.rings.integer import Integer5960from sage.structure.factory import UniqueFactory6162class FreeAbelianMonoidFactory(UniqueFactory):63"""64Create the free abelian monoid in `n` generators.6566INPUT:676869- ``n`` - integer7071- ``names`` - names of generators727374OUTPUT: free abelian monoid7576EXAMPLES::7778sage: FreeAbelianMonoid(0, '')79Free abelian monoid on 0 generators ()80sage: F = FreeAbelianMonoid(5,names = list("abcde"))81sage: F82Free abelian monoid on 5 generators (a, b, c, d, e)83sage: F(1)84185sage: (a, b, c, d, e) = F.gens()86sage: mul([ a, b, a, c, b, d, c, d ], F(1))87a^2*b^2*c^2*d^288sage: a**2 * b**3 * a**2 * b**489a^4*b^79091::9293sage: loads(dumps(F)) is F94True95"""96def create_key(self, n, names):97n = int(n)98names = normalize_names(n, names)99return (n, names)100def create_object(self, version, key):101return FreeAbelianMonoid_class(*key)102103FreeAbelianMonoid = FreeAbelianMonoidFactory("FreeAbelianMonoid")104105106def is_FreeAbelianMonoid(x):107"""108Return True if `x` is a free abelian monoid.109110EXAMPLES::111112sage: from sage.monoids.free_abelian_monoid import is_FreeAbelianMonoid113sage: is_FreeAbelianMonoid(5)114False115sage: is_FreeAbelianMonoid(FreeAbelianMonoid(7,'a'))116True117sage: is_FreeAbelianMonoid(FreeMonoid(7,'a'))118False119sage: is_FreeAbelianMonoid(FreeMonoid(0,''))120False121"""122return isinstance(x, FreeAbelianMonoid_class)123124class FreeAbelianMonoid_class(ParentWithGens):125"""126Free abelian monoid on `n` generators.127"""128def __init__(self, n, names):129if not isinstance(n, (int, long, Integer)):130raise TypeError, "n (=%s) must be an integer."%n131if n < 0:132raise ValueError, "n (=%s) must be nonnegative."%n133self.__ngens = int(n)134assert not names is None135self._assign_names(names)136137def __repr__(self):138n = self.__ngens139return "Free abelian monoid on %s generators %s"%(n,self.gens())140141def __call__(self, x):142"""143Create an element of this abelian monoid from `x`.144145EXAMPLES::146147sage: F = FreeAbelianMonoid(10,'x')148sage: F(F.gen(2))149x2150sage: F(1)1511152"""153if isinstance(x, FreeAbelianMonoidElement) and x.parent() == self:154return x155return FreeAbelianMonoidElement(self, x)156157158def __contains__(self, x):159"""160Return True if `x` is an element of this abelian monoid.161162EXAMPLES::163164sage: F = FreeAbelianMonoid(10,'b')165sage: F.gen(2)*F.gen(3) in F166True167168Note that a monoid on `9` generators is not considered a169submonoid of one on `10` generators.170171::172173sage: FreeAbelianMonoid(9,'c').gen(2) in F174False175176However, multiple calls to the monoid constructor do *not* return177multiple distinct monoids.178179::180181sage: FreeAbelianMonoid(10,'b').gen(2) in F182True183"""184return isinstance(x, FreeAbelianMonoidElement) and x.parent() == self185186def gen(self, i=0):187"""188The `i`-th generator of the abelian monoid.189190EXAMPLES::191192sage: F = FreeAbelianMonoid(5,'a')193sage: F.gen(0)194a0195sage: F.gen(2)196a2197"""198n = self.__ngens199if i < 0 or not i < n:200raise IndexError, "Argument i (= %s) must be between 0 and %s."%(i, n-1)201x = [ 0 for j in range(n) ]202x[int(i)] = 1203return FreeAbelianMonoidElement(self,x)204205def ngens(self):206"""207The number of free generators of the abelian monoid.208209EXAMPLES::210211sage: F = FreeAbelianMonoid(3000, 'a')212sage: F.ngens()2133000214"""215return self.__ngens216217218219