On 23 Mai, 02:45, Kwankyu Lee <
ekwan...@gmail.com> wrote:
> Then my worry is
> that the "translating" code may clutter the main code implementing the
> objects.
No. The main code implementing the objects is not touched by pickling/
unpickling.
> I feel that there should be some infrastructure to guide writing
> the "translating" code instead of each author doing it ad hoc. I imagine
> that the class of objects define "_translate_objects_from_xxx_to_XXX(self)"
> method where xxx is the old version and XXX is the newer version, and the
> unpickling procedure automatically invoke the methods for old objects
> pickled by Sage ver. xxx to upgrade them to objects of Sage ver. XXX. An
> author changing the data structure then may add such a method. The
> translation may happen in several steps from xxx1 to xxx2, and from xxx2 to
> xxx3, and so on to XXX.
That is all done by the usual Python or Cython pickling methods. See
http://docs.python.org/library/pickle.html#pickle-protocol
The basic idea is that you do *not* store implementation details or a
bit-wise copy of the memory. Instead, you store a reference to a
function unpickle_function, together with arguments A to that
function, so that unpickle_function(*A) reconstructs the object that
you wanted to pickle.
EXAMPLE:
If you have an extension class, then pickling relies on a method
__reduce__, such as here:
sage: P.<a,b,c> = PolynomialRing(QQ)
sage: L = P.__reduce__(); L
(<built-in function unpickle_MPolynomialRing_libsingular>,
(Rational Field, ['a', 'b', 'c'], Degree reverse lexicographic term
order))
sage: L[0](*L[1])
Multivariate Polynomial Ring in a, b, c over Rational Field
So, the unpickle_function returns a polynomial ring with a given
basering, list of variable names, and term order.
Here is the string that is used to save P:
sage: dumps(P, compress=False)
'\x80\x02csage.rings.polynomial.multi_polynomial_libsingular
\nunpickle_MPolynomialRing_libsingular\nq\x01csage.rings.rational_field
\nRationalField\nq\x02)Rq\x03]q\x04(U\x01aU\x01bU
\x01cecsage.rings.polynomial.term_order\nTermOrder\nq\x05)\x81q\x06}q
\x07(U\x18_TermOrder__singular_strq\x08U\x02dpq\tU\x10_TermOrder__nameq
\nU\tdegrevlexq\x0bU\x07__doc__q\x0cU\xf3\nDegree reverse
lexicographic (degrevlex) term ordering.\n\nLet $deg(x^a) = a_0 + ...
+ a_{n-1},$ then $x^a < x^b <=> deg(x^a) < deg(x^b)$ or\n$deg(x^a) =
deg(x^b)$ and $\\exists\\ 0 <= i < n: a_{n-1} = b_{n-1}, ..., a_{i+1}
= b_{i+1}, a_i > b_i.$\nq\rU\x12_TermOrder__matrixq\x0eNU
\x19_TermOrder__macaulay2_strq\x0fU\x07GRevLexq\x10U
\x12_TermOrder__lengthq\x11K\x03U\x06blocksq\x12h\x05)\x81q\x13}q\x14(h
\x08h\th\nU\tdegrevlexq\x15h\x0ch\rh\x0eNh\x0fh\x10h\x11K\x03h\x12)U
\x15_TermOrder__magma_strq\x16U\t"grevlex"q\x17U\x11_TermOrder__forceq
\x18\x89ub\x85q\x19h\x16h\x17h\x18\x89ub\x87Rq\x1a.'
So, the first part of the string (that would usually be compressed, of
course) only describes where the unpickle function can be found, *not*
how it is implemented (and that is essential!).
Now, assume that back in the old times you had a "Polynomial ring over
QQ generated by a,b in degrevlex order, implemented in libSingular",
and you stored it by save(P, 'my_pickle.sobj').
Later, William Stein decides to replace libSingular by a new
implementation of polynomial rings, say, written in Lisp (he sometimes
does those things on April 1st).
William could completely remove libSingular from sage, as long as he
keeps a function
sage.rings.polynomial.multi_polynomial_libsingular.unpickle_MPolynomialRing_libsingular.
That function should still accept a ring, a list of strings and a term
order as arguments, but it should now return an instance of his new
Lisp-implementation of polynomial rings, with the given basering,
variable names, and term order.
Then, load('my_pickle.sobj') will simply return a "Polynomial ring
over QQ generated by a,b in degrevlex order, implemented in Lisp".
Note that there was no "cluttering William's nice new Lisp code by
details of how libSingular used to work", and no transformation of
your old pickle in a new pickle format was needed.
Cheers,
Simon