############################################################################# ## #W Intsect.gi FGA package Christian Sievers ## ## Installations for the computation of intersections of free groups ## #Y 2003 - 2012 ##
############################################################################# ## #F FGA_StateTable( <table>, <i>, <j> ) ##
InstallGlobalFunction( FGA_StateTable, function( t, i, j ) if not IsBound( t[i] ) then
t[i] := []; fi; if not IsBound( t[i][j] ) then
t[i][j] := FGA_newstate(); fi;
return t[i][j]; end );
############################################################################# ## #M Intersection2( <G1>, <G2> ) ##
InstallMethod( Intersection2, "for subgroups of free groups",
IsIdenticalObj,
[ CanComputeWithInverseAutomaton, CanComputeWithInverseAutomaton ], function( G1, G2 )
local A, t, sl1, sl2, i, nr1, nr2, Q, pair, g, q, q1, q2, bpd, bpdi;
# let the gap lib handle this case: if IsSubgroupOfWholeGroupByQuotientRep( G1 ) and
IsSubgroupOfWholeGroupByQuotientRep( G2 ) then
TryNextMethod(); fi;
t := [];
i := FGA_StateTable( t, 1, 1 );
sl1 := FGA_States( FreeGroupAutomaton( G1 ) );
sl2 := FGA_States( FreeGroupAutomaton( G2 ) );
Q := [ [1,1] ]; for pair in Q do
q1 := sl1[ pair[1] ];
q2 := sl2[ pair[2] ];
q := FGA_StateTable( t, pair[1], pair[2] ); for g in Difference(
Intersection( BoundPositions( q1.delta ),
BoundPositions( q2.delta ) ),
BoundPositions( q.delta ) ) do
nr1 := q1.delta[g].nr;
nr2 := q2.delta[g].nr;
FGA_connectpos( q, FGA_StateTable( t, nr1, nr2 ), g );
Add( Q, [ nr1, nr2 ] );
od;
for g in Difference(
Intersection( BoundPositions( q1.deltainv ),
BoundPositions( q2.deltainv ) ),
BoundPositions( q.deltainv ) ) do
nr1 := q1.deltainv[g].nr;
nr2 := q2.deltainv[g].nr;
FGA_connectpos( FGA_StateTable( t, nr1, nr2 ), q, g );
Add( Q, [ nr1, nr2 ] );
od;
bpd := BoundPositions( q.delta );
bpdi := BoundPositions( q.deltainv ); while Size( bpd ) + Size( bpdi ) = 1 and
IsNotIdenticalObj( q, i ) do if Size( bpd ) = 1then
g := bpd[ 1 ];
q := q.delta[ g ];
Unbind( q.deltainv[ g ] ); else
g := bpdi[ 1 ];
q := q.deltainv[ g ];
Unbind( q.delta[ g ] ); fi;
bpd := BoundPositions( q.delta );
bpdi := BoundPositions( q.deltainv );
od;
od;
A := Objectify( NewType( FamilyObj( G1 ), IsSimpleInvAutomatonRep ),
rec( initial:=i, terminal:=i,
group := TrivialSubgroup( G1 ) ) );
return AsGroup( A ); end );
############################################################################# ## #F FGA_TrySetRepTable( <t>, <i>, <j>, <r>, <g> ) ##
InstallGlobalFunction( FGA_TrySetRepTable, function( t, i, j, r, g )
local rx; if not IsBound( t[i] ) then
t[i] := []; fi; if not IsBound( t[i][j] ) then
rx := ShallowCopy( r );
Add( rx, g );
t[i][j] := rx;
return rx; else
return fail; fi; end );
############################################################################# ## #F FGA_GetNr ( <state>, <statelist> ) ##
InstallGlobalFunction( FGA_GetNr, function( q, sl ) if not IsBound( q.nr ) then
Add( sl, q );
q.nr := Size( sl ); elif not IsBound( sl[ q.nr ] ) then
sl[ q.nr ] := q; fi;
return q.nr; end );
############################################################################# ## #F FGA_FindRepInIntersection ( <A1>, <t1>, <A2>, <t2> ) ##
InstallGlobalFunction( FGA_FindRepInIntersection, function( A1, t1, A2, t2 )
local tab, sl1, sl2, Q, pair, g, q1, nr1, q2, nr2, r, rx;
sl1 := [];
sl2 := [];
q1 := A1!.initial;
q2 := A2!.initial; if IsIdenticalObj( q1, t1) and
IsIdenticalObj( q2, t2) then
return []; fi;
nr1 := FGA_GetNr( q1, sl1 );
nr2 := FGA_GetNr( q2, sl2 );
tab := [];
tab [ nr1 ] := [];
tab [ nr1 ][ nr2 ] := []; # empty word at initial state
Q := [ [ nr1, nr2 ] ]; for pair in Q do
q1 := sl1[ pair[1] ];
q2 := sl2[ pair[2] ];
r := tab [ pair[1] ] [ pair[2] ]; for g in Intersection( BoundPositions( q1.delta ),
BoundPositions( q2.delta ) ) do
nr1 := FGA_GetNr(q1.delta[g], sl1);
nr2 := FGA_GetNr(q2.delta[g], sl2);
rx := FGA_TrySetRepTable( tab, nr1, nr2, r, g ); if rx <> fail then if IsIdenticalObj(sl1[ nr1 ], t1) and
IsIdenticalObj(sl2[ nr2 ], t2) then
return rx; fi;
Add( Q, [ nr1, nr2 ] ); fi;
od;
for g in Intersection( BoundPositions( q1.deltainv ),
BoundPositions( q2.deltainv ) ) do
nr1 := FGA_GetNr(q1.deltainv[g], sl1);
nr2 := FGA_GetNr(q2.deltainv[g], sl2);
rx := FGA_TrySetRepTable( tab, nr1, nr2, r, -g ); if rx <> fail then if IsIdenticalObj(sl1[ nr1 ], t1) and
IsIdenticalObj(sl2[ nr2 ], t2) then
return rx; fi;
Add( Q, [ nr1, nr2 ] ); fi;
od;
od;
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 und die Messung sind noch experimentell.