A<y,x> := PolynomialRing(GF(3),2);
P,homogenize := Homogenization(A);
print("f := an improved polynomial for X1(40)");
f := (y-1)^3*x^15-(5*y+2)*(y-1)^3*x^14+(10*y^3-4*y^2-8*y-3)*(y-1)^2*x^13-(y-1)*(10*y^5-16*y^4-5*y^3+11*y^2-3*y+4)*x^12+(y-1)*(5*y^6-23*y^5+36*y^4-13*y^3-18*y^2+9*y+6)*x^11-(y-1)*(y^7-39*y^6+139*y^5-177*y^4+94*y^3-29*y^2+7*y+6)*x^10-(y-1)*(43*y^7-224*y^6+488*y^5-564*y^4+334*y^3-54*y^2-19*y-6)*x^9+(y-1)*(26*y^8-202*y^7+684*y^6-1196*y^5+1056*y^4-375*y^3-y^2+7*y-6)*x^8+(-3023*y^6-671*y^8+1898*y^7-35*y^2+120*y^9-6+374*y^3+y+2783*y^5-1434*y^4-8*y^10)*x^7+(-1140*y^8+313*y^9-41*y^10-3*y+2434*y^7+388*y^3-36*y^2+4+2783*y^5-1431*y^4-3270*y^6+y^11)*x^6+(9*y^11-3023*y^6-898*y^4-1236*y^8+2252*y^5-84*y^10+405*y^9-7*y+2434*y^7+123*y^3-3+27*y^2)*x^5-(y-1)*(y^11-9*y^10+73*y^9-332*y^8+808*y^7-1090*y^6+790*y^5-262*y^4+9*y^3+14*y^2+2)*x^4+(y-1)*(10*y^10-74*y^9+239*y^8-432*y^7+454*y^6-258*y^5+58*y^4+9*y^3-7*y^2+2*y+1)*x^3-y*(y^9-7*y^8+26*y^7-61*y^6+80*y^5-46*y^4+6*y^3-y^2+3*y-3)*(y-1)^2*x^2+y^2*(y^7-6*y^6+13*y^5-11*y^4+5*y^3-7*y^2+7*y-3)*(y-1)^2*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-8:");
[#Places(AFF,i) : i in [1..8]];
// [ 12, 6, 0, 38, 72, 80, 408, 708]

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

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

// Here we take one element from each of the two orbits under the diamond operators.
// This way, we can save time in some of the searches below.
pl,val := Support(Divisor(AFF.1));
for i in [1..#val] do
      if val[i] eq -3 then
		// a member of the orbit of length 8.
		orb1 := pl[i];
	end if;
end for;

pl,val := Support(Divisor(1 - AFF.1));
for i in [1..#val] do
	if val[i] eq 3 then
		// a member of the orbit of length 4.
		orb2 := pl[i];
	end if;
end for;

orbs := [orb1, orb2];

// The cases below are semi-automatically generated:


// Degree >1 places: []
// Rat-places: [3, 4, 5] (only multiplicities >1 are listed).
s := {(cuspsum + 2*Q1+3*Q2+4*Q3) : 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: []
// Rat-places: [2, 3, 7] (only multiplicities >1 are listed).
s := {(cuspsum + 1*Q1+2*Q2+6*Q3) : 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: [2, 6]
// Rat-places: [] (only multiplicities >1 are listed).
s := {(cuspsum + P1+P2) : P1 in Places(AFF,2), P2 in Places(AFF,6)};
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: [8]
// Rat-places: [] (only multiplicities >1 are listed).
s := {(cuspsum + P1) : P1 in Places(AFF,8)};
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: [2] (only multiplicities >1 are listed).
s := {(cuspsum + P1 + 1*Q1) : P1 in Places(AFF,7), 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: [2, 5]
// Rat-places: [2] (only multiplicities >1 are listed).
s := {(cuspsum + P1+P2 + 1*Q1) : P1 in Places(AFF,2), P2 in Places(AFF,5), 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: [2, 2, 2, 2]
// Rat-places: [] (only multiplicities >1 are listed).
s := {(cuspsum + P1+P2+P3+P4) : P1 in Places(AFF,2), P2 in Places(AFF,2), P3 in Places(AFF,2), P4 in Places(AFF,2)};
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: [2, 2, 4]
// Rat-places: [] (only multiplicities >1 are listed).
s := {(cuspsum + P1+P2+P3) : P1 in Places(AFF,2), P2 in Places(AFF,2), P3 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: [4, 4]
// Rat-places: [] (only multiplicities >1 are listed).
s := {(cuspsum + P1+P2) : P1 in Places(AFF,4), 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: [2]
// Rat-places: [3, 3, 5] (only multiplicities >1 are listed).
s := {(cuspsum + P1 + 2*Q1+2*Q2+4*Q3) : P1 in Places(AFF,2), 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, 2] (only multiplicities >1 are listed).
s := {(cuspsum + P1 + 1*Q1+1*Q2) : P1 in Places(AFF,6), Q1 in plc1, Q2 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: []
// Rat-places: [2, 3, 3, 5] (only multiplicities >1 are listed).
s := {(cuspsum + 1*Q1+2*Q2+2*Q3+4*Q4) : 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: [2, 2, 2]
// Rat-places: [2, 2] (only multiplicities >1 are listed).
s := {(cuspsum + P1+P2+P3 + 1*Q1+1*Q2) : P1 in Places(AFF,2), P2 in Places(AFF,2), P3 in Places(AFF,2), Q1 in plc1, Q2 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: [2, 4]
// Rat-places: [2, 2] (only multiplicities >1 are listed).
s := {(cuspsum + P1+P2 + 1*Q1+1*Q2) : P1 in Places(AFF,2), P2 in Places(AFF,4), Q1 in plc1, Q2 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: [2, 2]
// Rat-places: [2, 2, 3] (only multiplicities >1 are listed).
s := {(cuspsum + P1+P2 + 1*Q1+1*Q2+2*Q3) : P1 in Places(AFF,2), P2 in Places(AFF,2), 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: [4]
// Rat-places: [2, 2, 3] (only multiplicities >1 are listed).
s := {(cuspsum + P1 + 1*Q1+1*Q2+2*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: [5]
// Rat-places: [2, 2, 2] (only multiplicities >1 are listed).
s := {(cuspsum + P1 + 1*Q1+1*Q2+1*Q3) : P1 in Places(AFF,5), 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: [2]
// Rat-places: [2, 2, 2, 3] (only multiplicities >1 are listed).
s := {(cuspsum + P1 + 1*Q1+1*Q2+1*Q3+2*Q4) : P1 in Places(AFF,2), 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: []
// Rat-places: [2, 2, 2, 2, 3] (only multiplicities >1 are listed).
s := {(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;
