Path: blob/master/sage/categories/examples/semigroups.py
4057 views
r"""1Examples of semigroups2"""3#*****************************************************************************4# Copyright (C) 2008-2009 Nicolas M. Thiery <nthiery at users.sf.net>5#6# Distributed under the terms of the GNU General Public License (GPL)7# http://www.gnu.org/licenses/8#*****************************************************************************910from sage.misc.cachefunc import cached_method11from sage.structure.parent import Parent12from sage.structure.unique_representation import UniqueRepresentation13from sage.structure.element_wrapper import ElementWrapper14from sage.categories.all import Semigroups15from sage.sets.family import Family1617class LeftZeroSemigroup(UniqueRepresentation, Parent):18r"""19An example of a semigroup.2021This class illustrates a minimal implementation of a semigroup.2223EXAMPLES::2425sage: S = Semigroups().example(); S26An example of a semigroup: the left zero semigroup2728This is the semigroup that contains all sorts of objects::2930sage: S.some_elements()31[3, 42, 'a', 3.4, 'raton laveur']3233with product rule given by $a \times b = a$ for all $a, b$::3435sage: S('hello') * S('world')36'hello'37sage: S(3)*S(1)*S(2)38339sage: S(3)^123123213123214034142TESTS::4344sage: TestSuite(S).run(verbose = True)45running ._test_an_element() . . . pass46running ._test_associativity() . . . pass47running ._test_category() . . . pass48running ._test_elements() . . .49Running the test suite of self.an_element()50running ._test_category() . . . pass51running ._test_eq() . . . pass52running ._test_not_implemented_methods() . . . pass53running ._test_pickling() . . . pass54pass55running ._test_elements_eq() . . . pass56running ._test_eq() . . . pass57running ._test_not_implemented_methods() . . . pass58running ._test_pickling() . . . pass59running ._test_some_elements() . . . pass60"""61def __init__(self):62r"""63The left zero semigroup6465EXAMPLES::6667sage: S = Semigroups().example(); S68An example of a semigroup: the left zero semigroup6970TESTS::7172sage: TestSuite(S).run()7374"""75Parent.__init__(self, category = Semigroups())7677def _repr_(self):78r"""7980EXAMPLES::8182sage: Semigroups().example()._repr_()83'An example of a semigroup: the left zero semigroup'8485"""86return "An example of a semigroup: the left zero semigroup"8788def product(self, x, y):89r"""90Returns the product of ``x`` and ``y`` in the semigroup, as per91:meth:`Semigroups.ParentMethods.product`.9293EXAMPLES::9495sage: S = Semigroups().example()96sage: S('hello') * S('world')97'hello'98sage: S(3)*S(1)*S(2)993100101"""102assert x in self103assert y in self104return x105106def an_element(self):107r"""108Returns an element of the semigroup.109110EXAMPLES::111112sage: Semigroups().example().an_element()11342114115"""116return self(42)117118def some_elements(self):119r"""120Returns a list of some elements of the semigroup.121122EXAMPLES::123124sage: Semigroups().example().some_elements()125[3, 42, 'a', 3.4, 'raton laveur']126127"""128return [self(i) for i in [3, 42, "a", 3.4, "raton laveur"]]129130class Element(ElementWrapper):131def is_idempotent(self):132r"""133Trivial implementation of ``Semigroups.Element.is_idempotent``134since all elements of this semigroup are idempotent!135136EXAMPLES::137138sage: S = Semigroups().example()139sage: S.an_element().is_idempotent()140True141sage: S(17).is_idempotent()142True143144"""145return True146147148class FreeSemigroup(UniqueRepresentation, Parent):149r"""150An example of semigroup.151152The purpose of this class is to provide a minimal template for153implementing of a semigroup.154155EXAMPLES::156157sage: S = Semigroups().example("free"); S158An example of a semigroup: the free semigroup generated by ('a', 'b', 'c', 'd')159160This is the free semigroup generated by::161162sage: S.semigroup_generators()163Family ('a', 'b', 'c', 'd')164165and with product given by contatenation::166167sage: S('dab') * S('acb')168'dabacb'169170TESTS::171172sage: TestSuite(S).run(verbose = True)173running ._test_an_element() . . . pass174running ._test_associativity() . . . pass175running ._test_category() . . . pass176running ._test_elements() . . .177Running the test suite of self.an_element()178running ._test_category() . . . pass179running ._test_eq() . . . pass180running ._test_not_implemented_methods() . . . pass181running ._test_pickling() . . . pass182pass183running ._test_elements_eq() . . . pass184running ._test_eq() . . . pass185running ._test_not_implemented_methods() . . . pass186running ._test_pickling() . . . pass187running ._test_some_elements() . . . pass188"""189def __init__(self, alphabet=('a','b','c','d')):190r"""191The free semigroup.192193INPUT::194195- ``alphabet`` -- a tuple of strings: the generators of the semigroup196197EXAMPLES::198199sage: from sage.categories.examples.semigroups import FreeSemigroup200sage: F = FreeSemigroup(('a','b','c')); F201An example of a semigroup: the free semigroup generated by ('a', 'b', 'c')202203TESTS::204205sage: F == loads(dumps(F))206True207208"""209self.alphabet = alphabet210Parent.__init__(self, category = Semigroups())211212def _repr_(self):213r"""214EXAMPLES::215216sage: from sage.categories.examples.semigroups import FreeSemigroup217sage: FreeSemigroup(('a','b','c'))._repr_()218"An example of a semigroup: the free semigroup generated by ('a', 'b', 'c')"219220"""221return "An example of a semigroup: the free semigroup generated by %s"%(self.alphabet,)222223def product(self, x, y):224r"""225Returns the product of ``x`` and ``y`` in the semigroup, as per226:meth:`Semigroups.ParentMethods.product`.227228EXAMPLES::229230sage: F = Semigroups().example('free')231sage: F.an_element() * F('a')^5232'abcdaaaaa'233234"""235assert x in self236assert y in self237return self(x.value + y.value)238239@cached_method240def semigroup_generators(self):241r"""242Returns the generators of the semigroup.243244EXAMPLES::245246sage: F = Semigroups().example('free')247sage: F.semigroup_generators()248Family ('a', 'b', 'c', 'd')249250"""251return Family([self(i) for i in self.alphabet])252253def an_element(self):254r"""255Returns an element of the semigroup.256257EXAMPLES::258259sage: F = Semigroups().example('free')260sage: F.an_element()261'abcd'262263"""264return self(''.join(self.alphabet))265266def _element_constructor_(self, x):267r"""268Construct an element of this semigroup from the data ``x``.269270INPUT::271272- ``x`` -- a string273274EXAMPLES::275276sage: F = Semigroups().example('free'); F277An example of a semigroup: the free semigroup generated by ('a', 'b', 'c', 'd')278sage: F._element_constructor_('a')279'a'280sage: F._element_constructor_('bad')281'bad'282283TESTS::284285sage: F._element_constructor_('z')286Traceback (most recent call last):287...288assert a in self.alphabet289AssertionError290sage: bad = F._element_constructor_('bad'); bad291'bad'292sage: bad in F293True294295296TESTS::297298sage: S = Semigroups().Subquotients().example()299sage: type(S._element_constructor_(17))300<class 'sage.categories.examples.semigroups.QuotientOfLeftZeroSemigroup_with_category.element_class'>301302"""303for a in x:304assert a in self.alphabet305return self.element_class(x, parent = self)306307class Element(ElementWrapper):308r"""309The class for elements of the free semigroup.310"""311wrapped_class = str312313314class QuotientOfLeftZeroSemigroup(UniqueRepresentation, Parent):315r"""316Example of a quotient semigroup317318EXAMPLES::319320sage: S = Semigroups().Subquotients().example(); S321An example of a (sub)quotient semigroup: a quotient of the left zero semigroup322323This is the quotient of::324325sage: S.ambient()326An example of a semigroup: the left zero semigroup327328obtained by setting `x=42` for any `x\geq 42`::329330sage: S(100)33142332sage: S(100) == S(42)333True334335The product is inherited from the ambient semigroup::336337sage: S(1)*S(2) == S(1)338True339340TESTS::341342sage: TestSuite(S).run(verbose = True)343running ._test_an_element() . . . pass344running ._test_associativity() . . . pass345running ._test_category() . . . pass346running ._test_elements() . . .347Running the test suite of self.an_element()348running ._test_category() . . . pass349running ._test_eq() . . . pass350running ._test_not_implemented_methods() . . . pass351running ._test_pickling() . . . pass352pass353running ._test_elements_eq() . . . pass354running ._test_eq() . . . pass355running ._test_not_implemented_methods() . . . pass356running ._test_pickling() . . . pass357running ._test_some_elements() . . . pass358"""359def _element_constructor_(self, x):360r"""361Convert ``x`` into an element of this semigroup.362363EXAMPLES::364365sage: S = Semigroups().Subquotients().example()366sage: S._element_constructor_(17)36717368369TESTS::370371sage: S = Semigroups().Subquotients().example()372sage: type(S._element_constructor_(17))373<class 'sage.categories.examples.semigroups.QuotientOfLeftZeroSemigroup_with_category.element_class'>374375"""376return self.retract(self.ambient()(x))377378def __init__(self, category = None):379r"""380This quotient of the left zero semigroup of integers obtained by381setting `x=42` for any `x\geq 42`.382383EXAMPLES::384385sage: S = Semigroups().Subquotients().example(); S386An example of a (sub)quotient semigroup: a quotient of the left zero semigroup387sage: S.ambient()388An example of a semigroup: the left zero semigroup389sage: S(100)39042391sage: S(100) == S(42)392True393sage: S(1)*S(2) == S(1)394True395396TESTS::397398sage: TestSuite(S).run()399"""400if category is None:401category = Semigroups().Quotients()402Parent.__init__(self, category = category)403404def _repr_(self):405r"""406407EXAMPLES::408409sage: Semigroups().Subquotients().example()._repr_()410'An example of a (sub)quotient semigroup: a quotient of the left zero semigroup'411412"""413return "An example of a (sub)quotient semigroup: a quotient of the left zero semigroup"414415def ambient(self):416r"""417Returns the ambient semigroup.418419EXAMPLES::420421sage: S = Semigroups().Subquotients().example()422sage: S.ambient()423An example of a semigroup: the left zero semigroup424425"""426return Semigroups().example()427428def lift(self, x):429r"""430Lift the element ``x`` into the ambient semigroup.431432INPUT::433434- ``x`` -- an element of ``self``.435436OUTPUT::437438- an element of ``self.ambient()``.439440EXAMPLES::441442sage: S = Semigroups().Subquotients().example()443sage: x = S.an_element(); x44442445sage: S.lift(x)44642447sage: S.lift(x) in S.ambient()448True449sage: y = S.ambient()(100); y450100451sage: S.lift(S(y))45242453454"""455assert x in self456return x.value457458def the_answer(self):459r"""460Returns the Answer to Life, the Universe, and Everything as an461element of this semigroup.462463EXAMPLES::464465sage: S = Semigroups().Subquotients().example()466sage: S.the_answer()46742468469"""470return self.retract(self.ambient()(42))471472def an_element(self):473r"""474Returns an element of the semigroup.475476EXAMPLES::477478sage: S = Semigroups().Subquotients().example()479sage: S.an_element()48042481482"""483return self.the_answer()484485def some_elements(self):486r"""487Returns a list of some elements of the semigroup.488489EXAMPLES::490491sage: S = Semigroups().Subquotients().example()492sage: S.some_elements()493[1, 2, 3, 8, 42, 42]494495"""496return [self.retract(self.ambient()(i))497for i in [1, 2, 3, 8, 42, 100]]498499def retract(self, x):500r"""501Returns the retract ``x`` onto an element of this semigroup.502503INPUT::504505- ``x`` -- an element of the ambient semigroup (``self.ambient()``).506507OUTPUT::508509- an element of ``self``.510511EXAMPLES::512513sage: S = Semigroups().Subquotients().example()514sage: L = S.ambient()515sage: S.retract(L(17))51617517sage: S.retract(L(42))51842519sage: S.retract(L(171))52042521522TESTS::523524sage: S.retract(L(171)) in S525True526527"""528from sage.rings.integer_ring import ZZ529assert x in self.ambient() and x.value in ZZ530if x.value > 42:531return self.the_answer()532else:533return self.element_class(x, parent = self)534535class Element(ElementWrapper):536pass537538class IncompleteSubquotientSemigroup(UniqueRepresentation,Parent):539def __init__(self, category = None):540r"""541An incompletely implemented subquotient semigroup, for testing purposes542543EXAMPLES::544545sage: S = sage.categories.examples.semigroups.IncompleteSubquotientSemigroup()546sage: S547A subquotient of An example of a semigroup: the left zero semigroup548549TESTS::550551sage: S._test_not_implemented_methods()552Traceback (most recent call last):553...554AssertionError: Not implemented method: lift555556sage: TestSuite(S).run(verbose = True)557running ._test_an_element() . . . pass558running ._test_associativity() . . . fail559Traceback (most recent call last):560...561NotImplementedError: <abstract method retract at ...>562------------------------------------------------------------563running ._test_category() . . . pass564running ._test_elements() . . .565Running the test suite of self.an_element()566running ._test_category() . . . pass567running ._test_eq() . . . pass568running ._test_not_implemented_methods() . . . pass569running ._test_pickling() . . . pass570pass571running ._test_elements_eq() . . . pass572running ._test_eq() . . . pass573running ._test_not_implemented_methods() . . . fail574Traceback (most recent call last):575...576AssertionError: Not implemented method: lift577------------------------------------------------------------578running ._test_pickling() . . . pass579running ._test_some_elements() . . . pass580The following tests failed: _test_associativity, _test_not_implemented_methods581"""582Parent.__init__(self, category=Semigroups().Subquotients().or_subcategory(category))583584def ambient(self):585r"""586Returns the ambient semigroup.587588EXAMPLES::589590sage: S = Semigroups().Subquotients().example()591sage: S.ambient()592An example of a semigroup: the left zero semigroup593594"""595return Semigroups().example()596597class Element(ElementWrapper):598pass599600601