/*
Newton polygons test
Nicole Sharp, March 2000
*/


/*
Creation
*/
R<c, d> := PolynomialRing(Integers(), 2);
f := 4*c^6*d^3 + 5*c^2*d^7 + 7*c^3*d^5 + c^10 + d^5;
ND := NewtonPolygon(f);
assert HasPolynomial(ND);
assert Polynomial(ND) eq f;
/* assert ParentRing(ND) eq R; */

P<x> := PuiseuxSeriesRing(FiniteField(3, 2));
S<y> := PolynomialRing(P);
g := y^7 - (x^3 + x^5)*y^5 + (x + x^4 - 9*x^6)*y^4 + y^3 + (x^2 + x^7)*y^2 + x;
NPU := NewtonPolygon(g);
assert HasPolynomial(NPU);
assert Polynomial(NPU) eq g;
assert ParentRing(NPU) eq S;

T<z> := PolynomialRing(Integers());
L<a> := UnramifiedExtension(pAdicRing(5, 50), 3);
L<b> := TotallyRamifiedExtension(L, z^2 + 25*z + 10);
T<z> := PolynomialRing(L);
h := (z - b + a)*(z - b^3 - b^4)*(z - b^4*a + a^2)*(z - b^10*a^3 - b^15);
NLU := NewtonPolygon(h);
assert HasPolynomial(NLU);
assert Polynomial(NLU) eq h;
assert ParentRing(NLU) eq T;

Tq<w> := PolynomialRing(Integers());
Lq<aq> := UnramifiedExtension(pAdicQuotientRing(5, 50), 3);
Lq<bq> := TotallyRamifiedExtension(Lq, w^2 + 25*w + 10);
Tq<w> := PolynomialRing(Lq);
hq := (w - bq + aq)*(w - bq^3 - bq^4)*(w - bq^4*aq + aq^2)*(w - bq^10*aq^3 - bq^15);
NLUq := NewtonPolygon(hq);
assert HasPolynomial(NLUq);
assert Polynomial(NLUq) eq hq;
assert ParentRing(NLUq) eq Tq;

S := [<4, 3>, <1/3, 5>, <5, 6>, <4/5, 8>, <9, 7>, <3, 4>];
NS := NewtonPolygon(S);
assert SequenceToSet(DefiningPoints(NS)) eq SequenceToSet(S);
assert not HasPolynomial(NS);

/*
Faces and Vertices
*/
FD := Faces(ND);
FPU := Faces(NPU);
FLU := Faces(NLU);
FLUq := Faces(NLUq);
FS := Faces(NS);

VD := Vertices(ND);
VPU := Vertices(NPU);
VLU := Vertices(NLU);
VS := Vertices(NS);

assert FD eq InnerFaces(ND);
assert FPU eq InnerFaces(NPU);
assert FLU eq LowerFaces(NLU);
assert FS eq AllFaces(NS);

assert VD eq InnerVertices(ND);
assert VPU eq InnerVertices(NPU);
assert VLU eq LowerVertices(NLU);
assert VS eq AllVertices(NS);

assert InnerFaces(NS) cat OuterFaces(NS) eq AllFaces(NS);
assert SequenceToSet(InnerFaces(NS)) subset SequenceToSet(LowerFaces(NS));

assert SequenceToSet(InnerVertices(NS) cat OuterVertices(NS)) eq SequenceToSet(AllVertices(NS));
assert SequenceToSet(InnerVertices(NS)) subset SequenceToSet(LowerVertices(NS));

G := [GradientVector(FLU[i]) : i in [1 .. #FLU]];
V := [G[i][1]/G[i][2] : i in [1 .. #G]];
assert SequenceToSet(V) eq {3, 0, 10};
E := [EndVertices(FLU[i]) : i in [1 .. #FLU]];
M := [E[i][2][1] - E[i][1][1] : i in [1 .. #E]];
assert SequenceToSet(M) eq {1, 2};

assert SequenceToSet([IsPoint(NS, S[i]) : i in [1 .. #S]]) eq {true};
assert SequenceToSet([FD[i] in FacesContaining(ND, EndVertices(FD[i])[j]) : j in [1, 2], i in [1 .. #FD]]) eq {true};

assert SequenceToSet([IsFace(NPU, <GradientVector(FPU[i])[1], GradientVector(FPU[i])[2], Weight(FPU[i])>) : i in [1 .. #FPU]]) eq {true};
assert not IsFace(NPU, <100, -100, 456>);

assert SequenceToSet([IsVertex(NLU, VLU[i]) : i in [1 .. #VLU]]) eq {true};
assert not IsVertex(NLU, <-1, -1>);

assert SequenceToSet(Coefficients(FaceFunction(FD[#FD]))) subset 
	SequenceToSet(Coefficients(f));
assert SequenceToSet(Coefficients(FaceFunction(FPU[1]))) subset 
	SequenceToSet([RelativePrecision(G) eq 0 or IsZero(G) select G else 
		LeadingTerm(G) : G in Coefficients(g)]);
assert SequenceToSet(Coefficients(FaceFunction(FLU[Floor(#FLU/2)]))) subset 
	SequenceToSet([ChangePrecision(ChangePrecision(H, Valuation(H) + 1), 
	Precision(H)) : H in Coefficients(h)]);
assert SequenceToSet(Coefficients(FaceFunction(FLUq[Floor(#FLUq/2)]))) subset 
	SequenceToSet([Lq!(ResidueClassField(Lq)!(H div bq^Valuation(H)))*bq^
	Valuation(H) : H in Coefficients(hq)]);


/*
PuiseuxExpansions and Roots
Nicole Sutherland July 2001
*/
P<x> := PuiseuxSeriesRing(Rationals());
R<y> := PolynomialRing(P);
f := y^3 + 2*x^-1*y^2 + 1*x^-2*y + 2*x;
F := Roots(f, 20);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 20 : r in F];
F := Roots(f);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq P`Precision : r in F];
f := f^2;
F := Roots(f, 20);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 20 : r in F];
assert &and[r[2] eq 2 : r in F];
F := Roots(f, 5);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 5 : r in F];
assert &and[r[2] eq 2 : r in F];
F := Roots(f, 10);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 10 : r in F];
assert &and[r[2] eq 2 : r in F];
F := Roots(f, 7);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 7 : r in F];
assert &and[r[2] eq 2 : r in F];
F := Roots(f, 9);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 9 : r in F];
assert &and[r[2] eq 2 : r in F];

F := PuiseuxExpansion(f, 9);
assert &and[RelativePrecision(Evaluate(f, r)) eq 0 : r in F];
assert &and[RelativePrecision(r) eq 9 : r in F];
F := PuiseuxExpansion(f, 11);
assert &and[RelativePrecision(Evaluate(f, r)) eq 0 : r in F];
assert &and[RelativePrecision(r) eq 11 : r in F];
F := PuiseuxExpansion(f, 13);
assert &and[RelativePrecision(Evaluate(f, r)) eq 0 : r in F];
assert &and[RelativePrecision(r) eq 13 : r in F];

P<x> := PuiseuxSeriesRing(Rationals() : Precision := 30);
R<y> := PolynomialRing(P);
f := y^3 + 2*x^-1*y^2 + 1*x^-2*y + 2*x;
f := f^2;
F := PuiseuxExpansion(f, 13);
assert &and[RelativePrecision(Evaluate(f, r)) eq 0 : r in F];
assert &and[RelativePrecision(r) eq 13 : r in F];
F := PuiseuxExpansion(f, 14);
assert &and[RelativePrecision(Evaluate(f, r)) eq 0 : r in F];
assert &and[RelativePrecision(r) eq 14 : r in F];

F := Roots(f, 10);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 10 : r in F];
assert &and[r[2] eq 2 : r in F];
F := Roots(f, 12);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 12 : r in F];
assert &and[r[2] eq 2 : r in F];
F := Roots(f, 14);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 14 : r in F];
assert &and[r[2] eq 2 : r in F];
F := Roots(f, 16);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 16 : r in F];
assert &and[r[2] eq 2 : r in F];
F := Roots(f, 17);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 17 : r in F];
assert &and[r[2] eq 2 : r in F];
F := Roots(f, 19);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 19 : r in F];
assert &and[r[2] eq 2 : r in F];
F := Roots(f, 21);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 21 : r in F];
assert &and[r[2] eq 2 : r in F];
F := Roots(f, 22);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 22 : r in F];
assert &and[r[2] eq 2 : r in F];

P<x> := PuiseuxSeriesRing(FiniteField(5));
R<y> := PolynomialRing(P);
f := (y^2 - x^3)^2 - y*x^6;
F := Roots(f, 10);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 10/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 1 : r in F];
f := f^2 - y*x^15;
F := Roots(f);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq P`Precision/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 1 : r in F];

P<x> := PuiseuxSeriesRing(Rationals());
R<y> := PolynomialRing(P);
f := (y^2 - x^3)^2 - y*x^6;
c := PuiseuxExpansion(f, 0);
A<a> := Parent(c[1]);
assert &and[RelativePrecision(Evaluate(f, r)) eq 0 : r in c];
c1 := ExpandToPrecision(f, c[1], 10);
assert RelativePrecision(Evaluate(f, c1)) eq 0;
assert RelativePrecision(c1) eq 10/ExponentDenominator(c1);
c1 := ExpandToPrecision(f, c1, 50);
assert RelativePrecision(Evaluate(f, c1)) eq 0;
assert RelativePrecision(c1) eq 50/ExponentDenominator(c1);
c1 := ExpandToPrecision(f, a^(3/2) + 1/2*a^(9/4) + O(a^(11/4)), 20);
assert RelativePrecision(Evaluate(f, c1)) eq 0;
assert RelativePrecision(c1) eq 20/ExponentDenominator(c1);

P<x> := PuiseuxSeriesRing(Rationals());
R<y> := PolynomialRing(P);
f := y^3 + 2/x*y^2 + 1/x^2*y + 2*x;
c := PuiseuxExpansion(f, 10);
assert &and[RelativePrecision(Evaluate(f, r)) eq 0 : r in c];
assert &and[RelativePrecision(r) eq 10 : r in c];

f := y^3 + 2/x*y^2 + 1/x^2*y + 4*x;
c := PuiseuxExpansion(f, 15);
assert &and[RelativePrecision(Evaluate(f, r)) eq 0 : r in c];
assert &and[RelativePrecision(r) eq 15 : r in c];

P<x> := PuiseuxSeriesRing(Rationals());
R<y> := PolynomialRing(P);
f := y^3 + 2*x^-1*y^2 + 1*x^-2*y + 2*x;
F := Roots(f, 10);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 10 : r in F];
assert &and[r[2] eq 1 : r in F];
f := y^3 + 2*x^-1*y^2 + 1*x^-2*y + 4*x;
F := Roots(f, 10);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 10 : r in F];
assert &and[r[2] eq 1 : r in F];
f := (y^2 + x^3)^2 - y*x^6;
F := Roots(f, 20);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 20/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 1 : r in F];
f := f^2;
F := Roots(f, 10);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 10/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 2 : r in F];

P<x> := PuiseuxSeriesRing(Rationals());
R<y> := PolynomialRing(P);
f := (y^2 - x^3)^2 - y*x^6;
c := PuiseuxExpansion(f, 0);
A<a> := Parent(c[1]);
N<n> := CoefficientRing(A);
assert &and[RelativePrecision(Evaluate(f, r)) eq 0 : r in c];
c := PuiseuxExpansion(f, 10);
assert &and[RelativePrecision(Evaluate(f, r)) eq 0 : r in c];
assert &and[RelativePrecision(r) eq 10/ExponentDenominator(r) : r in c];
c1 := ExpandToPrecision(f, -a^(3/2) - 1/2*n*a^(9/4), 30);
assert RelativePrecision(Evaluate(f, c1)) eq 0;
assert RelativePrecision(c1) eq 30/ExponentDenominator(c1);
D := DuvalPuiseuxExpansion(f, 0);
p := ParametrizationToPuiseux(D[1]);
assert &and[RelativePrecision(Evaluate(f, r)) eq 0 : r in p];
D := DuvalPuiseuxExpansion(f, 10);
p := ParametrizationToPuiseux(D[1]);
assert &and[RelativePrecision(Evaluate(f, r)) eq 0 : r in p];
F := Roots(f);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq P`Precision/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 1 : r in F];
F := Roots(f, 30);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 30/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 1 : r in F];
Q<q> := PolynomialRing(A);
F := Roots(Q!f);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq A`Precision/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 1 : r in F];
F := Roots(Q!f, 10);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 10/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 1 : r in F];
f := y^3 + 2*x^-1*y^2 + 1*x^-2*y + 2*x;
f := f^2;
F := Roots(f);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq A`Precision/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 2 : r in F];
F := Roots(f, 10);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 10/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 2 : r in F];
F := Roots(f, 1);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 1/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 2 : r in F];
f := (y^2 - x^3)^2 - y*x^6;
f := f^2;
F := Roots(f);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq P`Precision/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 2 : r in F];
F := Roots(f, 10);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 10/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 2 : r in F];

P<x> := PowerSeriesRing(Rationals() : Precision := 30);
R<y> := PolynomialRing(P);
f := (y - x^3)*(y - x + x^7)*(y - x);
c := PuiseuxExpansion(f, 0);
A<a> := Parent(c[1]);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(PolynomialRing(A)!f, r) : r in c];
D := DuvalPuiseuxExpansion(f, 0);
p1 := ParametrizationToPuiseux(D[1]);
p2 := ParametrizationToPuiseux(D[2]);
p3 := ParametrizationToPuiseux(D[3]);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(PolynomialRing(A)!f, r) : r in p1];
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(PolynomialRing(A)!f, r) : r in p2];
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(PolynomialRing(A)!f, r) : r in p3];
F := Roots(f, 10);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is Evaluate(f, r[1])
: r in F];
assert &and[RelativePrecision(r[1]) ge 10 : r in F];
assert &and[r[2] eq 1 : r in F];
F := Roots(f);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is Evaluate(f, r[1])
: r in F];
assert &and[RelativePrecision(r[1]) ge P`Precision : r in F];
assert &and[r[2] eq 1 : r in F];
F := Roots(f, 1);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is Evaluate(f, r[1])
: r in F];
assert &and[RelativePrecision(r[1]) ge P`Precision : r in F];
assert &and[r[2] eq 1 : r in F];
f := f^2;
c := PuiseuxExpansion(f, 0);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(PolynomialRing(A)!f, r) : r in c];
c := PuiseuxExpansion(f, 10);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(PolynomialRing(A)!f, r) : r in c];
assert &and[RelativePrecision(r) in {10, Infinity()} : r in c];
c := PuiseuxExpansion(f, 2);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(PolynomialRing(A)!f, r) : r in c];
assert &and[RelativePrecision(r) ge 2 : r in c];
c := PuiseuxExpansion(f, 1);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(PolynomialRing(A)!f, r) : r in c];
assert &and[RelativePrecision(r) ge 1 : r in c];
F := Roots(f, 1);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is Evaluate(f, r[1]) :
r in F];
assert &and[RelativePrecision(r[1]) ge 1 : r in F];
assert &and[r[2] eq 2 : r in F];


P<x> := PuiseuxSeriesRing(Rationals());
R<y> := PolynomialRing(P);
f := y^3 + 2*x^-1*y^2 + 1*x^-2*y + 2*x;
D := DuvalPuiseuxExpansion(f, 0);
p := &cat[ParametrizationToPuiseux(d) : d in D];
assert &and[RelativePrecision(Evaluate(f, r)) eq 0 : r in p];
D := DuvalPuiseuxExpansion(f, 10);
p := &cat[ParametrizationToPuiseux(d) : d in D];
assert &and[RelativePrecision(Evaluate(f, r)) eq 0 : r in p];
f := f^2;
D := DuvalPuiseuxExpansion(f, 0);
p := &cat[ParametrizationToPuiseux(d) : d in D];
assert &and[RelativePrecision(Evaluate(f, r)) eq 0 : r in p];
D := DuvalPuiseuxExpansion(f, 10);
p := &cat[ParametrizationToPuiseux(d) : d in D];
assert &and[RelativePrecision(Evaluate(f, r)) eq 0 : r in p];
f := (y - x^3)*(y - x - x^7)^3*(y - x)^2;
D := DuvalPuiseuxExpansion(f, 10);
p := &cat[ParametrizationToPuiseux(d) : d in D];
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is Evaluate(f, r) : r in p];

P<x> := PuiseuxSeriesRing(Rationals());
R<y> := PolynomialRing(P);
f := y^3 + 2*x^-1*y^2 + 1*x^-2*y + 2*x;
F := Roots(f, 1);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 1 : r in F];
assert &and[r[2] eq 1 : r in F];
F := Roots(f, 6);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 6 : r in F];
assert &and[r[2] eq 1 : r in F];
F := Roots(f, 10);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 10 : r in F];
assert &and[r[2] eq 1 : r in F];
F := Roots(f, 20);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 20 : r in F];
assert &and[r[2] eq 1 : r in F];
F := Roots(f, 100);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 100 : r in F];
assert &and[r[2] eq 1 : r in F];
 
f := (y^2 - x^3)^2 - y*x^6;
F := Roots(f, 10);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 10/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 1 : r in F];
F := Roots(f, 20);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 20/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 1 : r in F];
F := Roots(f, 30);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 30/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 1 : r in F];
F := Roots(f, 40);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 40/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 1 : r in F];

f := (-x^3 + x^4) - 2*x^2*y - x*y^2 + 2*x*y^4 + y^5;
F := Roots(f, 5);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 5/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 1 : r in F];
F := Roots(f, 10);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 10/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 1 : r in F];
F := Roots(f, 20);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 20/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 1 : r in F];

P<x> := PuiseuxSeriesRing(Rationals());
R<y> := PolynomialRing(P);
f := (y^2 - x^3);
c := PuiseuxExpansion(f, 0);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(f, r) : r in c];
c := PuiseuxExpansion(f, 4);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(f, r) : r in c];
assert &and[p eq 4/d or p eq Infinity() where p is RelativePrecision(r) 
where d is ExponentDenominator(r) : r in c];
c := PuiseuxExpansion(f, 4 : PreciseRoot := true);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(f, r) : r in c];
assert &and[RelativePrecision(r) eq Infinity() : r in c];
r := ExpandToPrecision(f, c[1], 60);
assert RelativePrecision(e) eq 0 or IsZero(e) where e is Evaluate(f, r);
assert p eq 60/d or p eq Infinity() 
	where p is RelativePrecision(r) where d is ExponentDenominator(r);
c := PuiseuxExpansion(f, 60);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(f, r) : r in c];
assert &and[RelativePrecision(r) eq 60/ExponentDenominator(r) : r in c];
r := ExpandToPrecision(f, c[1], 30);
assert RelativePrecision(e) eq 0 or IsZero(e) where e is Evaluate(f, r);
assert p eq 30/d or p eq Infinity() 
	where p is RelativePrecision(r) where d is ExponentDenominator(r);
r := ExpandToPrecision(f, c[1], 70 : PreciseRoot := true);
assert RelativePrecision(e) eq 0 or IsZero(e) where e is Evaluate(f, r);
assert p eq 70/d or p eq Infinity() 
	where p is RelativePrecision(r) where d is ExponentDenominator(r);

f2 := y^3 + 2/x*y^2 + 1/x^2*y + 4*x;
c := PuiseuxExpansion(f2, 10);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(f2, r) : r in c];
assert &and[RelativePrecision(r) eq 10/ExponentDenominator(r) : r in c];
r := ExpandToPrecision(f2, c[1], 20);
assert RelativePrecision(e) eq 0 or IsZero(e) where e is Evaluate(f2, r);
assert p eq 20/d or p eq Infinity() 
	where p is RelativePrecision(r) where d is ExponentDenominator(r);
r := ExpandToPrecision(f2, r, 15);
assert RelativePrecision(e) eq 0 or IsZero(e) where e is Evaluate(f2, r);
assert p eq 15/d or p eq Infinity() 
	where p is RelativePrecision(r) where d is ExponentDenominator(r);

P<x> := PuiseuxSeriesRing(Rationals());
R<y> := PolynomialRing(P);
f := y^4 - x^(1/3)*y^3 + x^(5/2)*y^2 + (x^(4/5) - 4*x^7)*y - x^(1/12);
F := Roots(f, 50);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 50/Lcm(ExponentDenominator(r[1]), pd) : r in F] where pd is Lcm([ExponentDenominator(c) : c in Coefficients(f)]);
assert &and[r[2] eq 1 : r in F];
 

P<x> := PuiseuxSeriesRing(Rationals() : Precision := 25);
R<y> := PolynomialRing(P);
f := ((y^2 - x^3)^2 - y*x^6)^2 - y*x^15;
c := PuiseuxExpansion(f, 10);
A<a> := Parent(c[1]);
N<n> := CoefficientRing(A);
Q<q> := PolynomialRing(A);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(f, r) : r in c];
assert &and[p eq 10/d or p eq Infinity() where p is RelativePrecision(r)
where d is ExponentDenominator(r) : r in c];

f := ((y^2 + x^3)^2 + y*x^6)^2 + y*x^15;
c := PuiseuxExpansion(f, 5);
A<a> := Parent(c[1]);
N<n> := CoefficientRing(A);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(f, r) : r in c];
assert &and[p ge 5/d or p eq Infinity() where p is RelativePrecision(r)
where d is ExponentDenominator(r) : r in c];

f := ((y^2 - x^3)^2 - y*x^6)^2 + y*x^15;
c := PuiseuxExpansion(f, 7);
A<a> := Parent(c[1]);
N<n> := CoefficientRing(A);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(f, r) : r in c];
assert &and[p eq 7/d or p eq Infinity() where p is RelativePrecision(r)
where d is ExponentDenominator(r) : r in c];

P<x> := PuiseuxSeriesRing(Rationals());
R<y> := PolynomialRing(P);
f := (-x^3 + x^4) - 2*x^2*y - x*y^2 + 2*x*y^4 + y^5;
c := PuiseuxExpansion(f, 10);
A<a> := Parent(c[1]);
N<n> := CoefficientRing(A);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(f, r) : r in c];
assert &and[p eq 10/d or p eq Infinity() where p is RelativePrecision(r)
where d is ExponentDenominator(r) : r in c];

r := ExpandToPrecision(f, -a - a^(3/2), 10);
assert RelativePrecision(e) eq 0 or IsZero(e) where e is Evaluate(f, r);
assert p eq 10/d or p eq Infinity() where p is RelativePrecision(r)
where d is ExponentDenominator(r);
assert IsPartialRoot(f, -a);

assert IsPartialRoot(f, -a + a^(3/2));
assert IsPartialRoot(f, a^(1/3));
assert not IsUniquePartialRoot(f, -a);

D := DuvalPuiseuxExpansion(f, 0);
p1 := ParametrizationToPuiseux(D[1]);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(f, r) : r in p1];
p2 := ParametrizationToPuiseux(D[2]);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(f, r) : r in p2];
D := DuvalPuiseuxExpansion(f, 10);
p1 := ParametrizationToPuiseux(D[1]);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(f, r) : r in p1];
p2 := ParametrizationToPuiseux(D[2]);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(f, r) : r in p2];

F := Roots(f, 30);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 30/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 1 : r in F];

f := f^2;
c := PuiseuxExpansion(f, 10);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(f, r) : r in c];
assert &and[p eq 10/d or p eq Infinity() where p is RelativePrecision(r)
where d is ExponentDenominator(r) : r in c];

F := Roots(f, 40);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 40/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 2 : r in F];

P<x> := PuiseuxSeriesRing(FiniteField(5));
R<y> := PolynomialRing(P);
f := (y^2 - x^3)^5 - 2*y*x^6;
c := PuiseuxExpansion(f, 5);
A<a> := Parent(c[1]);
N<n> := CoefficientRing(A);
assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(f, r) : r in c];
assert &and[p eq 5/d or p eq Infinity() where p is RelativePrecision(r)
where d is ExponentDenominator(r) : r in c];

F := Roots(f);
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 20/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 1 : r in F];

assert IsPartialRoot(f, 2*a^9);
assert IsUniquePartialRoot(f, 2*a^9);

/*
for expansions

assert &and[RelativePrecision(e) eq 0 or IsZero(e) where e is
Evaluate(f, r) : r in c];
assert &and[p eq 7/d or p eq Infinity() where p is RelativePrecision(r)
where d is ExponentDenominator(r) : r in c];

for Roots
assert &and[RelativePrecision(Evaluate(f, r[1])) eq 0 : r in F];
assert &and[RelativePrecision(r[1]) eq 20/ExponentDenominator(r[1]) : r in F];
assert &and[r[2] eq 1 : r in F];
*/
