From f027ce2b5e1abe22d49bcdc96f2cfeebced8fc16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Wed, 15 Oct 2014 18:25:09 +0200 Subject: [PATCH 1/5] 17610: first draft of finitely generated axiom for magmas/groups/axioms --- src/sage/categories/category_with_axiom.py | 27 ++- src/sage/categories/coxeter_groups.py | 6 +- .../categories/examples/finite_monoids.py | 4 +- .../categories/examples/finite_semigroups.py | 4 +- src/sage/categories/examples/semigroups.py | 2 +- src/sage/categories/finite_coxeter_groups.py | 4 +- src/sage/categories/finite_semigroups.py | 152 ++----------- .../categories/finitely_generated_magmas.py | 55 +++++ .../finitely_generated_semigroups.py | 200 ++++++++++++++++++ src/sage/categories/magmas.py | 101 +++++++++ src/sage/categories/primer.py | 3 +- src/sage/categories/semigroups.py | 34 +++ src/sage/groups/perm_gps/permgroup.py | 6 +- 13 files changed, 445 insertions(+), 153 deletions(-) create mode 100644 src/sage/categories/finitely_generated_magmas.py create mode 100644 src/sage/categories/finitely_generated_semigroups.py diff --git a/src/sage/categories/category_with_axiom.py b/src/sage/categories/category_with_axiom.py index 84031ba8f30..20315f1f050 100644 --- a/src/sage/categories/category_with_axiom.py +++ b/src/sage/categories/category_with_axiom.py @@ -1677,6 +1677,7 @@ class ``Sets.Finite``), or in a separate file (typically in a class all_axioms += ("Flying", "Blue", "Facade", "Finite", "Infinite", "FiniteDimensional", "Connected", "WithBasis", + "FinitelyGeneratedAsMagma", "Irreducible", "Commutative", "Associative", "Inverse", "Unital", "Division", "NoZeroDivisors", "AdditiveCommutative", "AdditiveAssociative", "AdditiveInverse", "AdditiveUnital", @@ -2129,18 +2130,10 @@ def super_categories(self): ``self``, as per :meth:`Category.super_categories`. This implements the property that if ``As`` is a subcategory - of ``Bs``, then the intersection of As with ``FiniteSets()`` + of ``Bs``, then the intersection of ``As`` with ``FiniteSets()`` is a subcategory of ``As`` and of the intersection of ``Bs`` with ``FiniteSets()``. - EXAMPLES:: - - sage: FiniteSets().super_categories() - [Category of sets] - - sage: FiniteSemigroups().super_categories() - [Category of semigroups, Category of finite enumerated sets] - EXAMPLES: A finite magma is both a magma and a finite set:: @@ -2148,6 +2141,16 @@ def super_categories(self): sage: Magmas().Finite().super_categories() [Category of magmas, Category of finite sets] + Variants:: + + sage: Sets().Finite().super_categories() + [Category of sets] + + sage: Monoids().Finite().super_categories() + [Category of monoids, Category of finite semigroups] + + EXAMPLES: + TESTS:: sage: from sage.categories.category_with_axiom import TestObjects @@ -2232,6 +2235,8 @@ def _repr_object_names_static(category, axioms): sage: from sage.categories.homsets import Homsets sage: CategoryWithAxiom._repr_object_names_static(Homsets(), ["Endset"]) 'endsets' + sage: CategoryWithAxiom._repr_object_names_static(PermutationGroups(), ["FinitelyGeneratedAsMagma"]) + 'finitely generated permutation groups' """ axioms = canonicalize_axioms(all_axioms,axioms) base_category = category._without_axioms(named=True) @@ -2254,6 +2259,10 @@ def _repr_object_names_static(category, axioms): elif axiom == "Endset" and "homsets" in result: # Without the space at the end to handle Homsets().Endset() result = result.replace("homsets", "endsets", 1) + elif axiom == "FinitelyGeneratedAsMagma": + from sage.categories.additive_magmas import AdditiveMagmas + if not base_category.is_subcategory(AdditiveMagmas()): + result = "finitely generated " + result else: result = uncamelcase(axiom) + " " + result return result diff --git a/src/sage/categories/coxeter_groups.py b/src/sage/categories/coxeter_groups.py index 2c6b1b65438..2646176f4b0 100644 --- a/src/sage/categories/coxeter_groups.py +++ b/src/sage/categories/coxeter_groups.py @@ -39,7 +39,7 @@ class CoxeterGroups(Category_singleton): sage: C = CoxeterGroups(); C Category of coxeter groups sage: C.super_categories() - [Category of groups, Category of enumerated sets] + [Category of finitely generated groups] sage: W = C.example(); W The symmetric group on {0, ..., 3} @@ -117,9 +117,9 @@ def super_categories(self): EXAMPLES:: sage: CoxeterGroups().super_categories() - [Category of groups, Category of enumerated sets] + [Category of finitely generated groups] """ - return [Groups(), EnumeratedSets()] + return [Groups().FinitelyGenerated()] Finite = LazyImport('sage.categories.finite_coxeter_groups', 'FiniteCoxeterGroups') Algebras = LazyImport('sage.categories.coxeter_group_algebras', 'CoxeterGroupAlgebras') diff --git a/src/sage/categories/examples/finite_monoids.py b/src/sage/categories/examples/finite_monoids.py index 0b43207827c..fc5feb28b86 100644 --- a/src/sage/categories/examples/finite_monoids.py +++ b/src/sage/categories/examples/finite_monoids.py @@ -13,7 +13,7 @@ from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation from sage.structure.element_wrapper import ElementWrapper -from sage.categories.all import FiniteMonoids +from sage.categories.all import Monoids from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ @@ -72,7 +72,7 @@ def __init__(self, n = 12): """ self.n = n - Parent.__init__(self, category = FiniteMonoids()) + Parent.__init__(self, category = Monoids().Finite()) def _repr_(self): r""" diff --git a/src/sage/categories/examples/finite_semigroups.py b/src/sage/categories/examples/finite_semigroups.py index 0cbb6d15e0d..a109e525949 100644 --- a/src/sage/categories/examples/finite_semigroups.py +++ b/src/sage/categories/examples/finite_semigroups.py @@ -10,7 +10,7 @@ from sage.misc.cachefunc import cached_method from sage.sets.family import Family -from sage.categories.all import FiniteSemigroups +from sage.categories.semigroups import Semigroups from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation from sage.structure.element_wrapper import ElementWrapper @@ -114,7 +114,7 @@ def __init__(self, alphabet=('a','b','c','d')): sage: TestSuite(S).run() """ self.alphabet = alphabet - Parent.__init__(self, category = FiniteSemigroups()) + Parent.__init__(self, category = Semigroups().Finite().FinitelyGenerated()) def _repr_(self): r""" diff --git a/src/sage/categories/examples/semigroups.py b/src/sage/categories/examples/semigroups.py index 8f7f59bcff1..86e69bce22d 100644 --- a/src/sage/categories/examples/semigroups.py +++ b/src/sage/categories/examples/semigroups.py @@ -214,7 +214,7 @@ def __init__(self, alphabet=('a','b','c','d')): """ self.alphabet = alphabet - Parent.__init__(self, category = Semigroups()) + Parent.__init__(self, category = Semigroups().FinitelyGenerated()) def _repr_(self): r""" diff --git a/src/sage/categories/finite_coxeter_groups.py b/src/sage/categories/finite_coxeter_groups.py index d17296a5164..5860913e248 100644 --- a/src/sage/categories/finite_coxeter_groups.py +++ b/src/sage/categories/finite_coxeter_groups.py @@ -23,7 +23,9 @@ class FiniteCoxeterGroups(CategoryWithAxiom): sage: FiniteCoxeterGroups() Category of finite coxeter groups sage: FiniteCoxeterGroups().super_categories() - [Category of finite groups, Category of coxeter groups] + [Category of coxeter groups, + Category of finite groups, + Category of finite enumerated sets] sage: G = FiniteCoxeterGroups().example() sage: G.cayley_graph(side = "right").plot() diff --git a/src/sage/categories/finite_semigroups.py b/src/sage/categories/finite_semigroups.py index 5c84f41e34e..7b74e5c2973 100644 --- a/src/sage/categories/finite_semigroups.py +++ b/src/sage/categories/finite_semigroups.py @@ -19,28 +19,35 @@ class FiniteSemigroups(CategoryWithAxiom): r""" The category of finite (multiplicative) semigroups. - A :class:`semigroup ` is a :class:`finite sets ` - endowed with an associative binary operation `*`. + A finite semigroup is a :class:`finite set ` endowed + with an associative binary operation `*`. - .. NOTE:: + .. WARNING:: - A finite semigroup in Sage is currently automatically endowed - with an :class:`enumerated set ` structure, with - the default enumeration being obtained by iteratively - multiplying the semigroup generators (see - :meth:`FiniteSemigroups.super_categories` and - :meth:`FiniteSemigroups.ParentMethods.__iter__`). Therefore a - finite semigroup must at this point either implement an - enumeration or provide semigroup generators. + Finite semigroups in Sage used to be automatically endowed + with an :class:`enumerated set ` structure; + the default enumeration is then obtained by iteratively + multiplying the semigroup generators. This forced any finite + semigroup to either implement an enumeration, or provide + semigroup generators; this was often inconvenient. - .. TODO:: make this optional + Instead, finite semigroups that provide a distinguished finite + set of generators with :meth:`semigroup_generators` should now + explicitly declare themselves in the category of + :class:`finitely generated semigroups + `:: + + sage: Semigroups().FinitelyGenerated() + Category of finitely generated semigroups + + This is a backward incompatible change. EXAMPLES:: sage: C = FiniteSemigroups(); C Category of finite semigroups sage: C.super_categories() - [Category of semigroups, Category of finite enumerated sets] + [Category of semigroups, Category of finite sets] sage: sorted(C.axioms()) ['Associative', 'Finite'] sage: C.example() @@ -51,42 +58,7 @@ class FiniteSemigroups(CategoryWithAxiom): sage: TestSuite(C).run() """ - @cached_method - def extra_super_categories(self): - r""" - Returns a list of the (immediate) super categories of ``self``. - - EXAMPLES:: - - sage: FiniteSemigroups().extra_super_categories() - [Category of finite enumerated sets] - - """ - return [FiniteEnumeratedSets()] - class ParentMethods: - r""" - Collection of methods shared by all finite semigroups. - """ - def some_elements(self): - r""" - Returns an iterable containing some elements of the semigroup. - - .. note: - - Since the semigroup is finite, this method returns self. - - EXAMPLES:: - - sage: S = FiniteSemigroups().example(alphabet=('x','y')) - sage: S.some_elements() - An example of a finite semigroup: the left regular band generated by ('x', 'y') - sage: list(S) - ['y', 'x', 'xy', 'yx'] - - """ - return self - def idempotents(self): r""" Returns the idempotents of the semigroup @@ -99,90 +71,6 @@ def idempotents(self): """ return [x for x in self if x.is_idempotent()] - def succ_generators(self, side="twosided"): - r""" - Returns the the successor function of the ``side``-sided Cayley - graph of ``self``. - - This is a function that maps an element of ``self`` to all the - products of ``x`` by a generator of this semigroup, where the - product is taken on the left, right or both sides. - - INPUT:: - - - ``side``: "left", "right", or "twosided" - - FIXME: find a better name for this method - FIXME: should we return a set? a family? - - EXAMPLES:: - - sage: S = FiniteSemigroups().example() - sage: S.succ_generators("left" )(S('ca')) - ('ac', 'bca', 'ca', 'dca') - sage: S.succ_generators("right")(S('ca')) - ('ca', 'cab', 'ca', 'cad') - sage: S.succ_generators("twosided" )(S('ca')) - ('ac', 'bca', 'ca', 'dca', 'ca', 'cab', 'ca', 'cad') - - """ - left = (side == "left" or side == "twosided") - right = (side == "right" or side == "twosided") - generators = self.semigroup_generators() - return lambda x: (tuple(g * x for g in generators) if left else ()) + (tuple(x * g for g in generators) if right else ()) - - def __iter__(self): - """ - Returns an iterator over the elements of ``self``. - - EXAMPLES:: - - sage: S = FiniteSemigroups().example(alphabet=('x','y')) - sage: it = S.__iter__() - sage: list(it) - ['y', 'x', 'xy', 'yx'] - - """ - from sage.combinat.backtrack import TransitiveIdeal - return TransitiveIdeal(self.succ_generators(side = "right"), self.semigroup_generators()).__iter__() - - def ideal(self, gens, side="twosided"): - r""" - Returns the ``side``-sided ideal generated by ``gens``. - - INPUT:: - - - ``gens``: a list (or iterable) of elements of ``self`` - - ``side``: [default: "twosided"] "left", "right" or "twosided" - - EXAMPLES:: - - sage: S = FiniteSemigroups().example() - sage: list(S.ideal([S('cab')], side="left")) - ['cab', 'dcab', 'adcb', 'acb', 'bdca', 'bca', 'abdc', - 'cadb', 'acdb', 'bacd', 'abcd', 'cbad', 'abc', 'acbd', - 'dbac', 'dabc', 'cbda', 'bcad', 'cabd', 'dcba', - 'bdac', 'cba', 'badc', 'bac', 'cdab', 'dacb', 'dbca', - 'cdba', 'adbc', 'bcda'] - sage: list(S.ideal([S('cab')], side="right")) - ['cab', 'cabd'] - sage: list(S.ideal([S('cab')], side="twosided")) - ['cab', 'dcab', 'acb', 'adcb', 'acbd', 'bdca', 'bca', - 'cabd', 'abdc', 'cadb', 'acdb', 'bacd', 'abcd', 'cbad', - 'abc', 'dbac', 'dabc', 'cbda', 'bcad', 'dcba', 'bdac', - 'cba', 'cdab', 'bac', 'badc', 'dacb', 'dbca', 'cdba', - 'adbc', 'bcda'] - sage: list(S.ideal([S('cab')])) - ['cab', 'dcab', 'acb', 'adcb', 'acbd', 'bdca', 'bca', - 'cabd', 'abdc', 'cadb', 'acdb', 'bacd', 'abcd', 'cbad', - 'abc', 'dbac', 'dabc', 'cbda', 'bcad', 'dcba', 'bdac', - 'cba', 'cdab', 'bac', 'badc', 'dacb', 'dbca', 'cdba', - 'adbc', 'bcda'] - - """ - from sage.combinat.backtrack import TransitiveIdeal - return TransitiveIdeal(self.succ_generators(side = side), gens) - @cached_method def j_classes(self): r""" diff --git a/src/sage/categories/finitely_generated_magmas.py b/src/sage/categories/finitely_generated_magmas.py new file mode 100644 index 00000000000..52033ee2057 --- /dev/null +++ b/src/sage/categories/finitely_generated_magmas.py @@ -0,0 +1,55 @@ +r""" +Finitely generated magmas +""" +#***************************************************************************** +# Copyright (C) 2014 Nicolas M. Thiery +# +# Distributed under the terms of the GNU General Public License (GPL) +# http://www.gnu.org/licenses/ +#****************************************************************************** + +from sage.misc.abstract_method import abstract_method +from sage.categories.category_with_axiom import CategoryWithAxiom +from sage.categories.magmas import Magmas + +class FinitelyGeneratedMagmas(CategoryWithAxiom): + r""" + The category of finitely generated (multiplicative) magmas. + + See :meth:`Magmas.SubcategoryMethods.FinitelyGeneratedAsMagma` for + details. + + EXAMPLES:: + + sage: C = Magmas().FinitelyGeneratedAsMagma(); C + Category of finitely generated magmas + sage: C.super_categories() + [Category of magmas] + sage: sorted(C.axioms()) + ['FinitelyGeneratedAsMagma'] + + TESTS:: + + sage: TestSuite(C).run() + """ + + _base_category_class_and_axiom = (Magmas, "FinitelyGeneratedAsMagma") + + class ParentMethods: + + @abstract_method + def magma_generators(self): + """ + Return distinguished magma generators for ``self``. + + OUTPUT: a finite family + + This method should be implemented by all + :class:`finitely generated magmas `_. + + EXAMPLES:: + + sage: S = FiniteSemigroups().example() + sage: S.magma_generators() + Family ('a', 'b', 'c', 'd') + """ diff --git a/src/sage/categories/finitely_generated_semigroups.py b/src/sage/categories/finitely_generated_semigroups.py new file mode 100644 index 00000000000..6b5f834c778 --- /dev/null +++ b/src/sage/categories/finitely_generated_semigroups.py @@ -0,0 +1,200 @@ +r""" +Finitely generated semigroups +""" +#***************************************************************************** +# Copyright (C) 2014 Nicolas M. Thiery +# +# Distributed under the terms of the GNU General Public License (GPL) +# http://www.gnu.org/licenses/ +#****************************************************************************** + +from sage.misc.abstract_method import abstract_method +from sage.misc.cachefunc import cached_method +from sage.categories.category_with_axiom import CategoryWithAxiom +from sage.categories.semigroups import Semigroups +from sage.categories.enumerated_sets import EnumeratedSets + +class FinitelyGeneratedSemigroups(CategoryWithAxiom): + r""" + The category of finitely generated (multiplicative) semigroups. + + A :class:`finitely generated semigroup ` is a + :class:`semigroup ` endowed with a distinguished + finite set of generators (see + :meth:`FinitelyGeneratedSemigroups.ParentMethods.semigroup_generators`). This + makes it into an :class:`enumerated set `. + + EXAMPLES:: + + sage: C = Semigroups().FinitelyGenerated(); C + Category of finitely generated semigroups + sage: C.super_categories() + [Category of semigroups, + Category of finitely generated magmas, + Category of enumerated sets] + sage: sorted(C.axioms()) + ['Associative', 'FinitelyGeneratedAsMagma'] + sage: C.example() + An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd') + + TESTS:: + + sage: TestSuite(C).run() + """ + + _base_category_class_and_axiom = (Semigroups, "FinitelyGeneratedAsMagma") + + @cached_method + def extra_super_categories(self): + r""" + State that a finitely generated semigroup is endowed with a + default enumeration. + + EXAMPLES:: + + sage: Semigroups().FinitelyGenerated().extra_super_categories() + [Category of enumerated sets] + + """ + return [EnumeratedSets()] + + def example(self): + """ + EXAMPLES:: + + sage: Semigroups().FinitelyGenerated().example() + An example of a semigroup: the free semigroup generated by ('a', 'b', 'c', 'd') + """ + return Semigroups().example("free") + + class ParentMethods: + + @abstract_method + def semigroup_generators(self): + """ + Return distinguished semigroup generators for ``self``. + + OUTPUT: a finite family + + This method should be implemented by all semigroups in + :class:`FinitelyGeneratedSemigroups`. + + EXAMPLES:: + + sage: S = FiniteSemigroups().example() + sage: S.semigroup_generators() + Family ('a', 'b', 'c', 'd') + """ + + # TODO: update transitive ideal + + def succ_generators(self, side="twosided"): + r""" + Return the successor function of the ``side``-sided Cayley + graph of ``self``. + + This is a function that maps an element of ``self`` to all + the products of ``x`` by a generator of this semigroup, + where the product is taken on the left, right, or both + sides. + + INPUT:: + + - ``side``: "left", "right", or "twosided" + + FIXME: find a better name for this method + FIXME: should we return a set? a family? + + EXAMPLES:: + + sage: S = FiniteSemigroups().example() + sage: S.succ_generators("left" )(S('ca')) + ('ac', 'bca', 'ca', 'dca') + sage: S.succ_generators("right")(S('ca')) + ('ca', 'cab', 'ca', 'cad') + sage: S.succ_generators("twosided" )(S('ca')) + ('ac', 'bca', 'ca', 'dca', 'ca', 'cab', 'ca', 'cad') + + """ + left = (side == "left" or side == "twosided") + right = (side == "right" or side == "twosided") + generators = self.semigroup_generators() + return lambda x: (tuple(g * x for g in generators) if left else ()) + (tuple(x * g for g in generators) if right else ()) + + def __iter__(self): + """ + Return an iterator over the elements of ``self``. + + This brute force implementation recursively multiplies + together the distinguished semigroup generators. + + .. SEEALSO:: :meth:`semigroup_generators` + + EXAMPLES:: + + sage: S = FiniteSemigroups().example(alphabet=('x','y')) + sage: it = S.__iter__() + sage: list(it) + ['y', 'x', 'xy', 'yx'] + """ + from sage.combinat.backtrack import TransitiveIdeal + return TransitiveIdeal(self.succ_generators(side = "right"), self.semigroup_generators()).__iter__() + + def ideal(self, gens, side="twosided"): + r""" + Return the ``side``-sided ideal generated by ``gens``. + + This brute force implementation recursively multiplies the + elements of ``gens`` by the distinguished generators of + this semigroup. + + .. SEEALSO:: :meth:`semigroup_generators` + + INPUT:: + + - ``gens``: a list (or iterable) of elements of ``self`` + - ``side``: [default: "twosided"] "left", "right" or "twosided" + + EXAMPLES:: + + sage: S = FiniteSemigroups().example() + sage: list(S.ideal([S('cab')], side="left")) + ['cab', 'dcab', 'adcb', 'acb', 'bdca', 'bca', 'abdc', + 'cadb', 'acdb', 'bacd', 'abcd', 'cbad', 'abc', 'acbd', + 'dbac', 'dabc', 'cbda', 'bcad', 'cabd', 'dcba', + 'bdac', 'cba', 'badc', 'bac', 'cdab', 'dacb', 'dbca', + 'cdba', 'adbc', 'bcda'] + sage: list(S.ideal([S('cab')], side="right")) + ['cab', 'cabd'] + sage: list(S.ideal([S('cab')], side="twosided")) + ['cab', 'dcab', 'acb', 'adcb', 'acbd', 'bdca', 'bca', + 'cabd', 'abdc', 'cadb', 'acdb', 'bacd', 'abcd', 'cbad', + 'abc', 'dbac', 'dabc', 'cbda', 'bcad', 'dcba', 'bdac', + 'cba', 'cdab', 'bac', 'badc', 'dacb', 'dbca', 'cdba', + 'adbc', 'bcda'] + sage: list(S.ideal([S('cab')])) + ['cab', 'dcab', 'acb', 'adcb', 'acbd', 'bdca', 'bca', + 'cabd', 'abdc', 'cadb', 'acdb', 'bacd', 'abcd', 'cbad', + 'abc', 'dbac', 'dabc', 'cbda', 'bcad', 'dcba', 'bdac', + 'cba', 'cdab', 'bac', 'badc', 'dacb', 'dbca', 'cdba', + 'adbc', 'bcda'] + + """ + from sage.combinat.backtrack import TransitiveIdeal + return TransitiveIdeal(self.succ_generators(side = side), gens) + + + def some_elements(self): + r""" + Return an iterable containing some elements of the semigroup. + + EXAMPLES:: + + sage: S = FiniteSemigroups().example(alphabet=('x','y')) + sage: S.some_elements() + An example of a finite semigroup: the left regular band generated by ('x', 'y') + sage: list(S) + ['y', 'x', 'xy', 'yx'] + """ + return self + diff --git a/src/sage/categories/magmas.py b/src/sage/categories/magmas.py index 8692bbbf100..6a18b7a1fd9 100644 --- a/src/sage/categories/magmas.py +++ b/src/sage/categories/magmas.py @@ -159,6 +159,106 @@ def Unital(self): """ return self._with_axiom("Unital") + @cached_method + def FinitelyGeneratedAsMagma(self): + r""" + Return the subcategory of the objects of ``self`` that are + endowed with a distinguished finite set of + (multiplicative) magma generators. + + A set `S` of elements of a multiplicative magma form a + *set of generators* if any element of the magma can be + expressed recursively from elements of `S` and products + thereof. + + It is not imposed that morphisms shall preserve the + distinguished set of generators; hence this is a full + subcategory. + + .. SEEALSO:: :wikipedia:`Unital_magma#unital` + + EXAMPLES:: + + sage: Magmas().FinitelyGeneratedAsMagma() + Category of finitely generated magmas + + Being finitely generated does depend on the structure: for + a ring, being finitely generated as a magma, as an + additive magma, or as a ring are different concepts. Hence + the name of this axiom is explicit:: + + sage: Rings().FinitelyGeneratedAsMagma() + Category of finitely generated as magma rings + + On the other hand, it does not depend on the + multiplicative structure: for example a group is finitely + generated if and only if it is finitely generated as a + magma. A short hand is provided when there is no + ambiguity, and the output tries to reflect that:: + + sage: Semigroups().FinitelyGenerated() + Category of finitely generated semigroups + sage: Groups().FinitelyGenerated() + Category of finitely generated groups + + sage: Semigroups().FinitelyGenerated().axioms() + frozenset({'Associative', 'FinitelyGeneratedAsMagma'}) + + Note that the set of generators may depend on the actual + category; for example, in a group, one can often use less + generators since it is allowed to take inverses. + + TESTS:: + + sage: TestSuite(Magmas().FinitelyGeneratedAsMagma()).run() + sage: Semigroups().FinitelyGeneratedAsMagma.__module__ + 'sage.categories.magmas' + """ + return self._with_axiom("FinitelyGeneratedAsMagma") + + @cached_method + def FinitelyGenerated(self): + r""" + Return the subcategory of the objects of ``self`` that are + endowed with a distinguished finite set of + (multiplicative) magma generators. + + EXAMPLES:: + + This is a shorthand for :meth:`FinitelyGeneratedAsMagma`, + which see:: + + sage: Magmas().FinitelyGenerated() + Category of finitely generated magmas + sage: Semigroups().FinitelyGenerated() + Category of finitely generated semigroups + sage: Groups().FinitelyGenerated() + Category of finitely generated groups + + An error is raised if this is ambiguous:: + + sage: (Magmas() & AdditiveMagmas()).FinitelyGenerated() + Traceback (most recent call last): + ... + ValueError: FinitelyGenerated is ambiguous for + Join of Category of magmas and Category of additive magmas. + Please use explicitly one of the FinitelyGeneratedAsXXX methods + + .. NOTE:: + + Checking that there is no ambiguity currently assumes + that all the other "finitely generated" axioms involve + an additive structure. As of Sage 6.4, this is + correct. + + The use of this shorthand should be reserved to casual + interactive use or when there is no risk of ambiguity. + """ + from sage.categories.additive_magmas import AdditiveMagmas + if self.is_subcategory(AdditiveMagmas()): + raise ValueError("FinitelyGenerated is ambiguous for {}.\nPlease use explicitly one of the FinitelyGeneratedAsXXX methods".format(self)) + return self.FinitelyGeneratedAsMagma() + @cached_method def Distributive(self): """ @@ -214,6 +314,7 @@ def Distributive(self): return (self & MagmasAndAdditiveMagmas()).Distributive() Associative = LazyImport('sage.categories.semigroups', 'Semigroups', at_startup=True) + FinitelyGeneratedAsMagma = LazyImport('sage.categories.finitely_generated_magmas', 'FinitelyGeneratedMagmas') class Algebras(AlgebrasCategory): diff --git a/src/sage/categories/primer.py b/src/sage/categories/primer.py index 7c1f7508b39..f0cbe6185c7 100644 --- a/src/sage/categories/primer.py +++ b/src/sage/categories/primer.py @@ -957,7 +957,8 @@ class SubcategoryMethods: sage: FiniteSemigroups().required_methods() {'element': {'optional': ['_mul_'], 'required': []}, - 'parent': {'optional': [], 'required': ['__contains__']}} + 'parent': {'optional': ['semigroup_generators'], + 'required': ['__contains__']}} ``product`` does not appear in the list because a default implementation is provided in term of the method ``_mul_`` on elements. Of course, at diff --git a/src/sage/categories/semigroups.py b/src/sage/categories/semigroups.py index ff991fd32e2..d7f5bc92319 100644 --- a/src/sage/categories/semigroups.py +++ b/src/sage/categories/semigroups.py @@ -12,6 +12,7 @@ # http://www.gnu.org/licenses/ #****************************************************************************** +from sage.misc.abstract_method import abstract_method from sage.misc.cachefunc import cached_method from sage.misc.lazy_import import LazyImport from sage.misc.misc_c import prod @@ -117,6 +118,38 @@ def _test_associativity(self, **options): for x,y,z in tester.some_elements(CartesianProduct(S,S,S)): tester.assert_((x * y) * z == x * (y * z)) + @abstract_method(optional=True) + def semigroup_generators(self): + """ + Return distinguished semigroup generators for ``self``. + + OUTPUT: a family + + This method is optional. + + EXAMPLES:: + + sage: S = Semigroups().example("free"); S + An example of a semigroup: the free semigroup generated by ('a', 'b', 'c', 'd') + sage: S.semigroup_generators() + Family ('a', 'b', 'c', 'd') + """ + + def magma_generators(self): + """ + An alias for :meth:`semigroup_generators`. + + EXAMPLES:: + + sage: S = Semigroups().example("free"); S + An example of a semigroup: the free semigroup generated by ('a', 'b', 'c', 'd') + sage: S.magma_generators() + Family ('a', 'b', 'c', 'd') + sage: S.semigroup_generators() + Family ('a', 'b', 'c', 'd') + """ + return self.semigroup_generators() + def prod(self, args): r""" Return the product of the list of elements ``args`` @@ -341,6 +374,7 @@ def _pow_(self, n): Finite = LazyImport('sage.categories.finite_semigroups', 'FiniteSemigroups', at_startup=True) + FinitelyGeneratedAsMagma = LazyImport('sage.categories.finitely_generated_semigroups', 'FinitelyGeneratedSemigroups') Unital = LazyImport('sage.categories.monoids', 'Monoids', at_startup=True) ####################################### diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py index fc453786b5d..bedb3916399 100644 --- a/src/sage/groups/perm_gps/permgroup.py +++ b/src/sage/groups/perm_gps/permgroup.py @@ -391,8 +391,10 @@ def __init__(self, gens=None, gap_group=None, canonicalize=True, domain=None, ca sage: TestSuite(PermutationGroup([])).run() sage: TestSuite(PermutationGroup([(0,1)])).run() """ - from sage.categories.finite_permutation_groups import FinitePermutationGroups - super(PermutationGroup_generic, self).__init__(category = FinitePermutationGroups().or_subcategory(category)) + from sage.categories.permutation_groups import PermutationGroups + category = PermutationGroups().FinitelyGenerated().Finite() \ + .or_subcategory(category) + super(PermutationGroup_generic, self).__init__(category=category) if (gens is None and gap_group is None): raise ValueError("you must specify gens or gap_group") From cf9b429455e3330ff76d544bf39bc9ff7c76e514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Thu, 12 Mar 2015 11:25:11 +0100 Subject: [PATCH 2/5] Fixed ReST typo --- src/sage/categories/magmas.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/categories/magmas.py b/src/sage/categories/magmas.py index 1022ca78462..2dde8b4e674 100644 --- a/src/sage/categories/magmas.py +++ b/src/sage/categories/magmas.py @@ -223,7 +223,7 @@ def FinitelyGenerated(self): endowed with a distinguished finite set of (multiplicative) magma generators. - EXAMPLES:: + EXAMPLES: This is a shorthand for :meth:`FinitelyGeneratedAsMagma`, which see:: From aff2689ac6a7f6b80c1d4678ff348761f6a38919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Fri, 13 Mar 2015 14:18:40 +0100 Subject: [PATCH 3/5] 17160: fixed category for finite set endomaps + minor __init__ refactoring --- src/sage/sets/finite_set_maps.py | 34 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/sage/sets/finite_set_maps.py b/src/sage/sets/finite_set_maps.py index f4461022ae0..c3b05743fde 100644 --- a/src/sage/sets/finite_set_maps.py +++ b/src/sage/sets/finite_set_maps.py @@ -22,8 +22,8 @@ from sage.rings.integer import Integer from sage.structure.unique_representation import UniqueRepresentation from sage.categories.sets_cat import Sets, EmptySetError -from sage.categories.finite_monoids import FiniteMonoids -from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets +from sage.categories.monoids import Monoids +from sage.categories.enumerated_sets import EnumeratedSets from sage.sets.finite_enumerated_set import FiniteEnumeratedSet from sage.combinat.cartesian_product import CartesianProduct from sage.sets.integer_range import IntegerRange @@ -117,7 +117,7 @@ class FiniteSetMaps(UniqueRepresentation, Parent): This makes `M` into a monoid:: sage: M.category() - Category of finite monoids + Join of Category of finite monoids and Category of finite enumerated sets sage: M.one() map: 1 -> 1, 2 -> 2, 3 -> 3 @@ -216,7 +216,7 @@ class FiniteSetMaps_MN(FiniteSetMaps): - ``category`` -- the category in which the sets of maps is constructed. It must be a sub-category of - ``FiniteEnumeratedSets()`` which is the default value. + ``EnumeratedSets().Finite()`` which is the default value. """ def __init__(self, m, n, category=None): @@ -231,7 +231,7 @@ def __init__(self, m, n, category=None): sage: TestSuite(M).run() """ Parent.__init__(self, - category=FiniteEnumeratedSets().or_subcategory(category)) + category=EnumeratedSets().Finite().or_subcategory(category)) self._m = Integer(m) self._n = Integer(n) @@ -378,8 +378,8 @@ class FiniteSetMaps_Set(FiniteSetMaps_MN): - ``codomain`` -- an object in the category ``FiniteSets()``. - ``category`` -- the category in which the sets of maps is - constructed. It must be a sub-category of ``FiniteEnumeratedSets()`` - which is the default value. + constructed. It must be a sub-category of + ``EnumeratedSets().Finite`` which is the default value. """ def __init__(self, domain, codomain, category=None): """ @@ -488,8 +488,8 @@ class FiniteSetEndoMaps_N(FiniteSetMaps_MN): - ``n`` -- an integer. - ``category`` -- the category in which the sets of maps is - constructed. It must be a sub-category of ``FiniteMonoids()`` - which is the default value. + constructed. It must be a sub-category of ``Monoids().Finite()`` + and ``EnumeratedSets().Finite()`` which is the default value. """ def __init__(self, n, action, category=None): @@ -498,14 +498,13 @@ def __init__(self, n, action, category=None): sage: M = FiniteSetMaps(3) sage: M.category() - Category of finite monoids + Join of Category of finite monoids and Category of finite enumerated sets sage: M.__class__ sage: TestSuite(M).run() """ - Parent.__init__(self, category=FiniteMonoids().or_subcategory(category)) - self._m = n - self._n = n + category = (EnumeratedSets() & Monoids().Finite()).or_subcategory(category) + FiniteSetMaps_MN.__init__(self, n, n, category=category) self._action = action @cached_method @@ -554,8 +553,8 @@ class FiniteSetEndoMaps_Set(FiniteSetMaps_Set, FiniteSetEndoMaps_N): - ``domain`` -- an object in the category ``FiniteSets()``. - ``category`` -- the category in which the sets of maps is - constructed. It must be a sub-category of ``FiniteMonoids()`` - which is the default value. + constructed. It must be a sub-category of ``Monoids().Finite()`` + and ``EnumeratedSets().Finite()`` which is the default value. """ def __init__(self, domain, action, category=None): """ @@ -563,13 +562,14 @@ def __init__(self, domain, action, category=None): sage: M = FiniteSetMaps(["a", "b", "c"]) sage: M.category() - Category of finite monoids + Join of Category of finite monoids and Category of finite enumerated sets sage: M.__class__ sage: TestSuite(M).run() """ + category = (EnumeratedSets() & Monoids().Finite()).or_subcategory(category) FiniteSetMaps_MN.__init__(self, domain.cardinality(), domain.cardinality(), - category=FiniteMonoids().or_subcategory(category)) + category=category) self._domain = domain self._codomain = domain From ad5d6c0dc9cf55eed4900ed76df26f4a3e86f73f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Fri, 20 Mar 2015 00:57:38 -0700 Subject: [PATCH 4/5] 8678: permutation groups are finitely generated, finite fields are enumerated, fixes * Doctests updates * Bug fix in the handling of FinitelyGeneratedAsAxiom in CategoryWithAxiom._repr_object_names * Prefer `finitely generated finite xxx` to `finite finitely generated xxx` * Fixed Semigroups.FinitelyGenerated.ParentMethods.some_elements: it's now capped to the 10 first elements --- src/sage/categories/category.py | 2 +- src/sage/categories/category_with_axiom.py | 26 +++++++------- .../categories/examples/finite_monoids.py | 4 +-- src/sage/categories/examples/semigroups.py | 20 +---------- src/sage/categories/finite_coxeter_groups.py | 2 +- src/sage/categories/finite_fields.py | 28 +++++++++++---- .../categories/finite_permutation_groups.py | 31 +++++++++++++--- .../finitely_generated_semigroups.py | 35 +++++++++++-------- src/sage/categories/integral_domains.py | 1 + .../unique_factorization_domains.py | 5 +-- 10 files changed, 91 insertions(+), 63 deletions(-) diff --git a/src/sage/categories/category.py b/src/sage/categories/category.py index 66d10edf186..4d8f880bcbd 100644 --- a/src/sage/categories/category.py +++ b/src/sage/categories/category.py @@ -2625,7 +2625,7 @@ def category_graph(categories = None): Graphics object consisting of 20 graphics primitives sage: sage.categories.category.category_graph().plot() - Graphics object consisting of 312 graphics primitives + Graphics object consisting of ... graphics primitives """ from sage import graphs if categories is None: diff --git a/src/sage/categories/category_with_axiom.py b/src/sage/categories/category_with_axiom.py index 20315f1f050..90586546b9a 100644 --- a/src/sage/categories/category_with_axiom.py +++ b/src/sage/categories/category_with_axiom.py @@ -1675,14 +1675,14 @@ class ``Sets.Finite``), or in a separate file (typically in a class all_axioms = AxiomContainer() all_axioms += ("Flying", "Blue", - "Facade", "Finite", "Infinite", - "FiniteDimensional", "Connected", "WithBasis", - "FinitelyGeneratedAsMagma", - "Irreducible", - "Commutative", "Associative", "Inverse", "Unital", "Division", "NoZeroDivisors", - "AdditiveCommutative", "AdditiveAssociative", "AdditiveInverse", "AdditiveUnital", - "Distributive", - "Endset" + "FinitelyGeneratedAsMagma", + "Facade", "Finite", "Infinite", + "FiniteDimensional", "Connected", "WithBasis", + "Irreducible", + "Commutative", "Associative", "Inverse", "Unital", "Division", "NoZeroDivisors", + "AdditiveCommutative", "AdditiveAssociative", "AdditiveInverse", "AdditiveUnital", + "Distributive", + "Endset" ) def uncamelcase(s,separator=" "): @@ -2237,7 +2237,10 @@ def _repr_object_names_static(category, axioms): 'endsets' sage: CategoryWithAxiom._repr_object_names_static(PermutationGroups(), ["FinitelyGeneratedAsMagma"]) 'finitely generated permutation groups' + sage: CategoryWithAxiom._repr_object_names_static(Rings(), ["FinitelyGeneratedAsMagma"]) + 'finitely generated as magma rings' """ + from sage.categories.additive_magmas import AdditiveMagmas axioms = canonicalize_axioms(all_axioms,axioms) base_category = category._without_axioms(named=True) if isinstance(base_category, CategoryWithAxiom): # Smelly runtime type checking @@ -2259,10 +2262,9 @@ def _repr_object_names_static(category, axioms): elif axiom == "Endset" and "homsets" in result: # Without the space at the end to handle Homsets().Endset() result = result.replace("homsets", "endsets", 1) - elif axiom == "FinitelyGeneratedAsMagma": - from sage.categories.additive_magmas import AdditiveMagmas - if not base_category.is_subcategory(AdditiveMagmas()): - result = "finitely generated " + result + elif axiom == "FinitelyGeneratedAsMagma" and \ + not base_category.is_subcategory(AdditiveMagmas()): + result = "finitely generated " + result else: result = uncamelcase(axiom) + " " + result return result diff --git a/src/sage/categories/examples/finite_monoids.py b/src/sage/categories/examples/finite_monoids.py index fc5feb28b86..4e7575d6f90 100644 --- a/src/sage/categories/examples/finite_monoids.py +++ b/src/sage/categories/examples/finite_monoids.py @@ -29,7 +29,7 @@ class IntegerModMonoid(UniqueRepresentation, Parent): An example of a finite multiplicative monoid: the integers modulo 12 sage: S.category() - Category of finite monoids + Category of finitely generated finite monoids We conclude by running systematic tests on this monoid:: @@ -72,7 +72,7 @@ def __init__(self, n = 12): """ self.n = n - Parent.__init__(self, category = Monoids().Finite()) + Parent.__init__(self, category = Monoids().Finite().FinitelyGenerated()) def _repr_(self): r""" diff --git a/src/sage/categories/examples/semigroups.py b/src/sage/categories/examples/semigroups.py index 86e69bce22d..23ff9a59ad7 100644 --- a/src/sage/categories/examples/semigroups.py +++ b/src/sage/categories/examples/semigroups.py @@ -173,25 +173,7 @@ class FreeSemigroup(UniqueRepresentation, Parent): TESTS:: - sage: TestSuite(S).run(verbose = True) - running ._test_an_element() . . . pass - running ._test_associativity() . . . pass - running ._test_category() . . . pass - running ._test_elements() . . . - Running the test suite of self.an_element() - running ._test_category() . . . pass - running ._test_eq() . . . pass - running ._test_not_implemented_methods() . . . pass - running ._test_pickling() . . . pass - pass - running ._test_elements_eq_reflexive() . . . pass - running ._test_elements_eq_symmetric() . . . pass - running ._test_elements_eq_transitive() . . . pass - running ._test_elements_neq() . . . pass - running ._test_eq() . . . pass - running ._test_not_implemented_methods() . . . pass - running ._test_pickling() . . . pass - running ._test_some_elements() . . . pass + sage: TestSuite(S).run() """ def __init__(self, alphabet=('a','b','c','d')): r""" diff --git a/src/sage/categories/finite_coxeter_groups.py b/src/sage/categories/finite_coxeter_groups.py index 5860913e248..91e2c1db758 100644 --- a/src/sage/categories/finite_coxeter_groups.py +++ b/src/sage/categories/finite_coxeter_groups.py @@ -25,7 +25,7 @@ class FiniteCoxeterGroups(CategoryWithAxiom): sage: FiniteCoxeterGroups().super_categories() [Category of coxeter groups, Category of finite groups, - Category of finite enumerated sets] + Category of finite finitely generated semigroups] sage: G = FiniteCoxeterGroups().example() sage: G.cayley_graph(side = "right").plot() diff --git a/src/sage/categories/finite_fields.py b/src/sage/categories/finite_fields.py index c649a60821b..f36f55bb7af 100644 --- a/src/sage/categories/finite_fields.py +++ b/src/sage/categories/finite_fields.py @@ -12,6 +12,7 @@ #****************************************************************************** from sage.categories.category_with_axiom import CategoryWithAxiom +from sage.categories.enumerated_sets import EnumeratedSets class FiniteFields(CategoryWithAxiom): """ @@ -19,14 +20,16 @@ class FiniteFields(CategoryWithAxiom): EXAMPLES:: - sage: K = FiniteFields() - sage: K + sage: K = FiniteFields(); K Category of finite fields - A finite field is a finite monoid with the structure of a field:: + A finite field is a finite monoid with the structure of a field; + it is currently assumed to be enumerated:: sage: K.super_categories() - [Category of fields, Category of finite commutative rings] + [Category of fields, + Category of finite commutative rings, + Category of finite enumerated sets] Some examples of membership testing and coercion:: @@ -41,11 +44,24 @@ class FiniteFields(CategoryWithAxiom): TESTS:: - sage: TestSuite(FiniteFields()).run() - sage: FiniteFields().is_subcategory(FiniteEnumeratedSets()) + sage: K is Fields().Finite() True + sage: TestSuite(K).run() """ + def extra_super_categories(self): + r""" + Any finite field is assumed to be endowed with an enumeration. + + TESTS:: + + sage: Fields().Finite().extra_super_categories() + [Category of finite enumerated sets] + sage: FiniteFields().is_subcategory(FiniteEnumeratedSets()) + True + """ + return [EnumeratedSets().Finite()] + def __contains__(self, x): """ EXAMPLES:: diff --git a/src/sage/categories/finite_permutation_groups.py b/src/sage/categories/finite_permutation_groups.py index e5679256291..68dcfa5545f 100644 --- a/src/sage/categories/finite_permutation_groups.py +++ b/src/sage/categories/finite_permutation_groups.py @@ -9,26 +9,36 @@ # http://www.gnu.org/licenses/ #****************************************************************************** +from sage.categories.magmas import Magmas from sage.categories.category_with_axiom import CategoryWithAxiom +from sage.categories.permutation_groups import PermutationGroups class FinitePermutationGroups(CategoryWithAxiom): r""" The category of finite permutation groups, i.e. groups concretely represented as groups of permutations acting on a finite set. + It is currently assumed that any finite permutation group comes + endowed with a distinguished finite set of generators (method + ``group_generators``); this is the case for all the existing + implementations in Sage. + EXAMPLES:: - sage: FinitePermutationGroups() + sage: C = PermutationGroups().Finite(); C Category of finite permutation groups - sage: FinitePermutationGroups().super_categories() - [Category of permutation groups, Category of finite groups] + sage: C.super_categories() + [Category of permutation groups, + Category of finite groups, + Category of finite finitely generated semigroups] - sage: FinitePermutationGroups().example() + sage: C.example() Dihedral group of order 6 as a permutation group TESTS:: - sage: C = FinitePermutationGroups() + sage: C is FinitePermutationGroups() + True sage: TestSuite(C).run() sage: G = FinitePermutationGroups().example() @@ -72,6 +82,17 @@ def example(self): from sage.groups.perm_gps.permgroup_named import DihedralGroup return DihedralGroup(3) + def extra_super_categories(self): + """ + Any permutation group is assumed to be endowed with a finite set of generators. + + TESTS: + + sage: PermutationGroups().Finite().extra_super_categories() + [Category of finitely generated magmas] + """ + return [Magmas().FinitelyGenerated()] + class ParentMethods: # TODO # - Port features from MuPAD-Combinat, lib/DOMAINS/CATEGORIES/PermutationGroup.mu diff --git a/src/sage/categories/finitely_generated_semigroups.py b/src/sage/categories/finitely_generated_semigroups.py index 6b5f834c778..b9cbc7de3b2 100644 --- a/src/sage/categories/finitely_generated_semigroups.py +++ b/src/sage/categories/finitely_generated_semigroups.py @@ -8,6 +8,7 @@ # http://www.gnu.org/licenses/ #****************************************************************************** +import itertools from sage.misc.abstract_method import abstract_method from sage.misc.cachefunc import cached_method from sage.categories.category_with_axiom import CategoryWithAxiom @@ -35,7 +36,7 @@ class FinitelyGeneratedSemigroups(CategoryWithAxiom): sage: sorted(C.axioms()) ['Associative', 'FinitelyGeneratedAsMagma'] sage: C.example() - An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd') + An example of a semigroup: the free semigroup generated by ('a', 'b', 'c', 'd') TESTS:: @@ -59,7 +60,7 @@ def extra_super_categories(self): return [EnumeratedSets()] def example(self): - """ + r""" EXAMPLES:: sage: Semigroups().FinitelyGenerated().example() @@ -71,7 +72,7 @@ class ParentMethods: @abstract_method def semigroup_generators(self): - """ + r""" Return distinguished semigroup generators for ``self``. OUTPUT: a finite family @@ -122,7 +123,7 @@ def succ_generators(self, side="twosided"): return lambda x: (tuple(g * x for g in generators) if left else ()) + (tuple(x * g for g in generators) if right else ()) def __iter__(self): - """ + r""" Return an iterator over the elements of ``self``. This brute force implementation recursively multiplies @@ -183,18 +184,22 @@ def ideal(self, gens, side="twosided"): from sage.combinat.backtrack import TransitiveIdeal return TransitiveIdeal(self.succ_generators(side = side), gens) + class Finite(CategoryWithAxiom): - def some_elements(self): - r""" - Return an iterable containing some elements of the semigroup. + class ParentMethods: + def some_elements(self): + r""" + Return an iterable containing some elements of the semigroup. - EXAMPLES:: + OUTPUT: the ten first elements of the semigroup, if they exist. - sage: S = FiniteSemigroups().example(alphabet=('x','y')) - sage: S.some_elements() - An example of a finite semigroup: the left regular band generated by ('x', 'y') - sage: list(S) - ['y', 'x', 'xy', 'yx'] - """ - return self + EXAMPLES:: + sage: S = FiniteSemigroups().example(alphabet=('x','y')) + sage: S.some_elements() + ['y', 'x', 'xy', 'yx'] + sage: S = FiniteSemigroups().example(alphabet=('x','y','z')) + sage: S.some_elements() + ['y', 'x', 'xy', 'xyz', 'xz', 'yx', 'yxz', 'xzy', 'yz', 'z'] + """ + return list(itertools.islice(self, 10)) diff --git a/src/sage/categories/integral_domains.py b/src/sage/categories/integral_domains.py index 3312a529135..2587f37b221 100644 --- a/src/sage/categories/integral_domains.py +++ b/src/sage/categories/integral_domains.py @@ -81,6 +81,7 @@ def _contains_helper(cls): Join of Category of finite commutative rings and Category of subquotients of monoids and Category of quotients of semigroups + and Category of finite enumerated sets sage: ID = IntegralDomains() sage: ID._contains_helper(R) False diff --git a/src/sage/categories/unique_factorization_domains.py b/src/sage/categories/unique_factorization_domains.py index 2d70236139b..50c6fd107a4 100644 --- a/src/sage/categories/unique_factorization_domains.py +++ b/src/sage/categories/unique_factorization_domains.py @@ -98,8 +98,9 @@ def _contains_helper(cls): sage: R = Zmod(7) sage: R.category() Join of Category of finite commutative rings - and Category of subquotients of monoids - and Category of quotients of semigroups + and Category of subquotients of monoids + and Category of quotients of semigroups + and Category of finite enumerated sets sage: ID = UniqueFactorizationDomains() sage: ID._contains_helper(R) False From 839200e376b595f7bfe3247c55fc31adf0693ef3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= Date: Fri, 20 Mar 2015 01:09:54 -0700 Subject: [PATCH 5/5] 8678: More doctest updates. Should almost pass all tests. --- src/doc/en/thematic_tutorials/coercion_and_categories.rst | 2 +- src/sage/misc/c3_controlled.pyx | 6 ++++-- src/sage/quivers/path_semigroup.py | 2 +- src/sage/rings/finite_rings/integer_mod_ring.py | 4 ++++ src/sage/rings/ring.pyx | 7 ++++--- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/doc/en/thematic_tutorials/coercion_and_categories.rst b/src/doc/en/thematic_tutorials/coercion_and_categories.rst index 2a683de7d17..2378707cecb 100644 --- a/src/doc/en/thematic_tutorials/coercion_and_categories.rst +++ b/src/doc/en/thematic_tutorials/coercion_and_categories.rst @@ -461,7 +461,7 @@ And indeed, ``MS2`` has *more* methods than ``MS1``:: sage: len([s for s in dir(MS1) if inspect.ismethod(getattr(MS1,s,None))]) 57 sage: len([s for s in dir(MS2) if inspect.ismethod(getattr(MS2,s,None))]) - 82 + 83 This is because the class of ``MS2`` also inherits from the parent class for algebras:: diff --git a/src/sage/misc/c3_controlled.pyx b/src/sage/misc/c3_controlled.pyx index 51214e77bb3..fcee4db6726 100644 --- a/src/sage/misc/c3_controlled.pyx +++ b/src/sage/misc/c3_controlled.pyx @@ -316,9 +316,9 @@ For a typical category, few bases, if any, need to be added to force sage: x.mro == x.mro_standard False sage: x.all_bases_len() - 66 + 67 sage: x.all_bases_controlled_len() - 69 + 70 sage: C = GradedHopfAlgebrasWithBasis(QQ) sage: x = HierarchyElement(C, attrcall("super_categories"), attrgetter("_cmp_key")) @@ -338,9 +338,11 @@ for any that requires the addition of some bases:: ....: if len(C._super_categories_for_classes) != len(C.super_categories())], ....: key=str) [Category of affine weyl groups, + Category of coxeter groups, Category of fields, Category of finite dimensional algebras with basis over Rational Field, Category of finite dimensional hopf algebras with basis over Rational Field, + Category of finite permutation groups, Category of graded hopf algebras with basis over Rational Field, Category of hopf algebras with basis over Rational Field] diff --git a/src/sage/quivers/path_semigroup.py b/src/sage/quivers/path_semigroup.py index 10a67a4431e..be2253c3373 100644 --- a/src/sage/quivers/path_semigroup.py +++ b/src/sage/quivers/path_semigroup.py @@ -57,7 +57,7 @@ class PathSemigroup(UniqueRepresentation, Parent): sage: S.gens() (e_1, e_2, e_3, a, b, c, d) sage: S.category() - Category of finite semigroups + Join of Category of finite semigroups and Category of finite enumerated sets In the test suite, we skip the associativity test, as in this example the paths used for testing can't be concatenated:: diff --git a/src/sage/rings/finite_rings/integer_mod_ring.py b/src/sage/rings/finite_rings/integer_mod_ring.py index 913503c1aed..396990fae07 100644 --- a/src/sage/rings/finite_rings/integer_mod_ring.py +++ b/src/sage/rings/finite_rings/integer_mod_ring.py @@ -148,6 +148,7 @@ class IntegerModFactory(UniqueFactory): Join of Category of finite commutative rings and Category of subquotients of monoids and Category of quotients of semigroups + and Category of finite enumerated sets sage: R in Fields() True sage: R.category() @@ -321,6 +322,7 @@ class IntegerModRing_generic(quotient_ring.QuotientRing_generic): Join of Category of finite commutative rings and Category of subquotients of monoids and Category of quotients of semigroups + and Category of finite enumerated sets sage: FF.is_field() True sage: FF.characteristic() @@ -380,6 +382,7 @@ class IntegerModRing_generic(quotient_ring.QuotientRing_generic): Join of Category of finite commutative rings and Category of subquotients of monoids and Category of quotients of semigroups + and Category of finite enumerated sets sage: Z16.is_field() False sage: Z16.order() @@ -716,6 +719,7 @@ def is_field(self, proof=None): Join of Category of finite commutative rings and Category of subquotients of monoids and Category of quotients of semigroups + and Category of finite enumerated sets sage: R.is_field() True sage: R.category() diff --git a/src/sage/rings/ring.pyx b/src/sage/rings/ring.pyx index e606c4e05f5..0be8dfe9539 100644 --- a/src/sage/rings/ring.pyx +++ b/src/sage/rings/ring.pyx @@ -262,9 +262,10 @@ cdef class Ring(ParentWithGens): sage: I.base_ring() is I True sage: I.category() - Join of Category of finite commutative rings and - Category of subquotients of monoids and - Category of quotients of semigroups + Join of Category of finite commutative rings + and Category of subquotients of monoids + and Category of quotients of semigroups + and Category of finite enumerated sets """ # Defining a category method is deprecated for parents. # For rings, however, it is strictly needed that self.category()