A<x,y> := PolynomialRing(GF(5),2);
P,homogenize := Homogenization(A);

print("f := an improved polynomial for X1(36)");
f := x^2*y^11+x*(2*x+1)*(x^2-2*x+2)*y^10+(1+8*x^4+6*x-2*x^5-5*x^3-5*x^2+x^6)*y^9+(-6*x^4+12*x^5-23*x^2+13*x^3-2*x^6+3+5*x+x^7)*y^8+(-8*x+23*x^3+32*x^5+4+3*x^7-5*x^6-16*x^4-32*x^2)*y^7+(x-1)*(5*x^6+6*x^5+29*x^4+63*x^3+37*x^2+22*x-3)*y^6+(x-1)*(x^7+2*x^6+26*x^5+10*x^4+112*x^3+24*x^2+25*x-1)*y^5+x*(x-1)*(3*x^6-3*x^5+42*x^4-3*x^3+109*x^2+6*x+16)*y^4+x*(x-1)*(4*x^6-2*x^5+35*x^4-x^3+57*x^2+6)*y^3+x*(x-1)*(x^2+1)*(3*x^4+15*x^2+1)*y^2+x^3*(x-1)*(x^4+6*x^2+2)*y+x^5*(x-1) ;


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];
load "function_degrees.m";

print("The number of places of degrees 1-5:");
[#Places(AFF,i) : i in [1..5]];
// [ 15, 5, 49, 144, 660 ]

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

// Take the sum of the first 7 rational places:
cuspsum := &+ div1[1..7];
// Note: Unlike the other files, cuspsum has only a subset of the rational places!

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



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