[GAP Forum] Re: reply to GAP forum question
Thomas Breuer
thomas.breuer at math.rwth-aachen.de
Fri Sep 3 17:42:31 BST 2004
Dear GAP Forum,
Laurent Bartholdi had asked for a special `Enumerator' method
for free magmas.
The GAP code below provides this.
All the best,
Thomas
#############################################################################
##
#M Enumerator( <M> ) . . . . . . . . . . . . . . enumerator for a free magma
##
BindGlobal( "CATALAN", [ 1 ] );
BindGlobal( "Catalan", function( n )
if not IsBound( CATALAN[n+1] ) then
CATALAN[n+1]:= Binomial( 2*n, n ) / ( n+1 );
fi;
return CATALAN[n+1];
end );
BindGlobal( "ElementNumber_FreeMagma", function( enum, nr )
local WordFromInfo, n, l, summand, NB, q, p;
# Create the external representation (recursively).
WordFromInfo:= function( N, l, p, q )
local k, NB, summand, Nk, p1, p2, q1, q2;;
if l = 1 then
return p;
fi;
k:= 0;
while 0 < q do
k:= k+1;
NB:= Catalan( l-k-1 );
summand:= Catalan( k-1 ) * NB;
q:= q - summand;
od;
q:= q + summand;
Nk:= N^k;
p1:= p mod Nk;
if p1 = 0 then
p1:= Nk;
fi;
p2:= ( p - p1 ) / Nk + 1;
q2:= q mod NB;
if q2 = 0 then
q2:= NB;
fi;
q1:= ( q - q2 ) / NB + 1;
return [ WordFromInfo( N, k, p1, q1 ),
WordFromInfo( N, l-k, p2, q2 ) ];
end;
n:= enum!.nrgenerators;
l:= 0;
while 0 < nr do
NB:= Catalan( l );
l:= l+1;
summand:= n^l * NB;
nr:= nr - summand;
od;
nr:= nr + summand;
q:= nr mod NB;
if q = 0 then
q:= NB;
fi;
p:= ( nr - q ) / NB + 1;
return ObjByExtRep( enum!.family, WordFromInfo( n, l, p, q ) );
end );
BindGlobal( "NumberElement_FreeMagma", function( enum, elm )
local WordInfo, n, info, pos, i;
if not IsCollsElms( FamilyObj( enum ), FamilyObj( elm ) ) then
return fail;
fi;
# Analyze the structure (recursively).
WordInfo:= function( ngens, obj )
local info1, info2, N;
if IsInt( obj ) then
return [ ngens, 1, obj, 1 ];
else
info1:= WordInfo( ngens, obj[1] );
info2:= WordInfo( ngens, obj[2] );
N:= info1[2] + info2[2];
return [ ngens, N,
info1[3]+ ngens^info1[2] * ( info2[3]-1 ),
Sum( List( [ 1 .. info1[2]-1 ],
i -> Catalan( i-1 ) * Catalan( N-i-1 ) ), 0 )
+ ( info1[4] - 1 ) * Catalan( info2[2]-1 ) + info2[4] ];
fi;
end;
# Calculate the length, the number of the corresponding assoc. word,
# and the number of the bracketing.
n:= enum!.nrgenerators;
info:= WordInfo( n, ExtRepOfObj( elm ) );
# Compute the position.
pos:= 0;
for i in [ 1 .. info[2]-1 ] do
pos:= pos + n^i * Catalan( i-1 );
od;
return pos + ( info[3] - 1 ) * Catalan( info[2]-1 ) + info[4];
end );
InstallMethod( Enumerator,
"for a free magma",
[ IsWordCollection and IsWholeFamily and IsMagma ],
function( M )
# A free associative structure needs another method.
if IsAssocWordCollection( M ) then
TryNextMethod();
fi;
return EnumeratorByFunctions( M, rec(
ElementNumber := ElementNumber_FreeMagma,
NumberElement := NumberElement_FreeMagma,
family := ElementsFamily( FamilyObj( M ) ),
nrgenerators := Length( ElementsFamily(
FamilyObj( M ) )!.names ) ) );
end );
More information about the Forum
mailing list