#E is an elliptic curve defined by E : f = 0 over QQ_2 #Aim: Find (f,fx,fy) \cap <1,x,y,x*y>_ZZ[a1,a2,a3,a4,a6] #Note: we do calculations over $ZZ$ and later use the fact that we are actually over ZZ_2. from sage.rings.polynomial.toy_d_basis import d_basis # We introduce an extra variable xy=x*y in order to have a monomial ordering that satiesfies x^2>y^2>xy >x>y ... R.<xy,x,y,a1,a2,a3,a4,a6> = PolynomialRing(ZZ, 8, order = 'deglex(3),deglex(5)') f = y^2 + a1*x*y + a3*y - x^3 + a2*x^2 + a4*x + a6 fx = f.derivative(x) fy = f.derivative(y) fz = xy-x*y I = R.ideal(f,fx,fy,fz) I_gb = d_basis(I); I_gb

Polynomial Sequence with 44 Polynomials in 8 Variables

for i in range(10): [i, I_gb[i].lm()]

[0, x^3]
[1, xy^2]
[2, xy*x]
[3, xy*y]
[4, x^2*a2]
[5, x^2*a4]
[6, x^2]
[7, x*y]
[8, y^2]
[9, xy*a2*a3^2]

#We want to find I \cap <1,x,x*y,y>, so we leave out elements with higher leading monomial. I_neu = I_gb[9:]; #And we add the terms x*Delta, y*Delta and xy*Delta in order to get a generating system as a $ZZ[a1,a2,a3,a4,a6]$-module (!) Delta = I_neu[len(I_neu)-1] I_neu = I_neu + [Delta*x,Delta*y,Delta*xy]

#We show that only 4 of the elements in I_neu are necessary to generate all of <1,x,y,xy> as an ZZ_2[a1,a2,a3,a4,a6]-module. #Those are: generators = [I_neu[4], I_neu[5], I_neu[6], fy]; #Calculations are done over QQ[x,y], so that we can calculate lifts. R.<xy,x,y,a1,a2,a3,a4,a6> = PolynomialRing(QQ,8,order = 'deglex(3),deglex(5)') I_neu=[R(el) for el in I_neu] generators = [R(el) for el in generators] #Check that {I_neu[4], I_neu[5], I_neu[6],f y} generate I_neu #The coefficients for the lifts of the elements in I_neu are stored in the list "coeff" I_test = R.ideal(generators) coeff = [] for el in I_neu: if el in I_test: coeff.append(el.lift(I_test)) else: print 'not in ideal' #This means I_neu[i] = sum_{j=0}^{3} coeff[i][j]*generators[j] for each i

#The coefficients are elements of QQ[x,y,a1,a2,a3,a4,a6]. We have to check that they are actually in ZZ_2[a1,a2,a3,a4,a6]. That is for each element: 2 does not divide its denominator and the leading monomial is in QQ[a1,a2,a3,a4,a6] for el in coeff: for poly in el: if 2.divides(poly.denominator()) or not poly.lm() < y: print 'non-integral lift', el