// Order formulae for Chevalley groups

P<q> := PolynomialRing(Integers());
print "Type A_n";
for n := 1 to 5 do
  N := n*(n+1) div 2;
  f := q^N * &*[q^i - 1 : i in [2..n+1]];
  assert f eq ChevalleyOrderPolynomial("A",n);
end for;
print "Type 2A_n";
for n := 1 to 5 do
  N := n*(n+1) div 2;
  f := q^N * &*[q^i - (-1)^i : i in [2..n+1]];
  assert f eq ChevalleyOrderPolynomial("2A",n);
end for;
print "Type B_n";
for n := 1 to 5 do
  N := n*n;
  f := q^N * &*[q^(2*i) - 1 : i in [1..n]];
  assert f eq ChevalleyOrderPolynomial("B",n);
end for;
print "Type 2B2";
  f := q^2*(q-1)*(q^2+1);
  assert f eq ChevalleyOrderPolynomial("2B",2);
print "Type C_n";
for n := 1 to 5 do
  N := n*n;
  f := q^N * &*[q^(2*i) - 1 : i in [1..n]];
  assert f eq ChevalleyOrderPolynomial("C",n);
end for;
print "Type D_n";
for n := 1 to 5 do
  N := n*(n-1);
  f := (n eq 1) select q-1 else
       q^N * (q^n-1) * &*[q^(2*i) - 1 : i in [1..n-1]];
  assert f eq ChevalleyOrderPolynomial("D",n);
end for;
print "Type 2D_n";
for n := 1 to 5 do
  N := n*(n-1);
  f := (n eq 1) select q+1 else
       q^N * (q^n+1) * &*[q^(2*i) - 1 : i in [1..n-1]];
  assert f eq ChevalleyOrderPolynomial("2D",n);
end for;
print "Type 3D_4";
  f := q^12*(q^2-1)*(q^4-q^2+1)*(q^4+q^2+1)*(q^6-1);
  assert f eq ChevalleyOrderPolynomial("3D",4);
print "Type E_n";
  f := q^36*(q^2-1)*(q^5-1)*(q^6-1)*(q^8-1)*(q^9-1)*(q^12-1);
  assert f eq ChevalleyOrderPolynomial("E",6);
  f := q^63*(q^2-1)*(q^6-1)*(q^8-1)*(q^10-1)*(q^12-1)*(q^14-1)*(q^18-1);
  assert f eq ChevalleyOrderPolynomial("E",7);
  f := q^120*(q^2-1)*(q^8-1)*(q^12-1)*(q^14-1)*(q^18-1)*(q^20-1)*(q^24-1)*(q^30-1);
  assert f eq ChevalleyOrderPolynomial("E",8);
print "Type 2E_6";
  f := q^36*(q^2-1)*(q^5+1)*(q^6-1)*(q^8-1)*(q^9+1)*(q^12-1);
  assert f eq ChevalleyOrderPolynomial("2E",6);
print "Type F_4";
  f := q^24*(q^2-1)*(q^6-1)*(q^8-1)*(q^12-1);
  assert f eq ChevalleyOrderPolynomial("F",4);
print "Type 2F_4";
  f := q^12*(q^6+1)*(q^4-1)*(q^3+1)*(q-1);
  assert f eq ChevalleyOrderPolynomial("2F",4);
print "Type G_2";
  f := q^6*(q^2-1)*(q^6-1);
  assert f eq ChevalleyOrderPolynomial("G",2);
print "Type 2G_2";
  f := q^3*(q^3+1)*(q-1);
  assert f eq ChevalleyOrderPolynomial("2G",2);

print "Factored adjoint order test";
for q in [2,3,4,5,7,9] do
  print q;
  assert FactoredChevalleyGroupOrder("A",3,q : Version := "Adjoint") eq FactoredOrder(PSL(4,q));
  assert FactoredChevalleyGroupOrder("B",3,q : Version := "Adjoint") eq FactoredOrder(POmega(7,q));
  assert FactoredChevalleyGroupOrder("C",3,q : Version := "Adjoint") eq FactoredOrder(PSp(6,q));
  assert FactoredChevalleyGroupOrder("D",3,q : Version := "Adjoint") eq FactoredOrder(POmegaPlus(6,q));
  assert FactoredChevalleyGroupOrder("2A",3,q : Version := "Adjoint") eq FactoredOrder(PSU(4,q));
  assert FactoredChevalleyGroupOrder("2D",3,q : Version := "Adjoint") eq FactoredOrder(POmegaMinus(6,q));
  assert FactoredChevalleyGroupOrder("G",2,q : Version := "Adjoint") eq FactoredOrder(G2(q));
end for;
for q in [2,8] do
  assert FactoredChevalleyGroupOrder("2B",2,q : Version := "Adjoint") eq FactoredOrder(SuzukiGroup(q));
end for;

print "Factored Chevalley order test (1)";
for q in [2,3,4,5,7,9] do
  print q;
  assert FactoredChevalleyGroupOrder("A",3,q) eq FactoredOrder(SL(4,q));
  assert FactoredChevalleyGroupOrder("B",3,q) eq FactoredOrder(Omega(7,q));
  assert FactoredChevalleyGroupOrder("C",3,q) eq FactoredOrder(Sp(6,q));
  assert FactoredChevalleyGroupOrder("D",3,q) eq FactoredOrder(OmegaPlus(6,q));
  assert FactoredChevalleyGroupOrder("2A",3,q) eq FactoredOrder(SU(4,q));
  assert FactoredChevalleyGroupOrder("2D",3,q) eq FactoredOrder(OmegaMinus(6,q));
  assert FactoredChevalleyGroupOrder("G",2,q) eq FactoredOrder(G2(q));
end for;
for q in [2,8] do
  assert FactoredChevalleyGroupOrder("2B",2,q) eq FactoredOrder(SuzukiGroup(q));
end for;
for q in [27] do
  assert FactoredChevalleyGroupOrder("2G",2,q) eq FactoredOrder(ReeGroup(q));
end for;

print "Factored Chevalley order test (2)";
for q in [2,3,4,5,7,9] do
  print q;
  assert FactoredChevalleyGroupOrder("A",3,q) eq FactoredOrder(ChevalleyGroup("A",3,q));
  assert FactoredChevalleyGroupOrder("B",3,q) eq FactoredOrder(ChevalleyGroup("B",3,q));
  assert FactoredChevalleyGroupOrder("C",3,q) eq FactoredOrder(ChevalleyGroup("C",3,q));
  assert FactoredChevalleyGroupOrder("D",3,q) eq FactoredOrder(ChevalleyGroup("D",3,q));
  assert FactoredChevalleyGroupOrder("2A",3,q) eq FactoredOrder(ChevalleyGroup("2A",3,q));
  assert FactoredChevalleyGroupOrder("2D",3,q) eq FactoredOrder(ChevalleyGroup("2D",3,q));
  z := Factorization(GCD(q+1,3));
  assert FactoredChevalleyGroupOrder("2E",6,q : Version := "Adjoint") eq FactoredOrder(ChevalleyGroup("2E",6,q))/z;
end for;
for q in [2,8] do
  assert FactoredChevalleyGroupOrder("2B",2,q) eq FactoredOrder(ChevalleyGroup("2B",2,q));
  assert FactoredChevalleyGroupOrder("2F",4,q) eq FactoredOrder(ChevalleyGroup("2F",4,q));
end for;
for q in [3,27] do
  assert FactoredChevalleyGroupOrder("2G",2,q) eq FactoredOrder(ChevalleyGroup("2G",2,q));
end for;

print "Adjoint order test";
for q in [2,3,4,5,7,9] do
  print q;
  assert ChevalleyGroupOrder("A",3,q : Version := "Adjoint") eq Order(PSL(4,q));
  assert ChevalleyGroupOrder("B",3,q : Version := "Adjoint") eq Order(POmega(7,q));
  assert ChevalleyGroupOrder("C",3,q : Version := "Adjoint") eq Order(PSp(6,q));
  assert ChevalleyGroupOrder("D",3,q : Version := "Adjoint") eq Order(POmegaPlus(6,q));
  assert ChevalleyGroupOrder("2A",3,q : Version := "Adjoint") eq Order(PSU(4,q));
  assert ChevalleyGroupOrder("2D",3,q : Version := "Adjoint") eq Order(POmegaMinus(6,q));
  assert ChevalleyGroupOrder("G",2,q : Version := "Adjoint") eq Order(G2(q));
  z := GCD(q+1,3);
  assert ChevalleyGroupOrder("2E",6,q : Version := "Adjoint") eq Order(ChevalleyGroup("2E",6,q)) div z;
end for;
for q in [2,8] do
  assert ChevalleyGroupOrder("2B",2,q : Version := "Adjoint") eq Order(SuzukiGroup(q));
end for;


print "Chevalley order test (1)";
for q in [2,3,4,5,7,9] do
  print q;
  assert ChevalleyGroupOrder("A",3,q) eq Order(SL(4,q));
  assert ChevalleyGroupOrder("B",3,q) eq Order(Omega(7,q));
  assert ChevalleyGroupOrder("C",3,q) eq Order(Sp(6,q));
  assert ChevalleyGroupOrder("D",3,q) eq Order(OmegaPlus(6,q));
  assert ChevalleyGroupOrder("2A",3,q) eq Order(SU(4,q));
  assert ChevalleyGroupOrder("2D",3,q) eq Order(OmegaMinus(6,q));
  assert ChevalleyGroupOrder("G",2,q) eq Order(G2(q));
end for;
for q in [2,8] do
  assert ChevalleyGroupOrder("2B",2,q) eq Order(SuzukiGroup(q));
end for;
for q in [27] do
  assert ChevalleyGroupOrder("2G",2,q) eq Order(ReeGroup(q));
end for;


print "Chevalley order test (HB)";
for q in [2,3,4,5,7,9] do
  print q;
  assert HBChevalleyGroupOrder("A",3,q) eq ChevalleyGroupOrder("A",3,q);
  assert HBChevalleyGroupOrder("B",3,q) eq ChevalleyGroupOrder("B",3,q);
  assert HBChevalleyGroupOrder("C",3,q) eq ChevalleyGroupOrder("C",3,q);
  assert HBChevalleyGroupOrder("D",3,q) eq ChevalleyGroupOrder("D",3,q);
  assert HBChevalleyGroupOrder("2A",3,q^2) eq ChevalleyGroupOrder("2A",3,q);
  assert HBChevalleyGroupOrder("2D",3,q) eq ChevalleyGroupOrder("2D",3,q);
  assert HBChevalleyGroupOrder("E",6,q) eq ChevalleyGroupOrder("E",6,q);
  assert HBChevalleyGroupOrder("E",7,q) eq ChevalleyGroupOrder("E",7,q);
  assert HBChevalleyGroupOrder("E",8,q) eq ChevalleyGroupOrder("E",8,q);
  assert HBChevalleyGroupOrder("F",4,q) eq ChevalleyGroupOrder("F",4,q);
  assert HBChevalleyGroupOrder("G",2,q) eq ChevalleyGroupOrder("G",2,q);
end for;
for q in [2,8] do
  assert HBChevalleyGroupOrder("2B",2,q) eq ChevalleyGroupOrder("2B",2,q);
  assert HBChevalleyGroupOrder("2F",4,q) eq ChevalleyGroupOrder("2F",4,q);
end for;
for q in [3,27] do
  assert HBChevalleyGroupOrder("2G",2,q) eq ChevalleyGroupOrder("2G",2,q);
end for;

print "Chevalley order test (Field parameter)";
for q in [2,3,4,5,7,9] do
  print q;
  F := GF(q);
  assert ChevalleyGroupOrder("A",3,q) eq ChevalleyGroupOrder("A",3,F);
  assert ChevalleyGroupOrder("B",3,q) eq ChevalleyGroupOrder("B",3,F);
  assert ChevalleyGroupOrder("C",3,q) eq ChevalleyGroupOrder("C",3,F);
  assert ChevalleyGroupOrder("D",3,q) eq ChevalleyGroupOrder("D",3,F);
  assert ChevalleyGroupOrder("2A",3,q) eq ChevalleyGroupOrder("2A",3,GF(q^2));
  assert ChevalleyGroupOrder("2D",3,q) eq ChevalleyGroupOrder("2D",3,q);
  assert ChevalleyGroupOrder("G",2,q) eq ChevalleyGroupOrder("G",2,q);
  z := GCD(q+1,3);
  assert ChevalleyGroupOrder("2E",6, GF(q^2) : Version := "Adjoint") eq Order(ChevalleyGroup("2E",6,q)) div z;
end for;
for q in [2,8] do
  print q;
  assert ChevalleyGroupOrder("2B",2,q) eq ChevalleyGroupOrder("2B",2,GF(q));
end for;
for q in [27] do
  print q;
  assert ChevalleyGroupOrder("2G",2,q) eq ChevalleyGroupOrder("2G",2,GF(q));
end for;

print "Classical group orders";
for q in [2,3,4,5,7,9] do
  print q;
  F := GF(q);
  assert ClassicalGroupOrder("linear",4,F) eq Order(SL(4,q));
  assert ClassicalGroupOrder("orthogonalcircle",7,F) eq Order(Omega(7,q));
  assert ClassicalGroupOrder("symplectic",6,F) eq Order(Sp(6,q));
  assert ClassicalGroupOrder("orthogonalplus",6,F) eq Order(OmegaPlus(6,q));
  assert ClassicalGroupOrder("unitary",4,GF(q^2)) eq Order(SU(4,q));
  assert ClassicalGroupOrder("orthogonalminus",6,F) eq Order(OmegaMinus(6,q));
end for;



