Ask Your Question

Revision history [back]

Hello,

Yes but not as direct as you may want. And the most important is: it really depends on what you want to do with these monoids.

If you put the following in a file like "finite_monoid.py"

from sage.structure.parent import Parent
from sage.categories.semigroups import Semigroups
from sage.structure.element_wrapper import ElementWrapper

class FiniteMonoidFromMultiplicationTable(Parent):
    def __init__(self, table):
        self._table = table
        Parent.__init__(self, category=Semigroups().Finite())

    def product(self, x, y):
        return self(self._table[x.value][y.value])

    def _repr_(self):
        return "Finite monoid on {} elements given by its multiplication table".format(len(self._table))

    def _element_constructor_(self, data):
        data = int(data)
        assert 0 <= data < len(self._table):
        return self.element_class(self, data)

    def __reduce__(self):
        return (FiniteMonoidFromMultiplicationTable,
                 (self._table,))

    def __eq__(self, other):
        return type(self) is type(other) and \
               self._table == other._table

    def __ne__(self, other):
        return not self == other

    class Element(ElementWrapper):
        wrapped_class = Integer

        def __reduce__(self):
            return self.parent(), (self.value,)

In the above code the most important are:

  • the constructor __init__ and the choice of the category Semigroups().Finite()

  • the method product that defines the product of elements from the multiplication table

  • the subclass Element and the method _element_constructor_ that tells how to construct elements

Then you can do from the console

sage: from finite_monoid import FiniteMonoidFromMultiplicationTable
sage: F = FiniteMonoidFromMultiplicationTable([[0, 0, 0], [0, 1, 1], [0, 1, 2]])
sage: e0 = F(0); e1 = F(1); e2 = F(2)
sage: print (e0, e1, e2)
sage: e0 * e1 * e2 * e1
0
sage: e1 * e2 * e2
1
sage: TestSuite(F).run()   # check thaat everything is fine

If you want to know more, you should have a look at the thematic tutorial http://doc.sagemath.org/html/en/thematic_tutorials/coercion_and_categories.html#coercion-and-categories.

Hello,

Yes but not as direct as you may want. And the most important is: it really depends on what you want to do with these monoids.

If you put the following in a file like "finite_monoid.py"

from sage.structure.parent import Parent
from sage.categories.semigroups import Semigroups
from sage.structure.element_wrapper import ElementWrapper

class FiniteMonoidFromMultiplicationTable(Parent):
    def __init__(self, table):
        self._table = table
        Parent.__init__(self, category=Semigroups().Finite())

    def product(self, x, y):
        return self(self._table[x.value][y.value])

    def _repr_(self):
        return "Finite monoid on {} elements given by its multiplication table".format(len(self._table))

    def _element_constructor_(self, data):
        data = int(data)
        assert 0 <= data < len(self._table):
        return self.element_class(self, data)

    def __reduce__(self):
        return (FiniteMonoidFromMultiplicationTable,
                 (self._table,))

    def __eq__(self, other):
        return type(self) is type(other) and \
               self._table == other._table

    def __ne__(self, other):
        return not self == other

    class Element(ElementWrapper):
        wrapped_class = Integer

        def __reduce__(self):
            return self.parent(), (self.value,)

In the above code the most important are:

  • the constructor __init__ and the choice of the category Semigroups().Finite()

  • the method product that defines the product of elements from the multiplication table

  • the subclass Element and the method _element_constructor_ that tells how to construct elements

Then you can do from the console

sage: from finite_monoid import FiniteMonoidFromMultiplicationTable
sage: F = FiniteMonoidFromMultiplicationTable([[0, 0, 0], [0, 1, 1], [0, 1, 2]])
sage: e0 = F(0); e1 = F(1); e2 = F(2)
sage: print (e0, e1, e2)
sage: e0 * e1 * e2 * e1
0
sage: e1 * e2 * e2
1
sage: TestSuite(F).run()   # check thaat everything is fine

If you want to know more, you should have a look at the thematic tutorial http://doc.sagemath.org/html/en/thematic_tutorials/coercion_and_categories.html#coercion-and-categories.

EDIT:

Then you can do cartesian products and create morphisms as follows

sage: from sage.categories.morphism import SetMorphism
sage: from finite_monoid import FiniteMonoidFromMultiplicationTable
sage: F1 = FiniteMonoidFromMultiplicationTable([[0, 0, 0], [0, 1, 1], [0, 1, 2]])
sage: F2 = FiniteMonoidFromMultiplicationTable([[0, 1, 2], [1, 1, 2], [2, 2, 2]])
sage: F = cartesian_product([F1,F2])
sage: F((0,1)) * F((1,1))
(0, 1)
sage: TestSuite(F).run()

sage: from sage.categories.morphism import SetMorphism
sage: H = HomF1F2 = Hom(F1, F2, Semigroups())
sage: f = SetMorphism(H, lambda x: F2(2-x.value))
sage: e1_0 = F1(0)
sage: e1_1 = F1(1)
sage: e1_2 = F1(2)
sage: f(e1_1) * f(e1_2) == f(e1_1 * e1_2)
True

Hello,

Yes but not as direct as you may want. And the most important is: it really depends on what you want to do with these monoids.

If you put the following in a file like "finite_monoid.py"

from sage.structure.parent import Parent
from sage.categories.semigroups import Semigroups
from sage.structure.element_wrapper import ElementWrapper

class FiniteMonoidFromMultiplicationTable(Parent):
    def __init__(self, table):
        self._table = table
        Parent.__init__(self, category=Semigroups().Finite())

    def product(self, x, y):
        return self(self._table[x.value][y.value])

    def _repr_(self):
        return "Finite monoid on {} elements given by its multiplication table".format(len(self._table))

    def _element_constructor_(self, data):
        data = int(data)
        assert 0 <= data < len(self._table):
        return self.element_class(self, data)

    def __reduce__(self):
        return (FiniteMonoidFromMultiplicationTable,
                 (self._table,))

    def __eq__(self, other):
        return type(self) is type(other) and \
               self._table == other._table

    def __ne__(self, other):
        return not self == other

    class Element(ElementWrapper):
        wrapped_class = Integer

        def __reduce__(self):
            return self.parent(), (self.value,)

In the above code the most important are:

  • the constructor __init__ and the choice of the category Semigroups().Finite()

  • the method product that defines the product of elements from the multiplication table

  • the subclass Element and the method _element_constructor_ that tells how to construct elements

Then you can do from the console

sage: from finite_monoid import FiniteMonoidFromMultiplicationTable
sage: F = FiniteMonoidFromMultiplicationTable([[0, 0, 0], [0, 1, 1], [0, 1, 2]])
sage: e0 = F(0); e1 = F(1); e2 = F(2)
sage: print (e0, e1, e2)
sage: e0 * e1 * e2 * e1
0
sage: e1 * e2 * e2
1
sage: TestSuite(F).run()   # check thaat everything is fine

If you want to know more, you should have a look at the thematic tutorial http://doc.sagemath.org/html/en/thematic_tutorials/coercion_and_categories.html#coercion-and-categoriesHow to implement new algebraic structures in Sage?.

EDIT:

Then you can do cartesian products and create morphisms as follows

sage: from sage.categories.morphism import SetMorphism
sage: from finite_monoid import FiniteMonoidFromMultiplicationTable
sage: F1 = FiniteMonoidFromMultiplicationTable([[0, 0, 0], [0, 1, 1], [0, 1, 2]])
sage: F2 = FiniteMonoidFromMultiplicationTable([[0, 1, 2], [1, 1, 2], [2, 2, 2]])
sage: F = cartesian_product([F1,F2])
sage: F((0,1)) * F((1,1))
(0, 1)
sage: TestSuite(F).run()

sage: from sage.categories.morphism import SetMorphism
sage: H = HomF1F2 = Hom(F1, F2, Semigroups())
sage: f = SetMorphism(H, lambda x: F2(2-x.value))
sage: e1_0 = F1(0)
sage: e1_1 = F1(1)
sage: e1_2 = F1(2)
sage: f(e1_1) * f(e1_2) == f(e1_1 * e1_2)
True

Hello,

Yes but not as direct as you may want. And the most important is: it really depends on what you want to do with these monoids.

If you put the following in a file like "finite_monoid.py"

from sage.structure.parent import Parent
from sage.categories.semigroups import Semigroups
from sage.structure.element_wrapper import ElementWrapper

class FiniteMonoidFromMultiplicationTable(Parent):
    def __init__(self, table):
        self._table = table
        Parent.__init__(self, category=Semigroups().Finite())

    def product(self, x, y):
        return self(self._table[x.value][y.value])

    def _repr_(self):
        return "Finite monoid on {} elements given by its multiplication table".format(len(self._table))

    def _element_constructor_(self, data):
        data = int(data)
        assert 0 <= data < len(self._table):
len(self._table)
        return self.element_class(self, data)

    def __reduce__(self):
        return (FiniteMonoidFromMultiplicationTable,
                 (self._table,))

    def __eq__(self, other):
        return type(self) is type(other) and \
               self._table == other._table

    def __ne__(self, other):
        return not self == other

    class Element(ElementWrapper):
        wrapped_class = Integer

        def __reduce__(self):
            return self.parent(), (self.value,)

In the above code the most important are:

  • the constructor __init__ and the choice of the category Semigroups().Finite()

  • the method product that defines the product of elements from the multiplication table

  • the subclass Element and the method _element_constructor_ that tells how to construct elements

Then you can do from the console

sage: from finite_monoid import FiniteMonoidFromMultiplicationTable
sage: F = FiniteMonoidFromMultiplicationTable([[0, 0, 0], [0, 1, 1], [0, 1, 2]])
sage: e0 = F(0); e1 = F(1); e2 = F(2)
sage: print (e0, e1, e2)
sage: e0 * e1 * e2 * e1
0
sage: e1 * e2 * e2
1
sage: TestSuite(F).run()   # check thaat everything is fine

If you want to know more, you should have a look at the thematic tutorial How to implement new algebraic structures in Sage?.

EDIT:

Then you can do cartesian products and create morphisms as follows

sage: from sage.categories.morphism import SetMorphism
sage: from finite_monoid import FiniteMonoidFromMultiplicationTable
sage: F1 = FiniteMonoidFromMultiplicationTable([[0, 0, 0], [0, 1, 1], [0, 1, 2]])
sage: F2 = FiniteMonoidFromMultiplicationTable([[0, 1, 2], [1, 1, 2], [2, 2, 2]])
sage: F = cartesian_product([F1,F2])
sage: F((0,1)) * F((1,1))
(0, 1)
sage: TestSuite(F).run()

sage: from sage.categories.morphism import SetMorphism
sage: H = HomF1F2 = Hom(F1, F2, Semigroups())
sage: f = SetMorphism(H, lambda x: F2(2-x.value))
sage: e1_0 = F1(0)
sage: e1_1 = F1(1)
sage: e1_2 = F1(2)
sage: f(e1_1) * f(e1_2) == f(e1_1 * e1_2)
True