/*
Test multivariate factorization over Z, etc.
AKS 4/10/95.
*/


SetAssertions(true);
VERB := false;
// SetEchoInput(true);

Z := IntegerRing();

test_fact_set := procedure(Q)
    S := { Abs(PrimitivePart(f)): f in Q };
    if VERB then
	print "";
	print "S:", S;
    end if;
    P := &*S;
    time PF := Factorization(P);
    if { t[1]: t in PF } ne S then
	print S, "FAILS";
	print "Factorization:", PF;
	error "";
    end if;
end procedure;

test_fact_seq := procedure(Q)
    P := &*Q;
    L := Factorization(P);
    assert L eq Sort([<Normalize(f), 1>: f in Q]);
end procedure;

test_fact := procedure(F)
    if VERB then
	print "";
	if #Terms(F) gt 50 then
	    print "F: [", #Terms(F), "terms ]";
	else
	    print "F:", F;
	end if;
    end if;
    time Q := Factorization(F);
    if VERB then
	print "Factorization:", Q;
    end if;
    if &*[t[1]^t[2]: t in Q] ne Normalize(F) then
	F, "FAILS";
	"Factorization:", Q;
	error "";
    end if;
    if not forall{t: t in Q | IsIrreducible(t[1])} then
	F, "FAILS";
	"Reducible factor:", Q;
	error "";
    end if;

    F2 := F^2;
    l, G := IsSquare(F^2);
    assert l and G^2 eq F^2;
end procedure;

ran := func<k | Ranbig(k)>;

P<a,b,c,d> := PolynomialRing(Z, 4);

A := b*c*d*(b+c+d);
B := a*c*d*(a+c+d);
C := b*a*d*(b+a+d);
D := b*a*c*(b+a+c);
T := (A + B - C - D)^2 - 4*A*B - 4*C*D;
U := T^2 - 64*A*B*C*D;
test_fact(U);


P<x, y, z> := PolynomialRing(Z, 3);

test_fact_set({ -y*x+1, (-y+z)*x + y, (y+z)^1*x^5-z });
test_fact_set({ (2*y+z)^3*x+3*z, 6*y*(y+1)*x + z*(z+1)*(z+2)*(z+3)*(z+4) });
test_fact_set(
    {
	55555555555555555555*x^3 + 1125899906842625*x*y + 11231*z,
	88888888888888888888*y^5 + 1048576*y*z + 1152921504606846977*x
    }
);
test_fact_set({ x^i + y^j + z^k: i, j, k in [1..2] });
test_fact_set({ (y^i+z^j)*x^k + 1: i,j in [1..2], k in [1..3] });

// Wang paper:
test_fact(
    (4*z^2*y^4 + 4*z^3*y^3 - 4*z^4*y^2 - 4*z^5*y)*x^6 +
    (z^3*y^4 + 12*z*y^3 + (-z^5+12*z^2)*y^2 - 12*z^3*y - 12*z^4)*x^5 +
    (
        8*y^4 + (6*z^2 + 8*z)*y^3 + (-4*z^4 + 4*z^3 - 8*z^2)*y^2 +
        (-4*z^5 - 2*z^4 - 8*z^3)*y
    )*x^4 +
    (
        2*z*y^4 + z^3*y^3 + (-z^5 - 2*z^3 + 9*z)*y^2 +
        (-12*z^3 + 12*z^2)*y - 12*z^4 + 3*z^3
    )*x^3 +
    (6*y^3 + (-6*z^2+8*z)*y^2 + (-2*z^4-8*z^3+2*z^2)*y)*x^2 +
    (2*z*y^3 - 2*z^3*y^2 - 3*z*y + 3*z^3)*x
    -2*y^2 + 2*z^2*y
);

test_fact_set(
    { ran(50) * x^2 + ran(50) * y + ran(50) * z + 1: i in [1..3] }
);

test_fact_set(
    { ran(300) * x^5*y^2 + ran(300) * y*z + ran(300) * x*z + 1: i in [1..3] }
);

P<f1, f2, f3, f4, f5, f6, f7> := PolynomialRing(Z, 7);
F := f3^6 - f4^6*f5^6*f6^2*f7^2;
for i := 1 to 20 do test_fact(F); end for;

_<x1,z1,x2,z2>:=PolynomialRing(Rationals(),4);
F := -1/4*x1^2*x2*z2 + 1/2*x1^2*z2^2 - 1/4*x1*z1*x2^2 + 5/6*x1*z1*x2*z2 -
    3/2*x1*z1*z2^2 + 1/12*z1^2*x2^2 - 13/12*z1^2*x2*z2 + z1^2*z2^2;
for i := 1 to 20 do test_fact(F); end for;

P<f1, f2, f3, f4, f5, f6> := PolynomialRing(GF(3), 6);
F := f3^8 + f3^4*f5^15*f6^24 + f3^4*f5^5*f6^8 +
	f5^30*f6^48 + 2*f5^25*f6^40 + 2*f5^15*f6^24 + f5^10*f6^16;
L := Factorization(F);
assert L eq
[
    <f3^4 + f3^2*f5^5*f6^8 + 2*f5^15*f6^24 + 2*f5^10*f6^16 + 2*f5^5*f6^8, 1>,
    <f3^4 + 2*f3^2*f5^5*f6^8 + 2*f5^15*f6^24 + 2*f5^10*f6^16 + 2*f5^5*f6^8, 1>
];


P<f1, f2, f3, f4, f5, f6> := PolynomialRing(GF(2), 6);
f:=
f1^3*f2*f4^2 + f1^3*f2*f4 + f1^3*f3*f4^2 + f1^3*f3*f4*f6 +
    f1^3*f3*f4 + f1^2*f2^2*f4*f5 + f1^2*f2^2*f4 + f1^2*f2^2*f5 +
    f1^2*f2^2 + f1^2*f2*f3*f4*f5 + f1^2*f2*f3*f4*f6 + f1^2*f2*f3*f4
    + f1^2*f2*f3*f5*f6 + f1^2*f2*f3*f5 + f1^2*f2*f3 + f1^2*f2*f4*f5
    + f1^2*f3^2*f4*f6 + f1^2*f3^2*f6^2 + f1^2*f3^2*f6 + f1^2*f3*f4^2
    + f1*f2^3*f4^2 + f1*f2^3*f4 + f1*f2^2*f3*f4^2 + f1*f2^2*f3*f4*f5
    + f1*f2^2*f3*f4*f6 + f1*f2^2*f3*f4 + f1*f2^2*f3*f5 +
    f1*f2^2*f5^2 + f1*f2^2*f5 + f1*f2*f3^2*f4*f5 + f1*f2*f3^2*f5*f6
    + f1*f2*f3^2*f5 + f1*f2*f3*f4*f5 + f1*f2*f3*f4 + f1*f2*f3*f5*f6
    + f1*f3^2*f4*f6 + f2^3*f4*f5 + f2^2*f3*f4^2 + f2^2*f3*f5^2 +
    f2*f3^2*f4*f5;
L := Factorization(f);
assert L eq
[
    <f1*f2*f4 + f1*f2 + f1*f3*f4 + f1*f3*f6 + f1*f3 + f2*f5 + f3*f4, 1>,
    <f1^2*f4 + f1*f2*f5 + f1*f2 + f1*f3*f6 + f2^2*f4 + f2*f3*f5, 1>
];

P<a>:=PolynomialRing(Rationals());
_<x,y>:=PolynomialRing(P,2);
f:=a*x;
test_fact(f);
test_fact(a^2*(x+a)^2*(a*(x+a))^4);
test_fact(a*(x+a)*(a*(x+a))^2);


P<x,y> := PolynomialRing(GF(2),2);      
assert SquarefreeFactorization(x^2) eq [<x, 2>];
assert SquarefreeFactorization(x^2*y) eq Sort([<x, 2>, <y, 1>]);
assert SquarefreeFactorization(x^2*y^2) eq Sort([<x, 2>, <y, 2>]);
assert SquarefreePart(x^2) eq x;
assert SquarefreePart(x^2*y) eq x*y;
assert SquarefreePart(x^2*y^2) eq x*y;
assert SquarefreePart(x^2*y^3) eq x*y;

//

//SetVerbose("PolyFact",1);
"Special char 3 fact"; // P Lisonek

P<X,a> := PolynomialRing(GF(3), 2);
L :=
[
    <X^3 + 2*a, 6>,
    <X^3 + X^2 + 2*a, 9>,
    <X^9 + 2*X^3*a + 2*a^3 + 2*a^2, 6>,
    <X^27 + 2*X^18*a + 2*X^9*a^4 + X^9*a^3 + 2*a^9 + 2*a^7, 2>,
    <X^81 + 2*X^63*a + X^54*a^4 + 2*X^54*a^3 + 2*X^54*a^2 + 2*X^45*a^4 + 
        2*X^36*a^10 + X^36*a^7 + X^27*a^13 + 2*X^27*a^12 + 2*X^27*a^11 + 
        X^27*a^9 + X^18*a^13 + 2*X^9*a^19 + 2*X^9*a^16 + 2*a^27 + a^22 + 2*a^21 
        + 2*a^20, 2>
];
f := &*[t[1]^t[2]: t in L];
F := Factorization(f);
assert F eq L;
assert forall{t: t in F | IsIrreducible(t[1])};



f4<a>:=GF(2,2);
A2<X,Y>:=AffineSpace(f4,2);
C:=Curve(A2,X^3+Y^2+Y);
K<X,Y>:=FunctionField(C);
R<T>:=PolynomialRing(K);
q:=T^2 + (Y + (a^2*X + a))*T;
L := Factorization(q);
assert L[1,1]*L[2,1] eq q;
assert L[1,2] eq 1 and L[2,2] eq 1;

// AKS, from Tobias Beck

B := RationalField();
F<s> := FunctionField(B);
R := PolynomialRing(F);
g := (R.1^10 + 13*s*R.1^8 + (446/27*s^3 - 2)*R.1^7 +
16/3*s^2*R.1^6 + (11/3*s^4 + 11*s)*R.1^5 + (s^6 + 344/27*s^3 + 1)*R.1^4 +
(125/27*s^5 + 7/12*s^2)*R.1^3 + 173/108*s^4*R.1^2 + (17/12*s^6 + 4/27*s^3)*R.1 +
1/4*s^8 + 1/27*s^5);
// F1 := FunctionField(g);
F1 := quo<R | g>;
AssignNames(~F1, ["alpha_0"]); alpha_0 := F1.1;

P<z> := PolynomialRing(F1);
f := z^5 + 3*z^4 + (-s*alpha_0 + 3)*z^3 + (-alpha_0^3 -
3*s*alpha_0 - s^3 + 1)*z^2 + (2*s^2*alpha_0^2 - 2*s*alpha_0 - s^3)*z +
s^2*alpha_0^2;

"Factorization over function field (TB)";
time L := Factorization(f);
assert #L eq 2 and [<Degree(t[1]), t[2]>: t in L] eq [ <1, 2>, <3, 1> ];
assert &*[t[1]^t[2]: t in L] eq Normalize(f);

R<p10,g0,g1,g2,g3,g4,X1,X2>:=PolynomialRing(IntegerRing(), 8);
f := -p10^170*X1^10*X2^10 + p10^130*X1^10*X2^5 + p10^130*X1^5*X2^10 -
    p10^90*X1^5*X2^5 + p10^80*X1^5*X2^5 - p10^40*X1^5 - p10^40*X2^5 + 1;
time L := Factorization(f);
assert L eq
[
    <p10^8*X2 - 1, 1>,
    <p10^8*X1 - 1, 1>,
    <p10^18*X1*X2 - 1, 1>,
    <p10^32*X2^4 + p10^24*X2^3 + p10^16*X2^2 + p10^8*X2 + 1, 1>,
    <p10^32*X1^4 + p10^24*X1^3 + p10^16*X1^2 + p10^8*X1 + 1, 1>,
    <p10^72*X1^4*X2^4 + p10^54*X1^3*X2^3 + p10^36*X1^2*X2^2 + p10^18*X1*X2 + 1,
    1>
];

"Factorization over algebraic function field over GF(3)";
k:=GF(3);
K<t>:=RationalFunctionField(k);
r<x>:=PolynomialRing(K);
F<eta>:=FunctionField(2*(1+x^2)^6*(1+x^4)-t*(x^2-1)^8);
R<X>:=PolynomialRing(F);
f := X^8+X^6-t;
time L := Factorization(f);
assert L eq
[
    <X + (t + 1)*eta^14 + (2*t + 1)*eta^12 + 2*eta^10 + (t + 1)*eta^8 + (2*t + 
        1)*eta^6 + (t + 1)*eta^2 + 2*t, 1>,
    <X + (2*t + 2)*eta^14 + (t + 2)*eta^12 + eta^10 + (2*t + 2)*eta^8 + (t + 
        2)*eta^6 + (2*t + 2)*eta^2 + t, 1>,
    <X^6 + ((t + 1)*eta^12 + 2*eta^10 + eta^8 + (t + 2)*eta^6 + t)*X^4 + ((2*t +
        2)*eta^14 + 2*t*eta^12 + (t + 1)*eta^10 + (t + 1)*eta^8 + 2*t*eta^6 + 
        (2*t + 2)*eta^4 + eta^2 + (2*t + 1))*X^2 + (2*t + 2)*eta^12 + (t + 
        2)*eta^10 + (t + 2)*eta^8 + (2*t + 1)*eta^6 + 2*eta^4 + 2*eta^2 + 2, 1>
];
assert &*[t[1]: t in L] eq Normalize(f);

f := (2*t + 2)*X^16 + 2*t*X^14 + (2*t + 2)*X^12 + (2*t + 1)*X^10 +
    2*t*X^8 + (2*t + 1)*X^6 + (2*t + 2)*X^4 + 2*t*X^2 + 2*t + 2;
time L := Factorization(f);
assert L eq
[
    <X + eta, 1>,
    <X + 2*eta, 1>,
    <X + eta^15 + t/(t + 1)*eta^13 + eta^11 + (t + 2)/(t + 1)*eta^9 + t/(t + 
        1)*eta^7 + (t + 2)/(t + 1)*eta^5 + eta^3 + t/(t + 1)*eta, 1>,
    <X + 2*eta^15 + 2*t/(t + 1)*eta^13 + 2*eta^11 + (2*t + 1)/(t + 1)*eta^9 + 
        2*t/(t + 1)*eta^7 + (2*t + 1)/(t + 1)*eta^5 + 2*eta^3 + 2*t/(t + 1)*eta,
    1>,
    <X^12 + (2*eta^14 + 2*t/(t + 1)*eta^12 + 2*eta^10 + (2*t + 1)/(t + 1)*eta^8 
        + 2*t/(t + 1)*eta^6 + (2*t + 1)/(t + 1)*eta^4)*X^10 + (2*eta^12 + 2*t/(t
        + 1)*eta^10 + 2*eta^8 + (2*t + 1)/(t + 1)*eta^6 + 1/(t + 1)*eta^4 + 1/(t
        + 1)*eta^2 + 1)*X^8 + (2*eta^14 + 2*t/(t + 1)*eta^12 + eta^10 + eta^8 + 
        2*t/(t + 1)*eta^6 + 2*eta^4 + 1/(t + 1)*eta^2)*X^6 + (2*eta^12 + 2*t/(t 
        + 1)*eta^10 + 2*eta^8 + (2*t + 1)/(t + 1)*eta^6 + 1/(t + 1)*eta^4 + 1/(t
        + 1)*eta^2 + 1)*X^4 + (2*eta^14 + 2*t/(t + 1)*eta^12 + 2*eta^10 + (2*t +
        1)/(t + 1)*eta^8 + 2*t/(t + 1)*eta^6 + (2*t + 1)/(t + 1)*eta^4)*X^2 + 1,
    1>
];
assert &*[t[1]: t in L] eq Normalize(f);

///

"Bivariate over non-standard extension";
F:=GF(3); _<u>:=PolynomialRing(F);
FF<I>:=ext<F|u^2+1>;
_<y>:=PolynomialRing(FF);
f := y * (y^6 + y^5 - y^3 + y^2 - 1)^4 / (y^2 - y - 1)^12;
K<u,v>:=PolynomialRing(FF,2);
F:=Numerator(Evaluate(f,u)-Evaluate(f,v));
time L:=Factorization(F);
assert #L eq 3;
assert &*[t[1]: t in L] eq Normalize(F);
assert L[1] eq <u - v, 1>;

///

l, S := IsIntrinsic("SetDpolyCheck");
if l then
    _ := eval "S(false); return 1;";
end if;

procedure test_aff_fact(K, D)
    "Factorization over algebraic function field over", K;

    L<a4,a6>:=RationalFunctionField(K, 2);

    P<T>:=PolynomialRing(L);
    g:=-1728*T^8 - 13824*a6*T^6 + (-4608*a4^3 - 31104*a6^2)*T^4 + 1024*a4^6
    + 13824*a4^3*a6^2 + 46656*a6^4;
    A:=quo<P|g/LeadingCoefficient(g)>;
    h:=T^8 + (12*a4^3*a6 + 72*a6^3)/(a4^6 + 18*a4^3*a6^2 + 81*a6^4)*T^6 +
        2/(a4^3 + 9*a6^2)*T^4 - 1/3/(a4^6 + 18*a4^3*a6^2 + 81*a6^4);

    hA:=Polynomial(A,h);
    _<x> := Parent(hA);
    time L := Factorization(hA);

    assert &*[t[1]^t[2]: t in L] eq Normalize(hA);
    assert [Degree(t[1]): t in L] eq D;

end procedure;

test_aff_fact(GF(5), [1, 1, 6]);
test_aff_fact(GF(7), [1, 1, 3, 3]);
test_aff_fact(GF(1009), [1, 1, 3, 3]);
test_aff_fact(RationalField(), [1, 1, 6]);

/////////////

for K in <RationalField(), GF(3), GF(5), GF(7)> do
    "Non-monic def poly over func field over", K;

    F<t> := FunctionField(K);
    P<x> := PolynomialRing(F);
    f := x^8 + 8*x^6 + (-44*t^2 + 20)/(t^2 + 1)*x^4 + (48*t^4 - 64*t^2 + 16)/
    (t^4 + 2*t^2 + 1)*x^2 + (36*t^4 - 24*t^2 + 4)/(t^6 + 3*t^4 + 3*t^2 + 1);
    time L := Factorization(Polynomial(FunctionField(f), f));
    f := &*[t[1]^t[2]: t in L];
    assert [Degree(t[1]): t in L] eq [1, 1, 1, 1, 2, 2];
end for;

/////////////
// Orig from MG, Aug 09

"Factorization with deflation";

P<a,b,c,d> := PolynomialRing(Z, 4);

L := [
    <d - 1, 5>, <d + 1, 5>, <d^2 + 1, 5>, <d^2 - d + 1, 5>, <d^2 + d + 1, 5>, 
    <d^4 + 1, 5>, <d^4 - d^2 + 1, 5>, <d^6 - d^3 + 1, 1>, <d^6 + d^3 + 1, 1>, 
    <d^8 + 1, 2>, <d^8 - d^4 + 1, 5>, <d^12 - d^6 + 1, 1>, <d^16 + 1, 1>, <d^16 
    - d^8 + 1, 2>, <d^24 - d^12 + 1, 1>, <d^32 - d^16 + 1, 1>, <c - 1, 1>, <c + 
    1, 1>, <c - d^2, 1>, <c + d^2, 1>, <c*d^2 - 1, 1>, <c*d^2 + 1, 1>, <c^2 + 1,
    1>, <c^2 + d^4, 1>, <c^2 - c + 1, 1>, <c^2 + c + 1, 1>, <c^2 - c*d^2 + d^4, 
    1>, <c^2 + c*d^2 + d^4, 1>, <c^2*d^4 + 1, 1>, <c^2*d^4 - c*d^2 + 1, 1>, 
    <c^2*d^4 + c*d^2 + 1, 1>, <c^4 + 1, 1>, <c^4 + d^8, 1>, <c^4 - c^2 + 1, 1>, 
    <c^4 - c^2*d^4 + d^8, 1>, <c^4*d^8 + 1, 1>, <c^4*d^8 - c^2*d^4 + 1, 1>, <c^8
    - c^4 + 1, 1>, <c^8 - c^4*d^8 + d^16, 1>, <c^8*d^16 - c^4*d^8 + 1, 1>, <b - 
    1, 1>, <b + 1, 1>, <b^2 + 1, 1>, <b^2 - b + 1, 1>, <b^2 + b + 1, 1>, <b^4 + 
    1, 1>, <b^4 - b^2 + 1, 1>, <b^8 - b^4 + 1, 1>, <a - 1, 5>, <a + 1, 5>, <a - 
    d, 3>, <a + d, 3>, <a - d^2, 1>, <a + d^2, 1>, <a - d^3, 1>, <a + d^3, 1>, 
    <a*d - 1, 1>, <a*d + 1, 1>, <a*d - b, 1>, <a*d + b, 1>, <a*d^2 - 1, 3>, 
    <a*d^2 + 1, 3>, <a*d^3 - 1, 1>, <a*d^3 + 1, 1>, <a*d^4 - 1, 1>, <a*d^4 + 1, 
    1>, <a*b*d - 1, 1>, <a*b*d + 1, 1>, <a^2 + 1, 5>, <a^2 - d, 1>, <a^2 + d, 
    1>, <a^2 + d^2, 3>, <a^2 + d^4, 1>, <a^2 + d^6, 1>, <a^2 - c, 1>, <a^2 + c, 
    1>, <a^2 - a + 1, 5>, <a^2 + a + 1, 5>, <a^2 - a*d + d^2, 3>, <a^2 + a*d + 
    d^2, 3>, <a^2 - a*d^2 + d^4, 1>, <a^2 + a*d^2 + d^4, 1>, <a^2 - a*d^3 + d^6,
    1>, <a^2 + a*d^3 + d^6, 1>, <a^2*d - 1, 2>, <a^2*d + 1, 2>, <a^2*d^2 + 1, 
    1>, <a^2*d^2 + b^2, 1>, <a^2*d^2 - a*d + 1, 1>, <a^2*d^2 + a*d + 1, 1>, 
    <a^2*d^2 - a*b*d + b^2, 1>, <a^2*d^2 + a*b*d + b^2, 1>, <a^2*d^4 + 1, 3>, 
    <a^2*d^4 - a*d^2 + 1, 3>, <a^2*d^4 + a*d^2 + 1, 3>, <a^2*d^6 + 1, 1>, 
    <a^2*d^6 - a*d^3 + 1, 1>, <a^2*d^6 + a*d^3 + 1, 1>, <a^2*d^8 + 1, 1>, 
    <a^2*d^8 - a*d^4 + 1, 1>, <a^2*d^8 + a*d^4 + 1, 1>, <a^2*c - 1, 1>, <a^2*c +
    1, 1>, <a^2*b^2*d^2 + 1, 1>, <a^2*b^2*d^2 - a*b*d + 1, 1>, <a^2*b^2*d^2 + 
    a*b*d + 1, 1>, <a^3 - d, 1>, <a^3 + d, 1>, <a^3*d - 1, 1>, <a^3*d + 1, 1>, 
    <a^3*d^2 - 1, 1>, <a^3*d^2 + 1, 1>, <a^4 + 1, 5>, <a^4 + d^2, 1>, <a^4 + 
    d^4, 3>, <a^4 + d^8, 1>, <a^4 + d^12, 1>, <a^4 + c^2, 1>, <a^4 - a^2 + 1, 
    5>, <a^4 - a^2*d + d^2, 1>, <a^4 + a^2*d + d^2, 1>, <a^4 - a^2*d^2 + d^4, 
    3>, <a^4 - a^2*d^4 + d^8, 1>, <a^4 - a^2*d^6 + d^12, 1>, <a^4 - a^2*c + c^2,
    1>, <a^4 + a^2*c + c^2, 1>, <a^4*d^2 + 1, 2>, <a^4*d^2 - a^2*d + 1, 2>, 
    <a^4*d^2 + a^2*d + 1, 2>, <a^4*d^4 + 1, 1>, <a^4*d^4 + b^4, 1>, <a^4*d^4 - 
    a^2*d^2 + 1, 1>, <a^4*d^4 - a^2*b^2*d^2 + b^4, 1>, <a^4*d^8 + 1, 3>, 
    <a^4*d^8 - a^2*d^4 + 1, 3>, <a^4*d^12 + 1, 1>, <a^4*d^12 - a^2*d^6 + 1, 1>, 
    <a^4*d^16 + 1, 1>, <a^4*d^16 - a^2*d^8 + 1, 1>, <a^4*c^2 + 1, 1>, <a^4*c^2 -
    a^2*c + 1, 1>, <a^4*c^2 + a^2*c + 1, 1>, <a^4*b^4*d^4 + 1, 1>, <a^4*b^4*d^4 
    - a^2*b^2*d^2 + 1, 1>, <a^6 + d^2, 1>, <a^6 - a^3 + 1, 1>, <a^6 + a^3 + 1, 
    1>, <a^6 - a^3*d + d^2, 1>, <a^6 + a^3*d + d^2, 1>, <a^6*d^2 + 1, 1>, 
    <a^6*d^2 - a^3*d + 1, 1>, <a^6*d^2 + a^3*d + 1, 1>, <a^6*d^4 + 1, 1>, 
    <a^6*d^4 - a^3*d^2 + 1, 1>, <a^6*d^4 + a^3*d^2 + 1, 1>, <a^8 + 1, 3>, <a^8 +
    d^4, 1>, <a^8 + c^4, 1>, <a^8 - a^4 + 1, 5>, <a^8 - a^4*d^2 + d^4, 1>, <a^8 
    - a^4*d^4 + d^8, 3>, <a^8 - a^4*d^8 + d^16, 1>, <a^8 - a^4*d^12 + d^24, 1>, 
    <a^8 - a^4*c^2 + c^4, 1>, <a^8*d^4 + 1, 2>, <a^8*d^4 - a^4*d^2 + 1, 2>, 
    <a^8*d^8 + 1, 2>, <a^8*d^8 - a^4*d^4 + 1, 1>, <a^8*d^8 - a^4*b^4*d^4 + b^8, 
    1>, <a^8*d^16 + 1, 1>, <a^8*d^16 - a^4*d^8 + 1, 3>, <a^8*d^24 - a^4*d^12 + 
    1, 1>, <a^8*d^32 - a^4*d^16 + 1, 1>, <a^8*c^4 + 1, 1>, <a^8*c^4 - a^4*c^2 + 
    1, 1>, <a^8*b^8*d^8 - a^4*b^4*d^4 + 1, 1>, <a^12 + d^4, 1>, <a^12 - a^6 + 1,
    1>, <a^12 - a^6*d^2 + d^4, 1>, <a^12*d^4 + 1, 1>, <a^12*d^4 - a^6*d^2 + 1, 
    1>, <a^12*d^8 + 1, 1>, <a^12*d^8 - a^6*d^4 + 1, 1>, <a^16 + 1, 1>, <a^16 - 
    a^8 + 1, 3>, <a^16 - a^8*d^4 + d^8, 1>, <a^16 - a^8*c^4 + c^8, 1>, <a^16*d^8
    + 1, 1>, <a^16*d^8 - a^8*d^4 + 1, 2>, <a^16*d^16 - a^8*d^8 + 1, 2>, 
    <a^16*d^32 - a^8*d^16 + 1, 1>, <a^16*c^8 - a^8*c^4 + 1, 1>, <a^24 - a^12 + 
    1, 1>, <a^24 - a^12*d^4 + d^8, 1>, <a^24*d^8 - a^12*d^4 + 1, 1>, <a^24*d^16 
    - a^12*d^8 + 1, 1>, <a^32 - a^16 + 1, 1>, <a^32*d^16 - a^16*d^8 + 1, 1>
];

S := [
    <d^96 + d^72 + 2*d^48 + d^24 + 1, 1>,
    <c^24 - 1, 1>,
    <c^48*d^48 - c^24*d^96 - c^24 + d^48, 1>,
    <b^24 - 1, 1>,
    <a^48*b^24*d^48 - a^24*b^48*d^24 - a^24*d^24 + b^24, 1>,
    <a^96 + a^72 + 2*a^48 + a^24 + 1, 1>,
    <a^96*c^24 - a^48*c^48 - a^48 + c^24, 1>,
    <a^456*d^336 - a^432*d^408 - a^432*d^384 - a^432*d^312 + a^432*d^288 - 
        a^432*d^264 - a^432*d^240 + a^408*d^456 + a^408*d^384 - a^408*d^360 + 
        3*a^408*d^312 + a^408*d^288 - a^408*d^264 + a^408*d^240 - a^408*d^192 + 
        a^408*d^168 + 2*a^384*d^408 - 2*a^384*d^384 - 3*a^384*d^360 + 
        2*a^384*d^336 - 2*a^384*d^312 - 2*a^384*d^288 + 3*a^384*d^264 - 
        a^384*d^240 - 2*a^384*d^216 + a^384*d^192 + a^384*d^168 - a^384*d^144 + 
        a^384*d^120 - a^360*d^480 + 2*a^360*d^432 + 4*a^360*d^360 - a^360*d^336 
        - 3*a^360*d^312 + 6*a^360*d^288 - 3*a^360*d^240 + 4*a^360*d^216 - 
        2*a^360*d^168 + a^360*d^144 - a^360*d^96 - a^336*d^480 + a^336*d^456 - 
        2*a^336*d^432 - a^336*d^408 + 4*a^336*d^384 - 3*a^336*d^360 - 
        4*a^336*d^336 + 4*a^336*d^312 - 3*a^336*d^288 - 6*a^336*d^264 + 
        4*a^336*d^240 - 4*a^336*d^192 + 4*a^336*d^168 + a^336*d^144 - 
        2*a^336*d^120 + a^336*d^96 - a^312*d^456 - 2*a^312*d^432 + 3*a^312*d^408
        - 2*a^312*d^384 - 3*a^312*d^360 + 8*a^312*d^336 - a^312*d^312 - 
        5*a^312*d^288 + 8*a^312*d^264 - 2*a^312*d^240 - 6*a^312*d^216 + 
        4*a^312*d^192 + a^312*d^168 - 4*a^312*d^144 + a^312*d^120 - 2*a^312*d^72
        + a^288*d^504 + 3*a^288*d^432 - 2*a^288*d^408 - 3*a^288*d^384 + 
        5*a^288*d^360 - 2*a^288*d^336 - 6*a^288*d^312 + 9*a^288*d^288 - 
        9*a^288*d^240 + 7*a^288*d^216 - 5*a^288*d^168 + 5*a^288*d^144 + 
        2*a^288*d^120 - a^288*d^96 + a^288*d^72 + a^288*d^48 - a^264*d^480 + 
        2*a^264*d^456 - a^264*d^432 - 3*a^264*d^408 + 5*a^264*d^384 - 
        4*a^264*d^360 - 6*a^264*d^336 + 9*a^264*d^312 - 6*a^264*d^264 + 
        9*a^264*d^240 + a^264*d^216 - 9*a^264*d^192 + 4*a^264*d^168 + 
        a^264*d^144 - 6*a^264*d^120 + 2*a^264*d^96 - a^264*d^48 + a^240*d^480 + 
        5*a^240*d^408 - 5*a^240*d^360 + 8*a^240*d^336 - 2*a^240*d^312 - 
        9*a^240*d^288 + 11*a^240*d^264 - 8*a^240*d^216 + 8*a^240*d^192 + 
        2*a^240*d^168 - 5*a^240*d^144 + 3*a^240*d^120 + 3*a^240*d^96 - 
        2*a^240*d^72 + 2*a^240*d^48 + a^240*d^24 - a^216*d^480 - 2*a^216*d^456 +
        2*a^216*d^432 - 3*a^216*d^408 - 3*a^216*d^384 + 5*a^216*d^360 - 
        2*a^216*d^336 - 8*a^216*d^312 + 8*a^216*d^288 - 11*a^216*d^240 + 
        9*a^216*d^216 + 2*a^216*d^192 - 8*a^216*d^168 + 5*a^216*d^144 - 
        5*a^216*d^96 - a^216*d^24 + a^192*d^456 - 2*a^192*d^408 + 6*a^192*d^384 
        - a^192*d^360 - 4*a^192*d^336 + 9*a^192*d^312 - a^192*d^288 - 
        9*a^192*d^264 + 6*a^192*d^240 - 9*a^192*d^192 + 6*a^192*d^168 + 
        4*a^192*d^144 - 5*a^192*d^120 + 3*a^192*d^96 + a^192*d^72 - 2*a^192*d^48
        + a^192*d^24 - a^168*d^456 - a^168*d^432 + a^168*d^408 - 2*a^168*d^384 -
        5*a^168*d^360 + 5*a^168*d^336 - 7*a^168*d^288 + 9*a^168*d^264 - 
        9*a^168*d^216 + 6*a^168*d^192 + 2*a^168*d^168 - 5*a^168*d^144 + 
        3*a^168*d^120 + 2*a^168*d^96 - 3*a^168*d^72 - a^168 + 2*a^144*d^432 - 
        a^144*d^384 + 4*a^144*d^360 - a^144*d^336 - 4*a^144*d^312 + 
        6*a^144*d^288 + 2*a^144*d^264 - 8*a^144*d^240 + 5*a^144*d^216 + 
        a^144*d^192 - 8*a^144*d^168 + 3*a^144*d^144 + 2*a^144*d^120 - 
        3*a^144*d^96 + 2*a^144*d^72 + a^144*d^48 - a^120*d^408 + 2*a^120*d^384 -
        a^120*d^360 - 4*a^120*d^336 + 4*a^120*d^312 - 4*a^120*d^264 + 
        6*a^120*d^240 + 3*a^120*d^216 - 4*a^120*d^192 + 4*a^120*d^168 + 
        3*a^120*d^144 - 4*a^120*d^120 + a^120*d^96 + 2*a^120*d^72 - a^120*d^48 +
        a^120*d^24 + a^96*d^408 - a^96*d^360 + 2*a^96*d^336 - 4*a^96*d^288 + 
        3*a^96*d^264 - 6*a^96*d^216 + 3*a^96*d^192 + a^96*d^168 - 4*a^96*d^144 -
        2*a^96*d^72 + a^96*d^24 - a^72*d^384 + a^72*d^360 - a^72*d^336 - 
        a^72*d^312 + 2*a^72*d^288 + a^72*d^264 - 3*a^72*d^240 + 2*a^72*d^216 + 
        2*a^72*d^192 - 2*a^72*d^168 + 3*a^72*d^144 + 2*a^72*d^120 - 2*a^72*d^96 
        - a^48*d^336 + a^48*d^312 - a^48*d^264 + a^48*d^240 - a^48*d^216 - 
        3*a^48*d^192 + a^48*d^144 - a^48*d^120 - a^48*d^48 + a^24*d^264 + 
        a^24*d^240 - a^24*d^216 + a^24*d^192 + a^24*d^120 + a^24*d^96 - d^168, 
    1>,
    <d^24 + 1, 2>,
    <a^72*d^48 + a^48*d^24 - a^24*d^24 - 1, 2>,
    <a^24 + 1, 3>,
    <a^48*d^48 - a^24*d^72 - a^24 + d^24, 3>,
    <d^24 - 1, 5>,
    <a^24 - 1, 5>
];

time f := &*[t[1]^t[2]: t in S];
time L2 := Factorization(f);
assert L2 eq L;

/////////////
// PM, Sep 10

K:=GF(2^5);
R<x,y> := PolynomialRing(K,2);
f := (x^63-1) div (x-1);
g := (y^63-1) div (y-1);
F := (f-g) div (x-y);
time L := Factorization(F);
assert #L eq 2;

/////////////
// Jan 11

p := 79;
R<[x]> := PolynomialRing(GF(p),4);
f1 := x[1] + 61*x[2] + 14*x[3] + 54*x[4];
f2 := x[1]^2 + 52*x[1]*x[2] + 61*x[1]*x[3] + 52*x[1]*x[4]
    + 50*x[2]^2 + 31*x[2]*x[3] + 25*x[2]*x[4] + 36*x[3]^2
    + 47*x[3]*x[4] + 47*x[4]^2;
f := f1*f2;
L := Factorization(f);
assert L eq [<f1, 1>, <f2, 1>];

///////////////

R3<[x]> := PolynomialRing(GF(3),4);
f := x[1]^2 + 2*x[2]^2 + x[2]*x[3] + 2*x[2]*x[4]
    + 2*x[3]^2 + x[3]*x[4] + 2*x[4]^2;
L := Factorization(f);
assert L eq [<f, 1>];

////////////////

P<x,y,z,w> :=  PolynomialRing(GF(5), 4);
f := 3*x^3 + 3*x^2*z + 3*x^2*w + x*y^2 + 3*x*y*z + 4*x*y*w + x*w^2 + y^3
+ 2*y^2*z + 4*y^2*w + 2*y*z*w + 3*y*w^2 +4*z^3 + 3*w^3;
test_fact_seq([f]);
test_fact_seq([f, f + 1]);
test_fact_seq([f + c: c in [0 .. 4]]);
test_fact_seq([f + c: c in [0, 1, x, y, z, w]]);
test_fact_seq([f + c^2: c in [0, 1, x, y, z, w]]);
test_fact_seq([f + L[i]*L[j]: j in [1 .. i - 1], i in [1 .. #L]]
    where L:= [1, -1, x, y, z, w]);

//////////////// Sep 2012

P<a,b,c,d,e,f,g,h,x>:=PolynomialRing(Rationals(),9);
L :=
[
    <a*b*c*f^2 + a*c*d*g^2 - a*c*h^2 - a*d*e^2 - b*c + 1/48*x, 1>,
    <a^2*b^2*c^2*f^4 - 5/2*a^2*b*c^2*d*f^2*g^2 - 2*a^2*b*c^2*f^2*h^2 + 
        5/2*a^2*b*c*d*e^2*f^2 + a^2*c^2*d^2*g^4 - 2*a^2*c^2*d*g^2*h^2 + 
        a^2*c^2*h^4 - 2*a^2*c*d^2*e^2*g^2 + 2*a^2*c*d*e^2*h^2 + a^2*d^2*e^4 - 
        2*a*b^2*c^2*f^2 + 5/2*a*b*c^2*d*g^2 + 2*a*b*c^2*h^2 - 5/2*a*b*c*d*e^2 + 
        1/96*a*b*c*f^2*x + 1/96*a*c*d*g^2*x - 1/96*a*c*h^2*x - 1/96*a*d*e^2*x + 
        b^2*c^2 - 1/96*b*c*x - 1/4608*x^2, 1>
];
f := L[1,1] * L[2, 1];
for i := 1 to 10 do
    assert Factorization(f) eq L;
end for;


//////////////// Feb 2013 (test over function field; orig from MG, 2003)

K<w> := GF(2, 3);
P<x,y>:=PolynomialRing(K, 2);
g := x^6*y^7 + x^5*y^7 + x^4*y^7 + x^3*y^7 + x^2*y^14 + x^2 + x*y^14 +
    x + y^21 + y^14 + y^7 + 1;
FF<a,b> := FunctionField(g);
P_FF<z>:=PolynomialRing(FF);
f := z^21 + (FF.1^2 + FF.1 + 1)*z^14 + (FF.1^2*FF.2^14 + FF.1^2 + FF.1*FF.2^14
    + FF.1 + FF.2^21 + FF.2^14 + 1)/FF.2^7*z^7 + FF.1^2 + FF.1 + 1;
time r := Roots(f);
assert #r eq Degree(f);
assert &*[z - t[1]: t in r] eq f;

//////////////// Mar 2013 (Stuck in evaluation loop on Hensel fail)

P<x,y,z,w> := PolynomialRing(GF(5),4);
f := -4*x^2*z + 5*x^2*w + 7*x*y*z - 10*x*y*w - 3*x*z^2 + 8*x*z*w -
3*x*w^2 - 3*y^2*z + 5*y^2*w + 2*y*z^2 - 6*y*z*w + 2*y*w^2 - 3*z^3 +
13*z^2*w - 18*z*w^2 + 8*w^3;
assert #Factorization(f) eq 1;

//////////////// Sep 2014 (GCD handling bad prime wrongly)

R<x1,x2,x3,x4> := PolynomialRing(IntegerRing(),4);
f := 29863479889565217561237477930*x1 -
494208470496363445237582170615*x2 +
945949281092565382750471421368*x3 - 492208250621843886360799394994*x4;
assert Factorization(f^2) eq [<f, 2>];

//////////////// Sep 2016

P<H,x,y> := PolynomialRing(GF(2), 3);
f := H^527 + H^523*x^3*y + H^523*y^4 + x^527;
assert IsHomogeneous(f);
assert Factorization(f) eq [<f, 1>];

//////////////// Nov 2016

P<x,y> := PolynomialRing(Z, 2);
f := x^64 + 3*x^63*y^4 + 20*x^63*y^2 + 21*x^63 + 4*x^62*y^6 + 57*x^62*y^4 + 
    128*x^62*y^2 + 56*x^62 - 2*x^61*y^8 + 68*x^61*y^6 + 363*x^61*y^4 + 
    413*x^61*y^2 + 115*x^61 - 4*x^60*y^10 + 14*x^60*y^8 + 507*x^60*y^6 + 
    1232*x^60*y^4 + 824*x^60*y^2 + 126*x^60 - x^59*y^12 - 52*x^59*y^10 + 
    320*x^59*y^8 + 2131*x^59*y^6 + 2908*x^59*y^4 + 1208*x^59*y^2 + 115*x^59 - 
    63*x^58*y^12 - 128*x^58*y^10 + 2007*x^58*y^8 + 5818*x^58*y^6 + 4817*x^58*y^4
    + 1249*x^58*y^2 + 56*x^58 - 35*x^57*y^14 - 443*x^57*y^12 + 577*x^57*y^10 + 
    7291*x^57*y^8 + 11615*x^57*y^6 + 6151*x^57*y^4 + 987*x^57*y^2 + 21*x^57 - 
    10*x^56*y^16 - 439*x^56*y^14 - 1247*x^56*y^12 + 4792*x^56*y^10 + 
    17722*x^56*y^8 + 17265*x^56*y^6 + 5852*x^56*y^4 + 538*x^56*y^2 + x^56 - 
    248*x^55*y^16 - 2144*x^55*y^14 - 742*x^55*y^12 + 17002*x^55*y^10 + 
    32025*x^55*y^8 + 19995*x^55*y^6 + 4336*x^55*y^4 + 214*x^55*y^2 - 
    76*x^54*y^18 - 1806*x^54*y^16 - 5725*x^54*y^14 + 6468*x^54*y^12 + 
    39010*x^54*y^10 + 43771*x^54*y^8 + 17726*x^54*y^6 + 2317*x^54*y^4 + 
    45*x^54*y^2 - 5*x^53*y^20 - 921*x^53*y^18 - 7067*x^53*y^16 - 8053*x^53*y^14 
    + 27851*x^53*y^12 + 65840*x^53*y^10 + 46895*x^53*y^8 + 12206*x^53*y^6 + 
    914*x^53*y^4 + 6*x^53*y^2 - 271*x^52*y^20 - 5123*x^52*y^18 - 17447*x^52*y^16
    - 152*x^52*y^14 + 64019*x^52*y^12 + 84003*x^52*y^10 + 38499*x^52*y^8 + 
    6098*x^52*y^6 + 208*x^52*y^4 - 27*x^51*y^22 - 2364*x^51*y^20 - 
    17171*x^51*y^18 - 27953*x^51*y^16 + 28541*x^51*y^14 + 103612*x^51*y^12 + 
    83238*x^51*y^10 + 24146*x^51*y^8 + 2112*x^51*y^6 + 29*x^51*y^4 - 
    653*x^50*y^22 - 10798*x^50*y^20 - 39407*x^50*y^18 - 25385*x^50*y^16 + 
    75706*x^50*y^14 + 123697*x^50*y^12 + 62021*x^50*y^10 + 10342*x^50*y^8 + 
    314*x^50*y^6 - 3*x^50*y^4 - 72*x^49*y^24 - 4390*x^49*y^22 - 32190*x^49*y^20 
    - 64240*x^49*y^18 + 3483*x^49*y^16 + 121536*x^49*y^14 + 111533*x^49*y^12 + 
    33186*x^49*y^10 + 2323*x^49*y^8 - 59*x^49*y^6 - 2*x^48*y^26 - 1026*x^48*y^24
    - 17323*x^48*y^22 - 68855*x^48*y^20 - 74262*x^48*y^18 + 51846*x^48*y^16 + 
    134365*x^48*y^14 + 70581*x^48*y^12 + 9284*x^48*y^10 - 607*x^48*y^8 - 
    52*x^48*y^6 - 73*x^47*y^26 - 5807*x^47*y^24 - 46670*x^47*y^22 - 
    110112*x^47*y^20 - 54648*x^47*y^18 + 92156*x^47*y^16 + 102976*x^47*y^14 + 
    24980*x^47*y^12 - 2200*x^47*y^10 - 687*x^47*y^8 - 4*x^47*y^6 - 921*x^46*y^26
    - 20293*x^46*y^24 - 93319*x^46*y^22 - 135371*x^46*y^20 - 17049*x^46*y^18 + 
    87666*x^46*y^16 + 40651*x^46*y^14 - 6565*x^46*y^12 - 4413*x^46*y^10 - 
    276*x^46*y^8 + 67*x^45*y^28 - 4494*x^45*y^26 - 49935*x^45*y^24 - 
    143533*x^45*y^22 - 130008*x^45*y^20 + 6494*x^45*y^18 + 35123*x^45*y^16 - 
    15835*x^45*y^14 - 16345*x^45*y^12 - 2549*x^45*y^10 - 39*x^45*y^8 + 
    20*x^44*y^30 + 313*x^44*y^28 - 14130*x^44*y^26 - 92712*x^44*y^24 - 
    176513*x^44*y^22 - 109969*x^44*y^20 - 19128*x^44*y^18 - 40091*x^44*y^16 - 
    44499*x^44*y^14 - 13028*x^44*y^12 - 865*x^44*y^10 + 483*x^43*y^30 + 
    1263*x^43*y^28 - 31056*x^43*y^26 - 134163*x^43*y^24 - 180517*x^43*y^22 - 
    106375*x^43*y^20 - 84484*x^43*y^18 - 91173*x^43*y^16 - 42202*x^43*y^14 - 
    6193*x^43*y^12 - 130*x^43*y^10 + 78*x^42*y^32 + 2898*x^42*y^30 + 
    4245*x^42*y^28 - 51047*x^42*y^26 - 157775*x^42*y^24 - 174524*x^42*y^22 - 
    146652*x^42*y^20 - 153550*x^42*y^18 - 100085*x^42*y^16 - 26334*x^42*y^14 - 
    1913*x^42*y^12 - 4*x^42*y^10 + 2*x^41*y^34 + 1124*x^41*y^32 + 
    11284*x^41*y^30 + 12409*x^41*y^28 - 62904*x^41*y^26 - 157863*x^41*y^24 - 
    183668*x^41*y^22 - 207096*x^41*y^20 - 177733*x^41*y^18 - 73716*x^41*y^16 - 
    11127*x^41*y^14 - 300*x^41*y^12 + 148*x^40*y^34 + 6256*x^40*y^32 + 
    31479*x^40*y^30 + 29485*x^40*y^28 - 59893*x^40*y^26 - 154850*x^40*y^24 - 
    223863*x^40*y^22 - 248354*x^40*y^20 - 151418*x^40*y^18 - 39726*x^40*y^16 - 
    3177*x^40*y^14 - 13*x^40*y^12 + 5*x^39*y^36 + 1769*x^39*y^34 + 
    22345*x^39*y^32 + 68903*x^39*y^30 + 57956*x^39*y^28 - 44031*x^39*y^26 - 
    164047*x^39*y^24 - 261236*x^39*y^22 - 230148*x^39*y^20 - 95104*x^39*y^18 - 
    14949*x^39*y^16 - 473*x^39*y^14 + 205*x^38*y^36 + 8972*x^38*y^34 + 
    57616*x^38*y^32 + 121935*x^38*y^30 + 91983*x^38*y^28 - 34701*x^38*y^26 - 
    190503*x^38*y^24 - 262532*x^38*y^22 - 165733*x^38*y^20 - 44360*x^38*y^18 - 
    3742*x^38*y^16 - 28*x^38*y^14 + 7*x^37*y^38 + 2088*x^37*y^36 + 
    29707*x^37*y^34 + 115147*x^37*y^32 + 181472*x^37*y^30 + 123359*x^37*y^28 - 
    35685*x^37*y^26 - 196890*x^37*y^24 - 204235*x^37*y^22 - 87258*x^37*y^20 - 
    13790*x^37*y^18 - 439*x^37*y^16 + 205*x^36*y^38 + 9800*x^36*y^36 + 
    70606*x^36*y^34 + 184812*x^36*y^32 + 230701*x^36*y^30 + 137811*x^36*y^28 - 
    44273*x^36*y^26 - 164696*x^36*y^24 - 118016*x^36*y^22 - 31378*x^36*y^20 - 
    2371*x^36*y^18 - 4*x^36*y^16 + 4*x^35*y^40 + 1932*x^35*y^38 + 
    29736*x^35*y^36 + 128741*x^35*y^34 + 246863*x^35*y^32 + 261503*x^35*y^30 + 
    143259*x^35*y^28 - 27489*x^35*y^26 - 88842*x^35*y^24 - 39893*x^35*y^22 - 
    4626*x^35*y^20 + 121*x^35*y^18 - x^35*y^16 + 150*x^34*y^40 + 8259*x^34*y^38 
    + 63856*x^34*y^36 + 185061*x^34*y^34 + 281531*x^34*y^32 + 269548*x^34*y^30 +
    145205*x^34*y^28 + 15576*x^34*y^26 - 11871*x^34*y^24 + 1447*x^34*y^22 + 
    1726*x^34*y^20 + 88*x^34*y^18 + x^33*y^42 + 1363*x^33*y^40 + 22328*x^33*y^38
    + 101625*x^33*y^36 + 216184*x^33*y^34 + 289303*x^33*y^32 + 272583*x^33*y^30 
    + 167486*x^33*y^28 + 76659*x^33*y^26 + 37311*x^33*y^24 + 12224*x^33*y^22 + 
    1289*x^33*y^20 + 4*x^33*y^18 + 77*x^32*y^42 + 5129*x^32*y^40 + 
    40025*x^32*y^38 + 119618*x^32*y^36 + 209755*x^32*y^34 + 279003*x^32*y^32 + 
    274058*x^32*y^30 + 195837*x^32*y^28 + 114099*x^32*y^26 + 45493*x^32*y^24 + 
    7949*x^32*y^22 + 279*x^32*y^20 + 698*x^31*y^42 + 10815*x^31*y^40 + 
    45662*x^31*y^38 + 99813*x^31*y^36 + 181963*x^31*y^34 + 273767*x^31*y^32 + 
    286436*x^31*y^30 + 218316*x^31*y^28 + 115132*x^31*y^26 + 31572*x^31*y^24 + 
    2889*x^31*y^22 + 13*x^31*y^20 + 26*x^30*y^44 + 1800*x^30*y^42 + 
    9817*x^30*y^40 + 17808*x^30*y^38 + 46192*x^30*y^36 + 153191*x^30*y^34 + 
    269786*x^30*y^32 + 287052*x^30*y^30 + 204278*x^30*y^28 + 83265*x^30*y^26 + 
    14253*x^30*y^24 + 515*x^30*y^22 + 178*x^29*y^44 + 129*x^29*y^42 - 
    14520*x^29*y^40 - 48232*x^29*y^38 - 8821*x^29*y^36 + 144238*x^29*y^34 + 
    269009*x^29*y^32 + 269192*x^29*y^30 + 159182*x^29*y^28 + 45484*x^29*y^26 + 
    4293*x^29*y^24 + 32*x^29*y^22 - x^28*y^46 - 516*x^28*y^44 - 14614*x^28*y^42 
    - 75410*x^28*y^40 - 130242*x^28*y^38 - 40652*x^28*y^36 + 140036*x^28*y^34 + 
    247593*x^28*y^32 + 217458*x^28*y^30 + 98087*x^28*y^28 + 17817*x^28*y^26 + 
    715*x^28*y^24 - 80*x^27*y^46 - 6341*x^27*y^44 - 55527*x^27*y^42 - 
    162271*x^27*y^40 - 186360*x^27*y^38 - 39820*x^27*y^36 + 134043*x^27*y^34 + 
    209172*x^27*y^32 + 150083*x^27*y^30 + 47622*x^27*y^28 + 4863*x^27*y^26 + 
    43*x^27*y^24 - 4*x^26*y^48 - 1474*x^26*y^46 - 26239*x^26*y^44 - 
    125455*x^26*y^42 - 239890*x^26*y^40 - 198651*x^26*y^38 - 34936*x^26*y^36 + 
    107746*x^26*y^34 + 151169*x^26*y^32 + 83586*x^26*y^30 + 17041*x^26*y^28 + 
    738*x^26*y^26 + x^26*y^24 - 128*x^25*y^48 - 7938*x^25*y^46 - 67654*x^25*y^44
    - 202002*x^25*y^42 - 268380*x^25*y^40 - 175947*x^25*y^38 - 36575*x^25*y^36 +
    75705*x^25*y^34 + 94302*x^25*y^32 + 37321*x^25*y^30 + 4273*x^25*y^28 + 
    42*x^25*y^26 - x^24*y^50 - 1369*x^24*y^48 - 25565*x^24*y^46 - 
    124572*x^24*y^44 - 247043*x^24*y^42 - 245872*x^24*y^40 - 158074*x^24*y^38 - 
    53640*x^24*y^36 + 41773*x^24*y^34 + 47673*x^24*y^32 + 12310*x^24*y^30 + 
    595*x^24*y^28 - 78*x^23*y^50 - 6284*x^23*y^48 - 56315*x^23*y^46 - 
    170160*x^23*y^44 - 233072*x^23*y^42 - 200257*x^23*y^40 - 154343*x^23*y^38 - 
    62605*x^23*y^36 + 20014*x^23*y^34 + 19621*x^23*y^32 + 2874*x^23*y^30 + 
    24*x^23*y^28 - 849*x^22*y^50 - 17964*x^22*y^48 - 89601*x^22*y^46 - 
    172734*x^22*y^44 - 177158*x^22*y^42 - 176427*x^22*y^40 - 160898*x^22*y^38 - 
    59211*x^22*y^36 + 7196*x^22*y^34 + 5948*x^22*y^32 + 347*x^22*y^30 - 
    31*x^21*y^52 - 3651*x^21*y^50 - 34935*x^21*y^48 - 101120*x^21*y^46 - 
    121756*x^21*y^44 - 120719*x^21*y^42 - 176147*x^21*y^40 - 148301*x^21*y^38 - 
    40932*x^21*y^36 + 2470*x^21*y^34 + 1283*x^21*y^32 + 10*x^21*y^30 - 
    384*x^20*y^52 - 9501*x^20*y^50 - 46289*x^20*y^48 - 70641*x^20*y^46 - 
    49013*x^20*y^44 - 104498*x^20*y^42 - 182416*x^20*y^40 - 115260*x^20*y^38 - 
    21956*x^20*y^36 + 592*x^20*y^34 + 135*x^20*y^32 - 6*x^19*y^54 - 
    1590*x^19*y^52 - 15695*x^19*y^50 - 34404*x^19*y^48 - 2495*x^19*y^46 + 
    940*x^19*y^44 - 119253*x^19*y^42 - 162833*x^19*y^40 - 70029*x^19*y^38 - 
    8293*x^19*y^36 + 172*x^19*y^34 - 125*x^18*y^54 - 3633*x^18*y^52 - 
    13810*x^18*y^50 + 9727*x^18*y^48 + 66178*x^18*y^46 - 1467*x^18*y^44 - 
    136924*x^18*y^42 - 119671*x^18*y^40 - 33234*x^18*y^38 - 2206*x^18*y^36 + 
    12*x^18*y^34 - 478*x^17*y^54 - 4161*x^17*y^52 + 6553*x^17*y^50 + 
    73663*x^17*y^48 + 97090*x^17*y^46 - 35830*x^17*y^44 - 125646*x^17*y^42 - 
    68115*x^17*y^40 - 11333*x^17*y^38 - 301*x^17*y^36 - 22*x^16*y^56 - 
    811*x^16*y^54 + 2042*x^16*y^52 + 46906*x^16*y^50 + 123777*x^16*y^48 + 
    75097*x^16*y^46 - 68665*x^16*y^44 - 90406*x^16*y^42 - 29730*x^16*y^40 - 
    2664*x^16*y^38 - 14*x^16*y^36 - 72*x^15*y^56 + 328*x^15*y^54 + 
    19915*x^15*y^52 + 93457*x^15*y^50 + 133781*x^15*y^48 + 26952*x^15*y^46 - 
    72026*x^15*y^44 - 48746*x^15*y^42 - 9166*x^15*y^40 - 312*x^15*y^38 - 
    x^14*y^58 + 31*x^14*y^56 + 5575*x^14*y^54 + 47652*x^14*y^52 + 
    121784*x^14*y^50 + 100473*x^14*y^48 - 14781*x^14*y^46 - 52647*x^14*y^44 - 
    19597*x^14*y^42 - 1855*x^14*y^40 - 10*x^14*y^38 + 3*x^13*y^58 + 
    965*x^13*y^56 + 16723*x^13*y^54 + 74656*x^13*y^52 + 117490*x^13*y^50 + 
    50936*x^13*y^48 - 29106*x^13*y^46 - 27080*x^13*y^44 - 5345*x^13*y^42 - 
    173*x^13*y^40 + 84*x^12*y^58 + 3799*x^12*y^56 + 31640*x^12*y^54 + 
    86287*x^12*y^52 + 84525*x^12*y^50 + 11057*x^12*y^48 - 23497*x^12*y^46 - 
    9930*x^12*y^44 - 902*x^12*y^42 - x^12*y^40 + x^11*y^60 + 473*x^11*y^58 + 
    9010*x^11*y^56 + 43963*x^11*y^54 + 76971*x^11*y^52 + 44665*x^11*y^50 - 
    5983*x^11*y^48 - 11640*x^11*y^46 - 2325*x^11*y^44 - 54*x^11*y^42 + 
    18*x^10*y^60 + 1523*x^10*y^58 + 15208*x^10*y^56 + 46690*x^10*y^54 + 
    52405*x^10*y^52 + 14931*x^10*y^50 - 7563*x^10*y^48 - 3840*x^10*y^46 - 
    307*x^10*y^44 + 107*x^9*y^60 + 3301*x^9*y^58 + 19473*x^9*y^56 + 
    38732*x^9*y^54 + 27010*x^9*y^52 + 1630*x^9*y^50 - 3720*x^9*y^48 - 
    724*x^9*y^46 - 10*x^9*y^44 + 356*x^8*y^60 + 5212*x^8*y^58 + 19143*x^8*y^56 +
    24620*x^8*y^54 + 9568*x^8*y^52 - 1451*x^8*y^50 - 1072*x^8*y^48 - 67*x^8*y^46
    + 7*x^7*y^62 + 764*x^7*y^60 + 6214*x^7*y^58 + 14684*x^7*y^56 + 
    11903*x^7*y^54 + 2028*x^7*y^52 - 807*x^7*y^50 - 142*x^7*y^48 + 38*x^6*y^62 +
    1151*x^6*y^60 + 5624*x^6*y^58 + 8502*x^6*y^56 + 4015*x^6*y^54 - 12*x^6*y^52 
    - 198*x^6*y^50 - 5*x^6*y^48 + 84*x^5*y^62 + 1280*x^5*y^60 + 3896*x^5*y^58 + 
    3709*x^5*y^56 + 897*x^5*y^54 - 94*x^5*y^52 - 12*x^5*y^50 + 127*x^4*y^62 + 
    1033*x^4*y^60 + 1966*x^4*y^58 + 1084*x^4*y^56 + 77*x^4*y^54 - 21*x^4*y^52 + 
    127*x^3*y^62 + 619*x^3*y^60 + 719*x^3*y^58 + 214*x^3*y^56 + 2*x^3*y^54 + 
    84*x^2*y^62 + 239*x^2*y^60 + 152*x^2*y^58 + 15*x^2*y^56 - x^2*y^54 + 
    38*x*y^62 + 61*x*y^60 + 18*x*y^58 + x*y^56 + 7*y^62 + 3*y^60;

time L:=Factorization(f);
assert &*[t[1]^t[2]: t in L] eq f;
assert #L eq 5;

// Factorization over RngFunFrac (May 17)

Q<a> := RationalFunctionField(Rationals(),1);
R<x1,y1,x2,y2> := PolynomialRing(Q,4);
C1:= quo<R|x1^2 + y1^2 -a^2, x2^2 + y2^2 -a^2>;
FC1<X1,Y1,X2,Y2> := FieldOfFractions(C1);
P<X> := PolynomialRing(FC1);
m := (Y1-Y2)/(X1-X2);
lineX1Y2X2Y2a0 := m*X - a*m;
f := X^2 +  (lineX1Y2X2Y2a0)^2 - a^2;
f := Normalize(f);
fac := Factorization(f);
assert #fac eq 2;
assert fac[1,1] * fac[2,1] eq f;


K:=GF(5);
P<z>:=PolynomialRing(K);
q1<z>:=quo<P|z^3 + z^2 + 1>;
P2<y>:=PolynomialRing(q1);
q2<y>:=quo<P2|y^31 + 3*z>;
P<X1> := PolynomialRing(q2);
P<X1> := PolynomialRing(q2, 1);
F := X1^31 + (2*z^2 + 1)*z^5*X1^25 + (3*z^2 + 3*z)*z^25*X1 + 3*z^2 + 4;
//time InternalGAFFFactorization(F, false); // OK
L := Factorization(F);
assert #L eq 2 and L[1, 1]*L[2, 1] eq F;

