Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News Sign UpSign In
| Download
Views: 162
Kernel: SageMath (stable)

Infrastructure for generic code in Sage: categories, axioms, constructions

from sage.categories.category_with_axiom import CategoryWithAxiom from sage.categories.cartesian_product import CartesianProductsCategory

Parents, Elements, and generic code, the plain Python way

class SemigroupElement: def __pow__(self, k): assert k==8 self = self * self self = self * self self = self * self return self class Stroumph(element): def __init__(self, name): self._name = name def __repr__(self): return self._name def __mul__(self, other): return other def sing(self): print "I sing"
s = Stroumph("Stroumph coquet"); s
t = Stroumph("Stroumph costaud"); t
s*t
s^12
s^8
class Semigroup: def cayley_graph(): pass # stuff about generators, ... class BandOfStroumphs(Semigroup): def __iter__(self): yield Stroumph("Stroumph coquet") yield Stroumph("Stroumph costaud") yield Stroumph("Grand stroumph")
for x in BandOfStroumphs(): print x

A hierarchy of abstract classes the usual way

class Set(object): """Methods for sets""" class SetElement(object): """Methods for elements of sets""" class SetMorphism(object): """Methods for set morphisms""" class Magma(Set): """Methods for magmas""" class MagmaElement(SetElement): """Methods for elements of magmas""" class Semigroup(Magma): """Methods for semigroups""" class SemigroupElement(MagmaElement): """Methods for elements of semigroups""" def __pow__(self, k): pass

Refactoring as a category

class MySemigroups(Category): def super_categories(self): # Mathematical information return [Magmas()] class ParentMethods: # This is a mix-in """Methods for semigroups""" class ElementMethods: """Methods for semigroup elements""" def __pow__(self, k): pass class MorphismMethods: """Methods for semigroup morphisms"""
MySemigroups().super_categories()
cls = MySemigroups().parent_class
cls.mro()

A complete Parent, written the Sage way

class BandOfStroumphs(Parent): def __init__(self): category = Semigroups() & EnumeratedSets().Finite() Parent.__init__(self, category=category) def semigroup_generators(self): return Family(list(self)) def __iter__(self): yield self("Stroumph coquet") yield self("Stroumph costaud") yield self("Grand stroumph") class Element(ElementWrapper): def _mul_(self, other): return other
B = BandOfStroumphs()
B("Stroumph coquet")
B.list()
s = B.an_element(); s
B.cayley_graph()
TestSuite(B).run(verbose=True, skip="_test_pickling")
B.category()
B.categories()
B.__class__.mro()

Side benefits of having categories as first class objects

C = Semigroups()
C
S = C.example()
S??
C.axioms()
C.structure()
C = Fields(); C
C.structure()
C.axioms()
C = HopfAlgebras(QQ).Graded().Connected().Commutative().WithBasis()
C.structure()
C.axioms()

Operations on categories

  • Adding an axiom

Magmas().Commutative()
Rings().Commutative()
  • Intersection

Groups() & Sets().Finite()
C = (AdditiveMagmas() & Magmas()).Distributive(); C
C = C.AdditiveAssociative().AdditiveUnital().AdditiveCommutative(); C
C = C.Associative().Unital(); C
C = C.AdditiveInverse(); C
C = C.Division(); C
C = C.Finite(); C
C.axioms()
C.structure()