A<x,y> := PolynomialRing(GF(2),2);
P,homogenize := Homogenization(A);
print("f := An improved equation for X1(57) reduced mod 2");
f := (y^2+y+1)*(y^3+y+1)*(y+1)^2*(y^6+y^4+y^2+y+1)*y^5*(y^5+y^3+1)*x^19+(y^2+y+1)^15*x+(y+1)^8*x^26+(y+1)^10*x^30+(y^2+y+1)^15+(y^2+y+1)*(y+1)^6*(y^8+y^4+y^3+y^2+1)*x^27+(y+1)^8*(y^8+y^5+y^3+y+1)*(y^5+y^4+y^2+y+1)*x^24+(y^16+y^14+y^11+y^10+y^9+y^8+y^7+y^6+y^5+y+1)*(y^2+y+1)*(y+1)^5*x^21+(y^16+y^11+y^10+y^9+y^7+y^4+1)*(y+1)^3*(y^3+y^2+1)*x^20+(y^2+y+1)^2*(y^12+y^11+y^10+y^8+1)^2*y^2*x^14+(y^13+y^11+y^9+y^8+y^4+y^2+1)*(y^2+y+1)^3*(y^11+y^2+1)*x^13+(y^18+y^17+y^16+y^15+y^14+y^13+y^11+y^10+y^7+y^6+y^5+y^4+1)*(y^8+y^7+y^6+y^4+y^2+y+1)*(y^2+y+1)^2*x^12+(y^2+y+1)^3*(y^20+y^16+y^15+y^13+y^12+y^8+y^4+y^3+y^2+y+1)*y^4*x^11+(y^2+y+1)^4*(y^3+y^2+1)^2*(y^8+y^4+y^3+y+1)^2*x^10+(y^2+y+1)^5*(y^19+y^18+y^17+y^16+y^15+y^11+y^10+y^8+y^6+y^5+y^2+y+1)*y*x^8+(y^2+y+1)*(y^3+y+1)*(y+1)^10*x^29+(y^4+y^3+1)^2*(y^2+y+1)^6*(y^5+y^3+y^2+y+1)^2*x^6+(y^2+y+1)^6*(y^17+y^16+y^14+y^12+y^11+y^10+y^8+y^7+y^6+y^5+y^3+y+1)*y*x^5+(y^2+y+1)^7*(y^10+y^8+y^6+y^5+1)*(y^6+y^5+y^2+y+1)*x^4+(y^2+y+1)^4*(y^22+y^21+y^19+y^18+y^16+y^14+y^13+y^12+y^11+y^9+y^8+y^6+y^4+y^2+1)*x^9+(y^9+y^8+y^7+y^6+y^4+y^3+1)^2*(y+1)^2*x^18+(y+1)^10*y*x^28+(y^2+y+1)^14*y^2*x^2+(y^2+y+1)*(y^28+y^24+y^21+y^20+y^17+y^16+y^14+y^10+y^8+y^7+y^4+y^3+1)*x^15+(y^2+y+1)^5*(y^20+y^16+y^15+y^14+y^12+y^10+y^8+y^3+1)*x^7+(y+1)^20*y^2*x^22+(y^8+y^7+y^5+y^4+y^3+y^2+1)*(y^2+y+1)^7*(y^4+y^3+y^2+y+1)*(y^4+y+1)*x^3+(y^9+y^8+y^7+y^6+y^4+y^3+1)^2*(y^2+y+1)*(y^3+y+1)*(y+1)^2*x^17+(y^2+y+1)*(y^9+y^5+1)*(y^7+y^5+y^4+y^3+1)*(y+1)^4*x^23+(y^2+y+1)*(y^5+y^4+y^3+y+1)*(y+1)^7*y*x^25+(y^7+y^3+1)*(y^14+y^12+y^10+y^9+y^7+y^6+y^3+y^2+1)*(y+1)*(y^6+y^4+y^2+y+1)*y*x^16 ;

f := homogenize(f);
XF2 := Scheme(ProjectiveSpace(P),f);
FF := FunctionField(XF2);
AFF := AlgorithmicFunctionField(FF);
plc1 := Places(AFF,1);
plc2 := Places(AFF,2);
divgrp := DivisorGroup(AFF);
cuspsum :=  &+plc1;
cuspsum2 := &+plc2;

function FunctionDegrees(divisor)
    constantField := ConstantField(FunctionField(divisor));
    space,map := RiemannRochSpace(divisor);
    return [Degree(map(i)) : i in space | map(i) notin constantField];
end function;
function Run(s)
   return {Sort(FunctionDegrees(D)) : D in s};                  // for the actual proof
   // return Dimension(RiemannRochSpace(SetToSequence(s)[1]));  // for testing the file
end function;

// Part I covered all partitions that included a place of degree > 2, all partitions
// that involve only deg1 places, and all partitions that involve both deg1 and deg2
// for which:
//
//      max(multiplicity of deg1 places) + max(multiplicity of deg2 places) <= 4


// Partitions not yet covered in Part I are listed below.

// One deg-2 place with multiplicity 1, and the multiplicities > 2 of the deg-1 places are:
//  [<= 9], [3, <= 7], [4, <= 6], [5, 5], [3, 3, <= 5], [3, 4, 4]
//
Run({
	3*cuspsum + cuspsum2 + 2*plc1[1],                      // [3, 3, <= 5]
	4*cuspsum + plc2[1],                                   // [3, 4, 4]
	2*cuspsum + cuspsum2 + 5*plc1[1] + 3*(&+plc1[1..4]),   //
	2*cuspsum + cuspsum2 + 5*plc1[1] + 3*(&+plc1[5..8]),   //
	2*cuspsum + cuspsum2 + 5*plc1[1] + 3*(&+plc1[9..12]),  // [<= 9], [3, <= 7], [4, <= 6], [5, 5]
	2*cuspsum + cuspsum2 + 5*plc1[1] + 3*(&+plc1[13..16]), //
	2*cuspsum + cuspsum2 + 5*plc1[1] + 3*(&+plc1[17..18])  //
});

print("Not all cases are covered yet, continued in X1_57_Part_III.m");

// Remains to do:

// Two deg-2 places (counting with multiplicity), and the multiplicities > 1 of the
// deg1 places and the multiplicities of the deg2 places are:
//
// {[[7], [2]], [[7], [1, 1]], [[2, 6], [2]], [[2, 6], [1, 1]], [[3, 5], [2]], [[3, 5], [1, 1]], [[4, 4], [2]], [[4, 4], [1, 1]],
// [[2, 2, 5], [2]], [[2, 2, 5], [1, 1]], [[2, 3, 4], [2]], [[2, 3, 4], [1, 1]], [[3, 3, 3], [2]], [[2, 2, 2, 4], [2]],
// [[2, 2, 2, 4], [1, 1]], [[2, 2, 3, 3], [2]], [[2, 2, 2, 2, 3], [2]]}
//
// Syntax [[ multiplicity of deg1 places with 1's omitted], [multiplicity of deg2 places]]


// Three deg-2 places (counting with multiplicity), and the multiplicities > 1 of the
// deg1 places and the multiplicities of the deg2 places are:
//
// {[[5], [3]], [[5], [1, 2]], [[5], [1, 1, 1]], [[2, 4], [3]], [[2, 4], [1, 2]], [[2, 4], [1, 1, 1]], [[3, 3], [3]],
// [[3, 3], [1,2]], [[2, 2, 3], [3]], [[2, 2, 3], [1, 2]], [[2, 2, 2, 2], [3]]}


// Four resp. five deg-2 places (counting with multiplicity), and the multiplicities > 1
// of the deg1 places and the multiplicities of the deg2 places are:
//
// {[[3], [4]], [[3], [1, 3]], [[3], [2, 2]], [[3], [1, 1, 2]], [[2, 2], [4]], [[2, 2], [1, 3]]}
//
// resp.
//
// {[[], [5]], [[], [1, 4]]}
