#10963: More functorial constructions
-------------------------------------------------------------------------+--
Reporter: nthiery |
Owner: stumpc5
Type: enhancement |
Status: needs_work
Priority: major |
Milestone:
Component: categories |
Resolution:
Keywords: |
Work issues: Reduce startup time by 5%. Avoid "recursion depth exceeded
(ignored)". Trivial doctest fixes.
Report Upstream: N/A |
Reviewers: Simon King
Authors: Nicolas M. ThiƩry |
Merged in:
Dependencies: #11224, #8327, #10193, #12895, #14516, #14722, #13589 |
Stopgaps:
-------------------------------------------------------------------------+--
Comment (by SimonKing):
If I understand correctly, the reason for creating a `JoinCategory` is to
get the correct supercategories. But there are alternative ways to get the
supercategories right. I could imagine to use a dynamic class instead. So,
the aim of this post is to present an alternative approach that avoids
joins.
If C is a category and one wants to have `C.MyAxiom()`, then I suggest to
create a dynamic class `cls` out of `C.__class__` (and perhaps also using
the class `C.MyAxiom`?), and set a ''class'' attribute `cls._used_axioms`
which is a (frozen) set formed by `C.__class__._used_axioms` and
`"MyAxiom"`.
Note: The order in which the axioms are given should not matter. Hence,
the way of caching the dynamic class should be: By a class that has no
axioms, and by `C.__class__._used_axioms`.
We would like to call `cls` with the same `__init__` arguments that were
used for creating `C`. So, how to get the init data? No problem, since `C`
uses `UniqueRepresentation`!. For example:
{{{
sage: C = Bimodules(ZZ, QQ)
sage: C._reduction
(sage.categories.bimodules.Bimodules, (Integer Ring, Rational Field), {})
}}}
So, `C.MyAxiom()` would eventually do something like this
{{{
cls = dynamic_class("MyAxiom"+C.__class__.__name__, (C.__class__,
C.MyAxiom), C.__class__, <take care of caching>)
return cls(*(C._reduction[1][0]), **(C._reduction[1][1]))
}}}
Note that by way of caching the dynamic class, I guess the above would
automatically cover the corner case that `C.__class__._used_axioms`
contains `"MyAxiom"`. Namely, in this case, `cls is C.__class__` by means
of caching the dynamic class, and then `cls(*..., **...)` coincides with
C, since it is a `UniqueRepresentation`.
By means of explicitly overloading the cache of the dynamic class, one
could even ensure that `DivisionRings.Finite()` returns `Fields.Finite()`,
I guess.
Let's denote `C2=C.MyAxiom()`. And then, the critical question is: How to
determine the super categories of `C2`?
I guess for each axiom `A in C2.__class__._used_axioms`, we want to return
`C2._without_axiom(A)`, and we want to return `D._with_axiom(A)` for all
`D` is in `C2._without_axiom(A).super_categories()`, of course removing
duplicates.
So, there only remains to answer: What is `C2._without_axiom(A)`?
Again, we can use `C2._reduction` to get the input data, but how to get
the class of `D=C2._without_axiom(A)`? Note that `C2` might have several
axioms, and we do ''not'' order the axioms.
However, we know what `D.__class__._used_axioms` is supposed to look like:
It is `C2.__class__._used_axiom.difference("MyAxiom")`.
Thus, we get something like this:
{{{
@cached_method
def _without_axiom(self, axiom):
if axiom not in self.__class__._used_axioms:
<raise some error>
new_axioms = self.__class__._used_axioms.difference([axiom])
for cls in self.__class__.__mro__:
if getattr(cls, "_used_axioms", None) == new_axioms:
break
if cls is object:
<raise some error>
return cls(*(self._reduction[1][0]), **(self._reduction[1][1]))
}}}
Do you think this would make sense?
--
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/10963#comment:44>
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.