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;

// The partitions not yet covered in Part I and II are summarized in the rest of this file,
// and will then be covered in this file (Part III) and the next file (Part IV).

// 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]]}
//
// Among these partitions, there are those of the form 1,1 := [[..], [1, 1]]
// and those of form 2:  [[..], [2]]
// Those of form 1,1 have two degree-2 multiplicity-1 places, and their degree-1
// places whose multiplicities are > 1 have multiplicity:
//
//	{[7], [2, 6], [3, 5], [4, 4], [2, 2, 5], [2, 3, 4], [2, 2, 2, 4]}
//
// All of those can be covered by:
//
// 	2*cuspsum + cuspsum2 + 5*plc1[1] + 3*Deg1Place
//
// and this was done in Part II  (treating several Deg1Places at the same time).
//
// Next, lets look at form 2:  [[..], [2]],  these are partitions with one
// degree-2 place, with multiplicity 2.  Their degree-1 places whose multiplicities
// are more than 1 have multiplicity:
// {[7], [2, 6], [3, 5], [4, 4], [2, 2, 5], [2, 3, 4], [3, 3, 3], [2, 2, 2, 4], [2, 2, 3, 3], [2, 2, 2, 2, 3]}
//
// The multiplicities > 2 are of the form:
//
//	{[<= 7], [<= 4, <=5], [3, 3, 3]}
//
// The case [3,3,3] will be covered by "3*cuspsum + 3*plc2[1] + 1*partA" in Part IV.
//
// Remains to do: [<= 7] and [<=4, <=5]  (with the rest of the deg1 places having mult <= 2).


Deg1PartA := &+plc1[1..9];
Deg1PartB := &+plc1[10..18];

Deg2PartA := &+plc2[1..3];
Deg2PartB := &+plc2[4..6];
Deg2PartC := &+plc2[7..9];

// Covers: [<= 7] and [<=4, <=5].
Run({
	2*cuspsum + 3*plc1[1] + 2*(D1+D2) : D1 in [Deg1PartA, Deg1PartB], D2 in [Deg2PartA, Deg2PartB, Deg2PartC]
});

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


// The partitions below are covered in Part IV.
//
// 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 or five deg-2 places (counting with multiplicity),
// and the multiplicities > 1 of the deg1 places and
// the multiplicities of the deg2 places are indicated as [[deg1 mult's], [deg2 mult's]]
// where deg=1 mult=1 is omitted as before:
//
// [[3], [4]]    and [[3], [1, 3]]
// [[3], [2, 2]] and [[3], [1, 1, 2]]
// [[2, 2], [4]] and [[2, 2], [1, 3]]
// [[],     [5]] and [[],     [1, 4]]
//
// Note: cases where
//	max(multiplicity of deg1 places) + max(multiplicity of deg2 places) <= 4
// were already handled in Part I.
