Ejemplo n.º 1
0
    def extra_super_categories(self):
        """
        Implement the fact that a `J`-trivial semigroup is `L` and `R`-trivial.

        EXAMPLES::

            sage: Semigroups().JTrivial().extra_super_categories()
            [Category of l trivial semigroups, Category of r trivial semigroups]
        """
        return [Semigroups().LTrivial(), Semigroups().RTrivial()]
    def example(self):
        r"""
        EXAMPLES::

            sage: Semigroups().FinitelyGenerated().example()
            An example of a semigroup: the free semigroup generated by ('a', 'b', 'c', 'd')
        """
        return Semigroups().example("free")
Ejemplo n.º 3
0
    def extra_super_categories(self):
        r"""
        Implement the fact that an aperiodic semigroup is `H`-trivial.

        EXAMPLES::

            sage: Semigroups().Aperiodic().extra_super_categories()
            [Category of h trivial semigroups]
        """
        return [Semigroups().HTrivial()]
Ejemplo n.º 4
0
    def super_categories(self):
        r"""
        Returns a list of the (immediate) super categories of ``self``.

        EXAMPLES::

            sage: FiniteSemigroups().super_categories()
            [Category of semigroups, Category of finite enumerated sets]

        """
        return [Semigroups(), FiniteEnumeratedSets()]
Ejemplo n.º 5
0
    def super_categories(self):
        """
        Returns a list of the immediate super categories of ``self``.

        EXAMPLES::

            sage: Monoids().super_categories()
            [Category of semigroups]

        """
        return [Semigroups()]
Ejemplo n.º 6
0
    def Finite_extra_super_categories(self):
        r"""
        Implement the fact that a finite `H`-trivial is aperiodic

        EXAMPLES::

            sage: Semigroups().HTrivial().Finite_extra_super_categories()
            [Category of aperiodic semigroups]
            sage: Semigroups().HTrivial().Finite() is Semigroups().Aperiodic().Finite()
            True
        """
        return [Semigroups().Aperiodic()]
Ejemplo n.º 7
0
        def extra_super_categories(self):
            """
            EXAMPLES::

                sage: from sage.categories.additive_semigroups import AdditiveSemigroups
                sage: AdditiveSemigroups().Algebras(QQ).extra_super_categories()
                [Category of semigroups]
                sage: CommutativeAdditiveSemigroups().Algebras(QQ).super_categories()
                [Category of additive semigroup algebras over Rational Field,
                 Category of additive commutative additive magma algebras over Rational Field]
            """
            from sage.categories.semigroups import Semigroups
            return [Semigroups()]
Ejemplo n.º 8
0
    def __init__(self, alphabet=('a','b','c','d')):
        r"""
        A left regular band.

        EXAMPLES::

            sage: S = FiniteSemigroups().example(); S
            An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd')
            sage: S = FiniteSemigroups().example(alphabet=('x','y')); S
            An example of a finite semigroup: the left regular band generated by ('x', 'y')
            sage: TestSuite(S).run()
        """
        self.alphabet = alphabet
        Parent.__init__(self, category = Semigroups().Finite().FinitelyGenerated())
Ejemplo n.º 9
0
    def _repr_(self):
        """
        Return the string representation for ``self``.

        EXAMPLES::

            sage: from sage.monoids.automatic_semigroup import AutomaticSemigroup
            sage: R = IntegerModRing(12)
            sage: AutomaticSemigroup(Family({1: R(3), 2: R(5)}), one=R.one())
            A submonoid of (Ring of integers modulo 12) with 2 generators
            sage: AutomaticSemigroup(Family({1: R(3), 2: R(5)}))
            A subsemigroup of (Ring of integers modulo 12) with 2 generators

            sage: AutomaticSemigroup(Family({1: R(3), 2: R(5)}), mul=operator.add)
            A semigroup with 2 generators
            sage: AutomaticSemigroup(Family({1: R(3), 2: R(5)}), mul=operator.add, one=R.zero())
            A semigroup with 2 generators

            sage: S5 = SymmetricGroup(5); S5.rename("S5")
            sage: AutomaticSemigroup(Family({1: S5((1,2))}), category=Groups().Finite().Subobjects())
            A subgroup of (S5) with 1 generators
        """
        categories = [Groups(), Monoids(), Semigroups()]
        for category in categories:
            if self in category:
                typ = "A " + category._repr_object_names()[:-1]
        for category in [Groups(), Monoids(), Semigroups()]:
            if self.ambient() in category and self in category.Subobjects():
                typ = "A sub" + category._repr_object_names()[:-1]
                break
        if self._mul is operator.mul:
            of = " of (%s)" % self.ambient()
        else:
            of = ""

        return "%s%s with %s generators" % (typ, of, len(self._generators))
Ejemplo n.º 10
0
    def example(self, alphabet=('a', 'b', 'c')):
        """
        Returns an example of (finite) right trivial semigroup

        .. SEEALSO:: :meth:`Category.example`

        EXAMPLES::

            sage: S = Semigroups().RTrivial().example(); S
            An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd')
            sage: S.category()
            Category of finite r trivial semigroups
        """
        from sage.categories.examples.finite_semigroups import LeftRegularBand
        return LeftRegularBand(
            alphabet=alphabet,
            category=Semigroups().RTrivial().Finite().FinitelyGenerated())
    def extra_super_categories(self):
        r"""
        EXAMPLES:

        Any aperiodic monoid is H-trivial::

            sage: Semigroups().Aperiodic().super_categories()
            [Category of h trivial semigroups]

        This methods implements the fact that reciprocally any finite
        H-trivial semigroup is aperiodic::

            sage: Semigroups().HTrivial().Finite().extra_super_categories()
            [Category of aperiodic semigroups]

            sage: Semigroups().HTrivial().Finite().super_categories()
            [Category of finite semigroups, Category of aperiodic semigroups]

        .. seealso:: :meth:`sage.categories.adjective_category.AdjectiveCategory.extra_super_category`
        """
        return [Semigroups().Aperiodic()]
Ejemplo n.º 12
0
    def __init__(self, Q):
        """
        Initialize ``self``.

        INPUT:

        - a :class:`~sage.graphs.digraph.DiGraph`.

        EXAMPLES:

        Note that usually a path semigroup is created using
        :meth:`sage.graphs.digraph.DiGraph.path_semigroup`. Here, we
        demonstrate the direct construction::

            sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}}, immutable=True)
            sage: from sage.quivers.path_semigroup import PathSemigroup
            sage: P = PathSemigroup(Q)
            sage: P is DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}}).path_semigroup() # indirect doctest
            True
            sage: P
            Partial semigroup formed by the directed paths of Multi-digraph on 3 vertices

        While hardly of any use, it is possible to construct the path
        semigroup of an empty quiver (it is, of course, empty)::

            sage: D = DiGraph({})
            sage: A = D.path_semigroup(); A
            Partial semigroup formed by the directed paths of Digraph on 0 vertices
            sage: A.list()
            []

        .. TODO::

            When the graph has more than one edge, the proper category would be
            a "partial semigroup" or a "semigroupoid" but definitely not a
            semigroup!
        """
        #########
        ## Verify that the graph labels are acceptable for this implementation ##
        # Check that edges are labelled with nonempty strings and don't begin
        # with 'e_' or contain '*'
        labels = Q.edge_labels()
        if len(set(labels)) != len(labels):
            raise ValueError("edge labels of the digraph must be unique")
        for x in labels:
            if not isinstance(x, str) or x == '':
                raise ValueError("edge labels of the digraph must be nonempty strings")
            if x[0:2] == 'e_':
                raise ValueError("edge labels of the digraph must not begin with 'e_'")
            if x.find('*') != -1:
                raise ValueError("edge labels of the digraph must not contain '*'")

        # Check validity of input: vertices have to be labelled 1,2,3,... and
        # edge labels must be unique
        for v in Q:
            if not isinstance(v, integer_types + (Integer,)):
                raise ValueError("vertices of the digraph must be labelled by integers")

        ## Determine the category which this (partial) semigroup belongs to
        if Q.is_directed_acyclic():
            cat = FiniteEnumeratedSets()
        else:
            cat = InfiniteEnumeratedSets()
        self._sorted_edges = tuple(sorted(Q.edges(), key=lambda x:x[2]))
        self._labels = tuple([x[2] for x in self._sorted_edges])
        self._label_index = {s[2]: i for i,s in enumerate(self._sorted_edges)}
        self._nb_arrows = max(len(self._sorted_edges), 1)
        names = ['e_{0}'.format(v) for v in Q.vertices()] + list(self._labels)
        self._quiver = Q
        if Q.num_verts() == 1:
            cat = cat.join([cat,Monoids()])
        else:
            cat = cat.join([cat,Semigroups()])
        Parent.__init__(self, names=names, category=cat)
Ejemplo n.º 13
0
    def __classcall_private__(cls,
                              generators,
                              ambient=None,
                              one=None,
                              mul=operator.mul,
                              category=None):
        """
        Parse and straighten the arguments; figure out the category.

        TESTS::

            sage: from sage.monoids.automatic_semigroup import AutomaticSemigroup
            sage: R = IntegerModRing(9)
            sage: M = AutomaticSemigroup((), one=R.one())
            sage: M.ambient() == R
            True
            sage: AutomaticSemigroup((0,)).category()
            Join of Category of finitely generated semigroups and Category of subquotients of semigroups and Category of commutative magmas and Category of subobjects of sets
            sage: AutomaticSemigroup((0,), one=1).category()
            Join of Category of subquotients of monoids and
            Category of commutative monoids and
            Category of finitely generated semigroups and
            Category of subobjects of sets
            sage: AutomaticSemigroup((0,), one=0).category()
            Join of Category of commutative monoids and
            Category of finitely generated semigroups and
            Category of subquotients of semigroups and
            Category of subobjects of sets
            sage: AutomaticSemigroup((0,), mul=operator.add).category()
            Join of Category of semigroups and Category of subobjects of sets
            sage: AutomaticSemigroup((0,), one=0, mul=operator.add).category()
            Join of Category of monoids and Category of subobjects of sets

            sage: S5 = SymmetricGroup(5)
            sage: AutomaticSemigroup([S5((1,2))]).category()
            Join of Category of finite groups and
            Category of subquotients of monoids and
            Category of finite finitely generated semigroups and
            Category of subquotients of finite sets and
            Category of subobjects of sets

        .. TODO::

            One would want a subsemigroup of a group to be
            automatically a subgroup (in ``Groups().Subobjects()``).
        """
        generators = Family(generators)
        if ambient is None:
            # Try to guess the ambient semigroup from the generators or the unit
            if generators.cardinality() > 0:
                ambient = generators.first().parent()
            elif one is not None:
                ambient = one.parent()
            else:
                raise ValueError(
                    "AutomaticSemigroup requires at least one generator or `one` to determine the ambient space"
                )
        elif ambient not in Sets:
            raise ValueError("ambient (=%s) should be a set" % ambient)

        # if mul is not operator.mul  and category.is_subcategory(Monoids().Subobjects())  error

        if one is None and category is not None:
            if category.is_subcategory(Monoids().Subobjects()):
                one = ambient.one()
            elif category.is_subcategory(Monoids()):
                raise ValueError(
                    "For a monoid which is just a subsemigroup, the unit should be specified"
                )

        # Try to determine the most specific category
        # This logic should be in the categories
        if mul is operator.mul:
            default_category = Semigroups().FinitelyGenerated()
            if one is not None and one == ambient.one():
                default_category = default_category.Unital()
            if ambient in Semigroups().Commutative():
                default_category = default_category.Commutative()
            if ambient in Groups().Finite():
                default_category = default_category & Groups()
        else:
            default_category = Sets()

        if ambient in Sets().Finite():
            default_category = default_category.Finite()

        default_category = default_category.Subobjects() & Semigroups()
        if one is not None:
            default_category = default_category.Unital()
            cls = AutomaticMonoid

        if category is None:
            category = default_category
        else:
            category = default_category & category
        return super(AutomaticSemigroup, cls).__classcall__(cls,
                                                            generators,
                                                            ambient=ambient,
                                                            one=one,
                                                            mul=mul,
                                                            category=category)
 def super_categories(self):
     return [Semigroups()]
    class Subobjects(SubobjectsCategory):
        class ParentMethods:
            def domain(self):
                return self.ambient().domain()

        class ElementMethods:
            def __call__(self, *args):
                return self.lift()(*args)

            def image_set(self):
                return self.lift().image_set()

            def rank(self):
                return self.lift().rank()

            def fibers(self):
                return self.lift().fibers()

            def domain(self):
                return self.lift().domain()

            def codomain(self):
                return self.lift().codomain()


Semigroups.Transformation = TransformationSemigroups

Semigroups().subcategory_class.Transformation = lambda self: self._with_axiom(
    "Transformation")
Ejemplo n.º 16
0
 def __init__(self, jmonoid):
     assert (jmonoid in Monoids().JTrivial().Finite())
     self.jmonoid = jmonoid
     Parent.__init__(self, category=Semigroups().Finite())
    def __init__(self, Q):
        """
        Initialize ``self``.

        INPUT:

        - a :class:`~sage.graphs.digraph.DiGraph`.

        EXAMPLES:

        Note that usually a path semigroup is created using
        :meth:`sage.graphs.digraph.DiGraph.path_semigroup`. Here, we
        demonstrate the direct construction::

            sage: Q = DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}}, immutable=True)
            sage: from sage.quivers.path_semigroup import PathSemigroup
            sage: P = PathSemigroup(Q)
            sage: P is DiGraph({1:{2:['a','b'], 3:['c']}, 2:{3:['d']}}).path_semigroup() # indirect doctest
            True
            sage: P
            Partial semigroup formed by the directed paths of Multi-digraph on 3 vertices

        While hardly of any use, it is possible to construct the path
        semigroup of an empty quiver (it is, of course, empty)::

            sage: D = DiGraph({})
            sage: A = D.path_semigroup(); A
            Partial semigroup formed by the directed paths of Digraph on 0 vertices
            sage: A.list()
            []
        """
        #########
        ## Verify that the graph labels are acceptable for this implementation ##
        # Check that edges are labelled with nonempty strings and don't begin
        # with 'e_' or contain '*'
        for x in Q.edge_labels():
            if not isinstance(x, str) or x == '':
                raise ValueError(
                    "edge labels of the digraph must be nonempty strings")
            if x[0:2] == 'e_':
                raise ValueError(
                    "edge labels of the digraph must not begin with 'e_'")
            if x.find('*') != -1:
                raise ValueError(
                    "edge labels of the digraph must not contain '*'")
        # Check validity of input: vertices have to be labelled 1,2,3,... and
        # edge labels must be unique
        for v in Q:
            if v not in ZZ:
                raise ValueError(
                    "vertices of the digraph must be labelled by integers")
        if len(set(Q.edge_labels())) != Q.num_edges():
            raise ValueError("edge labels of the digraph must be unique")
        nvert = len(Q.vertices())
        ## Determine the category which this (partial) semigroup belongs to
        if Q.is_directed_acyclic() and not Q.has_loops():
            cat = FiniteEnumeratedSets()
        else:
            cat = InfiniteEnumeratedSets()
        names = ['e_{0}'.format(v)
                 for v in Q.vertices()] + [e[2] for e in Q.edges()]
        self._quiver = Q
        if nvert == 1:
            cat = cat.join([cat, Monoids()])
        else:
            # TODO: Make this the category of "partial semigroups"
            cat = cat.join([cat, Semigroups()])
        Parent.__init__(self, names=names, category=cat)