On Saturday, September 7, 2013 9:38:04 AM UTC-7, Volker Braun wrote:

> Is that really true? That is basically my question. What would go wrong? 
> If one can only break cyclic references in specific orders then the whole 
> thing is probably not going to work as we can't predict how a user will 
> compose Sage objects.
>

Let's try. I think there are structures where you can't just delete cyclic 
references at all, unless you take special efforts to recreate them 
afterwards. For instance, consider

class GraphNode(object):
    def __init__(self,neighbours=None):
        if neighbours is None:
            self.neighbours=[]
        else:
            self.neighbours=neighbours

#make the complete graph on 4 nodes
C=[GraphNode() for i in range(4)]
for c in C:
    c.neighbours.extend([b for b in C if b is not c])

 I can imagine that similar situations could naturally arise in sage. 
Perhaps the following:

Consider a class for ProjectiveSpace and its associated PicardGroup, 
created by

P2=ProjectiveSpace(k,2)
PicP2=PicardGroup(P2)

Let's assume computing a PicardGroup is expensive, so we'd like to ensure 
that PicP2's lifetime coincides with P2's, so we put a reference from P2 to 
PicP2 on P2. Of course PicP2 needs a reference to P2.

When pickling P2 we don't absolutely need to pickle PicP2, although not 
doing so means that after unpickling that P2 it might be expensive to 
obtain PicP2. A solution would be to pickle [P2,PicP2] instead.

Even for pickling PicP2 it would not be strictly necessary to store a 
reference to P2 explicitly: if it gets pickled to "execute PicardGroup(P2)" 
the reference to P2 would be implied anyway. However, that's of course NOT 
how we'd pickle something that's expensive to compute. It should probably 
have some set_state way of recreating PicP2 with the expensively computed 
data explicitly passed to it. That probably includes P2.

Now a different example, which I think is a little more like the graph 
example above. Suppose we store the affine patches to P2 as affine spaces. 
Since affine spaces can exist on their own, their creation doesn't 
necessarily imply a reference to P2. However, for pickling the 
constellation of P2 with its affine patches I would think that including 
the relations between them (which need to be stored in both directions!) is 
probably the expected behaviour.

We can of course impose (artificially) a hierarchy here to break 
circularity: We can say affine patches always know about their projective 
closure and only cache the references on projective space to its patches 
for efficiency reasons. But doing so might have consequences when someone 
does:

A2 = AffineSpace(k,2)
P2= ProjectiveClosure(A2)
allA2s= AllAffinePatches(P2)

(i.e., here P2 is derived from A2 rather than the other way around)

The problem is that the relations between the A2s and the P2 cannot be 
found by coercion discovery: The relations are only there because of how 
they are constructed. So if we were to simply break the connections and 
pickle P2 and allA2s, we'd end up with just a bunch of ambient spaces, 
without the relations that they are supposed to have.

I suspect similar things can happen with number fields, where certain 
coercions might get installed upon creation (e.g., a 
"represent_relative_extension_as_absolute_extension"), but where the 
creation data on the number field doesn't hold a hint that this happened. 
So here one would not necessarily end up with a defunct pickle, but unless 
one also explicitly pickles the appropriate "register_coercion" the pickle 
would lose information. I think solving this will simply be too 
complicated: This is state that ends up living outside the objects 
explicitly referenced, so pickle can't see this.

Finally, for rings there is always a fundamental circularity:

Rings tend to store a "zero" and "one" element. Those being elements, they 
carry a pointer to their parent, so any ring tends to be part of a cycle 
(this is actually nice for GC purposes: it extends the life of rings 
automatically to the next cyclic GC, so frequent ring creation/destruction 
is automatically moderated. It also increases the burden on GC, making it 
more expensive)

So automatic pickling of a ring would have to deal with circularity too. 
Here, the appropriate solution is to not worry about zero and one: they'll 
get created anyway, so you shouldn't pickle them explicitly.

Most of these situations have fairly simple solutions, but in each case 
specific knowledge of the objects at hand seems to be required.

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

Reply via email to