Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/categories/examples/semigroups.py
4057 views
1
r"""
2
Examples of semigroups
3
"""
4
#*****************************************************************************
5
# Copyright (C) 2008-2009 Nicolas M. Thiery <nthiery at users.sf.net>
6
#
7
# Distributed under the terms of the GNU General Public License (GPL)
8
# http://www.gnu.org/licenses/
9
#*****************************************************************************
10
11
from sage.misc.cachefunc import cached_method
12
from sage.structure.parent import Parent
13
from sage.structure.unique_representation import UniqueRepresentation
14
from sage.structure.element_wrapper import ElementWrapper
15
from sage.categories.all import Semigroups
16
from sage.sets.family import Family
17
18
class LeftZeroSemigroup(UniqueRepresentation, Parent):
19
r"""
20
An example of a semigroup.
21
22
This class illustrates a minimal implementation of a semigroup.
23
24
EXAMPLES::
25
26
sage: S = Semigroups().example(); S
27
An example of a semigroup: the left zero semigroup
28
29
This is the semigroup that contains all sorts of objects::
30
31
sage: S.some_elements()
32
[3, 42, 'a', 3.4, 'raton laveur']
33
34
with product rule given by $a \times b = a$ for all $a, b$::
35
36
sage: S('hello') * S('world')
37
'hello'
38
sage: S(3)*S(1)*S(2)
39
3
40
sage: S(3)^12312321312321
41
3
42
43
TESTS::
44
45
sage: TestSuite(S).run(verbose = True)
46
running ._test_an_element() . . . pass
47
running ._test_associativity() . . . pass
48
running ._test_category() . . . pass
49
running ._test_elements() . . .
50
Running the test suite of self.an_element()
51
running ._test_category() . . . pass
52
running ._test_eq() . . . pass
53
running ._test_not_implemented_methods() . . . pass
54
running ._test_pickling() . . . pass
55
pass
56
running ._test_elements_eq() . . . pass
57
running ._test_eq() . . . pass
58
running ._test_not_implemented_methods() . . . pass
59
running ._test_pickling() . . . pass
60
running ._test_some_elements() . . . pass
61
"""
62
def __init__(self):
63
r"""
64
The left zero semigroup
65
66
EXAMPLES::
67
68
sage: S = Semigroups().example(); S
69
An example of a semigroup: the left zero semigroup
70
71
TESTS::
72
73
sage: TestSuite(S).run()
74
75
"""
76
Parent.__init__(self, category = Semigroups())
77
78
def _repr_(self):
79
r"""
80
81
EXAMPLES::
82
83
sage: Semigroups().example()._repr_()
84
'An example of a semigroup: the left zero semigroup'
85
86
"""
87
return "An example of a semigroup: the left zero semigroup"
88
89
def product(self, x, y):
90
r"""
91
Returns the product of ``x`` and ``y`` in the semigroup, as per
92
:meth:`Semigroups.ParentMethods.product`.
93
94
EXAMPLES::
95
96
sage: S = Semigroups().example()
97
sage: S('hello') * S('world')
98
'hello'
99
sage: S(3)*S(1)*S(2)
100
3
101
102
"""
103
assert x in self
104
assert y in self
105
return x
106
107
def an_element(self):
108
r"""
109
Returns an element of the semigroup.
110
111
EXAMPLES::
112
113
sage: Semigroups().example().an_element()
114
42
115
116
"""
117
return self(42)
118
119
def some_elements(self):
120
r"""
121
Returns a list of some elements of the semigroup.
122
123
EXAMPLES::
124
125
sage: Semigroups().example().some_elements()
126
[3, 42, 'a', 3.4, 'raton laveur']
127
128
"""
129
return [self(i) for i in [3, 42, "a", 3.4, "raton laveur"]]
130
131
class Element(ElementWrapper):
132
def is_idempotent(self):
133
r"""
134
Trivial implementation of ``Semigroups.Element.is_idempotent``
135
since all elements of this semigroup are idempotent!
136
137
EXAMPLES::
138
139
sage: S = Semigroups().example()
140
sage: S.an_element().is_idempotent()
141
True
142
sage: S(17).is_idempotent()
143
True
144
145
"""
146
return True
147
148
149
class FreeSemigroup(UniqueRepresentation, Parent):
150
r"""
151
An example of semigroup.
152
153
The purpose of this class is to provide a minimal template for
154
implementing of a semigroup.
155
156
EXAMPLES::
157
158
sage: S = Semigroups().example("free"); S
159
An example of a semigroup: the free semigroup generated by ('a', 'b', 'c', 'd')
160
161
This is the free semigroup generated by::
162
163
sage: S.semigroup_generators()
164
Family ('a', 'b', 'c', 'd')
165
166
and with product given by contatenation::
167
168
sage: S('dab') * S('acb')
169
'dabacb'
170
171
TESTS::
172
173
sage: TestSuite(S).run(verbose = True)
174
running ._test_an_element() . . . pass
175
running ._test_associativity() . . . pass
176
running ._test_category() . . . pass
177
running ._test_elements() . . .
178
Running the test suite of self.an_element()
179
running ._test_category() . . . pass
180
running ._test_eq() . . . pass
181
running ._test_not_implemented_methods() . . . pass
182
running ._test_pickling() . . . pass
183
pass
184
running ._test_elements_eq() . . . pass
185
running ._test_eq() . . . pass
186
running ._test_not_implemented_methods() . . . pass
187
running ._test_pickling() . . . pass
188
running ._test_some_elements() . . . pass
189
"""
190
def __init__(self, alphabet=('a','b','c','d')):
191
r"""
192
The free semigroup.
193
194
INPUT::
195
196
- ``alphabet`` -- a tuple of strings: the generators of the semigroup
197
198
EXAMPLES::
199
200
sage: from sage.categories.examples.semigroups import FreeSemigroup
201
sage: F = FreeSemigroup(('a','b','c')); F
202
An example of a semigroup: the free semigroup generated by ('a', 'b', 'c')
203
204
TESTS::
205
206
sage: F == loads(dumps(F))
207
True
208
209
"""
210
self.alphabet = alphabet
211
Parent.__init__(self, category = Semigroups())
212
213
def _repr_(self):
214
r"""
215
EXAMPLES::
216
217
sage: from sage.categories.examples.semigroups import FreeSemigroup
218
sage: FreeSemigroup(('a','b','c'))._repr_()
219
"An example of a semigroup: the free semigroup generated by ('a', 'b', 'c')"
220
221
"""
222
return "An example of a semigroup: the free semigroup generated by %s"%(self.alphabet,)
223
224
def product(self, x, y):
225
r"""
226
Returns the product of ``x`` and ``y`` in the semigroup, as per
227
:meth:`Semigroups.ParentMethods.product`.
228
229
EXAMPLES::
230
231
sage: F = Semigroups().example('free')
232
sage: F.an_element() * F('a')^5
233
'abcdaaaaa'
234
235
"""
236
assert x in self
237
assert y in self
238
return self(x.value + y.value)
239
240
@cached_method
241
def semigroup_generators(self):
242
r"""
243
Returns the generators of the semigroup.
244
245
EXAMPLES::
246
247
sage: F = Semigroups().example('free')
248
sage: F.semigroup_generators()
249
Family ('a', 'b', 'c', 'd')
250
251
"""
252
return Family([self(i) for i in self.alphabet])
253
254
def an_element(self):
255
r"""
256
Returns an element of the semigroup.
257
258
EXAMPLES::
259
260
sage: F = Semigroups().example('free')
261
sage: F.an_element()
262
'abcd'
263
264
"""
265
return self(''.join(self.alphabet))
266
267
def _element_constructor_(self, x):
268
r"""
269
Construct an element of this semigroup from the data ``x``.
270
271
INPUT::
272
273
- ``x`` -- a string
274
275
EXAMPLES::
276
277
sage: F = Semigroups().example('free'); F
278
An example of a semigroup: the free semigroup generated by ('a', 'b', 'c', 'd')
279
sage: F._element_constructor_('a')
280
'a'
281
sage: F._element_constructor_('bad')
282
'bad'
283
284
TESTS::
285
286
sage: F._element_constructor_('z')
287
Traceback (most recent call last):
288
...
289
assert a in self.alphabet
290
AssertionError
291
sage: bad = F._element_constructor_('bad'); bad
292
'bad'
293
sage: bad in F
294
True
295
296
297
TESTS::
298
299
sage: S = Semigroups().Subquotients().example()
300
sage: type(S._element_constructor_(17))
301
<class 'sage.categories.examples.semigroups.QuotientOfLeftZeroSemigroup_with_category.element_class'>
302
303
"""
304
for a in x:
305
assert a in self.alphabet
306
return self.element_class(x, parent = self)
307
308
class Element(ElementWrapper):
309
r"""
310
The class for elements of the free semigroup.
311
"""
312
wrapped_class = str
313
314
315
class QuotientOfLeftZeroSemigroup(UniqueRepresentation, Parent):
316
r"""
317
Example of a quotient semigroup
318
319
EXAMPLES::
320
321
sage: S = Semigroups().Subquotients().example(); S
322
An example of a (sub)quotient semigroup: a quotient of the left zero semigroup
323
324
This is the quotient of::
325
326
sage: S.ambient()
327
An example of a semigroup: the left zero semigroup
328
329
obtained by setting `x=42` for any `x\geq 42`::
330
331
sage: S(100)
332
42
333
sage: S(100) == S(42)
334
True
335
336
The product is inherited from the ambient semigroup::
337
338
sage: S(1)*S(2) == S(1)
339
True
340
341
TESTS::
342
343
sage: TestSuite(S).run(verbose = True)
344
running ._test_an_element() . . . pass
345
running ._test_associativity() . . . pass
346
running ._test_category() . . . pass
347
running ._test_elements() . . .
348
Running the test suite of self.an_element()
349
running ._test_category() . . . pass
350
running ._test_eq() . . . pass
351
running ._test_not_implemented_methods() . . . pass
352
running ._test_pickling() . . . pass
353
pass
354
running ._test_elements_eq() . . . pass
355
running ._test_eq() . . . pass
356
running ._test_not_implemented_methods() . . . pass
357
running ._test_pickling() . . . pass
358
running ._test_some_elements() . . . pass
359
"""
360
def _element_constructor_(self, x):
361
r"""
362
Convert ``x`` into an element of this semigroup.
363
364
EXAMPLES::
365
366
sage: S = Semigroups().Subquotients().example()
367
sage: S._element_constructor_(17)
368
17
369
370
TESTS::
371
372
sage: S = Semigroups().Subquotients().example()
373
sage: type(S._element_constructor_(17))
374
<class 'sage.categories.examples.semigroups.QuotientOfLeftZeroSemigroup_with_category.element_class'>
375
376
"""
377
return self.retract(self.ambient()(x))
378
379
def __init__(self, category = None):
380
r"""
381
This quotient of the left zero semigroup of integers obtained by
382
setting `x=42` for any `x\geq 42`.
383
384
EXAMPLES::
385
386
sage: S = Semigroups().Subquotients().example(); S
387
An example of a (sub)quotient semigroup: a quotient of the left zero semigroup
388
sage: S.ambient()
389
An example of a semigroup: the left zero semigroup
390
sage: S(100)
391
42
392
sage: S(100) == S(42)
393
True
394
sage: S(1)*S(2) == S(1)
395
True
396
397
TESTS::
398
399
sage: TestSuite(S).run()
400
"""
401
if category is None:
402
category = Semigroups().Quotients()
403
Parent.__init__(self, category = category)
404
405
def _repr_(self):
406
r"""
407
408
EXAMPLES::
409
410
sage: Semigroups().Subquotients().example()._repr_()
411
'An example of a (sub)quotient semigroup: a quotient of the left zero semigroup'
412
413
"""
414
return "An example of a (sub)quotient semigroup: a quotient of the left zero semigroup"
415
416
def ambient(self):
417
r"""
418
Returns the ambient semigroup.
419
420
EXAMPLES::
421
422
sage: S = Semigroups().Subquotients().example()
423
sage: S.ambient()
424
An example of a semigroup: the left zero semigroup
425
426
"""
427
return Semigroups().example()
428
429
def lift(self, x):
430
r"""
431
Lift the element ``x`` into the ambient semigroup.
432
433
INPUT::
434
435
- ``x`` -- an element of ``self``.
436
437
OUTPUT::
438
439
- an element of ``self.ambient()``.
440
441
EXAMPLES::
442
443
sage: S = Semigroups().Subquotients().example()
444
sage: x = S.an_element(); x
445
42
446
sage: S.lift(x)
447
42
448
sage: S.lift(x) in S.ambient()
449
True
450
sage: y = S.ambient()(100); y
451
100
452
sage: S.lift(S(y))
453
42
454
455
"""
456
assert x in self
457
return x.value
458
459
def the_answer(self):
460
r"""
461
Returns the Answer to Life, the Universe, and Everything as an
462
element of this semigroup.
463
464
EXAMPLES::
465
466
sage: S = Semigroups().Subquotients().example()
467
sage: S.the_answer()
468
42
469
470
"""
471
return self.retract(self.ambient()(42))
472
473
def an_element(self):
474
r"""
475
Returns an element of the semigroup.
476
477
EXAMPLES::
478
479
sage: S = Semigroups().Subquotients().example()
480
sage: S.an_element()
481
42
482
483
"""
484
return self.the_answer()
485
486
def some_elements(self):
487
r"""
488
Returns a list of some elements of the semigroup.
489
490
EXAMPLES::
491
492
sage: S = Semigroups().Subquotients().example()
493
sage: S.some_elements()
494
[1, 2, 3, 8, 42, 42]
495
496
"""
497
return [self.retract(self.ambient()(i))
498
for i in [1, 2, 3, 8, 42, 100]]
499
500
def retract(self, x):
501
r"""
502
Returns the retract ``x`` onto an element of this semigroup.
503
504
INPUT::
505
506
- ``x`` -- an element of the ambient semigroup (``self.ambient()``).
507
508
OUTPUT::
509
510
- an element of ``self``.
511
512
EXAMPLES::
513
514
sage: S = Semigroups().Subquotients().example()
515
sage: L = S.ambient()
516
sage: S.retract(L(17))
517
17
518
sage: S.retract(L(42))
519
42
520
sage: S.retract(L(171))
521
42
522
523
TESTS::
524
525
sage: S.retract(L(171)) in S
526
True
527
528
"""
529
from sage.rings.integer_ring import ZZ
530
assert x in self.ambient() and x.value in ZZ
531
if x.value > 42:
532
return self.the_answer()
533
else:
534
return self.element_class(x, parent = self)
535
536
class Element(ElementWrapper):
537
pass
538
539
class IncompleteSubquotientSemigroup(UniqueRepresentation,Parent):
540
def __init__(self, category = None):
541
r"""
542
An incompletely implemented subquotient semigroup, for testing purposes
543
544
EXAMPLES::
545
546
sage: S = sage.categories.examples.semigroups.IncompleteSubquotientSemigroup()
547
sage: S
548
A subquotient of An example of a semigroup: the left zero semigroup
549
550
TESTS::
551
552
sage: S._test_not_implemented_methods()
553
Traceback (most recent call last):
554
...
555
AssertionError: Not implemented method: lift
556
557
sage: TestSuite(S).run(verbose = True)
558
running ._test_an_element() . . . pass
559
running ._test_associativity() . . . fail
560
Traceback (most recent call last):
561
...
562
NotImplementedError: <abstract method retract at ...>
563
------------------------------------------------------------
564
running ._test_category() . . . pass
565
running ._test_elements() . . .
566
Running the test suite of self.an_element()
567
running ._test_category() . . . pass
568
running ._test_eq() . . . pass
569
running ._test_not_implemented_methods() . . . pass
570
running ._test_pickling() . . . pass
571
pass
572
running ._test_elements_eq() . . . pass
573
running ._test_eq() . . . pass
574
running ._test_not_implemented_methods() . . . fail
575
Traceback (most recent call last):
576
...
577
AssertionError: Not implemented method: lift
578
------------------------------------------------------------
579
running ._test_pickling() . . . pass
580
running ._test_some_elements() . . . pass
581
The following tests failed: _test_associativity, _test_not_implemented_methods
582
"""
583
Parent.__init__(self, category=Semigroups().Subquotients().or_subcategory(category))
584
585
def ambient(self):
586
r"""
587
Returns the ambient semigroup.
588
589
EXAMPLES::
590
591
sage: S = Semigroups().Subquotients().example()
592
sage: S.ambient()
593
An example of a semigroup: the left zero semigroup
594
595
"""
596
return Semigroups().example()
597
598
class Element(ElementWrapper):
599
pass
600
601