// AKS, Dec 2006

SetShowRealTime(true);

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

k := 2*10^3;
printf "Bernoulli(%o)\n", k;
time n := Bernoulli(k);

k := 2*10^6;
printf "Factorial(%o)\n", k;
time n := Factorial(k);

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

"\nGF(7) irreducibility/factorization";

P<x> := PolynomialRing(GF(7));
f := x^3547 + P!IntegerToSequence(16893, 7);
time assert IsIrreducible(f);
time _ := Factorization(f + 1);

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

"\nSwinnertonDyerPolynomial(8) irreducibility/factorization";

f := SwinnertonDyerPolynomial(8);
time assert IsIrreducible(f);
time L := Factorization(f*(f + 1));
assert L eq [<f, 1>, <f + 1, 1>];

g := SwinnertonDyerPolynomial(7);
time L := Factorization(g*f);
assert L eq [<g, 1>, <f, 1>];

time L := Factorization(g*f*(f + 1));
assert L eq [<g, 1>, <f, 1>, <f + 1, 1>];

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

n := 33;

printf "\nFactorization of (x^%o - 1) over Cyclotomic Field of order %o\n",
    n, n;

P<x> := PolynomialRing(CyclotomicField(n));
time L := Factorization(x^n - 1);
assert #L eq n and &*[t[1]: t in L] eq x^n - 1;

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

"\nGModule IndecomposableSummands";

G := PSU(3, 5);
H := Sylow(G, 3);
M := Restriction(GModule(G, GF(3)), H);
M;
time L := IndecomposableSummands(M);
D := {* Dimension(m): m in L *}; D;
assert D eq {* 9^^14 *};

p := 7; G := PGL(3, 13); // 1.8 [n13]
H := Sylow(G, p);
M := Restriction(GModule(G, GF(p)), H);
M;
time L := IndecomposableSummands(M);
D := {* Dimension(m): m in L *}; D;
assert D eq {* 1, 7^^26 *};

p := 2; G := PGL(3, 23); // 6.0 [n13]
H := Sylow(G, p);
M := Restriction(GModule(G, GF(p)), H);
M;
time L := IndecomposableSummands(M);
D := {* Dimension(m): m in L *}; D;
assert D eq {* 1, 8, 16^^12, 32^^11 *};

/*
p := 3; G := PGL(4, 8); // 8.6
p := 5; G := PGL(4, 8); // >>1min
p := 7; G := PGL(4, 7); // 7.5
p := 2; G := PGL(4, 8); // 9.4
p := 7; G := PGL(3, 17); // 19.7
*/

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

function cyclic(P, n)
    V := [P.i: i in [1 .. n]];
    V cat:= V;

    B := [
        &+[&*[V[j]: j in [i .. i + k - 1]]: i in [1 .. n]]: k in [1 .. n - 1]
    ];
    B[n] := &*[V[i]: i in [1 .. n]] - 1;

    return B;

end function;

K := GF(32003);
"\nCyclic 9 GB over", K;

n := 9;
P<[x]> := PolynomialRing(K, n, "grevlex");
I := Ideal(cyclic(P, n));
time G := GroebnerBasis(I);
#G;
assert #G eq 1344;

MS := SequenceToMultiset;
L:=[LeadingMonomial(f): f in G];
S := {* SequenceToMultiset(Exponents(x)): x in L *};
assert S eq 
{*
    {* 0^^3, 1^^4, 2, 5 *}^^4, {* 0^^3, 1^^4, 2, 6 *}^^10,
    {* 0^^3, 1^^5, 8 *}^^6, {* 0^^3, 1^^5, 9 *}^^15, {* 0^^3, 1^^6 *}^^7,
    {* 0^^4, 1^^2, 2^^2, 3 *}, {* 0^^4, 1^^2, 2^^2, 4 *}^^2,
    {* 0^^4, 1^^2, 2^^2, 5 *}^^9, {* 0^^4, 1^^2, 2^^2, 6 *}^^30,
    {* 0^^4, 1^^3, 2, 8 *}^^22, {* 0^^4, 1^^3, 2, 9 *}^^83,
    {* 0^^4, 1^^3, 3, 6 *}^^2, {* 0^^4, 1^^3, 3, 7 *}^^18,
    {* 0^^4, 1^^4, 2 *}^^57, {* 0^^4, 1^^4, 3 *}^^14, {* 0^^4, 1^^4, 10 *}^^16,
    {* 0^^4, 1^^4, 11 *}^^19, {* 0^^5, 1, 2, 3, 4 *},
    {* 0^^5, 1, 2, 3, 5 *}^^6, {* 0^^5, 1, 2, 3, 6 *}^^16,
    {* 0^^5, 1, 2, 3, 7 *}^^20, {* 0^^5, 1, 2^^2, 8 *}^^16,
    {* 0^^5, 1, 2^^2, 9 *}^^51, {* 0^^5, 1, 3^^3 *},
    {* 0^^5, 1^^2, 2, 3 *}^^42, {* 0^^5, 1^^2, 2, 10 *}^^48,
    {* 0^^5, 1^^2, 2, 11 *}^^34, {* 0^^5, 1^^2, 2^^2 *}^^78,
    {* 0^^5, 1^^2, 3, 8 *}^^27, {* 0^^5, 1^^2, 3, 9 *}^^51,
    {* 0^^5, 1^^2, 4, 7 *}^^14, {* 0^^5, 1^^3, 2 *}, {* 0^^5, 1^^3, 3 *}^^79,
    {* 0^^5, 1^^3, 4 *}^^20, {* 0^^5, 1^^3, 12 *}^^34, {* 0^^5, 2^^3, 4 *},
    {* 0^^5, 2^^3, 5 *}, {* 0^^5, 2^^3, 6 *}^^7, {* 0^^6, 1, 2, 3 *}^^84,
    {* 0^^6, 1, 2, 4 *}^^23, {* 0^^6, 1, 2, 12 *}^^30, {* 0^^6, 1, 2^^2 *}^^2,
    {* 0^^6, 1, 3, 10 *}^^24, {* 0^^6, 1, 3, 11 *}^^5, {* 0^^6, 1, 3^^2 *}^^18,
    {* 0^^6, 1, 4, 8 *}^^17, {* 0^^6, 1, 4, 9 *}^^12, {* 0^^6, 1, 5, 7 *}^^3,
    {* 0^^6, 1^^2, 2 *}, {* 0^^6, 1^^2, 4 *}^^64, {* 0^^6, 1^^2, 5 *}^^14,
    {* 0^^6, 1^^2, 13 *}^^17, {* 0^^6, 2, 3, 8 *}^^10, {* 0^^6, 2, 3, 9 *}^^16,
    {* 0^^6, 2, 4, 5 *}, {* 0^^6, 2, 4, 6 *}, {* 0^^6, 2, 4, 7 *}^^4,
    {* 0^^6, 2^^2, 3 *}^^9, {* 0^^6, 2^^2, 10 *}^^10, {* 0^^6, 2^^2, 11 *}^^4,
    {* 0^^6, 2^^3 *}^^10, {* 0^^6, 3^^2, 4 *}^^2, {* 0^^6, 3^^2, 6 *}^^2,
    {* 0^^6, 3^^2, 7 *}^^3, {* 0^^7, 1, 2 *}, {* 0^^7, 1, 3 *},
    {* 0^^7, 1, 5 *}^^26, {* 0^^7, 1, 6 *}^^3, {* 0^^7, 1, 14 *}^^2,
    {* 0^^7, 2, 3 *}, {* 0^^7, 2, 4 *}^^20, {* 0^^7, 2, 5 *}^^4,
    {* 0^^7, 2, 13 *}^^4, {* 0^^7, 3, 4 *}^^6, {* 0^^7, 3, 12 *}^^4,
    {* 0^^7, 3^^2 *}^^9, {* 0^^7, 4, 10 *}^^4, {* 0^^7, 5, 8 *}^^4,
    {* 0^^8, 1 *}, {* 0^^8, 2 *}, {* 0^^8, 6 *}^^4
*};




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

"\nCyclic 8 Q GB";

K := RationalField();
n := 8;
P<[x]> := PolynomialRing(K, n, "grevlex");
I := Ideal(cyclic(P, n));
#G;
time G := GroebnerBasis(I);

"\nCyclic 8 Homog Q GB";

K := RationalField();
P<a,b,c,d,e,f,g,h,H> := PolynomialRing(K, 9, "grevlex");
I := ideal<P |
a*b*c*d*e*f*g*h-H^8,
a*b*c*d*e*f*g+a*b*c*d*e*f*h+a*b*c*d*e*g*h+a*b*c*d*f*g*h+a*b*c*e*f*g*h+a*b*d*e*f*g*h+a*c*d*e*f*g*h+b*c*d*e*f*g*h,
a*b*c*d*e*f+b*c*d*e*f*g+a*b*c*d*e*h+a*b*c*d*g*h+a*b*c*f*g*h+a*b*e*f*g*h+a*d*e*f*
g*h+c*d*e*f*g*h,
a*b*c*d*e+b*c*d*e*f+c*d*e*f*g+a*b*c*d*h+a*b*c*g*h+a*b*f*g*h+a*e*f*g*h+d*e*f*g*h,
a*b*c*d+b*c*d*e+c*d*e*f+d*e*f*g+a*b*c*h+a*b*g*h+a*f*g*h+e*f*g*h,
a*b*c+b*c*d+c*d*e+d*e*f+e*f*g+a*b*h+a*g*h+f*g*h,
a*b+b*c+c*d+d*e+e*f+f*g+a*h+g*h,
a+b+c+d+e+f+g+h >;
time G := GroebnerBasis(I);
assert #G eq 1182;

L:=[LeadingMonomial(f): f in G];
S := {* SequenceToMultiset(Exponents(x)): x in L *};
assert S eq 
{*
    {* 0^^2, 1^^5, 3, 16 *}, {* 0^^2, 1^^5, 5, 8 *}^^2, {* 0^^2, 1^^5, 6,
    8 *}^^2, {* 0^^2, 1^^6, 2 *}, {* 0^^2, 1^^6, 8 *}, {* 0^^3, 1^^3, 2,
    3, 4 *}^^4, {* 0^^3, 1^^3, 2, 3, 8 *}, {* 0^^3, 1^^3, 2, 3^^2 *}^^2,
    {* 0^^3, 1^^3, 2, 4, 16 *}, {* 0^^3, 1^^3, 2, 5, 8 *}^^4, {* 0^^3,
    1^^3, 2, 5, 16 *}^^7, {* 0^^3, 1^^3, 2, 6, 8 *}^^16, {* 0^^3, 1^^3,
    2, 6, 16 *}^^4, {* 0^^3, 1^^3, 2, 7, 8 *}^^4, {* 0^^3, 1^^3, 2^^2,
    3 *}^^4, {* 0^^3, 1^^3, 2^^2, 6 *}^^9, {* 0^^3, 1^^3, 2^^2, 8 *}^^3,
    {* 0^^3, 1^^3, 2^^3 *}^^7, {* 0^^3, 1^^4, 2, 3 *}^^3, {* 0^^3, 1^^4,
    2, 4 *}^^11, {* 0^^3, 1^^4, 2, 5 *}^^7, {* 0^^3, 1^^4, 2, 8 *}^^7,
    {* 0^^3, 1^^4, 2^^2 *}, {* 0^^3, 1^^4, 3, 4 *}^^4, {* 0^^3, 1^^4, 3,
    6 *}^^12, {* 0^^3, 1^^4, 3^^2 *}^^2, {* 0^^3, 1^^4, 4^^2 *}^^6, {*
    0^^3, 1^^4, 8, 9 *}^^6, {* 0^^3, 1^^4, 8, 16 *}^^6, {* 0^^3, 1^^4,
    8^^2 *}^^9, {* 0^^3, 1^^5, 2 *}, {* 0^^3, 1^^5, 3 *}, {* 0^^3, 1^^5,
    4 *}^^2, {* 0^^3, 1^^5, 5 *}, {* 0^^3, 1^^5, 8 *}, {* 0^^3, 1^^5,
    16 *}^^4, {* 0^^4, 1, 2, 3^^2, 8 *}, {* 0^^4, 1, 2^^2, 3, 4 *}^^15,
    {* 0^^4, 1, 2^^2, 3, 8 *}, {* 0^^4, 1, 2^^2, 3^^2 *}^^13, {* 0^^4,
    1, 2^^2, 5, 16 *}^^2, {* 0^^4, 1, 2^^2, 6, 8 *}^^12, {* 0^^4, 1,
    2^^2, 6, 16 *}^^6, {* 0^^4, 1, 2^^2, 7, 8 *}^^6, {* 0^^4, 1, 2^^3,
    3 *}^^7, {* 0^^4, 1, 2^^3, 4 *}^^9, {* 0^^4, 1, 2^^3, 5 *}, {* 0^^4,
    1, 2^^3, 6 *}^^16, {* 0^^4, 1, 2^^3, 8 *}, {* 0^^4, 1, 2^^4 *}^^2, {*
    0^^4, 1^^2, 2, 3, 4 *}^^27, {* 0^^4, 1^^2, 2, 3, 5 *}^^25, {* 0^^4,
    1^^2, 2, 3, 6 *}^^54, {* 0^^4, 1^^2, 2, 3, 7 *}^^2, {* 0^^4, 1^^2,
    2, 3, 8 *}^^3, {* 0^^4, 1^^2, 2, 3^^2 *}^^13, {* 0^^4, 1^^2, 2, 4,
    5 *}^^5, {* 0^^4, 1^^2, 2, 4, 8 *}, {* 0^^4, 1^^2, 2, 4^^2 *}^^30,
    {* 0^^4, 1^^2, 2, 5^^2 *}, {* 0^^4, 1^^2, 2, 8, 9 *}^^17, {* 0^^4,
    1^^2, 2, 8, 16 *}^^6, {* 0^^4, 1^^2, 2, 8^^2 *}^^27, {* 0^^4, 1^^2,
    2^^2, 3 *}^^13, {* 0^^4, 1^^2, 2^^2, 4 *}^^19, {* 0^^4, 1^^2, 2^^2,
    5 *}^^8, {* 0^^4, 1^^2, 2^^2, 6 *}^^2, {* 0^^4, 1^^2, 2^^2, 7 *}^^11,
    {* 0^^4, 1^^2, 2^^2, 8 *}^^28, {* 0^^4, 1^^2, 2^^3 *}^^3, {* 0^^4,
    1^^2, 3, 4, 8 *}^^2, {* 0^^4, 1^^2, 3, 5, 8 *}^^3, {* 0^^4, 1^^2,
    3, 5, 16 *}, {* 0^^4, 1^^2, 3, 6, 8 *}^^5, {* 0^^4, 1^^2, 3, 6, 16
    *}^^2, {* 0^^4, 1^^2, 3, 7, 8 *}^^10, {* 0^^4, 1^^2, 3^^2, 4 *}^^18,
    {* 0^^4, 1^^2, 3^^2, 5 *}^^3, {* 0^^4, 1^^2, 3^^3 *}^^8, {* 0^^4,
    1^^2, 4^^2, 8 *}, {* 0^^4, 1^^2, 4^^3 *}, {* 0^^4, 1^^3, 2, 3 *}^^8,
    {* 0^^4, 1^^3, 2, 4 *}^^6, {* 0^^4, 1^^3, 2, 5 *}^^3, {* 0^^4, 1^^3,
    2, 6 *}^^3, {* 0^^4, 1^^3, 2, 8 *}^^9, {* 0^^4, 1^^3, 2, 16 *}^^9,
    {* 0^^4, 1^^3, 2^^2 *}^^2, {* 0^^4, 1^^3, 3, 4 *}^^9, {* 0^^4, 1^^3,
    3, 5 *}^^6, {* 0^^4, 1^^3, 3, 6 *}, {* 0^^4, 1^^3, 3, 7 *}^^4, {*
    0^^4, 1^^3, 3, 8 *}^^26, {* 0^^4, 1^^3, 3^^2 *}^^5, {* 0^^4, 1^^3,
    4, 5 *}^^4, {* 0^^4, 1^^3, 4, 6 *}^^10, {* 0^^4, 1^^3, 4, 8 *}^^4,
    {* 0^^4, 1^^3, 4^^2 *}, {* 0^^4, 1^^3, 5^^2 *}^^4, {* 0^^4, 1^^3,
    8, 10 *}^^14, {* 0^^4, 1^^3, 10, 16 *}^^3, {* 0^^4, 1^^4, 2 *}, {*
    0^^5, 1, 2, 3, 4 *}^^10, {* 0^^5, 1, 2, 3, 5 *}^^5, {* 0^^5, 1, 2,
    3, 6 *}^^4, {* 0^^5, 1, 2, 3, 7 *}^^6, {* 0^^5, 1, 2, 3, 8 *}^^39,
    {* 0^^5, 1, 2, 3, 16 *}, {* 0^^5, 1, 2, 3^^2 *}^^3, {* 0^^5, 1, 2,
    4, 5 *}^^9, {* 0^^5, 1, 2, 4, 6 *}^^12, {* 0^^5, 1, 2, 4, 7 *}^^2,
    {* 0^^5, 1, 2, 4, 8 *}^^3, {* 0^^5, 1, 2, 4^^2 *}^^3, {* 0^^5, 1,
    2, 5^^2 *}^^3, {* 0^^5, 1, 2, 6^^2 *}, {* 0^^5, 1, 2, 8, 10 *}^^12,
    {* 0^^5, 1, 2, 10, 16 *}^^3, {* 0^^5, 1, 2^^2, 3 *}^^3, {* 0^^5, 1,
    2^^2, 4 *}^^3, {* 0^^5, 1, 2^^2, 6 *}, {* 0^^5, 1, 2^^2, 8 *}^^9,
    {* 0^^5, 1, 2^^2, 16 *}^^7, {* 0^^5, 1, 2^^3 *}, {* 0^^5, 1, 3, 4,
    5 *}^^2, {* 0^^5, 1, 3, 4, 8 *}^^2, {* 0^^5, 1, 3, 4^^2 *}^^14, {*
    0^^5, 1, 3, 5^^2 *}, {* 0^^5, 1, 3, 8, 9 *}^^4, {* 0^^5, 1, 3, 8,
    16 *}, {* 0^^5, 1, 3, 8^^2 *}^^15, {* 0^^5, 1, 3^^2, 4 *}^^3, {*
    0^^5, 1, 3^^2, 5 *}^^9, {* 0^^5, 1, 3^^2, 6 *}^^9, {* 0^^5, 1, 3^^2,
    8 *}, {* 0^^5, 1, 3^^3 *}^^3, {* 0^^5, 1, 4, 5, 8 *}^^6, {* 0^^5, 1,
    4, 6, 8 *}, {* 0^^5, 1, 4, 7, 8 *}^^3, {* 0^^5, 1, 4, 8^^2 *}^^2,
    {* 0^^5, 1, 4^^2, 16 *}, {* 0^^5, 1^^2, 2, 3 *}^^3, {* 0^^5, 1^^2,
    2, 4 *}^^4, {* 0^^5, 1^^2, 2, 8 *}, {* 0^^5, 1^^2, 2^^2 *}^^2, {*
    0^^5, 1^^2, 3, 4 *}^^4, {* 0^^5, 1^^2, 3, 8 *}^^12, {* 0^^5, 1^^2,
    3, 16 *}^^15, {* 0^^5, 1^^2, 3^^2 *}, {* 0^^5, 1^^2, 4, 6 *}, {*
    0^^5, 1^^2, 4, 7 *}, {* 0^^5, 1^^2, 4, 8 *}^^18, {* 0^^5, 1^^2, 4,
    16 *}^^4, {* 0^^5, 1^^2, 5^^2 *}, {* 0^^5, 1^^2, 8, 11 *}, {* 0^^5,
    1^^2, 11, 16 *}^^5, {* 0^^5, 1^^3, 2 *}, {* 0^^5, 1^^3, 3 *}, {*
    0^^5, 1^^3, 4 *}, {* 0^^5, 2, 3, 4, 5 *}, {* 0^^5, 2, 3, 4, 6 *},
    {* 0^^5, 2, 3, 4, 8 *}^^4, {* 0^^5, 2, 3, 4^^2 *}^^2, {* 0^^5, 2, 3,
    6, 8 *}^^3, {* 0^^5, 2, 3, 6, 16 *}, {* 0^^5, 2, 3, 7, 8 *}^^5, {*
    0^^5, 2, 3^^2, 4 *}^^5, {* 0^^5, 2, 3^^2, 5 *}^^2, {* 0^^5, 2, 3^^2,
    7 *}, {* 0^^5, 2, 3^^2, 8 *}, {* 0^^5, 2, 3^^3 *}^^4, {* 0^^5, 2^^2,
    3, 4 *}^^14, {* 0^^5, 2^^2, 3, 5 *}^^4, {* 0^^5, 2^^2, 3, 6 *}^^10,
    {* 0^^5, 2^^2, 3^^2 *}, {* 0^^5, 2^^2, 4, 5 *}, {* 0^^5, 2^^2, 4^^2
    *}^^4, {* 0^^5, 2^^2, 8, 9 *}^^3, {* 0^^5, 2^^2, 8^^2 *}^^6, {* 0^^5,
    2^^3, 3 *}^^2, {* 0^^5, 2^^3, 4 *}^^2, {* 0^^5, 2^^3, 5 *}^^4, {*
    0^^5, 2^^3, 6 *}^^2, {* 0^^5, 2^^3, 7 *}, {* 0^^5, 2^^3, 8 *}^^6, {*
    0^^6, 1, 2, 3 *}^^2, {* 0^^6, 1, 2, 4 *}^^2, {* 0^^6, 1, 2^^2 *}, {*
    0^^6, 1, 3^^2 *}, {* 0^^6, 1, 4, 8 *}^^8, {* 0^^6, 1, 4, 16 *}^^6,
    {* 0^^6, 1, 5, 8 *}, {* 0^^6, 1^^2, 2 *}, {* 0^^6, 1^^2, 4 *}, {*
    0^^6, 2, 3, 8 *}^^6, {* 0^^6, 2, 3, 16 *}^^4, {* 0^^6, 2, 3^^2 *},
    {* 0^^6, 2, 4, 8 *}^^7, {* 0^^6, 2, 4, 16 *}^^2, {* 0^^6, 2, 11,
    16 *}, {* 0^^6, 2^^2, 3 *}^^2, {* 0^^6, 2^^2, 4 *}, {* 0^^6, 3, 4,
    8 *}, {* 0^^6, 3, 5, 8 *}, {* 0^^6, 3, 8, 10 *}^^3, {* 0^^6, 3^^2,
    8 *}^^3, {* 0^^6, 3^^2, 16 *}^^2, {* 0^^6, 4, 8, 9 *}, {* 0^^6, 4,
    8^^2 *}^^2, {* 0^^6, 4, 9, 16 *}, {* 0^^6, 5, 8, 9 *}^^2, {* 0^^7,
    1, 2 *}, {* 0^^7, 1, 3 *}, {* 0^^7, 2, 3 *}, {* 0^^7, 5, 8 *}, {*
    0^^8, 1 *}, {* 0^^8, 2 *}
*};

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

"\nPoint counting (250 bits)";

p :=
1365818482732697446402720195556907535508433803960330956891804833247742206397;
K := GF(p);
L := [ K |
  105319257760165612377382863332027372719546517814954679759055331222952775149, 
  889894525824026889708948328075802396592859068384361698847474424843480737211 ];
E := EllipticCurve(L);
time o := #E;
assert o eq
  1365818482732697446402720195556907535449788231835735960768287780741253111196;
assert IsZero(o*Random(E));

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

"\nInvariant Ring C_5, GF(5)";

R := InvariantRing(CyclicGroup(5), GF(5));
time HilbertSeries(Module(R)) eq HilbertSeries(R);

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

"";
"Matrix mult, rank, inverse";
time
for t in
    [
	<2, 10000>,
	<3, 5000>,
	<4, 5000>,
	<5, 4000>,
	<7, 3000>,
	<8, 2000>,
	<23, 2000>,
	<2965819, 2000>, <11863279, 2000>, <2^31 - 1, 1000>,
	<NextPrime(10^50: Proof := false), 500>
    ]
do
    p, k := Explode(t);
    printf "GF(%o), dim %o\n", p, k;
    X := Random(MatrixRing(GF(p), k));
    time Y := X*(X + 1);
    v := Random(Parent(X[1]));
    assert (v*X)*(X + 1) eq v*Y;
    delete Y;
    time r := Rank(X);
    time E, T := EchelonForm(X);
    assert forall{i: i in {r + 1 .. k} | IsZero(E[i])};
    time assert T*X eq E;
    delete E, T, X;
end for;

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