Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/monoids/free_abelian_monoid.py
4102 views
1
r"""
2
Free abelian monoids
3
4
AUTHORS:
5
6
- David Kohel (2005-09)
7
8
Sage supports free abelian monoids on any prescribed finite number
9
`n\geq 0` of generators. Use the
10
``FreeAbelianMonoid`` function to create a free abelian
11
monoid, and the ``gen`` and ``gens``
12
functions to obtain the corresponding generators. You can print the
13
generators as arbitrary strings using the optional
14
``names`` argument to the
15
``FreeAbelianMonoid`` function.
16
17
EXAMPLE 1: It is possible to create an abelian monoid in zero or
18
more variables; the syntax T(1) creates the monoid identity
19
element even in the rank zero case.
20
21
::
22
23
sage: T = FreeAbelianMonoid(0, '')
24
sage: T
25
Free abelian monoid on 0 generators ()
26
sage: T.gens()
27
()
28
sage: T(1)
29
1
30
31
EXAMPLE 2: A free abelian monoid uses a multiplicative
32
representation of elements, but the underlying representation is
33
lists of integer exponents.
34
35
::
36
37
sage: F = FreeAbelianMonoid(5,names='a,b,c,d,e')
38
sage: (a,b,c,d,e) = F.gens()
39
sage: a*b^2*e*d
40
a*b^2*d*e
41
sage: x = b^2*e*d*a^7
42
sage: x
43
a^7*b^2*d*e
44
sage: x.list()
45
[7, 2, 0, 1, 1]
46
"""
47
48
#*****************************************************************************
49
# Copyright (C) 2005 David Kohel <[email protected]>
50
#
51
# Distributed under the terms of the GNU General Public License (GPL):
52
#
53
# http://www.gnu.org/licenses/
54
#*****************************************************************************
55
56
57
from sage.structure.parent_gens import ParentWithGens, normalize_names
58
from free_abelian_monoid_element import FreeAbelianMonoidElement
59
from sage.rings.integer import Integer
60
61
from sage.structure.factory import UniqueFactory
62
63
class FreeAbelianMonoidFactory(UniqueFactory):
64
"""
65
Create the free abelian monoid in `n` generators.
66
67
INPUT:
68
69
70
- ``n`` - integer
71
72
- ``names`` - names of generators
73
74
75
OUTPUT: free abelian monoid
76
77
EXAMPLES::
78
79
sage: FreeAbelianMonoid(0, '')
80
Free abelian monoid on 0 generators ()
81
sage: F = FreeAbelianMonoid(5,names = list("abcde"))
82
sage: F
83
Free abelian monoid on 5 generators (a, b, c, d, e)
84
sage: F(1)
85
1
86
sage: (a, b, c, d, e) = F.gens()
87
sage: mul([ a, b, a, c, b, d, c, d ], F(1))
88
a^2*b^2*c^2*d^2
89
sage: a**2 * b**3 * a**2 * b**4
90
a^4*b^7
91
92
::
93
94
sage: loads(dumps(F)) is F
95
True
96
"""
97
def create_key(self, n, names):
98
n = int(n)
99
names = normalize_names(n, names)
100
return (n, names)
101
def create_object(self, version, key):
102
return FreeAbelianMonoid_class(*key)
103
104
FreeAbelianMonoid = FreeAbelianMonoidFactory("FreeAbelianMonoid")
105
106
107
def is_FreeAbelianMonoid(x):
108
"""
109
Return True if `x` is a free abelian monoid.
110
111
EXAMPLES::
112
113
sage: from sage.monoids.free_abelian_monoid import is_FreeAbelianMonoid
114
sage: is_FreeAbelianMonoid(5)
115
False
116
sage: is_FreeAbelianMonoid(FreeAbelianMonoid(7,'a'))
117
True
118
sage: is_FreeAbelianMonoid(FreeMonoid(7,'a'))
119
False
120
sage: is_FreeAbelianMonoid(FreeMonoid(0,''))
121
False
122
"""
123
return isinstance(x, FreeAbelianMonoid_class)
124
125
class FreeAbelianMonoid_class(ParentWithGens):
126
"""
127
Free abelian monoid on `n` generators.
128
"""
129
def __init__(self, n, names):
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
assert not names is None
136
self._assign_names(names)
137
138
def __repr__(self):
139
n = self.__ngens
140
return "Free abelian monoid on %s generators %s"%(n,self.gens())
141
142
def __call__(self, x):
143
"""
144
Create an element of this abelian monoid from `x`.
145
146
EXAMPLES::
147
148
sage: F = FreeAbelianMonoid(10,'x')
149
sage: F(F.gen(2))
150
x2
151
sage: F(1)
152
1
153
"""
154
if isinstance(x, FreeAbelianMonoidElement) and x.parent() == self:
155
return x
156
return FreeAbelianMonoidElement(self, x)
157
158
159
def __contains__(self, x):
160
"""
161
Return True if `x` is an element of this abelian monoid.
162
163
EXAMPLES::
164
165
sage: F = FreeAbelianMonoid(10,'b')
166
sage: F.gen(2)*F.gen(3) in F
167
True
168
169
Note that a monoid on `9` generators is not considered a
170
submonoid of one on `10` generators.
171
172
::
173
174
sage: FreeAbelianMonoid(9,'c').gen(2) in F
175
False
176
177
However, multiple calls to the monoid constructor do *not* return
178
multiple distinct monoids.
179
180
::
181
182
sage: FreeAbelianMonoid(10,'b').gen(2) in F
183
True
184
"""
185
return isinstance(x, FreeAbelianMonoidElement) and x.parent() == self
186
187
def gen(self, i=0):
188
"""
189
The `i`-th generator of the abelian monoid.
190
191
EXAMPLES::
192
193
sage: F = FreeAbelianMonoid(5,'a')
194
sage: F.gen(0)
195
a0
196
sage: F.gen(2)
197
a2
198
"""
199
n = self.__ngens
200
if i < 0 or not i < n:
201
raise IndexError, "Argument i (= %s) must be between 0 and %s."%(i, n-1)
202
x = [ 0 for j in range(n) ]
203
x[int(i)] = 1
204
return FreeAbelianMonoidElement(self,x)
205
206
def ngens(self):
207
"""
208
The number of free generators of the abelian monoid.
209
210
EXAMPLES::
211
212
sage: F = FreeAbelianMonoid(3000, 'a')
213
sage: F.ngens()
214
3000
215
"""
216
return self.__ngens
217
218
219