//////////////////////////////////////////////////////////////////
// This code determines the rational points on X441
//////////////////////////////////////////////////////////////////
// We need to handle the d = -2 twist of the genus 3 2-cover of X441
//    (The points (+-1, +- 28,3) lift to this twist) (28^2 = 784)

// X441 is y^2 =  x^6 - 3*x^4 + x^2 + 1
// C_d is  dy1^2 = x^2 - 1, dy2^2 =  x^4 - 2*x^2 - 1
// D_{d1,d2} is  d1y1^2 = x^2 - 1, d1d2y2^2 =  (x^2 - K.1 - 1), d2y3^2 = (x^2 + K.1 - 1)
//
// D maps to the genus 1 curves 
//   H1_{d1,d2}:    d1^2d2 y1^2 = (x^2 - 1) (x^2 - K.1 - 1) and 
//   H2_{d1,d2}:    d1 *d2 y1^2 = (x^2 - 1) (x^2 + K.1 - 1) 


_<t> := PolynomialRing(Rationals());
  K :=SplittingField(t^2 - 2);
  Q<x> := PolynomialRing(K);
  f := x^4 - 2*x^2 - 1; 
  OK := Integers(K);
  pp := Factorization(2*OK)[1][1];
 
sel2, msel2 := pSelmerGroup(2,{pp});
  msel2 := Inverse(msel2);

P1 := ProjectiveSpace(Rationals(),1);

possibleCoords:= {@@};


for dd in sel2 do 
  print "******************************";  
  d := msel2(dd);
  print "Working on the twist of the genus 5 cover by", d;
  
    H1 := QuadraticTwist(HyperellipticCurve(((x - 1)*(x + 1))*(x^2 - K.1 - 1))  , d);
    H2 := QuadraticTwist(HyperellipticCurve(((x - 1)*(x + 1))*(x^2 + K.1 - 1))  , -2*d);

    f1 := HyperellipticPolynomials(H1);
    f2 := HyperellipticPolynomials(H2);    
    pts1 := RationalPoints(H1 : Bound := 100);
    pts2 := RationalPoints(H2 : Bound := 100);    
    
    if #pts1*#pts2 eq 0 then
      print "No visible K-points.";
      print "IsLocallySolvable?";
      IsLocallySolvable(H1,pp) and IsLocallySolvable(H2,pp) ;
    else
      print "Checking ranks.";
      r1 :=   RankBound(Jacobian(H1));
      r2 :=   RankBound(Jacobian(H2));
      

     if r1*r2 eq 0 then  
       H := r1 eq 0 select H1 else H2;
       E, HtoE := EllipticCurve(H); 
         HtoEinv := Extend(Inverse(HtoE));
       _,AE,mwMapE := PseudoMordellWeilGroup(E);
       Hpts := {@HtoEinv(mwMapE(pt)) : pt in AE @};
       print "The Jacobian of the genus 1 curve", H, "has rank 0. The rational points of H are", Hpts;
       
       Q := r1 eq 0 select  d*(x^2 + K.1 - 1)   else -2*d*(x^2 - K.1 - 1); 
       
     else  
  
        print "There are visible K-points and both new elliptic curves have positive rank. Lets try ellitpic Chabauty";
         e,m :=   EllipticCurve(H2,pts2[1]);               
         minv := Extend(Inverse(m));       
         success, G, GtoEK := PseudoMordellWeilGroup(e);
    // elliptic chabauty map   
      eqns := DefiningEquations(minv);     
      xmap := Extend(map<e -> P1 | [eqns[1],eqns[3]]>);      
    // Elliptic Chabauty
    
    //  visiblePts := [<i,j> :   i in [0..1], j in [-10..10] |     xmap(GtoEK(i*G.1 + j*G.2))[1] in Rationals()];
      print "Does it work?";
     if exists(p){ p : p in SequenceToSet(PrimesUpTo(32)) diff {2}  
                           |   N eq #V   where   N, V, R, C is   Chabauty(GtoEK, xmap, p)} then
       N, V, R, C :=   Chabauty(GtoEK, xmap, p); 
       Hpts := {minv((GtoEK(a))) : a in V};
       print "The points on H with rational x cooordinate are",  Hpts;
            Q := -2*d*(x^2 - K.1 - 1);     
     else 
       print "Chabauty failed";
     end if; // exists(p)
      
  end if;  // r1*r2 eq 0 then  
   
  possibleCoords:= possibleCoords join {@[Rationals()!pt[1],Rationals()!pt[3]] : pt in Hpts@};  
    
  end if;  // #pts1*#pts2 eq 0 then
end for;

 print "The possible pairs [x:z] are", possibleCoords; 
zeroCoords := {@pt : pt in possibleCoords | pt[2] eq 0@};
print "Of these, ", zeroCoords, "and", {pt : pt in possibleCoords diff zeroCoords | 
                    IsSquare(x^6 - 3*x^4 + x^2 + 1) where x is pt[1]/pt[2]},
                    "correspond to points on X520";
 

  
  
// conclusion -- many twists map to a genus 1 curve with no local points. 
// all but two twists maps to a genus 0 elliptic curve. 
// On those two twists, elliptic Chabauty works on the target
// The twist by d = OK.2 gets the point with (x,z) = (+-1,+-3). 

//  The above code computes the lifts of all other points too. 
//  There are only the known points