
pMaximalOrderD := func<x, p | pMaximalOrder(x, p: Debug := true)>;

SetEchoInput(true);

P<x> := PolynomialRing(Integers());
K := EquationOrder(x^2 + 2);
D := Factorization(Discriminant(DefiningPolynomial(K)));
time pO := pMaximalOrder(K, D[1][1]);
v := Valuation(Index(pO, K), D[1][1]);
assert IsOne(Index(pO, K)/D[1][1]^v);
time assert Discriminant(MaximalOrder(K)) eq -8;

K := EquationOrder(x^2 + 11);
D := Factorization(Discriminant(DefiningPolynomial(K)));
time pO := pMaximalOrder(K, D[1][1]);
v := Valuation(Index(pO, K), D[1][1]);
assert IsOne(Index(pO, K)/D[1][1]^v);
time pO := pMaximalOrder(K, D[2][1]);
v := Valuation(Index(pO, K), D[2][1]);
assert IsOne(Index(pO, K)/D[2][1]^v);
time assert Discriminant(MaximalOrder(K)) eq -11;

k := CyclotomicField(3);
a := k!625;
K := ext<EquationOrder(k) | PolynomialRing(k).1^3 - a>;
D := Decomposition(MaximalOrder(k)!Discriminant(DefiningPolynomial(K)));
time pO := pMaximalOrder(K, D[1][1]);
v := Valuation(Index(pO, K), D[1][1]);
assert IsOne(Index(pO, K)/D[1][1]^v);
time pO := pMaximalOrder(K, D[2][1]);
v := Valuation(Index(pO, K), D[2][1]);
assert IsOne(Index(pO, K)/D[2][1]^v);
time M := MaximalOrder(K);
assert Discriminant(M) eq -225*MaximalOrder(k);

k := CyclotomicField(9);
a := k!2^4;
K := ext<EquationOrder(k) | PolynomialRing(k).1^9 - a>;
D := Decomposition(MaximalOrder(k)!Discriminant(DefiningPolynomial(K)));
time pO := pMaximalOrder(K, D[1][1]);
v := Valuation(Index(pO, K), D[1][1]);
assert IsOne(Index(pO, K)/D[1][1]^v);
time pO := pMaximalOrder(K, D[2][1]);
v := Valuation(Index(pO, K), D[2][1]);
assert IsOne(Index(pO, K)/D[2][1]^v);
time M := MaximalOrder(K);

k := CyclotomicField(6);
a := k!7^5;
K := ext<EquationOrder(k) | PolynomialRing(k).1^6 - a>;
D := Decomposition(MaximalOrder(k)!Discriminant(DefiningPolynomial(K)));
time pO := pMaximalOrder(K, D[1][1]);
v := Valuation(Index(pO, K), D[1][1]);
assert IsOne(Index(pO, K)/D[1][1]^v);
time pO := pMaximalOrder(K, D[2][1]);
v := Valuation(Index(pO, K), D[2][1]);
assert IsOne(Index(pO, K)/D[2][1]^v);
time M := MaximalOrder(K);

k := CyclotomicField(12);
a := k!5^7;
K := ext<EquationOrder(k) | PolynomialRing(k).1^12 - a>;
D := Decomposition(MaximalOrder(k)!Discriminant(DefiningPolynomial(K)));
time pO := pMaximalOrder(K, D[1][1]);
v := Valuation(Index(pO, K), D[1][1]);
assert IsOne(Index(pO, K)/D[1][1]^v);
time pO := pMaximalOrder(K, D[2][1]);
v := Valuation(Index(pO, K), D[2][1]);
assert IsOne(Index(pO, K)/D[2][1]^v);
time M := MaximalOrder(K);

P<x> := PolynomialRing(CyclotomicField(3));
P<y> := PolynomialRing(P);
k := FunctionField(y^2 + x);
a := k!625*x;
K := ext<EquationOrderFinite(k) | PolynomialRing(k).1^3 - a>;
D := Factorization(MaximalOrderFinite(k)*Discriminant(DefiningPolynomial(K)));
time pO := pMaximalOrder(K, D[1][1]);
v := Valuation(Index(pO, K), D[1][1]);
assert IsOne(Index(pO, K)/D[1][1]^v);

a := k!625/x;
K := ext<EquationOrderInfinite(k) | PolynomialRing(k).1^3 - a>;
D := Factorization(MaximalOrderInfinite(k)*Discriminant(DefiningPolynomial(K)));
time pO := pMaximalOrder(K, D[1][1]);
v := Valuation(Index(pO, K), D[1][1]);
assert IsOne(Index(pO, K)/D[1][1]^v);

P<x> := PolynomialRing(CyclotomicField(9));
P<y> := PolynomialRing(P);
k := FunctionField(y^2 + x);
a := k!2^4*x;
K := ext<EquationOrderFinite(k) | PolynomialRing(k).1^9 - a>;
D := Factorization(MaximalOrderFinite(k)*Discriminant(DefiningPolynomial(K)));
time pO := pMaximalOrder(K, D[1][1]);
v := Valuation(Index(pO, K), D[1][1]);
assert IsOne(Index(pO, K)/D[1][1]^v);

a := k!2^4/x;
K := ext<EquationOrderInfinite(k) | PolynomialRing(k).1^9 - a>;
D := Factorization(MaximalOrderInfinite(k)*Discriminant(DefiningPolynomial(K)));
time pO := pMaximalOrder(K, D[1][1]);
v := Valuation(Index(pO, K), D[1][1]);
assert IsOne(Index(pO, K)/D[1][1]^v);

P<x> := PolynomialRing(CyclotomicField(6));
P<y> := PolynomialRing(P);
k := FunctionField(y^2 + x);
a := k!7^5*x;
K := ext<EquationOrderFinite(k) | PolynomialRing(k).1^6 - a>;
D := Factorization(MaximalOrderFinite(k)*Discriminant(DefiningPolynomial(K)));
time pO := pMaximalOrder(K, D[1][1]);
v := Valuation(Index(pO, K), D[1][1]);
assert IsOne(Index(pO, K)/D[1][1]^v);

a := k!7^5/x;
K := ext<EquationOrderInfinite(k) | PolynomialRing(k).1^6 - a>;
D := Factorization(MaximalOrderInfinite(k)*Discriminant(DefiningPolynomial(K)));
time pO := pMaximalOrder(K, D[1][1]);
v := Valuation(Index(pO, K), D[1][1]);
assert IsOne(Index(pO, K)/D[1][1]^v);

P<x> := PolynomialRing(CyclotomicField(12));
P<y> := PolynomialRing(P);
k := FunctionField(y^2 + x);
a := k!5^7*x;
K := ext<EquationOrderFinite(k) | PolynomialRing(k).1^12 - a>;
D := Factorization(MaximalOrderFinite(k)*Discriminant(DefiningPolynomial(K)));
time pO := pMaximalOrder(K, D[1][1]);
v := Valuation(Index(pO, K), D[1][1]);
assert IsOne(Index(pO, K)/D[1][1]^v);

a := k!5^7/x;
K := ext<EquationOrderInfinite(k) | PolynomialRing(k).1^12 - a>;
D := Factorization(MaximalOrderInfinite(k)*Discriminant(DefiningPolynomial(K)));
time pO := pMaximalOrder(K, D[1][1]);
v := Valuation(Index(pO, K), D[1][1]);
assert IsOne(Index(pO, K)/D[1][1]^v);

valuation := function(x, p)
    v := 0;
    while x ne 0 do
	x, r := Quotrem(x, p);
	if r ne 0 then
	    break;
	end if;
	v +:= 1;
    end while;
    return v;
end function;

P<x> := PolynomialRing(Rationals());
P<y> := PolynomialRing(P);
F<c> := FunctionField(y^2 - x);
D := Factorization(Discriminant(DefiningPolynomial(F)));
time pO := pMaximalOrder(EquationOrderFinite(F), D[1][1]);
v := valuation(Index(pO, EquationOrderFinite(F)), D[1][1]);
assert IsOne(Index(pO, EquationOrderFinite(F))/D[1][1]^v);
D := Factorization(Discriminant(DefiningPolynomial(EquationOrderInfinite(F))));
time pO := pMaximalOrder(EquationOrderInfinite(F), D[1][1]);
v := valuation(Index(pO, EquationOrderInfinite(F)), D[1][1]);
assert IsOne(Index(pO, EquationOrderInfinite(F))/D[1][1]^v);
time assert Discriminant(MaximalOrderFinite(F)) eq 4*x;
time assert Discriminant(MaximalOrderInfinite(F)) eq 4/x;

P<x> := PolynomialRing(CyclotomicField(8));
P<y> := PolynomialRing(P);
F<c> := FunctionField(y^8 + 3*x^4);
D := Factorization(Discriminant(DefiningPolynomial(F)));
time pO := pMaximalOrder(EquationOrderFinite(F), D[1][1]);
v := valuation(Index(pO, EquationOrderFinite(F)), D[1][1]);
assert IsOne(Index(pO, EquationOrderFinite(F))/D[1][1]^v);
D := Factorization(Discriminant(DefiningPolynomial(EquationOrderInfinite(F))));
time pO := pMaximalOrder(EquationOrderInfinite(F), D[1][1]);
v := valuation(Index(pO, EquationOrderInfinite(F)), D[1][1]);
assert IsOne(Index(pO, EquationOrderInfinite(F))/D[1][1]^v);
time assert Discriminant(MaximalOrderFinite(F)) eq 36691771392*x^4;
time assert Discriminant(MaximalOrderInfinite(F)) eq 36691771392/x^4;

P<x> := PolynomialRing(CyclotomicField(20));
P<y> := PolynomialRing(P);
F<c> := FunctionField(y^20 + 7*x^11);
D := Factorization(Discriminant(DefiningPolynomial(F)));
time pO := pMaximalOrder(EquationOrderFinite(F), D[1][1]);
v := valuation(Index(pO, EquationOrderFinite(F)), D[1][1]);
assert IsOne(Index(pO, EquationOrderFinite(F))/D[1][1]^v);
D := Factorization(Discriminant(DefiningPolynomial(EquationOrderInfinite(F))));
time pO := pMaximalOrder(EquationOrderInfinite(F), D[1][1]);
v := valuation(Index(pO, EquationOrderInfinite(F)), D[1][1]);
assert IsOne(Index(pO, EquationOrderInfinite(F))/D[1][1]^v);
time assert Discriminant(MaximalOrderFinite(F)) eq 1195260791789782879436800000000000000000000*x^19;
time assert Discriminant(MaximalOrderInfinite(F)) eq 1195260791789782879436800000000000000000000/x^19;

P<x> := PolynomialRing(GF(5));
P<y> := PolynomialRing(P);
F<c> := FunctionField(y^4 + x);
D := Factorization(Discriminant(DefiningPolynomial(F)));
time pO := pMaximalOrder(EquationOrderFinite(F), D[1][1]);
v := valuation(Index(pO, EquationOrderFinite(F)), D[1][1]);
assert IsOne(Index(pO, EquationOrderFinite(F))/D[1][1]^v);
D := Factorization(Discriminant(DefiningPolynomial(EquationOrderInfinite(F))));
time pO := pMaximalOrder(EquationOrderInfinite(F), D[1][1]);
v := valuation(Index(pO, EquationOrderInfinite(F)), D[1][1]);
assert IsOne(Index(pO, EquationOrderInfinite(F))/D[1][1]^v);
time assert Discriminant(MaximalOrderFinite(F)) eq x^3;
time assert Discriminant(MaximalOrderInfinite(F)) eq 1/x^3;

P<x> := PolynomialRing(GF(7, 3));
P<y> := PolynomialRing(P);
F<c> := FunctionField(y^6 + 2*x^4);
D := Factorization(Discriminant(DefiningPolynomial(F)));
time pO := pMaximalOrder(EquationOrderFinite(F), D[1][1]);
v := valuation(Index(pO, EquationOrderFinite(F)), D[1][1]);
assert IsOne(Index(pO, EquationOrderFinite(F))/D[1][1]^v);
D := Factorization(Discriminant(DefiningPolynomial(EquationOrderInfinite(F))));
time pO := pMaximalOrder(EquationOrderInfinite(F), D[1][1]);
v := valuation(Index(pO, EquationOrderInfinite(F)), D[1][1]);
assert IsOne(Index(pO, EquationOrderInfinite(F))/D[1][1]^v);
time assert Discriminant(MaximalOrderFinite(F)) eq 3*x^4;
time assert Discriminant(MaximalOrderInfinite(F)) eq 3/x^4;

P<x> := PolynomialRing(Rationals());
P<y> := PolynomialRing(P);
F<c> := FunctionField(P!CyclotomicPolynomial(7));
FF<cc> := ext<F | Polynomial(F, [x*c, 0, 0, 0, 0, 0, 0, 1])>;
time MaximalOrderFinite(FF);
assert Discriminant($1) eq (823543*x^6*c^5 + 823543*x^6*c^4 + 823543*x^6*c^3 + 823543*x^6*c^2 + 823543*x^6*c
    + 823543*x^6)*MaximalOrderFinite(F);
time MaximalOrderInfinite(FF);
assert Discriminant($1) eq (823543/x^6*c^5 + 823543/x^6*c^4 + 823543/x^6*c^3 + 823543/x^6*c^2 + 823543/x^6*c
    + 823543/x^6)*MaximalOrderInfinite(F);

k := GF(9);
kx<x> := FunctionField(k);
kxy<y> := PolynomialRing(kx);
K := FunctionField(y^3+y+1/x+1/x^2);
lp := Places(K, 2);
D := &+ [1*Random(lp) : i in [1..4]];
R, mR := RayClassGroup(D);
Q, mQ := quo<R|8*R>;
lQ := Subgroups(Q: Quot := [8]);
A := [AbelianExtension(D, x`subgroup@@mQ) : x in lQ];
#A;
for i in [1 .. 10] do
    b := Random([1 .. #A]);
    a := A[b];
    Remove(~A, b);
    F := FunctionField(DefiningPolynomials(FunctionField(a))[1]);
    time MaximalOrderFinite(F);
    "\n\nFINITE", i, "\n\n";
    time MaximalOrderInfinite(F);
    "\n\nINFINITE", i, "\n\n";
    assert DiscriminantDivisor(a) eq
	    Divisor(Discriminant(MaximalOrderFinite(F))) + Divisor(Discriminant(
	    MaximalOrderInfinite(F)));
end for;

