////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// This code verifies the claims in the genus 2 section of "Elliptic curves over $\Q$ and 2-adic Images of Galois"
// (We used V19-9 of Magma)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

P<x> := PolynomialRing(Rationals());

// Info below is:
// <label, index, level, genus, equation, rank>, other info

" ";
"*********************************************************************";
"*********************************************************************";
"Working on the genus 2, rank 1 cases";
"*********************************************************************";
"*********************************************************************";
" ";

data1 := <
<"X377", 48, 16, 2, HyperellipticCurve(x^5 - 6*x^3 + x), 1>, 
  // The Jacobian splits as the product of E_1 : y^2 = x^3 + x^2 - 3x + 1 and E_2 : y^2 = x^3 - x^2 - 3x - 1, The curve E_2 has rank zero, We could also do Chabauty on the Jacobian, or perhaps do DM over Q(i), Also, the factorization seems to be useful, 
<"X407", 48, 32, 2, HyperellipticCurve(x^5 + 2*x), 1>, 
// The Jacobian appears to split as the product of two elliptic curves, E_1 : y^2 = x^3 + x^2 - 3x + 1 and E_2 : y^2 = x^3 - x^2 - 3x - 1, The second has rank zero, This seems similar to 
<"X408", 48, 32, 2, HyperellipticCurve(x^5 + x), 1>>;
// The Jacobian appears to split as the product of two elliptic curves, E_1 : y^2 = x^3 - x^2 - 13 + 21 and E_2 : y^2 = x^3 + x^2 - 13x - 21, Note that E_1 has rank zero,  

for i in [1..#data1] do
    J := Jacobian(data1[i][5]);
      "Working on ", data1[i][1], "; Rank of Jac is ", RankBound(J); // returns 1
    heightconst := HeightConstant(J : Effort:=2, Factor);
      pts := Points(J : Bound := 1000);
      min := Minimum({Height(P) : P in pts | Order(P) eq 0}); 
      bool := exists(PJ){pt : pt in pts | Height(pt) eq min};
      LogarithmicBound := Height(PJ) + heightconst;  // Bound on h(Q)
      AbsoluteBound := Ceiling(Exp(LogarithmicBound));
      PtsUpToAbsBound := Points(J : Bound:=AbsoluteBound );
      bas, ht := ReducedBasis([ pt : pt in PtsUpToAbsBound ]);       
      pts := Chabauty(bas[1]);
      "The rational points are ", pts; 
end for;    
 
// no surprises. 


" ";
"*********************************************************************";
"*********************************************************************";
"Working on the genus 2, rank 2 cases";
"*********************************************************************";
"*********************************************************************";
" ";

    
//<"X364", 48, 16, 2, HyperellipticCurve(x^6 + 10*x^4 - 20*x^2 - 8), 2>, 
//<"X376", 48, 16, 2, HyperellipticCurve(x^6 - 5*x^4 - 5*x^2 + 1),  2>,
//<"X526", 96, 32, 2, HyperellipticCurve(x^6 + 8*x^5 + 6*x^4 +  12*x^2 - 32*x + 8), 2>,
//<"X369", 48, 16, 2, HyperellipticCurve(x^6 - 5*x^4 - 5*x^2 + 1),  2>, 

// the above 4 curves are isomorphic to some of  the  4 curves below.    

// see the files X441 and X520 for Magma code verifying the genus 5 claims.

   

data2 := <
<"X395", 48, 16, 2, HyperellipticCurve(x^6 - 5*x^4 - 5*x^2 + 1), 2>,
// Descent details:
// x^6 - 5*x^4 - 5*x^2 + 1 =  (x^2 - 2*x - 1)*(x^2 + 1)*(x^2 + 2*x - 1)
// Admits an etale cover by the genus 3 curve
//    y1^2 = x^2 + 1
//    y2^2 = (x^2 - 2*x - 1)*(x^2 + 2*x - 1)
// The twists all map to the rank 0 elliptic curve dy2^2 = (x^2 - 2*x - 1)*(x^2 + 2*x - 1)
// Two visible rational points

<"X402", 48, 16, 2, HyperellipticCurve(x^6 + 10*x^4 - 20*x^2 - 8), 2>, 
// Descent details:
// x^6 + 10*x^4 - 20*x^2 - 8 = (x^2 - 2)*(x^4 + 12*x^2 + 4)
// Admits an etale cover by the genus 3 curve
//    y1^2 =     x^2 - 2
//    y2^2 =     x^4 + 12*x^2 + 4
//The twists all map to the rank 0 elliptic curve dy2^2 = x^4 + 12*x^2 + 4
// Two visible rational points


<"X441", 64, 16, 2, HyperellipticCurve(x^6 - 3*x^4 + x^2 + 1), 2>,
// The Jacobian decomposes as the product of E_1 : y^2 = x^3 - 2x and E_2 : y^2 = x^3 + x^2 - 3x + 1, Both have rank one, Burcu Baran claims that elliptic curve Chabauty finds all the rational points on the curve, 
// Proof that X441 is isomorphic to X^+(16):
// XBaran := HyperellipticCurve(2*(x*(x+1)^3 - 8*x^3));
// IsIsomorphic(HyperellipticCurve(2*(x*(x+1)^3 - 8*x^3),HyperellipticCurve(x^6 - 3*x^4 + x^2 + 1));
// Descent details (more involved):
// x^6 - 3*x^4 + x^2 + 1 = (x - 1)*(x + 1)*(x^4 - 2*x^2 - 1)
// Admits an etale cover by the genus 3 curve
//    y1^2 = (x - 1)*(x + 1)
//    y2^2 = x^4 - 2*x^2 - 1
// The twists by +-1 and 2  map to the rank 0 elliptic curve dy2^2 = x^4 - 2*x^2 - 1
// For d = -2 this has rank 1 and the genus 1 curve has rational points (since the genus 3 curve does too). 
// The twist by -2 admits a further cover by a genus 5 cover over the field $Q(\sqrt{2})$ (this is the field over which (x^4 - 2*x^2 - 1) factors into quadratics). There are 8 twists by the elements of $OK_{S}^{\times}/OK_{S}^{\times,2}$. 7 of these cover a rank 0 elliptic curve, and the remaining one is resolved by elliptic chabauty. 
//
// 10 visible rational points

// The defining equation factors as a quadratic and a quartic -- (x^2 + 2)*(x^4 + 8*x^3 + 4*x^2 - 16*x + 4); there is thus an etale double cover by a genus 3 curve. There are 4 relevant twists (by +-1, +-2). The twists by 1,+-2 cover a rank 0 elliptic curve. 


<"X520", 96, 32, 2, HyperellipticCurve(x^6 + 8*x^5 + 6*x^4 +  12*x^2 - 32*x + 8), 2>>;
// The defining equation factors as a quadratic and a quartic -- (x^2 + 2)*(x^4 + 8*x^3 + 4*x^2 - 16*x + 4); 
// Admits an etale cover by the genus 3 curve
//    y1^2 = (x^2 + 2)
//    y2^2 = (x^4 + 8*x^3 + 4*x^2 - 16*x + 4)
// The twists by -1 and +-2  map to the rank 0 elliptic curve dy2^2 = x^4 + 8*x^3 + 4*x^2 - 16*x + 4
// For d = 1 this has rank 1 and the genus 1 curve has rational points (since the genus 3 curve does too). 
// The twist by 1 admits a further cover by a genus 5 cover over the field $Q(\sqrt{2})$ (this is the field over which x^4 + 8*x^3 + 4*x^2 - 16*x + 4 factors into quadratics). There are 8 twists by the elements of $OK_{S}^{\times}/OK_{S}^{\times,2}$. 4 of these have no points mod pp, where pp is the prime over 2 (witnessed via covering a genus 1 curve with no local points). The other 4 cover an elliptic curve with rank 1; elliptic Chabauty resolves the points (noting that relevant points on the genus 1 curve have rational x coordinate). 
//
// Two visible rational points


// Here is code verifying the claims about the genus 3 double covers, twists, and the elliptic curve the twists cover.

P<x> := PolynomialRing(Rationals());

r2g2 := 
{@<x^2 + 1 , (x^2 - 2*x - 1)*(x^2 + 2*x - 1), "X396">,
 <x^2 - 2 , x^4 + 12*x^2 + 4, "X402">,
 <x^2 - 1, x^4 - 2*x^2 - 1, "X441" >,
 <x^2 + 2 , x^4 + 8*x^3 + 4*x^2 - 16*x + 4, "X520">
 @};
    
// returns the data for the elliptic curves covered by the genus 3 curves
for i in [1..#r2g2] do
    " ";
    print "************************************************************";
  "Working on ", r2g2[i][3],"which has the visible rational points";
   RationalPoints( HyperellipticCurve(r2g2[i][1]*r2g2[i][2]) : Bound := 100);    
 for d in {1,-1,2,-2} do
  print "******************************";
  <i, "d = " , d, r2g2[i][3]>;


  Hhyper := QuadraticTwist( HyperellipticCurve( r2g2[i][2] ), d);

  if not IsLocallySolvable(Hhyper,2) then
    print " is not  locally solvable at 2.";  
      
  else    
  
    A2<x1,y> := AffineSpace(Rationals(),2);
    A3<x2,y1,y2> := AffineSpace(Rationals(),3);
    C := Curve(A3, [d*y1^2 - Evaluate( r2g2[i][1], x2), d*y2^2 - Evaluate( r2g2[i][2], x2)]);
    H := Curve(A2,  d*y^2 - Evaluate( r2g2[i][2], x1));
    pr := map<C -> H | [x2,y2]>;
    
    pts := RationalPoints(Hhyper : Bound := 100);
    //pts := {@H![a/c^3,b/c^2] : a,b,c in [-10..10] | not c eq 0 and Evaluate(d*y^2 -Evaluate( r2g2[i][2], x1),[a/c  ^3,b/c^2] ) eq 0@};
    
    if #pts ge 1 then;
      print "H has visible rational points.";      
      E, HtoE := EllipticCurve(Hhyper, pts[1]);
      HtoEinv := Extend(Inverse(HtoE));
      if Rank(E) ge 1 then
          print "E has rank ", Rank(E);
      else
          A, mwMap := MordellWeilGroup(E);
          HhyperPts :=  {HtoEinv(mwMap(a)) : a in A};
          print "The rational points on the genus 1 curve H are", HhyperPts;
          print "The corresponding rational points on X_H are"; 
          
          for pt in HhyperPts do 
             if pt[3] eq 0 then
               bool := IsSquare(d*LeadingCoefficient(r2g2[i][1]));            
               print not bool select "... there are no rational points" else "a pair of rational points at infinity"; print "over", pt;
             else
                   bool, Y1 := IsSquare(Evaluate(r2g2[i][1],pt[1]));                
              print not bool select "... there are none" else   data2[1][5]![pt[1],Y1];             
              print "over", pt;
             end if;    
          end for;
          
      end if;
    else
     true;   
    end if;
      
      

  end if;       

 end for; 
end for;     


  
  

" ";
"*********************************************************************";
"*********************************************************************";
"Working on the genus 2, rank 0 cases";
"*********************************************************************";
"*********************************************************************";
" ";
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
// All of the rational points on the rank 0 curves have been determined via Chabauty0 and are in the summary file.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  

data := 
<<"X170", 24, 16, 2, HyperellipticCurve(x^5 - 4*x), 0>,
<"X171", 24, 16, 2, HyperellipticCurve(x^5 - 4*x), 0>,
<"X172", 24, 16, 2, HyperellipticCurve(-x^5 - 4*x), 0>,
<"X174", 24, 16, 2, HyperellipticCurve(-x^5 - 4*x), 0>,
<"X357", 48, 8, 2, HyperellipticCurve(-x^5 + x),    0>,
<"X519", 96, 16, 2, HyperellipticCurve(2*x^5 - 4*x^4 - 4*x^2 -  2*x), 0>,
<"X521", 96, 32, 2, HyperellipticCurve(-2*x^5 - 4*x^4 - 4*x^2 +  2*x), 0>,
<"X522", 96, 32, 2, HyperellipticCurve(x^5 - 2*x^4 - 2*x^2 - x),  0>, 
<"X523", 96, 32, 2, HyperellipticCurve(-x^5 - 2*x^4 - 2*x^2 + x),  0>, 
<"X524", 96, 32, 2, HyperellipticCurve(-x^5 - x^4 - x^3 - x^2,(x^3 + x^2 + x + 1)), 0>,
<"X525", 96, 32, 2, HyperellipticCurve(-x^6 + 8*x^5 - 6*x^4 -  12*x^2 - 32*x - 8), 0>,
<"X527", 96, 32, 2, HyperellipticCurve(-x^5 - 2*x^4 - 2*x^2 + x),  0>, 
<"X528", 96, 32, 2, HyperellipticCurve( -x^4 - x^3 - x^2 - x,(x^3 + x^2 + x + 1)), 0>,
<"X529", 96, 32, 2, HyperellipticCurve(2*x^5 + 4*x^4 + 4*x^2 -  2*x), 0>,
<"X530", 96, 32, 2, HyperellipticCurve(2*x^5 - 4*x^4 - 4*x^2 -  2*x), 0>,
<"X531", 96, 32, 2, HyperellipticCurve(-x^5 - x^4 - x^3 - x^2,(x^3 + x^2 + x + 1)), 0>,
<"X532", 96, 32, 2, HyperellipticCurve(-2*x^5 + 4*x^4 + 4*x^2 +  2*x), 0>,
<"X533", 96, 32, 2, HyperellipticCurve(-x^6 + 8*x^5 - 6*x^4 -  12*x^2 - 32*x - 8), 0>,
<"X534", 96, 32, 2, HyperellipticCurve(-2*x^5 - 4*x^4 - 4*x^2 +  2*x), 0>,
<"X535", 96, 32, 2, HyperellipticCurve(2*x^5 + 4*x^4 + 4*x^2 -  2*x), 0>,
<"X371", 48, 16, 2, HyperellipticCurve(-x^5 + x), 0>,
<"X380", 48, 16, 2, HyperellipticCurve(2*x^5 - 12*x^3 + 2*x), 0>, 
<"X386", 48, 16, 2, HyperellipticCurve(-x^5 + x), 0>,
<"X404", 48, 16, 2, HyperellipticCurve(x^5 - x), 0>,
<"X405", 48, 32, 2, HyperellipticCurve(-x^5 + x), 0>,
<"X406", 48, 32, 2, HyperellipticCurve(x^5 - x), 0>,
<"X500", 96, 16, 2, HyperellipticCurve(-x^5 - 2*x^4 - 2*x^2 + x),  0>, 
<"X501", 96, 16, 2, HyperellipticCurve(-x^5 - x^4 - x^3 - x^2, (x^3 + x^2 + x + 1)), 0>,
<"X502", 96, 16, 2, HyperellipticCurve(-2*x^5 - 4*x^4 - 4*x^2 +  2*x), 0>,
<"X503", 96, 16, 2, HyperellipticCurve(2*x^5 + 4*x^4 + 4*x^2 -  2*x), 0>,
<"X504", 96, 16, 2, HyperellipticCurve(-x^5 - x^4 - x^3 - x^2,(x^3 + x^2 + x + 1)), 0>,
<"X505", 96, 16, 2, HyperellipticCurve(x^5 - 2*x^4 - 2*x^2 - x),  0>, 
<"X506", 96, 16, 2, HyperellipticCurve(2*x^5 + 4*x^4 + 4*x^2 -  2*x), 0>,
<"X507", 96, 16, 2, HyperellipticCurve(x^5 - 2*x^4 - 2*x^2 - x),  0>, //Contrary to the log file, the two rational points (which do lift to the non-singular model) are cusps, 
<"X508", 96, 16, 2, HyperellipticCurve(-2*x^5 + 4*x^4 + 4*x^2 +  2*x), 0>,
<"X509", 96, 16, 2, HyperellipticCurve(2*x^5 - 4*x^4 - 4*x^2 -  2*x), 0>, //Contrary to the log file, the two rational points are cusps, 
<"X510", 96, 16, 2, HyperellipticCurve(-x^5 - x^4 - x^3 - x^2,(x^3 + x^2 + x + 1)), 0>, //Contrary to the log file, the two rational points are cusps, 
<"X511", 96, 16, 2, HyperellipticCurve(-x^5 - x^4 - x^3 - x^2,(x^3 + x^2 + x + 1)), 0>,
<"X512", 96, 16, 2, HyperellipticCurve(-x^5 - 2*x^4 - 2*x^2 + x),  0>, 
<"X513", 96, 16, 2, HyperellipticCurve(2*x^5 + 4*x^4 + 4*x^2 -  2*x), 0>,
<"X514", 96, 16, 2, HyperellipticCurve(-2*x^5 - 4*x^4 - 4*x^2 +  2*x), 0>,
<"X515", 96, 16, 2, HyperellipticCurve(x^5 - 2*x^4 - 2*x^2 - x),  0>, 
<"X516", 96, 16, 2, HyperellipticCurve(-2*x^5 + 4*x^4 + 4*x^2 +  2*x), 0>,
<"X517", 96, 16, 2, HyperellipticCurve(2*x^5 - 4*x^4 - 4*x^2 -  2*x), 0>,
<"X518", 96, 16, 2, HyperellipticCurve(-x^5 - x^4 - x^3 - x^2,(x^3 + x^2 + x + 1)), 0>>;

J := Jacobian(data[1][5]);
  tors,mtor := TorsionSubgroup(J);
//  for d in data do #TorsionSubgroup(Jacobian(SimplifiedModel(d[5]))); end for;
  for d in data do d[1], Chabauty0(Jacobian(SimplifiedModel(d[5]))); end for; // this finds all of the rational points.
      
// This reveals only the known rational points on our curves      