Sage: Ticket #13378: Do not cache the non-existence of coerce/convert map too often, and do not pretend that there is a conversion where it doesn't make sense at all
https://trac.sagemath.org/ticket/13378
<p>
Sorry for the long ticket title.
</p>
<p>
About the first part of the title:
</p>
<pre class="wiki">sage: P.<x,y> = QQ[]
sage: P.is_coercion_cached(x)
False
sage: P.coerce_map_from(x)
sage: P.is_coercion_cached(x)
True
</pre><p>
Hence, there is a reference to x in the coercion cache for P. OK, by <a class="closed ticket" href="https://trac.sagemath.org/ticket/715" title="defect: Parents probably not reclaimed due to too much caching (closed: fixed)">#715</a> and friends, the reference is weak --- unless x does not allow weak references, in which case the reference will be strong, and x would not be collectable. Hence, a potential memory leak.
</p>
<p>
About the second part:
</p>
<pre class="wiki">sage: ZZ.convert_map_from(1)
Conversion map:
From: Set of Python objects of
To: Integer Ring
</pre><p>
or
</p>
<pre class="wiki">sage: P.convert_map_from(x)
Traceback (most recent call last):
...
TypeError: Cannot convert sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular to sage.structure.parent.Parent
</pre><p>
I think it is not good that the error occurs. The answer of <code>ZZ.convert_map_from(1)</code> seems strange, but apparently those things actually occur, namely conversions from the category of sequences.
</p>
en-usSagehttps://trac.sagemath.org/chrome/site/logo_sagemath_trac.png
https://trac.sagemath.org/ticket/13378
Trac 1.1.6SimonKingSat, 18 Aug 2012 12:08:35 GMTdescription changed
https://trac.sagemath.org/ticket/13378#comment:1
https://trac.sagemath.org/ticket/13378#comment:1
<ul>
<li><strong>description</strong>
modified (<a href="/ticket/13378?action=diff&version=1">diff</a>)
</li>
</ul>
TicketnbruinSat, 18 Aug 2012 17:27:41 GMT
https://trac.sagemath.org/ticket/13378#comment:2
https://trac.sagemath.org/ticket/13378#comment:2
<p>
Are you sure
</p>
<pre class="wiki">ZZ.convert_map_from(10)
</pre><p>
should not raise an error? Shouldn't the argument be a parent? Something like:
</p>
<pre class="wiki"> if not(isinstance(S,type) or isinstance(type(S),sage.structure.parent.Parent):
raise TypeError('convert maps only exist from parents')
</pre><p>
This has the potential for getting hairy if you want this to work:
</p>
<pre class="wiki">sage: A=AdditiveGroups()
sage: A(ZZ)
Free commutative group on generators [1]
</pre><p>
because then <code>parent(ZZ)</code> should be a Parent and it's not. However, this doesn't seem to be the way categories work anyway and it's probably wise to keep a strict separation between sets (parents) and categories. It actually makes me wonder if parent(ZZ) should even work.
</p>
<p>
I know this all flies in the face of duck typing, but so does the whole category framework. I'm afraid that a fully duck typed computer algebra system would about as bad as an untyped one.
</p>
TicketSimonKingSat, 18 Aug 2012 19:53:38 GMT
https://trac.sagemath.org/ticket/13378#comment:3
https://trac.sagemath.org/ticket/13378#comment:3
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/13378#comment:2" title="Comment 2">nbruin</a>:
</p>
<blockquote class="citation">
<p>
Are you sure
</p>
<pre class="wiki">ZZ.convert_map_from(10)
</pre><p>
should not raise an error?
</p>
</blockquote>
<p>
No, I am not sure.
</p>
<blockquote class="citation">
<p>
Shouldn't the argument be a parent?
</p>
</blockquote>
<p>
Or a type, because we want a coercion (not just a conversion) between Python ints and Sage integers.
</p>
<blockquote class="citation">
<p>
This has the potential for getting hairy if you want this to work:
</p>
<pre class="wiki">sage: A=AdditiveGroups()
sage: A(ZZ)
Free commutative group on generators [1]
</pre></blockquote>
<p>
That's totally separate. <code>AdditiveGroups()</code>, which doesn't exist yet, is a category and not a parent. It would be desirable, though, to have
</p>
<pre class="wiki">sage: ZZ.category() # current behaviour
Category of euclidean domains
sage: AdditiveGroups()(ZZ).category() # not implemented
Category of additive groups
</pre><blockquote class="citation">
<p>
because then <code>parent(ZZ)</code>
</p>
</blockquote>
<p>
ZZ has no parent, it <em>is</em> a parent. Elements have a parent, but parents have a category.
</p>
<blockquote class="citation">
<p>
It actually makes me wonder if parent(ZZ) should even work.
</p>
</blockquote>
<p>
parent(X) currently returns the type of X, if X has no method <code>X.parent()</code>. This is in order to make <code>int(1)+1</code> work. I don't think one should slow it down by distinguishing cases like "if X is a parent then parent(X) should raise an error, but if X is anything else then either return X.parent() or type(X)".
</p>
<p>
Anyway. I tried to introduce a shortcut for <code>Parent.coerce_map_from</code>, such that <code>None</code> is returned (without caching) if the argument is neither a <code>CategoryObject</code> nor a type. Similarly, I introduced a shortcut for <code>Parent.convert_map_from</code>, but had to be more relaxed, because apparently convert maps also need to exist from sequences (which are <code>SageObject</code>, but not <code>CategoryObject</code>).
</p>
<p>
Result: It nearly worked. There was one segfault in sage.rings.polynomial.infinite_polynomial_element (which I wrote) and one doctest error.
</p>
TicketSimonKingSat, 18 Aug 2012 20:00:55 GMT
https://trac.sagemath.org/ticket/13378#comment:4
https://trac.sagemath.org/ticket/13378#comment:4
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/13378#comment:2" title="Comment 2">nbruin</a>:
</p>
<blockquote class="citation">
<p>
I know this all flies in the face of duck typing, but so does the whole category framework.
</p>
</blockquote>
<p>
One could say that the category framework is the opposite of duck typing: In duck typing, you'd test whether certain methods are available for X, and conclude that X belongs to the category of ducks. In the category framework, you would at some point initialise X as an object of the category of ducks, and the category then provides X with methods like "quack()", "swim()", "fly()" --- or, if the category framework can not provide generic methods, it does require that these methods are implemented.
</p>
<p>
But I actually think that's a strength of the category framework. And note that after category initialisation of X, it would to some extent be possible to determine <code>X.category()</code> from the methods X provides.
</p>
TicketnbruinSat, 18 Aug 2012 21:31:54 GMT
https://trac.sagemath.org/ticket/13378#comment:5
https://trac.sagemath.org/ticket/13378#comment:5
<blockquote class="citation">
<p>
ZZ has no parent, it <em>is</em> a parent. Elements have a parent, but parents have a category.
</p>
</blockquote>
<p>
Ah yes, keeping that distinction strict is probably a good idea, even if it's
not always desirable from a strictly mathematical point of view:
</p>
<pre class="wiki">sage: I=ZZ.ideal(3)
sage: I(6)
TypeError: 'Ideal_pid' object is not callable
sage: parent(I)
Monoid of ideals of Integer Ring
sage: category(I)
Category of ring ideals in Integer Ring
</pre><p>
so an ideal is an element and not a parent (although mathematically it's also a
a non-unitary ring and at the very least a ZZ-module). What's that category
doing on <code>I</code> though? Do elements have a parent <em>as well as</em> a category?
</p>
<pre class="wiki">sage: V=FreeModule(ZZ,1)
sage: W=V.span([3*V.0])
sage: parent(W)
<class 'sage.modules.free_module.FreeModule_submodule_pid_with_category'>
sage: category(W)
Category of modules with basis over Integer Ring
</pre><p>
And here we're not getting a parent "... of submodules of V", whatever the ...
should be.
</p>
<p>
Along these lines, by the way:
</p>
<pre class="wiki">sage: NumberField(x^2+1,name='i').ideal(3)
Fractional ideal (3)
sage: QQ.ideal(3)
Principal ideal (1) of Rational Field
</pre><p>
illustrating the usual schism between algebraists and number theorists.
</p>
<p>
I don't think I'm really trying to make any point here. I'm just checking to
what degree Sage agrees with my mathematical intuition.
</p>
TicketSimonKingTue, 28 Aug 2012 09:52:00 GMTattachment set
https://trac.sagemath.org/ticket/13378
https://trac.sagemath.org/ticket/13378
<ul>
<li><strong>attachment</strong>
set to <em>trac_13378-convert_map_shortcut.patch</em>
</li>
</ul>
<p>
Test validity of input before a (failing) construction of coercion
</p>
TicketSimonKingTue, 28 Aug 2012 09:55:53 GMTstatus changed; author set
https://trac.sagemath.org/ticket/13378#comment:6
https://trac.sagemath.org/ticket/13378#comment:6
<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 am not totally sure if the patch has dependencies, but let's test. With the patch, it is tested whether the input is valid as the domain of a conversion map or a coercion map. There is a difference between the two cases! Namely, Sequences are OK for a conversion map, but not for a coercion map.
</p>
<p>
If the input S is invalid, <code>P.coerce_map_from(S)</code> returns None, which is the expected answer if there is no coercion (hence, no error is raised). Because the short-cut is quick enough and in order to not pollute the cache, the answer is <em>not</em> cached.
</p>
TicketjpfloriFri, 31 Aug 2012 12:10:28 GMTcc changed
https://trac.sagemath.org/ticket/13378#comment:7
https://trac.sagemath.org/ticket/13378#comment:7
<ul>
<li><strong>cc</strong>
<em>jpflori</em> added
</li>
</ul>
TicketrobertwbTue, 15 Jan 2013 08:19:38 GMT
https://trac.sagemath.org/ticket/13378#comment:8
https://trac.sagemath.org/ticket/13378#comment:8
<p>
Could you clarify under what circumstances not having this code pollutes the cache? In particular, it seems that [coerce|convert]_map_from is always called with parent(x) which should always return a Parent or type? Perhaps what I'm asking is what object violate this in their parent() method.
</p>
TicketSimonKingTue, 15 Jan 2013 08:41:49 GMT
https://trac.sagemath.org/ticket/13378#comment:9
https://trac.sagemath.org/ticket/13378#comment:9
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/13378#comment:8" title="Comment 8">robertwb</a>:
</p>
<blockquote class="citation">
<p>
Could you clarify under what circumstances not having this code pollutes the cache?
</p>
</blockquote>
<p>
Unfortunately, I did not write in the ticket description what use case made me create this ticket. But probably it was some experimental code on the computation of Ext algebras of basic algebras (i.e., finite-dimensional path algebra quotients).
</p>
<p>
Anyway. The problem is that in the coercion code one quite typically has
</p>
<pre class="wiki"> if self.has_coerce_map_from(P):
...
</pre><p>
without checking whether P really is a category object or type. And that means trouble, if P happens to be, say, an element (Yes, that did occur! But I don't know where I had originally found it). See the ticket description for an example.
</p>
<p>
Of course, if P is neither a category object nor a type, then there is no coercion map from P to self. And as you know, the coercion framework would not only cache a coercion map from P to self, but it would also cache the non-existence of a coercion map from P to self.
</p>
<p>
So, the trouble starts if P runs over many elements that are not weakreffable. For each element P, the coercion framework would store the value <code></code>None<code></code> in self's coercion dictionary. And since the element is not weakreffable, the entry will stay in cache forever, and I think this may even prevent self from being garbage collected.
</p>
TicketSimonKingTue, 15 Jan 2013 08:47:11 GMT
https://trac.sagemath.org/ticket/13378#comment:10
https://trac.sagemath.org/ticket/13378#comment:10
<p>
PS: If P is not a category object nor a type, it is impossible that there is a coercion map from P to self. Therefore the patch introduces a short cut: <code></code>self.coerce_map_from(P)<code></code> immediately returns None, and does not try to find a coercion map by a costly backtrack algorithm.
</p>
TicketjpfloriTue, 15 Jan 2013 08:56:16 GMT
https://trac.sagemath.org/ticket/13378#comment:11
https://trac.sagemath.org/ticket/13378#comment:11
<p>
Didn't it happen with integer ? (I think python ints.)
</p>
TicketjpfloriTue, 15 Jan 2013 08:59:06 GMT
https://trac.sagemath.org/ticket/13378#comment:12
https://trac.sagemath.org/ticket/13378#comment:12
<p>
Some info here <a class="ext-link" href="http://trac.sagemath.org/sage_trac/ticket/13400#comment:31"><span class="icon"></span>http://trac.sagemath.org/sage_trac/ticket/13400#comment:31</a> but this ticket was opened before so...
</p>
TicketSimonKingTue, 15 Jan 2013 09:20:25 GMT
https://trac.sagemath.org/ticket/13378#comment:13
https://trac.sagemath.org/ticket/13378#comment:13
<p>
Thank you, Jean-Pierre! Yes, it seems <code>ZZ.ideal(5)</code> is a real-world-example in which the coercion framework caches the trivial fact that there is no coercion map whose domain is the <em>number</em> 5. In addition, 5 is not weakreffable, and finally the Sage integer 5 is not unique -- but the coercion cache compares its keys by uniqueness and not by equality.
</p>
<p>
So, doing <code>ZZ.ideal(5)</code> repeatedly will fill up the coercion cache (post <a class="closed ticket" href="https://trac.sagemath.org/ticket/715" title="defect: Parents probably not reclaimed due to too much caching (closed: fixed)">#715</a>, at least) with trivialities.
</p>
TicketSimonKingTue, 15 Jan 2013 09:24:35 GMT
https://trac.sagemath.org/ticket/13378#comment:14
https://trac.sagemath.org/ticket/13378#comment:14
<p>
Too bad/good, I just tested it with sage-5.6.beta1:
</p>
<pre class="wiki">sage: %timeit a = ZZ.ideal(5)
625 loops, best of 3: 147 µs per loop
sage: %timeit a = ZZ.ideal(5)
625 loops, best of 3: 144 µs per loop
sage: %timeit a = ZZ.ideal(5)
625 loops, best of 3: 147 µs per loop
sage: %timeit a = ZZ.ideal(5)
625 loops, best of 3: 148 µs per loop
sage: %timeit a = ZZ.ideal(5)
625 loops, best of 3: 146 µs per loop
sage: %timeit a = ZZ.ideal(5)
625 loops, best of 3: 147 µs per loop
sage: %timeit a = ZZ.ideal(5)
625 loops, best of 3: 148 µs per loop
sage: %timeit a = ZZ.has_coerce_map_from(5)
625 loops, best of 3: 82.1 µs per loop
sage: %timeit a = ZZ.has_coerce_map_from(5)
625 loops, best of 3: 81.4 µs per loop
sage: %timeit a = ZZ.has_coerce_map_from(5)
625 loops, best of 3: 81.3 µs per loop
</pre><p>
So, the problem mentioned at <a class="new ticket" href="https://trac.sagemath.org/ticket/13400" title="enhancement: Use strong caches diligently (new)">#13400</a> does currently not exist.
</p>
<p>
We should investigate why it is not a problem.
</p>
TicketjpfloriTue, 15 Jan 2013 10:01:47 GMT
https://trac.sagemath.org/ticket/13378#comment:15
https://trac.sagemath.org/ticket/13378#comment:15
<p>
Did you apply <a class="closed ticket" href="https://trac.sagemath.org/ticket/12313" title="defect: Fix yet another memory leak caused by caching of coercion data (closed: fixed)">#12313</a>?
It seems after a really quick read that <a class="new ticket" href="https://trac.sagemath.org/ticket/13400" title="enhancement: Use strong caches diligently (new)">#13400</a> is a follow up to <a class="closed ticket" href="https://trac.sagemath.org/ticket/12313" title="defect: Fix yet another memory leak caused by caching of coercion data (closed: fixed)">#12313</a> to mitigate a speed regression.
</p>
TicketSimonKingTue, 15 Jan 2013 10:44:12 GMT
https://trac.sagemath.org/ticket/13378#comment:16
https://trac.sagemath.org/ticket/13378#comment:16
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/13378#comment:15" title="Comment 15">jpflori</a>:
</p>
<blockquote class="citation">
<p>
Did you apply <a class="closed ticket" href="https://trac.sagemath.org/ticket/12313" title="defect: Fix yet another memory leak caused by caching of coercion data (closed: fixed)">#12313</a>?
</p>
</blockquote>
<p>
Nope.
</p>
<blockquote class="citation">
<p>
It seems after a really quick read that <a class="new ticket" href="https://trac.sagemath.org/ticket/13400" title="enhancement: Use strong caches diligently (new)">#13400</a> is a follow up to <a class="closed ticket" href="https://trac.sagemath.org/ticket/12313" title="defect: Fix yet another memory leak caused by caching of coercion data (closed: fixed)">#12313</a> to mitigate a speed regression.
</p>
</blockquote>
<p>
OK, what would explain it. Sorry, I will only be able to resume work tomorrow.
</p>
TicketSimonKingFri, 18 Jan 2013 17:17:28 GMT
https://trac.sagemath.org/ticket/13378#comment:17
https://trac.sagemath.org/ticket/13378#comment:17
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/13378#comment:15" title="Comment 15">jpflori</a>:
</p>
<blockquote class="citation">
<p>
Did you apply <a class="closed ticket" href="https://trac.sagemath.org/ticket/12313" title="defect: Fix yet another memory leak caused by caching of coercion data (closed: fixed)">#12313</a>?
It seems after a really quick read that <a class="new ticket" href="https://trac.sagemath.org/ticket/13400" title="enhancement: Use strong caches diligently (new)">#13400</a> is a follow up to <a class="closed ticket" href="https://trac.sagemath.org/ticket/12313" title="defect: Fix yet another memory leak caused by caching of coercion data (closed: fixed)">#12313</a> to mitigate a speed regression.
</p>
</blockquote>
<p>
OK, I confirm that the problem with <code>ZZ.ideal(5)</code> becoming incrementally slower really exists with <a class="closed ticket" href="https://trac.sagemath.org/ticket/12313" title="defect: Fix yet another memory leak caused by caching of coercion data (closed: fixed)">#12313</a>. hence, this here <em>is</em> needed.
</p>
TicketnbruinFri, 18 Jan 2013 20:14:34 GMT
https://trac.sagemath.org/ticket/13378#comment:18
https://trac.sagemath.org/ticket/13378#comment:18
<p>
Straightforward patch that applies (with slight whitespace fuzz for me) and doctests succeed. Plus it solves a real regression. At this pace, Sage 5.7 will have a negative memory footprint! yay.
</p>
<p>
Positive review.
</p>
TicketnbruinFri, 18 Jan 2013 20:15:52 GMTstatus, milestone changed; reviewer set
https://trac.sagemath.org/ticket/13378#comment:19
https://trac.sagemath.org/ticket/13378#comment:19
<ul>
<li><strong>status</strong>
changed from <em>needs_review</em> to <em>positive_review</em>
</li>
<li><strong>reviewer</strong>
set to <em>Nils Bruin</em>
</li>
<li><strong>milestone</strong>
changed from <em>sage-5.6</em> to <em>sage-5.7</em>
</li>
</ul>
TicketjdemeyerSat, 19 Jan 2013 09:31:40 GMTdependencies set
https://trac.sagemath.org/ticket/13378#comment:20
https://trac.sagemath.org/ticket/13378#comment:20
<ul>
<li><strong>dependencies</strong>
set to <em>#12313, #12215</em>
</li>
</ul>
TicketnbruinSat, 19 Jan 2013 20:29:33 GMT
https://trac.sagemath.org/ticket/13378#comment:21
https://trac.sagemath.org/ticket/13378#comment:21
<p>
Please don't add dependencies that aren't required for the patches to apply. The fix here can be applied independently of other tickets and makes sense too. It might solve a problem that doesn't become quite as apparent without those other tickets, but that has little to do with its applicability.
</p>
<p>
We've had problems before where tickets were unnecessarily dequeued due to superfluous dependencies on tickets that turned out to need further work. Also, <a class="closed ticket" href="https://trac.sagemath.org/ticket/12313" title="defect: Fix yet another memory leak caused by caching of coercion data (closed: fixed)">#12313</a> already states it's dependent on <a class="closed ticket" href="https://trac.sagemath.org/ticket/12215" title="defect: Memleak in UniqueRepresentation, @cached_method (closed: fixed)">#12215</a>, so there's no need to repeat that dependence here.
</p>
TicketSimonKingSat, 19 Jan 2013 20:37:58 GMT
https://trac.sagemath.org/ticket/13378#comment:22
https://trac.sagemath.org/ticket/13378#comment:22
<p>
Yes, neither <a class="closed ticket" href="https://trac.sagemath.org/ticket/12313" title="defect: Fix yet another memory leak caused by caching of coercion data (closed: fixed)">#12313</a> nor <a class="closed ticket" href="https://trac.sagemath.org/ticket/12215" title="defect: Memleak in UniqueRepresentation, @cached_method (closed: fixed)">#12215</a> are dependencies for my patch. They should be merged together, because <a class="closed ticket" href="https://trac.sagemath.org/ticket/13378" title="defect: Do not cache the non-existence of coerce/convert map too often, and do ... (closed: fixed)">#13378</a> avoids a regression that <a class="closed ticket" href="https://trac.sagemath.org/ticket/12313" title="defect: Fix yet another memory leak caused by caching of coercion data (closed: fixed)">#12313</a> would introduce, but <a class="closed ticket" href="https://trac.sagemath.org/ticket/13378" title="defect: Do not cache the non-existence of coerce/convert map too often, and do ... (closed: fixed)">#13378</a> makes perfectly sense without <a class="closed ticket" href="https://trac.sagemath.org/ticket/12313" title="defect: Fix yet another memory leak caused by caching of coercion data (closed: fixed)">#12313</a>.
</p>
TicketSimonKingSat, 19 Jan 2013 20:39:19 GMT
https://trac.sagemath.org/ticket/13378#comment:23
https://trac.sagemath.org/ticket/13378#comment:23TicketjdemeyerSat, 19 Jan 2013 20:44:45 GMT
https://trac.sagemath.org/ticket/13378#comment:24
https://trac.sagemath.org/ticket/13378#comment:24
<p>
I guess it's a matter of definitions. I consider "merge with" as an equivalence relation (symmetric and transitive). Given that <a class="closed ticket" href="https://trac.sagemath.org/ticket/12313" title="defect: Fix yet another memory leak caused by caching of coercion data (closed: fixed)">#12313</a> is to be merged with <a class="closed ticket" href="https://trac.sagemath.org/ticket/13378" title="defect: Do not cache the non-existence of coerce/convert map too often, and do ... (closed: fixed)">#13378</a> and <a class="closed ticket" href="https://trac.sagemath.org/ticket/12215" title="defect: Memleak in UniqueRepresentation, @cached_method (closed: fixed)">#12215</a> is to be merged with <a class="closed ticket" href="https://trac.sagemath.org/ticket/12313" title="defect: Fix yet another memory leak caused by caching of coercion data (closed: fixed)">#12313</a>, the logical conclusion is that these 3 tickets need to be merged together. I didn't use the phrase "merge with" here, only to make the order of merging more clear (first <a class="closed ticket" href="https://trac.sagemath.org/ticket/12215" title="defect: Memleak in UniqueRepresentation, @cached_method (closed: fixed)">#12215</a>, then <a class="closed ticket" href="https://trac.sagemath.org/ticket/12313" title="defect: Fix yet another memory leak caused by caching of coercion data (closed: fixed)">#12313</a>, then <a class="closed ticket" href="https://trac.sagemath.org/ticket/13378" title="defect: Do not cache the non-existence of coerce/convert map too often, and do ... (closed: fixed)">#13378</a>).
</p>
<blockquote class="citation">
<p>
no need to repeat that dependence here.
</p>
</blockquote>
<p>
I find it easier to have the full set of dependencies written down. Consider tickets A, B and C where A and B have positive review, C needs review, A depends on B and B depends on C. If the implicit dependency of A on C is not written down, then it's not obvious to the release manager that A cannot currently be merged.
</p>
TicketjdemeyerSat, 19 Jan 2013 20:47:16 GMTdependencies deleted
https://trac.sagemath.org/ticket/13378#comment:25
https://trac.sagemath.org/ticket/13378#comment:25
<ul>
<li><strong>dependencies</strong>
<em>#12313, #12215</em> deleted
</li>
</ul>
TicketjdemeyerTue, 22 Jan 2013 07:40:50 GMTstatus changed; resolution, merged set
https://trac.sagemath.org/ticket/13378#comment:26
https://trac.sagemath.org/ticket/13378#comment:26
<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.7.beta0</em>
</li>
</ul>
Ticket