/* For a cyclc group G = C_p one has DT(Z_pG) = C_{p-1}. */

for p in [3,5,7,11,13,17,19, 23] do
    print "************************** p = ", p, "  **********************";
    G := CyclicGroup(p);
    Krel := RelativeGroup(G, p);
    if not IsCyclic(Krel`DT) or #Krel`DT ne p-1 then
        print "ERROR ERROR ERROR !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
    end if;
end for;

/*******************************************************************************************/
/*******************************************************************************************/

/* For a dihedral group G = D_{2p}, p prime, one has DT(Z_2G) = 1 and DT(Z_pG) = C_{p-1}. */
for p in [3,5,7,11,13,17,19] do
    print "************************** p = ", p, "  **********************";
    G := DihedralGroup(p);
    Krel := [ RelativeGroup(G, q) : q in PrimeDivisors(#G) ];
    if  #Krel[1]`DT ne 1 or not IsCyclic(Krel[2]`DT) or #Krel[2]`DT ne p-1 then
        print "ERROR ERROR ERROR !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
    end if;
end for;

/******************************************************************************************/
/******************************************************************************************/

/* We check if Breuning's result ind_U^G = 0 for non-trivial subgroups U of
Q_8 can be generalized to Q_{2^n}. Q_{16} gives a counter example.
*/

G := QuaternionGroup(4);
i:=1;
KrelG := RelativeGroup(G, 2);
for s in Subgroups(G) do
    U := s`subgroup;
    if #U ne #G then
        print "*************************** i = ", i, "  ******************************";
        print "U = ", U;
        KrelU := RelativeGroup(U, 2);
        ind := hom<KrelU`DT->KrelG`DT | [g -> Induction(KrelU, KrelG, g) : g in Generators(KrelU`DT)]>;
        if Kernel(ind) ne KrelU`DT then
            print "----> induction is non-trivial !!!";
	    break;
        end if;
    end if;
    i +:= 1;
end for;

/******************************************************************************************/
/******************************************************************************************/


/* The induction map ind_U^G: K_0(Z_p[U] -> K_0(Z_p[G], Q_p)  is NOT trivial for p=5 */
p := 5;
G := QuaternionGroup(p);
i:=1;
KrelG := RelativeGroup(G, p);
for s in Subgroups(G) do
    U := s`subgroup;
    if #U ne #G then
        print "*************************** i = ", i, "  ******************************";
        print "U = ", U;
        KrelU := RelativeGroup(U, p);
        ind := hom<KrelU`DT->KrelG`DT | [g -> Induction(KrelU, KrelG, g) : g in Generators(KrelU`DT)]>;
        if Kernel(ind) ne KrelU`DT then
            print "----> induction is non-trivial !!!";
            break;
        end if;
    end if;
    i +:= 1;
end for;

/******************************************************************************************/
/******************************************************************************************/


/* By results of Wilson it is known that DT(Z_2G) = 1 for G=D_{2n}, n odd. */
for n in [9, 15, 21] do
    print "******************************* n = ", n, "  ***************************";
    G := DihedralGroup(n);
    Krel := RelativeGroup(G, 2);
    if #Krel`DT ne 1 then
        print "ERROR !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
	break;
    end if;
end for;

/*****************************************************************************************/
/*****************************************************************************************/

/* By a result of Breuning it is known that res : DT(Z_pG) -> DT(Z_pC) is injective for
   G = D_{2n}, n odd, and C the cyclic subgroup of order n.
*/
for n in [3, 5, 7, 9, 11, 13, 15, 17] do
    print "******************************* n = ", n, "  ***************************";
    G := DihedralGroup(n);
    S := Subgroups(G);
    for s in S do
        if #s`subgroup eq n then
            U := s`subgroup;
            break;
        end if;
    end for;
    for p in PrimeDivisors(n) do
        print "******************************* p = ", p, "  ***************************";
        KrelG := RelativeGroup(G, p);
        KrelU := RelativeGroup(U, p);
        res := hom<KrelG`DT->KrelU`DT | [g -> Restriction(KrelG, KrelU, g) : g in Generators(KrelG`DT)]>;
        if #Kernel(res) ne 1 then 
            print "ERROR !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
            break n;
        end if;
    end for;
end for;


/********************************************************************************/
/********************************************************************************/

/* We check the implementation against Curtis/Reiner, Theorem (53.13) */
ps := [3, 5];
s_bound := [2, 1];
for i:=1 to #ps do
    p := ps[i];
    for s := 1 to s_bound[i] do
        G := PermutationGroup( AbelianGroup( [p : i in [1..s+1]] ) );
        cl := LocallyFreeClassgroup(G, false);
        QG := cl`QG;
        rho := RegularRep(QG);
        log := [];
        M, f := MultiplicativeGroup( quo< Integers() | #G > );
        for g in Generators(M) do
            S := SwanModule( Integers()!f(g), rho );
            Append(~log, ClassGroupLog(cl, S));
        end for;
        print "p = ", p, " s = ", s, " cl = ", cl`cl, " log = ", log;
        TG := sub<cl`cl | log>;
        print "TG = ", TG;
        if not IsCyclic(TG) or #TG ne p^s then
            print "ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR";
        end if;
        print "*****************************************************";
       print "*****************************************************";
     end for;
end for;


/********************************************************************************/
/********************************************************************************/

/* We check the implementation against Curtis/Reiner, Theorem (53.14) */
    for s := 1 to 3 do
        G := PermutationGroup( AbelianGroup( [2 : i in [1..s+1]] ) );
        cl := LocallyFreeClassgroup(G, false);
        QG := cl`QG;
        rho := RegularRep(QG);
        log := [];
        M, f := MultiplicativeGroup( quo< Integers() | #G > );
        for g in Generators(M) do
            S := SwanModule( Integers()!f(g), rho );
            Append(~log, ClassGroupLog(cl, S));
        end for;
        print "s = ", s, " cl = ", cl`cl, " log = ", log;
        TG := sub<cl`cl | log>;
        print "TG = ", TG;
        if not IsCyclic(TG) or #TG ne 2^(s-1) then
            print "ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR";
        end if;
        print "*****************************************************";
       print "*****************************************************";
     end for;

/********************************************************************************/
/********************************************************************************/

/* We check the implementation against Curtis/Reiner, Theorem (53.16) */
lm := [ [1,1], [0,2], [2,0], [2,1], [1,2] ];
for x in lm do
        l := x[1]; m := x[2];
        v := [2 : i in [1..l]] cat [4 : i in [1..m]] ;
        G := PermutationGroup( AbelianGroup( v ) );
        cl := LocallyFreeClassgroup(G, false);
        QG := cl`QG;
        rho := RegularRep(QG);
        log := [];
        M, f := MultiplicativeGroup( quo< Integers() | #G > );
        for g in Generators(M) do
            S := SwanModule( Integers()!f(g), rho );
            Append(~log, ClassGroupLog(cl, S));
        end for;
        print "lm = ", x, " cl = ", cl`cl, " log = ", log;
        TG := sub<cl`cl | log>;
        print "TG = ", TG;
        if not IsCyclic(TG) or #TG ne 2^(l+2*m-2) then
            print "ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR";
        end if;
        print "*****************************************************";
       print "*****************************************************";
end for;


/********************************************************************************/
/********************************************************************************/

/* We check the implementation against Curtis/Reiner, Theorem (53.19) */
pqk := [ [5,4,2], [7,3,2], [7,6,3] ];
for x in pqk do
        p := x[1]; q := x[2]; k := x[3];
        G := MetacyclicGroup(p, q, k);
        cl := LocallyFreeClassgroup(G, false);
        QG := cl`QG;
        rho := RegularRep(QG);
        log := [];
        M, f := MultiplicativeGroup( quo< Integers() | #G > );
        for g in Generators(M) do
            S := SwanModule( Integers()!f(g), rho );
            Append(~log, ClassGroupLog(cl, S));
        end for;
        print "pqk = ", x, " cl = ", cl`cl, " log = ", log;
        TG := sub<cl`cl | log>;
        print "TG = ", TG;
        if not IsCyclic(TG) or #TG ne Integers()!(q / GCD(2,q)) then
            print "ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR";
        end if;
        print "*****************************************************";
       print "*****************************************************";
end for;

