#10963: More functorial constructions
-------------------------------------+-------------------------------------
       Reporter:  nthiery            |        Owner:  stumpc5
           Type:  enhancement        |       Status:  needs_review
       Priority:  major              |    Milestone:  sage-6.1
      Component:  categories         |   Resolution:
       Keywords:  days54             |    Merged in:
        Authors:  Nicolas M. Thiéry  |    Reviewers:  Simon King, Frédéric
Report Upstream:  N/A                |  Chapoton
         Branch:                     |  Work issues:
  public/ticket/10963                |       Commit:
   Dependencies:  #11224, #8327,     |  eb7b486c6fecac296052f980788e15e2ad1b59e4
  #10193, #12895, #14516, #14722,    |     Stopgaps:
  #13589, #14471, #15069, #15094,    |
  #11688, #13394, #15150, #15506     |
-------------------------------------+-------------------------------------

Comment (by SimonKing):

 Replying to [comment:427 nthiery]:
 > Replying to [comment:425 SimonKing]:
 > > I have attached [attachment:consistency.py],

 ... and updated it now, because of some previous typos.

 > > which provides routines to check whether Nicolas' local choice of
 default constructions for categories with axiom is globally consistent.
 >
 > Fun :-)

 Agreed, but I didn't tell how to use it. So, here it goes: Start sage and
 attach the file. Then:
 {{{
 sage: Bad, I,S,Rel = TestCategoryModel()
 Import all category classes
 Create boolean polynomial ring with 168 generators
 Collect all available axiomatic constructions
  => Found 277 constructions for 256 category classes

 8 cases of alternative axiomatic constructions
 Testing that default constructions are compatible
 Bad: <class 'sage.categories.category_with_axiom.Unital.Blue'> = <class
 'sage.categories.category_with_axiom.Blahs.Unital'>.Blue
 expected default Blahs*Unital
 got Blahs*Blue*Unital
 Basis is given by Blahs*Unital
 but Blahs*Blue*Unital is no standard monomial
 }}}
 What I find very strange: Apparently the number of alternative axiomatic
 constructions is not well-defined! Namely yesterday I got different
 figures.

 To be investigated...

 Anyway, we find:
 {{{
 sage: Bad
 [(sage.categories.category_with_axiom.Unital.Blue,
   Blahs*Blue*Unital,
   Blahs*Unital)]
 }}}
 which means that `Blahs.Unital.Blue` should coincide with `Blahs.Unital`,
 which makes perfect sense since
 {{{
 sage: Blahs().Blue() is Blahs().Unital()
 True
 }}}
 and thus `Blahs().Unital().Blue()` should be the same as
 `Blahs().Blue().Blue()`, thus the same as `Blahs().Blue()`, which is
 `Blahs().Unital()`. However, we find
 {{{
 sage: Blahs().Unital().Blue() is Blahs().Blue()
 False
 }}}
 This is a bug, which my test function correctly detects!

 Moreover, we have
 {{{
 sage: len(I)
 121
 }}}
 which means that 121 category classes do not give a reasonable answer when
 asked to return an instance.

 Finally,
 {{{
 sage: for rel in Rel.groebner_basis():
 ....:    print rel
 ....:
 
Blahs*DistributiveMagmasAndAdditiveMagmas*Flying*Facade*Finite*Commutative*Associative*Division*NoZeroDivisors*AdditiveCommutative*AdditiveAssociative*AdditiveInverse*AdditiveUnital
 +
 
Blahs*DistributiveMagmasAndAdditiveMagmas*Flying*Finite*Commutative*Associative*Inverse*Division*NoZeroDivisors*AdditiveCommutative*AdditiveAssociative*AdditiveInverse*AdditiveUnital
 
Blahs*DistributiveMagmasAndAdditiveMagmas*Flying*Finite*Infinite*Commutative*Associative*Division*NoZeroDivisors*AdditiveCommutative*AdditiveAssociative*AdditiveInverse*AdditiveUnital
 +
 
Blahs*DistributiveMagmasAndAdditiveMagmas*Flying*Finite*Commutative*Associative*Inverse*Division*NoZeroDivisors*AdditiveCommutative*AdditiveAssociative*AdditiveInverse*AdditiveUnital
 Blahs*Flying*Unital + Blahs*Flying
 Blahs*Blue + Blahs*Unital
 TestObjects*Blue + TestObjects*Unital
 TestObjectsOverBaseRing*Blue + TestObjectsOverBaseRing*Unital
 
DistributiveMagmasAndAdditiveMagmas*Facade*Finite*Commutative*Associative*Unital*Division*NoZeroDivisors*AdditiveCommutative*AdditiveAssociative*AdditiveInverse*AdditiveUnital
 +
 
DistributiveMagmasAndAdditiveMagmas*Finite*Commutative*Associative*Inverse*Unital*Division*NoZeroDivisors*AdditiveCommutative*AdditiveAssociative*AdditiveInverse*AdditiveUnital
 
DistributiveMagmasAndAdditiveMagmas*Finite*Infinite*Commutative*Associative*Unital*Division*NoZeroDivisors*AdditiveCommutative*AdditiveAssociative*AdditiveInverse*AdditiveUnital
 +
 
DistributiveMagmasAndAdditiveMagmas*Finite*Commutative*Associative*Inverse*Unital*Division*NoZeroDivisors*AdditiveCommutative*AdditiveAssociative*AdditiveInverse*AdditiveUnital
 }}}

 As we can see, most of the relations come from Nicolas' examples, but not
 from real mathematical theorems.

 One thing really irritates me, though. Yesterday, I also saw relations
 {{{
 Modules*VectorSpaces==VectorSpaces
 }}}
 which makes sense: The join of the module category over a base ring and
 the vector space category over the same base ring should be the vector
 space category, simply since in this case the module category coincides
 with the vector space category.

 So, why am I not seeing the same relations today??

 > > In this case, I try `C.an_instance().A().__class__.__base__` to get
 the class that is used to implement the result of applying axiom A to
 instances of category C.
 >
 > I believe that's the right approach for this need.

 OK, but then we'd like to have 121 more implementations of
 `an_instance()`...

 > You are taking some term order here, probably based on some order of
 > the axioms, right?

 Yes. That's another point that I should change. `BooleanPolynomialRing`
 apparently uses a lexicographic ordering by default. What I wanted was a
 degrevlex ordering: A construction involving fewer axioms should be
 preferred over a construction involving many axioms.

 Anyway. The generators of the ring correspond to
 1. All category classes that are not category-with-axiom, sorted (I don't
 know how Python sorts them).
 2. All axioms, in the same order as given in
 `sage.categories.category_with_axiom.all_axioms`.

 Is the sorting of category classes perhaps depending on the memory
 addresses of the classes? This would explain why I get different results
 on different runs.

 > >    It is thus no surprise that my routine complains here. I won't
 check now whether this example is ''supposed'' to demonstrate an illegal
 construction.
 >
 > Yup. This class demonstrates a possibly desirable but non-implemented
 > feature. See Blahs.Blue_extra_super_categories.

 Well, the reason for the complaint is that the axioms `Blue` and `Unital`
 do not commute. But applying axioms ''has'' to commute. Hence, the feature
 is not "desirable but non-implemented", but it is "mathematically
 illegal".

 > Question: what about turning the problem upside down, and write a
 > C._test_???  method that checks that everything is consistent within
 > the context of the super categories of ``C`` (and possibly all axiom
 > categories you can derive from those, though I guess it's not
 necessary)?

 Consistency is a global property. Hence, I think there is no way around to
 consider ''all'' category classes at once when testing consistency. It is
 clear that this must not happen during startup. Hence, as it is, the
 consistency test is a test that may be a tool for a developer wanting to
 add a new category.

 However, turning things "upside down" is what I want. But I mean a
 different thing.

 Currently, my functions import all categories, extract from it the local
 information that define the category-with-axiom lattice, and then uses
 commutative algebra to assert that the local information gives a globally
 consistent picture.

 Turning this upside down would mean:
 - First of all, create a Boolean polynomial ring, whose generators
 correspond to the list of basic categories and axioms available in Sage
 (this list may grow). Fix a reasonable monomial ordering, best would be a
 degree ordering.
 - Create an ideal in this ring, whose generators are given by mathematical
 results such as Wedderburn's. Compute the Gröbner basis. This Gröbner
 basis could be computed once, stored, and then loaded at Sage startup
 time. Hence, Sage startup would not suffer from an expensive Gröbner basis
 computation, it only is loading a fixed result.
 - When creating a category class, the Gröbner basis helps to provide this
 class with the available axiomatic constructions (this is what you do with
 lazy imports and with `SubcategoryMethods`), and also determines a default
 construction for this class (this is the `_base_category_class_and_axiom`
 attribute). Commutative algebra ensures consistency of this local
 information. This would be implemented by a meta-class for `Category`.

 This would be my approach to add more rigour to your category-with-axiom
 model, and replace handmade choices of default constructions by something
 that scales better.

 > Since every category class is supposed to be TestSuit'ed, we should
 > cover all categories this way. Do you think we would get a global
 > enough view?

 No.

 > And I believe that I have no merit in that. I haven't proven it
 > formally yet, but I am pretty much convinced that as long as the two
 > following specifications (which I have now described in detail in the
 > documentation) are satisfied:
 >
 > - Tree structure on the classes

 Which I totally don't like!

 Namely, as a consequence, you need to treat `DivisionRings.Finite`
 different from `Fields.Finite`: The latter is a (lazily imported) class
 stored as a class attribute, the former is a cached method obtained from
 Set() and will ''only'' work on instances, not on classes. This asymmetry
 is unfortunate, and I think using a metaclass that works with standard
 monomials corresponding to default axiomatic constructions is a nice way
 to make the implementation symmetric.

 You see, if a developer wants to implement a new mathematical theorem on
 equality of two axiomatic constructions, then your model is a bit awkward:
 (S)he needs to pick one of the constructions to become a cached method on
 instances, while the other stays a class attribute. But which of them?
 Doing the wrong choice would mean subtle inconsistencies resulting in
 difficult to find bugs.

 It seems obvious to me that we want that all axiomatic constructions can
 be implemented in the same way, and that there is no danger of wrong
 choices, because all choices will be made automatic by a method that is
 proven to yield well-defined results (namely: Computing normal forms using
 Gröbner bases).

 In other words: There is a tree structure in the set of standard
 monomials. We shouldn't force the developer to put the same tree structure
 ''manually'' into the class definitions.

 > I also believe we don't event need to impose a term order, but that I
 > have to think about.

 I think we at least want a degree order, so that applying three axioms
 will always be preferred over applying four axioms to get the same result.

 > On the other hand, I believe that there is at this point no need to
 > have a tool for deciding where to put the axiom category. So far I
 > have always been putting the axiom category where mathematics told me
 > to put it.

 Well, in the case of `Blahs.Blue.Unital`, you did wrong. I don't know if
 it was on purpose that you did wrong, but your example shows something
 that should never happen, namely axioms that do not commute.

--
Ticket URL: <http://trac.sagemath.org/ticket/10963#comment:429>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica, 
and MATLAB

-- 
You received this message because you are subscribed to the Google Groups 
"sage-trac" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sage-trac.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to