|
###############################################################################
##
#F Collect.gi The SymbCompCC package Dörte Feichtenschlager
##
###############################################################################
##
## What do the element of p-power-poly-pcp-groups look like?
## -------------------------------------
##
## The generators of the groups are
##
## g_1 , ... g_n ,
## t_1 , ... , t_d,
## x_1,1 , ... , x_n+d,n+d
##
## with the following relations:
##
## g_i^p = r_i,i(g_k^e_k , t_l^m_l(n) ) x_i,i for 1 <= i <= n , i < k <= n and
## some non-negative integers e_k,
## p-power-poly's m_l(n)
## g_i^g_j = r_i,j( g_k^e_k , t_l^m_l(n) ) x_i,j for 1 <= i <= n , 1 <= j < i,
## i < k <= n and some
## non-negative integers
## e_k, p-power-poly's m_l(n)
## t_i^(exp( i , n )) = r_n+i,n+i( t_l^m_l(n) ) x_n+i,n+i for 1 <= i <= d,
## i < l <= d and some
## non-negative
## p-power-poly's m_l(n)
## t_i^t_j = t_i x_n+i,n+j for 1 <= i <= d, 1 <= j < i
## t_i^g_j = r_n+i,j( t_l^m_l(n) ) x_n+i,j for 1 <= i <= d, 1 <= j <= n,
## 1 <= l <= d, some non-negative
## p-power-poly m_l(n)
## x_k,l^g_i = x_k,l for 1 <= i <= n and 1 <= k , l <= n+d
## x_k,l^t_i = x_k,l for 1 <= i <= d and 1 <= k , l <= n+d
## x_i,j^x_k,l = x_i,j for 1 <= i , j , k , l <= n+d
## => the x_i,j are central and there exist x_i,j for 1 <= i <= n+d and
## 1 <= j < i
##
## Define X := < x_i,j | 1 <= i <= n+d , 1 <= j < i >
## T := < t_j | 1 <= j <= d >
## G := < g_i | 1 <= i <= n >
##
## Then T/X abelian.
##
## We have elements of the (collected) form h = gtx where g \in G, t \in T and
## x \in X.
##
## How are the elements stored?
## ----------------------------
##
## Let h = gtx with g \in G, t \in T and x \in X. Then store h as follows:
##
## h := rec( prime, word, tails , div ) with
##
## h.word := gt with g = g_1^e_1 , ... , g_n^e_n where e_1 , ... , e_n \in
## {0 , ... , p-1} and t = t_1^f_1(x) ... t_d^f_d(x)
## where f_1(x) , ... , f_d(x) p-power-polys. Thus store
## h.word := [ e_1 , ... , e_n , f_1(x) , ... , f_d(x) ];
##
## h.tails := x with x = x_1,1^k_1,1(x) ... x_n+d,n+d^k_n+d,n+d(x) where
## k_1,1(x) , ... , k_n+d,n+d(x) p-power-poly elements. Thus store
## h.tails := [ k_1,1(x) , k_1,2(x) , ... , k_n+d,n+d(x) ];
## h.div := [a_1,1, ..., a_n+d,n+d]; where it is stored by which
## integer the corresponding exponent of x has to be divided (normally 1, but
## sometimes a power of 2).
##
## store relations
## r_i_j is a list of lists where r_i_j[i][j] gives the relations described
## above.
## then r_i_j[i][j] consists of the list of lists [[k,l]_k,l] where k gives
## the generator and l the exponent (l is positive).
## Keep in mind that to each realtion r_i_j[i][j] there belongs the
## tail x_i,j.
###############################################################################
##
## GetFullWord( list , p , n , d )
##
## [ IsList, IsPosInt, IsPosInt, IsPosInt ],
##
## Comment: technical function (change [..,[i,j],..] in [..,j,..] (j in
## position i))
##
InstallMethod( GetFullWord,
"generate full word out of parts",
[ IsList, IsPosInt, IsPosInt, IsPosInt ],
function( list , p , n , d )
local res , Zero0 , i;
if not IsPrimeInt(p) then
Error("Wrong input, the second parameter has to be a prime.");
fi;
res := [];
Zero0 := Int2PPowerPoly( p , 0 );
for i in [1..n] do
res[i] := 0;
od;
for i in [1..d] do
res[n+i] := Zero0;
od;
for i in [1..Length( list )] do
res[list[i][1]] := list[i][2];
od;
return res;
end);
###############################################################################
##
## PosTails( i , j )
##
## [ IsPosInt, IsPosInt ],
##
## Comment: technical function (position of x_i,j in list)
##
InstallMethod( PosTails,
"get position of tail x_i,j",
[ IsPosInt, IsPosInt ],
function( i , j )
local pos;
pos := (i*(i-1)/2) + j;
return pos;
end);
###############################################################################
##
## TailsPos( l, lim )
##
## [ IsPosInt, IsPosInt ],
##
## Comment: technical function (i,j of position l in tails)
##
InstallMethod( TailsPos,
"get i,j of tail-position l",
[ IsPosInt, IsPosInt ],
function( l, lim )
local i,j;
i := lim;
## lim = n+d
while l - (i*(i-1)/2) < 0 do
i := i - 1;
od;
j := l - (i*(i-1)/2);
return [i,j];
end);
###############################################################################
##
## Reduce_x_ij( p, n, d, x_ij_in, pos, expo )
##
## [ IsPosInt, IsPPowerPoly, IsPPowerPoly, IsPosInt ]
##
## Comment: technical function (reduce x)
##
InstallGlobalFunction( Reduce_x_ij,
function( p, n, d, x_ij_in, pos, expo )
local x_ij, list, i, j;
x_ij := StructuralCopy( x_ij_in );
if not IsPrimeInt(p) then
Error("Wrong input, the first parameter has to be a prime.");
fi;
list := TailsPos( pos, n+d );
i := list[1];
j := list[2];
if i > n and j > n and i <> j then
list := PPP_QuotientRemainder( x_ij, expo );
return list[2];
else return x_ij;
fi;
end);
###############################################################################
##
## Add_x_ij( p, n, d, pos, x_i, x_j, div_i, div_j, expo )
##
## [ IsPosInt, IsInt, IsInt, IsPPowerPoly, IsPPowerPoly, IsInt,
## IsInt, IsPPowerPoly ]
##
## Comment: technical function (add tails, paying attention to *.div)
##
InstallGlobalFunction( Add_x_ij,
function( p, n, d, pos, x_i, x_j, div_i, div_j, expo )
local x, div_x, Elm_i, Elm_j, m_i, m_j, min_pos;
if not IsPrimeInt(p) then
Error("Wrong input, the first parameter has to be a prime.");
fi;
## get min_pos, as higher pos-tails have to be reduced
min_pos := PosTails( n, n );
## add and reduce, paying attention to the different possible divs
## both divs are 1, so nothing to do
if (div_i = 1) and (div_j = 1) then
x := PPP_Add( x_i, x_j );
div_x := 1;
x := Reduce_x_ij( p, n, d, x, pos, expo );
elif div_i = 1 then
## only one div is 1, so fractional arithmetic
Elm_i := Int2PPowerPoly( p, div_j );
x := PPP_Add( PPP_Mult(Elm_i, x_i ), x_j );
div_x := div_j;
x := Reduce_x_ij( p, n, d, x, pos, expo );
elif div_j = 1 then
## same as last
Elm_j := Int2PPowerPoly( p, div_i );
x := PPP_Add( x_i, PPP_Mult( Elm_j, x_j ) );
div_x := div_i;
x := Reduce_x_ij( p, n, d, x, pos, expo );
else
## both divs >= 1, so get lcm and use frational arithmetic
div_x := Maximum( div_i, div_j );
m_i := div_x / div_i;
m_j := div_x / div_j;
Elm_i := Int2PPowerPoly( p, m_i );
Elm_j := Int2PPowerPoly( p, m_j );
x := PPP_Add( PPP_Mult( Elm_i, x_i ), PPP_Mult( Elm_j, x_j ) );
x := Reduce_x_ij( p, n, d, x, pos, expo );
fi;
## check if trivial case
if div_x <> 1 then
if PPP_Equal( x, PPP_ZeroNC( x ) ) then
div_x := 1;
fi;
fi;
## check if we can cancel
if div_x <> 1 then
if Length( x[2] ) = 1 then
if IsInt( x[2][1] / div_x ) then
x[2][1] := x[2][1] / div_x;
div_x := 1;
fi;
fi;
fi;
return [ x, div_x ];
end);
###############################################################################
##
## Mult_x_ij( p, n, d, pos, x_i, x_j, div_i, div_j, expo )
##
## [ IsPosInt, IsInt, IsInt, IsPPowerPoly, IsPPowerPoly, IsInt,
## IsInt, IsPPowerPoly ]
##
## Comment: technical function (multiply tails, paying attention to *.div)
##
InstallGlobalFunction( Mult_x_ij,
function( p, n, d, pos, x_i, x_j, div_i, div_j, expo )
local x, div_x;
if not IsPrimeInt( p ) then
Error("Wrong input, the first parameter has to be a prime.");
fi;
## multiply
x := PPP_Mult( x_i, x_j );
div_x := div_i * div_j;
## reduce x
x := Reduce_x_ij( p, n, d, x, pos, expo );
## check if trivial case
if div_x <> 1 then
if PPP_Equal( x, PPP_ZeroNC( x ) ) then
div_x := 1;
fi;
fi;
## check if we can cancel
if div_x <> 1 then
if Length( x[2] ) = 1 then
if IsInt( x[2][1] / div_x ) then
x[2][1] := x[2][1] / div_x;
div_x := 1;
fi;
fi;
fi;
return [ x, div_x ];
end);
###############################################################################
##
## Reduce_g_i( word_in,tails_in,div_in,n,d,p,i,wstack_in,l_in,rel_i_j,expo )
##
## [ IsList, IsList, IsList, IsPosInt, IsPosInt, IsPosInt, IsPosInt, IsList,
## IsInt, IsList, IsPPowerPoly ]
##
## Comment: technical function (reduce g_i)
##
InstallGlobalFunction( Reduce_g_i,
function( word_in,tails_in,div_in,n,d,p,i,wstack_in,l_in,rel_i_j,expo )
local div, word, tails, wstack, l, j, help, l_help, pos, Zero0, One1,
list, k;
if not IsPrimeInt(p) then
Error( "Wrong input, the sixth parameter has to be a prime." );
fi;
word := StructuralCopy( word_in );
tails := StructuralCopy( tails_in );
wstack := StructuralCopy( wstack_in );
div := StructuralCopy( div_in );
l := StructuralCopy( l_in );
Zero0 := Int2PPowerPoly( p, 0 );
One1 := Int2PPowerPoly( p, 1 );
## if exponent of g is greater than p, then we have to reduce g
if word[i] >= p then
## put t's on the stack
for j in [n+d,n+d-1..n+1] do
if not PPP_Equal( word[j], Zero0 ) then
l := l + 1;
wstack[l] := [j , word[j]];
word[j] := Zero0;
fi;
od;
## put the rest of the g's on the stack
for j in [n,n-1..i+1] do
if word[j] <> 0 then
l := l + 1;
wstack[l] := [j , word[j]];
word[j] := 0;
fi;
od;
fi;
## get the relation
help := MakeMutableCopyListPPP( rel_i_j[i][i] );
l_help := Length( help );
## reduce g until exponent is < p
while word[i] >= p do
word[i] := word[i] - p;
pos := PosTails( i ,i );
list := Add_x_ij( p, n, d, pos, tails[pos], One1, div[pos], 1, expo );
tails[pos] := list[1];
div[pos] := list[2];
## put relation on stack
for j in [l_help,l_help-1..1] do
if help[j][1] > n then
if not PPP_Equal( help[j][2], Zero0 ) then
l := l + 1;
wstack[l] := help[j];
fi;
elif help[j][2] <> 0 then
for k in [1..help[j][2]] do
l := l + 1;
wstack[l] := [help[j][1],1];
od;
fi;
od;
od;
return [ word, tails, div, wstack, l ];
end);
###############################################################################
##
## Collect_t_ti( word_in, p, n, d, i, b, tails_in, div_in, rel_i_j, expo )
##
## [ IsList, IsPosInt, IsPosInt, IsPosInt, IsPosInt, IsPPowerPoly,
## IsList, IsList, IsPPowerPoly ]
##
## Comment: technical function (collecting g_1^e_1..g_n^e_n t_1^b1...t_d^bd
## * t_i^b)
##
InstallGlobalFunction( Collect_t_ti,
function( word_in, p, n, d, i, b, tails_in, div_in, rel_i_j, expo )
local j, pos, help, list, m, m_div, word, tails, div;
if not IsPrimeInt(p) then
Error("Wrong input, the second parameter has to be a prime.");
fi;
word := StructuralCopy( word_in );
tails := StructuralCopy( tails_in );
div := StructuralCopy( div_in );
## add the exponents
word[n+i] := PPP_Add( word[n+i], b );
## reduce t_i, careful this is a recursive call, so only if >= expo
if not PPP_Smaller( word[n+i], expo ) then
list := Reduce_t_i( word, tails, div, n, d, p, n+i, rel_i_j, expo );
word := list[1];
tails := list[2];
div := list[3];
fi;
## correct the tails
for j in [i+1,i+2..d] do
pos := PosTails( n+j , n+i );
help := Mult_x_ij( p, n, d, pos, b, word[n+j], 1, 1, expo );
m := help[1];
m_div := help[2];
list := Add_x_ij( p,n,d,pos,tails[pos],m,div[pos],m_div,expo );
tails[pos] := list[1];
div[pos] := list[2];
od;
return [ word, tails, div ];
end);
###############################################################################
##
## Reduce_t_i( word_in, tails_in, div_in, n, d, p, i, rel_i_j, expo )
##
## [ IsList, IsPosInt, IsPosInt, IsPosInt, IsPosInt, IsPPowerPoly,
## IsList, IsList, IsPPowerPoly ]
##
## Comment: technical function (reduce t_i (higher t's can still have too
## large relations))
##
InstallGlobalFunction( Reduce_t_i,
function( word_in, tails_in, div_in, n, d, p, i, rel_i_j, expo )
local pos, list, Zero0, One1, word, tails, div;
if not IsPrimeInt(p) then
Error("Wrong input, the sixth parameter has to be a prime.");
fi;
word := StructuralCopy( word_in );
tails := StructuralCopy( tails_in );
div := StructuralCopy( div_in );
Zero0 := Int2PPowerPoly( p, 0 );
One1 := Int2PPowerPoly( p, 1 );
list := PPP_QuotientRemainder( word[i], expo );
word[i] := StructuralCopy( list[2] );
if not PPP_Equal( list[1], Zero0 ) then
pos := PosTails( i, i );
tails[pos] := PPP_Add( tails[pos], list[1] );
fi;
return [ word, tails, div ];
end);
###############################################################################
##
## Collect_h_x_ij( h_in, i , j , c , p, n, d, expo )
##
## [ IsRecord, IsPosInt, IsPosInt, IsPPowerPoly, IsPosInt, IsPosInt,
## IsPPowerPoly ]
##
## Comment: technical function (collecting h * x_{i,j}^c)
##
InstallGlobalFunction( Collect_h_x_ij,
function( h_in, i , j , c , p, n, d, expo )
local pos, list, h;
if not IsPrimeInt(p) then
Error("Wrong input, the fifth parameter has to be a prime.");
fi;
h := StructuralCopy( h_in );
pos := PosTails( i , j );
## add tails
list := Add_x_ij( p, n, d, pos, h.tails[pos], c, h.div[pos], 1, expo );
h.tails[pos] := list[1];
h.div[pos] := list[2];
return h;
end);
###############################################################################
##
## Collect_h_t_i( h_in , n , d , i , b, p, rel_i_j, expo )
##
## [ IsRecord, IsPosInt, IsPosInt, IsPosInt, IsPPowerPoly, IsPosInt,
## IsList, IsPPowerPoly ]
##
## Comment: technical function (collecting h * t_i^b)
InstallGlobalFunction( Collect_h_t_i,
function( h_in , n , d , i , b, p, rel_i_j, expo )
local h, list, word, tails, div, j;
if not IsPrimeInt(p) then
Error("Wrong input, the sixth parameter has to be a prime.");
fi;
h := StructuralCopy( h_in );
word := h.word;
tails := h.tails;
div := h.div;
## collect the t's
list := Collect_t_ti( word, p, n, d, i-n, b, tails, div, rel_i_j, expo );
word := list[1];
tails := list[2];
div := list[3];
## reduce the t's
for j in [1..d] do
if not PPP_Smaller( word[n+j], expo ) then
list := Reduce_t_i(word, tails, div, n, d, p, n+j, rel_i_j, expo);
word := list[1];
tails := list[2];
div := list[3];
fi;
od;
h.word := word;
h.tails := tails;
h.div := div;
return h;
end);
###############################################################################
##
## Collect_t_y( w_in, n , d , p , y , x_in , div_in, rel_i_j, expo )
##
## [ IsList, IsPosInt, IsPosInt, IsPosInt, IsPPowerPoly, IsList, IsList,
## IsList, IsPPowerPoly ]
##
## Comment: technical function (collecting t^y)
##
InstallGlobalFunction( Collect_t_y,
function( w_in, n , d , p , y , x_in , div_in, rel_i_j, expo )
local w, x, div, i, j, One1, Zero0, pos, elm, test, help, list, help2,
new_y, eval, value, c;
if not IsPrimeInt(p) then
Error("Wrong input, the fourth parameter has to be a prime.");
fi;
w := StructuralCopy( w_in );
x := StructuralCopy( x_in );
div := StructuralCopy( div_in );
One1 := Int2PPowerPoly( p, 1 );
Zero0 := Int2PPowerPoly( p, 0 );
if InfoLevel( InfoCollectingPPowerPoly ) = 1 then
Print("\n Doing t_y: w = " );
if IsInt( w[1] ) then
Print( w[1] );
else PPP_Print( w[1] );
fi;
for i in [2..Length( w )] do
Print( ", " );
if IsInt( w[i] ) then
Print( w[i] );
else PPP_Print( w[i] );
fi;
od;
Print( " y = " );
if IsInt( y ) then
Print( y );
else PPP_Print( y );
fi;
fi;
## test whether y is an integer
test := 0; ## tests whether y is an integer, so if can divide by 2
if Length( y[2] ) = 1 then
## now y is an integer, doesn't depend on m and can divide by 2
test := 1;
help := EvaluatePPowerPoly( y , 1 );
elm := ( help - 1 ) * help / 2;
elm := Int2PPowerPoly( p, elm );
fi;
if test = 0 then
if p = 2 then
test := 1;
help := StructuralCopy( PPP_Subtract( y, One1 ) );
## test if elm is even
eval := 1/2;;
value := 1;;
while not IsInt( eval ) do
eval := EvaluatePPowerPoly( help, value );
value := value + 1;;
od;
eval := EvaluatePPowerPoly( help, value+1 );
if IsEvenInt( eval ) then
## divide help by 2
new_y := y;
c := ShallowCopy( help[2] );
for i in [1..Length( c )] do
c[i] := c[i] / 2;
od;
help := PPP_Check( [ p, c ] );
else ## divide y by 2;
c := ShallowCopy( y[2] );
for i in [1..Length( c )] do
c[i] := c[i] / 2;
od;
new_y := PPP_Check( [p, c] );
fi;
elm := StructuralCopy( PPP_Mult( help, new_y ) );
else
elm := StructuralCopy( PPP_Mult( PPP_Subtract( y, One1 ), y ) );
fi;
fi;
## collect the tails
for i in [1..d-1] do
for j in [i+1,i+2..d]do
pos := PosTails( n+j , n+i );
## if one is 0, everything is 0 and we don't have to divide by 2
if PPP_Equal( w[n+i], Zero0 ) or PPP_Equal( w[n+j], Zero0 ) then
test := 1;
fi;
## collect the tails
if test = 0 then
help2:=Mult_x_ij(p,n,d,pos,w[n+i],PPP_Mult( w[n+j], elm ),div[n+i],div[n+j]*2,expo);
else ## we have already divides by 2
help2:=Mult_x_ij(p,n,d,pos,w[n+i],PPP_Mult( w[n+j], elm ),div[n+i],div[n+j],expo);
fi;
list := Add_x_ij(p,n,d,pos,x[pos],help2[1],div[pos],help2[2],expo);
x[pos] := list[1];
div[pos] := list[2];
od;
od;
## collect the t's
for i in [1..d] do
w[n+i] := PPP_Mult( w[n+i], y );
list := Reduce_t_i( w, x, div, n, d, p, n+i, rel_i_j, expo );
w := list[1];
x := list[2];
div := list[3];
od;
return [ w , x , div ];
end);
###############################################################################
##
## Collect_h_g_i( h_in , n , d , i , rel_i_j , expo )
##
## [ IsRecord, IsPosInt, IsPosInt, IsPosInt, IsList, IsPPowerPoly ]
##
## Comment: technical function (collecting h*g_i)
##
InstallGlobalFunction( Collect_h_g_i,
function( h_in , n , d , i , rel_i_j , expo )
local word, tails, wstack, l, u, e, res, j, help, k, m, list, s, l_r, p,
div, Zero0, One1, pos, exp_pexp, wstack_2, h;
h := StructuralCopy( h_in );
p := h.prime;
word := h.word;
tails := h.tails;
div := h.div;
wstack := [[i,1]];
Zero0 := Int2PPowerPoly( p, 0 );
One1 := Int2PPowerPoly( p, 1 );
## run until stacks are empty
l := 1;
while l > 0 do
## for checking!!!!
if InfoLevel( InfoCollectingPPowerPoly ) = 1 then
wstack_2 := [];
for j in [1..l] do
wstack_2[j] := wstack[j];
od;
Print( "\nword = " );
PPP_PrintRow( word );
Print( " tails = " );
PPP_PrintRow( tails );
Print( " wstack = [ [ ", wstack_2[1][1], ", " );
if IsInt( wstack_2[1][2] ) then
Print( wstack_2[1][2], " ]" );
else PPP_Print( wstack_2[1][2] );
Print( " ]" );
fi;
for j in [2..Length( wstack_2 )] do
Print( ", [ [ " );
if IsInt( wstack_2[j][2] ) then
Print( wstack_2[j][2], " ]" );
else PPP_Print( wstack_2[j][2] );
Print( " ]" );
fi;
od;
Print( " ]" );
Print( "\n div = ", div, "\n" );
fi;
## take a generator and its exponent
u := wstack[l][1];
e := wstack[l][2];
if InfoLevel( InfoCollectingPPowerPoly ) = 1 then
Print("\n u = ", u, " e = " );
if IsInt( e ) then
Print( e );
else PPP_Print( e );
Print( "\n" );
fi;
fi;
## correct stack length
## if u <= n and e > 1 than keep [u,e-1] on stack, to do later
## note: u <= n and e>1 should not occur
if u > n or e = 1 then
l := l - 1;
else wstack[l][2] := wstack[l][2] - 1;
fi;
j := n+d;
## if we take a g from the stack
if u <= n then
while u < j do
## conjugate through higher, first t's
if j > n then
if not PPP_Equal( word[j], Zero0 ) then
## put rest on stack
for k in [n+d,n+d-1..j+1] do
if not PPP_Equal( word[k], Zero0 ) then
l := l + 1;
wstack[l] := [k, word[k]];
word[k] := Zero0;
fi;
od;
## do the tails
pos := PosTails( j , u );
list:=Add_x_ij(p,n,d,pos,tails[pos],word[j],div[pos],1,expo);
tails[pos] := list[1];
div[pos] := list[2];
## get the relation
help := MakeMutableCopyListPPP( rel_i_j[j][u] );
## help := StructuralCopy( rel_i_j[j][u] );
help := GetFullWord( help , p, n, d );
## possibly power relation
if not PPP_Equal( word[j], One1 ) then
list:=Collect_t_y(help,n,d,p,word[j],tails,div,rel_i_j,expo);
help := list[1];
tails := list[2];
div := list[3];
fi;
## put relation on stack, first t-part
for k in [d,d-1..1] do
if not PPP_Equal( help[n+k], Zero0 ) then
l := l + 1;
wstack[l] := [n+k,help[n+k]];
fi;
od;
## put relation on stack, now g-part
for k in [n,n-1..1] do
if help[k] <> 0 then
for i in [1..help[k]] do
l := l + 1;
wstack[l] := [k,1];
od;
fi;
od;
word[j] := Zero0;
fi;
## conjugacte through higher g's
else pos := PosTails( j , u );
if word[j] <> 0 then
## put t's on stack
for k in [n+d,n+d-1..n+1] do
if not PPP_Equal( word[k], Zero0 ) then
l := l + 1;
wstack[l] := [k, word[k]];
word[k] := Zero0;
fi;
od;
## put greater g's on stack
for k in [n,n-1..j+1] do
if word[k] <> 0 then
l := l + 1;
wstack[l] := [k, word[k]];
word[k] := 0;
fi;
od;
## correct the tails
exp_pexp := Int2PPowerPoly( p, word[j] );
list:=Add_x_ij(p,n,d,pos,tails[pos],exp_pexp,div[pos],1,expo);
tails[pos] := list[1];
div[pos] := list[2];
## get relation
help := MakeMutableCopyListPPP( rel_i_j[j][u] );
## help := StructuralCopy( rel_i_j[j][u] );
l_r := Length( help );
## put relations word[j]-times on stack
for k in [1..word[j]] do
for m in [l_r,l_r-1..1] do
if help[m][1] > n then
l := l + 1;
wstack[l] := [ help[m][1] , help[m][2] ];
else
if help[m][2] > 0 then
for s in [1..help[m][2]] do
l := l + 1;
wstack[l] := [ help[m][1] , 1 ];
od;
fi;
fi;
od;
od;
word[j] := 0;
fi;
fi;
j := j - 1;
od;
word[u] := word[u] + e;
list := Reduce_g_i(word,tails,div,n,d,p,u,wstack,l,rel_i_j,expo);
word := list[1];
tails := list[2];
div := list[3];
wstack := list[4];
l := list[5];
## if we take a t from the stack, collect
else
h.word := word;
h.tails := tails;
h.div := div;
res := Collect_h_t_i( h , n , d , u , e, p, rel_i_j, expo );
word := res.word;
tails := res.tails;
div := res.div;
fi;
od;
## reduce the t's
for i in [1..d] do
if not PPP_Smaller( word[n+i], expo ) then
list := Reduce_t_i(word, tails, div, n, d, p, n+i, rel_i_j, expo);
word := list[1];
tails := list[2];
div := list[3];
fi;
od;
h.word := word;
h.tails := tails;
h.div := div;
return h;
end);
#E Collect.gi . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here
[ Dauer der Verarbeitung: 0.31 Sekunden
(vorverarbeitet)
]
|