A<y,x> := PolynomialRing(GF(2),2);
P,homogenize := Homogenization(A);
// print("f := The polynomial from math.mit.edu/~drew/FFFc35.txt reduced mod 2:");
// f := x^16*y^5+(y+y^3+1)*y^4*x^14+(y^2+y+1)^2*(y+1)*y^4*x^13+(y+1)^3*y^4*x^12+(y^2+y+1)*(y^5+y^3+y^2+y+1)*y^4*x^11+(y^5+y^3+1)*y^3*x^10+(y^3+y^2+1)*(y^7+y^6+y^5+y^2+1)*(y+1)*y^2*x^9+(y^2+y+1)*(y^10+y^9+y^5+y^4+y^2+y+1)*y*x^8+(y^2+y+1)*(y^12+y^10+y^9+y^8+y^7+y^3+y^2+y+1)*y*x^7+(y^6+y+1)*(y+1)*(y^8+y^7+y^2+y+1)*x^6+(1+y^2+y^3+y^5+y^8+y^11+y^10+y^13+y^12)*(y+1)^2*x^5+(1+y^4+y^5+y^6+y^8+y^11+y^9+y^10+y^12)*(y+1)^3*x^4+(y^3+y^2+1)*(y^4+y^3+1)*(y+1)^4*x^3+(y^6+y^5+1)*(y+1)^5*x^2+(y^5+y^4+y^3+y^2+1)*(y+1)^6*x+(y^4+y^3+y^2+y+1)*(y+1)^7 ;

print("f := an improved polynomial for X1(35):");
f := x^16*y^3+y^2*(4*y^2+3-5*y)*x^15+(19*y^3+3*y+6*y^5-15*y^4-1-9*y^2)*x^14+(-14*y^5-25*y^3+1+27*y^4-7*y+4*y^6+18*y^2)*x^13+(2*y-1-6*y^2-2*y^6-5*y^4+y^7+12*y^3+4*y^5)*x^12+(1+3*y^7+22*y^3-24*y^4-7*y^2-11*y^6+22*y^5-2*y)*x^11+(21*y^4+8*y^6-1-5*y^2+2*y+y^8-2*y^3-3*y^7-18*y^5)*x^10+(-2*y+7*y^4+1+2*y^2-5*y^3-y^6)*x^9+(13*y^8+21*y^6-22*y^7-1-3*y^9+2*y^2-23*y^5+2*y-17*y^3+29*y^4)*x^8-y*(y-1)*(3*y^8-14*y^7+27*y^6-28*y^5+21*y^4-13*y^3+6*y^2-2*y+1)*x^7-y*(y-1)*(y^9-6*y^8+16*y^7-23*y^6+16*y^5+4*y^4-10*y^3-y^2+10*y-5)*x^6+y^3*(y-1)*(2*y^6-10*y^5+18*y^4-17*y^3+8*y^2-3)*x^5+y^2*(y-1)*(3*y^8-18*y^7+40*y^6-38*y^5+7*y^4+9*y^3+4*y^2-16*y+8)*x^4+y^2*(y-1)*(y^9-7*y^8+20*y^7-30*y^6+25*y^5-11*y^4-3*y^3+12*y^2-11*y+3)*x^3+y^3*(y^6-6*y^5+14*y^4-16*y^3+7*y^2+2*y-4)*(y-1)^2*x^2-y^3*(y^3-4*y^2+7*y-3)*(y-1)^3*x-y^3*(y-1)^5;

f := homogenize(f);
XF2 := Scheme(ProjectiveSpace(P),f);
FF := FunctionField(XF2);
AFF := AlgorithmicFunctionField(FF);
plc1 := Places(AFF,1);
divgrp := DivisorGroup(AFF);
div1 := [divgrp ! i : i in plc1];
cuspsum := &+ div1;
load "function_degrees.m";

print("The number of places of degrees 1-7:");
[#Places(AFF,i) : i in [1..7]];

// Our goal is to show that X1(35) has no non-constant functions of degree <12
// over F2 and hence over Q.

// Say f is a function of degree <= 11, since f^(-1)({0,1,infinity}) contains
// all 12 rational points, by the pigeon hole principle we may assume that
// f^(-1)({infinity} contains at least 4 distinct rational points, and so
// the remaining polar-part of f has degree at most 7.

// This contains one place of each diamond-orbit of rational places. In
// this case there is only one such orbit.
orbs := [plc1[1]];


// Degree >1 places: [3]
// Rat-places: [2, 2, 2, 2] (only multiplicities >1 are listed).
s := {(cuspsum + P1 + 1*Q1+1*Q2+1*Q3+1*Q4) : P1 in Places(AFF,3), Q1 in plc1, Q2 in plc1, Q3 in plc1, Q4 in orbs};
print "The number of RR-computations to be done for this case is:",
#s;
s := &cat[FunctionDegrees(D) : D in s];
if not s eq [] then s := Min(s); end if;
s;

// Degree >1 places: [4]
// Rat-places: [2, 2, 2] (only multiplicities >1 are listed).
s := {(cuspsum + P1 + 1*Q1+1*Q2+1*Q3) : P1 in Places(AFF,4), Q1 in plc1, Q2 in plc1, Q3 in orbs};
print "The number of RR-computations to be done for this case is:",
#s;
s := &cat[FunctionDegrees(D) : D in s];
if not s eq [] then s := Min(s); end if;
s;

// Degree >1 places: [6]
// Rat-places: [2] (only multiplicities >1 are listed).
s := {(cuspsum + P1 + 1*Q1) : P1 in Places(AFF,6), Q1 in orbs};
print "The number of RR-computations to be done for this case is:",
#s;
s := &cat[FunctionDegrees(D) : D in s];
if not s eq [] then s := Min(s); end if;
s;

// Degree >1 places: [7]
// Rat-places: [] (only multiplicities >1 are listed).
s := {(cuspsum + P1) : P1 in Places(AFF,7)};
print "The number of RR-computations to be done for this case is:",
#s;
s := &cat[FunctionDegrees(D) : D in s];
if not s eq [] then s := Min(s); end if;
s;

// Degree >1 places: [3, 3]
// Rat-places: [2] (only multiplicities >1 are listed).
s := {(cuspsum + P1+P2 + 1*Q1) : P1 in Places(AFF,3), P2 in Places(AFF,3), Q1 in orbs};
print "The number of RR-computations to be done for this case is:",
#s;
s := &cat[FunctionDegrees(D) : D in s];
if not s eq [] then s := Min(s); end if;
s;

// Degree >1 places: [3, 4]
// Rat-places: [] (only multiplicities >1 are listed).
s := {(cuspsum + P1+P2) : P1 in Places(AFF,3), P2 in Places(AFF,4)};
print "The number of RR-computations to be done for this case is:",
#s;
s := &cat[FunctionDegrees(D) : D in s];
if not s eq [] then s := Min(s); end if;
s;
                  

// Degree >1 places: []
// Rat-places: [2, 2, 2, 5] (only multiplicities >1 are listed).
s := {(cuspsum + 1*Q1+1*Q2+1*Q3+4*Q4) : Q1 in plc1, Q2 in plc1, Q3 in plc1, Q4 in orbs};
  
// Degree >1 places: []
// Rat-places: [2, 2, 3, 4] (only multiplicities >1 are listed).
s := s join {(cuspsum + 1*Q1+1*Q2+2*Q3+3*Q4) : Q1 in plc1, Q2 in plc1, Q3 in plc1, Q4 in orbs};

// Degree >1 places: []
// Rat-places: [2, 3, 3, 3] (only multiplicities >1 are listed).
s := s join {(cuspsum + 1*Q1+2*Q2+2*Q3+2*Q4) : Q1 in plc1, Q2 in plc1, Q3 in plc1, Q4 in orbs};
  
// Degree >1 places: []
// Rat-places: [2, 2, 2, 2, 3] (only multiplicities >1 are listed).
s := s join {(cuspsum + 1*Q1+1*Q2+1*Q3+1*Q4+2*Q5) : Q1 in plc1, Q2 in plc1, Q3 in plc1, Q4 in plc1, Q5 in orbs};
print "The number of RR-computations to be done for this case is:",
#s;
s := &cat[FunctionDegrees(D) : D in s];
if not s eq [] then s := Min(s); end if;
s;
  
