Skip to content

Commit

Permalink
Trac #17160: Finitely generated axiom for (mutiplicative) magmas, sem…
Browse files Browse the repository at this point in the history
…igroups, monoids, groups

This introduce an axiom FinitelyGeneratedAsMagma, as well as related
categories with axioms for magmas, semigroups and groups::
{{{
    sage: Groups().FinitelyGeneratedAsMagma()
    Category of finitely generated groups
}}}
For ease of notations, when there is no ambiguity, one can do::
{{{
    sage: Groups().FinitelyGenerated()
    Category of finitely generated groups
}}}

One motivation for this change (for #8678) is that finite semigroups
in Sage used to be automatically endowed with an `EnumeratedSets`
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.

Instead, finite semigroups that provide a distinguished finite set of
generators with `semigroup_generators` should now explicitly declare
themselves in the category of `FinitelyGeneratedSemigroups`:
{{{
    sage: Semigroups().FinitelyGenerated()
    Category of finitely generated semigroups
}}}
This is a backward incompatible change.

TODO:
- Use the occasion to migrate TransitiveIdeal to
RecursivelyEnumeratedSet

URL: http://trac.sagemath.org/17160
Reported by: nthiery
Ticket author(s): Nicolas M. Thiéry
Reviewer(s): Travis Scrimshaw
  • Loading branch information
Release Manager authored and vbraun committed Apr 14, 2015
2 parents 8019549 + 19ceb81 commit 4922c8c
Show file tree
Hide file tree
Showing 24 changed files with 545 additions and 218 deletions.
2 changes: 1 addition & 1 deletion src/doc/en/thematic_tutorials/coercion_and_categories.rst
Expand Up @@ -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::
Expand Down
2 changes: 1 addition & 1 deletion src/sage/categories/category.py
Expand Up @@ -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 310 graphics primitives
Graphics object consisting of ... graphics primitives
"""
from sage import graphs
if categories is None:
Expand Down
43 changes: 27 additions & 16 deletions src/sage/categories/category_with_axiom.py
Expand Up @@ -1675,13 +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",
"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=" "):
Expand Down Expand Up @@ -2129,25 +2130,27 @@ 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::
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
Expand Down Expand Up @@ -2232,7 +2235,12 @@ 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'
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
Expand All @@ -2254,6 +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" and \
not base_category.is_subcategory(AdditiveMagmas()):
result = "finitely generated " + result
else:
result = uncamelcase(axiom) + " " + result
return result
Expand Down
6 changes: 3 additions & 3 deletions src/sage/categories/coxeter_groups.py
Expand Up @@ -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}
Expand Down Expand Up @@ -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')
Expand Down
6 changes: 3 additions & 3 deletions src/sage/categories/examples/finite_monoids.py
Expand Up @@ -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

Expand All @@ -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::
Expand Down Expand Up @@ -72,7 +72,7 @@ def __init__(self, n = 12):
"""
self.n = n
Parent.__init__(self, category = FiniteMonoids())
Parent.__init__(self, category = Monoids().Finite().FinitelyGenerated())

def _repr_(self):
r"""
Expand Down
4 changes: 2 additions & 2 deletions src/sage/categories/examples/finite_semigroups.py
Expand Up @@ -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
Expand Down Expand Up @@ -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"""
Expand Down
22 changes: 2 additions & 20 deletions src/sage/categories/examples/semigroups.py
Expand Up @@ -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"""
Expand All @@ -214,7 +196,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"""
Expand Down
4 changes: 3 additions & 1 deletion src/sage/categories/finite_coxeter_groups.py
Expand Up @@ -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 finitely generated semigroups]
sage: G = FiniteCoxeterGroups().example()
sage: G.cayley_graph(side = "right").plot()
Expand Down
28 changes: 22 additions & 6 deletions src/sage/categories/finite_fields.py
Expand Up @@ -12,21 +12,24 @@
#******************************************************************************

from sage.categories.category_with_axiom import CategoryWithAxiom
from sage.categories.enumerated_sets import EnumeratedSets

class FiniteFields(CategoryWithAxiom):
"""
The category of finite fields.
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::
Expand All @@ -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::
Expand Down
31 changes: 26 additions & 5 deletions src/sage/categories/finite_permutation_groups.py
Expand Up @@ -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()
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 4922c8c

Please sign in to comment.