Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/monoids/free_monoid.py
4072 views
1
r"""
2
Free Monoids
3
4
AUTHORS:
5
6
- David Kohel (2005-09)
7
- Simon King (2011-04): Put free monoids into the category framework
8
9
Sage supports free monoids on any prescribed finite number
10
`n\geq 0` of generators. Use the ``FreeMonoid``
11
function to create a free monoid, and the ``gen`` and
12
``gens`` functions to obtain the corresponding
13
generators. You can print the generators as arbitrary strings using
14
the optional ``names`` argument to the
15
``FreeMonoid`` function.
16
"""
17
18
#*****************************************************************************
19
# Copyright (C) 2005 David Kohel <[email protected]>
20
#
21
# Distributed under the terms of the GNU General Public License (GPL)
22
#
23
# This code is distributed in the hope that it will be useful,
24
# but WITHOUT ANY WARRANTY; without even the implied warranty
25
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26
#
27
# See the GNU General Public License for more details; the full text
28
# is available at:
29
#
30
# http://www.gnu.org/licenses/
31
#*****************************************************************************
32
33
from sage.rings.integer import Integer
34
from sage.structure.parent_gens import normalize_names
35
from free_monoid_element import FreeMonoidElement
36
37
from monoid import Monoid_class
38
39
40
from sage.structure.factory import UniqueFactory
41
from sage.misc.cachefunc import cached_method
42
43
class FreeMonoidFactory(UniqueFactory):
44
"""
45
Returns a free monoid on `n` generators.
46
47
INPUT:
48
49
50
- ``n`` - integer
51
52
- ``names`` - names of generators
53
54
55
OUTPUT: free abelian monoid
56
57
EXAMPLES::
58
59
sage: FreeMonoid(0,'')
60
Free monoid on 0 generators ()
61
sage: F.<a,b,c,d,e> = FreeMonoid(5); F
62
Free monoid on 5 generators (a, b, c, d, e)
63
sage: F(1)
64
1
65
sage: mul([ a, b, a, c, b, d, c, d ], F(1))
66
a*b*a*c*b*d*c*d
67
"""
68
def create_key(self, n, names):
69
n = int(n)
70
names = normalize_names(n, names)
71
return (n, names)
72
73
def create_object(self, version, key):
74
return FreeMonoid_class(*key)
75
76
FreeMonoid = FreeMonoidFactory("FreeMonoid")
77
78
79
def is_FreeMonoid(x):
80
"""
81
Return True if `x` is a free monoid.
82
83
EXAMPLES::
84
85
sage: from sage.monoids.free_monoid import is_FreeMonoid
86
sage: is_FreeMonoid(5)
87
False
88
sage: is_FreeMonoid(FreeMonoid(7,'a'))
89
True
90
sage: is_FreeMonoid(FreeAbelianMonoid(7,'a'))
91
False
92
sage: is_FreeMonoid(FreeAbelianMonoid(0,''))
93
False
94
"""
95
return isinstance(x, FreeMonoid_class)
96
97
class FreeMonoid_class(Monoid_class):
98
"""
99
The free monoid on `n` generators.
100
"""
101
Element = FreeMonoidElement
102
def __init__(self, n, names=None):
103
"""
104
Create free monoid on `n` generators.
105
106
INPUT:
107
108
- ``n`` - integer
109
110
- ``names`` - (optional) variable name or list of
111
variable names
112
113
114
EXAMPLES::
115
116
sage: F = FreeMonoid(3,'x'); F
117
Free monoid on 3 generators (x0, x1, x2)
118
sage: x = F.gens()
119
sage: x[0]*x[1]**5 * (x[0]*x[2])
120
x0*x1^5*x0*x2
121
sage: F = FreeMonoid(3, 'a')
122
sage: F
123
Free monoid on 3 generators (a0, a1, a2)
124
125
::
126
127
sage: M = FreeMonoid(3, names=['a','b','c'])
128
sage: TestSuite(M).run()
129
"""
130
if not isinstance(n, (int, long, Integer)):
131
raise TypeError, "n (=%s) must be an integer."%n
132
if n < 0:
133
raise ValueError, "n (=%s) must be nonnegative."%n
134
self.__ngens = int(n)
135
#self._assign_names(names)
136
Monoid_class.__init__(self,names)
137
138
def __cmp__(self, other):
139
if not isinstance(other, FreeMonoid_class):
140
return -1
141
c = cmp(self.__ngens, other.__ngens)
142
if c: return c
143
if self.variable_names() == other.variable_names():
144
return 0
145
return 1
146
147
def _repr_(self):
148
return "Free monoid on %s generators %s"%(self.__ngens,self.gens())
149
150
def _element_constructor_(self, x, check=True):
151
"""
152
Return `x` coerced into this free monoid.
153
154
One can create a free monoid from the integer 1 and from a list of
155
2-tuples of integers `(i,j)`, where `(i,j)`
156
corresponds to `x_i^j`, where `x_i` is the
157
`i`th generator.
158
159
EXAMPLES::
160
161
sage: F = FreeMonoid(3, 'a')
162
sage: F(1)
163
1
164
sage: F(F.gen(0))
165
a0
166
sage: F(0)
167
Traceback (most recent call last):
168
...
169
TypeError: Argument x (= 0) is of the wrong type.
170
171
::
172
173
sage: F([(0,5),(1,2),(0,10),(0,2),(1,2)])
174
a0^5*a1^2*a0^12*a1^2
175
"""
176
## There should really some careful type checking here...
177
if isinstance(x, FreeMonoidElement) and x.parent() is self:
178
return x
179
if isinstance(x, FreeMonoidElement) and x.parent() == self:
180
return self.element_class(self,x._element_list,check)
181
elif isinstance(x, (int, long, Integer)) and x == 1:
182
return self.element_class(self, x, check)
183
elif isinstance(x, list):
184
return self.element_class(self, x, check)
185
else:
186
raise TypeError, "Argument x (= %s) is of the wrong type."%x
187
188
def __contains__(self, x):
189
return isinstance(x, FreeMonoidElement) and x.parent() == self
190
191
def gen(self,i=0):
192
"""
193
The `i`-th generator of the monoid.
194
195
INPUT:
196
197
- ``i`` - integer (default: 0)
198
199
EXAMPLES::
200
201
sage: F = FreeMonoid(3, 'a')
202
sage: F.gen(1)
203
a1
204
sage: F.gen(2)
205
a2
206
sage: F.gen(5)
207
Traceback (most recent call last):
208
...
209
IndexError: Argument i (= 5) must be between 0 and 2.
210
"""
211
n = self.__ngens
212
if i < 0 or not i < n:
213
raise IndexError, "Argument i (= %s) must be between 0 and %s."%(i, n-1)
214
return self.element_class(self,[(Integer(i),Integer(1))])
215
216
def ngens(self):
217
"""
218
The number of free generators of the monoid.
219
220
EXAMPLES::
221
222
sage: F = FreeMonoid(2005, 'a')
223
sage: F.ngens()
224
2005
225
"""
226
return self.__ngens
227
228
@cached_method
229
def one_element(self):
230
"""
231
Returns the identity element in this monoid.
232
233
EXAMPLES::
234
235
sage: F = FreeMonoid(2005, 'a')
236
sage: F.one_element()
237
1
238
"""
239
return self(1)
240
241