Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
trac 26221: FreeMonoid: use UniqueRepresentation instead of UniqueFac…
Browse files Browse the repository at this point in the history
…tory.
  • Loading branch information
jhpalmieri committed Sep 9, 2018
1 parent d6c3b5f commit 8c1e9ea
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 108 deletions.
178 changes: 75 additions & 103 deletions src/sage/monoids/free_monoid.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,111 +34,11 @@

from sage.combinat.words.finite_word import FiniteWord_class

from sage.structure.factory import UniqueFactory
from sage.structure.unique_representation import UniqueRepresentation
from sage.misc.decorators import rename_keyword
from sage.rings.all import ZZ


class FreeMonoidFactory(UniqueFactory):
"""
Create the free monoid in `n` generators.
INPUT:
- ``n`` - integer
- ``names`` - names of generators
OUTPUT: free monoid
EXAMPLES::
sage: FreeMonoid(0,'')
Free monoid on 0 generators ()
sage: F.<a,b,c,d,e> = FreeMonoid(5); F
Free monoid on 5 generators (a, b, c, d, e)
sage: F(1)
1
sage: mul([ a, b, a, c, b, d, c, d ], F(1))
a*b*a*c*b*d*c*d
"""
def create_key(self, n, names):
n = int(n)
names = normalize_names(n, names)
return (n, names)
def create_object(self, version, key, **kwds):
return FreeMonoid_class(*key)

FreeMonoid_factory = FreeMonoidFactory("sage.monoids.free_monoid.FreeMonoid_factory")

@rename_keyword(deprecation=15289, n="index_set")
def FreeMonoid(index_set=None, names=None, commutative=False, **kwds):
r"""
Return a free monoid on `n` generators or with the generators indexed by
a set `I`.
We construct free monoids by specifing either:
- the number of generators and/or the names of the generators
- the indexing set for the generators
INPUT:
- ``index_set`` -- an indexing set for the generators; if an integer,
than this becomes `\{0, 1, \ldots, n-1\}`
- ``names`` -- names of generators
- ``commutative`` -- (default: ``False``) whether the free monoid is
commutative or not
OUTPUT:
A free monoid.
EXAMPLES::
sage: F.<a,b,c,d,e> = FreeMonoid(); F
Free monoid on 5 generators (a, b, c, d, e)
sage: FreeMonoid(index_set=ZZ)
Free monoid indexed by Integer Ring
sage: F.<x,y,z> = FreeMonoid(abelian=True); F
Free abelian monoid on 3 generators (x, y, z)
sage: FreeMonoid(index_set=ZZ, commutative=True)
Free abelian monoid indexed by Integer Ring
TESTS::
sage: FreeMonoid(index_set=ZZ, names='x,y,z')
Free monoid indexed by Integer Ring
"""
if 'abelian' in kwds:
commutative = kwds.pop('abelian')

if commutative:
from sage.monoids.free_abelian_monoid import FreeAbelianMonoid
return FreeAbelianMonoid(index_set, names, **kwds)

if isinstance(index_set, str): # Swap args (this works if names is None as well)
names, index_set = index_set, names

if index_set is None and names is not None:
if isinstance(names, str):
index_set = names.count(',')
else:
index_set = len(names)

if index_set not in ZZ:
if names is not None:
names = normalize_names(-1, names)
from sage.monoids.indexed_free_monoid import IndexedFreeMonoid
return IndexedFreeMonoid(index_set, names=names, **kwds)

if names is None:
raise ValueError("names must be specified")
return FreeMonoid_factory(index_set, names)

def is_FreeMonoid(x):
"""
Return True if `x` is a free monoid.
Expand All @@ -159,16 +59,88 @@ def is_FreeMonoid(x):
sage: is_FreeMonoid(FreeAbelianMonoid(index_set=ZZ))
False
"""
if isinstance(x, FreeMonoid_class):
if isinstance(x, FreeMonoid):
return True
from sage.monoids.indexed_free_monoid import IndexedFreeMonoid
return isinstance(x, IndexedFreeMonoid)

class FreeMonoid_class(Monoid_class):
class FreeMonoid(Monoid_class, UniqueRepresentation):
"""
The free monoid on `n` generators.
"""
@staticmethod
def __classcall_private__(cls, index_set=None, names=None,
commutative=False, **kwds):
r"""
Return a free monoid on `n` generators or with the generators
indexed by a set `I`.
We construct free monoids by specifing either:
- the number of generators and/or the names of the generators
- the indexing set for the generators
INPUT:
- ``index_set`` -- an indexing set for the generators; if an
integer, than this becomes `\{0, 1, \ldots, n-1\}`
- ``names`` -- names of generators
- ``commutative`` -- (default: ``False``) whether the free
monoid is commutative or not
OUTPUT:
A free monoid.
EXAMPLES::
sage: F.<a,b,c,d,e> = FreeMonoid(); F
Free monoid on 5 generators (a, b, c, d, e)
sage: FreeMonoid(index_set=ZZ)
Free monoid indexed by Integer Ring
sage: F.<x,y,z> = FreeMonoid(abelian=True); F
Free abelian monoid on 3 generators (x, y, z)
sage: FreeMonoid(index_set=ZZ, commutative=True)
Free abelian monoid indexed by Integer Ring
TESTS::
sage: FreeMonoid(index_set=ZZ, names='x,y,z')
Free monoid indexed by Integer Ring
"""

if 'abelian' in kwds:
commutative = kwds.pop('abelian')

if commutative:
from sage.monoids.free_abelian_monoid import FreeAbelianMonoid
return FreeAbelianMonoid(index_set, names, **kwds)

if isinstance(index_set, str): # Swap args (this works if names is None as well)
names, index_set = index_set, names

if index_set is None and names is not None:
if isinstance(names, str):
index_set = names.count(',')
else:
index_set = len(names)

if index_set not in ZZ:
if names is not None:
names = normalize_names(-1, names)
from sage.monoids.indexed_free_monoid import IndexedFreeMonoid
return IndexedFreeMonoid(index_set, names=names, **kwds)

if names is None:
raise ValueError("names must be specified")
names = normalize_names(index_set, names)
return super(FreeMonoid, cls).__classcall__(cls, index_set, names)

Element = FreeMonoidElement

def __init__(self, n, names=None):
"""
Create free monoid on `n` generators.
Expand Down
2 changes: 1 addition & 1 deletion src/sage/monoids/free_monoid_element.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class FreeMonoidElement(MonoidElement):
sage: x**(-1)
Traceback (most recent call last):
...
TypeError: bad operand type for unary ~: 'FreeMonoid_class_with_category.element_class'
TypeError: bad operand type for unary ~: 'FreeMonoid_with_category.element_class'
"""
def __init__(self, F, x, check=True):
"""
Expand Down
8 changes: 4 additions & 4 deletions src/sage/monoids/string_monoid.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#*****************************************************************************


from .free_monoid import FreeMonoid_class
from .free_monoid import FreeMonoid
from .string_monoid_element import StringMonoidElement
from .string_ops import strip_encoding

Expand Down Expand Up @@ -195,7 +195,7 @@ def AlphabeticStrings():
#*****************************************************************************


class StringMonoid_class(FreeMonoid_class):
class StringMonoid_class(FreeMonoid):
r"""
A free string monoid on `n` generators.
"""
Expand All @@ -221,8 +221,8 @@ def __init__(self, n, alphabet=()):
"""
# Names must be alphabetical -- omitted since printing is
# defined locally.
# FreeMonoid_class.__init__(self, n, names = alphabet)
FreeMonoid_class.__init__(self, n)
# FreeMonoid.__init__(self, n, names = alphabet)
FreeMonoid.__init__(self, n)
self._alphabet = alphabet

def __contains__(self, x):
Expand Down

0 comments on commit 8c1e9ea

Please sign in to comment.