#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, | 478de48553d203516cddb47e0cb89c34ccc210ee
#10193, #12895, #14516, #14722, | Stopgaps:
#13589, #14471, #15069, #15094, |
#11688, #13394, #15150, #15506 |
-------------------------------------+-------------------------------------
Comment (by SimonKing):
Replying to [comment:330 nthiery]:
> - We should leave the database discussion aside for now. It's just
> going to pollute that thread which is already too long.
+1. I said that we should get the correct logic into the code right now.
But using a "proper" database is something for the future.
> - Nils is right in that the category *code* is indeed structured as a
> tree.
That's why I said "this is what large parts of Nicolas' model do". But:
> Of course, the inheritance diagram between the categories
> forms an acyclic digraph.
You explained to me that the categories being arranged in something that
is not a tree gave you some headache. See
"`DivisionRings().Finite()==Fields().Finite()`".
=
> - The guessing is just about allowing for the shorthand
> {{{FiniteDimensionalAlgebras(QQ) ->
Algebras(QQ).FiniteDimensional()}}}
>
> Those shorthands are mostly used interactively or for backward
> compatibility.
And, as I have pointed out above, only 5 shorthands are used when Sage
starts.
> - In case there is a typo in the class name, you get an explicit error
> the first time you try to create the category. So, assuming the
> black magic is now reasonably robust (I believe so, but ...), the
> issues should only pop up when creating a new category, and thus be
> well localized and easy to debug.
+1. I think it is important that the consistency tests take place, and I
think they guarantee robustness of the code.
I can't check the code right now; but didn't one of your last commits
remove the "assert" statement that has originally triggered the recursion?
I think after my commit, the assertion would not trigger a recursion, and
it would perhaps be better to keep it in---unless you can point out that
an equivalent consistency check is happening anyway.
> - By setting explicitly _base_category_and_axiom, you are putting in
> information which is redundant with the reverse link from the base
> category. For the above example, here are the two pieces of
> information:
>
> In Algebras:
> {{{
> FiniteDimensional =
LazyImport('sage.categories.finite_dimensional_algebras',
'FiniteDimensionalAlgebras')
> }}}
>
> In FiniteDimensionalAlgebras:
> {{{
> _base_category_and_axiom = [Algebras, "FiniteDimensional"]
> }}}
>
> This violates the single point of truth and opens the door for
> inconsistent information.
In a digraph, it is useful that any node knows both the in-arrows and the
out-arrows. So, the data structure should be so that both
`Algebras.FiniteDimensional` and
`FiniteDimensionalAlgebras._base_category_and_axiom` are available (and of
course this is what your code provides.
However, it would indeed be nice to have a single point of truth. I
believe
that this single point of truth should (in FUTURE!!) not be the naming
scheme,
but a database. You'd register the fact that `MyNiceCategory` is obtained
from `MyUglyCategory` by adding the axiom `Makeup` in the database, and
the
database would automatically add the relevant information both to
`MyNiceCategory` and to `MyUglyCategory`.
> - The act of not specifying _base_category_and_axiom is actually a
> statement: ``this category is following the naming standards''. This
> statement is used in the name building for category objects (see
> _repr_object_names). Getting nice names for category objects is an
> important feature that we will have to support one way or the other.
+1. I'd find it annoying to override `_repr_object_names` whenever
implementing a new category.
> Altogether, I really don't like adding this redundant information
> everywhere. It feels to me as spreading dirt over my carefully crafted
> idioms :-)
I agree that it would be annoying to add the same info in two places.
> If instead you have a protocol in mind that avoids this redundant
> information without doing name mangling and while leaving the same
> flexibility in terms of code organization (in particular supporting to
> implement a category with axioms either as a nested class or in a
> separate file, typically lazy imported), I am all ear!
Let's try...
Consider the `DivisionRings().Finite()==Fields().Finite()==FiniteFields()`
example. My Sage version is on a different branch now, but I hope it is
correct
that `FiniteFields._base_category_class_and_axiom==(Fields, 'Finite')`.
Hence, `FiniteFields()` knows one possible way of being
constructed. The other possible way is encoded in
`DivisionRings.Finite_extra_super_categories`. In addition to that, we
have
`Fields.Finite=FiniteFields` (lazily imported).
It seems evident to me that each category-with-axiom should know one
(namely
the default) way of construction, as encoded in
`_base_category_class_and_axiom`---either hardcoded or encoded in the
class
name. In the example, mathematics forces us to encode a second way of
construction, namely `DivisionRings.Finite_extra_super_categories`.
However,
why should we additionally hardcode `Fields.Finite=FiniteFields`, as this
information is already encoded in `FiniteFields`?
Couldn't a database do the job? If I am not mistaken, there are databases
that
can not only store items (here: Category classes), but also relations
between
items (here: Construction of a category by applying an axiom). Hence, the
database knows the default construction of `FiniteFields()` (in
particular, it
knows that it involves `Fields()`), and it knows an additional
construction of
`FiniteFields()` (namely starting with `DivisionRings()`).
Registering default and additional constructions into the database would
be
your "single point of truth".
It would be possible to have the database act as a metaclass for
`CategoryWithAxioms`. Hence, ''during creation of a category class
`cls`'',
the database would be called, and could certainly be made to look up
- the default construction of `cls`, registering it in
`cls._base_category_class_and_axiom`
- any known construction starting with `cls`, registering it in lazily
imported class attributes (similar to `Fields.Finite` and some attribute
of `DivisionRings`).
To summarise my suggestion (again: For the future, not for now):
- Have a database that acts as metaclass of `CategoryWithAxiom`
- As a single point of truth, constructions are registered in the
database.
- Of course, the database is stored, and loaded at startup of Sage. Note
that
the database knows where to find the category classes---it is ''not''
the case
that loading the database implies loading all possible category classes
during startup!!
- When being asked to return a category class `cls`, the metaclass (=the
database) would handle the incoming and outgoing constructions of
`cls`---lazily.
- It is possible to register further constructions into the database in an
interactive session.
So, we'd have flexibility/interactivity, no name mangling, lazy imports,
and a
single point of truth.
--
Ticket URL: <http://trac.sagemath.org/ticket/10963#comment:332>
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.