/* File generate.c. */
/* Copyright (C) 1992 by Jeffrey S. Leon. This software may be used freely
for educational and research purposes . Any other use requires permission
from the author. */
/* Main program for generate command, which may be used
to find a base and strong generating set for a permutation group using
the random Schreier and / or Schreier - Todd - Coxeter - Sims methods . The format
of the command is :
generate < options > < permGroup > < generatedPermGroup >
where the meaning of the parameters is as follows :
< permGroup > : the permutation group G for which a base and strong
generating set is to be found .
< generatedPermGroup > : the same permutation group G with a base and strong
generating set , depending on options , possibly a
strong presentation .
The general options are as follows :
- nr Omit random - Schreier phase .
- ns Omit Schreier - Todd - Coxeter - Sims phase ( automatically
omitted if order is known in advance and random - Schreier
phases generates full order , unless the - p option is given .
- p Find a presentation .
- q Don ' t write status information to standard output .
- in : < group > Group G is contained in < group > . Only base of < group > is
used ; < group > need not be valid as long as its base ,
base size , and degree fields are filled in correctly .
- overwrite Overwrite , rather than append to , the output file .
- i Image format for output group .
- c Cycle format for output group .
- gn : < name >
Options applicable specifically to the random - Schreier phase are :
- s : < integer > Seed for random number generator .
- tr : < integer > Random Schreier phase terminates after this many
consecutive " successes " ( quasi - random elements that
are factorable ) .
- ti : < integer > This many consecutive non - involutory generators will
be rejected in an attempt to choose involutory generators .
- th : k This many consecutive generators will be rejected in
an attempt to choose a generator of order 3 ( or less ) .
- nro Suppress normal attempt to reduce generator order by
replacing generators with powers .
- wi : w , x Here w and x are integers with w < = x . The word length
increment will be random between w and x .
- z Redundant strong generators will be removed after the
algorithm completes . .
Options applicable to the STCS phase are :
- go : m Automatically include the order of each generator as a
relator when the generator order does not exceed m
( default 15 ) .
- po : m Automatically include the order of each product of
generators as a relator when the product order does
not exceed m ( default 5 ) .
- x2 : m If the STCS phase terminates with more than
m generators ( excluding inverses ) , redundant generators
are removed .
- pr : a , b , c , d , e Determines priority for relator selection . The priority
of a relator r is a - b * ( len + symLen ) / 2 . Relators are
selected if their priority exceeds
c + d * chosen - e * omitted , where chosen represents the
number of relators chosen at this level and omitted
represents the number not chosen .
- sh : i1 , k1 , i2 . . Specifies which cyclic shifts of relators will be
used in the Felsch enumeration . Specifies that an
i1 position shift will be used if the relator
priority exceeds the selection priority by at least
k1 , etc . By default , all shifts are always used .
- x : k Specifies use of up to k extra cosets during enumeration
( default 0 ) . When k > 0 , a different procedure is
used to check point stabilizers .
- y : m The number of extra cosets used will be
m / 100 * degree ( rounded up ) , but in no case more than
k, as above (default 10). */
#include <stddef.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define MAIN
#include "group.h"
#include "groupio.h"
#include "enum.h"
#include "storage.h"
#include "chbase.h"
#include "inform.h"
#ifdef ALT_TIME_HEADER
#include "cputime.h"
#endif
#ifdef TICK
#undef CLK_TCK
#define CLK_TCK TICK
#endif
#include "errmesg.h"
#include "new.h"
#include "readgrp.h"
#include "randschr.h"
#include "stcs.h"
#include "util.h"
static void nameGenerators(
PermGroup *const H,
char genNamePrefix[]);
static void informGenerateTime(
clock_t startTime,
clock_t randSchrTime,
clock_t optGroupTime,
clock_t stcsTime);
static void verifyOptions(void );
GroupOptions options;
STCSOptions sOptions;
Unsigned relatorSelection[5 ] = {1000 ,0 ,800 ,0 ,0 };
Unsigned shiftSelection[11 ] = {UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,
UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,
UNKNOWN};
Unsigned shiftPriority[11 ];
int main( int argc, char *argv[])
{
char groupFileName[MAX_FILE_NAME_LENGTH] = "" ,
genGroupFileName[MAX_FILE_NAME_LENGTH] = "" ,
containingGroupFileName[MAX_FILE_NAME_LENGTH] = "" ;
char groupLibraryName[MAX_NAME_LENGTH+1 ] = "" ,
genGroupLibraryName[MAX_NAME_LENGTH+1 ] = "" ,
genGroupObjectName[MAX_NAME_LENGTH+1 ] = "" ,
containingGroupLibraryName[MAX_NAME_LENGTH+1 ] = "" ,
prefix[MAX_FILE_NAME_LENGTH],
suffix[MAX_NAME_LENGTH];
Unsigned i, j, optionCountPlus1, level;
BOOLEAN omitRandomSchreierOption, omitStcsOption, presentationOption,
quietOption, cycleFormatFlag, imageFormatFlag, removeRedunStrGens,
noBackupFlag;
Unsigned trimStrGenSet1, trimStrGenSet2;
PermGroup *G, *containingGroup;
char comment[1024 ] = "" ;
UnsignedS *pointList = allocIntArrayBaseSize();
char tempStr[12 ];
char *strPtr, *commaPtr;
Unsigned *knownBase = allocIntArrayBaseSize();
RandomSchreierOptions rOptions = {47 ,UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,
UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN};
clock_t startTime, randSchrTime, optGroupTime, stcsTime;
/* Provide usage info if no arguments are specified. */
if ( argc == 1 ) {
printf( "\nUsage: generate [options] originalPermGroup permGroupWithBaseSGS\n" );
freeIntArrayBaseSize( pointList);
freeIntArrayBaseSize( knownBase);
return 0 ;
}
/* Check for limits option. If present in position 1 give limits and
return. */
if ( strcmp( argv[1 ], "-l" ) == 0 || strcmp( argv[1 ], "-L" ) == 0 ) {
showLimits();
freeIntArrayBaseSize( pointList);
freeIntArrayBaseSize( knownBase);
return 0 ;
}
/* Check for verify option. If present, perform verify (Note verifyOptions
terminates program). */
if ( strcmp( argv[1 ], "-v" ) == 0 || strcmp( argv[1 ], "-V" ) == 0 )
verifyOptions();
/* Check for 1 or 2 parameters following options. */
for ( optionCountPlus1 = 1 ; optionCountPlus1 <= argc-1 &&
argv[optionCountPlus1][0 ] == '-' ; ++optionCountPlus1 )
;
if ( argc - optionCountPlus1 < 1 || argc - optionCountPlus1 > 2 ) {
printf( "\n\nError: 1 or 2 non-option parameters are required.\n" );
exit (ERROR_RETURN_CODE);
}
/* Process options. */
prefix[0 ] = '\0' ;
suffix[0 ] = '\0' ;
options.maxBaseSize = DEFAULT_MAX_BASE_SIZE;
sOptions.maxDeducQueueSize = UNKNOWN;
sOptions.genOrderLimit = 13 ;
sOptions.prodOrderLimit = 3 ;
sOptions.maxExtraCosets = 0 ;
sOptions.percentExtraCosets = 10 ;
omitRandomSchreierOption = FALSE ;
omitStcsOption = TRUE ;
presentationOption = FALSE ;
rOptions.reduceGenOrder = TRUE ;
rOptions.rejectNonInvols = 0 ;
removeRedunStrGens = FALSE ;
quietOption = FALSE ;
options.genNamePrefix[0 ] = '\0' ;
trimStrGenSet1 = 20 ;
trimStrGenSet2 = 20 ;
cycleFormatFlag = FALSE ;
imageFormatFlag = FALSE ;
noBackupFlag = FALSE ;
strcpy( options.outputFileMode, "w" );
strcpy( options.genNamePrefix, "" );
for ( i = 1 ; i < optionCountPlus1 ; ++i )
/* General options. */
if ( strcmp( argv[i], "-a" ) == 0 )
strcpy( options.outputFileMode, "a" );
else if ( strcmp( argv[i], "-c" ) == 0 )
cycleFormatFlag = TRUE ;
else if ( strcmp( argv[i], "-i" ) == 0 )
imageFormatFlag = TRUE ;
else if ( strncmp( argv[i], "-mb:" , 4 ) == 0 ) {
errno = 0 ;
options.maxBaseSize = (Unsigned ) strtol(argv[i]+4 ,NULL,0 );
if ( errno )
ERROR( "main (cent)" , "Invalid syntax for -mb option" )
}
else if ( strncmp( argv[i], "-mw:" , 4 ) == 0 ) {
errno = 0 ;
options.maxWordLength = (Unsigned ) strtol(argv[i]+4 ,NULL,0 );
if ( errno )
ERROR( "main (cent)" , "Invalid syntax for -mw option" )
}
else if ( strncmp(argv[i],"-n:" ,3 ) == 0 )
strcpy( genGroupObjectName, argv[i]+3 );
else if ( strcmp( argv[i], "-nb" ) == 0 )
noBackupFlag = TRUE ;
else if ( strcmp( argv[i], "-overwrite" ) == 0 )
strcpy( options.outputFileMode, "w" );
else if ( strncmp( argv[i], "-p:" , 3 ) == 0 ) {
strcpy( prefix, argv[i]+3 );
}
else if ( strcmp( argv[i], "-q" ) == 0 )
quietOption = TRUE ;
else if ( strncmp( argv[i], "-t:" , 3 ) == 0 ) {
strcpy( suffix, argv[i]+3 );
}
else if ( strcmp( argv[i], "-z" ) == 0 ) {
removeRedunStrGens = TRUE ;
}
/* Method selection options. */
else if ( strcmp( argv[i], "-nr" ) == 0 )
omitRandomSchreierOption = TRUE ;
else if ( strcmp( argv[i], "-stcs" ) == 0 )
omitStcsOption = FALSE ;
/* Random Schreier options. */
else if ( strcmp( argv[i], "-nro" ) == 0 )
rOptions.reduceGenOrder = FALSE ;
else if ( strncmp(argv[i],"-s:" ,3 ) == 0 ) {
errno = 0 ;
rOptions.initialSeed = (unsigned long ) strtol( argv[i]+3 , NULL, 0 );
if ( errno )
ERROR1s( "main (generate command)" , "Invalid option " , argv[i], "." )
}
else if ( strncmp(argv[i],"-ti:" ,4 ) == 0 ) {
errno = 0 ;
rOptions.rejectNonInvols = (unsigned long ) strtol( argv[i]+4 , NULL, 0 );
if ( errno )
ERROR1s( "main (generate command)" , "Invalid option " , argv[i], "." )
}
else if ( strncmp(argv[i],"-tr:" ,4 ) == 0 ) {
errno = 0 ;
rOptions.stopAfter = (unsigned long ) strtol( argv[i]+4 , NULL, 0 );
if ( errno )
ERROR1s( "main (generate command)" , "Invalid option " , argv[i], "." )
}
else if ( strncmp( argv[i], "-wi:" , 4 ) == 0 ) {
errno = 0 ;
rOptions.minWordLengthIncrement = (unsigned long ) strtol( argv[i]+4 , &commaPtr, 0 );
if ( errno || *commaPtr != ',' )
ERROR1s( "main (generate command)" , "Invalid syntax in option " ,
argv[i], "." )
rOptions.maxWordLengthIncrement = (unsigned long ) strtol( commaPtr+1 , NULL, 0 );
if ( errno )
ERROR1s( "main (generate command)" , "Invalid syntax in option " ,
argv[i], "." )
}
/* STCS options. */
else if ( strncmp( argv[i], "-in:" , 4 ) == 0 ) {
parseLibraryName( argv[i]+4 , "" , "" , containingGroupFileName,
containingGroupLibraryName);
}
else if ( strncmp(argv[i],"-pr:" ,4 ) == 0 ) {
errno = 0 ;
commaPtr = argv[i]+3 ;
for ( j = 0 ; j <= 4 ; ++j ) {
strPtr = commaPtr + 1 ;
relatorSelection[j] = (Unsigned ) (unsigned long ) strtol( strPtr, &commaPtr, 0 );
if ( errno || ( j < 4 && *commaPtr != ',' ) )
ERROR1s( "main (generate command)" , "Invalid option " , argv[i],
"." )
}
}
else if ( strncmp(argv[i],"-sh:" ,4 ) == 0 ) {
errno = 0 ;
commaPtr = argv[i]+3 ;
for ( j = 0 ; j < 10 && *commaPtr != '\0' ; ++j ) {
strPtr = commaPtr + 1 ;
shiftSelection[j] = (Unsigned ) (unsigned long ) strtol( strPtr, &commaPtr, 0 );
if ( errno || *commaPtr != ',' )
ERROR1s( "main (generate command)" , "Invalid option " , argv[i],
"." )
strPtr = commaPtr + 1 ;
shiftPriority[j] = (Unsigned ) (unsigned long ) strtol( strPtr, &commaPtr, 0 );
if ( errno || (*commaPtr != ',' && *commaPtr != '\0' ) )
ERROR1s( "main (generate command)" , "Invalid option " , argv[i],
"." )
}
}
else if ( strncmp(argv[i],"-th:" ,4 ) == 0 ) {
errno = 0 ;
rOptions.rejectHighOrder = (unsigned long ) strtol( argv[i]+4 , NULL, 0 );
if ( errno )
ERROR1s( "main (generate command)" , "Invalid option " , argv[i], "." )
}
else if ( strncmp(argv[i],"-go:" ,4 ) == 0 ) {
errno = 0 ;
sOptions.genOrderLimit = (unsigned long ) strtol( argv[i]+4 , NULL, 0 );
if ( errno )
ERROR1s( "main (generate command)" , "Invalid option " , argv[i], "." )
}
else if ( strncmp(argv[i],"-po:" ,4 ) == 0 ) {
errno = 0 ;
sOptions.prodOrderLimit = (unsigned long ) strtol( argv[i]+4 , NULL, 0 );
if ( errno )
ERROR1s( "main (generate command)" , "Invalid option " , argv[i], "." )
}
else if ( strncmp(argv[i],"-x:" ,3 ) == 0 ) {
errno = 0 ;
sOptions.maxExtraCosets = (unsigned long ) strtol( argv[i]+3 , NULL, 0 );
if ( errno )
ERROR1s( "main (generate command)" , "Invalid option " , argv[i], "." )
}
else if ( strncmp(argv[i],"-y:" ,3 ) == 0 ) {
errno = 0 ;
sOptions.percentExtraCosets = (unsigned long ) strtol( argv[i]+3 , NULL, 0 );
if ( errno )
ERROR1s( "main (generate command)" , "Invalid option " , argv[i], "." )
}
else
ERROR1s( "main (generate command)" , "Invalid option " , argv[i], "." )
/* Compute maximum degree and word length. */
options.maxWordLength = 200 + 5 * options.maxBaseSize;
options.maxDegree = MAX_INT - 2 - options.maxBaseSize;
/* Compute names for input and output groups. */
parseLibraryName( argv[optionCountPlus1], prefix, suffix, groupFileName,
groupLibraryName);
if ( argc - optionCountPlus1 == 2 )
parseLibraryName( argv[optionCountPlus1+1 ], "" , "" , genGroupFileName,
genGroupLibraryName);
else {
strcpy( genGroupFileName, groupFileName);
strcpy( genGroupLibraryName, groupLibraryName);
}
/* Set initialize option for STCS. */
sOptions.initialize = omitRandomSchreierOption;
/* Set default generator name prefix, if not specified. */
if ( options.genNamePrefix[0 ] == ' ' )
strncpy( options.genNamePrefix, genGroupLibraryName, 4 );
/* Read in input group, and base for containing group, if requested. */
G = readPermGroup( groupFileName, groupLibraryName, 0 , "" );
if ( containingGroupFileName[0 ] ) {
containingGroup = readPermGroup( containingGroupFileName,
containingGroupLibraryName, G->degree, "" );
for ( i = 1 ; i <= containingGroup->baseSize ; ++i )
knownBase[i] = containingGroup->base[i];
knownBase[containingGroup->baseSize+1 ] = 0 ;
deletePermGroup( containingGroup);
}
startTime = CPU_TIME();
/* Apply random Schreier algorithm. */
if ( !omitRandomSchreierOption ) {
/* SETUP OPTIONS STRING */
randomSchreier( G, rOptions);
if ( removeRedunStrGens )
removeRedunSGens( G, 1 );
}
randSchrTime = CPU_TIME();
optGroupTime = CPU_TIME();
/* Apply Schreier-Todd-Coxeter-Sims algorithm, if appropriate. */
if ( !omitStcsOption /* FIX THIS */ )
schreierToddCoxeterSims( G, knownBase);
stcsTime = CPU_TIME();
if ( !quietOption ) {
informGroup(G);
printf( "\n Base: " );
for ( level = 1 ; level <= G->baseSize ; ++level )
printf( " %5u" , G->base[level]);
printf( "\n Basic orbit lengths:" );
for ( level = 1 ; level <= G->baseSize ; ++level )
printf( " %5u" , G->basicOrbLen[level]);
printf( "\n" );
informGenerateTime( startTime, randSchrTime, optGroupTime, stcsTime);
}
/* Write out the generated group. */
sprintf( comment, "The group %s, base and strong generating set constucted." ,
G->name);
if ( cycleFormatFlag )
G->printFormat = cycleFormat;
if ( imageFormatFlag )
G->printFormat = imageFormat;
if ( genGroupObjectName[0 ] )
strcpy( G->name, genGroupObjectName);
if ( argc - optionCountPlus1 == 1 && !noBackupFlag )
if ( rename(groupFileName,"oldgroup" ) == -1 )
ERROR1s( "main (generate command)" , "Original group " , groupFileName,
" could not be renamed as oldgroup." )
writePermGroup( genGroupFileName, genGroupLibraryName, G, comment);
/* Free pseudo-stack storage. */
freeIntArrayBaseSize( pointList);
freeIntArrayBaseSize( knownBase);
return 0 ;
}
/*-------------------------- nameGenerators ------------------------------*/
static void nameGenerators(
PermGroup *const H,
char genNamePrefix[])
{
Unsigned i;
Permutation *gen;
if ( genNamePrefix[0 ] == '\0' ) {
strncpy( genNamePrefix, H->name, 4 );
genNamePrefix[4 ] = '\0' ;
}
for ( gen = H->generator , i = 1 ; gen ; gen = gen->next , ++i ) {
strcpy( gen->name, genNamePrefix);
sprintf( gen->name + strlen(gen->name), "%02d" , i);
}
}
/*-------------------------- verifyOptions -------------------------------*/
static void verifyOptions(void )
{
CompileOptions mainOpts = { DEFAULT_MAX_BASE_SIZE, MAX_NAME_LENGTH,
MAX_PRIME_FACTORS,
MAX_REFINEMENT_PARMS, MAX_FAMILY_PARMS,
MAX_EXTRA, XLARGE, SGND, NFLT};
extern void xaddsge( CompileOptions *cOpts);
extern void xbitman( CompileOptions *cOpts);
extern void xchbase( CompileOptions *cOpts);
extern void xcopy ( CompileOptions *cOpts);
extern void xcstbor( CompileOptions *cOpts);
extern void xerrmes( CompileOptions *cOpts);
extern void xessent( CompileOptions *cOpts);
extern void xfactor( CompileOptions *cOpts);
extern void xinform( CompileOptions *cOpts);
extern void xnew ( CompileOptions *cOpts);
extern void xoldcop( CompileOptions *cOpts);
extern void xpermgr( CompileOptions *cOpts);
extern void xpermut( CompileOptions *cOpts);
extern void xprimes( CompileOptions *cOpts);
extern void xrandgr( CompileOptions *cOpts);
extern void xrandsc( CompileOptions *cOpts);
extern void xreadgr( CompileOptions *cOpts);
extern void xrelato( CompileOptions *cOpts);
extern void xstcs ( CompileOptions *cOpts);
extern void xstorag( CompileOptions *cOpts);
extern void xtoken ( CompileOptions *cOpts);
extern void xutil ( CompileOptions *cOpts);
xaddsge( &mainOpts);
xbitman( &mainOpts);
xchbase( &mainOpts);
xcopy ( &mainOpts);
xcstbor( &mainOpts);
xerrmes( &mainOpts);
xessent( &mainOpts);
xfactor( &mainOpts);
xinform( &mainOpts);
xnew ( &mainOpts);
xoldcop( &mainOpts);
xpermgr( &mainOpts);
xpermut( &mainOpts);
xprimes( &mainOpts);
xrandgr( &mainOpts);
xrandsc( &mainOpts);
xreadgr( &mainOpts);
xrelato( &mainOpts);
xstcs ( &mainOpts);
xstorag( &mainOpts);
xtoken ( &mainOpts);
xutil ( &mainOpts);
}
/*-------------------------- informGenerateTime ----------------------------*/
static void informGenerateTime(
clock_t startTime,
clock_t randSchrTime,
clock_t optGroupTime,
clock_t stcsTime)
{
clock_t totalTime;
#ifdef NOFLOAT
unsigned long secs, hSecs;
#endif
stcsTime -= optGroupTime;
optGroupTime -= randSchrTime;
randSchrTime -= startTime;
totalTime = randSchrTime + optGroupTime + stcsTime;
#ifndef NOFLOAT
printf( "\nTime: Random Schreier: %6.2lf sec" ,
(double ) randSchrTime / CLK_TCK);
printf( "\n Gen optimization: %6.2lf sec" ,
(double ) optGroupTime / CLK_TCK);
printf( "\n Schr-Todd-Cox-Sims: %6.2lf sec" ,
(double ) stcsTime / CLK_TCK);
printf( "\n TOTAL: %6.2lf sec" ,
(double ) totalTime / CLK_TCK);
#endif
#ifdef NOFLOAT
secs = randSchrTime / CLK_TCK;
hSecs = (randSchrTime - secs * CLK_TCK) * 100 ;
hSecs /= CLK_TCK;
printf( "\nTime: Random Schreier: %4lu.%02lu sec" , secs, hSecs);
secs = optGroupTime / CLK_TCK;
hSecs = (optGroupTime - secs * CLK_TCK) * 100 ;
hSecs /= CLK_TCK;
printf( "\n Gen optimization: %4lu.%02lu sec" , secs, hSecs);
secs = stcsTime / CLK_TCK;
hSecs = (stcsTime - secs * CLK_TCK) * 100 ;
hSecs /= CLK_TCK;
printf( "\n Schr-Todd-Cox-Sims: %4lu.%02lu sec" , secs, hSecs);
secs = totalTime / CLK_TCK;
hSecs = (totalTime - secs * CLK_TCK) * 100 ;
hSecs /= CLK_TCK;
printf( "\n TOTAL: %4lu.%02lu sec" , secs, hSecs);
#endif
printf( "\n" );
}
Messung V0.5 in Prozent C=93 H=81 G=86
¤ Dauer der Verarbeitung: 0.21 Sekunden
(vorverarbeitet am 2026-06-26)
¤
*© Formatika GbR, Deutschland