SetEchoInput(true);

/// Dec 23

_<x>:=PolynomialRing(Integers());
f:=x^6 - x^5 + 2*x^4 - 67*x^3 + 32*x^2 - 256*x + 4096;

K<a>:=NumberField(f);
O:=MaximalOrder(K);
gensS:=[
<[1/9,1/144,1/2304,29/1152,1147/2304,1717/2304]>,
<[0,1/48,1/384,43/64,323/384,325/384]>,
<[0,0,1/256,101/128,11/256,213/256]>,
<[0,0,0,1,0,0]>,
<[0,0,0,0,1,0]>,
<[0,0,0,0,0,1]>
];
gensS:=[ &+[ g[1][i]*a^(i-1) : i in [1..Degree(f)] ] : g in gensS ];
S:=Order(gensS);
ff:=O!!Conductor(S);

//RayResidueRing := InternalRayResidueRing;
R,r:=RayResidueRing(ff); // (O/ff)^*
assert forall{x : x in Generators(R) | r(x)@@r eq x};


///

//SetUseMontes(false);
//SetVerbose("NumberFieldAlgorithms", 1);

p := NextPrime(100000000);

have_primes := Cputime();

P<x> := PolynomialRing(Integers());
f := x^5+7*x+2+1;
N := NumberField(f);
f :=  PolynomialAlgebra(Rationals())!f;
P<x> := PolynomialRing(Rationals());
f := Evaluate(f, x/19)*19^Degree(f);
E := EquationOrder(f);
time M := MaximalOrder(E : Discriminant := Discriminant(N));
assert Discriminant(M) eq Discriminant(N);
f := x^5+7*x+2+1;
N := NumberField(f);
f :=  PolynomialAlgebra(Rationals())!f;
P<x> := PolynomialRing(Rationals());
f := Evaluate(f, x/(19*37*18731123*2*3))*(19*37*18731123*2*3)^Degree(f);
E := EquationOrder(f);
time M := MaximalOrder(E : Discriminant := Discriminant(N));
assert Discriminant(M) eq Discriminant(N);
f := x^2 + 5;
N := NumberField(f);
P<x> := PolynomialRing(MaximalOrder(N));
f := x^2 + 2;
f :=  PolynomialRing(N)!f;
N2 := NumberField(f : Check := false);
time d := Discriminant(MaximalOrder(N2));
P<x> := PolynomialRing(N);
f := Evaluate(f, x/19)*19^Degree(f);
f := PolynomialRing(MaximalOrder( N ))!f;
E := EquationOrder(f : Check := false);
time M := MaximalOrder(E : Discriminant := d);
assert Discriminant(M) eq d;
P<x> := PolynomialRing(IntegerRing());
f := x^2 + 5;
N := NumberField(f);
P<x> := PolynomialRing(MaximalOrder(N));
f := x^2 + 2;
f :=  PolynomialRing(N)!f;
N2 := NumberField(f : Check := false);
time d := Discriminant(MaximalOrder(N2));
P<x> := PolynomialRing(N);
f := Evaluate(f, x/(19*37*18731123*2*3))*(19*37*18731123*2*3)^Degree(f);
f := PolynomialRing(MaximalOrder( N ))!f;
E := EquationOrder(f : Check := false);
time M := MaximalOrder(E : Discriminant := d);
assert Discriminant(M) eq d;

P<x> := PolynomialRing(IntegerRing());
E := EquationOrder(x^2 + 5);
M := MaximalOrder(E);
I := ideal<M | M!4, M![0, 8]>;
assert IsPower(I^3, 3);
assert Root(I^3, 3) eq I;
assert Sqrt(I^2) eq I;
assert IsSquare(I^2);
assert IsSquare(I);
assert not IsPower(I, 3);
assert Sqrt(I)^2 eq I;
r, r2 := IsPower(I, 4);
assert r;
assert r2^4 eq I;
assert not IsPower(I, 5);

QQ:=Rationals();
d:=17;
Px<x>:=PolynomialRing(QQ);
F<w>:=NumberField(x^2+d);
OF:=Integers(F);
G,classmap:=ClassGroup(F);
G;
T:=CharacterTable(G);
fC:=Parent(T[2][3]);
nC:=NumberField(x^2+1);
IsIsomorphic(nC,fC);
tf:=IsIsomorphic(nC,fC);

_<x>:=PolynomialRing(Rationals());
for g in [x^2 - 5/8*x + 1/8, x^2 - 10/27*x + 1/27,
x^2 - 1/2*x - 9/8,
x^2 + 5/2*x + 3/8,
x^2 + 27/8*x + 9/4] do

L, roots:=SplittingField(g);
G:=Automorphisms(L);
a2:=G[2];
a2(roots[1]);
s:=a2(roots[1]);
assert IsZero(Evaluate(g,s));
end for;

K:=NumberField(x^3-112*x+400);
ZK:=Integers(K);
F:=Factorization(2*ZK); // only leaks at 2

F1<I,w3,w13,w17>:=NumberField([Polynomial([-x,0,1]):x in [-1,3,13,17]]);
F1a:=GroundField(F1);
F1b:=GroundField(F1a);
F1c:=GroundField(F1b);
F2<t2>:=NumberField(Polynomial(F1,[-x,0,1])) where x:=(4*w13 + 12)*w3
+ 6*w13 + 18;
F3<t3>:=NumberField(Polynomial(F2,[-x,0,1])) where x:=2*w17+34;
F4<t4>:=NumberField(Polynomial(F3,[-x,0,1])) where x:=(w17 + 7)*t3 +
12*w17 + 68;
F5<t5>:=NumberField(Polynomial(F4,[-x,0,1])) where x:=26*t4 +
(13/2*w17 - 13/2)*t3 + -26*w17 + 442;
F1c!(F5.8);

/*
Dembele example is too large for tests
QQ := Rationals();
PolsQ<x> := PolynomialRing(QQ);
F<b> := QuadraticField(73);
O<w> := Integers(F);
PolsF<t> := PolynomialRing(F);
f := x^6 - 2*x^5 + 4*x^4 - 4*x^3 + 3*x^2 - 2*x - 1;
time L := SplittingField(f);
time OL := MaximalOrder(L : Ramification := [ 2, 73 ]);
*/

P<x>:=PolynomialRing(Rationals());
U:=NumberField(x^8 - 15*x^4 - 10*x^2 + 5 );
// KG:=SplittingField(U);
F:=Subfields(U,2)[1][1];
IsSubfield(F,U);
RE:=RelativeField(F,U);
HeckeCharacterGroup(RE);


P<x> := PolynomialRing(Integers());
o := MaximalOrder(x^2-2);
O := MaximalOrder(PolynomialRing(o)!x^2-3);
Oa := AbsoluteOrder(O);

Ao := NumberField(o);
AO := NumberField(O);

Fo := FieldOfFractions(o);
FO := FieldOfFractions(O);

Vo := RSpace(o, 2);
VA := RSpace(Integers(), 4);

x := Random(O, 20);
assert Evaluate(MinimalPolynomial(x, o), x) eq 0;
assert Evaluate(MinimalPolynomial(x, Integers()), x) eq 0;
assert Evaluate(MinimalPolynomial(x, Ao), x) eq 0;
assert Evaluate(MinimalPolynomial(x, Rationals()), x) eq 0;
assert Evaluate(MinimalPolynomial(x, Fo), x) eq 0;
assert Evaluate(MinimalPolynomial(x, O), x) eq 0;
assert Evaluate(MinimalPolynomial(x, FO), x) eq 0;
assert Evaluate(MinimalPolynomial(x, AO), x) eq 0;

assert Evaluate(CharacteristicPolynomial(x, o), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, Integers()), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, Ao), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, Rationals()), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, Fo), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, O), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, FO), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, AO), x) eq 0;

assert O!Eltseq(x) eq x;

y := Random(O, 20);
v1 := Vo!Eltseq(y);
v2 := VA!&cat[Eltseq(u) : u in Eltseq(y)];
v := RSpace(O, 1)![y];
assert O!Eltseq(ChangeRing(v1, Ao)*RepresentationMatrix(x, Ao)) eq y*x;
assert O![Fo![s[1], s[2]], Fo![s[3], s[4]]] eq y*x where s is Eltseq(ChangeRing(v2, Rationals())*RepresentationMatrix(x, Rationals()));
assert O!Eltseq(ChangeRing(v1, Fo)*RepresentationMatrix(x, Fo)) eq y*x;
assert O!Eltseq(v*RepresentationMatrix(x, O))[1] eq y*x;
assert O!Eltseq(ChangeRing(v, FO)*RepresentationMatrix(x, FO))[1] eq y*x;
assert O!Eltseq(ChangeRing(v, AO)*RepresentationMatrix(x, AO))[1] eq y*x;

assert RepresentationMatrix(x, Fo) eq RepresentationMatrix(x);
assert RepresentationMatrix(x, Rationals()) eq AbsoluteRepresentationMatrix(x);

assert Norm(x, o) eq Norm(x);
assert Norm(x, Integers()) eq AbsoluteNorm(x);
assert Norm(x, Ao) eq Ao!Norm(x);
assert Norm(x, Rationals()) eq AbsoluteNorm(x);
assert Norm(x, Fo) eq Fo!Norm(x);
assert Norm(x, O) eq x;
assert Norm(x, FO) eq FO!x;
assert Norm(x, AO) eq AO!x;

assert Trace(x, o) eq Trace(x);
assert Trace(x, Integers()) eq AbsoluteTrace(x);
assert Trace(x, Ao) eq Ao!Trace(x);
assert Trace(x, Rationals()) eq AbsoluteTrace(x);
assert Trace(x, Fo) eq Fo!Trace(x);
assert Trace(x, O) eq x;
assert Trace(x, FO) eq FO!x;
assert Trace(x, AO) eq AO!x;

Vo := KSpace(Fo, 2);
VA := KSpace(Fo, 4);

x := Random(FO, 20);
assert Evaluate(MinimalPolynomial(x, o), x) eq 0;
assert Evaluate(MinimalPolynomial(x, Fo), x) eq 0;
assert Evaluate(MinimalPolynomial(x, Ao), x) eq 0;
assert Evaluate(MinimalPolynomial(x, Integers()), x) eq 0;
assert Evaluate(MinimalPolynomial(x, Rationals()), x) eq 0;
assert Evaluate(MinimalPolynomial(x, O), x) eq 0;
assert Evaluate(MinimalPolynomial(x, FO), x) eq 0;
assert Evaluate(MinimalPolynomial(x, AO), x) eq 0;

assert Evaluate(CharacteristicPolynomial(x, o), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, Ao), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, O), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, Integers()), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, Rationals()), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, Fo), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, FO), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, AO), x) eq 0;

y := Random(FO, 20);
v1 := Vo!Eltseq(y);
v2 := VA!&cat[Eltseq(u) : u in Eltseq(y)];
v := RSpace(FO, 1)![y];
if IsIntegral(x) and &and[B[1] eq 1*BaseRing(O) : B in PseudoBasis(Module(O))] then
x;
    assert FO!Eltseq(v1*ChangeRing(RepresentationMatrix(x, o), Fo)) eq y*x;
end if;
assert FO!Eltseq(v1*(RepresentationMatrix(x, Fo))) eq y*x;
assert FO!Eltseq(ChangeRing(v1, Ao)*(RepresentationMatrix(x, Ao))) eq y*x;
if IsIntegral(x) and &and[B[1] eq 1*BaseRing(O) : B in PseudoBasis(Module(O))] then
    assert FO![Fo![s[1], s[2]], Fo![s[3], s[4]]] eq y*x where s is 
    Eltseq(v2*ChangeRing(RepresentationMatrix(x, Integers()), Fo));
end if;
assert FO![Fo![s[1], s[2]], Fo![s[3], s[4]]] eq y*x where s is Eltseq(ChangeRing(v2, Rationals())*(RepresentationMatrix(x, Rationals())));
if IsIntegral(x) and &and[B[1] eq 1*BaseRing(O) : B in PseudoBasis(Module(O))] then
    assert FO!Eltseq(v*ChangeRing(RepresentationMatrix(x, O), FO))[1] eq y*x;
end if;
assert FO!Eltseq(ChangeRing(v, FO)*(RepresentationMatrix(x, FO)))[1] eq y*x;
assert FO!Eltseq(ChangeRing(v, AO)*(RepresentationMatrix(x, AO)))[1] eq
 y*x;

assert RepresentationMatrix(x, Fo) eq RepresentationMatrix(x);
assert RepresentationMatrix(x, Rationals()) eq AbsoluteRepresentationMatrix(x);

if IsIntegral(x) then
x;
    assert Norm(x, o) eq Norm(x);
end if;
assert Norm(x, Ao) eq Ao!Norm(x);
assert Norm(x, Fo) eq Fo!Norm(x);
if IsIntegral(x) then
    assert Norm(x, Integers()) eq AbsoluteNorm(x);
end if;
assert Norm(x, Rationals()) eq AbsoluteNorm(x);
if IsIntegral(x) then
    assert Norm(x, O) eq x;
end if;
assert Norm(x, FO) eq FO!x;
assert Norm(x, AO) eq AO!x;

if IsIntegral(x) then
    assert Trace(x, o) eq Trace(x);
    assert Trace(x, Integers()) eq AbsoluteTrace(x);
end if;
assert Trace(x, Ao) eq Ao!Trace(x);
assert Trace(x, Rationals()) eq AbsoluteTrace(x);
assert Trace(x, Fo) eq Fo!Trace(x);
if IsIntegral(x) then
    assert Trace(x, O) eq x;
end if;
assert Trace(x, FO) eq FO!x;
assert Trace(x, AO) eq AO!x;

Vo := KSpace(Ao, 2);
VA := KSpace(Ao, 4);

x := Random(AO, 20);
assert Evaluate(MinimalPolynomial(x, o), x) eq 0;
assert Evaluate(MinimalPolynomial(x, Integers()), x) eq 0;
assert Evaluate(MinimalPolynomial(x, Ao), x) eq 0;
assert Evaluate(MinimalPolynomial(x, Rationals()), x) eq 0;
assert Evaluate(MinimalPolynomial(x, Fo), x) eq 0;
assert Evaluate(MinimalPolynomial(x, O), x) eq 0;
assert Evaluate(MinimalPolynomial(x, FO), x) eq 0;
assert Evaluate(MinimalPolynomial(x, AO), x) eq 0;

assert Evaluate(CharacteristicPolynomial(x, o), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, Integers()), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, Ao), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, Rationals()), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, Fo), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, O), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, FO), x) eq 0;
assert Evaluate(CharacteristicPolynomial(x, AO), x) eq 0;

y := Random(AO, 20);
v1 := Vo!Eltseq(y);
v2 := VA!&cat[Eltseq(u) : u in Eltseq(y)];
v := RSpace(AO, 1)![y];
if IsIntegral(x) then
x;
    assert AO!Eltseq(v1*ChangeRing(RepresentationMatrix(x, o), Ao)) eq y*x;
    assert AO![Ao![s[1], s[2]], Ao![s[3], s[4]]] eq y*x where s is 
    Eltseq(v2*ChangeRing(RepresentationMatrix(x, Integers()), Ao));
end if;
assert AO!Eltseq(ChangeRing(v1, Ao)*(RepresentationMatrix(x, Ao))) eq y*x;
assert AO![Ao![s[1], s[2]], Ao![s[3], s[4]]] eq y*x where s is Eltseq(ChangeRing(v2, Rationals())*(RepresentationMatrix(x, Rationals())));
assert AO!Eltseq(ChangeRing(v1, Fo)*(RepresentationMatrix(x, Fo))) eq y*x;
if IsIntegral(x) then
    assert AO!Eltseq(v*ChangeRing(RepresentationMatrix(x, O), AO))[1] eq y*x;
end if;
assert AO!Eltseq(ChangeRing(v, FO)*RepresentationMatrix(x, FO))[1] eq y*x;
assert AO!Eltseq(ChangeRing(v, AO)*RepresentationMatrix(x, AO))[1] eq y*x;

assert RepresentationMatrix(x, Ao) eq RepresentationMatrix(x);
assert RepresentationMatrix(x, Rationals()) eq AbsoluteRepresentationMatrix(x);

if IsIntegral(x) then
    assert Norm(x, o) eq Norm(x);
    assert Norm(x, Integers()) eq AbsoluteNorm(x);
end if;
assert Norm(x, Ao) eq Ao!Norm(x);
assert Norm(x, Rationals()) eq AbsoluteNorm(x);
assert Norm(x, Fo) eq Fo!Norm(x);
if IsIntegral(x) then
    assert Norm(x, O) eq x;
end if;
assert Norm(x, FO) eq FO!x;
assert Norm(x, AO) eq AO!x;

if IsIntegral(x) then
    assert Trace(x, o) eq Trace(x);
    assert Trace(x, Integers()) eq AbsoluteTrace(x);
end if;
assert Trace(x, Ao) eq Ao!Trace(x);
assert Trace(x, Rationals()) eq AbsoluteTrace(x);
assert Trace(x, Fo) eq Fo!Trace(x);
if IsIntegral(x) then
    assert Trace(x, O) eq x;
end if;
assert Trace(x, FO) eq FO!x;
assert Trace(x, AO) eq AO!x;

Zx<x>:=PolynomialRing(Rationals());
f:=x^15 - 6*x^10 - 3*x^6 + 3*x^5 + 3*x^3 + 1;
b:=432134115405903623925;
E:=EquationOrder(f);
time o:=MaximalOrder(E:Discriminant:=b);
assert b mod Discriminant(o) eq 0;
g:=x^15 - 2*x^12 - 3*x^10 - 3*x^5 - 4*x^3 + 1;
c:=322763338071518266368;
EE:=EquationOrder(g);
time assert c mod Discriminant(MaximalOrder(EE:Discriminant:=c)) eq 0;

p:=5897;
h:=x^32 - 304*x^30 + 19740*x^28 + 1536112*x^26 - 115553350*x^24 -
6945150560*x^22 + 144703539528*x^20 + 18275404841680*x^18 +
528287933085923*x^16 + 6559941955405216*x^14 + 20592\
877515922584*x^12 - 258284175691577712*x^10 -
983929772609739414*x^8 + 17846760219589922192*x^6 +
95418922301525026612*x^4 - 121878529991820258656*x^2 + 350392590250134935281;
K:=NumberField(h); 
time OK:=MaximalOrder(K:Ramification:=[2,p]);
assert Discriminant(OK) mod 2*p eq 0;

for d in [3 .. 10] do

    f := Zx!Polynomial(Integers(), RandomIrreduciblePolynomial(GF(NextPrime(10001)), d));
f;
    time D := Discriminant(MaximalOrder(f));

    time assert D eq Discriminant(MaximalOrder(f : Discriminant := D));
    time assert D eq Discriminant(MaximalOrder(f : Discriminant := Random(1, 10)*D));
    time assert D eq Discriminant(MaximalOrder(f : Ramification := PrimeDivisors(D)));
    time assert D eq Discriminant(MaximalOrder(f : Ramification := Setseq(Seqset(PrimeDivisors(D) cat [-RandomPrime(7) : i in [1 .. 3]]))));

    m := Random(-100000, 100000);
m;
    f := Evaluate(f, x/m)*m^Degree(f);
    time assert D eq Discriminant(MaximalOrder(f : Discriminant := D));
    time assert D eq Discriminant(MaximalOrder(f : Discriminant := Random(1, 10)*D));
    time assert D eq Discriminant(MaximalOrder(f : Ramification := PrimeDivisors(D)));
    time assert D eq Discriminant(MaximalOrder(f : Ramification := Setseq(Seqset(PrimeDivisors(D) cat [RandomPrime(7) : i in [1 .. Random(1, 3)]]))));

end for;
Cputime(have_primes);

F6<t6>:=NumberField(y^3 - 59*y^2 + 42*y + 18) where y:=PolynomialRing(Rationals()).1;
GaloisGroup(F6);
SplittingField(F6);

function RandomPrimeIdeal(R)

    if Type(R) in {RngOrd, RngQuad, RngCyc, RngFunOrd} then
        p := RandomPrimeIdeal(CoefficientRing(R));
        ps := Decomposition(R, p);
        if ISA(Type(R), RngOrd) then
            return ps[i][1] where i is Random([1 .. #ps]);
        else
            return ps[i] where i is Random([1 .. #ps]);
        end if;
    elif Type(R) eq  RngInt then
        return RandomPrime(10);
    elif Type(R) eq RngUPol then
        if Characteristic(R) eq 0 then
            return R!ChangeUniverse(Eltseq(RandomPrimePolynomial(PolynomialRing(GF(NextPrime(100))), 3)), Integers());
        else
            return RandomPrimePolynomial(R, 3);
        end if;
    elif Type(R) eq RngVal then
        return R!(1/FieldOfFractions(R).1);
    end if;
    assert false;

end function;

K:= QuadraticField(3);
E:= ext< K | Polynomial([1,0,1]) >; 
M:= MaximalOrder(E);
w := WeakApproximation( [ K.1*M ] , [-1] );
assert Valuation(w, K.1*M) eq -1;

P := [RandomPrimeIdeal(M), RandomPrimeIdeal(M)];
w := WeakApproximation(P, [1, 2]);
assert Valuation(w, P[1]) eq 1;
assert Valuation(w, P[2]) eq 2;
w := WeakApproximation(P, [-1, -2]);
assert Valuation(w, P[1]) eq -1;
assert Valuation(w, P[2]) eq -2;
P := [RandomPrimeIdeal(M) : i in [1 .. 3]];
w := WeakApproximation(P, [1, 2, -1]);
assert Valuation(w, P[1]) eq 1;
assert Valuation(w, P[2]) eq 2;
assert Valuation(w, P[3]) eq -1;

//SetDelCheck(false);
f := Polynomial([ 72, 12, 45, 24, 42, 59, 1 ]);
E := EquationOrder(f);
M := MaximalOrder(E);
SetClassGroupBounds("GRH");
time ClassGroup(M);
time IndependentUnits(M);
SetOrderUnitsAreFundamental(M);
U, f := UnitGroup(M);
G, m := PicardGroup(E);
minc := Minimum(Conductor(E));
for I in &cat[[x[1] : x in Decomposition(E, p)] : p in [2, 3, 5, 11, 13, 17, 19]] do
    mincI := minc*I;
    prin, mg := IsPrincipal(I);
    if prin then
	assert mg*E eq I;
    else
	if ColonIdeal(1*E, I)*I eq 1*E then
	    assert not IsId(I @@ m);
	end if;
    end if;
    prin, mg := IsPrincipal(mincI);
    if prin then
	assert mg*E eq mincI;
    else
	if ColonIdeal(1*E, I)*I eq 1*E then
	    assert not IsId(I @@ m);
	end if;
    end if;
end for;

f := Polynomial([ 35, 38, 67, 98, 10, 25, 98, 1 ]);
E := EquationOrder(f);
M := MaximalOrder(E);
SetClassGroupBounds("GRH");
time ClassGroup(M);
time IndependentUnits(M);
SetOrderUnitsAreFundamental(M);
U, f := UnitGroup(M);
G, m := PicardGroup(E);
minc := Minimum(Conductor(E));
for I in &cat[[x[1] : x in Decomposition(E, p)] : p in [2, 3, 5, 11, 13, 17, 19]] do
    mincI := minc*I;
    time prin, mg := IsPrincipal(I);
    if prin then
	assert mg*E eq I;
    else
	if ColonIdeal(1*E, I)*I eq 1*E then
	    assert not IsId(I @@ m);
	end if;
    end if;
    time prin, mg := IsPrincipal(mincI);
    if prin then
	assert mg*E eq minc*I;
    else
	if ColonIdeal(1*E, I)*I eq 1*E then
	    assert not IsId(I @@ m);
	end if;
    end if;
end for;

F := sub<M|3*M.6, 21*M.7>;
A := ideal<F|Matrix(Integers(), 7, 7,
[ 1, 0, 0, 0, 0, 0, 1760212813261937805369, 0, 1, 0, 0, 0, 0,
1663465685850475878343, 0, 0, 1, 0, 0, 0, 1199874686123066036818, 0, 0, 0,
1, 0, 0, 1262917720737191620654, 0, 0, 0, 0, 1, 0, 1059129105603035725755,
0, 0, 0, 0, 0, 1, 146403459190834041259, 0, 0, 0, 0, 0, 0, 2968496435939085044434 ])>;
G, m := PicardGroup(F);
A3 := 3*A;
prin, mg := IsPrincipal(A);
if assigned mg then
    assert mg*E eq A;
else
    if ColonIdeal(1*F, A)*A eq 1*F then
	assert not IsId(A @@ m);
    end if;
end if;
prin, mg := IsPrincipal(A3);
if assigned mg then
    assert mg*E eq A3;
else
    if ColonIdeal(1*F, A3)*A3 eq 1*F then
	assert not IsId(A3 @@ m);
    end if;
end if;

repeat 
    f := RandomPrimePolynomial(PolynomialRing(GF(NextPrime(500))), 4);
    E := EquationOrder(Polynomial(Integers(), f));
    M := MaximalOrder(E);
until M ne E;
Eltseq(f);

Cputime(have_primes);
_<x>:=PolynomialRing(Rationals());
gg := [ x^2 - 5/8*x - 1/8, x^2 - 10/27*x + 1/27, x^2 - 1/2*x - 9/8, x^2 + 5/2*x + 3/8, x^2 + 27/8*x + 9/4 ];
gg cat:= [Polynomial(Rationals(), [Random(-100, 100) : j in [1 .. Max(3, i mod 6)]])/Random(1, 100) : i in [3 .. 100]];
gg;
for g in gg do
L, roots:=SplittingField(g);
if Degree(L) le 2*Degree(g) then
G:=Automorphisms(L);
else
G := Automorphisms(NumberField(g : Global));
roots := [x[1] : x in Roots(g, NumberField(g : Global))];
end if;
for a in G do
    s:=a(roots[1]);
    assert Evaluate(g,s) eq 0;
end for;
end for;

K<a>:=NumberField(x^2 - 2405) where x:=PolynomialRing(Rationals()).1;
K2:=NumberField(y^5 + (-a + 23)*y^4 + (-8*a + 583)*y^3 + 1/2*(-11*a -
107)*y^2 + 1/2*(171*a - 8233)*y + 1/2*(143*a - 6819)) where
y:=PolynomialRing(K).1;
K3:=NumberField(y^5 + (1/412544248165*(9713835003*a +
482587765090)*K2.1^4 + 1/825088496330*(-493373689441*a -
23326004103025)*K2.1^3 + 1/412544248165*(1505572590321*a \
+ 78937857504880)*K2.1^2 + 1/825088496330*(-2111303445369*a -
128149433026855)*K2.1 + 1/58934892595*(-38729554722*a -
8028067874910))*y^4 + (1/165017699266*(344442271*a +\
14225989215)*K2.1^4 + 1/825088496330*(-27684458127*a -
2270225739725)*K2.1^3 + 1/825088496330*(322717193109*a +
5432731418745)*K2.1^2 + 1/825088496330*(-756988248353*a -\
19911586114775)*K2.1 + 1/117869785190*(-1765935205787*a +
73746580079705))*y^3 + (1/412544248165*(-5610841104842*a -
274711682904685)*K2.1^4 + 1/825088496330*(2774493720\
14443*a + 13668751706106975)*K2.1^3 + 1/412544248165*(-900317570988763*a
- 43804296511091290)*K2.1^2 + 1/412544248165*(719236402266456*a +
33734009974862385)*K2.1 + 1/117\
86978519*(13704993184081*a + 556038060583798))*y^2 +
(1/825088496330*(99134783181087*a + 4865712996707305)*K2.1^4 +
1/165017699266*(-492612457384987*a - 24097054501786647\
)*K2.1^3 + 1/165017699266*(3164715905532907*a +
156144396798030659)*K2.1^2 + 1/82508849633*(-1251590107006255*a -
60852725655416215)*K2.1 + 1/58934892595*(-52789627304315\
3*a - 28663864580969855))*y + 1/412544248165*(480066575331778*a +
23512540502387515)*K2.1^4 + 1/82508849633*(-2376372654873473*a -
116963749692666995)*K2.1^3 + 1/82508849\
633*(15418920701132105*a + 751073419742369865)*K2.1^2 +
1/23573957038*(-3482034644598211*a - 168548819284681053)*K2.1 +
1/117869785190*(-11354146833062483*a - 50221980355\
1268765)) where y:=PolynomialRing(K2).1;
time MaximalOrder(K2);
time MaximalOrder(K3);

R<tt> := PolynomialRing(Rationals());
f := tt^5 + 5310484212450/141783684211*tt^4 +
54680043008511086788270084680/21328872508059689504764781*tt^3 +
97147076897526269929308321762811989445200/3024086124259414569082280689138572\
791*tt^2 +
862104645486223299229241275025356383230255298821365680/8256275906806976\
94625028870765990128518515676911*tt +
19884185814852727410405699282764752734231\
24941795642259067652256/2124510373737945707220885761695881561898594047216009\
58171;

resfield := NumberField(f);
OK := MaximalOrder(resfield : Ramification := [2,3,5,11,31,1061]);

