#(C) Pablo Ascariz, 2005-2006

#####################################################################
#####################################################################
InstallGlobalFunction(LowerCentralSeriesLieAlgebra,
function(G)

local LCSeries,Lgth,i,AbInvariants,j,aux,QuotLCS,Dim,DimLieAlgebra,Generat,n,ITPair,Bracket,SCTabl,L,NatHom,Homs;

if not IsPcpGroup(G) then 
Print("The group must be a pcp group.");
return fail; fi;

########################################################################
NatHom:=function(i)

local NH;

if IsPolycyclicGroup(G) then
	NH:=NaturalHomomorphism(LCSeries[i],LCSeries[i+1]);
else
	NH:=NaturalHomomorphismByNormalSubgroupNC(LCSeries[i],LCSeries[i+1]);
fi;

return NH;

end;
########################################################################

LCSeries:=LowerCentralSeries(G);
Lgth:=Length(LCSeries);
Dim:=[];
Generat:=[];
Homs:=List([1..Lgth-1],i->NatHom(i));
QuotLCS:=List([1..Lgth-1],i->Range(Homs[i]));
aux:=AbelianInvariants(QuotLCS[1])[1];

for i in [1..Lgth-1] do
	AbInvariants:=AbelianInvariants(QuotLCS[i]);
	Dim[i]:=Length(AbInvariants);
	for j in [1..Length(AbInvariants)] do;
		if not AbInvariants[j]=aux then
			return "The abelian invariants are not all the same";
		fi;
	od;
	Generat[i]:=GeneratorsOfGroup(QuotLCS[i]);
	if not Length(Generat[i])=Dim[i] then
		return "Error finding generators of abelian group";
	fi;
od;

DimLieAlgebra:=Sum([1..Lgth-1],i->Dim[i]);

########################################################################
ITPair:=function(n)

local s,suma,Term,BasisEl;

if n>DimLieAlgebra then
	return [Lgth,1];
fi;

suma:=0;

for s in [1..Lgth-1] do
	suma:=suma+Dim[s];
	if n<=suma then
		Term:=s;
		break;
	fi;
od;

suma:=suma-Dim[Term];
for s in [1..Dim[Term]] do
	if n=suma+s then
		BasisEl:=s;
		break;
	fi;
od;

return [Term,BasisEl];

end;
#######################################################################

#######################################################################
SCTabl:=function(i,j)

local x,y,Bracket,Commut,k,aux,F,Homomor,a,b;

Bracket:=[];
for k in [1..2*DimLieAlgebra] do
	if IsOddInt(k)=true then
		Bracket[k]:=0;
	else
		Bracket[k]:=1;
	fi;
od;
if ITPair(i)[1]+ITPair(j)[1]>Lgth-1 then
	return Bracket;
fi;
if ITPair(i+j)[1]>Lgth-1 then
	return Bracket;
fi;
aux:=Sum([1..ITPair(i)[1]+ITPair(j)[1]-1],k->Dim[k]);
x:=ITPair(i);
y:=ITPair(j);
a:=PreImagesRepresentative(Homs[x[1]],Generat[x[1]][x[2]]);
b:=PreImagesRepresentative(Homs[y[1]],Generat[y[1]][y[2]]);

Commut:=a*b*Inverse(a)*Inverse(b);
Commut:=Image(Homs[ITPair(i)[1]+ITPair(j)[1]],Commut);
F:=FreeGroup(Length(Generat[ITPair(i)[1]+ITPair(j)[1]]));
Homomor:=GroupHomomorphismByImagesNC(F,QuotLCS[ITPair(i)[1]+ITPair(j)[1]],GeneratorsOfGroup(F),Generat[ITPair(i)[1]+ITPair(j)[1]]);
Commut:=PreImagesRepresentative(Homomor,Commut);
Commut:=LetterRepAssocWord(Commut);

for k in [1..Length(Commut)] do
	Bracket[2*(aux+AbsInt(Commut[k]))-1]:=Bracket[2*(aux+AbsInt(Commut[k]))-1]+SignInt(Commut[k]);
	Bracket[2*(aux+AbsInt(Commut[k]))]:=aux+AbsInt(Commut[k]);
od;

return Bracket;

end;
#####################################################################

L:=EmptySCTable(DimLieAlgebra,0,"antisymmetric");
for i in [1..DimLieAlgebra] do
for j in [i..DimLieAlgebra] do
	SetEntrySCTable(L,i,j,SCTabl(i,j));
od;od;

if aux=0 then
	L:=LieAlgebraByStructureConstants(Integers,L);
else
	L:=LieAlgebraByStructureConstants(GF(aux),L);
fi;

return L;

end);
#####################################################################
#####################################################################
