/*
Descendants of 6.178

We split the descendants of 6.178 order p^7 into five parametrized presentations

<a,b,c|ca-bab,cb-wbaa,pa-bab,pb-wbaa,pc-xbaaa,class=4>(all x, x~-x)
<a,b,c|ca-bab,cb-wbaa,pa-baa,pb+bab,pc-xbaab,class=4>(all x, x~-x)(p=1 mod 4)
<a,b,c|ca-bab,cb-wbaa,pa-bab,pb+wbaa,pc-xbaaa,class=4>(all x, x~-x)
<a,b,c|ca-bab,cb-wbaa,pa-baa-ybab,pb+(w*y)baa+bab,pc-xbaaa,class=4>(See Notes6.178)
<a,b,c|ca-bab,cb-wbaa,pa-ybab-tbaaa,pb-zbaa-ubaaa,pc-vbaaa,class=4>(See Notes6.178)
<a,b,c|ca-bab,cb-wbaa,pa-baa-ybab-tbaab,pb-zbaa+bab-ubaab,pc-vbaab,class=4>(See Notes6.178)

The first three of these presentations can be handled by your usual methods for the
straightforward cases.

The fourth presentation has two parameters [y,x] --- NOTE perverse order, with x second!

The fifth and sixth presentations have parameters [y,z,t,u,v], but we have to separate them
since they have different tails (baaa in the fifth, baab in the sixth).

We put the parameters for the fourth, fifth and sixth presentations into params4, params5,
params6.  Note that params4 will be empty unless p=3 mod 4.  You could add in a comment
"p=3 mod 4" into the appropriate field in the gapdec6.178 file.

The program potentially computes sets of parameters for presentations 1,2,3, but I have
commented out those bits.

*/

params4:=[];
params5:=[];
params6:=[];

readi p,"Input the prime p";
w:=0;
F:=FiniteField(p);
for i in [2..p-1] do
a:=F!i;
S:={a};
for j in [2..p-1] do
  Include(~S,a^j);
end for;
if #S eq p-1 then
  w:=i;
  break;
end if;
end for;
print "p equals",p;
print "w equals",w;

/*
Baker-Campbell-Hausdorff applied to
  <a,b,c|ca-bab,cb-wbaa,pa-xbaa-ybab,pb-zbaa+xbab,pc,class=4>
gives:

(b,a,a,a)^x*(b,a,a,b)^y = 1
(b,a,a,b)^z = (b,a,b,b)^x
(b,a,a,a)^z*(b,a,b,b)^y = 1

L^4 is generated by baaa unless y=0, in which case L^4 is generated by baab

GR[]:=Group<a,b,c | (c,a)*(b,a,b)^-1*(b,a,b,b), (c,b)*(b,a,a)^-w*(b,a,a,a)^w, 
a^p*(b,a,a)^-x*(b,a,b)^-y*(b,a,a,a)^x*(b,a,a,b)^(1/2*x+1/2*y)*(b,a,b,b)^y, 
b^p*(b,a,a)^-z*(b,a,b)^x*(b,a,a,a)^z*(b,a,a,b)^(-1/2*x+1/2*z)*(b,a,b,b)^-x, 
c^p>;

*/

SQ:={};
for i in [0..((p-1) div 2)] do
  Include(~SQ,i^2 mod p);
end for;

Z:=Integers();
V1:=VectorSpace(F,1);
V2:=VectorSpace(F,2);
H22:=Hom(V2,V2);

GR:=[];

count:=0;
mats:=[];

for y1 in [0,1] do
for y2 in [0..p-1] do
for y3 in [0..p-1] do
y4:=(p-y1) mod p;

A:=H22![y1,y2,y3,y4];
if Rank(A) lt 2 then continue; end if;

new:=1;
index:=p^2*y1+p*y2+y3;

for a in [0..p-1] do
for b in [0..p-1] do
if a+b eq 0 then continue; end if;
for c in [1,-1] do

P:=H22![a,b,w*b*c,a*c];
C:=F!(c*(a^2-w*b^2));

D:=P*A*P^-1*C^-1;

z1:=Z!(D[1][1]);
z2:=Z!(D[1][2]);
z3:=Z!(D[2][1]);

ind1:=p^2*z1+p*z2+z3;

if ind1 lt index then new:=0; break; end if;

end for;
if new eq 0 then break; end if;
end for;
if new eq 0 then break; end if;
end for;

if new eq 1 then
  count:=count+1;
  //print y1,y2,y3,y4;
  Append(~mats,A);
end if;

end for;
end for;
end for;

//print count,(3*p-1)/2;

count:=0;

for A in mats do
x:=Z!(A[1][1]);
y:=Z!(A[1][2]);
z:=Z!(A[2][1]);

r:=(F!(x+y))*(F!2)^-1; r:=Z!r;
s:=(F!(z-x))*(F!2)^-1; s:=Z!s;

u:=F!((x^2+y*z)*(2*(w*y+z)^2+w*(x^2+y*z))); u:=Z!u;

//Case 1
if x eq 0 and y eq 1 and z eq w then continue; end if;
//  for t in [0..((p-1) div 2)] do
//    count:=count+1;
//    GR[count]:=Group<a,b,c | (c,a)*(b,a,b)^-1*(b,a,b,b), (c,b)*(b,a,a)^-w*(b,a,a,a)^w, 
//         a^p*(b,a,a)^-x*(b,a,b)^-y*(b,a,a,a)^x*(b,a,a,b)^r*(b,a,b,b)^y, 
//         b^p*(b,a,a)^-z*(b,a,b)^x*(b,a,a,a)^z*(b,a,a,b)^s*(b,a,b,b)^-x, 
//         c^p=(b,a,a,a)^t>;
//    //tail on pa,pb zero, tail on pc equals tbaaa
//    Append(~params1,[x,y,z,0,0,t]);
//  end for;
//end if;

//Case 2
if x eq 1 and y eq 0 and z eq 0 then continue; end if;
//  range:=[0..((p-1) div 2)];
//  if p mod 4 eq 3 then print "Arghhh!!!"; end if;
//  //if p mod 4 eq 3 then range:=[0..p-1]; end if;
//  for t in range do
//    count:=count+1;
//    GR[count]:=Group<a,b,c | (c,a)*(b,a,b)^-1*(b,a,b,b), (c,b)*(b,a,a)^-w*(b,a,a,a)^w, 
//         a^p*(b,a,a)^-x*(b,a,b)^-y*(b,a,a,a)^x*(b,a,a,b)^r*(b,a,b,b)^y, 
//         b^p*(b,a,a)^-z*(b,a,b)^x*(b,a,a,a)^z*(b,a,a,b)^s*(b,a,b,b)^-x, 
//         c^p=(b,a,a,b)^t>;
//    //tail on pa,pb zero, tail on pc equals tbaab
//    Append(~params2,[x,y,z,0,0,t]);
//  end for;
//end if;

//Cases 3 and 4
if y ne 0 and (w*y+z) mod p eq 0 then 
  if x eq 0 then continue; end if; //This is Case 3
  for t in [0..((p-1) div 2)] do
    count:=count+1;
    GR[count]:=Group<a,b,c | (c,a)*(b,a,b)^-1*(b,a,b,b), (c,b)*(b,a,a)^-w*(b,a,a,a)^w, 
         a^p*(b,a,a)^-x*(b,a,b)^-y*(b,a,a,a)^x*(b,a,a,b)^r*(b,a,b,b)^y, 
         b^p*(b,a,a)^-z*(b,a,b)^x*(b,a,a,a)^z*(b,a,a,b)^s*(b,a,b,b)^-x, 
         c^p=(b,a,a,a)^t>;
    //tail on pa,pb zero, tail on pc equals tbaaa
    Append(~params4,[y,t]);
  end for;
end if;

//Case 5
if x eq 0 and z ne (w*y) mod p and z ne (w*(p-y)) mod p then
  for t in [0..((p-1) div 2)] do
    count:=count+1;
    GR[count]:=Group<a,b,c | (c,a)*(b,a,b)^-1*(b,a,b,b), (c,b)*(b,a,a)^-w*(b,a,a,a)^w, 
         a^p*(b,a,a)^-x*(b,a,b)^-y*(b,a,a,a)^x*(b,a,a,b)^r*(b,a,b,b)^y, 
         b^p*(b,a,a)^-z*(b,a,b)^x*(b,a,a,a)^z*(b,a,a,b)^s*(b,a,b,b)^-x, 
         c^p=(b,a,a,a)^t>;
    //tail on pa,pb zero, tail on pc equals tbaaa
    Append(~params5,[y,z,0,0,t]);
  end for;
  if u eq 0 then
    if (w*y+2*z) mod p eq 0 then
      for t in [1..((p-1) div 2)] do
        count:=count+1;
        GR[count]:=Group<a,b,c | (c,a)*(b,a,b)^-1*(b,a,b,b), (c,b)*(b,a,a)^-w*(b,a,a,a)^w, 
           a^p*(b,a,a)^-x*(b,a,b)^-y*(b,a,a,a)^(x-t)*(b,a,a,b)^r*(b,a,b,b)^y, 
           b^p*(b,a,a)^-z*(b,a,b)^x*(b,a,a,a)^z*(b,a,a,b)^s*(b,a,b,b)^-x, 
           c^p>;
        //tail on pb,pc zero, tail on pa equals tbaaa
        Append(~params5,[y,z,t,0,0]);
      end for;
    end if;
    if (2*w*y+z) mod p eq 0 then
      for t in [1..((p-1) div 2)] do
        count:=count+1;
        GR[count]:=Group<a,b,c | (c,a)*(b,a,b)^-1*(b,a,b,b), (c,b)*(b,a,a)^-w*(b,a,a,a)^w, 
           a^p*(b,a,a)^-x*(b,a,b)^-y*(b,a,a,a)^x*(b,a,a,b)^r*(b,a,b,b)^y, 
           b^p*(b,a,a)^-z*(b,a,b)^x*(b,a,a,a)^(z-t)*(b,a,a,b)^s*(b,a,b,b)^-x, 
           c^p>;
        //tail on pa,pc zero, tail on pb equals tbaaa
        Append(~params5,[y,z,0,t,0]);
      end for;
    end if;
  end if;
  if u ne 0 and u in SQ then
    u1:=F!(u)*(F!y)^-2; u1:=Z!u1;
    //find value of t such that u=t^2
    for t in [1..((p-1) div 2)] do
      if t^2 mod p eq u1 then val:=t; break; end if;
    end for;
    for t in [1..((p-1) div 2)] do
      count:=count+1;
      GR[count]:=Group<a,b,c | (c,a)*(b,a,b)^-1*(b,a,b,b), (c,b)*(b,a,a)^-w*(b,a,a,a)^w, 
         a^p*(b,a,a)^-x*(b,a,b)^-y*(b,a,a,a)^x*(b,a,a,b)^r*(b,a,b,b)^y, 
         b^p*(b,a,a)^-z*(b,a,b)^x*(b,a,a,a)^(z-t)*(b,a,a,b)^s*(b,a,b,b)^-x, 
         c^p=(b,a,a,a)^val>;
      //tail on pa zero, tail on pb equals tbaaa, tail on pc equals valbaaa
      Append(~params5,[y,z,0,t,val]);
    end for;
  end if;
end if;

//Case 6
if x eq 1 and (z+w*y) mod p ne 0 then
  for t in [0..p-1] do
    count:=count+1;
    GR[count]:=Group<a,b,c | (c,a)*(b,a,b)^-1*(b,a,b,b), (c,b)*(b,a,a)^-w*(b,a,a,a)^w, 
         a^p*(b,a,a)^-x*(b,a,b)^-y*(b,a,a,a)^x*(b,a,a,b)^r*(b,a,b,b)^y, 
         b^p*(b,a,a)^-z*(b,a,b)^x*(b,a,a,a)^z*(b,a,a,b)^s*(b,a,b,b)^-x, 
         c^p=(b,a,a,b)^t>;
    //tails on pa,pb zero, tail on pc is tbaab
    Append(~params6,[y,z,0,0,t]);
  end for;
  if u eq 0 then print "Arghhh!!!!!"; end if;
  //I have a proof that u can't be 0, but it is too long to fit here!
  if u in SQ then
    //find t such that u=t^2
    for t in [1..p-1] do
      if t^2 mod p eq u then val:=t; break; end if;
    end for;
    if F!(-w*y-z+val) eq 0 and F!(-w*y^2-2*y*z-1) eq 0 then
      for t in [1..((p-1) div 2)] do
        count:=count+1;
        GR[count]:=Group<a,b,c | (c,a)*(b,a,b)^-1*(b,a,b,b), (c,b)*(b,a,a)^-w*(b,a,a,a)^w, 
            a^p*(b,a,a)^-x*(b,a,b)^-y*(b,a,a,a)^x*(b,a,a,b)^(r-t)*(b,a,b,b)^y, 
            b^p*(b,a,a)^-z*(b,a,b)^x*(b,a,a,a)^z*(b,a,a,b)^s*(b,a,b,b)^-x, 
            c^p=(b,a,a,b)^val>;
        //tail on pa is tbaab, tail on pb is 0, tail on pc is val.baab
        Append(~params6,[y,z,t,0,val]);
      end for;
    else;
      for t in [1..((p-1) div 2)] do
        count:=count+1;
        GR[count]:=Group<a,b,c | (c,a)*(b,a,b)^-1*(b,a,b,b), (c,b)*(b,a,a)^-w*(b,a,a,a)^w, 
           a^p*(b,a,a)^-x*(b,a,b)^-y*(b,a,a,a)^x*(b,a,a,b)^r*(b,a,b,b)^y, 
           b^p*(b,a,a)^-z*(b,a,b)^x*(b,a,a,a)^z*(b,a,a,b)^(s-t)*(b,a,b,b)^-x, 
           c^p=(b,a,a,b)^val>;
        //tail on pa is 0, tail on pb is tbaab, tail on pc is val.baab
        Append(~params6,[y,z,0,t,val]);
      end for;
    end if;
    if F!(-w*y-z-val) eq 0 and F!(-w*y^2-2*y*z-1) eq 0 then
      for t in [1..((p-1) div 2)] do
        count:=count+1;
        GR[count]:=Group<a,b,c | (c,a)*(b,a,b)^-1*(b,a,b,b), (c,b)*(b,a,a)^-w*(b,a,a,a)^w, 
            a^p*(b,a,a)^-x*(b,a,b)^-y*(b,a,a,a)^x*(b,a,a,b)^(r-t)*(b,a,b,b)^y, 
            b^p*(b,a,a)^-z*(b,a,b)^x*(b,a,a,a)^z*(b,a,a,b)^s*(b,a,b,b)^-x, 
            c^p=(b,a,a,b)^-val>;
        //tail on pa is tbaab, tail on pb is 0, tail on pc is -val.baab
        Append(~params6,[y,z,t,0,-val]);
      end for;
    else;
      for t in [1..((p-1) div 2)] do
        count:=count+1;
        GR[count]:=Group<a,b,c | (c,a)*(b,a,b)^-1*(b,a,b,b), (c,b)*(b,a,a)^-w*(b,a,a,a)^w, 
            a^p*(b,a,a)^-x*(b,a,b)^-y*(b,a,a,a)^x*(b,a,a,b)^r*(b,a,b,b)^y, 
            b^p*(b,a,a)^-z*(b,a,b)^x*(b,a,a,a)^z*(b,a,a,b)^(s-t)*(b,a,b,b)^-x, 
            c^p=(b,a,a,b)^-val>;
        //tail on pa is 0, tail on pb is tbaab, tail on pc is -val.baab
        Append(~params6,[y,z,0,t,-val]);
      end for;
    end if;
  end if;
end if;

end for;

/*
print "Algebra 6.178 has",count,"descendants of order p^7 and class 4";
print "(3p^2-1)/2 =",(3*p^2-1)/2;
print "Parameter lists have size",#params1+#params2;
*/

if p mod 4 eq 1 then
  print "params4 has size 0:",#params4 eq 0;
else;
  print "params4 has size (p+1)/2:",#params4 eq (p+1)/2;
end if;

print "params5 and params6 together have size (3p^2-3p-4)/2:",#params5+#params6 eq (3*p^2-3*p-4)/2;

