/**************************************************************************** ** ** This file is part of GAP, a system for computational discrete algebra. ** ** Copyright of GAP belongs to its developers, whose names are too numerous ** to list here. Please refer to the COPYRIGHT file for details. ** ** SPDX-License-Identifier: GPL-2.0-or-later ** ** Objects Collected From The Left. ** This file contains a collector from the left for polycyclic ** presentations. ** ** This code (in particular the function "CollectPolycyc") is used exclusively by ** the polycyclic package. So in an ideal world, we'd turn it into a kernel ** extensions that is shipped with polycyclic. However, doing so could lead to a ** significant number of people not being able to use polycyclic (as they would ** not know how to compile a kernel extension). And polycyclic is a very central ** package upon which tons of other packages depend... so for now, we leave this ** code here.
*/
Obj wst = CFTLState()->WORD_STACK;
Obj west = CFTLState()->WORD_EXPONENT_STACK;
Obj sst = CFTLState()->SYLLABLE_STACK;
Obj est = CFTLState()->EXPONENT_STACK;
Obj conj=0, iconj=0; /*QQ initialize to please compiler */
Int st;
Int g, syl, h, hh;
Obj e, ee, ge, mge, we, s, t;
Obj w, x = (Obj)0, y = (Obj)0;
if( LEN_PLIST(word) == 0 ) return (Obj)0;
if( LEN_PLIST(list) < ngens ) {
ErrorQuit("vector too short", 0, 0);
} if( LEN_PLIST(word) % 2 != 0 ) {
ErrorQuit("Length of word odd", 0, 0);
}
st = 0;
PUSH_STACK( word, INTOBJ_INT(1) );
while( st > 0 ) {
w = ELM_PLIST( wst, st );
syl = INT_INTOBJ( ELM_PLIST( sst, st ) );
g = INT_INTOBJ( ELM_PLIST( w, syl ) );
if( st > 1 && syl==1 && g == GET_COMMUTE(g) ) { // Collect word^exponent in one go.
e = ELM_PLIST( west, st );
// Add in.
AddIn( list, w, e );
// Reduce. for( h = g; h <= ngens; h++ ) {
s = ELM_PLIST( list, h ); if( IS_INT_ZERO( s ) ) continue;
y = (Obj)0; if( (e = GET_EXPONENT( h )) != (Obj)0 ) { if( !LtInt( s, e ) ) {
t = ModInt( s, e );
SET_ELM_PLIST( list, h, t ); CHANGED_BAG( list ); if( (y = GET_POWER( h )) ) e = QuoInt( s, e );
} elseif( IS_NEG_INT( s ) ) {
t = ModInt( s, e );
SET_ELM_PLIST( list, h, t ); CHANGED_BAG( list );
if( (y = GET_IPOWER( h )) ) {
e = QuoInt( s, e ); if( !IS_INT_ZERO( t ) ) e = DecInt( e );
e = AInvInt(e);
}
}
} if( y != (Obj)0 ) AddIn( list, y, e );
}
st--;
} else { if( g == GET_COMMUTE( g ) ) {
s = ELM_PLIST( list, g );
t = ELM_PLIST( est, st );
C_SUM_FIA( ge, s, t );
SET_ELM_PLIST( est, st, INTOBJ_INT(0) );
} else { // Assume that the top of the exponent stack is non-zero.
e = ELM_PLIST( est, st );
if( IS_POS_INT( e ) ) {
e = DecInt( e );
SET_ELM_PLIST( est, st, e ); CHANGED_BAG( est );
conj = CONST_ADDR_OBJ(pcp)[PC_CONJUGATES];
iconj = CONST_ADDR_OBJ(pcp)[PC_INVERSECONJUGATES];
ge = IncInt( ELM_PLIST( list, g ) );
} else {
C_SUM_FIA( ee, e, INTOBJ_INT(1) ); e = ee;
SET_ELM_PLIST( est, st, e ); CHANGED_BAG( est );
conj = CONST_ADDR_OBJ(pcp)[PC_CONJUGATESINVERSE];
iconj = CONST_ADDR_OBJ(pcp)[PC_INVERSECONJUGATESINVERSE];
ge = DecInt( ELM_PLIST( list, g ) );
}
}
SET_ELM_PLIST( list, g, ge ); CHANGED_BAG( list );
/* Reduce the exponent. We delay putting the power onto the stack until all the conjugates are on the stack. The power is
stored in y, its exponent in ge. */
y = (Obj)0; if( (e = GET_EXPONENT( g )) ) { if( !LtInt( ge, e ) ) {
mge = ModInt( ge, e );
SET_ELM_PLIST( list, g, mge ); CHANGED_BAG( list );
if( (y = GET_POWER( g )) ) ge = QuoInt( ge, e );
} elseif( IS_NEG_INT( ge ) ) {
mge = ModInt( ge, e );
SET_ELM_PLIST( list, g, mge ); CHANGED_BAG( list );
if( (y = GET_IPOWER( g )) ) {
ge = QuoInt( ge, e ); if( !IS_INT_ZERO( mge ) )
ge = DecInt( ge );
ge = AInvInt(ge);
}
}
}
hh = h = GET_COMMUTE( g );
// Find the place where we start to collect. for( ; h > g; h-- ) {
e = ELM_PLIST( list, h ); if( !IS_INT_ZERO(e) ) {
if( IS_POS_INT( e ) ) { if( GET_CONJ( h, g ) ) break;
} else { if( GET_ICONJ( h, g ) ) break;
}
}
}
// Put those onto the stack, if necessary. if( h > g || y != (Obj)0 ) for( ; hh > h; hh-- ) {
e = ELM_PLIST( list, hh ); if( !IS_INT_ZERO(e) ) {
SET_ELM_PLIST( list, hh, INTOBJ_INT(0) );
if( IS_POS_INT( e ) ) {
x = ELM_PLIST( gens, hh );
} else {
x = ELM_PLIST( igens, hh );
e = FastAInvInt(e);
}
PUSH_STACK( x, e );
}
}
for( ; h > g; h-- ) {
e = ELM_PLIST( list, h ); if( !IS_INT_ZERO(e) ) {
SET_ELM_PLIST( list, h, INTOBJ_INT(0) );
x = IS_POS_INT( e ) ? GET_CONJ( h, g ) : GET_ICONJ( h, g );
if( x == (Obj)0 ) {
x = IS_POS_INT( e ) ? ELM_PLIST( gens, h ) : ELM_PLIST( igens, h );
} if( IS_NEG_INT( e ) ) {
e = FastAInvInt(e);
}
PUSH_STACK( x, e );
}
}
if( y != (Obj)0 ) PUSH_STACK( y, ge );
}
while( st > 0 && IS_INT_ZERO( ELM_PLIST( est, st ) ) ) {
w = ELM_PLIST( wst, st );
syl = INT_INTOBJ( ELM_PLIST( sst, st ) ) + 2; if( syl > LEN_PLIST( w ) ) {
we = DecInt( ELM_PLIST( west, st ) ); if( we == INTOBJ_INT(0) ) { st--; } else {
SET_ELM_PLIST( west, st, we );
SET_ELM_PLIST( sst, st, INTOBJ_INT(1) );
SET_ELM_PLIST( est, st, ELM_PLIST( w, 2 ) );
CHANGED_BAG( west ); CHANGED_BAG( est );
}
} else {
SET_ELM_PLIST( sst, st, INTOBJ_INT(syl) );
SET_ELM_PLIST( est, st, ELM_PLIST( w, syl+1 ));
CHANGED_BAG( est );
}
}
}
// signal to polycyclic that 'CollectPolycyclic' does not use resp. // require stacks inside the collector objects
AssConstantGVar(GVarName("NO_STACKS_INSIDE_COLLECTORS"), True);
// init filters and functions
InitGVarFuncsFromTable( GVarFuncs );
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.