GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#######################################################################
##
#W omput.gi OpenMath Package Andrew Solomon
#W Marco Costantini
##
#Y Copyright (C) 1999, 2000, 2001, 2006
#Y School Math and Comp. Sci., University of St. Andrews, Scotland
#Y Copyright (C) 2004, 2005, 2006 Marco Costantini
##
## Writes a GAP object to an output stream, as an OpenMath object
##
#######################################################################
##
#M OMPut( <OMWriter>, <cyc> )
##
## Printing for cyclotomics
##
InstallMethod( OMPut, "for a proper cyclotomic", true,
[ IsOpenMathWriter, IsCyc ],0,
function(writer, x)
local real,
imaginary,
n, # Length(powlist)
i,
clist; # x = Sum_i clist[i]*E(n)^(i-1)
if IsGaussRat( x ) then
real := x -> (x + ComplexConjugate( x )) / 2;
imaginary := x -> (x - ComplexConjugate( x )) * -1 / 2 * E( 4 );
OMPutApplication( writer, "complex1", "complex_cartesian",
[ real(x), imaginary(x)] );
else
n := Conductor(x);
clist := CoeffsCyc(x, n);
OMPutOMA( writer );
OMPutSymbol( writer, "arith1", "plus" );
for i in [1 .. n] do
if clist[i] <> 0 then
OMPutOMA( writer ); #times
OMPutSymbol( writer, "arith1", "times" );
OMPut(writer, clist[i]);
OMPutApplication( writer, "algnums", "NthRootOfUnity", [ n, i-1 ] );
OMPutEndOMA( writer ); #times
fi;
od;
OMPutEndOMA( writer );
fi;
end);
#######################################################################
##
#M OMPut( <writer>, <transformation> )
##
## Printing for transformations : specified in permut1.ocd
##
InstallMethod(OMPut, "for a transformation", true,
[IsOpenMathWriter, IsTransformation],0,
function(writer, x)
OMPutApplication( writer, "transform1", "transformation",
ImageListOfTransformation(x) );
end);
#######################################################################
##
#M OMPut( <writer>, <semigroup> )
##
InstallMethod(OMPut, "for a semigroup", true,
[IsOpenMathWriter, IsSemigroup],0,
function(writer, x)
OMPutApplication( writer, "semigroup1", "semigroup_by_generators",
GeneratorsOfSemigroup(x) );
end);
#######################################################################
##
#M OMPut( <writer>, <monoid> )
##
##
InstallMethod(OMPut, "for a monoid", true,
[IsOpenMathWriter, IsMonoid],0,
function(writer, x)
OMPutApplication( writer, "monoid1", "monoid_by_generators",
GeneratorsOfMonoid(x) );
end);
#######################################################################
##
#M OMPut( <writer>, <free group> )
##
##
InstallMethod(OMPut, "for a free group", true,
[IsOpenMathWriter, IsFreeGroup],0,
function(writer, f)
# SetOMReference( f, Concatenation("freegroup", RandomString(16) ) );
# OMWriteLine( writer, [ "<OMA id=\"", OMReference( f ), "\" >" ] );
OMPutOMA( writer );
OMPutSymbol( writer, "fpgroup1", "free_groupn" );
OMPut( writer, Length( GeneratorsOfGroup( f ) ) );
OMPutEndOMA( writer );
end);
#######################################################################
##
#M OMPut( <writer>, <FpGroup> )
##
##
InstallMethod(OMPut, "for an FpGroup", true,
[IsOpenMathWriter, IsFpGroup],0,
function(writer, g)
local x;
# SetOMReference( g, Concatenation( "fpgroup", RandomString(16) ) );
# OMWriteLine( writer, [ "<OMA id=\"", OMReference( g ), "\" >" ] );
OMPutOMA( writer );
OMPutSymbol( writer, "fpgroup1", "fpgroup" );
OMPutReference( writer, FreeGroupOfFpGroup( g ) );
for x in RelatorsOfFpGroup( g ) do
OMPut( writer, ExtRepOfObj( x ) );
od;
OMPutEndOMA( writer );
end);
#######################################################################
##
#M OMPut( <writer>, <record> )
##
## There is no OpenMath representation for records, though this might
## be done within standard using OMATTR. However, for better efficiency
## we introduce private symbol for the record, as records are native
## objects in many programming languages.
##
## To minimise the number of OM tags in the resulting OM code, the
## record with N components will be encoded as a list of the length
## 2*N where strings with component names will be on odd places and
## corresponding values will be on even ones.
##
## As a practical application of this, we consider transmitting
## graphs given as records in the Grape package format, which stores
## extra information not included in the default OpenMath encoding
## for graphs.
##
InstallMethod(OMPut, "for a record", true,
[IsOpenMathWriter, IsRecord], 0 ,
function(writer, x )
local r;
OMPutOMA( writer );
OMPutSymbol( writer, "record1", "record" );
for r in RecNames(x) do
OMPut( writer, r );
OMPut( writer, x.(r) );
od;
OMPutEndOMA( writer );
end);
#######################################################################
##
#M OMPut( <writer>, <group> )
##
## Printing for groups as in openmath/cds/group1.ocd (Note that it
## differs from group1.group from the group1 CD at http://www.openmath.org,
## since we just output the list of generators)
##
InstallMethod(OMPut, "for a group", true,
[IsOpenMathWriter, IsGroup],0,
function(writer, x)
OMPutApplication( writer, "group1", "group_by_generators",
GeneratorsOfGroup(x) );
end);
#######################################################################
##
#M OMPut( <writer>, <pcgroup> )
##
## Printing for pcgroups as pcgroup1.pcgroup_by_pcgscode:
## the 1st argument is pcgs code of the group, the 2nd is
## its order. Note that OMTest will return fail in this
## case, since the result of parsing the output will be
## an isomorphic group but not equal to the original one.
##
InstallMethod(OMPut, "for a pcgroup", true,
[IsOpenMathWriter, IsPcGroup],0,
function(writer, x)
OMPutOMA( writer );
OMPutSymbol( writer, "pcgroup1", "pcgroup_by_pcgscode" );
OMPut( writer, CodePcGroup(x) );
OMPut( writer, Size(x) );
OMPutEndOMA( writer );
end);
#######################################################################
##
#M OMPut( <writer>, <subgroup lattice> )
##
##
InstallMethod(OMPut, "for a lattice of subgroups", true,
[IsOpenMathWriter, IsLatticeSubgroupsRep],0,
function(writer, L)
local cls, sz, len, i, levels, j, class, max, levelnr, rep, k, z, t,
nr, class_size;
cls:=ConjugacyClassesSubgroups(L);
# set of orders of subgroups that appear in the group
sz:=[];
len:=[];
for i in cls do
Add(len,Size(i));
AddSet(sz,Size(Representative(i)));
od;
# reverse it so G comes first, {1} last
sz:=Reversed(sz);
# create a list of records describing levels
levels := [];
for i in [ 1 .. Length(sz) ] do
levels[i] := rec( index := sz[1]/sz[i], classes:=rec() );
od;
# populate levels with classes
for i in [1..Length(cls)] do
class := rec( number := i, vertices := List( [1..len[i]], j -> [] ) );
levels[ Position(sz,Size(Representative(cls[i]))) ].classes.(Concatenation("nr",String(i))) := class;
od;
# label:=0;
# # assign labels
# for i in [ Length(sz), Length(sz)-1 .. 2 ] do
# for nr in RecNames( levels[i].classes ) do
# levels[i].classes.(nr).labels:=[];
# for j in [ 1 .. Length( levels[i].classes.(nr).vertices) ] do
# label:=label+1;
# Add( levels[i].classes.(nr).labels, String(label) );
# od;
# od;
# od;
# levels[1].classes.(RecNames( levels[1].classes )[1]).labels:=["G"];
max:=MaximalSubgroupsLattice(L);
for i in [1..Length(cls)] do
levelnr := Position(sz,Size(Representative(cls[i])));
for j in max[i] do
rep:=ClassElementLattice(cls[i],1);
for k in [1..len[i]] do
if k=1 then
z:=j[2];
else
t:=cls[i]!.normalizerTransversal[k];
z:=ClassElementLattice(cls[j[1]],1); # force computation of transv.
z:=cls[j[1]]!.normalizerTransversal[j[2]]*t;
z:=PositionCanonical(cls[j[1]]!.normalizerTransversal,z);
fi;
Add( levels[levelnr].classes.(Concatenation("nr",String(i))).vertices[k], [ j[1], z ] );
od;
od;
od;
OMPutOMA( writer );
OMPutSymbol( writer, "poset1", "poset_diagram" );
for i in [ 1 .. Length(levels) ] do
OMPutOMA( writer );
OMPutSymbol( writer, "poset1", "level" );
OMPut( writer, levels[i].index );
OMPutOMA( writer );
OMPutSymbol( writer, "list1", "list" );
for nr in RecNames( levels[i].classes ) do
OMPutOMA( writer );
OMPutSymbol( writer, "poset1", "class" );
OMPutOMA( writer );
OMPutSymbol( writer, "list1", "list" );
class_size := Length( levels[i].classes.(nr).vertices );
for j in [ 1 .. class_size ] do
OMPutOMA( writer );
OMPutSymbol( writer, "poset1", "vertex" );
if i = 1 then
OMPut( writer, "G" );
elif class_size = 1 then
OMPut( writer, String( levels[i].classes.(nr).number ) );
else
OMPut( writer, Concatenation( String( levels[i].classes.(nr).number ), ".", String(j) ) );
fi;
if Length( levels[i].classes.(nr).vertices[j] ) > 0 then
OMPutOMA( writer );
OMPutSymbol( writer, "list1", "list" );
for k in levels[i].classes.(nr).vertices[j] do
if len[k[1]] = 1 then
OMPut( writer, String( k[1] ) );
else
OMPut( writer, Concatenation( String( k[1] ), ".", String( k[2] ) ) );
fi;
od;
OMPutEndOMA( writer );
else
OMPutSymbol( writer, "set1", "emptyset" );
fi;
OMPutEndOMA( writer );
od;
OMPutEndOMA( writer );
OMPutEndOMA( writer );
od;
OMPutEndOMA( writer );
OMPutEndOMA( writer );
od;
OMPutEndOMA( writer );
end);
#######################################################################
##
## Experimental methods for OMPut for character tables"
##
#######################################################################
##
#F OMIrredMatEntryPut( <writer>, <entry>, <data> )
##
## <entry> is a (possibly unknown) cyclotomic
## <data> is the record of information about names and values
## used to substitute for complicated irreducible expressions.
##
## This borrows heavily from Thomas Breuer's
## CharacterTableDisplayStringEntryDefault
##
BindGlobal("OMIrredMatEntryPut", function(writer, entry, data)
local val, irrstack, irrnames, name, ll, i, letters, n;
# OMPut(writer,entry);
if IsCyc( entry ) and not IsInt( entry ) then
# find shorthand for cyclo
irrstack:= data.irrstack;
irrnames:= data.irrnames;
for i in [ 1 .. Length( irrstack ) ] do
if entry = irrstack[i] then
OMPutVar(writer, irrnames[i]);
return;
elif entry = -irrstack[i] then
OMPutOMA( writer );
OMPutSymbol(writer, "arith1", "unary_minus");
OMPutVar(writer, irrnames[i]);
OMPutEndOMA( writer );
return;
fi;
val:= GaloisCyc( irrstack[i], -1 );
if entry = val then
OMPutOMA( writer );
OMPutSymbol(writer, "complex1", "conjugate");
OMPutVar(writer, irrnames[i]);
OMPutEndOMA( writer );
return;
elif entry = -val then
OMPutOMA( writer );
OMPutSymbol(writer, "arith1", "unary_minus");
OMPutOMA( writer );
OMPutSymbol(writer, "complex1", "conjugate");
OMPutVar(writer, irrnames[i]);
OMPutEndOMA( writer );
OMPutEndOMA( writer );
return;
fi;
val:= StarCyc( irrstack[i] );
if entry = val then
OMPutOMA( writer );
OMPutSymbol(writer, "algnums", "star");
OMPutVar(writer, irrnames[i]);
OMPutEndOMA( writer );
return;
elif -entry = val then
OMPutOMA( writer );
OMPutSymbol(writer, "arith1", "unary_minus");
OMPutOMA( writer );
OMPutSymbol(writer, "algnums", "star");
OMPutVar(writer, irrnames[i]);
OMPutEndOMA( writer );
OMPutEndOMA( writer );
return;
fi;
i:= i+1;
od;
Add( irrstack, entry );
# Create a new name for the irrationality.
name:= "";
n:= Length( irrstack );
letters:= data.letters;
ll:= Length( letters );
while 0 < n do
name:= Concatenation( letters[(n-1) mod ll + 1], name );
n:= QuoInt(n-1, ll);
od;
Add( irrnames, name );
OMPutVar(writer, irrnames[ Length( irrnames ) ]);
return;
elif IsUnknown( entry ) then
OMPutVar(writer, "?");
return;
else
OMPut(writer, entry);
return;
fi;
end);
#######################################################################
##
#F OMPutIrredMat( <writer>, <x> )
##
## <x> is a character table
##
## This borrows heavily from Thomas Breuer's
## character table Display routines -- see lib/ctbl.gi
##
BindGlobal("OMPutIrredMat", function(writer, x)
local r,i, irredmat, data;
data := CharacterTableDisplayStringEntryDataDefault( x );
# irreducibles matrix
irredmat := List(Irr(x), ValuesOfClassFunction);
# OMPut(writer,irredmat);
OMPutOMA( writer );
OMPutSymbol( writer, "linalg2", "matrix" );
for r in irredmat do
OMPutOMA( writer );
OMPutSymbol( writer, "linalg2", "matrixrow" );
for i in r do
OMIrredMatEntryPut(writer, i, data);
od;
OMPutEndOMA( writer );
od;
OMPutEndOMA( writer );
# Now output the list of (variable = value) pairs
OMPutOMA( writer );
OMPutSymbol(writer, "list1", "list");
for i in [1 .. Length(data.irrstack)] do
OMPutOMA( writer );
OMPutSymbol(writer, "relation1", "eq");
OMPutVar(writer, data.irrnames[i]);
OMPut(writer, data.irrstack[i]);
OMPutEndOMA( writer );
od;
OMPutEndOMA( writer );
end);
#######################################################################
##
#M OMPut( <writer>, <character table> )
##
##
InstallMethod(OMPut, "for a character table", true,
[IsOpenMathWriter, IsCharacterTable],0,
function(writer, c)
local
centralizersizes,
centralizerindices,
centralizerprimes,
ordersclassreps,
sizesconjugacyclasses,
classnames,
powmap;
# the centralizer primes
centralizersizes := SizesCentralizers(c);
centralizerprimes := AsSSortedList(Factors(Product(centralizersizes)));
# the indices which define the factorisation of the
# centralizer orders
centralizerindices := List(centralizersizes, z->
List(centralizerprimes, x->Size(Filtered(Factors(z), y->y=x))));
# ordersclassreps - every element of a conjugacy class has
# the same order.
ordersclassreps := OrdersClassRepresentatives( c );
# SizesConjugacyClasses
sizesconjugacyclasses := SizesConjugacyClasses( c );
# the classnames
classnames := ClassNames(c);
# the powermap
powmap := List(centralizerprimes,
x->List(PowerMap(c, x),z->ClassNames(c)[z]));
# irreducibles matrix
# irredmat := List(Irr(c), ValuesOfClassFunction);
OMPutOMA( writer );
OMPutSymbol( writer, "group1", "character_table" );
OMPutList(writer, classnames);
OMPutList(writer, centralizersizes);
OMPutList(writer, centralizerprimes);
OMPutList(writer, centralizerindices);
OMPutList(writer, powmap);
OMPutList(writer, sizesconjugacyclasses);
OMPutList(writer, ordersclassreps);
# OMPut(writer, irredmat); # previous cd version
OMPutIrredMat(writer, c);
OMPutEndOMA( writer );
end);
#############################################################################
#E