Sage: Ticket #14084: Wrong domain of the fraction field construction functor
https://trac.sagemath.org/ticket/14084
<p>
The construction functor for fraction fields pretends that it takes any ring as input:
</p>
<pre class="wiki">sage: Fract,R = QQ.construction()
sage: Fract.domain()
Category of rings
sage: Fract.codomain()
Category of fields
</pre><p>
But of course that's wrong:
</p>
<pre class="wiki">sage: Fract(ZZ.quo(15))
Traceback (most recent call last):
...
TypeError: self must be an integral domain.
</pre><p>
Hence, it would be better to declare right away that its domain is the category of integral domains.
</p>
en-usSagehttps://trac.sagemath.org/chrome/site/logo_sagemath_trac.png
https://trac.sagemath.org/ticket/14084
Trac 1.1.6SimonKingFri, 08 Feb 2013 20:13:18 GMT
https://trac.sagemath.org/ticket/14084#comment:1
https://trac.sagemath.org/ticket/14084#comment:1
<p>
First two problems:
</p>
<pre class="wiki">sage: Zp(7) in IntegralDomains()
False
sage: ZZ[['x']] in IntegralDomains()
False
</pre>
TicketSimonKingFri, 08 Feb 2013 20:15:16 GMT
https://trac.sagemath.org/ticket/14084#comment:2
https://trac.sagemath.org/ticket/14084#comment:2
<p>
And similarly:
</p>
<pre class="wiki">sage: Qp(7).category()
Category of commutative rings
sage: Qp(7).is_field()
True
</pre>
TicketnbruinFri, 08 Feb 2013 20:41:20 GMT
https://trac.sagemath.org/ticket/14084#comment:3
https://trac.sagemath.org/ticket/14084#comment:3
<p>
... but
</p>
<pre class="wiki">sage: k=Qp(7)
sage: k.category()
Category of commutative rings
sage: k in Fields()
True
sage: k.category()
Category of fields
</pre><p>
which is a little uncomfortable in its own right. You'd think that a category is part of the defining properties of the parent, so changing it seems to fly into the face of immutability of parents.
</p>
<p>
If we have to keep it like this, we'd have to be very clear that one should only test if a parent is IN a given category; never rely on the category reported by "<parent>.category()". It certainly flies in the face of what I thought sage did: I thought specifying a parent implied specifying the category in which you want to consider it, and that if you want to consider a number field as a <code>QQ</code>-vector space instead, one should explicitly apply a functor and use a map (or perhaps conversion if you want to be implicit about it) to go between the two.
</p>
TicketSimonKingFri, 08 Feb 2013 20:48:16 GMT
https://trac.sagemath.org/ticket/14084#comment:4
https://trac.sagemath.org/ticket/14084#comment:4
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14084#comment:3" title="Comment 3">nbruin</a>:
</p>
<blockquote class="citation">
<p>
... but
</p>
<pre class="wiki">sage: k=Qp(7)
sage: k.category()
Category of commutative rings
sage: k in Fields()
True
sage: k.category()
Category of fields
</pre><p>
which is a little uncomfortable in its own right.
</p>
</blockquote>
<p>
No, this is very important for making the test <code>k in Fields()</code> fast without caching.
</p>
<blockquote class="citation">
<p>
You'd think that a category is part of the defining properties of the parent, so changing it seems to fly into the face of immutability of parents.
</p>
</blockquote>
<p>
No. It is just "learning more and more about immutable properties of the parent".
</p>
<blockquote class="citation">
<p>
If we have to keep it like this, we'd have to be very clear that one should only test if a parent is IN a given category; never rely on the category reported by "<parent>.category()".
</p>
</blockquote>
<p>
Sure. It could always be that the reported category is a subcategory of what one wants to have. <code>R in C</code> is recommended, but <code>R.category() is C</code> is not.
</p>
<blockquote class="citation">
<p>
It certainly flies in the face of what I thought sage did: I thought specifying a parent implied specifying the category in which you want to consider it, and that if you want to consider a number field as a <code>QQ</code>-vector space instead, one should explicitly apply a functor and use a map (or perhaps conversion if you want to be implicit about it) to go between the two.
</p>
</blockquote>
<p>
I think this is currently not supported.
</p>
TicketnthieryFri, 08 Feb 2013 21:01:23 GMT
https://trac.sagemath.org/ticket/14084#comment:5
https://trac.sagemath.org/ticket/14084#comment:5
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14084#comment:3" title="Comment 3">nbruin</a>:
</p>
<blockquote class="citation">
<p>
... but
</p>
<pre class="wiki">sage: k=Qp(7)
sage: k.category()
Category of commutative rings
sage: k in Fields()
True
sage: k.category()
Category of fields
</pre><p>
which is a little uncomfortable in its own right. You'd think that a category is part of the defining properties of the parent, so changing it seems to fly into the face of immutability of parents.
</p>
</blockquote>
<blockquote class="citation">
<p>
If we have to keep it like this, we'd have to be very clear that one should only test if a parent is IN a given category; never rely on the category reported by "<parent>.category()". It certainly flies in the face of what I thought sage did: I thought specifying a parent implied specifying the category in which you want to consider it, and that if you want to consider a number field as a <code>QQ</code>-vector space instead, one should explicitly apply a functor and use a map (or perhaps conversion if you want to be implicit about it) to go between the two.
</p>
</blockquote>
<p>
The above is in fact alright because Fields is a full subcategory of
Rings. So by going from one to the other, one don't change the
structure under consideration. One is just learning more properties of
this structure.
</p>
<p>
I certainly agree that I would not want the category of my parent to
change from Vector Space to Ring, because then I am adding a new
structure (the multiplication).
</p>
<p>
Full subcategories are not yet modeled in Sage, but this is in the
plans, because that's what we want to go further with homsets.
</p>
<p>
Cheers,
</p>
<blockquote>
<p>
Nicolas
</p>
</blockquote>
TicketSimonKingFri, 08 Feb 2013 23:08:36 GMT
https://trac.sagemath.org/ticket/14084#comment:6
https://trac.sagemath.org/ticket/14084#comment:6
<p>
At first glance, changing the categories of Zp(p) and Qp(p) seems not totally easy, simply because the code base is formed by a lot of slightly differently sounding base classes. But, as it says in sage.rings.padic.local_generic:
</p>
<pre class="wiki">Local Generic
Superclass for `p`-adic and power series rings.
</pre><p>
So, if we are lucky, both Zp, Qp and power series rings can be fixed at the same time.
</p>
TicketSimonKingFri, 08 Feb 2013 23:19:28 GMT
https://trac.sagemath.org/ticket/14084#comment:7
https://trac.sagemath.org/ticket/14084#comment:7
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14084#comment:6" title="Comment 6">SimonKing</a>:
</p>
<blockquote class="citation">
<pre class="wiki">Local Generic
Superclass for `p`-adic and power series rings.
</pre><p>
So, if we are lucky, both Zp, Qp and power series rings can be fixed at the same time.
</p>
</blockquote>
<p>
We are not lucky.
</p>
<pre class="wiki">sage: P = QQ[['x']]
sage: isinstance(P,sage.rings.padics.local_generic.LocalGeneric)
False
</pre>
TicketSimonKingSat, 09 Feb 2013 10:36:22 GMTowner, component changed
https://trac.sagemath.org/ticket/14084#comment:8
https://trac.sagemath.org/ticket/14084#comment:8
<ul>
<li><strong>owner</strong>
changed from <em>nthiery</em> to <em>roed</em>
</li>
<li><strong>component</strong>
changed from <em>categories</em> to <em>padics</em>
</li>
</ul>
<p>
Part of the problem is that the padic rings and fields inherit from sage.rings.ring.Ring, but they never call ring initialisation.
</p>
<p>
There are cases in which calling <code>__init__</code> of the super-classes is a bad idea, as it gives a speed regression. Question to users of padics: Are there cases in which one needs to create very many different padic rings and fields? If "yes", then shortcutting <code>__init__</code> makes sense. If not, it would be cleaner to call <code>__init__</code> of the base classes.
</p>
TicketSimonKingSat, 09 Feb 2013 10:39:22 GMT
https://trac.sagemath.org/ticket/14084#comment:9
https://trac.sagemath.org/ticket/14084#comment:9
<p>
PS: Part of the problem is that <code>sage.padics.local_generic.LocalGeneric</code> inherits from <code>CommutativeRing</code>, but calls <code> Parent.__init__(self, base, element_constructor=element_class, names=(names,), normalize=False, category=category or _CommutativeRings)</code>.
</p>
<p>
Where is the problem? Well, <code>CommutativeRing.__init__</code> does not know about the argument <code>element_constructor</code>...
</p>
TicketSimonKingSat, 09 Feb 2013 10:44:35 GMT
https://trac.sagemath.org/ticket/14084#comment:10
https://trac.sagemath.org/ticket/14084#comment:10
<p>
Aha! Instead of passing the element_class to <code>Parent.__init__</code>, one can simply assign it to <code>self.Element</code>! Then, the category framework can be initialised as usual, namely by calling <code>CommutativeRing.__init__</code>.
</p>
TicketSimonKingSat, 09 Feb 2013 15:07:52 GMT
https://trac.sagemath.org/ticket/14084#comment:11
https://trac.sagemath.org/ticket/14084#comment:11
<p>
It is becoming odder and odder.
</p>
<pre class="wiki">sage: P = Zp(15, check=False)
sage: P.__class__.mro()
[sage.rings.padics.padic_base_leaves.pAdicRingCappedRelative_with_category,
sage.rings.padics.padic_base_leaves.pAdicRingCappedRelative,
sage.rings.padics.generic_nodes.pAdicRingBaseGeneric,
sage.rings.padics.padic_base_generic.pAdicBaseGeneric,
sage.rings.padics.generic_nodes.pAdicCappedRelativeRingGeneric,
sage.rings.padics.generic_nodes.pAdicRingGeneric,
sage.rings.padics.padic_generic.pAdicGeneric,
sage.rings.ring.EuclideanDomain,
sage.rings.ring.PrincipalIdealDomain,
sage.rings.ring.IntegralDomain,
sage: P.is_integral_domain()
True
</pre><p>
So, if one creates a p-adic ring where p is not prime, then it still inherits from <code>EuclideanDomain</code>, and is convinced that it is an integral domain. That makes me wonder whether we could actually <em>always</em> initialise a p-adic ring in the category of Euclidean domains, regardless whether check=True or check=False is used.
</p>
TicketSimonKingSat, 09 Feb 2013 15:30:58 GMT
https://trac.sagemath.org/ticket/14084#comment:12
https://trac.sagemath.org/ticket/14084#comment:12
<p>
Aha!! Finally, the old ways of programming are helpful! The old base classes have an attribute <code>_default_category</code>. Hence, in <code>LocalGeneric</code>, one can simply do
</p>
<pre class="wiki"> self.Element = element_class
Parent.__init__(self, base, names=(names,), normalize=False, category=getattr(self,'_default_category',None))
</pre><p>
and then one immediately gets
</p>
<pre class="wiki">sage: P = Zp(5)
sage: TestSuite(P).run()
sage: K = Qp(7)
sage: TestSuite(K).run()
</pre><p>
Since (in spite of the comment in the doc string of <code>sage.rings.padics.local_generic</code>) power series rings do not inherit from that class, they need to be dealt with independently.
</p>
TicketSimonKingSat, 09 Feb 2013 15:34:12 GMT
https://trac.sagemath.org/ticket/14084#comment:13
https://trac.sagemath.org/ticket/14084#comment:13
<p>
Good!
</p>
<pre class="wiki">sage: P = ZZ[['x']]
sage: P._default_category
Category of integral domains
sage: P._is_category_initialized()
True
sage: P.category()
Category of commutative rings
</pre><p>
So, again, one should be able to simply use <code>self._default_category</code> when initialising the power series ring.
</p>
TicketSimonKingSat, 09 Feb 2013 17:01:35 GMT
https://trac.sagemath.org/ticket/14084#comment:14
https://trac.sagemath.org/ticket/14084#comment:14
<p>
Argh. Multivariate power series rings appear to not have an attribute <code>_default_category</code>. So, they need to be provided with it.
</p>
TicketnbruinSat, 09 Feb 2013 21:25:11 GMT
https://trac.sagemath.org/ticket/14084#comment:15
https://trac.sagemath.org/ticket/14084#comment:15
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14084#comment:5" title="Comment 5">nthiery</a>:
</p>
<blockquote class="citation">
<p>
The above is in fact alright because Fields is a full subcategory of
Rings. So by going from one to the other, one don't change the
structure under consideration. One is just learning more properties of
this structure.
</p>
</blockquote>
<p>
For the most part I probably agree with that. However, how does this relate to additional concepts such as "finitely generated"?
</p>
<p>
The following is probably not entirely kosher in terms of mathematical categories, but it may affect the colloquial use of them in computer algebra:
</p>
<p>
The Gaussian field <code>QQ(i)</code> would generally be considered a finitely generated field, but as a ring it would not be finitely generated (no characteristic 0 field is). Of course one should specify over what object they are finitely generated, and the discrepancy comes from the different default choices for fields and rings: The prime fields <code>QQ</code> and <code>GF(p)</code> for fields versus <code>ZZ</code> for commutative rings.
</p>
<p>
I would love to see that we can use the "category" field as a dynamic attribute as suggested, because it does make these <code>is_field</code> tests wonderfully fast without requiring complicated additional caching. But I am concerned that phenomena (or misconceptions) as above might come back and bite us if we're coming to depend on such tricks extensively. Can you ease that concern?
</p>
TicketSimonKingSat, 09 Feb 2013 23:18:58 GMTstatus changed; author set
https://trac.sagemath.org/ticket/14084#comment:16
https://trac.sagemath.org/ticket/14084#comment:16
<ul>
<li><strong>status</strong>
changed from <em>new</em> to <em>needs_review</em>
</li>
<li><strong>author</strong>
set to <em>Simon King</em>
</li>
</ul>
<p>
I think I made it work. See attachment.
</p>
<p>
Implementing the category can result in a slow-down in the creation of parents. Let's see what happens here. Without the patch:
</p>
<pre class="wiki">sage: %time L = [Zp(p) for p in prime_range(2,10^4)]
CPU times: user 2.00 s, sys: 0.09 s, total: 2.09 s
Wall time: 2.09 s
</pre><p>
With the patch:
</p>
<pre class="wiki">sage: %time L = [Zp(p) for p in prime_range(2,10^4)]
CPU times: user 2.10 s, sys: 0.05 s, total: 2.15 s
Wall time: 2.15 s
</pre><p>
I hope that's acceptable.
</p>
TicketnthierySun, 10 Feb 2013 00:17:53 GMT
https://trac.sagemath.org/ticket/14084#comment:17
https://trac.sagemath.org/ticket/14084#comment:17
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14084#comment:15" title="Comment 15">nbruin</a>:
</p>
<blockquote class="citation">
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14084#comment:5" title="Comment 5">nthiery</a>:
</p>
<blockquote class="citation">
<p>
The above is in fact alright because Fields is a full subcategory of
Rings. So by going from one to the other, one don't change the
structure under consideration. One is just learning more properties of
this structure.
</p>
</blockquote>
<p>
For the most part I probably agree with that. However, how does this relate to additional concepts such as "finitely generated"?
</p>
<p>
The following is probably not entirely kosher in terms of mathematical categories, but it may affect the colloquial use of them in computer algebra:
</p>
<p>
The Gaussian field <code>QQ(i)</code> would generally be considered a finitely generated field, but as a ring it would not be finitely generated (no characteristic 0 field is). Of course one should specify over what object they are finitely generated, and the discrepancy comes from the different default choices for fields and rings: The prime fields <code>QQ</code> and <code>GF(p)</code> for fields versus <code>ZZ</code> for commutative rings.
</p>
<p>
I would love to see that we can use the "category" field as a dynamic attribute as suggested, because it does make these <code>is_field</code> tests wonderfully fast without requiring complicated additional caching. But I am concerned that phenomena (or misconceptions) as above might come back and bite us if we're coming to depend on such tricks extensively. Can you ease that concern?
</p>
</blockquote>
<p>
I guess you pointed the key fact above: one can have some shortcuts
for the users convenience, but for a robust answer one should always
specify for which category the thing is finitely generated. For the
same reason .gens should only be a shortcut. For robust results, one
should always specify the category. Which is my motivation for
promoting the use of semigroup_generators / monoid_generators /
algebra_generators / ... Luckily, in some cases we have nice names
(finite dimensional, basis,...) for those.
</p>
<p>
Cheers,
</p>
<blockquote>
<p>
Nicolas
</p>
</blockquote>
TicketnbruinSun, 10 Feb 2013 02:07:22 GMT
https://trac.sagemath.org/ticket/14084#comment:18
https://trac.sagemath.org/ticket/14084#comment:18
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14084#comment:17" title="Comment 17">nthiery</a>:
</p>
<blockquote class="citation">
<p>
For robust results, one should always specify the category.
</p>
</blockquote>
<p>
But that's the issue: The category <em>is</em> specified:
</p>
<p>
Hypothetical dialogue (I'm sorry it has to be this academic--I don't presently have an actual example).
</p>
<pre class="wiki">sage: QQ.category()
Category of Commutative Rings
sage: QQ.is_finitely_generated()
False
</pre><p>
Sage confirms that at this point, it's considering <code>QQ</code> as a commutative ring and as such is not finitely generated.
</p>
<pre class="wiki">sage: QQ in Fields()
True
sage: QQ.category()
Category of Fields
sage: QQ.is_finitely_generated()
True
</pre><p>
Since the category here is <code>Fields</code> the question about finite generation should be considered there. Since it's a prime field I don't see how any other answer than <code>True</code> could be considered there.
</p>
<p>
This suggests to me that the concept of finite generation is not well-behaved w.r.t. restricting to <em>full subcategories</em>. I don't think that disqualifies it as a reasonable thing to ask. Instead, it suggests to me that it's not safe to implicitly change categories to full subcategories, since that change can affect what the answers to certain perfectly reasonable questions are.
</p>
<p>
It's important to keep in mind that by insisting on unique parents, sage is deviating from what most computer algebra systems choose to do. It makes the immutability of parents extremely important, because mutations can have extremely non-local consequences. Hence, every time immutability is violated one has to argue extremely carefully that the effect is immaterial. Changing categories sounds like a very dangerous thing to me.
</p>
<p>
Normally I'm not a fan of discussions about hypothetical code. However, here I think this issue is worth serious thinking because we're touching on fundamental infrastructure in sage:
</p>
<p>
The parent you get back when you ask for its construction can either be a fresh one, or one that is already referenced somewhere, or one that was already deleted but not yet found by the garbage collector (perhaps because it got trapped in a permanent cache somewhere), depending on what happened before.
</p>
TicketSimonKingSun, 10 Feb 2013 11:43:59 GMT
https://trac.sagemath.org/ticket/14084#comment:19
https://trac.sagemath.org/ticket/14084#comment:19
<p>
I do agree that changing the category on the fly looks suspicious. The true reason for originally implementing it in that way was speed: There were many fields that have not been initialised as fields, but had a method <code>is_field</code>; hence, the test <code>K in Fields()</code> used to first check the category and then the answer of <code>is_field</code> (similar to what is done now). Repeating this test used to be incredibly slow, which was quite visible in some examples.
</p>
<p>
Note that this change of class and category---changing from (the parent class of) one category to (the parent class of) the join of this category with the category of fields---is not a regression. Actually, it fixes a bug. Namely, in the good old times, one could very well have <code>P in Fields()</code> return true and <code>P in IntegralDomains()</code> return false. Now, <code>P in IntegralDomains()</code> would return true---at least when it is called after <code>P in Fields()</code>.
</p>
<p>
If all fields would be initialised as fields right away, we could certainly avoid this dangerous game. But the original rationale for working with the is_field methods is still valid: Sometimes the test of something really is a field is very expensive (primality tests, etc). So, one should avoid the expensive test as long as possible.
</p>
TicketnbruinSun, 10 Feb 2013 18:52:36 GMT
https://trac.sagemath.org/ticket/14084#comment:20
https://trac.sagemath.org/ticket/14084#comment:20
<p>
I think we really need another way to cache whether a ring is a field then. What you describe is indeed the case:
</p>
<pre class="wiki">sage: R=ZZ.quo(7)
sage: R in IntegralDomains() ##1
False
sage: R in Fields()
True
sage: R in IntegralDomains() ##2
True
</pre><p>
you can see that the call <code>R in Fields()</code> has mutated the parent in an essential way. The kind of call that people HAVE to use to look at the category field because it is not trustworthy by itself even can change depending on what happens with the parent elsewhere!
</p>
<p>
Whether <code>##1</code> is a bug or not depends on how you interpret the question: Are we asking the mathematical truth (which in general might be undecidable) or are we asking what sage knows about the object by construction? The first would of course be nicer, but computer algebra systems often settle for the second.
</p>
<p>
The important thing here is to illustrate how easy it is to mutate parents in a significant way if you start mucking with their category.
</p>
<p>
Personally I think it's fine if <code>ZZ.quo(7)</code> doesn't advertise itself as a <code>field by construction</code>. People can ask for <code>GF(7)</code> instead, which luckily does give back a non-identical parent:
</p>
<pre class="wiki">sage: R=ZZ.quo(7)
sage: R2=GF(7)
sage: id(R)
85206256
sage: id(R2)
17095856
</pre><p>
By the way:
</p>
<pre class="wiki">sage: R.category()
Join of Category of commutative rings and Category of subquotients of monoids and Category of quotients of semigroups and Category of finite enumerated sets
sage: R2.category()
Join of Category of subquotients of monoids and Category of quotients of semigroups and Category of finite fields
</pre><p>
I have to say those values do a good job of dissuading people from ever looking at them!
</p>
<p>
Also, this discussion is not of direct relevance to this ticket, so perhaps we should take the discussion to sage-devel instead.
</p>
TicketSimonKingSun, 10 Feb 2013 22:24:06 GMT
https://trac.sagemath.org/ticket/14084#comment:21
https://trac.sagemath.org/ticket/14084#comment:21
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14084#comment:20" title="Comment 20">nbruin</a>:
</p>
<blockquote class="citation">
<p>
I think we really need another way to cache whether a ring is a field then.
</p>
</blockquote>
<p>
Another instance of a weak cache perhaps? But if I recall correctly, I played with weak caches of the "is_Field" function -- and the speed was not competitive.
</p>
<p>
Also note that changing the category of the ring has indirect advantages: There may be more parent and element methods become available when passing to a sub-category.
</p>
<p>
I would say the change of category is allowed when one could have chosen that category during initialisation, and if the only reason for <em>not</em> doing so during initialisation is efficiency: I have seen applications involving matrix spaces, for which it really did not matter whether the matrix space is a vector space or an algebra or just a set -- I just don't remember the ticket number. Hence, in these applications, one would <em>postpone</em> the initialisation of the category of a matrix space, and only do it when necessary.
</p>
<p>
And in the case of ring versus field, I could imagine that there are examples in which one just needs to know that a given parent is a ring. In these applications, it would be a waste of time to determine during creation of the parent whether it actually is a field or not (which may involve primality tests). Hence, for efficiency, one should postpone the test of "being a field" until it is really needed.
</p>
<blockquote class="citation">
<p>
Also, this discussion is not of direct relevance to this ticket, so perhaps we should take the discussion to sage-devel instead.
</p>
</blockquote>
<p>
+1.
</p>
<p>
The "change of category" has not been introduced here, and not in <a class="closed ticket" href="https://trac.sagemath.org/ticket/13370" title="defect: Do not cache the result of is_Field externally (closed: fixed)">#13370</a> either. In fact, in the good old times, it was possible to have <code>P in Fields()</code> and <code>P not in IntegralDomains()</code>. Hence, I think of the refinement of categories as a progress.
</p>
<p>
I therefore suggest to use a new ticket, if someone finds a more satisfying solution of the "speed versus immutability problem".
</p>
TicketnthieryMon, 11 Feb 2013 18:38:58 GMT
https://trac.sagemath.org/ticket/14084#comment:22
https://trac.sagemath.org/ticket/14084#comment:22
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14084#comment:18" title="Comment 18">nbruin</a>:
</p>
<blockquote class="citation">
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14084#comment:17" title="Comment 17">nthiery</a>:
</p>
<blockquote class="citation">
<p>
For robust results, one should always specify the category.
</p>
</blockquote>
<p>
But that's the issue: The category <em>is</em> specified:
</p>
<p>
Hypothetical dialogue (I'm sorry it has to be this academic--I don't presently have an actual example).
</p>
<pre class="wiki">sage: QQ.category()
Category of Commutative Rings
sage: QQ.is_finitely_generated()
False
</pre><p>
Sage confirms that at this point, it's considering <code>QQ</code> as a commutative ring and as such is not finitely generated.
</p>
<pre class="wiki">sage: QQ in Fields()
True
sage: QQ.category()
Category of Fields
sage: QQ.is_finitely_generated()
True
</pre><p>
Since the category here is <code>Fields</code> the question about finite generation should be considered there. Since it's a prime field I don't see how any other answer than <code>True</code> could be considered there.
</p>
</blockquote>
<p>
Sorry, I have been ambiguous. What I mean is that, for the answer to
be well defined, one should specify the category at the time one asks
whether the object is finitely generated. Something like:
</p>
<pre class="wiki"> sage: Q.is_finitely_generated(Fields())
</pre><p>
or
</p>
<pre class="wiki"> sage: Q.is_finitely_generated_field()
</pre><p>
Then,
</p>
<pre class="wiki"> sage: Q.is_finitely_generated()
</pre><p>
would return the answer for the current category of Q; but that's just
a lousy syntactic sugar, for the user convenience, when there is no
ambiguity.
</p>
<blockquote class="citation">
<p>
This suggests to me that the concept of finite generation is not
well-behaved w.r.t. restricting to <em>full subcategories</em>.
</p>
</blockquote>
<p>
It's just not well defined if you don't specify explicitly for which
category you are asking the question.
</p>
<p>
Cheers,
</p>
<blockquote>
<p>
Nicolas
</p>
</blockquote>
TicketnbruinMon, 11 Feb 2013 18:53:33 GMT
https://trac.sagemath.org/ticket/14084#comment:23
https://trac.sagemath.org/ticket/14084#comment:23
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14084#comment:22" title="Comment 22">nthiery</a>:
[...]
Would you take this discussion to sage-devel, please? These are very important points that will need good thought and solutions, so there are likely more people interested in them. Also, these issues are not really directly relevant to this ticket.
</p>
TicketnthieryMon, 11 Feb 2013 19:14:22 GMT
https://trac.sagemath.org/ticket/14084#comment:24
https://trac.sagemath.org/ticket/14084#comment:24
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14084#comment:20" title="Comment 20">nbruin</a>:
</p>
<blockquote class="citation">
<p>
I think we really need another way to cache whether a ring is a field then. What you describe is indeed the case:
</p>
<pre class="wiki">sage: R=ZZ.quo(7)
sage: R in IntegralDomains() ##1
False
sage: R in Fields()
True
sage: R in IntegralDomains() ##2
True
</pre><p>
you can see that the call <code>R in Fields()</code> has mutated the parent in an essential way. The kind of call that people HAVE to use to look at the category field because it is not trustworthy by itself even can change depending on what happens with the parent elsewhere!
</p>
<p>
Whether <code>##1</code> is a bug or not depends on how you interpret the question: Are we asking the mathematical truth (which in general might be undecidable) or are we asking what sage knows about the object by construction? The first would of course be nicer, but computer algebra systems often settle for the second.
</p>
</blockquote>
<p>
By design, the category of an object in Sage describes:
</p>
<p>
(a) It's "operations" (additive structure, multiplicative
</p>
<blockquote>
<p>
structure). This conditions what the morphisms are in the category.
</p>
</blockquote>
<p>
(b) The properties of the operations that Sage is aware of at this
</p>
<blockquote>
<p>
point in time (either because they were specified by the user or
discovered during some computation).
</p>
</blockquote>
<p>
Note that the distinction between (a) and (b) will be made clearer
with the upcoming functorial construction patch <a class="closed ticket" href="https://trac.sagemath.org/ticket/10963" title="enhancement: Axioms and more functorial constructions (closed: fixed)">#10963</a> which
introduces an infrastructure for "axioms" for (b).
</p>
<p>
I totally agree that (a) should not change over the lifetime of an
object. But I consider it a very important feature that (b) can change
over time: when we discover new properties of an object, we want to
exploit them to use better algorithms. And we might as well have every
reference to that object in the current Sage session benefit from the
improvement.
</p>
<p>
Of course, for that to make sense, changing (b) should only influence
efficiency, and not change the *semantic* of questions; for that the
questions should be unambiguous.
</p>
<p>
Note that GAP is doing (b) intensively for precisely that reason
(although they use a different mechanism, through method selection
rather than object orientation).
</p>
<blockquote class="citation">
<p>
By the way:
</p>
<pre class="wiki">sage: R.category()
Join of Category of commutative rings and Category of subquotients of monoids and Category of quotients of semigroups and Category of finite enumerated sets
sage: R2.category()
Join of Category of subquotients of monoids and Category of quotients of semigroups and Category of finite fields
</pre><p>
I have to say those values do a good job of dissuading people from ever looking at them!
</p>
</blockquote>
<p>
Working on that :-) With my current functorial patch, this should be
roughly "Category of finite commutative quotient fields."
</p>
<p>
Cheers,
</p>
<blockquote>
<p>
Nicolas
</p>
</blockquote>
TicketnthieryMon, 11 Feb 2013 19:16:11 GMT
https://trac.sagemath.org/ticket/14084#comment:25
https://trac.sagemath.org/ticket/14084#comment:25
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14084#comment:23" title="Comment 23">nbruin</a>:
</p>
<blockquote class="citation">
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14084#comment:22" title="Comment 22">nthiery</a>:
[...]
Would you take this discussion to sage-devel, please? These are very important points that will need good thought and solutions, so there are likely more people interested in them. Also, these issues are not really directly relevant to this ticket.
</p>
</blockquote>
<p>
I totally agree. Now to start a constructive discussion on sage-devel one would need to write a short synthesis of the above discussion. With Sage Days 45 just starting, I just don't have the time now for that. But please proceed if you can!
</p>
TicketnthieryMon, 11 Feb 2013 19:16:48 GMT
https://trac.sagemath.org/ticket/14084#comment:26
https://trac.sagemath.org/ticket/14084#comment:26
<p>
Sorry I had missed the thread you had already created ...
</p>
TicketsaraedumThu, 14 Feb 2013 15:01:50 GMTstatus changed; reviewer set
https://trac.sagemath.org/ticket/14084#comment:27
https://trac.sagemath.org/ticket/14084#comment:27
<ul>
<li><strong>status</strong>
changed from <em>needs_review</em> to <em>needs_info</em>
</li>
<li><strong>reviewer</strong>
set to <em>Julian Rueth</em>
</li>
</ul>
<p>
Simon, in <code>local_generic.py</code> you add a category parameter but seem to ignore it. Was that intended?
</p>
TicketSimonKingThu, 14 Feb 2013 17:34:26 GMTattachment set
https://trac.sagemath.org/ticket/14084
https://trac.sagemath.org/ticket/14084
<ul>
<li><strong>attachment</strong>
set to <em>trac14084_integral_domains.patch</em>
</li>
</ul>
TicketSimonKingThu, 14 Feb 2013 17:40:06 GMTstatus changed
https://trac.sagemath.org/ticket/14084#comment:28
https://trac.sagemath.org/ticket/14084#comment:28
<ul>
<li><strong>status</strong>
changed from <em>needs_info</em> to <em>needs_review</em>
</li>
</ul>
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14084#comment:27" title="Comment 27">saraedum</a>:
</p>
<blockquote class="citation">
<p>
Simon, in <code>local_generic.py</code> you add a category parameter but seem to ignore it. Was that intended?
</p>
</blockquote>
<p>
No. Originally I thought of a different way to initialise stuff, because I thought that <code>LocalGeneric</code> is the base class of <em>both</em> power series rings and p-adic rings. So, I expected that the sub-classes would eventually like to pass a <code>category</code> to the init method of <code>LocalGeneric</code>.
</p>
<p>
But since it is only used for p-adic rings, it isn't needed.
</p>
<p>
The questions remain:
</p>
<ul><li><em>Should</em> power series inherit from <code>LocalGeneric</code>? This would be for a different ticket.
</li><li>Since power series do not inherit from <code>LocalGeneric</code>, shouldn't the documentation of local_generic.py be corrected accordingly?
</li></ul><p>
Anyway. I have updated the patch.
</p>
TicketsaraedumThu, 14 Feb 2013 18:01:11 GMT
https://trac.sagemath.org/ticket/14084#comment:29
https://trac.sagemath.org/ticket/14084#comment:29
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/14084#comment:28" title="Comment 28">SimonKing</a>:
</p>
<blockquote class="citation">
<p>
The questions remain:
</p>
<ul><li><em>Should</em> power series inherit from <code>LocalGeneric</code>? This would be for a different ticket.
</li></ul></blockquote>
<p>
In theory they should. Otherwise we would not need the distinction of <code>pAdicGeneric</code> and <code>LocalGeneric</code>. I guess we should open a new ticket and see if anything bad happens if they do.
</p>
<blockquote class="citation">
<p>
Anyway. I have updated the patch.
</p>
</blockquote>
<p>
Great. I'll wait for the patchbot to test this, and then I'll set it to positive review.
</p>
TicketSimonKingFri, 15 Feb 2013 16:12:00 GMT
https://trac.sagemath.org/ticket/14084#comment:30
https://trac.sagemath.org/ticket/14084#comment:30
<p>
The patchbot seems to like it...
</p>
TicketsaraedumSun, 17 Feb 2013 16:46:34 GMTstatus changed
https://trac.sagemath.org/ticket/14084#comment:31
https://trac.sagemath.org/ticket/14084#comment:31
<ul>
<li><strong>status</strong>
changed from <em>needs_review</em> to <em>positive_review</em>
</li>
</ul>
TicketjdemeyerSun, 17 Feb 2013 19:08:26 GMTmilestone changed
https://trac.sagemath.org/ticket/14084#comment:32
https://trac.sagemath.org/ticket/14084#comment:32
<ul>
<li><strong>milestone</strong>
changed from <em>sage-5.7</em> to <em>sage-5.8</em>
</li>
</ul>
TicketjdemeyerTue, 19 Feb 2013 06:48:46 GMTstatus changed; resolution, merged set
https://trac.sagemath.org/ticket/14084#comment:33
https://trac.sagemath.org/ticket/14084#comment:33
<ul>
<li><strong>status</strong>
changed from <em>positive_review</em> to <em>closed</em>
</li>
<li><strong>resolution</strong>
set to <em>fixed</em>
</li>
<li><strong>merged</strong>
set to <em>sage-5.8.beta0</em>
</li>
</ul>
Ticket