1 /* File compgrp.c. Contains main program for command compgrp, which can be
2 used to compare two groups. The command format is
3
4 compgrp <options> <group1> <group2>
5
6 where <group1> and <group2> are the permutation groups to be compared.
7 The command prints one of the following messages:
8
9 i) <group1> and <group2> are equal.
10 ii) <group1> is properly contained in <group2>.
11 iii) <group2> is properly contained in <group1>.
12 iv) Neither of <group1> or <group2> is contained in the other.
13
14 The return value is 0, 1, 2, or 3 depending on whether (i), (ii), (iii),
15 or (iv) above hold, respectively. If an error occurs, the return code
16 is 4.
17
18 The only options are -c and -n (and the special options -l and -v, which
19 have their standard meaning). If -c is specified, the program checks
20 whether the two groups centralize each other. If -n is specified, it
21 checks whether either group normalizes the other.
22 */
23
24 #include <errno.h>
25 #include <stddef.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29
30 #define MAIN
31
32 #include "group.h"
33 #include "groupio.h"
34
35 #include "errmesg.h"
36 #include "permgrp.h"
37 #include "permut.h"
38 #include "readgrp.h"
39 #include "readpar.h"
40 #include "readper.h"
41 #include "readpts.h"
42 #include "util.h"
43
44 /* Nonstandard error return code. */
45 #undef ERROR_RETURN_CODE
46 #define ERROR_RETURN_CODE 4
47
48 static int comparePerm(
49 const Permutation *const perm1,
50 const Permutation *const perm2);
51 static int comparePointSet(
52 const PointSet *const set1,
53 const PointSet *const set2);
54 static int comparePartition(
55 const Partition *const partn1,
56 const Partition *const partn2);
57 static void verifyOptions(void);
58
59 GroupOptions options;
60
61
main(int argc,char * argv[])62 int main( int argc, char *argv[])
63 {
64 char group1FileName[MAX_FILE_NAME_LENGTH] = "",
65 group2FileName[MAX_FILE_NAME_LENGTH] = "",
66 group1LibraryName[MAX_NAME_LENGTH] = "",
67 group2LibraryName[MAX_NAME_LENGTH] = "",
68 prefix[MAX_FILE_NAME_LENGTH] = "",
69 suffix[MAX_NAME_LENGTH] = "";
70 PermGroup *group1, *group2 = NULL;
71 Permutation *perm1, *perm2 = NULL;
72 Partition *partn1, *partn2 = NULL;
73 PointSet *set1, *set2 = NULL;
74 Unsigned optionCountPlus1, i, j;
75 Unsigned normalizeFlag = FALSE, centralizeFlag = FALSE,
76 skipNormalize = FALSE, returnCode, degree;
77 BOOLEAN comparePermFlag = FALSE, comparePointSetFlag = FALSE,
78 comparePartitionFlag = FALSE;
79
80 /* If there are no options, provide usage information and exit. */
81 if ( argc == 1 ) {
82 printf( "\nUsage: compgrp [-n] [-c] permGroup1 [permGroup2]\n");
83 return 0;
84 }
85 if ( argc == 2 && strncmp( argv[1], "-perm:", 6) == 0 ) {
86 printf( "\nUsage: compper degree permutation1 [permutation2]\n");
87 return 0;
88 }
89 if ( argc == 2 && strncmp( argv[1], "-set:", 5) == 0 ) {
90 printf( "\nUsage: compset degree set1 [set2]\n");
91 return 0;
92 }
93 if ( argc == 2 && strncmp( argv[1], "-partition:", 11 ) == 0 ) {
94 printf( "\nUsage: comppar degree partition1 [partition2]\n");
95 return 0;
96 }
97
98 /* Count the number of options. */
99 for ( optionCountPlus1 = 1 ; optionCountPlus1 <= argc-1 &&
100 argv[optionCountPlus1][0] == '-' ; ++optionCountPlus1 )
101 ;
102
103 /* Translate options to lower case. */
104 for ( i = 1 ; i < optionCountPlus1 ; ++i ) {
105 for ( j = 1 ; argv[i][j] != ':' && argv[i][j] != '\0' ; ++j )
106 #ifdef EBCDIC
107 argv[i][j] = ( argv[i][j] >= 'A' && argv[i][j] <= 'I' ||
108 argv[i][j] >= 'J' && argv[i][j] <= 'R' ||
109 argv[i][j] >= 'S' && argv[i][j] <= 'Z' ) ?
110 (argv[i][j] + 'a' - 'A') : argv[i][j];
111 #else
112 argv[i][j] = (argv[i][j] >= 'A' && argv[i][j] <= 'Z') ?
113 (argv[i][j] + 'a' - 'A') : argv[i][j];
114 #endif
115 }
116
117 /* Check for limits option. If present in position 1, give limits and
118 return. */
119 if ( strcmp( argv[1], "-l") == 0 || strcmp( argv[1], "-L") == 0 ) {
120 showLimits();
121 return 0;
122 }
123 /* Check for verify option. If present in position i (i as above) perform
124 verify (Note verifyOptions terminates program). */
125 if ( strcmp( argv[1], "-v") == 0 || strcmp( argv[1], "-V") == 0 )
126 verifyOptions();
127
128 /* Check for at most 2 parameters following options. */
129 if ( argc - optionCountPlus1 > 2 )
130 ERROR( "Compgrp", "Exactly 2 non-option parameters are required.")
131
132 /* Process options. */
133 options.maxBaseSize = DEFAULT_MAX_BASE_SIZE;
134 options.inform = TRUE;
135 for ( i = 1 ; i < optionCountPlus1 ; ++i )
136 if ( strcmp(argv[i],"-c") == 0 )
137 centralizeFlag = TRUE;
138 else if ( strcmp(argv[i],"-n") == 0 )
139 normalizeFlag = TRUE;
140 else if ( strncmp( argv[i], "-mb:", 4) == 0 ) {
141 errno = 0;
142 options.maxBaseSize = (Unsigned) strtol(argv[i]+4,NULL,0);
143 if ( errno )
144 ERROR( "main (cent)", "Invalid syntax for -mb option")
145 }
146 else if ( strncmp( argv[i], "-mw:", 4) == 0 ) {
147 errno = 0;
148 options.maxWordLength = (Unsigned) strtol(argv[i]+4,NULL,0);
149 if ( errno )
150 ERROR( "main (cent)", "Invalid syntax for -mw option")
151 }
152 else if ( strncmp( argv[i], "-p:", 3) == 0 ) {
153 strcpy( prefix, argv[i]+3);
154 }
155 else if ( strcmp( argv[i], "-q") == 0 )
156 options.inform = FALSE;
157 else if ( strncmp( argv[i], "-t:", 3) == 0 ) {
158 strcpy( suffix, argv[i]+3);
159 }
160 else if ( strncmp( argv[i], "-perm:", 6) == 0 ) {
161 errno = 0;
162 degree = (Unsigned) strtol(argv[i]+6,NULL,0);
163 comparePermFlag = TRUE;
164 if ( errno )
165 ERROR( "main (compgrp)", "Invalid syntax for -perm option")
166 }
167 else if ( strncmp( argv[i], "-set:", 5) == 0 ) {
168 errno = 0;
169 degree = (Unsigned) strtol(argv[i]+5,NULL,0);
170 comparePointSetFlag = TRUE;
171 if ( errno )
172 ERROR( "main (compgrp)", "Invalid syntax for -set option")
173 }
174 else if ( strncmp( argv[i], "-partition:", 11) == 0 ) {
175 errno = 0;
176 degree = (Unsigned) strtol(argv[i]+11,NULL,0);
177 comparePartitionFlag = TRUE;
178 if ( errno )
179 ERROR( "main (compgrp)", "Invalid syntax for -partition option")
180 }
181 else
182 ERROR1s( "main (compgrp command)", "Invalid option ", argv[i], ".")
183
184
185 /* Compute maximum degree and word length. */
186 options.maxWordLength = 200 + 5 * options.maxBaseSize;
187 options.maxDegree = MAX_INT - 2 - options.maxBaseSize;
188
189 /* Compute file and library names. */
190 parseLibraryName( argv[optionCountPlus1], prefix, suffix,
191 group1FileName, group1LibraryName);
192 parseLibraryName( argv[optionCountPlus1+1], prefix, suffix,
193 group2FileName, group2LibraryName);
194
195 /* Read in groups. For types other than permutation groups, call special
196 function to perform comparison. */
197 if ( comparePermFlag ) {
198 perm1 = readPermutation( group1FileName, group1LibraryName, degree, FALSE);
199 if ( argc > optionCountPlus1+1 )
200 perm2 = readPermutation( group2FileName, group2LibraryName, degree, FALSE);
201 return comparePerm( perm1, perm2);
202 }
203 else if ( comparePointSetFlag ) {
204 set1 = readPointSet( group1FileName, group1LibraryName, degree);
205 if ( argc > optionCountPlus1+1 )
206 set2 = readPointSet( group2FileName, group2LibraryName, degree);
207 return comparePointSet( set1, set2);
208 }
209 else if ( comparePartitionFlag) {
210 partn1 = readPartition( group1FileName, group1LibraryName, degree);
211 if ( argc > optionCountPlus1+1 )
212 partn2 = readPartition( group2FileName, group2LibraryName, degree);
213 return comparePartition( partn1, partn2);
214 }
215 else {
216 group1 = readPermGroup( group1FileName, group1LibraryName, 0, "Generate");
217 if ( argc > optionCountPlus1+1 )
218 group2 = readPermGroup( group2FileName, group2LibraryName, group1->degree,
219 "Generate");
220 }
221
222 /* If second group is omitted, check if first group is the identity. */
223 if ( !group2 )
224 if ( group1->order->noOfFactors == 0 ) {
225 if ( options.inform )
226 printf( "\n %s is the identity.\n", group1->name);
227 return 0;
228 }
229 else {
230 if ( options.inform )
231 printf( "\n %s is not the identity.\n", group1->name);
232 return 1;
233 }
234
235 /* Check containment. */
236 if ( isSubgroupOf(group1,group2) )
237 if ( isSubgroupOf(group2,group1) ) {
238 if ( options.inform )
239 printf( "\n %s and %s are equal.\n", group1->name, group2->name);
240 if ( centralizeFlag )
241 if ( isCentralizedBy(group1,group2) ) {
242 printf( " %s and %s centralize each other.\n",
243 group1->name, group2->name);
244 skipNormalize = TRUE;
245 }
246 else
247 printf( " %s and %s do not centralize each other.\n",
248 group1->name, group2->name);
249 returnCode = 0;
250 }
251 else {
252 if ( options.inform )
253 printf( "\n %s is properly contained in %s.\n", group1->name,
254 group2->name);
255 if ( centralizeFlag )
256 if ( isCentralizedBy(group1,group2) ) {
257 printf( " %s and %s centralize each other.\n",
258 group1->name, group2->name);
259 skipNormalize = TRUE;
260 }
261 else
262 printf( " %s and %s do not centralize each other.\n",
263 group1->name, group2->name);
264 if ( normalizeFlag && !skipNormalize )
265 if ( isNormalizedBy(group1,group2) )
266 printf( " %s is normal in %s.\n", group1->name,
267 group2->name);
268 else
269 printf( " %s is not normal in %s.\n", group1->name,
270 group2->name);
271 returnCode = 1;
272 }
273 else
274 if ( isSubgroupOf(group2,group1) ) {
275 if ( options.inform )
276 printf( "\n %s is properly contained in %s.\n", group2->name,
277 group1->name);
278 if ( centralizeFlag )
279 if ( isCentralizedBy(group1,group2) ) {
280 printf( " %s and %s centralize each other.\n",
281 group1->name, group2->name);
282 skipNormalize = TRUE;
283 }
284 else
285 printf( " %s and %s do not centralize each other.\n",
286 group1->name, group2->name);
287 if ( normalizeFlag && !skipNormalize )
288 if ( isNormalizedBy( group2, group1) )
289 printf( " %s is normal in %s.\n", group2->name,
290 group1->name);
291 else
292 printf( " %s is not normal in %s.\n", group2->name,
293 group1->name);
294 returnCode = 2;
295 }
296 else {
297 if ( options.inform )
298 printf( "\n Neither of %s or %s is contained in the other.\n",
299 group1->name, group2->name);
300 if ( centralizeFlag )
301 if ( isCentralizedBy(group1,group2) ) {
302 printf( " %s and %s centralize each other.\n",
303 group1->name, group2->name);
304 skipNormalize = TRUE;
305 }
306 else
307 printf( " %s and %s do not centralize each other.\n",
308 group1->name, group2->name);
309 if ( normalizeFlag && !skipNormalize ) {
310 if ( isNormalizedBy( group1, group2) )
311 printf( " %s is normalized by %s.\n", group1->name,
312 group2->name);
313 else
314 printf( " %s is not normalized by %s.\n", group1->name,
315 group2->name);
316 if ( isNormalizedBy( group2, group1) )
317 printf( " %s is normalized by %s.\n", group2->name,
318 group1->name);
319 else
320 printf( " %s is not normalized by %s.\n", group2->name,
321 group1->name);
322 }
323 returnCode = 3;
324 }
325
326 return returnCode;
327 }
328
329
330
331 /*-------------------------- comparePerm ---------------------------------*/
332
comparePerm(const Permutation * const perm1,const Permutation * const perm2)333 static int comparePerm(
334 const Permutation *const perm1,
335 const Permutation *const perm2)
336 {
337 Unsigned pt;
338
339 if ( perm2 ) {
340 for ( pt = 1 ; pt <= perm1->degree ; ++pt )
341 if ( perm1->image[pt] != perm2->image[pt] ) {
342 if ( options.inform )
343 printf( "\n %s and %s are not equal.\n", perm1->name,
344 perm2->name);
345 return 1;
346 }
347 if ( options.inform )
348 printf( "\n %s and %s are equal.\n", perm1->name, perm2->name);
349 return 0;
350 }
351 else {
352 for ( pt = 1 ; pt <= perm1->degree ; ++pt )
353 if ( perm1->image[pt] != pt ) {
354 if ( options.inform )
355 printf( "\n %s is not the identity.\n", perm1->name);
356 return 1;
357 }
358 if ( options.inform )
359 printf( "\n %s is the identity.\n", perm1->name);
360 return 0;
361 }
362 }
363
364
365
366
367 /*-------------------------- comparePointSet -------------------------------*/
368
comparePointSet(const PointSet * const set1,const PointSet * const set2)369 static int comparePointSet(
370 const PointSet *const set1,
371 const PointSet *const set2)
372 {
373 Unsigned i;
374 BOOLEAN set1InSet2 = TRUE, set2InSet1 = TRUE;
375
376 if ( set2 ) {
377 for ( i = 1 ; i <= set1->size ; ++i )
378 if ( !set2->inSet[set1->pointList[i]] ) {
379 set1InSet2 = FALSE;
380 break;
381 }
382 for ( i = 1 ; i <= set2->size ; ++i )
383 if ( !set1->inSet[set2->pointList[i]] ) {
384 set2InSet1 = FALSE;
385 break;
386 }
387 if ( set1InSet2 && set2InSet1 ) {
388 if ( options.inform )
389 printf( "\n Sets %s and %s are equal.\n", set1->name, set2->name);
390 return 0;
391 }
392 else if ( set1InSet2 ) {
393 if ( options.inform )
394 printf( "\n Set %s is properly contained in set %s.\n", set1->name,
395 set2->name);
396 return 1;
397 }
398 else if ( set2InSet1 ) {
399 if ( options.inform )
400 printf( "\n Set %s is properly contained in set %s.\n", set2->name,
401 set1->name);
402 return 2;
403 }
404 else {
405 if ( options.inform )
406 printf( "\n Neither set %s or set %s is contained in the other.\n",
407 set1->name, set2->name);
408 return 3;
409 }
410 }
411 else {
412 if ( set1->size == 0 ) {
413 if ( options.inform )
414 printf( "\n %s is empty.\n", set1->name);
415 return 0;
416 }
417 else {
418 if ( options.inform )
419 printf( "\n %s is not empty.\n", set1->name);
420 return 1;
421 }
422 }
423 }
424
425
426 /*-------------------------- comparePartition ----------------------------*/
427
comparePartition(const Partition * const partn1,const Partition * const partn2)428 static int comparePartition(
429 const Partition *const partn1,
430 const Partition *const partn2)
431 {
432 ERROR( "comparePartition", "Comparison of partitions not yet implemented")
433 }
434
435
436 /*-------------------------- verifyOptions -------------------------------*/
437
verifyOptions(void)438 static void verifyOptions(void)
439 {
440 CompileOptions mainOpts = { DEFAULT_MAX_BASE_SIZE, MAX_NAME_LENGTH,
441 MAX_PRIME_FACTORS,
442 MAX_REFINEMENT_PARMS, MAX_FAMILY_PARMS,
443 MAX_EXTRA, XLARGE, SGND, NFLT};
444 extern void xaddsge( CompileOptions *cOpts);
445 extern void xbitman( CompileOptions *cOpts);
446 extern void xcopy ( CompileOptions *cOpts);
447 extern void xcstbor( CompileOptions *cOpts);
448 extern void xerrmes( CompileOptions *cOpts);
449 extern void xessent( CompileOptions *cOpts);
450 extern void xfactor( CompileOptions *cOpts);
451 extern void xnew ( CompileOptions *cOpts);
452 extern void xoldcop( CompileOptions *cOpts);
453 extern void xpermgr( CompileOptions *cOpts);
454 extern void xpermut( CompileOptions *cOpts);
455 extern void xprimes( CompileOptions *cOpts);
456 extern void xrandgr( CompileOptions *cOpts);
457 extern void xrandsc( CompileOptions *cOpts);
458 extern void xreadgr( CompileOptions *cOpts);
459 extern void xreadpe( CompileOptions *cOpts);
460 extern void xstorag( CompileOptions *cOpts);
461 extern void xtoken ( CompileOptions *cOpts);
462 extern void xutil ( CompileOptions *cOpts);
463
464 xaddsge( &mainOpts);
465 xbitman( &mainOpts);
466 xcopy ( &mainOpts);
467 xcstbor( &mainOpts);
468 xerrmes( &mainOpts);
469 xessent( &mainOpts);
470 xfactor( &mainOpts);
471 xnew ( &mainOpts);
472 xoldcop( &mainOpts);
473 xpermgr( &mainOpts);
474 xpermut( &mainOpts);
475 xprimes( &mainOpts);
476 xrandgr( &mainOpts);
477 xrandsc( &mainOpts);
478 xreadgr( &mainOpts);
479 xreadpe( &mainOpts);
480 xstorag( &mainOpts);
481 xtoken ( &mainOpts);
482 xutil ( &mainOpts);
483 }
484