Attach("RelAlgKTheory.m");
Attach("SqrtInvDiff.m");
Attach("INB.m");
AttachSpec("spec");


/* pCubedFields.data contains a list of three number field extensions L/Q, each Galois of degree 27 with a unique
   prime above p=3 such that the completions at the unique prime above p give the extensions of Qp of degree 27 which
   are wildly and weakly ramifified. We then compute for each of these fields the values for setting`lhs, setting`rhs and
   setting`twisted_unram-char which are, in the same order, the left hand side of the local epsilon constant conjecture, i.e. \fra_{L/Qp},
   the right hand side of the local epsilon constant conjecture and, finally, the twisted unramified characteristic.

   Conjecturally, all three values coincide, as confirmed by the computations.

   The whole computation takes about 53 minutes on my laptop.
*/

start := Cputime();
load "pCubedFields.data";
Ls := [L1, L2, L3];
results := [];

p := 3;
// SetVerbose("epsConj", 1);
// SetVerbose("RelKTh", 0);
for L in Ls do
    setting := LECcreateRec(L, p);
    time pCubedLECverify(~setting);

    Append(~results, setting);
end for;
print "This needed ", (Cputime() - start)/60, " minutes.";

for res in results do
    print "*********************************************************";
    print "The invariant fra :", res`lhs;
    print "The twisted unramified characteristic :", res`twisted_unram_char;
    print "The right hand side of the local eps conjecture :", res`rhs;
end for;



/* Computation of all on-abelian wildly and weakly ramified extensions L/Qp of degre 27 and global represantatives.
   Our approach is completely heuristic. It may be possible to obtain much better global representatives,
   better in the sense that they are better suited to numerical computations.
   
   We then compute the class of the square root of the inverse different in the locally free class group. In each of the cases
   the class is trivial, as it has to be in order to be consistent with the above computations: there we have computed that \fra = \frc,
   and by theory, since the ramification group is of p-power order, we know that \frc projects to zero, hence \fra projects to zero.
      
   The whole computation takes about 1.5 minutes on my laptop.

*/

start := Cputime();
GlobalpCubedFields, LocalpCubedFields := Find3CubedExtensions(19, 30);

/* Check whether the fields are non isomorphic. */
F0 := LocalpCubedFields[1];
F1 := LocalpCubedFields[2];
F2 := LocalpCubedFields[3];
IsIsomorphic(F0, F1);
IsIsomorphic(F0, F2);
IsIsomorphic(F1, F2);

/* For each of the global fields we check whether the square root of the inverse different is a free Z[G]-module.
*/
p := 3;
for L in  GlobalpCubedFields do
    print "Check ", L;

    G, Aut, h := AutomorphismGroup(L);
    h := map<Domain(h)->Codomain(h) | g:->h(g^-1)>;

    OL := MaximalOrder(L);
    DL := Different(OL);
    AL := Sqrt(DL)^-1;

    /* The class group log will only work if we make a good choice for theta. Using an arbitrary theta leads to a
       bad Ath. If we first compute a weak integral normal basis for AL (i.e. a genarator over a maximal order, then
       this theta is much better suited to numerical computations.
    */
    X :=pCubed_nb(L, G, AL, h: WeakINB:=true);
    theta := X[2]; AssOrd := X[4]; wnb := X[5]; QG := X[7];
    lambda := QG ! Eltseq(wnb);
    delta := QGAction(lambda, theta, h);
    Adelta := ComputeAtheta(OL, AL, h, delta);
    Adelta := ModuleScalarProd(QG, QG!p^3, Adelta);

    rho := RegularRep(QG);
    M := ZGModuleInit(Adelta`hnf, rho);

    C := LocallyFreeClassgroup(G, true);

    time log := ClassGroupLog(C, M);
    print "log = ", log;
end for;
print "This needed ", (Cputime() - start)/60, " minutes.";



/* Computation of all on-abelian wildly and weakly ramified extensions L/Qp of degree 63and global represantatives
   such that Gal(L^C/Qp) \simeq Z/3 x Z/3.
   Our approach is completely heuristic. It may be possible to obtain much better global representatives,
   better in the sense that they are better suited to numerical computations.

   The complete computation (including the computation below) takes about 131 minutes on my laptop.
*/

start := Cputime();
ExtensionsOfDeg63 := FindExtensionsOfDeg63(2, 30);

/* For the 3 extensions found above we show that the class of the square root of the inverse different is trivial in 
   the locally free class group. In addition, we compute the idelic twisted unramified characteristic and show that
   the projection to the locally free class group is trivial.
*/

for i in [1..#ExtensionsOfDeg63] do
    print "i = ", i;
    L := ExtensionsOfDeg63[i][1];
    OL := MaximalOrder(L);
    DL := Different(OL);
    AL := Sqrt(DL)^-1;
    G, Aut, h := AutomorphismGroup(L);
    h := map<Domain(h)->Codomain(h) | g:->h(g^-1)>;
    time X :=G63_nb(L, G, h: WeakINB:=true);
    theta := X[2]; Ath := X[3]; AssOrd := X[4]; wnb := X[5]; QG := X[7]; MaxOrd := X[8]; MaxAth := X[9];
    lambda := QG ! Eltseq(wnb);
    delta := QGAction(lambda, theta, h);
    Adelta := ComputeAtheta(OL, AL, h, delta);
    rho := RegularRep(QG);
    M := ZGModuleInit(ModuleScalarProd(QG, QG!63, Adelta), rho);
    cl := LocallyFreeClassgroup(G, true);
    time log := ClassGroupLog(cl, M);
    print "log = ", log;



    P7 := Factorization(7*OL)[1,1];
    I := RamificationGroup(P7, 0, h);
    eI := SubgroupIdempotent(QG, I);
    Frob := Frobenius(OL, h, 7) ;
    eta := (One(QG) - eI) + Frob^-1*eI;
    nr := NewtonReducedNorm(eta);
    K := RelativeGroup(QG, 7);
    twisted_unram_char := K0RelLog(K, nr);

    ProjectionToClassgroup(twisted_unram_char, K, cl);

end for;
print "This needed ", (Cputime() - start)/60, " minutes.";


/* We compute the invariant fra for the first of the three extensions of degree 63 and compare it to the
   twisted unramified chatacteristic. As conjectured both invariants coincide.

   This takes about 39 minutes.
*/
start := Cputime();
L := ExtensionsOfDeg63[1][1];
p := 7;
// SetVerbose("epsConj", 1);
// SetVerbose("RelKTh", 0);
setting := LECcreateRec(L, p);
time pCubedLECverify(~setting);

print "The invariant fra : ", setting`lhs;
print "The twisted unramified characteristic : ", setting`twisted_unram_char;
print "This needed ", (Cputime() - start)/60, " minutes.";
