/* File compgrp.c. Contains main program for command compgrp, which can be
used to compare two groups. The command format is
compgrp <options> <group1> <group2>
where <group1> and <group2> are the permutation groups to be compared.
The command prints one of the following messages:
i) <group1> and <group2> are equal.
ii) <group1> is properly contained in <group2>.
iii) <group2> is properly contained in <group1>.
iv) Neither of <group1> or <group2> is contained in the other.
The return value is 0, 1, 2, or 3 depending on whether (i), (ii), (iii),
or (iv) above hold, respectively. If an error occurs, the return code
is 4.
The only options are -c and -n (and the special options -l and -v, which
have their standard meaning). If -c is specified, the program checks
whether the two groups centralize each other. If -n is specified, it
checks whether either group normalizes the other.
*/
#include <errno.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAIN
#include "group.h"
#include "groupio.h"
#include "errmesg.h"
#include "permgrp.h"
#include "permut.h"
#include "readgrp.h"
#include "readpar.h"
#include "readper.h"
#include "readpts.h"
#include "util.h"
/* Nonstandard error return code. */
#undef ERROR_RETURN_CODE
#define ERROR_RETURN_CODE 4
static int comparePerm(
const Permutation *const perm1,
const Permutation *const perm2);
static int comparePointSet(
const PointSet *const set1,
const PointSet *const set2);
static int comparePartition(
const Partition *const partn1,
const Partition *const partn2);
static void verifyOptions(void);
GroupOptions options;
int main( int argc, char *argv[])
{
char group1FileName[MAX_FILE_NAME_LENGTH] = "",
group2FileName[MAX_FILE_NAME_LENGTH] = "",
group1LibraryName[MAX_NAME_LENGTH] = "",
group2LibraryName[MAX_NAME_LENGTH] = "",
prefix[MAX_FILE_NAME_LENGTH] = "",
suffix[MAX_NAME_LENGTH] = "";
PermGroup *group1, *group2 = NULL;
Permutation *perm1, *perm2 = NULL;
Partition *partn1, *partn2 = NULL;
PointSet *set1, *set2 = NULL;
Unsigned optionCountPlus1, i, j;
Unsigned normalizeFlag = FALSE, centralizeFlag = FALSE,
skipNormalize = FALSE, returnCode, degree;
BOOLEAN comparePermFlag = FALSE, comparePointSetFlag = FALSE,
comparePartitionFlag = FALSE;
/* If there are no options, provide usage information and exit. */
if ( argc == 1 ) {
printf( "\nUsage: compgrp [-n] [-c] permGroup1 [permGroup2]\n");
return 0;
}
if ( argc == 2 && strncmp( argv[1], "-perm:", 6) == 0 ) {
printf( "\nUsage: compper degree permutation1 [permutation2]\n");
return 0;
}
if ( argc == 2 && strncmp( argv[1], "-set:", 5) == 0 ) {
printf( "\nUsage: compset degree set1 [set2]\n");
return 0;
}
if ( argc == 2 && strncmp( argv[1], "-partition:", 11 ) == 0 ) {
printf( "\nUsage: comppar degree partition1 [partition2]\n");
return 0;
}
/* Count the number of options. */
for ( optionCountPlus1 = 1 ; optionCountPlus1 <= argc-1 &&
argv[optionCountPlus1][0] == '-' ; ++optionCountPlus1 )
;
/* Translate options to lower case. */
for ( i = 1 ; i < optionCountPlus1 ; ++i ) {
for ( j = 1 ; argv[i][j] != ':' && argv[i][j] != '\0' ; ++j )
#ifdef EBCDIC
argv[i][j] = ( argv[i][j] >= 'A' && argv[i][j] <= 'I' ||
argv[i][j] >= 'J' && argv[i][j] <= 'R' ||
argv[i][j] >= 'S' && argv[i][j] <= 'Z' ) ?
(argv[i][j] + 'a' - 'A') : argv[i][j];
#else
argv[i][j] = (argv[i][j] >= 'A' && argv[i][j] <= 'Z') ?
(argv[i][j] + 'a' - 'A') : argv[i][j];
#endif
}
/* 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();
return 0;
}
/* Check for verify option. If present in position i (i as above) perform
verify (Note verifyOptions terminates program). */
if ( strcmp( argv[1], "-v") == 0 || strcmp( argv[1], "-V") == 0 )
verifyOptions();
/* Check for at most 2 parameters following options. */
if ( argc - optionCountPlus1 > 2 )
ERROR( "Compgrp", "Exactly 2 non-option parameters are required.")
/* Process options. */
options.maxBaseSize = DEFAULT_MAX_BASE_SIZE;
options.inform = TRUE;
for ( i = 1 ; i < optionCountPlus1 ; ++i )
if ( strcmp(argv[i],"-c") == 0 )
centralizeFlag = TRUE;
else if ( strcmp(argv[i],"-n") == 0 )
normalizeFlag = 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], "-p:", 3) == 0 ) {
strcpy( prefix, argv[i]+3);
}
else if ( strcmp( argv[i], "-q") == 0 )
options.inform = FALSE;
else if ( strncmp( argv[i], "-t:", 3) == 0 ) {
strcpy( suffix, argv[i]+3);
}
else if ( strncmp( argv[i], "-perm:", 6) == 0 ) {
errno = 0;
degree = (Unsigned) strtol(argv[i]+6,NULL,0);
comparePermFlag = TRUE;
if ( errno )
ERROR( "main (compgrp)", "Invalid syntax for -perm option")
}
else if ( strncmp( argv[i], "-set:", 5) == 0 ) {
errno = 0;
degree = (Unsigned) strtol(argv[i]+5,NULL,0);
comparePointSetFlag = TRUE;
if ( errno )
ERROR( "main (compgrp)", "Invalid syntax for -set option")
}
else if ( strncmp( argv[i], "-partition:", 11) == 0 ) {
errno = 0;
degree = (Unsigned) strtol(argv[i]+11,NULL,0);
comparePartitionFlag = TRUE;
if ( errno )
ERROR( "main (compgrp)", "Invalid syntax for -partition option")
}
else
ERROR1s( "main (compgrp 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 file and library names. */
parseLibraryName( argv[optionCountPlus1], prefix, suffix,
group1FileName, group1LibraryName);
parseLibraryName( argv[optionCountPlus1+1], prefix, suffix,
group2FileName, group2LibraryName);
/* Read in groups. For types other than permutation groups, call special
function to perform comparison. */
if ( comparePermFlag ) {
perm1 = readPermutation( group1FileName, group1LibraryName, degree, FALSE);
if ( argc > optionCountPlus1+1 )
perm2 = readPermutation( group2FileName, group2LibraryName, degree, FALSE);
return comparePerm( perm1, perm2);
}
else if ( comparePointSetFlag ) {
set1 = readPointSet( group1FileName, group1LibraryName, degree);
if ( argc > optionCountPlus1+1 )
set2 = readPointSet( group2FileName, group2LibraryName, degree);
return comparePointSet( set1, set2);
}
else if ( comparePartitionFlag) {
partn1 = readPartition( group1FileName, group1LibraryName, degree);
if ( argc > optionCountPlus1+1 )
partn2 = readPartition( group2FileName, group2LibraryName, degree);
return comparePartition( partn1, partn2);
}
else {
group1 = readPermGroup( group1FileName, group1LibraryName, 0, "Generate");
if ( argc > optionCountPlus1+1 )
group2 = readPermGroup( group2FileName, group2LibraryName, group1->degree,
"Generate");
}
/* If second group is omitted, check if first group is the identity. */
if ( !group2 ) {
if ( group1->order->noOfFactors == 0 ) {
if ( options.inform )
printf( "\n %s is the identity.\n", group1->name);
return 0;
}
else {
if ( options.inform )
printf( "\n %s is not the identity.\n", group1->name);
return 1;
}
}
/* Check containment. */
if ( isSubgroupOf(group1,group2) ) {
if ( isSubgroupOf(group2,group1) ) {
if ( options.inform )
printf( "\n %s and %s are equal.\n", group1->name, group2->name);
if ( centralizeFlag ) {
if ( isCentralizedBy(group1,group2) ) {
printf( " %s and %s centralize each other.\n",
group1->name, group2->name);
skipNormalize = TRUE;
}
else
printf( " %s and %s do not centralize each other.\n",
group1->name, group2->name);
}
returnCode = 0;
}
else {
if ( options.inform )
printf( "\n %s is properly contained in %s.\n", group1->name,
group2->name);
if ( centralizeFlag ) {
if ( isCentralizedBy(group1,group2) ) {
printf( " %s and %s centralize each other.\n",
group1->name, group2->name);
skipNormalize = TRUE;
}
else
printf( " %s and %s do not centralize each other.\n",
group1->name, group2->name);
}
if ( normalizeFlag && !skipNormalize ) {
if ( isNormalizedBy(group1,group2) )
printf( " %s is normal in %s.\n", group1->name,
group2->name);
else
printf( " %s is not normal in %s.\n", group1->name,
group2->name);
}
returnCode = 1;
}
}
else {
if ( isSubgroupOf(group2,group1) ) {
if ( options.inform )
printf( "\n %s is properly contained in %s.\n", group2->name,
group1->name);
if ( centralizeFlag ) {
if ( isCentralizedBy(group1,group2) ) {
printf( " %s and %s centralize each other.\n",
group1->name, group2->name);
skipNormalize = TRUE;
}
else
printf( " %s and %s do not centralize each other.\n",
group1->name, group2->name);
}
if ( normalizeFlag && !skipNormalize ) {
if ( isNormalizedBy( group2, group1) )
printf( " %s is normal in %s.\n", group2->name,
group1->name);
else
printf( " %s is not normal in %s.\n", group2->name,
group1->name);
}
returnCode = 2;
}
else {
if ( options.inform )
printf( "\n Neither of %s or %s is contained in the other.\n",
group1->name, group2->name);
if ( centralizeFlag ) {
if ( isCentralizedBy(group1,group2) ) {
printf( " %s and %s centralize each other.\n",
group1->name, group2->name);
skipNormalize = TRUE;
}
else
printf( " %s and %s do not centralize each other.\n",
group1->name, group2->name);
}
if ( normalizeFlag && !skipNormalize ) {
if ( isNormalizedBy( group1, group2) )
printf( " %s is normalized by %s.\n", group1->name,
group2->name);
else
printf( " %s is not normalized by %s.\n", group1->name,
group2->name);
if ( isNormalizedBy( group2, group1) )
printf( " %s is normalized by %s.\n", group2->name,
group1->name);
else
printf( " %s is not normalized by %s.\n", group2->name,
group1->name);
}
returnCode = 3;
}
}
return returnCode;
}
/*-------------------------- comparePerm ---------------------------------*/
static int comparePerm(
const Permutation *const perm1,
const Permutation *const perm2)
{
Unsigned pt;
if ( perm2 ) {
for ( pt = 1 ; pt <= perm1->degree ; ++pt )
if ( perm1->image[pt] != perm2->image[pt] ) {
if ( options.inform )
printf( "\n %s and %s are not equal.\n", perm1->name,
perm2->name);
return 1;
}
if ( options.inform )
printf( "\n %s and %s are equal.\n", perm1->name, perm2->name);
return 0;
}
else {
for ( pt = 1 ; pt <= perm1->degree ; ++pt )
if ( perm1->image[pt] != pt ) {
if ( options.inform )
printf( "\n %s is not the identity.\n", perm1->name);
return 1;
}
if ( options.inform )
printf( "\n %s is the identity.\n", perm1->name);
return 0;
}
}
/*-------------------------- comparePointSet -------------------------------*/
static int comparePointSet(
const PointSet *const set1,
const PointSet *const set2)
{
Unsigned i;
BOOLEAN set1InSet2 = TRUE, set2InSet1 = TRUE;
if ( set2 ) {
for ( i = 1 ; i <= set1->size ; ++i )
if ( !set2->inSet[set1->pointList[i]] ) {
set1InSet2 = FALSE;
break;
}
for ( i = 1 ; i <= set2->size ; ++i )
if ( !set1->inSet[set2->pointList[i]] ) {
set2InSet1 = FALSE;
break;
}
if ( set1InSet2 && set2InSet1 ) {
if ( options.inform )
printf( "\n Sets %s and %s are equal.\n", set1->name, set2->name);
return 0;
}
else if ( set1InSet2 ) {
if ( options.inform )
printf( "\n Set %s is properly contained in set %s.\n", set1->name,
set2->name);
return 1;
}
else if ( set2InSet1 ) {
if ( options.inform )
printf( "\n Set %s is properly contained in set %s.\n", set2->name,
set1->name);
return 2;
}
else {
if ( options.inform )
printf( "\n Neither set %s or set %s is contained in the other.\n",
set1->name, set2->name);
return 3;
}
}
else {
if ( set1->size == 0 ) {
if ( options.inform )
printf( "\n %s is empty.\n", set1->name);
return 0;
}
else {
if ( options.inform )
printf( "\n %s is not empty.\n", set1->name);
return 1;
}
}
}
/*-------------------------- comparePartition ----------------------------*/
static int comparePartition(
const Partition *const partn1,
const Partition *const partn2)
{
ERROR( "comparePartition", "Comparison of partitions not yet implemented")
return 0; /* silence compiler warning */
}
/*-------------------------- 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 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 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 xreadpe( CompileOptions *cOpts);
extern void xstorag( CompileOptions *cOpts);
extern void xtoken ( CompileOptions *cOpts);
extern void xutil ( CompileOptions *cOpts);
xaddsge( &mainOpts);
xbitman( &mainOpts);
xcopy ( &mainOpts);
xcstbor( &mainOpts);
xerrmes( &mainOpts);
xessent( &mainOpts);
xfactor( &mainOpts);
xnew ( &mainOpts);
xoldcop( &mainOpts);
xpermgr( &mainOpts);
xpermut( &mainOpts);
xprimes( &mainOpts);
xrandgr( &mainOpts);
xrandsc( &mainOpts);
xreadgr( &mainOpts);
xreadpe( &mainOpts);
xstorag( &mainOpts);
xtoken ( &mainOpts);
xutil ( &mainOpts);
}
¤ Dauer der Verarbeitung: 0.2 Sekunden
(vorverarbeitet am 2026-11-04)
¤
*© Formatika GbR, Deutschland
|
|